Panzer Version of the Day
Loading...
Searching...
No Matches
Panzer_InitialCondition_Builder.cpp
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
12
13#include "Teuchos_Assert.hpp"
14
15#include "Panzer_EquationSet_DefaultImpl.hpp"
20
21namespace panzer {
22
23void
25 const std::vector<Teuchos::RCP<panzer::PhysicsBlock> >& physicsBlocks,
27 const Teuchos::ParameterList& ic_block_closure_models,
29 const Teuchos::ParameterList& user_data,
30 const bool write_graphviz_file,
31 const std::string& graphviz_file_prefix,
32 std::map< std::string, Teuchos::RCP< PHX::FieldManager<panzer::Traits> > >& phx_ic_field_managers)
33{
34 std::vector<Teuchos::RCP<panzer::PhysicsBlock> >::const_iterator blkItr;
35 for (blkItr=physicsBlocks.begin();blkItr!=physicsBlocks.end();++blkItr) {
36 Teuchos::RCP<panzer::PhysicsBlock> pb = *blkItr;
37 std::string blockId = pb->elementBlockID();
38
39 // build a field manager object
40 Teuchos::RCP<PHX::FieldManager<panzer::Traits> > fm
41 = Teuchos::rcp(new PHX::FieldManager<panzer::Traits>);
42
43 // Choose model sublist for this element block
44 std::string closure_model_name = "";
45 if (ic_block_closure_models.isSublist(blockId))
46 closure_model_name = blockId;
47 else if (ic_block_closure_models.isSublist("Default"))
48 closure_model_name = "Default";
49 else
50 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Failed to find initial condition for element block \"" << blockId
51 << "\". You must provide an initial condition for each element block or set a default!"
52 << ic_block_closure_models);
53
54 // Only the residual is used by initial conditions
55 std::vector<bool> active_evaluation_types(Sacado::mpl::size<panzer::Traits::EvalTypes>::value,false);
56 int residual_index = Sacado::mpl::find<panzer::Traits::EvalTypes,panzer::Traits::Residual>::value;
57 active_evaluation_types[residual_index] = true;
58 pb->setActiveEvaluationTypes(active_evaluation_types);
59
60 // use the physics block to register evaluators
61 pb->buildAndRegisterInitialConditionEvaluators(*fm, cm_factory, closure_model_name, ic_block_closure_models, lo_factory, user_data);
62
63 pb->activateAllEvaluationTypes();
64
65 // build the setup data using passed in information
66 Traits::SD setupData;
67 const WorksetDescriptor wd = blockDescriptor(blockId);
68 setupData.worksets_ = wkstContainer.getWorksets(wd);
69 setupData.orientations_ = wkstContainer.getOrientations();
70
71 int i=0;
72 for (auto eval_type=fm->begin(); eval_type != fm->end(); ++eval_type,++i) {
73 if (active_evaluation_types[i])
74 eval_type->postRegistrationSetup(setupData,*fm,false,false,nullptr);
75 }
76
77 phx_ic_field_managers[blockId] = fm;
78
79 if (write_graphviz_file)
80 fm->writeGraphvizFile(graphviz_file_prefix+"_IC_"+blockId);
81 }
82}
83
84void
86 const std::vector<Teuchos::RCP<panzer::PhysicsBlock> >& physicsBlocks,
88 const Teuchos::ParameterList& closure_models,
89 const Teuchos::ParameterList& ic_block_closure_models,
91 const Teuchos::ParameterList& user_data,
92 const bool write_graphviz_file,
93 const std::string& graphviz_file_prefix,
94 std::map< std::string, Teuchos::RCP< PHX::FieldManager<panzer::Traits> > >& phx_ic_field_managers)
95{
96 std::vector<Teuchos::RCP<panzer::PhysicsBlock> >::const_iterator blkItr;
97 for (blkItr=physicsBlocks.begin();blkItr!=physicsBlocks.end();++blkItr) {
98 Teuchos::RCP<panzer::PhysicsBlock> pb = *blkItr;
99 std::string blockId = pb->elementBlockID();
100
101 // build a field manager object
102 Teuchos::RCP<PHX::FieldManager<panzer::Traits> > fm
103 = Teuchos::rcp(new PHX::FieldManager<panzer::Traits>);
104
105 // Choose model sublist for this element block
106 std::string closure_model_name = "";
107 if (ic_block_closure_models.isSublist(blockId))
108 closure_model_name = blockId;
109 else if (ic_block_closure_models.isSublist("Default"))
110 closure_model_name = "Default";
111 else
112 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Failed to find initial condition for element block \"" << blockId
113 << "\". You must provide an initial condition for each element block or set a default!"
114 << ic_block_closure_models);
115
116 // Only the residual is used by initial conditions
117 std::vector<bool> active_evaluation_types(Sacado::mpl::size<panzer::Traits::EvalTypes>::value,false);
118 int residual_index = Sacado::mpl::find<panzer::Traits::EvalTypes,panzer::Traits::Residual>::value;
119 active_evaluation_types[residual_index] = true;
120 pb->setActiveEvaluationTypes(active_evaluation_types);
121
122 // build and register all closure models
123 pb->buildAndRegisterClosureModelEvaluators(*fm,cm_factory,closure_models,user_data);
124
125 // use the physics block to register evaluators
126 pb->buildAndRegisterInitialConditionEvaluators(*fm, cm_factory, closure_model_name, ic_block_closure_models, lo_factory, user_data);
127
128 pb->activateAllEvaluationTypes();
129
130 // build the setup data using passed in information
131 Traits::SD setupData;
132 const WorksetDescriptor wd = blockDescriptor(blockId);
133 setupData.worksets_ = wkstContainer.getWorksets(wd);
134 setupData.orientations_ = wkstContainer.getOrientations();
135
136 int i=0;
137 for (auto eval_type=fm->begin(); eval_type != fm->end(); ++eval_type,++i) {
138 if (active_evaluation_types[i])
139 eval_type->postRegistrationSetup(setupData,*fm,false,false,nullptr);
140 }
141
142 phx_ic_field_managers[blockId] = fm;
143
144 if (write_graphviz_file)
145 fm->writeGraphvizFile(graphviz_file_prefix+"_IC_"+blockId);
146 }
147}
148
149void
151 const std::map< std::string,Teuchos::RCP< PHX::FieldManager<panzer::Traits> > >& phx_ic_field_managers,
152 Teuchos::RCP<panzer::LinearObjContainer> loc,
154 const double time_stamp,
155 const double step_size,
156 const int stage_number)
157{
158 typedef LinearObjContainer LOC;
160
161 // allocate a ghosted container for the initial condition
162 Teuchos::RCP<LOC> ghostedloc = lo_factory.buildGhostedLinearObjContainer();
163 lo_factory.initializeGhostedContainer(LOC::X,*ghostedloc);
164
165 // allocate a counter to keep track of where this processor set initial conditions
166 Teuchos::RCP<LOC> localCounter = lo_factory.buildPrimitiveGhostedLinearObjContainer();
167 Teuchos::RCP<LOC> globalCounter = lo_factory.buildPrimitiveLinearObjContainer();
168 Teuchos::RCP<LOC> summedGhostedCounter = lo_factory.buildPrimitiveGhostedLinearObjContainer();
169
170 lo_factory.initializeGhostedContainer(LOC::F,*localCounter); // store counter in F
171 localCounter->initialize();
172
173 ped.gedc->addDataObject("Residual Scatter Container",ghostedloc);
174 ped.gedc->addDataObject("Dirichlet Counter",localCounter);
176
177 for(std::map< std::string,Teuchos::RCP< PHX::FieldManager<panzer::Traits> > >::const_iterator itr=phx_ic_field_managers.begin();
178 itr!=phx_ic_field_managers.end();++itr) {
179 std::string blockId = itr->first;
180 Teuchos::RCP< PHX::FieldManager<panzer::Traits> > fm = itr->second;
181
182 fm->preEvaluate<panzer::Traits::Residual>(ped);
183
184 // Loop over worksets in this element block
185 const WorksetDescriptor wd = blockDescriptor(blockId);
186 std::vector<panzer::Workset>& w = *wkstContainer.getWorksets(wd);
187 for (std::size_t i = 0; i < w.size(); ++i) {
188 panzer::Workset& workset = w[i];
189 workset.time = time_stamp;
190 workset.step_size = step_size;
191 workset.stage_number = static_cast<double>(stage_number);
192
193 fm->evaluateFields<panzer::Traits::Residual>(workset);
194 }
195 }
196
197 lo_factory.initializeGhostedContainer(LOC::F,*summedGhostedCounter); // store counter in F
198 summedGhostedCounter->initialize();
199
200 // do communication to build summed ghosted counter for dirichlet conditions
201 {
202 lo_factory.initializeContainer(LOC::F,*globalCounter); // store counter in F
203 globalCounter->initialize();
204 lo_factory.ghostToGlobalContainer(*localCounter,*globalCounter,LOC::F);
205 // Here we do the reduction across all processors so that the number of times
206 // a dirichlet condition is applied is summed into the global counter
207
208 lo_factory.globalToGhostContainer(*globalCounter,*summedGhostedCounter,LOC::F);
209 // finally we move the summed global vector into a local ghosted vector
210 // so that the dirichlet conditions can be applied to both the ghosted
211 // right hand side and the ghosted matrix
212 }
213
215 gedc.addDataObject("Residual Scatter Container",ghostedloc);
216
217 // adjust ghosted system for boundary conditions
218 for(GlobalEvaluationDataContainer::iterator itr=gedc.begin();itr!=gedc.end();itr++) {
219 Teuchos::RCP<LOC> loc2 = Teuchos::rcp_dynamic_cast<LOC>(itr->second);
220 if(loc2!=Teuchos::null) {
221 bool zeroVectorRows = false;
222 bool adjustX = true;
223 lo_factory.adjustForDirichletConditions(*localCounter,*summedGhostedCounter,*loc2, zeroVectorRows, adjustX);
224 }
225 }
226
227 // gather the ghosted solution back into the global container, which performs the sum
228 lo_factory.ghostToGlobalContainer(*ghostedloc,*loc,LOC::X);
229}
230
231// This is an anonymous namespace that hides a few helper classes for the control
232// initial condition construction. In particual an IC Equation set is defined that
233// is useful for building initial condition vectors.
234namespace {
235
236template <typename EvalT>
237class EquationSet_IC : public EquationSet_DefaultImpl<EvalT> {
238public:
239
243 EquationSet_IC(const Teuchos::RCP<Teuchos::ParameterList>& params,
244 const int& default_integration_order,
245 const CellData& cell_data,
246 const Teuchos::RCP<GlobalData>& global_data,
247 const bool build_transient_support);
248
251 void buildAndRegisterEquationSetEvaluators(PHX::FieldManager<Traits>& /* fm */,
252 const FieldLibrary& /* field_library */,
253 const Teuchos::ParameterList& /* user_data */) const {}
254
255};
256
257// ***********************************************************************
258template <typename EvalT>
259EquationSet_IC<EvalT>::
260EquationSet_IC(const Teuchos::RCP<Teuchos::ParameterList>& params,
261 const int& default_integration_order,
262 const CellData& cell_data,
263 const Teuchos::RCP<GlobalData>& global_data,
264 const bool build_transient_support) :
265 EquationSet_DefaultImpl<EvalT>(params, default_integration_order, cell_data, global_data, build_transient_support )
266{
267 // ********************
268 // Validate and parse parameter list
269 // ********************
270 Teuchos::ParameterList valid_parameters_sublist;
271 valid_parameters_sublist.set("Basis Type","HGrad","Type of Basis to use");
272 valid_parameters_sublist.set("Basis Order",1,"Order of the basis");
273
274 for(auto itr=params->begin();itr!=params->end();++itr) {
275
276 const std::string field = params->name(itr);
277 const Teuchos::ParameterEntry & entry = params->entry(itr);
278
279 // only process lists
280 if(!entry.isList()) continue;
281
282 Teuchos::ParameterList & basisPL = entry.getValue((Teuchos::ParameterList *) 0);
283 basisPL.validateParametersAndSetDefaults(valid_parameters_sublist);
284
285 std::string basis_type = basisPL.get<std::string>("Basis Type");
286 int basis_order = basisPL.get<int>("Basis Order");
287
288 this->addDOF(field,basis_type,basis_order,default_integration_order);
289 }
290
291 this->addClosureModel("");
292
293 this->setupDOFs();
294}
295
296PANZER_DECLARE_EQSET_TEMPLATE_BUILDER(EquationSet_IC, EquationSet_IC)
297
298// A user written factory that creates each equation set. The key member here
299// is buildEquationSet
300class IC_EquationSetFactory : public EquationSetFactory {
301public:
302
303 Teuchos::RCP<EquationSet_TemplateManager<Traits> >
304 buildEquationSet(const Teuchos::RCP<Teuchos::ParameterList>& params,
305 const int& default_integration_order,
306 const CellData& cell_data,
307 const Teuchos::RCP<GlobalData>& global_data,
308 const bool build_transient_support) const
309 {
310 Teuchos::RCP<EquationSet_TemplateManager<Traits> > eq_set=
311 Teuchos::rcp(new EquationSet_TemplateManager<Traits>);
312
313 bool found = false; // this is used by PANZER_BUILD_EQSET_OBJECTS
314
315 // macro checks if(ies.name=="Poisson") then an EquationSet_Energy object is constructed
316 PANZER_BUILD_EQSET_OBJECTS("IC", EquationSet_IC)
317
318 // make sure your equation set has been found
319 if(!found) {
320 std::string msg = "Error - the \"Equation Set\" called \"" + params->get<std::string>("Type") +
321 "\" is not a valid equation set identifier. Please supply the correct factory.\n";
322 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, msg);
323 }
324
325 return eq_set;
326 }
327
328};
329
330} // end anonymous namespace
331
332void
333setupControlInitialCondition(const std::map<std::string,Teuchos::RCP<const shards::CellTopology> > & block_ids_to_cell_topo,
334 const std::map<std::string,std::vector<ICFieldDescriptor> > & block_ids_to_fields,
335 WorksetContainer & wkstContainer,
336 const LinearObjFactory<Traits> & lof,
338 const Teuchos::ParameterList & ic_closure_models,
339 const Teuchos::ParameterList & user_data,
340 int workset_size,
341 double t0,
342 const Teuchos::RCP<Thyra::VectorBase<double> > & vec)
343{
344 std::vector<Teuchos::RCP<PhysicsBlock> > physics_blocks;
345 buildICPhysicsBlocks(block_ids_to_cell_topo,block_ids_to_fields,workset_size,physics_blocks);
346
347 std::map<std::string, Teuchos::RCP< PHX::FieldManager<Traits> > > phx_ic_field_managers;
349 physics_blocks,
350 cm_factory,
351 ic_closure_models,
352 lof,
353 user_data,
354 false,
355 "initial_condition_control_test",
356 phx_ic_field_managers);
357
358
359 Teuchos::RCP<LinearObjContainer> loc = lof.buildLinearObjContainer();
360 Teuchos::rcp_dynamic_cast<ThyraObjContainer<double> >(loc)->set_x_th(vec);
361
362 evaluateInitialCondition(wkstContainer, phx_ic_field_managers, loc, lof, t0);
363}
364
365
366void
367buildICPhysicsBlocks(const std::map<std::string,Teuchos::RCP<const shards::CellTopology> > & block_ids_to_cell_topo,
368 const std::map<std::string,std::vector<ICFieldDescriptor> > & block_ids_to_fields,
369 int workset_size,
370 std::vector<Teuchos::RCP<PhysicsBlock> > & physics_blocks)
371{
372 using Teuchos::RCP;
373 using Teuchos::rcp;
374
375 std::map<std::string,std::string> block_ids_to_physics_ids;
376
377 RCP<Teuchos::ParameterList> ipb = rcp(new Teuchos::ParameterList);
378
379 for(auto itr=block_ids_to_cell_topo.begin();itr!=block_ids_to_cell_topo.end();++itr) {
380 std::string eblock = itr->first;
381 RCP<const shards::CellTopology> ct = itr->second;
382
383 // get the field descriptor vector, check to make sure block is represented
384 auto fds_itr = block_ids_to_fields.find(eblock);
385 TEUCHOS_ASSERT(fds_itr!=block_ids_to_fields.end());
386
387 const std::vector<ICFieldDescriptor> & fd_vec = fds_itr->second;
388
389 std::string physics_id = "ic_"+eblock;
390 block_ids_to_physics_ids[eblock] = physics_id;
391
392 // start building a physics block named "ic_"+eblock, with one anonymous list
393 Teuchos::ParameterList & physics_block = ipb->sublist(physics_id).sublist("");
394 physics_block.set("Type","IC"); // point IC type
395
396 for(std::size_t i=0;i<fd_vec.size();i++) {
397 const ICFieldDescriptor & fd = fd_vec[i];
398
399 // number the lists, these should be anonymous
400 physics_block.sublist(fd.fieldName).set("Basis Type", fd.basisName);
401 physics_block.sublist(fd.fieldName).set("Basis Order",fd.basisOrder);
402 }
403 }
404
405 RCP<EquationSetFactory> eqset_factory = Teuchos::rcp(new IC_EquationSetFactory);
406
407 RCP<GlobalData> gd = createGlobalData();
408 buildPhysicsBlocks(block_ids_to_physics_ids,
409 block_ids_to_cell_topo,
410 ipb,1,workset_size,eqset_factory,gd,false,physics_blocks);
411}
412
413} // end namespace panzer
#define PANZER_BUILD_EQSET_OBJECTS(key, fType)
#define PANZER_DECLARE_EQSET_TEMPLATE_BUILDER(fClass, fType)
PHX::MDField< ScalarT, panzer::Cell, panzer::BASIS > field
A field to which we'll contribute, or in which we'll store, the result of computing this integral.
void addDataObject(const std::string &key, const Teuchos::RCP< GlobalEvaluationData > &ged)
std::unordered_map< std::string, Teuchos::RCP< GlobalEvaluationData > >::iterator iterator
virtual Teuchos::RCP< LinearObjContainer > buildLinearObjContainer() const =0
virtual void initializeGhostedContainer(int, LinearObjContainer &loc) const =0
virtual Teuchos::RCP< LinearObjContainer > buildGhostedLinearObjContainer() const =0
virtual Teuchos::RCP< LinearObjContainer > buildPrimitiveGhostedLinearObjContainer() const =0
virtual void globalToGhostContainer(const LinearObjContainer &container, LinearObjContainer &ghostContainer, int) const =0
virtual void ghostToGlobalContainer(const LinearObjContainer &ghostContainer, LinearObjContainer &container, int) const =0
virtual Teuchos::RCP< LinearObjContainer > buildPrimitiveLinearObjContainer() const =0
virtual void initializeContainer(int, LinearObjContainer &loc) const =0
virtual void adjustForDirichletConditions(const LinearObjContainer &localBCRows, const LinearObjContainer &globalBCRows, LinearObjContainer &ghostedObjs, bool zeroVectorRows=false, bool adjustX=false) const =0
Class that provides access to worksets on each element block and side set.
Teuchos::RCP< std::vector< Workset > > getWorksets(const WorksetDescriptor &wd)
Access to volume worksets.
Teuchos::RCP< const std::vector< Intrepid2::Orientation > > getOrientations() const
WorksetDescriptor blockDescriptor(const std::string &eBlock)
void buildICPhysicsBlocks(const std::map< std::string, Teuchos::RCP< const shards::CellTopology > > &block_ids_to_cell_topo, const std::map< std::string, std::vector< ICFieldDescriptor > > &block_ids_to_fields, int workset_size, std::vector< Teuchos::RCP< PhysicsBlock > > &physics_blocks)
Teuchos::RCP< panzer::GlobalData > createGlobalData(bool build_default_os, int print_process)
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 setupControlInitialCondition(const std::map< std::string, Teuchos::RCP< const shards::CellTopology > > &block_ids_to_cell_topo, const std::map< std::string, std::vector< ICFieldDescriptor > > &block_ids_to_fields, WorksetContainer &wkstContainer, const LinearObjFactory< Traits > &lof, const ClosureModelFactory_TemplateManager< Traits > &cm_factory, const Teuchos::ParameterList &ic_closure_models, const Teuchos::ParameterList &user_data, int workset_size, double t0, const Teuchos::RCP< Thyra::VectorBase< double > > &vec)
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)
Teuchos::RCP< GlobalEvaluationDataContainer > gedc
std::string first_sensitivities_name
Teuchos::RCP< const std::vector< panzer::Workset > > worksets_
Teuchos::RCP< const std::vector< Intrepid2::Orientation > > orientations_