00001
00002
00003
00004
00005
00006
00007 #include "QCAD_PoissonProblem.hpp"
00008 #include "QCAD_MaterialDatabase.hpp"
00009 #include "Albany_Utils.hpp"
00010
00011 QCAD::PoissonProblem::
00012 PoissonProblem( const Teuchos::RCP<Teuchos::ParameterList>& params_,
00013 const Teuchos::RCP<ParamLib>& paramLib_,
00014 const int numDim_,
00015 const Teuchos::RCP<const Epetra_Comm>& comm_) :
00016 Albany::AbstractProblem(params_, paramLib_, 1),
00017 comm(comm_),
00018 haveSource(false),
00019 numDim(numDim_)
00020 {
00021 if (numDim==1) periodic = params->get("Periodic BC", false);
00022 else periodic = false;
00023 if (periodic) *out <<" Periodic Boundary Conditions being used." <<std::endl;
00024
00025 haveSource = params->isSublist("Poisson Source");
00026
00027 TEUCHOS_TEST_FOR_EXCEPTION(params->isSublist("Source Functions"), Teuchos::Exceptions::InvalidParameter,
00028 "\nError! Poisson problem does not parse Source Functions sublist\n"
00029 << "\tjust Poisson Source sublist " << std::endl);
00030
00031
00032 length_unit_in_m = 1e-6;
00033 if(params->isType<double>("Length Unit In Meters"))
00034 length_unit_in_m = params->get<double>("Length Unit In Meters");
00035
00036
00037 energy_unit_in_eV = 1.0;
00038 if(params->isType<double>("Energy Unit In Electron Volts"))
00039 energy_unit_in_eV = params->get<double>("Energy Unit In Electron Volts");
00040
00041 temperature = 300;
00042 if(params->isType<double>("Temperature"))
00043 temperature = params->get<double>("Temperature");
00044
00045
00046 std::string mtrlDbFilename = "materials.xml";
00047 if(params->isType<std::string>("MaterialDB Filename"))
00048 mtrlDbFilename = params->get<std::string>("MaterialDB Filename");
00049 materialDB = Teuchos::rcp(new QCAD::MaterialDatabase(mtrlDbFilename, comm));
00050
00051
00052 nEigenvectors = 0;
00053 Teuchos::ParameterList& psList = params->sublist("Poisson Source");
00054 if(psList.isType<int>("Eigenvectors to Import"))
00055 nEigenvectors = psList.get<int>("Eigenvectors to Import");
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081 *out << "Length unit = " << length_unit_in_m << " meters" << std::endl;
00082 *out << "Energy unit = " << energy_unit_in_eV << " electron volts" << std::endl;
00083 }
00084
00085 QCAD::PoissonProblem::
00086 ~PoissonProblem()
00087 {
00088 }
00089
00090 void
00091 QCAD::PoissonProblem::
00092 buildProblem(
00093 Teuchos::ArrayRCP<Teuchos::RCP<Albany::MeshSpecsStruct> > meshSpecs,
00094 Albany::StateManager& stateMgr)
00095 {
00096
00097 TEUCHOS_TEST_FOR_EXCEPTION(meshSpecs.size()!=1,std::logic_error,"Problem supports one Material Block");
00098 fm.resize(1);
00099 fm[0] = Teuchos::rcp(new PHX::FieldManager<PHAL::AlbanyTraits>);
00100 buildEvaluators(*fm[0], *meshSpecs[0], stateMgr, Albany::BUILD_RESID_FM,
00101 Teuchos::null);
00102 constructDirichletEvaluators(*meshSpecs[0]);
00103
00104 if(meshSpecs[0]->ssNames.size() > 0)
00105 constructNeumannEvaluators(meshSpecs[0]);
00106
00107 }
00108
00109 Teuchos::Array< Teuchos::RCP<const PHX::FieldTag> >
00110 QCAD::PoissonProblem::
00111 buildEvaluators(
00112 PHX::FieldManager<PHAL::AlbanyTraits>& fm0,
00113 const Albany::MeshSpecsStruct& meshSpecs,
00114 Albany::StateManager& stateMgr,
00115 Albany::FieldManagerChoice fmchoice,
00116 const Teuchos::RCP<Teuchos::ParameterList>& responseList)
00117 {
00118
00119
00120 Albany::ConstructEvaluatorsOp<PoissonProblem> op(
00121 *this, fm0, meshSpecs, stateMgr, fmchoice, responseList);
00122 boost::mpl::for_each<PHAL::AlbanyTraits::BEvalTypes>(op);
00123 return *op.tags;
00124 }
00125
00126 void
00127 QCAD::PoissonProblem::constructDirichletEvaluators(
00128 const Albany::MeshSpecsStruct& meshSpecs)
00129 {
00130 using Teuchos::RCP;
00131 using Teuchos::rcp;
00132 using Teuchos::ParameterList;
00133 using PHX::DataLayout;
00134 using PHX::MDALayout;
00135 using std::vector;
00136 using std::map;
00137 using std::string;
00138
00139 using PHAL::DirichletFactoryTraits;
00140 using PHAL::AlbanyTraits;
00141
00142
00143 vector<string> dirichletNames(neq);
00144 dirichletNames[0] = "Phi";
00145
00146
00147 const std::vector<std::string>& nodeSetIDs = meshSpecs.nsNames;
00148
00149 Teuchos::ParameterList DBCparams = params->sublist("Dirichlet BCs");
00150 DBCparams.validateParameters(*(Albany::DirichletTraits::getValidBCParameters(nodeSetIDs,dirichletNames)),0);
00151
00152 map<string, RCP<ParameterList> > evaluators_to_build;
00153 RCP<DataLayout> dummy = rcp(new MDALayout<Dummy>(0));
00154 vector<string> dbcs;
00155
00156
00157 for (std::size_t i=0; i<nodeSetIDs.size(); i++) {
00158 for (std::size_t j=0; j<dirichletNames.size(); j++) {
00159
00160 std::stringstream sstrm; sstrm << "DBC on NS " << nodeSetIDs[i] << " for DOF " << dirichletNames[j];
00161 std::string ss = sstrm.str();
00162
00163 if (DBCparams.isParameter(ss)) {
00164 RCP<ParameterList> p = rcp(new ParameterList);
00165 int type = DirichletFactoryTraits<AlbanyTraits>::id_qcad_poisson_dirichlet;
00166 p->set<int>("Type", type);
00167
00168 p->set< RCP<DataLayout> >("Data Layout", dummy);
00169 p->set< string > ("Dirichlet Name", ss);
00170 p->set< RealType >("Dirichlet Value", DBCparams.get<double>(ss));
00171 p->set< string > ("Node Set ID", nodeSetIDs[i]);
00172 p->set< int > ("Number of Equations", dirichletNames.size());
00173 p->set< int > ("Equation Offset", j);
00174
00175 p->set<RCP<ParamLib> >("Parameter Library", paramLib);
00176
00178 Teuchos::ParameterList& paramList = params->sublist("Poisson Source");
00179 p->set<Teuchos::ParameterList*>("Poisson Source Parameter List", ¶mList);
00180
00181 p->set<double>("Temperature", temperature);
00182 p->set< RCP<QCAD::MaterialDatabase> >("MaterialDB", materialDB);
00183 p->set<double>("Energy unit in eV", energy_unit_in_eV);
00184
00185 std::stringstream ess; ess << "Evaluator for " << ss;
00186 evaluators_to_build[ess.str()] = p;
00187
00188 dbcs.push_back(ss);
00189 }
00190 }
00191 }
00192
00193
00194 string allDBC="Evaluator for all Dirichlet BCs";
00195 {
00196 RCP<ParameterList> p = rcp(new ParameterList);
00197 int type = DirichletFactoryTraits<AlbanyTraits>::id_dirichlet_aggregator;
00198 p->set<int>("Type", type);
00199
00200 p->set<vector<string>* >("DBC Names", &dbcs);
00201 p->set< RCP<DataLayout> >("Data Layout", dummy);
00202 p->set<string>("DBC Aggregator Name", allDBC);
00203 evaluators_to_build[allDBC] = p;
00204 }
00205
00206
00207 PHX::EvaluatorFactory<AlbanyTraits,DirichletFactoryTraits<AlbanyTraits> > factory;
00208 RCP< vector< RCP<PHX::Evaluator_TemplateManager<AlbanyTraits> > > > evaluators;
00209 evaluators = factory.buildEvaluators(evaluators_to_build);
00210
00211
00212 dfm = Teuchos::rcp(new PHX::FieldManager<AlbanyTraits>);
00213
00214
00215 PHX::registerEvaluators(evaluators, *dfm);
00216
00217 PHX::Tag<AlbanyTraits::Residual::ScalarT> res_tag0(allDBC, dummy);
00218 dfm->requireField<AlbanyTraits::Residual>(res_tag0);
00219
00220 PHX::Tag<AlbanyTraits::Jacobian::ScalarT> jac_tag0(allDBC, dummy);
00221 dfm->requireField<AlbanyTraits::Jacobian>(jac_tag0);
00222
00223 PHX::Tag<AlbanyTraits::Tangent::ScalarT> tan_tag0(allDBC, dummy);
00224 dfm->requireField<AlbanyTraits::Tangent>(tan_tag0);
00225
00226 #ifdef ALBANY_SG_MP
00227 PHX::Tag<AlbanyTraits::SGResidual::ScalarT> sgres_tag0(allDBC, dummy);
00228 dfm->requireField<AlbanyTraits::SGResidual>(sgres_tag0);
00229
00230 PHX::Tag<AlbanyTraits::SGJacobian::ScalarT> sgjac_tag0(allDBC, dummy);
00231 dfm->requireField<AlbanyTraits::SGJacobian>(sgjac_tag0);
00232
00233 PHX::Tag<AlbanyTraits::SGTangent::ScalarT> sgtan_tag0(allDBC, dummy);
00234 dfm->requireField<AlbanyTraits::SGTangent>(sgtan_tag0);
00235
00236 PHX::Tag<AlbanyTraits::MPResidual::ScalarT> mpres_tag0(allDBC, dummy);
00237 dfm->requireField<AlbanyTraits::MPResidual>(mpres_tag0);
00238
00239 PHX::Tag<AlbanyTraits::MPJacobian::ScalarT> mpjac_tag0(allDBC, dummy);
00240 dfm->requireField<AlbanyTraits::MPJacobian>(mpjac_tag0);
00241
00242 PHX::Tag<AlbanyTraits::MPTangent::ScalarT> mptan_tag0(allDBC, dummy);
00243 dfm->requireField<AlbanyTraits::MPTangent>(mptan_tag0);
00244 #endif //ALBANY_SG_MP
00245 }
00246
00247
00248 void
00249 QCAD::PoissonProblem::constructNeumannEvaluators(const Teuchos::RCP<Albany::MeshSpecsStruct>& meshSpecs)
00250 {
00251 using std::string;
00252
00253
00254
00255 Albany::BCUtils<Albany::NeumannTraits> bcUtils;
00256
00257
00258
00259 if(!bcUtils.haveBCSpecified(this->params))
00260
00261 return;
00262
00263
00264
00265 std::vector<string> bcNames(neq);
00266 Teuchos::ArrayRCP<string> dof_names(neq);
00267 Teuchos::Array<Teuchos::Array<int> > offsets;
00268 offsets.resize(neq);
00269
00270 bcNames[0] = "Phi";
00271 dof_names[0] = "Potential";
00272 offsets[0].resize(1);
00273 offsets[0][0] = 0;
00274
00275
00276
00277
00278 std::vector<string> condNames(4);
00279
00280
00281
00282 if(numDim == 2)
00283 condNames[0] = "(dudx, dudy)";
00284 else if(numDim == 3)
00285 condNames[0] = "(dudx, dudy, dudz)";
00286 else
00287 TEUCHOS_TEST_FOR_EXCEPTION(true, Teuchos::Exceptions::InvalidParameter,
00288 std::endl << "Error: Sidesets only supported in 2 and 3D." << std::endl);
00289
00290 condNames[1] = "dudn";
00291
00292 condNames[2] = "scaled jump";
00293
00294 condNames[3] = "robin";
00295
00296 nfm.resize(1);
00297
00298
00299
00300 bool isVectorField = false;
00301 int offsetToFirstDOF = 0;
00302
00303
00304
00305 using Teuchos::RCP;
00306 using Teuchos::rcp;
00307 using Teuchos::ParameterList;
00308 using PHX::DataLayout;
00309 using PHX::MDALayout;
00310 using std::vector;
00311
00312 using PHAL::NeumannFactoryTraits;
00313 using PHAL::AlbanyTraits;
00314
00315
00316 Teuchos::ParameterList BCparams = this->params->sublist(Albany::NeumannTraits::bcParamsPl);
00317 BCparams.validateParameters(*(Albany::NeumannTraits::getValidBCParameters(meshSpecs->ssNames, bcNames, condNames)),0);
00318
00319
00320 std::map<string, RCP<ParameterList> > evaluators_to_build;
00321 vector<string> bcs;
00322
00323
00324 for (std::size_t i=0; i<meshSpecs->ssNames.size(); i++) {
00325 for (std::size_t j=0; j<bcNames.size(); j++) {
00326 for (std::size_t k=0; k<condNames.size(); k++) {
00327
00328
00329
00330
00331
00332
00333
00334
00335 std::string ss = Albany::NeumannTraits::constructBCName(meshSpecs->ssNames[i], bcNames[j], condNames[k]);
00336
00337
00338
00339 if (BCparams.isParameter(ss)) {
00340
00341
00342
00343 TEUCHOS_TEST_FOR_EXCEPTION(BCparams.isType<string>(ss), std::logic_error,
00344 "NBC array information in XML file must be of type Array(double)\n");
00345
00346
00347
00348 RCP<ParameterList> p = rcp(new ParameterList);
00349
00350 int type = NeumannFactoryTraits<AlbanyTraits>::id_qcad_poisson_neumann;
00351 p->set<int> ("Type", type);
00352
00353 p->set<RCP<ParamLib> > ("Parameter Library", this->paramLib);
00354
00356 Teuchos::ParameterList& paramList = params->sublist("Poisson Source");
00357 p->set<Teuchos::ParameterList*>("Poisson Source Parameter List", ¶mList);
00358 p->set<double>("Temperature", temperature);
00359 p->set< RCP<QCAD::MaterialDatabase> >("MaterialDB", materialDB);
00360 p->set<double>("Energy unit in eV", energy_unit_in_eV);
00361
00362 p->set<string> ("Side Set ID", meshSpecs->ssNames[i]);
00363 p->set<Teuchos::Array< int > > ("Equation Offset", offsets[j]);
00364 p->set< RCP<Albany::Layouts> > ("Layouts Struct", dl);
00365 p->set< RCP<Albany::MeshSpecsStruct> > ("Mesh Specs Struct", meshSpecs);
00366
00367 p->set<string> ("Coordinate Vector Name", "Coord Vec");
00368
00369 if(condNames[k] == "robin") {
00370 p->set<string> ("DOF Name", dof_names[j]);
00371 p->set<bool> ("Vector Field", isVectorField);
00372 if (isVectorField) {p->set< RCP<DataLayout> >("DOF Data Layout", dl->node_vector);}
00373 else p->set< RCP<DataLayout> >("DOF Data Layout", dl->node_scalar);
00374 }
00375 else if(condNames[k] == "basal") {
00376 std::string betaName = BCparams.get("BetaXY", "Constant");
00377 double L = BCparams.get("L", 1.0);
00378 p->set<string> ("BetaXY", betaName);
00379 p->set<double> ("L", L);
00380 p->set<string> ("DOF Name", dof_names[0]);
00381 p->set<bool> ("Vector Field", isVectorField);
00382 if (isVectorField) {p->set< RCP<DataLayout> >("DOF Data Layout", dl->node_vector);}
00383 else p->set< RCP<DataLayout> >("DOF Data Layout", dl->node_scalar);
00384 }
00385
00386
00387 p->set< string > ("Neumann Input String", ss);
00388 p->set< Teuchos::Array<double> > ("Neumann Input Value", BCparams.get<Teuchos::Array<double> >(ss));
00389 p->set< string > ("Neumann Input Conditions", condNames[k]);
00390
00391
00392
00393
00394 if(condNames[k] == "scaled jump" || condNames[k] == "robin"){
00395
00396 TEUCHOS_TEST_FOR_EXCEPTION(materialDB == Teuchos::null,
00397 Teuchos::Exceptions::InvalidParameter,
00398 "This BC needs a material database specified");
00399
00400 p->set< RCP<QCAD::MaterialDatabase> >("MaterialDB", materialDB);
00401
00402
00403 }
00404
00405
00406
00407
00408
00409 std::stringstream ess; ess << "Evaluator for " << ss;
00410 evaluators_to_build[ess.str()] = p;
00411
00412
00413 bcs.push_back(ss);
00414 }
00415 }
00416 }
00417 }
00418
00419
00420
00421 string NeuGCV="Evaluator for Gather Coordinate Vector";
00422 {
00423 RCP<ParameterList> p = rcp(new ParameterList);
00424 p->set<int>("Type", Albany::NeumannTraits::typeGCV);
00425
00426
00427 p->set<bool>("Periodic BC", false);
00428
00429
00430 p->set< RCP<DataLayout> > ("Coordinate Data Layout", dl->vertices_vector);
00431 p->set< string >("Coordinate Vector Name", "Coord Vec");
00432
00433 evaluators_to_build[NeuGCV] = p;
00434 }
00435
00436
00437 string NeuGS="Evaluator for Gather Solution";
00438 {
00439 RCP<ParameterList> p = rcp(new ParameterList());
00440 p->set<int>("Type", Albany::NeumannTraits::typeGS);
00441
00442
00443 p->set< RCP<Albany::Layouts> >("Layouts Struct", dl);
00444
00445 p->set< Teuchos::ArrayRCP<std::string> >("Solution Names", dof_names);
00446
00447 p->set<bool>("Vector Field", isVectorField);
00448 if (isVectorField) p->set< RCP<DataLayout> >("Data Layout", dl->node_vector);
00449 else p->set< RCP<DataLayout> >("Data Layout", dl->node_scalar);
00450
00451 p->set<int>("Offset of First DOF", offsetToFirstDOF);
00452 p->set<bool>("Disable Transient", true);
00453
00454 evaluators_to_build[NeuGS] = p;
00455 }
00456
00457
00458
00459 string allBC="Evaluator for all Neumann BCs";
00460 {
00461 RCP<ParameterList> p = rcp(new ParameterList);
00462 p->set<int>("Type", Albany::NeumannTraits::typeNa);
00463
00464 p->set<vector<string>* >("NBC Names", &bcs);
00465 p->set< RCP<DataLayout> >("Data Layout", dl->dummy);
00466 p->set<string>("NBC Aggregator Name", allBC);
00467 evaluators_to_build[allBC] = p;
00468 }
00469
00470
00471
00472
00473
00474
00475 PHX::EvaluatorFactory<AlbanyTraits,PHAL::NeumannFactoryTraits<AlbanyTraits> > factory;
00476 RCP< vector< RCP<PHX::Evaluator_TemplateManager<AlbanyTraits> > > > evaluators;
00477 evaluators = factory.buildEvaluators(evaluators_to_build);
00478
00479
00480 Teuchos::RCP<PHX::FieldManager<AlbanyTraits> > fm
00481 = Teuchos::rcp(new PHX::FieldManager<AlbanyTraits>);
00482
00483
00484 PHX::registerEvaluators(evaluators, *fm);
00485
00486 PHX::Tag<AlbanyTraits::Residual::ScalarT> res_tag0(allBC, dl->dummy);
00487 fm->requireField<AlbanyTraits::Residual>(res_tag0);
00488
00489 PHX::Tag<AlbanyTraits::Jacobian::ScalarT> jac_tag0(allBC, dl->dummy);
00490 fm->requireField<AlbanyTraits::Jacobian>(jac_tag0);
00491
00492 PHX::Tag<AlbanyTraits::Tangent::ScalarT> tan_tag0(allBC, dl->dummy);
00493 fm->requireField<AlbanyTraits::Tangent>(tan_tag0);
00494
00495 #ifdef ALBANY_SG_MP
00496 PHX::Tag<AlbanyTraits::SGResidual::ScalarT> sgres_tag0(allBC, dl->dummy);
00497 fm->requireField<AlbanyTraits::SGResidual>(sgres_tag0);
00498
00499 PHX::Tag<AlbanyTraits::SGJacobian::ScalarT> sgjac_tag0(allBC, dl->dummy);
00500 fm->requireField<AlbanyTraits::SGJacobian>(sgjac_tag0);
00501
00502 PHX::Tag<AlbanyTraits::SGTangent::ScalarT> sgtan_tag0(allBC, dl->dummy);
00503 fm->requireField<AlbanyTraits::SGTangent>(sgtan_tag0);
00504
00505 PHX::Tag<AlbanyTraits::MPResidual::ScalarT> mpres_tag0(allBC, dl->dummy);
00506 fm->requireField<AlbanyTraits::MPResidual>(mpres_tag0);
00507
00508 PHX::Tag<AlbanyTraits::MPJacobian::ScalarT> mpjac_tag0(allBC, dl->dummy);
00509 fm->requireField<AlbanyTraits::MPJacobian>(mpjac_tag0);
00510
00511 PHX::Tag<AlbanyTraits::MPTangent::ScalarT> mptan_tag0(allBC, dl->dummy);
00512 fm->requireField<AlbanyTraits::MPTangent>(mptan_tag0);
00513 #endif //ALBANY_SG_MP
00514
00515 nfm[0] = fm;
00516 }
00517
00518 Teuchos::RCP<const Teuchos::ParameterList>
00519 QCAD::PoissonProblem::getValidProblemParameters() const
00520 {
00521 Teuchos::RCP<Teuchos::ParameterList> validPL =
00522 this->getGenericProblemParams("ValidPoissonProblemParams");
00523
00524 if (numDim==1)
00525 validPL->set<bool>("Periodic BC", false, "Flag to indicate periodic BC for 1D problems");
00526 validPL->sublist("Permittivity", false, "");
00527 validPL->sublist("Poisson Source", false, "");
00528 validPL->set<double>("Length Unit In Meters",1e-6,"Length unit in meters");
00529 validPL->set<double>("Energy Unit In Electron Volts",1.0,"Energy (voltage) unit in electron volts for output values only (e.g. DBCs are still in volts)");
00530 validPL->set<double>("Temperature",300,"Temperature in Kelvin");
00531 validPL->set<std::string>("MaterialDB Filename","materials.xml","Filename of material database xml file");
00532
00533
00534
00535
00536
00537
00538 validPL->sublist("Dummy Dirichlet BCs", false, "");
00539 validPL->sublist("Dummy Parameters", false, "");
00540
00541 return validPL;
00542 }
00543