00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "FEApp_Application.hpp"
00033 #include "FEApp_ProblemFactory.hpp"
00034 #include "FEApp_QuadratureFactory.hpp"
00035 #include "FEApp_DiscretizationFactory.hpp"
00036 #include "FEApp_InitPostOps.hpp"
00037 #include "FEApp_GlobalFill.hpp"
00038
00039 FEApp::Application::Application(
00040 const std::vector<double>& coords,
00041 const Teuchos::RCP<const Epetra_Comm>& comm,
00042 const Teuchos::RCP<Teuchos::ParameterList>& params,
00043 bool is_transient) :
00044 transient(is_transient)
00045 {
00046
00047 paramLib = Teuchos::rcp(new Sacado::ScalarParameterLibrary);
00048
00049
00050 Teuchos::RCP<Teuchos::ParameterList> problemParams =
00051 Teuchos::rcp(&(params->sublist("Problem")),false);
00052 FEApp::ProblemFactory problemFactory(problemParams, paramLib);
00053 Teuchos::RCP<FEApp::AbstractProblem> problem =
00054 problemFactory.create();
00055
00056
00057 unsigned int num_equations = problem->numEquations();
00058
00059
00060 Teuchos::RCP<Teuchos::ParameterList> quadParams =
00061 Teuchos::rcp(&(params->sublist("Quadrature")),false);
00062 FEApp::QuadratureFactory quadFactory(quadParams);
00063 quad = quadFactory.create();
00064
00065
00066 Teuchos::RCP<Teuchos::ParameterList> discParams =
00067 Teuchos::rcp(&(params->sublist("Discretization")),false);
00068 FEApp::DiscretizationFactory discFactory(discParams);
00069 disc = discFactory.create(coords, num_equations, comm);
00070 disc->createMesh();
00071 disc->createMaps();
00072 disc->createJacobianGraphs();
00073
00074
00075 importer = Teuchos::rcp(new Epetra_Import(*(disc->getOverlapMap()),
00076 *(disc->getMap())));
00077 exporter = Teuchos::rcp(new Epetra_Export(*(disc->getOverlapMap()),
00078 *(disc->getMap())));
00079 overlapped_x = Teuchos::rcp(new Epetra_Vector(*(disc->getOverlapMap())));
00080 if (transient)
00081 overlapped_xdot =
00082 Teuchos::rcp(new Epetra_Vector(*(disc->getOverlapMap())));
00083 overlapped_f = Teuchos::rcp(new Epetra_Vector(*(disc->getOverlapMap())));
00084 overlapped_jac =
00085 Teuchos::rcp(new Epetra_CrsMatrix(Copy,
00086 *(disc->getOverlapJacobianGraph())));
00087
00088
00089 initial_x = Teuchos::rcp(new Epetra_Vector(*(disc->getMap())));
00090 problem->buildProblem(*(disc->getMap()), *(disc->getOverlapMap()),
00091 pdeTM, bc, initial_x);
00092 typedef FEApp::AbstractPDE_TemplateManager<ValidTypes>::iterator iterator;
00093 int nqp = quad->numPoints();
00094 int nn = disc->getNumNodesPerElement();
00095 for (iterator it = pdeTM.begin(); it != pdeTM.end(); ++it)
00096 it->init(nqp, nn);
00097 }
00098
00099 FEApp::Application::~Application()
00100 {
00101 }
00102
00103 Teuchos::RCP<const Epetra_Map>
00104 FEApp::Application::getMap() const
00105 {
00106 return disc->getMap();
00107 }
00108
00109 Teuchos::RCP<const Epetra_CrsGraph>
00110 FEApp::Application::getJacobianGraph() const
00111 {
00112 return disc->getJacobianGraph();
00113 }
00114
00115 Teuchos::RCP<const Epetra_Vector>
00116 FEApp::Application::getInitialSolution() const
00117 {
00118 return initial_x;
00119 }
00120
00121 Teuchos::RCP<Sacado::ScalarParameterLibrary>
00122 FEApp::Application::getParamLib()
00123 {
00124 return paramLib;
00125 }
00126
00127 bool
00128 FEApp::Application::isTransient() const
00129 {
00130 return transient;
00131 }
00132
00133 void
00134 FEApp::Application::computeGlobalResidual(
00135 const Epetra_Vector* xdot,
00136 const Epetra_Vector& x,
00137 const Sacado::ScalarParameterVector* p,
00138 Epetra_Vector& f)
00139 {
00140
00141 overlapped_x->Import(x, *importer, Insert);
00142
00143
00144 if (transient)
00145 overlapped_xdot->Import(*xdot, *importer, Insert);
00146
00147
00148 if (p != NULL) {
00149 for (unsigned int i=0; i<p->size(); ++i) {
00150 (*p)[i].family->setRealValueForAllTypes((*p)[i].baseValue);
00151 }
00152 }
00153
00154
00155 overlapped_f->PutScalar(0.0);
00156 f.PutScalar(0.0);
00157
00158
00159 Teuchos::RCP<FEApp::ResidualOp> op;
00160 op = Teuchos::rcp(new FEApp::ResidualOp(overlapped_xdot, overlapped_x,
00161 overlapped_f));
00162
00163
00164 Teuchos::RCP< FEApp::AbstractPDE<ResidualOp::fill_type> > pde =
00165 pdeTM.getAsObject<ResidualOp::fill_type>();
00166
00167
00168 FEApp::GlobalFill<ResidualOp::fill_type> globalFill(disc->getMesh(), quad,
00169 pde, bc, transient);
00170 globalFill.computeGlobalFill(*op);
00171
00172
00173 f.Export(*overlapped_f, *exporter, Add);
00174 }
00175
00176 void
00177 FEApp::Application::computeGlobalJacobian(
00178 double alpha, double beta,
00179 const Epetra_Vector* xdot,
00180 const Epetra_Vector& x,
00181 const Sacado::ScalarParameterVector* p,
00182 Epetra_Vector* f,
00183 Epetra_CrsMatrix& jac)
00184 {
00185
00186 overlapped_x->Import(x, *importer, Insert);
00187
00188
00189 if (transient)
00190 overlapped_xdot->Import(*xdot, *importer, Insert);
00191
00192
00193 if (p != NULL) {
00194 for (unsigned int i=0; i<p->size(); ++i) {
00195 (*p)[i].family->setRealValueForAllTypes((*p)[i].baseValue);
00196 }
00197 }
00198
00199
00200 Teuchos::RCP<Epetra_Vector> overlapped_ff;
00201 if (f != NULL) {
00202 overlapped_ff = overlapped_f;
00203 overlapped_ff->PutScalar(0.0);
00204 f->PutScalar(0.0);
00205 }
00206
00207
00208 overlapped_jac->PutScalar(0.0);
00209 jac.PutScalar(0.0);
00210
00211
00212 Teuchos::RCP<FEApp::JacobianOp> op;
00213 op = Teuchos::rcp(new FEApp::JacobianOp(alpha, beta, overlapped_xdot,
00214 overlapped_x, overlapped_ff,
00215 overlapped_jac));
00216
00217
00218 Teuchos::RCP< FEApp::AbstractPDE<JacobianOp::fill_type> > pde =
00219 pdeTM.getAsObject<JacobianOp::fill_type>();
00220
00221
00222 FEApp::GlobalFill<JacobianOp::fill_type> globalFill(disc->getMesh(),
00223 quad, pde, bc,
00224 transient);
00225 globalFill.computeGlobalFill(*op);
00226
00227
00228 if (f != NULL)
00229 f->Export(*overlapped_f, *exporter, Add);
00230
00231
00232 jac.Export(*overlapped_jac, *exporter, Add);
00233
00234 jac.FillComplete(true);
00235 }
00236
00237 void
00238 FEApp::Application::computeGlobalTangent(
00239 double alpha, double beta,
00240 bool sum_derivs,
00241 const Epetra_Vector* xdot,
00242 const Epetra_Vector& x,
00243 Sacado::ScalarParameterVector* p,
00244 const Epetra_MultiVector* Vx,
00245 const Teuchos::SerialDenseMatrix<int,double>* Vp,
00246 Epetra_Vector* f,
00247 Epetra_MultiVector* JVx,
00248 Epetra_MultiVector* fVp)
00249 {
00250
00251 overlapped_x->Import(x, *importer, Insert);
00252
00253
00254 if (transient)
00255 overlapped_xdot->Import(*xdot, *importer, Insert);
00256
00257
00258 Teuchos::RCP<Epetra_Vector> overlapped_ff;
00259 if (f != NULL) {
00260 overlapped_ff = overlapped_f;
00261 overlapped_ff->PutScalar(0.0);
00262 f->PutScalar(0.0);
00263 }
00264
00265 Teuchos::RCP<Epetra_MultiVector> overlapped_JVx;
00266 if (JVx != NULL) {
00267 overlapped_JVx =
00268 Teuchos::rcp(new Epetra_MultiVector(*(disc->getOverlapMap()),
00269 JVx->NumVectors()));
00270 overlapped_JVx->PutScalar(0.0);
00271 JVx->PutScalar(0.0);
00272 }
00273
00274 Teuchos::RCP<Epetra_MultiVector> overlapped_fVp;
00275 if (fVp != NULL) {
00276 overlapped_fVp =
00277 Teuchos::rcp(new Epetra_MultiVector(*(disc->getOverlapMap()),
00278 fVp->NumVectors()));
00279 overlapped_fVp->PutScalar(0.0);
00280 fVp->PutScalar(0.0);
00281 }
00282
00283 Teuchos::RCP<Epetra_MultiVector> overlapped_Vx;
00284 if (Vx != NULL) {
00285 overlapped_Vx =
00286 Teuchos::rcp(new Epetra_MultiVector(*(disc->getOverlapMap()),
00287 Vx->NumVectors()));
00288 }
00289
00290 Teuchos::RCP<const Teuchos::SerialDenseMatrix<int,double> > vp =
00291 Teuchos::rcp(Vp, false);
00292 Teuchos::RCP<Sacado::ScalarParameterVector> params =
00293 Teuchos::rcp(p, false);
00294
00295
00296 Teuchos::RCP<FEApp::TangentOp> op;
00297 op = Teuchos::rcp(new FEApp::TangentOp(alpha, beta, sum_derivs,
00298 overlapped_xdot,
00299 overlapped_x,
00300 params,
00301 overlapped_Vx,
00302 overlapped_Vx,
00303 vp,
00304 overlapped_ff,
00305 overlapped_JVx,
00306 overlapped_fVp));
00307
00308
00309 Teuchos::RCP< FEApp::AbstractPDE<JacobianOp::fill_type> > pde =
00310 pdeTM.getAsObject<JacobianOp::fill_type>();
00311
00312
00313 FEApp::GlobalFill<JacobianOp::fill_type> globalFill(disc->getMesh(),
00314 quad, pde, bc,
00315 transient);
00316 globalFill.computeGlobalFill(*op);
00317
00318
00319 if (f != NULL)
00320 f->Export(*overlapped_f, *exporter, Add);
00321
00322
00323 if (JVx != NULL)
00324 JVx->Export(*overlapped_JVx, *exporter, Add);
00325 if (fVp != NULL)
00326 fVp->Export(*overlapped_fVp, *exporter, Add);
00327 }