Panzer Version of the Day
Loading...
Searching...
No Matches
Panzer_STK_ModelEvaluatorFactory_impl.hpp
Go to the documentation of this file.
1// @HEADER
2// *****************************************************************************
3// Panzer: A partial differential equation assembly
4// engine for strongly coupled complex multiphysics systems
5//
6// Copyright 2011 NTESS and the Panzer contributors.
7// SPDX-License-Identifier: BSD-3-Clause
8// *****************************************************************************
9// @HEADER
10
11#ifndef PANZER_STK_MODEL_EVALUATOR_FACTORY_T_HPP
12#define PANZER_STK_MODEL_EVALUATOR_FACTORY_T_HPP
13
14#include "Thyra_ModelEvaluator.hpp"
15#include "Teuchos_Assert.hpp"
16#include "Teuchos_as.hpp"
17#include "Teuchos_DefaultMpiComm.hpp"
18#include "Teuchos_AbstractFactoryStd.hpp"
19
20#include "PanzerAdaptersSTK_config.hpp"
21#include "Panzer_Traits.hpp"
22#include "Panzer_GlobalData.hpp"
23#include "Panzer_BC.hpp"
26#include "Panzer_DOFManager.hpp"
31#include "Panzer_TpetraLinearObjFactory.hpp"
42
57#ifdef PANZER_HAVE_TEMPUS
59#endif
63#include "Panzer_ClosureModel_Factory_Composite.hpp"
67
68#include <vector>
69#include <iostream>
70#include <fstream>
71#include <cstdlib> // for std::getenv
72
73// Piro solver objects
74#include "Piro_ConfigDefs.hpp"
75#include "Piro_NOXSolver.hpp"
76#include "Piro_LOCASolver.hpp"
77#ifdef PANZER_HAVE_TEMPUS
78#include "Piro_TempusSolverForwardOnly.hpp"
79#endif
80
81#ifdef PANZER_HAVE_EPETRA_STACK
83#include "Thyra_EpetraModelEvaluator.hpp"
86#endif
87
88#include <Panzer_NodeType.hpp>
89
90namespace panzer_stk {
91
92 template<typename ScalarT>
93 void ModelEvaluatorFactory<ScalarT>::setParameterList(Teuchos::RCP<Teuchos::ParameterList> const& paramList)
94 {
95 paramList->validateParametersAndSetDefaults(*this->getValidParameters());
96
97 // add in some addtional defaults that are hard to validate externally (this is because of the "disableRecursiveValidation" calls)
98
99 if(!paramList->sublist("Initial Conditions").isType<bool>("Zero Initial Conditions"))
100 paramList->sublist("Initial Conditions").set<bool>("Zero Initial Conditions",false);
101
102 paramList->sublist("Initial Conditions").sublist("Vector File").validateParametersAndSetDefaults(
103 getValidParameters()->sublist("Initial Conditions").sublist("Vector File"));
104
105 this->setMyParamList(paramList);
106 }
107
108 template<typename ScalarT>
109 void ModelEvaluatorFactory<ScalarT>::setStratimikosList(const Teuchos::RCP<Teuchos::ParameterList>& paramList)
110 {
111 m_stratimikos_params = paramList;
112 }
113
114 template<typename ScalarT>
115 Teuchos::RCP<const Teuchos::ParameterList> ModelEvaluatorFactory<ScalarT>::getValidParameters() const
116 {
117 static Teuchos::RCP<const Teuchos::ParameterList> validPL;
118 if (is_null(validPL)) {
119 Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::rcp(new Teuchos::ParameterList());
120
121 pl->sublist("Physics Blocks").disableRecursiveValidation();
122 pl->sublist("Closure Models").disableRecursiveValidation();
123 pl->sublist("Boundary Conditions").disableRecursiveValidation();
124 pl->sublist("Solution Control").disableRecursiveValidation();
125 pl->set<bool>("Use Discrete Adjoint",false);
126
127 pl->sublist("Mesh").disableRecursiveValidation();
128
129 pl->sublist("Initial Conditions").set<bool>("Zero Initial Conditions",false);
130 pl->sublist("Initial Conditions").sublist("Transient Parameters").disableRecursiveValidation();
131 pl->sublist("Initial Conditions").sublist("Vector File");
132 pl->sublist("Initial Conditions").sublist("Vector File").set("File Name","");
133 pl->sublist("Initial Conditions").sublist("Vector File").set<bool>("Enabled",false);
134 pl->sublist("Initial Conditions").disableRecursiveValidation();
135
136 pl->sublist("Output").set("File Name","panzer.exo");
137 pl->sublist("Output").set("Write to Exodus",true);
138 pl->sublist("Output").sublist("Cell Average Quantities").disableRecursiveValidation();
139 pl->sublist("Output").sublist("Cell Quantities").disableRecursiveValidation();
140 pl->sublist("Output").sublist("Cell Average Vectors").disableRecursiveValidation();
141 pl->sublist("Output").sublist("Nodal Quantities").disableRecursiveValidation();
142 pl->sublist("Output").sublist("Allocate Nodal Quantities").disableRecursiveValidation();
143
144 // Assembly sublist
145 {
146 Teuchos::ParameterList& p = pl->sublist("Assembly");
147 p.set<int>("Workset Size", 1);
148 p.set<int>("Default Integration Order",-1);
149 p.set<std::string>("Field Order","");
150 p.set<std::string>("Auxiliary Field Order","");
151 p.set<bool>("Use DOFManager FEI",false);
152 p.set<bool>("Load Balance DOFs",false);
153 p.set<bool>("Use Tpetra",false);
154 p.set<bool>("Use Epetra ME",true);
155 p.set<bool>("Lump Explicit Mass",false);
156 p.set<bool>("Constant Mass Matrix",true);
157 p.set<bool>("Apply Mass Matrix Inverse in Explicit Evaluator",true);
158 p.set<bool>("Use Conservative IMEX",false);
159 p.set<bool>("Compute Real Time Derivative",false);
160 p.set<bool>("Use Time Derivative in Explicit Model",false);
161 p.set<bool>("Compute Time Derivative at Time Step",false);
162 p.set<Teuchos::RCP<const panzer::EquationSetFactory> >("Equation Set Factory", Teuchos::null);
163 p.set<Teuchos::RCP<const panzer::ClosureModelFactory_TemplateManager<panzer::Traits> > >("Closure Model Factory", Teuchos::null);
164 p.set<Teuchos::RCP<const panzer::BCStrategyFactory> >("BC Factory",Teuchos::null);
165 p.set<std::string>("Excluded Blocks","");
166 p.sublist("ALE").disableRecursiveValidation();
167 }
168
169 pl->sublist("Block ID to Physics ID Mapping").disableRecursiveValidation();
170 pl->sublist("Options").disableRecursiveValidation();
171 pl->sublist("Active Parameters").disableRecursiveValidation();
172 pl->sublist("Controls").disableRecursiveValidation();
173 pl->sublist("ALE").disableRecursiveValidation(); // this sucks
174 pl->sublist("User Data").disableRecursiveValidation();
175 pl->sublist("User Data").sublist("Panzer Data").disableRecursiveValidation();
176
177 validPL = pl;
178 }
179 return validPL;
180 }
181
182 namespace {
183 bool hasInterfaceCondition(const std::vector<panzer::BC>& bcs)
184 {
185 for (std::vector<panzer::BC>::const_iterator bcit = bcs.begin(); bcit != bcs.end(); ++bcit)
186 if (bcit->bcType() == panzer::BCT_Interface)
187 return true;
188 return false;
189 }
190
191 Teuchos::RCP<STKConnManager>
192 getSTKConnManager(const Teuchos::RCP<panzer::ConnManager>& conn_mgr)
193 {
194 const Teuchos::RCP<STKConnManager> stk_conn_mgr =
195 Teuchos::rcp_dynamic_cast<STKConnManager>(conn_mgr);
196 TEUCHOS_TEST_FOR_EXCEPTION(stk_conn_mgr.is_null(), std::logic_error,
197 "There are interface conditions, but the connection manager"
198 " does not support the necessary connections.");
199 return stk_conn_mgr;
200 }
201
202 void buildInterfaceConnections(const std::vector<panzer::BC>& bcs,
203 const Teuchos::RCP<panzer::ConnManager>& conn_mgr)
204 {
205 const Teuchos::RCP<STKConnManager> stk_conn_mgr = getSTKConnManager(conn_mgr);
206 for (std::vector<panzer::BC>::const_iterator bcit = bcs.begin(); bcit != bcs.end(); ++bcit)
207 if (bcit->bcType() == panzer::BCT_Interface)
208 stk_conn_mgr->associateElementsInSideset(bcit->sidesetID());
209 }
210
211 void checkInterfaceConnections(const Teuchos::RCP<panzer::ConnManager>& conn_mgr,
212 const Teuchos::RCP<Teuchos::Comm<int> >& comm)
213 {
214 const Teuchos::RCP<STKConnManager> stk_conn_mgr = getSTKConnManager(conn_mgr);
215 std::vector<std::string> sidesets = stk_conn_mgr->checkAssociateElementsInSidesets(*comm);
216 if ( ! sidesets.empty()) {
217 std::stringstream ss;
218 ss << "Sideset IDs";
219 for (std::size_t i = 0; i < sidesets.size(); ++i)
220 ss << " " << sidesets[i];
221 ss << " did not yield associations, but these sidesets correspond to BCT_Interface BCs.";
222 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, ss.str());
223 }
224 }
225 } // namespace
226
227 template<typename ScalarT>
228 void ModelEvaluatorFactory<ScalarT>::buildObjects(const Teuchos::RCP<const Teuchos::Comm<int> >& comm,
229 const Teuchos::RCP<panzer::GlobalData>& global_data,
230 const Teuchos::RCP<const panzer::EquationSetFactory>& eqset_factory,
231 const panzer::BCStrategyFactory & bc_factory,
233 bool meConstructionOn)
234 {
235 TEUCHOS_TEST_FOR_EXCEPTION(Teuchos::is_null(this->getParameterList()), std::runtime_error,
236 "ParameterList must be set before objects can be built!");
237
238 TEUCHOS_ASSERT(nonnull(comm));
239 TEUCHOS_ASSERT(nonnull(global_data));
240 TEUCHOS_ASSERT(nonnull(global_data->os));
241 TEUCHOS_ASSERT(nonnull(global_data->pl));
242
243 // begin at the beginning...
244 m_global_data = global_data;
245
248 // Parse input file, setup parameters
251
252 // this function will need to be broken up eventually and probably
253 // have parts moved back into panzer. Just need to get something
254 // running.
255
256 Teuchos::ParameterList& p = *this->getNonconstParameterList();
257
258 // "parse" parameter list
259 Teuchos::ParameterList & mesh_params = p.sublist("Mesh");
260 Teuchos::ParameterList & assembly_params = p.sublist("Assembly");
261 Teuchos::ParameterList & solncntl_params = p.sublist("Solution Control");
262 Teuchos::ParameterList & output_list = p.sublist("Output");
263
264 Teuchos::ParameterList & user_data_params = p.sublist("User Data");
265 Teuchos::ParameterList & panzer_data_params = user_data_params.sublist("Panzer Data");
266
267 Teuchos::RCP<Teuchos::ParameterList> physics_block_plist = Teuchos::sublist(this->getMyNonconstParamList(),"Physics Blocks");
268
269 // extract assembly information
270 std::size_t workset_size = Teuchos::as<std::size_t>(assembly_params.get<int>("Workset Size"));
271 std::string field_order = assembly_params.get<std::string>("Field Order"); // control nodal ordering of unknown
272 // global IDs in linear system
273 bool use_dofmanager_fei = assembly_params.get<bool>("Use DOFManager FEI"); // use FEI if true, otherwise use internal dof manager
274 bool use_load_balance = assembly_params.get<bool>("Load Balance DOFs");
275 bool useTpetra = assembly_params.get<bool>("Use Tpetra");
276 bool useThyraME = !assembly_params.get<bool>("Use Epetra ME");
277
278 // this is weird...we are accessing the solution control to determine if things are transient
279 // it is backwards!
280 bool is_transient = (solncntl_params.get<std::string>("Piro Solver") == "Tempus") ? true : false;
281 // for pseudo-transient, we need to enable transient solver support to get time derivatives into fill
282 if (solncntl_params.get<std::string>("Piro Solver") == "NOX") {
283 if (solncntl_params.sublist("NOX").get<std::string>("Nonlinear Solver") == "Pseudo-Transient")
284 is_transient = true;
285 }
286 // for eigenvalues, we need to enable transient solver support to
287 // get time derivatives into generalized eigenvale problem
288 if (solncntl_params.get<std::string>("Piro Solver") == "LOCA") {
289 if (solncntl_params.sublist("LOCA").sublist("Stepper").get<bool>("Compute Eigenvalues"))
290 is_transient = true;
291 }
292 m_is_transient = is_transient;
293
294 useDiscreteAdjoint = p.get<bool>("Use Discrete Adjoint");
295
298 // Do stuff
301
302 Teuchos::FancyOStream& fout = *global_data->os;
303
304 // for convience cast to an MPI comm
305 const Teuchos::RCP<const Teuchos::MpiComm<int> > mpi_comm =
306 Teuchos::rcp_dynamic_cast<const Teuchos::MpiComm<int> >(comm);
307
308 // Build mesh factory and uncommitted mesh
310
311 Teuchos::RCP<panzer_stk::STK_MeshFactory> mesh_factory = this->buildSTKMeshFactory(mesh_params);
312 Teuchos::RCP<panzer_stk::STK_Interface> mesh = mesh_factory->buildUncommitedMesh(*(mpi_comm->getRawMpiComm()));
313 m_mesh = mesh;
314
315 m_eqset_factory = eqset_factory;
316
317 // setup the physcs blocks
319
320 std::vector<Teuchos::RCP<panzer::PhysicsBlock> > physicsBlocks;
321 {
322 // setup physical mappings and boundary conditions
323 std::map<std::string,std::string> block_ids_to_physics_ids;
324 panzer::buildBlockIdToPhysicsIdMap(block_ids_to_physics_ids, p.sublist("Block ID to Physics ID Mapping"));
325
326 // build cell ( block id -> cell topology ) mapping
327 std::map<std::string,Teuchos::RCP<const shards::CellTopology> > block_ids_to_cell_topo;
328 for(std::map<std::string,std::string>::const_iterator itr=block_ids_to_physics_ids.begin();
329 itr!=block_ids_to_physics_ids.end();++itr) {
330 block_ids_to_cell_topo[itr->first] = mesh->getCellTopology(itr->first);
331 TEUCHOS_ASSERT(block_ids_to_cell_topo[itr->first]!=Teuchos::null);
332 }
333
334 // build physics blocks
335
336 panzer::buildPhysicsBlocks(block_ids_to_physics_ids,
337 block_ids_to_cell_topo,
338 physics_block_plist,
339 assembly_params.get<int>("Default Integration Order"),
340 workset_size,
341 eqset_factory,
342 global_data,
343 is_transient,
344 physicsBlocks);
345 m_physics_blocks = physicsBlocks; // hold onto physics blocks for safe keeping
346 }
347
348 // add fields automatically written through the closure model
350 addUserFieldsToMesh(*mesh,output_list);
351
352 // finish building mesh, set required field variables and mesh bulk data
354
355 try {
356 // this throws some exceptions, catch them as neccessary
357 this->finalizeMeshConstruction(*mesh_factory,physicsBlocks,*mpi_comm,*mesh);
359 fout << "*****************************************\n\n";
360 fout << "Element block exception, could not finalize the mesh, printing block and sideset information:\n";
361 fout.pushTab(3);
362 mesh->printMetaData(fout);
363 fout.popTab();
364 fout << std::endl;
365
366 throw ebexp;
367 } catch(const panzer_stk::STK_Interface::SidesetException & ssexp) {
368 fout << "*****************************************\n\n";
369 fout << "Sideset exception, could not finalize the mesh, printing block and sideset information:\n";
370 fout.pushTab(3);
371 mesh->printMetaData(fout);
372 fout.popTab();
373 fout << std::endl;
374
375 throw ssexp;
376 }
377
378 mesh->print(fout);
379 if(p.sublist("Output").get<bool>("Write to Exodus"))
380 mesh->setupExodusFile(p.sublist("Output").get<std::string>("File Name"));
381
382 // Register the mesh with the closure model factories (recursive for composite factories)
384 p.sublist("User Data").set("panzer_stk::STK_Interface",mesh);
385 this->registerMeshWithClosureModelFactories(mesh,const_cast<panzer::ClosureModelFactory_TemplateManager<panzer::Traits>&>(user_cm_factory));
386
387 // build a workset factory that depends on STK
389 Teuchos::RCP<panzer_stk::WorksetFactory> wkstFactory;
390 if(m_user_wkst_factory==Teuchos::null)
391 wkstFactory = Teuchos::rcp(new panzer_stk::WorksetFactory()); // build STK workset factory
392 else
393 wkstFactory = m_user_wkst_factory;
394
395 // set workset factory mesh
396 wkstFactory->setMesh(mesh);
397
398 // handle boundary and interface conditions
400 std::vector<panzer::BC> bcs;
401 panzer::buildBCs(bcs, p.sublist("Boundary Conditions"), global_data);
402
403 // build the connection manager
405 Teuchos::RCP<panzer::ConnManager> conn_manager = Teuchos::rcp(new panzer_stk::STKConnManager(mesh));
406 m_conn_manager = conn_manager;
407
408 // build DOF Manager
410
411 Teuchos::RCP<panzer::LinearObjFactory<panzer::Traits> > linObjFactory;
412 Teuchos::RCP<panzer::GlobalIndexer> globalIndexer;
413
414 std::string loadBalanceString = ""; // what is the load balancing information
415 bool blockedAssembly = false;
416
417 const bool has_interface_condition = hasInterfaceCondition(bcs);
418
419 if(panzer::BlockedDOFManagerFactory::requiresBlocking(field_order) && !useTpetra) {
420
421#ifdef PANZER_HAVE_EPETRA_STACK
422 // Can't yet handle interface conditions for this system
423 TEUCHOS_TEST_FOR_EXCEPTION(has_interface_condition,
424 Teuchos::Exceptions::InvalidParameter,
425 "ERROR: Blocked Epetra systems cannot handle interface conditions.");
426
427 // use a blocked DOF manager
428 blockedAssembly = true;
429
430 panzer::BlockedDOFManagerFactory globalIndexerFactory;
431 globalIndexerFactory.setUseDOFManagerFEI(use_dofmanager_fei);
432
433 Teuchos::RCP<panzer::GlobalIndexer> dofManager
434 = globalIndexerFactory.buildGlobalIndexer(mpi_comm->getRawMpiComm(),physicsBlocks,conn_manager,field_order);
435 globalIndexer = dofManager;
436
437 Teuchos::RCP<panzer::BlockedEpetraLinearObjFactory<panzer::Traits,int> > bloLinObjFactory
439 Teuchos::rcp_dynamic_cast<panzer::BlockedDOFManager>(dofManager)));
440
441 // parse any explicitly excluded pairs or blocks
442 const std::string excludedBlocks = assembly_params.get<std::string>("Excluded Blocks");
443 std::vector<std::string> stringPairs;
444 panzer::StringTokenizer(stringPairs,excludedBlocks,";",true);
445 for(std::size_t i=0;i<stringPairs.size();i++) {
446 std::vector<std::string> sPair;
447 std::vector<int> iPair;
448 panzer::StringTokenizer(sPair,stringPairs[i],",",true);
449 panzer::TokensToInts(iPair,sPair);
450
451 TEUCHOS_TEST_FOR_EXCEPTION(iPair.size()!=2,std::logic_error,
452 "Input Error: The correct format for \"Excluded Blocks\" parameter in \"Assembly\" sub list is:\n"
453 " <int>,<int>; <int>,<int>; ...; <int>,<int>\n"
454 "Failure on string pair " << stringPairs[i] << "!");
455
456 bloLinObjFactory->addExcludedPair(iPair[0],iPair[1]);
457 }
458
459 linObjFactory = bloLinObjFactory;
460
461 // build load balancing string for informative output
462 loadBalanceString = printUGILoadBalancingInformation(*dofManager);
463#else
464 TEUCHOS_TEST_FOR_EXCEPTION(true,std::runtime_error,"ERROR: buildObjects() - Epetra support is NOT enabled in this build!");
465#endif
466 }
467 else if(panzer::BlockedDOFManagerFactory::requiresBlocking(field_order) && useTpetra) {
468
469 // Can't yet handle interface conditions for this system
470 TEUCHOS_TEST_FOR_EXCEPTION(has_interface_condition,
471 Teuchos::Exceptions::InvalidParameter,
472 "ERROR: Blocked Tpetra system cannot handle interface conditions.");
473
474 // use a blocked DOF manager
475 blockedAssembly = true;
476
477 TEUCHOS_ASSERT(!use_dofmanager_fei);
478 panzer::BlockedDOFManagerFactory globalIndexerFactory;
479 globalIndexerFactory.setUseDOFManagerFEI(false);
480
481 Teuchos::RCP<panzer::GlobalIndexer> dofManager
482 = globalIndexerFactory.buildGlobalIndexer(mpi_comm->getRawMpiComm(),physicsBlocks,conn_manager,field_order);
483 globalIndexer = dofManager;
484
485 Teuchos::RCP<panzer::BlockedTpetraLinearObjFactory<panzer::Traits,double,int,panzer::GlobalOrdinal> > bloLinObjFactory
487 Teuchos::rcp_dynamic_cast<panzer::BlockedDOFManager>(dofManager)));
488
489 // parse any explicitly excluded pairs or blocks
490 const std::string excludedBlocks = assembly_params.get<std::string>("Excluded Blocks");
491 std::vector<std::string> stringPairs;
492 panzer::StringTokenizer(stringPairs,excludedBlocks,";",true);
493 for(std::size_t i=0;i<stringPairs.size();i++) {
494 std::vector<std::string> sPair;
495 std::vector<int> iPair;
496 panzer::StringTokenizer(sPair,stringPairs[i],",",true);
497 panzer::TokensToInts(iPair,sPair);
498
499 TEUCHOS_TEST_FOR_EXCEPTION(iPair.size()!=2,std::logic_error,
500 "Input Error: The correct format for \"Excluded Blocks\" parameter in \"Assembly\" sub list is:\n"
501 " <int>,<int>; <int>,<int>; ...; <int>,<int>\n"
502 "Failure on string pair " << stringPairs[i] << "!");
503
504 bloLinObjFactory->addExcludedPair(iPair[0],iPair[1]);
505 }
506
507 linObjFactory = bloLinObjFactory;
508
509 // build load balancing string for informative output
510 loadBalanceString = printUGILoadBalancingInformation(*dofManager);
511 }
512 else if(useTpetra) {
513
514 if (has_interface_condition)
515 buildInterfaceConnections(bcs, conn_manager);
516
517 // use a flat DOF manager
518
519 TEUCHOS_ASSERT(!use_dofmanager_fei);
520 panzer::DOFManagerFactory globalIndexerFactory;
521 globalIndexerFactory.setUseDOFManagerFEI(false);
522 globalIndexerFactory.setUseTieBreak(use_load_balance);
523 Teuchos::RCP<panzer::GlobalIndexer> dofManager
524 = globalIndexerFactory.buildGlobalIndexer(mpi_comm->getRawMpiComm(),physicsBlocks,conn_manager,field_order);
525 globalIndexer = dofManager;
526
527 if (has_interface_condition)
528 checkInterfaceConnections(conn_manager, dofManager->getComm());
529
530 TEUCHOS_ASSERT(!useDiscreteAdjoint); // safety check
531 linObjFactory = Teuchos::rcp(new panzer::TpetraLinearObjFactory<panzer::Traits,double,int,panzer::GlobalOrdinal>(mpi_comm,dofManager));
532
533 // build load balancing string for informative output
534 loadBalanceString = printUGILoadBalancingInformation(*dofManager);
535 }
536 else {
537
538#ifdef PANZER_HAVE_EPETRA_STACK
539 if (has_interface_condition)
540 buildInterfaceConnections(bcs, conn_manager);
541
542 // use a flat DOF manager
543 panzer::DOFManagerFactory globalIndexerFactory;
544 globalIndexerFactory.setUseDOFManagerFEI(use_dofmanager_fei);
545 globalIndexerFactory.setUseTieBreak(use_load_balance);
546 globalIndexerFactory.setUseNeighbors(has_interface_condition);
547 Teuchos::RCP<panzer::GlobalIndexer> dofManager
548 = globalIndexerFactory.buildGlobalIndexer(mpi_comm->getRawMpiComm(),physicsBlocks,conn_manager,
549 field_order);
550 globalIndexer = dofManager;
551
552 if (has_interface_condition)
553 checkInterfaceConnections(conn_manager, dofManager->getComm());
554
555 linObjFactory = Teuchos::rcp(new panzer::BlockedEpetraLinearObjFactory<panzer::Traits,int>(mpi_comm,dofManager,useDiscreteAdjoint));
556
557 // build load balancing string for informative output
558 loadBalanceString = printUGILoadBalancingInformation(*dofManager);
559#else
560 TEUCHOS_TEST_FOR_EXCEPTION(true,std::runtime_error,"ERROR: buildObjects() - Epetra support is NOT enabled in this build!");
561#endif
562 }
563
564 TEUCHOS_ASSERT(globalIndexer!=Teuchos::null);
565 TEUCHOS_ASSERT(linObjFactory!=Teuchos::null);
566 m_global_indexer = globalIndexer;
567 m_lin_obj_factory = linObjFactory;
568 m_blockedAssembly = blockedAssembly;
569
570 // print out load balancing information
571 fout << "Degree of freedom load balancing: " << loadBalanceString << std::endl;
572
573 // build worksets
575
576 // build up needs array for workset container
577 std::map<std::string,panzer::WorksetNeeds> needs;
578 for(std::size_t i=0;i<physicsBlocks.size();i++)
579 needs[physicsBlocks[i]->elementBlockID()] = physicsBlocks[i]->getWorksetNeeds();
580
581 Teuchos::RCP<panzer::WorksetContainer> wkstContainer // attach it to a workset container (uses lazy evaluation)
582 = Teuchos::rcp(new panzer::WorksetContainer(wkstFactory,needs));
583
584 wkstContainer->setWorksetSize(workset_size);
585 wkstContainer->setGlobalIndexer(globalIndexer); // set the global indexer so the orientations are evaluated
586
587 m_wkstContainer = wkstContainer;
588
589 // find max number of worksets
590 std::size_t max_wksets = 0;
591 for(std::size_t pb=0;pb<physicsBlocks.size();pb++) {
592 const panzer::WorksetDescriptor wd = panzer::blockDescriptor(physicsBlocks[pb]->elementBlockID());
593 Teuchos::RCP< std::vector<panzer::Workset> >works = wkstContainer->getWorksets(wd);
594 max_wksets = std::max(max_wksets,works->size());
595 }
596 user_data_params.set<std::size_t>("Max Worksets",max_wksets);
597 wkstContainer->clear();
598
599 // Setup lagrangian type coordinates
601
602 // see if field coordinates are required, if so reset the workset container
603 // and set the coordinates to be associated with a field in the mesh
604 useDynamicCoordinates_ = false;
605 for(std::size_t pb=0;pb<physicsBlocks.size();pb++) {
606 if(physicsBlocks[pb]->getCoordinateDOFs().size()>0) {
607 mesh->setUseFieldCoordinates(true);
608 useDynamicCoordinates_ = true;
609 wkstContainer->clear(); // this serves to refresh the worksets
610 // and put in new coordinates
611 break;
612 }
613 }
614
615 // Add mesh objects to user data to make available to user ctors
617
618 panzer_data_params.set("STK Mesh", mesh);
619 panzer_data_params.set("DOF Manager", globalIndexer);
620 panzer_data_params.set("Linear Object Factory", linObjFactory);
621
622 // If user requested it, short circuit model construction
624
625 if(!meConstructionOn)
626 return;
627
628 // Setup active parameters
630
631 std::vector<Teuchos::RCP<Teuchos::Array<std::string> > > p_names;
632 std::vector<Teuchos::RCP<Teuchos::Array<double> > > p_values;
633 if (p.isSublist("Active Parameters")) {
634 Teuchos::ParameterList& active_params = p.sublist("Active Parameters");
635
636 int num_param_vecs = active_params.get<int>("Number of Parameter Vectors",0);
637 p_names.resize(num_param_vecs);
638 p_values.resize(num_param_vecs);
639 for (int i=0; i<num_param_vecs; i++) {
640 std::stringstream ss;
641 ss << "Parameter Vector " << i;
642 Teuchos::ParameterList& pList = active_params.sublist(ss.str());
643 int numParameters = pList.get<int>("Number");
644 TEUCHOS_TEST_FOR_EXCEPTION(numParameters == 0,
645 Teuchos::Exceptions::InvalidParameter,
646 std::endl << "Error! panzer::ModelEvaluator::ModelEvaluator(): " <<
647 "Parameter vector " << i << " has zero parameters!" << std::endl);
648 p_names[i] =
649 Teuchos::rcp(new Teuchos::Array<std::string>(numParameters));
650 p_values[i] =
651 Teuchos::rcp(new Teuchos::Array<double>(numParameters));
652 for (int j=0; j<numParameters; j++) {
653 std::stringstream ss2;
654 ss2 << "Parameter " << j;
655 (*p_names[i])[j] = pList.get<std::string>(ss2.str());
656 ss2.str("");
657
658 ss2 << "Initial Value " << j;
659 (*p_values[i])[j] = pList.get<double>(ss2.str());
660
661 // this is a band-aid/hack to make sure parameters are registered before they are accessed
662 panzer::registerScalarParameter((*p_names[i])[j],*global_data->pl,(*p_values[i])[j]);
663 }
664 }
665 }
666
667 // setup the closure model for automatic writing (during residual/jacobian update)
669
670 panzer_stk::IOClosureModelFactory_TemplateBuilder<panzer::Traits> io_cm_builder(user_cm_factory,mesh,output_list);
672 cm_factory.buildObjects(io_cm_builder);
673
674 // setup field manager build
676
677 Teuchos::RCP<panzer::FieldManagerBuilder> fmb;
678 {
679 bool write_dot_files = p.sublist("Options").get("Write Volume Assembly Graphs",false);
680 std::string dot_file_prefix = p.sublist("Options").get("Volume Assembly Graph Prefix","Panzer_AssemblyGraph");
681 bool write_fm_files = p.sublist("Options").get("Write Field Manager Files",false);
682 std::string fm_file_prefix = p.sublist("Options").get("Field Manager File Prefix","Panzer_AssemblyGraph");
683
684 // Allow users to override inputs via runtime env
685 {
686 auto check_write_dag = std::getenv("PANZER_WRITE_DAG");
687 if (check_write_dag != nullptr) {
688 write_dot_files = true;
689 write_fm_files = true;
690 }
691 }
692
693 fmb = buildFieldManagerBuilder(wkstContainer,physicsBlocks,bcs,*eqset_factory,bc_factory,cm_factory,
694 user_cm_factory,p.sublist("Closure Models"),*linObjFactory,user_data_params,
695 write_dot_files,dot_file_prefix,
696 write_fm_files,fm_file_prefix);
697 }
698
699 // build response library
701
702 m_response_library = Teuchos::rcp(new panzer::ResponseLibrary<panzer::Traits>(wkstContainer,globalIndexer,linObjFactory));
703
704 {
705 bool write_dot_files = false;
706 std::string prefix = "Panzer_ResponseGraph_";
707 write_dot_files = p.sublist("Options").get("Write Volume Response Graphs",write_dot_files);
708 prefix = p.sublist("Options").get("Volume Response Graph Prefix",prefix);
709
710 Teuchos::ParameterList user_data(p.sublist("User Data"));
711 user_data.set<int>("Workset Size",workset_size);
712 }
713
714 // Setup solver factory
716
717 Teuchos::RCP<Thyra::LinearOpWithSolveFactoryBase<double> > lowsFactory =
718 buildLOWSFactory(blockedAssembly,globalIndexer,conn_manager,mesh,mpi_comm);
719
720 // Setup physics model evaluator
722
723 double t_init = 0.0;
724 if(is_transient)
725 t_init = this->getInitialTime(p.sublist("Initial Conditions").sublist("Transient Parameters"), *mesh);
726
727 if(blockedAssembly || useTpetra) // override the user request
728 useThyraME = true;
729
730 Teuchos::RCP<Thyra::ModelEvaluatorDefaultBase<double> > thyra_me
731 = buildPhysicsModelEvaluator(useThyraME, // blockedAssembly || useTpetra, // this determines if a Thyra or Epetra ME is used
732 fmb,
733 m_response_library,
734 linObjFactory,
735 p_names,
736 p_values,
737 lowsFactory,
738 global_data,
739 is_transient,
740 t_init);
741
742 // Setup initial conditions
744
745 {
746 // Create closure model list for use in defining initial conditions
747 // For now just remove Global MMS Parameters, if it exists
748 const Teuchos::ParameterList& models = p.sublist("Closure Models");
749 Teuchos::ParameterList cl_models(models.name());
750 for (Teuchos::ParameterList::ConstIterator model_it=models.begin();
751 model_it!=models.end(); ++model_it) {
752 std::string key = model_it->first;
753 if (model_it->first != "Global MMS Parameters")
754 cl_models.setEntry(key,model_it->second);
755 }
756 bool write_dot_files = false;
757 std::string prefix = "Panzer_AssemblyGraph_";
758 setupInitialConditions(*thyra_me,*wkstContainer,physicsBlocks,user_cm_factory,*linObjFactory,
759 cl_models,
760 p.sublist("Initial Conditions"),
761 p.sublist("User Data"),
762 p.sublist("Options").get("Write Volume Assembly Graphs",write_dot_files),
763 p.sublist("Options").get("Volume Assembly Graph Prefix",prefix));
764 }
765
766 // Write the IC vector into the STK mesh: use response library
768 writeInitialConditions(*thyra_me,physicsBlocks,wkstContainer,globalIndexer,linObjFactory,mesh,user_cm_factory,
769 p.sublist("Closure Models"),
770 p.sublist("User Data"),workset_size);
771
772 m_physics_me = thyra_me;
773 }
774
775 template<typename ScalarT>
777 addUserFieldsToMesh(panzer_stk::STK_Interface & mesh,const Teuchos::ParameterList & output_list) const
778 {
779 // register cell averaged scalar fields
780 const Teuchos::ParameterList & cellAvgQuants = output_list.sublist("Cell Average Quantities");
781 for(Teuchos::ParameterList::ConstIterator itr=cellAvgQuants.begin();
782 itr!=cellAvgQuants.end();++itr) {
783 const std::string & blockId = itr->first;
784 const std::string & fields = Teuchos::any_cast<std::string>(itr->second.getAny());
785 std::vector<std::string> tokens;
786
787 // break up comma seperated fields
788 panzer::StringTokenizer(tokens,fields,",",true);
789
790 for(std::size_t i=0;i<tokens.size();i++)
791 mesh.addCellField(tokens[i],blockId);
792 }
793
794 // register cell averaged components of vector fields
795 // just allocate space for the fields here. The actual calculation and writing
796 // are done by panzer_stk::ScatterCellAvgVector.
797 const Teuchos::ParameterList & cellAvgVectors = output_list.sublist("Cell Average Vectors");
798 for(Teuchos::ParameterList::ConstIterator itr = cellAvgVectors.begin();
799 itr != cellAvgVectors.end(); ++itr) {
800 const std::string & blockId = itr->first;
801 const std::string & fields = Teuchos::any_cast<std::string>(itr->second.getAny());
802 std::vector<std::string> tokens;
803
804 // break up comma seperated fields
805 panzer::StringTokenizer(tokens,fields,",",true);
806
807 for(std::size_t i = 0; i < tokens.size(); i++) {
808 std::string d_mod[3] = {"X","Y","Z"};
809 for(std::size_t d = 0; d < mesh.getDimension(); d++)
810 mesh.addCellField(tokens[i]+d_mod[d],blockId);
811 }
812 }
813
814 // register cell quantities
815 const Teuchos::ParameterList & cellQuants = output_list.sublist("Cell Quantities");
816 for(Teuchos::ParameterList::ConstIterator itr=cellQuants.begin();
817 itr!=cellQuants.end();++itr) {
818 const std::string & blockId = itr->first;
819 const std::string & fields = Teuchos::any_cast<std::string>(itr->second.getAny());
820 std::vector<std::string> tokens;
821
822 // break up comma seperated fields
823 panzer::StringTokenizer(tokens,fields,",",true);
824
825 for(std::size_t i=0;i<tokens.size();i++)
826 mesh.addCellField(tokens[i],blockId);
827 }
828
829 // register ndoal quantities
830 const Teuchos::ParameterList & nodalQuants = output_list.sublist("Nodal Quantities");
831 for(Teuchos::ParameterList::ConstIterator itr=nodalQuants.begin();
832 itr!=nodalQuants.end();++itr) {
833 const std::string & blockId = itr->first;
834 const std::string & fields = Teuchos::any_cast<std::string>(itr->second.getAny());
835 std::vector<std::string> tokens;
836
837 // break up comma seperated fields
838 panzer::StringTokenizer(tokens,fields,",",true);
839
840 for(std::size_t i=0;i<tokens.size();i++)
841 mesh.addSolutionField(tokens[i],blockId);
842 }
843
844 const Teuchos::ParameterList & allocNodalQuants = output_list.sublist("Allocate Nodal Quantities");
845 for(Teuchos::ParameterList::ConstIterator itr=allocNodalQuants.begin();
846 itr!=allocNodalQuants.end();++itr) {
847 const std::string & blockId = itr->first;
848 const std::string & fields = Teuchos::any_cast<std::string>(itr->second.getAny());
849 std::vector<std::string> tokens;
850
851 // break up comma seperated fields
852 panzer::StringTokenizer(tokens,fields,",",true);
853
854 for(std::size_t i=0;i<tokens.size();i++)
855 mesh.addSolutionField(tokens[i],blockId);
856 }
857 }
858
859 template<typename ScalarT>
862 panzer::WorksetContainer & wkstContainer,
863 const std::vector<Teuchos::RCP<panzer::PhysicsBlock> >& physicsBlocks,
866 const Teuchos::ParameterList & closure_pl,
867 const Teuchos::ParameterList & initial_cond_pl,
868 const Teuchos::ParameterList & user_data_pl,
869 bool write_dot_files,const std::string & dot_file_prefix) const
870 {
871 using Teuchos::RCP;
872
873 Thyra::ModelEvaluatorBase::InArgs<double> nomValues = model.getNominalValues();
874 Teuchos::RCP<Thyra::VectorBase<double> > x_vec = Teuchos::rcp_const_cast<Thyra::VectorBase<double> >(nomValues.get_x());
875
876 if(initial_cond_pl.get<bool>("Zero Initial Conditions")) {
877 // zero out the x vector
878 Thyra::assign(x_vec.ptr(),0.0);
879 }
880 else if(!initial_cond_pl.sublist("Vector File").get<bool>("Enabled")) {
881 // read from exodus, or compute using field managers
882
883 std::map<std::string, Teuchos::RCP< PHX::FieldManager<panzer::Traits> > > phx_ic_field_managers;
884
886 physicsBlocks,
887 cm_factory,
888 closure_pl,
889 initial_cond_pl,
890 lof,
891 user_data_pl,
892 write_dot_files,
893 dot_file_prefix,
894 phx_ic_field_managers);
895/*
896 panzer::setupInitialConditionFieldManagers(wkstContainer,
897 physicsBlocks,
898 cm_factory,
899 initial_cond_pl,
900 lof,
901 user_data_pl,
902 write_dot_files,
903 dot_file_prefix,
904 phx_ic_field_managers);
905*/
906
907 // set the vector to be filled
908 Teuchos::RCP<panzer::LinearObjContainer> loc = lof.buildLinearObjContainer();
909 Teuchos::RCP<panzer::ThyraObjContainer<double> > tloc = Teuchos::rcp_dynamic_cast<panzer::ThyraObjContainer<double> >(loc);
910 tloc->set_x_th(x_vec);
911
912 panzer::evaluateInitialCondition(wkstContainer, phx_ic_field_managers, loc, lof, 0.0);
913 }
914 else {
915 const std::string & vectorFile = initial_cond_pl.sublist("Vector File").get<std::string>("File Name");
916 TEUCHOS_TEST_FOR_EXCEPTION(vectorFile=="",std::runtime_error,
917 "If \"Read From Vector File\" is true, then parameter \"Vector File\" cannot be the empty string.");
918
919 // set the vector to be filled
920 Teuchos::RCP<panzer::LinearObjContainer> loc = lof.buildLinearObjContainer();
921 Teuchos::RCP<panzer::ThyraObjContainer<double> > tloc = Teuchos::rcp_dynamic_cast<panzer::ThyraObjContainer<double> >(loc);
922 tloc->set_x_th(x_vec);
923
924 // read the vector
925 lof.readVector(vectorFile,*loc,panzer::LinearObjContainer::X);
926 }
927 }
928
929 template<typename ScalarT>
932 const std::vector<Teuchos::RCP<panzer::PhysicsBlock> >& physicsBlocks,
933 const Teuchos::RCP<panzer::WorksetContainer> & wc,
934 const Teuchos::RCP<const panzer::GlobalIndexer> & ugi,
935 const Teuchos::RCP<const panzer::LinearObjFactory<panzer::Traits> > & lof,
936 const Teuchos::RCP<panzer_stk::STK_Interface> & mesh,
938 const Teuchos::ParameterList & closure_model_pl,
939 const Teuchos::ParameterList & user_data_pl,
940 int workset_size) const
941 {
942 Teuchos::RCP<panzer::LinearObjContainer> loc = lof->buildLinearObjContainer();
943 Teuchos::RCP<panzer::ThyraObjContainer<double> > tloc = Teuchos::rcp_dynamic_cast<panzer::ThyraObjContainer<double> >(loc);
944 tloc->set_x_th(Teuchos::rcp_const_cast<Thyra::VectorBase<double> >(model.getNominalValues().get_x()));
945
946 Teuchos::RCP<panzer::ResponseLibrary<panzer::Traits> > solnWriter
947 = initializeSolnWriterResponseLibrary(wc,ugi,lof,mesh);
948
949 {
950 Teuchos::ParameterList user_data(user_data_pl);
951 user_data.set<int>("Workset Size",workset_size);
952
953 finalizeSolnWriterResponseLibrary(*solnWriter,physicsBlocks,cm_factory,closure_model_pl,workset_size,user_data);
954 }
955
956 // initialize the assembly container
958 ae_inargs.container_ = loc;
959 ae_inargs.ghostedContainer_ = lof->buildGhostedLinearObjContainer();
960 ae_inargs.alpha = 0.0;
961 ae_inargs.beta = 1.0;
962 ae_inargs.evaluate_transient_terms = false;
963
964 // initialize the ghosted container
965 lof->initializeGhostedContainer(panzer::LinearObjContainer::X,*ae_inargs.ghostedContainer_);
966
967 // do import
968 lof->globalToGhostContainer(*ae_inargs.container_,*ae_inargs.ghostedContainer_,panzer::LinearObjContainer::X);
969
970 // fill STK mesh objects
971 solnWriter->addResponsesToInArgs<panzer::Traits::Residual>(ae_inargs);
972 solnWriter->evaluate<panzer::Traits::Residual>(ae_inargs);
973 }
974
976 template<typename ScalarT>
977 Teuchos::RCP<panzer_stk::STK_MeshFactory> ModelEvaluatorFactory<ScalarT>::buildSTKMeshFactory(const Teuchos::ParameterList & mesh_params) const
978 {
979 Teuchos::RCP<panzer_stk::STK_MeshFactory> mesh_factory;
980
981 // first contruct the mesh factory
982 if (mesh_params.get<std::string>("Source") == "Exodus File") {
983 mesh_factory = Teuchos::rcp(new panzer_stk::STK_ExodusReaderFactory());
984 mesh_factory->setParameterList(Teuchos::rcp(new Teuchos::ParameterList(mesh_params.sublist("Exodus File"))));
985 }
986 else if (mesh_params.get<std::string>("Source") == "Pamgen Mesh") {
987 mesh_factory = Teuchos::rcp(new panzer_stk::STK_ExodusReaderFactory());
988 Teuchos::RCP<Teuchos::ParameterList> pamgenList = Teuchos::rcp(new Teuchos::ParameterList(mesh_params.sublist("Pamgen Mesh")));
989 pamgenList->set("File Type","Pamgen"); // For backwards compatibility when pamgen had separate factory from exodus
990 mesh_factory->setParameterList(pamgenList);
991 }
992 else if (mesh_params.get<std::string>("Source") == "Inline Mesh") {
993
994 int dimension = mesh_params.sublist("Inline Mesh").get<int>("Mesh Dimension");
995 std::string typeStr = "";
996 if(mesh_params.sublist("Inline Mesh").isParameter("Type"))
997 typeStr = mesh_params.sublist("Inline Mesh").get<std::string>("Type");
998
999 if (dimension == 1) {
1000 mesh_factory = Teuchos::rcp(new panzer_stk::LineMeshFactory);
1001 Teuchos::RCP<Teuchos::ParameterList> in_mesh = Teuchos::rcp(new Teuchos::ParameterList);
1002 *in_mesh = mesh_params.sublist("Inline Mesh").sublist("Mesh Factory Parameter List");
1003 mesh_factory->setParameterList(in_mesh);
1004 }
1005 else if (dimension == 2 && typeStr=="Tri") {
1006 mesh_factory = Teuchos::rcp(new panzer_stk::SquareTriMeshFactory);
1007 Teuchos::RCP<Teuchos::ParameterList> in_mesh = Teuchos::rcp(new Teuchos::ParameterList);
1008 *in_mesh = mesh_params.sublist("Inline Mesh").sublist("Mesh Factory Parameter List");
1009 mesh_factory->setParameterList(in_mesh);
1010 }
1011 else if (dimension == 2) {
1012 mesh_factory = Teuchos::rcp(new panzer_stk::SquareQuadMeshFactory);
1013 Teuchos::RCP<Teuchos::ParameterList> in_mesh = Teuchos::rcp(new Teuchos::ParameterList);
1014 *in_mesh = mesh_params.sublist("Inline Mesh").sublist("Mesh Factory Parameter List");
1015 mesh_factory->setParameterList(in_mesh);
1016 }
1017 else if (dimension == 3 && typeStr=="Tet") {
1018 mesh_factory = Teuchos::rcp(new panzer_stk::CubeTetMeshFactory);
1019 Teuchos::RCP<Teuchos::ParameterList> in_mesh = Teuchos::rcp(new Teuchos::ParameterList);
1020 *in_mesh = mesh_params.sublist("Inline Mesh").sublist("Mesh Factory Parameter List");
1021 mesh_factory->setParameterList(in_mesh);
1022 }
1023 else if(dimension == 3) {
1024 mesh_factory = Teuchos::rcp(new panzer_stk::CubeHexMeshFactory);
1025 Teuchos::RCP<Teuchos::ParameterList> in_mesh = Teuchos::rcp(new Teuchos::ParameterList);
1026 *in_mesh = mesh_params.sublist("Inline Mesh").sublist("Mesh Factory Parameter List");
1027 mesh_factory->setParameterList(in_mesh);
1028 }
1029 else if(dimension==4) { // not really "dimension==4" simply a flag to try this other mesh for testing
1030 mesh_factory = Teuchos::rcp(new panzer_stk::MultiBlockMeshFactory);
1031 Teuchos::RCP<Teuchos::ParameterList> in_mesh = Teuchos::rcp(new Teuchos::ParameterList);
1032 *in_mesh = mesh_params.sublist("Inline Mesh").sublist("Mesh Factory Parameter List");
1033 mesh_factory->setParameterList(in_mesh);
1034 }
1035 }
1036 else if (mesh_params.get<std::string>("Source") == "Custom Mesh") {
1037 mesh_factory = Teuchos::rcp(new panzer_stk::CustomMeshFactory());
1038 mesh_factory->setParameterList(Teuchos::rcp(new Teuchos::ParameterList(mesh_params.sublist("Custom Mesh"))));
1039 }
1040 else {
1041 // throw a runtime exception for invalid parameter values
1042 }
1043
1044
1045 // get rebalancing parameters
1046 if(mesh_params.isSublist("Rebalance")) {
1047 const Teuchos::ParameterList & rebalance = mesh_params.sublist("Rebalance");
1048
1049 // check to see if its enabled
1050 bool enabled = false;
1051 if(rebalance.isType<bool>("Enabled"))
1052 enabled = rebalance.get<bool>("Enabled");
1053
1054 // we can also use a list description of what to load balance
1055 Teuchos::RCP<Teuchos::ParameterList> rebalanceCycles;
1056 if(enabled && rebalance.isSublist("Cycles"))
1057 rebalanceCycles = Teuchos::rcp(new Teuchos::ParameterList(rebalance.sublist("Cycles")));
1058
1059 // setup rebalancing as neccessary
1060 mesh_factory->enableRebalance(enabled,rebalanceCycles);
1061 }
1062
1063 return mesh_factory;
1064 }
1065
1066 template<typename ScalarT>
1068 const std::vector<Teuchos::RCP<panzer::PhysicsBlock> > & physicsBlocks,
1069 const Teuchos::MpiComm<int> mpi_comm,
1070 STK_Interface & mesh) const
1071 {
1072 // finish building mesh, set required field variables and mesh bulk data
1073 {
1074 std::vector<Teuchos::RCP<panzer::PhysicsBlock> >::const_iterator physIter;
1075 for(physIter=physicsBlocks.begin();physIter!=physicsBlocks.end();++physIter) {
1076 // what is the block weight for this element block?
1077 double blockWeight = 0.0;
1078
1079 Teuchos::RCP<const panzer::PhysicsBlock> pb = *physIter;
1080 const std::vector<panzer::StrPureBasisPair> & blockFields = pb->getProvidedDOFs();
1081 const std::vector<std::vector<std::string> > & coordinateDOFs = pb->getCoordinateDOFs();
1082 // these are treated specially
1083
1084 // insert all fields into a set
1085 std::set<panzer::StrPureBasisPair,panzer::StrPureBasisComp> fieldNames;
1086 fieldNames.insert(blockFields.begin(),blockFields.end());
1087
1088 // Now we will set up the coordinate fields (make sure to remove
1089 // the DOF fields)
1090 {
1091 std::set<std::string> fields_to_remove;
1092
1093 // add mesh coordinate fields, setup their removal from fieldNames
1094 // set to prevent duplication
1095 for(std::size_t i=0;i<coordinateDOFs.size();i++) {
1096 mesh.addMeshCoordFields(pb->elementBlockID(),coordinateDOFs[i],"DISPL");
1097 for(std::size_t j=0;j<coordinateDOFs[i].size();j++)
1098 fields_to_remove.insert(coordinateDOFs[i][j]);
1099 }
1100
1101 // remove the already added coordinate fields
1102 std::set<std::string>::const_iterator rmItr;
1103 for (rmItr=fields_to_remove.begin();rmItr!=fields_to_remove.end();++rmItr)
1104 fieldNames.erase(fieldNames.find(panzer::StrPureBasisPair(*rmItr,Teuchos::null)));
1105 }
1106
1107 // add basis to DOF manager: block specific
1108 std::set<panzer::StrPureBasisPair,panzer::StrPureBasisComp>::const_iterator fieldItr;
1109 for (fieldItr=fieldNames.begin();fieldItr!=fieldNames.end();++fieldItr) {
1110
1111 if(fieldItr->second->isScalarBasis() &&
1112 fieldItr->second->getElementSpace()==panzer::PureBasis::CONST) {
1113 mesh.addCellField(fieldItr->first,pb->elementBlockID());
1114 }
1115 else if(fieldItr->second->isScalarBasis()) {
1116 mesh.addSolutionField(fieldItr->first,pb->elementBlockID());
1117 }
1118 else if(fieldItr->second->isVectorBasis()) {
1119 std::string d_mod[3] = {"X","Y","Z"};
1120 for(int d=0;d<fieldItr->second->dimension();d++)
1121 mesh.addCellField(fieldItr->first+d_mod[d],pb->elementBlockID());
1122 }
1123 else { TEUCHOS_ASSERT(false); }
1124
1125 blockWeight += double(fieldItr->second->cardinality());
1126 }
1127
1128 // set the compute block weight (this is the sum of the cardinality of all basis
1129 // functions on this block
1130 mesh.setBlockWeight(pb->elementBlockID(),blockWeight);
1131 }
1132
1133 mesh_factory.completeMeshConstruction(mesh,*(mpi_comm.getRawMpiComm()));
1134 }
1135 }
1136
1137
1138 template<typename ScalarT>
1139 Teuchos::RCP<Thyra::ModelEvaluator<ScalarT> > ModelEvaluatorFactory<ScalarT>::getPhysicsModelEvaluator()
1140 {
1141 TEUCHOS_TEST_FOR_EXCEPTION(Teuchos::is_null(m_physics_me), std::runtime_error,
1142 "Objects are not built yet! Please call buildObjects() member function.");
1143 return m_physics_me;
1144 }
1145
1146 template<typename ScalarT>
1147 void ModelEvaluatorFactory<ScalarT>::setNOXObserverFactory(const Teuchos::RCP<const panzer_stk::NOXObserverFactory>& nox_observer_factory)
1148 {
1149 m_nox_observer_factory = nox_observer_factory;
1150 }
1151
1152#ifdef PANZER_HAVE_TEMPUS
1153 template<typename ScalarT>
1154 void ModelEvaluatorFactory<ScalarT>::setTempusObserverFactory(const Teuchos::RCP<const panzer_stk::TempusObserverFactory>& tempus_observer_factory)
1155 {
1156 m_tempus_observer_factory = tempus_observer_factory;
1157 }
1158#endif
1159
1160 template<typename ScalarT>
1161 void ModelEvaluatorFactory<ScalarT>::setUserWorksetFactory(Teuchos::RCP<panzer_stk::WorksetFactory>& user_wkst_factory)
1162 {
1163 m_user_wkst_factory = user_wkst_factory;
1164 }
1165
1166 template<typename ScalarT>
1167 Teuchos::RCP<Thyra::ModelEvaluator<ScalarT> > ModelEvaluatorFactory<ScalarT>::getResponseOnlyModelEvaluator()
1168 {
1169 if(m_rome_me==Teuchos::null)
1170 m_rome_me = buildResponseOnlyModelEvaluator(m_physics_me,m_global_data);
1171
1172 return m_rome_me;
1173 }
1174
1175 template<typename ScalarT>
1176 Teuchos::RCP<Thyra::ModelEvaluator<ScalarT> > ModelEvaluatorFactory<ScalarT>::
1178 const Teuchos::RCP<panzer::GlobalData>& global_data,
1179#ifdef PANZER_HAVE_TEMPUS
1180 const Teuchos::RCP<Piro::TempusSolverForwardOnly<ScalarT> > tempusSolver,
1181#endif
1182 const Teuchos::Ptr<const panzer_stk::NOXObserverFactory> & in_nox_observer_factory
1183#ifdef PANZER_HAVE_TEMPUS
1184 , const Teuchos::Ptr<const panzer_stk::TempusObserverFactory> & in_tempus_observer_factory
1185#endif
1186 )
1187 {
1188 using Teuchos::is_null;
1189 using Teuchos::Ptr;
1190
1191 TEUCHOS_TEST_FOR_EXCEPTION(is_null(m_lin_obj_factory), std::runtime_error,
1192 "Objects are not built yet! Please call buildObjects() member function.");
1193 TEUCHOS_TEST_FOR_EXCEPTION(is_null(m_global_indexer), std::runtime_error,
1194 "Objects are not built yet! Please call buildObjects() member function.");
1195 TEUCHOS_TEST_FOR_EXCEPTION(is_null(m_mesh), std::runtime_error,
1196 "Objects are not built yet! Please call buildObjects() member function.");
1197 Teuchos::Ptr<const panzer_stk::NOXObserverFactory> nox_observer_factory
1198 = is_null(in_nox_observer_factory) ? m_nox_observer_factory.ptr() : in_nox_observer_factory;
1199#ifdef PANZER_HAVE_TEMPUS
1200 Teuchos::Ptr<const panzer_stk::TempusObserverFactory> tempus_observer_factory
1201 = is_null(in_tempus_observer_factory) ? m_tempus_observer_factory.ptr() : in_tempus_observer_factory;
1202#endif
1203
1204 Teuchos::ParameterList& p = *this->getNonconstParameterList();
1205 Teuchos::ParameterList & solncntl_params = p.sublist("Solution Control");
1206 Teuchos::RCP<Teuchos::ParameterList> piro_params = Teuchos::rcp(new Teuchos::ParameterList(solncntl_params));
1207 Teuchos::RCP<Thyra::ModelEvaluatorDefaultBase<double> > piro;
1208
1209 std::string solver = solncntl_params.get<std::string>("Piro Solver");
1210 Teuchos::RCP<Thyra::ModelEvaluatorDefaultBase<double> > thyra_me_db
1211 = Teuchos::rcp_dynamic_cast<Thyra::ModelEvaluatorDefaultBase<double> >(thyra_me);
1212 if ( (solver=="NOX") || (solver == "LOCA") ) {
1213
1214 TEUCHOS_TEST_FOR_EXCEPTION(Teuchos::is_null(nox_observer_factory), std::runtime_error,
1215 "No NOX obersver built! Please call setNOXObserverFactory() member function if you plan to use a NOX solver.");
1216
1217 Teuchos::RCP<NOX::Abstract::PrePostOperator> ppo = nox_observer_factory->buildNOXObserver(m_mesh,m_global_indexer,m_lin_obj_factory);
1218 piro_params->sublist("NOX").sublist("Solver Options").set("User Defined Pre/Post Operator", ppo);
1219
1220 if (solver=="NOX")
1221 piro = Teuchos::rcp(new Piro::NOXSolver<double>(piro_params,
1222 Teuchos::rcp_dynamic_cast<Thyra::ModelEvaluatorDefaultBase<double> >(thyra_me_db)));
1223 else if (solver == "LOCA")
1224 piro = Teuchos::rcp(new Piro::LOCASolver<double>(piro_params,
1225 Teuchos::rcp_dynamic_cast<Thyra::ModelEvaluatorDefaultBase<double> >(thyra_me_db),
1226 Teuchos::null));
1227 TEUCHOS_ASSERT(nonnull(piro));
1228
1229 // override printing to use panzer ostream
1230 piro_params->sublist("NOX").sublist("Printing").set<Teuchos::RCP<std::ostream> >("Output Stream",global_data->os);
1231 piro_params->sublist("NOX").sublist("Printing").set<Teuchos::RCP<std::ostream> >("Error Stream",global_data->os);
1232 piro_params->sublist("NOX").sublist("Printing").set<int>("Output Processor",global_data->os->getOutputToRootOnly());
1233 }
1234#ifdef PANZER_HAVE_TEMPUS
1235 else if (solver=="Tempus") {
1236
1237 TEUCHOS_TEST_FOR_EXCEPTION(Teuchos::is_null(tempus_observer_factory), std::runtime_error,
1238 "No Tempus observer built! Please call setTempusObserverFactory() member function if you plan to use a Tempus solver.");
1239
1240 // install the nox observer
1241 if(tempus_observer_factory->useNOXObserver()) {
1242 Teuchos::RCP<NOX::Abstract::PrePostOperator> ppo = nox_observer_factory->buildNOXObserver(m_mesh,m_global_indexer,m_lin_obj_factory);
1243 piro_params->sublist("NOX").sublist("Solver Options").set("User Defined Pre/Post Operator", ppo);
1244 }
1245
1246 // override printing to use panzer ostream
1247 piro_params->sublist("NOX").sublist("Printing").set<Teuchos::RCP<std::ostream> >("Output Stream",global_data->os);
1248 piro_params->sublist("NOX").sublist("Printing").set<Teuchos::RCP<std::ostream> >("Error Stream",global_data->os);
1249 piro_params->sublist("NOX").sublist("Printing").set<int>("Output Processor",global_data->os->getOutputToRootOnly());
1250
1251 // use the user specfied tempus solver if they pass one in
1252 Teuchos::RCP<Piro::TempusSolverForwardOnly<double> > piro_tempus;
1253
1254 if(tempusSolver==Teuchos::null)
1255 {
1256 piro_tempus =
1257 Teuchos::rcp(new Piro::TempusSolverForwardOnly<double>(piro_params, thyra_me,
1258 tempus_observer_factory->buildTempusObserver(m_mesh,m_global_indexer,m_lin_obj_factory)));
1259 }
1260 else
1261 {
1262 piro_tempus = tempusSolver;
1263 piro_tempus->initialize(piro_params, thyra_me,
1264 tempus_observer_factory->buildTempusObserver(m_mesh,m_global_indexer,m_lin_obj_factory));
1265 }
1266
1267 piro = piro_tempus;
1268 }
1269#endif
1270 else {
1271 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
1272 "Error: Unknown Piro Solver : " << solver);
1273 }
1274 return piro;
1275 }
1276
1277 template<typename ScalarT>
1278 Teuchos::RCP<panzer::ResponseLibrary<panzer::Traits> > ModelEvaluatorFactory<ScalarT>::getResponseLibrary()
1279 {
1280 TEUCHOS_TEST_FOR_EXCEPTION(Teuchos::is_null(m_response_library), std::runtime_error,
1281 "Objects are not built yet! Please call buildObjects() member function.");
1282
1283 return m_response_library;
1284 }
1285
1286 template<typename ScalarT>
1287 const std::vector<Teuchos::RCP<panzer::PhysicsBlock> > & ModelEvaluatorFactory<ScalarT>::getPhysicsBlocks() const
1288 {
1289 TEUCHOS_TEST_FOR_EXCEPTION(m_physics_blocks.size()==0, std::runtime_error,
1290 "Objects are not built yet! Please call buildObjects() member function.");
1291
1292 return m_physics_blocks;
1293 }
1294
1295 template<typename ScalarT>
1296 Teuchos::RCP<panzer::FieldManagerBuilder>
1298 buildFieldManagerBuilder(const Teuchos::RCP<panzer::WorksetContainer> & wc,
1299 const std::vector<Teuchos::RCP<panzer::PhysicsBlock> >& physicsBlocks,
1300 const std::vector<panzer::BC> & bcs,
1301 const panzer::EquationSetFactory & eqset_factory,
1302 const panzer::BCStrategyFactory& bc_factory,
1305 const Teuchos::ParameterList& closure_models,
1307 const Teuchos::ParameterList& user_data,
1308 bool writeGraph,const std::string & graphPrefix,
1309 bool write_field_managers,const std::string & field_manager_prefix) const
1310 {
1311 Teuchos::RCP<panzer::FieldManagerBuilder> fmb = Teuchos::rcp(new panzer::FieldManagerBuilder);
1312 fmb->setWorksetContainer(wc);
1313 fmb->setupVolumeFieldManagers(physicsBlocks,volume_cm_factory,closure_models,lo_factory,user_data);
1314 fmb->setupBCFieldManagers(bcs,physicsBlocks,eqset_factory,bc_cm_factory,bc_factory,closure_models,lo_factory,user_data);
1315
1316 // Print Phalanx DAGs
1317 if (writeGraph){
1318 fmb->writeVolumeGraphvizDependencyFiles(graphPrefix, physicsBlocks);
1319 fmb->writeBCGraphvizDependencyFiles(graphPrefix);
1320 }
1321 if (write_field_managers){
1322 fmb->writeVolumeTextDependencyFiles(graphPrefix, physicsBlocks);
1323 fmb->writeBCTextDependencyFiles(field_manager_prefix);
1324 }
1325
1326 return fmb;
1327 }
1328
1329 template<typename ScalarT>
1330 Teuchos::RCP<Thyra::ModelEvaluator<double> >
1333 const Teuchos::RCP<Teuchos::ParameterList> & physics_block_plist,
1334 const Teuchos::RCP<const panzer::EquationSetFactory>& eqset_factory,
1335 const panzer::BCStrategyFactory & bc_factory,
1337 bool is_transient,bool is_explicit,
1338 const Teuchos::Ptr<const Teuchos::ParameterList> & bc_list,
1339 const Teuchos::RCP<Thyra::ModelEvaluator<ScalarT> > & physics_me_in) const
1340 {
1341 typedef panzer::ModelEvaluator<ScalarT> PanzerME;
1342
1343 Teuchos::RCP<Thyra::ModelEvaluator<ScalarT> > physics_me = physics_me_in==Teuchos::null ? m_physics_me : physics_me_in;
1344
1345 const Teuchos::ParameterList& p = *this->getParameterList();
1346
1347 // build PhysicsBlocks
1348 std::vector<Teuchos::RCP<panzer::PhysicsBlock> > physicsBlocks;
1349 {
1350 const Teuchos::ParameterList & assembly_params = p.sublist("Assembly");
1351
1352 // setup physical mappings and boundary conditions
1353 std::map<std::string,std::string> block_ids_to_physics_ids;
1354 panzer::buildBlockIdToPhysicsIdMap(block_ids_to_physics_ids, p.sublist("Block ID to Physics ID Mapping"));
1355
1356 // build cell ( block id -> cell topology ) mapping
1357 std::map<std::string,Teuchos::RCP<const shards::CellTopology> > block_ids_to_cell_topo;
1358 for(std::map<std::string,std::string>::const_iterator itr=block_ids_to_physics_ids.begin();
1359 itr!=block_ids_to_physics_ids.end();++itr) {
1360 block_ids_to_cell_topo[itr->first] = m_mesh->getCellTopology(itr->first);
1361 TEUCHOS_ASSERT(block_ids_to_cell_topo[itr->first]!=Teuchos::null);
1362 }
1363
1364 std::size_t workset_size = Teuchos::as<std::size_t>(assembly_params.get<int>("Workset Size"));
1365
1366 panzer::buildPhysicsBlocks(block_ids_to_physics_ids,
1367 block_ids_to_cell_topo,
1368 physics_block_plist,
1369 assembly_params.get<int>("Default Integration Order"),
1370 workset_size,
1371 eqset_factory,
1372 m_global_data,
1373 is_transient,
1374 physicsBlocks);
1375 }
1376
1377 // build FMB
1378 Teuchos::RCP<panzer::FieldManagerBuilder> fmb;
1379 {
1380 const Teuchos::ParameterList & user_data_params = p.sublist("User Data");
1381
1382 bool write_dot_files = false;
1383 std::string prefix = "Cloned_";
1384
1385 std::vector<panzer::BC> bcs;
1386 if(bc_list==Teuchos::null) {
1387 panzer::buildBCs(bcs, p.sublist("Boundary Conditions"), m_global_data);
1388 }
1389 else {
1390 panzer::buildBCs(bcs, *bc_list, m_global_data);
1391 }
1392
1393 fmb = buildFieldManagerBuilder(// Teuchos::rcp_const_cast<panzer::WorksetContainer>(
1394 // m_response_library!=Teuchos::null ? m_response_library->getWorksetContainer()
1395 // : m_wkstContainer),
1396 m_wkstContainer,
1397 physicsBlocks,
1398 bcs,
1399 *eqset_factory,
1400 bc_factory,
1401 user_cm_factory,
1402 user_cm_factory,
1403 p.sublist("Closure Models"),
1404 *m_lin_obj_factory,
1405 user_data_params,
1406 write_dot_files,prefix,
1407 write_dot_files,prefix);
1408 }
1409
1410 Teuchos::RCP<panzer::ResponseLibrary<panzer::Traits> > response_library
1411 = Teuchos::rcp(new panzer::ResponseLibrary<panzer::Traits>(m_wkstContainer,
1412 m_global_indexer,
1413 m_lin_obj_factory));
1414 // = Teuchos::rcp(new panzer::ResponseLibrary<panzer::Traits>(m_response_library->getWorksetContainer(),
1415 // m_response_library->getGlobalIndexer(),
1416 // m_response_library->getLinearObjFactory()));
1417
1418 // using the FMB, build the model evaluator
1419 {
1420 // get nominal input values, make sure they match with internal me
1421 Thyra::ModelEvaluatorBase::InArgs<ScalarT> nomVals = physics_me->getNominalValues();
1422
1423 // determine if this is a Epetra or Thyra ME
1424 Teuchos::RCP<PanzerME> panzer_me = Teuchos::rcp_dynamic_cast<PanzerME>(physics_me);
1425
1426 bool useThyra = true;
1427#ifdef PANZER_HAVE_EPETRA_STACK
1428 Teuchos::RCP<Thyra::EpetraModelEvaluator> ep_thyra_me = Teuchos::rcp_dynamic_cast<Thyra::EpetraModelEvaluator>(physics_me);
1429 if(ep_thyra_me!=Teuchos::null)
1430 useThyra = false;
1431#endif
1432
1433 // get parameter names
1434 std::vector<Teuchos::RCP<Teuchos::Array<std::string> > > p_names(physics_me->Np());
1435 std::vector<Teuchos::RCP<Teuchos::Array<double> > > p_values(physics_me->Np());
1436 for(std::size_t i=0;i<p_names.size();i++) {
1437 p_names[i] = Teuchos::rcp(new Teuchos::Array<std::string>(*physics_me->get_p_names(i)));
1438 p_values[i] = Teuchos::rcp(new Teuchos::Array<double>(p_names[i]->size(),0.0));
1439 }
1440
1441 Teuchos::RCP<Thyra::ModelEvaluatorDefaultBase<double> > thyra_me
1442 = buildPhysicsModelEvaluator(useThyra,
1443 fmb,
1444 response_library,
1445 m_lin_obj_factory,
1446 p_names,
1447 p_values,
1448 solverFactory,
1449 m_global_data,
1450 is_transient,
1451 nomVals.get_t());
1452
1453 // set the nominal values...does this work???
1454 thyra_me->getNominalValues() = nomVals;
1455
1456 // build an explicit model evaluator
1457 if(is_explicit) {
1458 const Teuchos::ParameterList & assembly_params = p.sublist("Assembly");
1459 bool lumpExplicitMass = assembly_params.get<bool>("Lump Explicit Mass");
1460 thyra_me = Teuchos::rcp(new panzer::ExplicitModelEvaluator<ScalarT>(thyra_me,!useDynamicCoordinates_,lumpExplicitMass));
1461 }
1462
1463 return thyra_me;
1464 }
1465 }
1466
1467 template<typename ScalarT>
1468 Teuchos::RCP<Thyra::ModelEvaluatorDefaultBase<double> >
1470 buildPhysicsModelEvaluator(bool buildThyraME,
1471 const Teuchos::RCP<panzer::FieldManagerBuilder> & fmb,
1472 const Teuchos::RCP<panzer::ResponseLibrary<panzer::Traits> > & rLibrary,
1473 const Teuchos::RCP<panzer::LinearObjFactory<panzer::Traits> > & lof,
1474 const std::vector<Teuchos::RCP<Teuchos::Array<std::string> > > & p_names,
1475 const std::vector<Teuchos::RCP<Teuchos::Array<double> > > & p_values,
1476 const Teuchos::RCP<Thyra::LinearOpWithSolveFactoryBase<ScalarT> > & solverFactory,
1477 const Teuchos::RCP<panzer::GlobalData> & global_data,
1478 bool is_transient,double t_init) const
1479 {
1480 Teuchos::RCP<Thyra::ModelEvaluatorDefaultBase<double> > thyra_me;
1481 if(!buildThyraME) {
1482#ifdef PANZER_HAVE_EPETRA_STACK
1483 Teuchos::RCP<panzer::ModelEvaluator_Epetra> ep_me
1484 = Teuchos::rcp(new panzer::ModelEvaluator_Epetra(fmb,rLibrary,lof, p_names,p_values, global_data, is_transient));
1485
1486 if (is_transient)
1487 ep_me->set_t_init(t_init);
1488
1489 // Build Thyra Model Evaluator
1490 thyra_me = Thyra::epetraModelEvaluator(ep_me,solverFactory);
1491#else
1492 TEUCHOS_TEST_FOR_EXCEPTION(true,std::runtime_error,"ERROR: buildPhysicsModelEvalautor() - Epetra stack is not enabled!");
1493#endif
1494 }
1495 else {
1496 thyra_me = Teuchos::rcp(new panzer::ModelEvaluator<double>
1497 (fmb,rLibrary,lof,p_names,p_values,solverFactory,global_data,is_transient,t_init));
1498 }
1499
1500 return thyra_me;
1501 }
1502
1503 template<typename ScalarT>
1505 getInitialTime(Teuchos::ParameterList& p,
1506 const panzer_stk::STK_Interface & mesh) const
1507 {
1508 Teuchos::ParameterList validPL;
1509 {
1510 validPL.set<std::string>("Start Time Type", "From Input File", "Set the start time",
1511 rcp(new Teuchos::StringValidator(Teuchos::tuple<std::string>("From Input File","From Exodus File"))));
1512
1513 validPL.set<double>("Start Time",0.0);
1514 }
1515
1516 p.validateParametersAndSetDefaults(validPL);
1517
1518 std::string t_init_type = p.get<std::string>("Start Time Type");
1519 double t_init = 10.0;
1520
1521 if (t_init_type == "From Input File")
1522 t_init = p.get<double>("Start Time");
1523
1524 if (t_init_type == "From Exodus File")
1525 t_init = mesh.getInitialStateTime();
1526
1527 return t_init;
1528 }
1529
1530 // Setup STK response library for writing out the solution fields
1532 template<typename ScalarT>
1533 Teuchos::RCP<panzer::ResponseLibrary<panzer::Traits> > ModelEvaluatorFactory<ScalarT>::
1534 initializeSolnWriterResponseLibrary(const Teuchos::RCP<panzer::WorksetContainer> & wc,
1535 const Teuchos::RCP<const panzer::GlobalIndexer> & ugi,
1536 const Teuchos::RCP<const panzer::LinearObjFactory<panzer::Traits> > & lof,
1537 const Teuchos::RCP<panzer_stk::STK_Interface> & mesh) const
1538 {
1539 Teuchos::RCP<panzer::ResponseLibrary<panzer::Traits> > stkIOResponseLibrary
1540 = Teuchos::rcp(new panzer::ResponseLibrary<panzer::Traits>(wc,ugi,lof));
1541
1542 std::vector<std::string> eBlocks;
1543 mesh->getElementBlockNames(eBlocks);
1544
1546 builder.mesh = mesh;
1547 stkIOResponseLibrary->addResponse("Main Field Output",eBlocks,builder);
1548
1549 return stkIOResponseLibrary;
1550 }
1551
1552 template<typename ScalarT>
1555 const std::vector<Teuchos::RCP<panzer::PhysicsBlock> > & physicsBlocks,
1557 const Teuchos::ParameterList & closure_models,
1558 int workset_size, Teuchos::ParameterList & user_data) const
1559 {
1560 user_data.set<int>("Workset Size",workset_size);
1561 rl.buildResponseEvaluators(physicsBlocks, cm_factory, closure_models, user_data);
1562 }
1563
1565 const Teuchos::RCP<panzer_stk::STK_Interface>& mesh_;
1567 SetMeshFunctor(const Teuchos::RCP<panzer_stk::STK_Interface>& mesh,
1569 : mesh_(mesh),user_cm_factory_(user_cm_factory){}
1570
1571 template<typename EvalT>
1572 void operator()(EvalT t) const {
1573 auto factory = user_cm_factory_.getAsObject<EvalT>();
1574 panzer_stk::STKMeshAccessor* mesh_accessor = nullptr;
1575 mesh_accessor = dynamic_cast<panzer_stk::STKMeshAccessor*>(factory.get());
1576 if (mesh_accessor) {
1577 mesh_accessor->setMesh(mesh_);
1578 }
1579 else {
1580 // try casting to a composite class and rescurively call this functor
1582 composite = dynamic_cast<panzer::ClosureModelFactoryComposite<EvalT>*>(factory.get());
1583 if (composite) {
1584 auto& sub_factories = composite->getFactories();
1585 for (auto sub_factory : sub_factories) {
1586 Sacado::mpl::for_each_no_kokkos<panzer::Traits::EvalTypes>(SetMeshFunctor(mesh_,*sub_factory));
1587 }
1588 }
1589 }
1590 }
1591 };
1592
1593 template<typename ScalarT>
1595 registerMeshWithClosureModelFactories(const Teuchos::RCP<panzer_stk::STK_Interface>& mesh,
1597 {
1598 Sacado::mpl::for_each_no_kokkos<panzer::Traits::EvalTypes>(SetMeshFunctor(mesh,user_cm_factory));
1599 }
1600
1601 template<typename ScalarT>
1602 Teuchos::RCP<Thyra::LinearOpWithSolveFactoryBase<double> > ModelEvaluatorFactory<ScalarT>::
1603 buildLOWSFactory(bool blockedAssembly,
1604 const Teuchos::RCP<const panzer::GlobalIndexer> & globalIndexer,
1605 const Teuchos::RCP<panzer::ConnManager> & conn_manager,
1606 const Teuchos::RCP<panzer_stk::STK_Interface> & mesh,
1607 const Teuchos::RCP<const Teuchos::MpiComm<int> > & mpi_comm
1608 #ifdef PANZER_HAVE_TEKO
1609 , const Teuchos::RCP<Teko::RequestHandler> & reqHandler
1610 #endif
1611 ) const
1612 {
1613 const Teuchos::ParameterList & p = *this->getParameterList();
1614 const Teuchos::ParameterList & solncntl_params = p.sublist("Solution Control");
1615
1616 // Build stratimikos solver (note that this defaults to a hard
1617 // coded path to linear solver options in nox list!)
1618 Teuchos::RCP<Teuchos::ParameterList> strat_params;
1619 if (nonnull(m_stratimikos_params)) {
1620 strat_params = m_stratimikos_params;
1621 }
1622 else {
1623 strat_params = Teuchos::rcp(new Teuchos::ParameterList(solncntl_params.sublist("NOX").sublist("Direction").
1624 sublist("Newton").sublist("Stratimikos Linear Solver").sublist("Stratimikos")));
1625 }
1626
1627 bool writeCoordinates = false;
1628 if(p.sublist("Options").isType<bool>("Write Coordinates"))
1629 writeCoordinates = p.sublist("Options").get<bool>("Write Coordinates");
1630
1631 bool writeTopo = false;
1632 if(p.sublist("Options").isType<bool>("Write Topology"))
1633 writeTopo = p.sublist("Options").get<bool>("Write Topology");
1634
1635
1637 blockedAssembly,globalIndexer,conn_manager,
1638 Teuchos::as<int>(mesh->getDimension()), mpi_comm, strat_params,
1639 #ifdef PANZER_HAVE_TEKO
1640 reqHandler,
1641 #endif
1642 writeCoordinates,
1643 writeTopo
1644 );
1645 }
1646
1647 template<typename ScalarT>
1650 const bool write_graphviz_file,
1651 const std::string& graphviz_file_prefix)
1652 {
1653 Teuchos::ParameterList & p = *this->getNonconstParameterList();
1654 Teuchos::ParameterList & user_data = p.sublist("User Data");
1655 Teuchos::ParameterList & closure_models = p.sublist("Closure Models");
1656
1657 // uninitialize the thyra model evaluator, and rebuild the
1658 // responses to get the correct response counts!
1659
1660 using PanzerME = panzer::ModelEvaluator<double>;
1661 Teuchos::RCP<PanzerME> panzer_me = Teuchos::rcp_dynamic_cast<PanzerME>(m_physics_me);
1662
1663 if(nonnull(panzer_me)) {
1664 panzer_me->buildResponses(m_physics_blocks,*m_eqset_factory,cm_factory,closure_models,user_data,write_graphviz_file,graphviz_file_prefix);
1665 return;
1666 }
1667#ifdef PANZER_HAVE_EPETRA_STACK
1668 else {
1669 Teuchos::RCP<Thyra::EpetraModelEvaluator> epetra_me = Teuchos::rcp_dynamic_cast<Thyra::EpetraModelEvaluator>(m_physics_me);
1670
1671 if(epetra_me!=Teuchos::null) {
1672 Teuchos::RCP<const EpetraExt::ModelEvaluator> const_ep_me;
1673 Teuchos::RCP<Thyra::LinearOpWithSolveFactoryBase<double> > solveFactory;
1674 epetra_me->uninitialize(&const_ep_me,&solveFactory);
1675
1676 Teuchos::RCP<EpetraExt::ModelEvaluator> ep_me = Teuchos::rcp_const_cast<EpetraExt::ModelEvaluator>(const_ep_me);
1677 Teuchos::RCP<panzer::ModelEvaluator_Epetra> ep_panzer_me = Teuchos::rcp_dynamic_cast<panzer::ModelEvaluator_Epetra>(ep_me);
1678 ep_panzer_me->buildResponses(m_physics_blocks,*m_eqset_factory,cm_factory,closure_models,user_data,write_graphviz_file,graphviz_file_prefix);
1679
1680 // reinitialize the thyra model evaluator, now with the correct responses
1681 epetra_me->initialize(ep_me,solveFactory);
1682
1683 return;
1684 }
1685 }
1686#endif
1687
1688 TEUCHOS_TEST_FOR_EXCEPTION(true,std::runtime_error,"ERROR: buildResponses() - could not cast Physics ME to PanzerME!");
1689 }
1690}
1691
1692#endif
Teuchos::RCP< panzer::LinearObjContainer > ghostedContainer_
Teuchos::RCP< panzer::LinearObjContainer > container_
static bool requiresBlocking(const std::string &fieldorder)
virtual Teuchos::RCP< panzer::GlobalIndexer > buildGlobalIndexer(const Teuchos::RCP< const Teuchos::OpaqueWrapper< MPI_Comm > > &mpiComm, const std::vector< Teuchos::RCP< panzer::PhysicsBlock > > &physicsBlocks, const Teuchos::RCP< ConnManager > &connMngr, const std::string &fieldOrder="") const
std::vector< Teuchos::RCP< panzer::ClosureModelFactory_TemplateManager< panzer::Traits > > > & getFactories()
virtual Teuchos::RCP< panzer::GlobalIndexer > buildGlobalIndexer(const Teuchos::RCP< const Teuchos::OpaqueWrapper< MPI_Comm > > &mpiComm, const std::vector< Teuchos::RCP< panzer::PhysicsBlock > > &physicsBlocks, const Teuchos::RCP< ConnManager > &connMngr, const std::string &fieldOrder="") const
virtual Teuchos::RCP< LinearObjContainer > buildLinearObjContainer() const =0
virtual void readVector(const std::string &identifier, LinearObjContainer &loc, int id) const =0
void buildResponseEvaluators(const std::vector< Teuchos::RCP< panzer::PhysicsBlock > > &physicsBlocks, const panzer::ClosureModelFactory_TemplateManager< panzer::Traits > &cm_factory, const Teuchos::ParameterList &closure_models, const Teuchos::ParameterList &user_data, const bool write_graphviz_file=false, const std::string &graphviz_file_prefix="")
Class that provides access to worksets on each element block and side set.
Teuchos::RCP< Thyra::LinearOpWithSolveFactoryBase< double > > buildLOWSFactory(bool blockedAssembly, const Teuchos::RCP< const panzer::GlobalIndexer > &globalIndexer, const Teuchos::RCP< panzer::ConnManager > &conn_manager, const Teuchos::RCP< panzer_stk::STK_Interface > &mesh, const Teuchos::RCP< const Teuchos::MpiComm< int > > &mpi_comm) const
Teuchos::RCP< panzer::ResponseLibrary< panzer::Traits > > getResponseLibrary()
Teuchos::RCP< panzer::ResponseLibrary< panzer::Traits > > initializeSolnWriterResponseLibrary(const Teuchos::RCP< panzer::WorksetContainer > &wc, const Teuchos::RCP< const panzer::GlobalIndexer > &ugi, const Teuchos::RCP< const panzer::LinearObjFactory< panzer::Traits > > &lof, const Teuchos::RCP< panzer_stk::STK_Interface > &mesh) const
void registerMeshWithClosureModelFactories(const Teuchos::RCP< panzer_stk::STK_Interface > &mesh, panzer::ClosureModelFactory_TemplateManager< panzer::Traits > &user_cm_factory)
Teuchos::RCP< panzer::FieldManagerBuilder > buildFieldManagerBuilder(const Teuchos::RCP< panzer::WorksetContainer > &wc, const std::vector< Teuchos::RCP< panzer::PhysicsBlock > > &physicsBlocks, const std::vector< panzer::BC > &bcs, const panzer::EquationSetFactory &eqset_factory, const panzer::BCStrategyFactory &bc_factory, const panzer::ClosureModelFactory_TemplateManager< panzer::Traits > &volume_cm_factory, const panzer::ClosureModelFactory_TemplateManager< panzer::Traits > &bc_cm_factory, const Teuchos::ParameterList &closure_models, const panzer::LinearObjFactory< panzer::Traits > &lo_factory, const Teuchos::ParameterList &user_data, bool writeGraph, const std::string &graphPrefix, bool write_field_managers, const std::string &field_manager_prefix) const
double getInitialTime(Teuchos::ParameterList &transient_ic_params, const panzer_stk::STK_Interface &mesh) const
Gets the initial time from either the input parameter list or an exodus file.
void finalizeMeshConstruction(const STK_MeshFactory &mesh_factory, const std::vector< Teuchos::RCP< panzer::PhysicsBlock > > &physicsBlocks, const Teuchos::MpiComm< int > mpi_comm, STK_Interface &mesh) const
Teuchos::RCP< Thyra::ModelEvaluator< ScalarT > > getResponseOnlyModelEvaluator()
void buildObjects(const Teuchos::RCP< const Teuchos::Comm< int > > &comm, const Teuchos::RCP< panzer::GlobalData > &global_data, const Teuchos::RCP< const panzer::EquationSetFactory > &eqset_factory, const panzer::BCStrategyFactory &bc_factory, const panzer::ClosureModelFactory_TemplateManager< panzer::Traits > &cm_factory, bool meConstructionOn=true)
Builds the model evaluators for a panzer assembly.
void addUserFieldsToMesh(panzer_stk::STK_Interface &mesh, const Teuchos::ParameterList &output_list) const
Add the user fields specified by output_list to the mesh.
Teuchos::RCP< Thyra::ModelEvaluator< double > > cloneWithNewPhysicsBlocks(const Teuchos::RCP< Thyra::LinearOpWithSolveFactoryBase< ScalarT > > &solverFactory, const Teuchos::RCP< Teuchos::ParameterList > &physics_block_plist, const Teuchos::RCP< const panzer::EquationSetFactory > &eqset_factory, const panzer::BCStrategyFactory &bc_factory, const panzer::ClosureModelFactory_TemplateManager< panzer::Traits > &user_cm_factory, bool is_transient, bool is_explicit, const Teuchos::Ptr< const Teuchos::ParameterList > &bc_list=Teuchos::null, const Teuchos::RCP< Thyra::ModelEvaluator< ScalarT > > &physics_me=Teuchos::null) const
Teuchos::RCP< Thyra::ModelEvaluator< ScalarT > > buildResponseOnlyModelEvaluator(const Teuchos::RCP< Thyra::ModelEvaluator< ScalarT > > &thyra_me, const Teuchos::RCP< panzer::GlobalData > &global_data, const Teuchos::Ptr< const panzer_stk::NOXObserverFactory > &in_nox_observer_factory=Teuchos::null)
void buildResponses(const panzer::ClosureModelFactory_TemplateManager< panzer::Traits > &cm_factory, const bool write_graphviz_file=false, const std::string &graphviz_file_prefix="")
void setStratimikosList(const Teuchos::RCP< Teuchos::ParameterList > &paramList)
Set the Stratimikos Linear Solver sublist used to create the LinearOpWithSolve factory.
void setParameterList(Teuchos::RCP< Teuchos::ParameterList > const &paramList)
void setupInitialConditions(Thyra::ModelEvaluator< ScalarT > &model, panzer::WorksetContainer &wkstContainer, const std::vector< Teuchos::RCP< panzer::PhysicsBlock > > &physicsBlocks, const panzer::ClosureModelFactory_TemplateManager< panzer::Traits > &cm_factory, const panzer::LinearObjFactory< panzer::Traits > &lof, const Teuchos::ParameterList &closure_pl, const Teuchos::ParameterList &initial_cond_pl, const Teuchos::ParameterList &user_data_pl, bool write_dot_files, const std::string &dot_file_prefix) const
Setup the initial conditions in a model evaluator. Note that this is entirely self contained.
void setUserWorksetFactory(Teuchos::RCP< panzer_stk::WorksetFactory > &user_wkst_factory)
Set user defined workset factory.
const std::vector< Teuchos::RCP< panzer::PhysicsBlock > > & getPhysicsBlocks() const
Teuchos::RCP< Thyra::ModelEvaluator< ScalarT > > getPhysicsModelEvaluator()
Teuchos::RCP< STK_MeshFactory > buildSTKMeshFactory(const Teuchos::ParameterList &mesh_params) const
build STK mesh factory from a mesh parameter list
void setNOXObserverFactory(const Teuchos::RCP< const panzer_stk::NOXObserverFactory > &nox_observer_factory)
void finalizeSolnWriterResponseLibrary(panzer::ResponseLibrary< panzer::Traits > &rl, const std::vector< Teuchos::RCP< panzer::PhysicsBlock > > &physicsBlocks, const panzer::ClosureModelFactory_TemplateManager< panzer::Traits > &cm_factory, const Teuchos::ParameterList &closure_models, int workset_size, Teuchos::ParameterList &user_data) const
Teuchos::RCP< Thyra::ModelEvaluatorDefaultBase< double > > buildPhysicsModelEvaluator(bool buildThyraME, const Teuchos::RCP< panzer::FieldManagerBuilder > &fmb, const Teuchos::RCP< panzer::ResponseLibrary< panzer::Traits > > &rLibrary, const Teuchos::RCP< panzer::LinearObjFactory< panzer::Traits > > &lof, const std::vector< Teuchos::RCP< Teuchos::Array< std::string > > > &p_names, const std::vector< Teuchos::RCP< Teuchos::Array< double > > > &p_values, const Teuchos::RCP< Thyra::LinearOpWithSolveFactoryBase< ScalarT > > &solverFactory, const Teuchos::RCP< panzer::GlobalData > &global_data, bool is_transient, double t_init) const
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
void writeInitialConditions(const Thyra::ModelEvaluator< ScalarT > &model, const std::vector< Teuchos::RCP< panzer::PhysicsBlock > > &physicsBlocks, const Teuchos::RCP< panzer::WorksetContainer > &wc, const Teuchos::RCP< const panzer::GlobalIndexer > &ugi, const Teuchos::RCP< const panzer::LinearObjFactory< panzer::Traits > > &lof, const Teuchos::RCP< panzer_stk::STK_Interface > &mesh, const panzer::ClosureModelFactory_TemplateManager< panzer::Traits > &cm_factory, const Teuchos::ParameterList &closure_model_pl, const Teuchos::ParameterList &user_data_pl, int workset_size) const
Write the initial conditions to exodus. Note that this is entirely self contained.
void setMesh(const Teuchos::RCP< STK_Interface > &mesh)
void setBlockWeight(const std::string &blockId, double weight)
void addCellField(const std::string &fieldName, const std::string &blockId)
void addMeshCoordFields(const std::string &blockId, const std::vector< std::string > &coordField, const std::string &dispPrefix)
unsigned getDimension() const
get the dimension
void addSolutionField(const std::string &fieldName, const std::string &blockId)
virtual void completeMeshConstruction(STK_Interface &mesh, stk::ParallelMachine parallelMach) const =0
Teuchos::RCP< Thyra::LinearOpWithSolveFactoryBase< double > > buildLOWSFactory(bool blockedAssembly, const Teuchos::RCP< const panzer::GlobalIndexer > &globalIndexer, const Teuchos::RCP< panzer_stk::STKConnManager > &stkConn_manager, int spatialDim, const Teuchos::RCP< const Teuchos::MpiComm< int > > &mpi_comm, const Teuchos::RCP< Teuchos::ParameterList > &strat_params, bool writeCoordinates, bool writeTopo, const Teuchos::RCP< const panzer::GlobalIndexer > &auxGlobalIndexer, bool useCoordinates)
void TokensToInts(std::vector< int > &values, const std::vector< std::string > &tokens)
Turn a vector of tokens into a vector of ints.
WorksetDescriptor blockDescriptor(const std::string &eBlock)
void StringTokenizer(std::vector< std::string > &tokens, const std::string &str, const std::string delimiters, bool trim)
Tokenize a string, put tokens in a vector.
std::pair< std::string, Teuchos::RCP< panzer::PureBasis > > StrPureBasisPair
@ BCT_Interface
Definition Panzer_BC.hpp:44
void registerScalarParameter(const std::string name, panzer::ParamLib &pl, double realValue)
void buildBlockIdToPhysicsIdMap(std::map< std::string, std::string > &b_to_p, const Teuchos::ParameterList &p)
void setupInitialConditionFieldManagers(WorksetContainer &wkstContainer, const std::vector< Teuchos::RCP< panzer::PhysicsBlock > > &physicsBlocks, const panzer::ClosureModelFactory_TemplateManager< panzer::Traits > &cm_factory, const Teuchos::ParameterList &ic_block_closure_models, const panzer::LinearObjFactory< panzer::Traits > &lo_factory, const Teuchos::ParameterList &user_data, const bool write_graphviz_file, const std::string &graphviz_file_prefix, std::map< std::string, Teuchos::RCP< PHX::FieldManager< panzer::Traits > > > &phx_ic_field_managers)
Builds PHX::FieldManager objects for inital conditions and registers evaluators.
void evaluateInitialCondition(WorksetContainer &wkstContainer, const std::map< std::string, Teuchos::RCP< PHX::FieldManager< panzer::Traits > > > &phx_ic_field_managers, Teuchos::RCP< panzer::LinearObjContainer > loc, const panzer::LinearObjFactory< panzer::Traits > &lo_factory, const double time_stamp, const double step_size, const int stage_number)
Interface for constructing a BCStrategy_TemplateManager.
Allocates and initializes an equation set template manager.
SetMeshFunctor(const Teuchos::RCP< panzer_stk::STK_Interface > &mesh, panzer::ClosureModelFactory_TemplateManager< panzer::Traits > &user_cm_factory)
panzer::ClosureModelFactory_TemplateManager< panzer::Traits > & user_cm_factory_
const Teuchos::RCP< panzer_stk::STK_Interface > & mesh_