Panzer Version of the Day
Loading...
Searching...
No Matches
Panzer_InitialCondition_Builder.cpp
Go to the documentation of this file.
1// @HEADER
2// ***********************************************************************
3//
4// Panzer: A partial differential equation assembly
5// engine for strongly coupled complex multiphysics systems
6// Copyright (2011) Sandia Corporation
7//
8// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9// the U.S. Government retains certain rights in this software.
10//
11// Redistribution and use in source and binary forms, with or without
12// modification, are permitted provided that the following conditions are
13// met:
14//
15// 1. Redistributions of source code must retain the above copyright
16// notice, this list of conditions and the following disclaimer.
17//
18// 2. Redistributions in binary form must reproduce the above copyright
19// notice, this list of conditions and the following disclaimer in the
20// documentation and/or other materials provided with the distribution.
21//
22// 3. Neither the name of the Corporation nor the names of the
23// contributors may be used to endorse or promote products derived from
24// this software without specific prior written permission.
25//
26// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37//
38// Questions? Contact Roger P. Pawlowski (rppawlo@sandia.gov) and
39// Eric C. Cyr (eccyr@sandia.gov)
40// ***********************************************************************
41// @HEADER
42
44
45#include "Teuchos_Assert.hpp"
46
47#include "Panzer_EquationSet_DefaultImpl.hpp"
52
53namespace panzer {
54
55void
57 const std::vector<Teuchos::RCP<panzer::PhysicsBlock> >& physicsBlocks,
59 const Teuchos::ParameterList& ic_block_closure_models,
61 const Teuchos::ParameterList& user_data,
62 const bool write_graphviz_file,
63 const std::string& graphviz_file_prefix,
64 std::map< std::string, Teuchos::RCP< PHX::FieldManager<panzer::Traits> > >& phx_ic_field_managers)
65{
66 std::vector<Teuchos::RCP<panzer::PhysicsBlock> >::const_iterator blkItr;
67 for (blkItr=physicsBlocks.begin();blkItr!=physicsBlocks.end();++blkItr) {
68 Teuchos::RCP<panzer::PhysicsBlock> pb = *blkItr;
69 std::string blockId = pb->elementBlockID();
70
71 // build a field manager object
72 Teuchos::RCP<PHX::FieldManager<panzer::Traits> > fm
73 = Teuchos::rcp(new PHX::FieldManager<panzer::Traits>);
74
75 // Choose model sublist for this element block
76 std::string closure_model_name = "";
77 if (ic_block_closure_models.isSublist(blockId))
78 closure_model_name = blockId;
79 else if (ic_block_closure_models.isSublist("Default"))
80 closure_model_name = "Default";
81 else
82 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Failed to find initial condition for element block \"" << blockId
83 << "\". You must provide an initial condition for each element block or set a default!"
84 << ic_block_closure_models);
85
86 // Only the residual is used by initial conditions
87 std::vector<bool> active_evaluation_types(Sacado::mpl::size<panzer::Traits::EvalTypes>::value,false);
88 int residual_index = Sacado::mpl::find<panzer::Traits::EvalTypes,panzer::Traits::Residual>::value;
89 active_evaluation_types[residual_index] = true;
90 pb->setActiveEvaluationTypes(active_evaluation_types);
91
92 // use the physics block to register evaluators
93 pb->buildAndRegisterInitialConditionEvaluators(*fm, cm_factory, closure_model_name, ic_block_closure_models, lo_factory, user_data);
94
95 pb->activateAllEvaluationTypes();
96
97 // build the setup data using passed in information
98 Traits::SD setupData;
99 const WorksetDescriptor wd = blockDescriptor(blockId);
100 setupData.worksets_ = wkstContainer.getWorksets(wd);
101 setupData.orientations_ = wkstContainer.getOrientations();
102
103 int i=0;
104 for (auto eval_type=fm->begin(); eval_type != fm->end(); ++eval_type,++i) {
105 if (active_evaluation_types[i])
106 eval_type->postRegistrationSetup(setupData,*fm,false,false,nullptr);
107 }
108
109 phx_ic_field_managers[blockId] = fm;
110
111 if (write_graphviz_file)
112 fm->writeGraphvizFile(graphviz_file_prefix+"_IC_"+blockId);
113 }
114}
115
116void
118 const std::vector<Teuchos::RCP<panzer::PhysicsBlock> >& physicsBlocks,
120 const Teuchos::ParameterList& closure_models,
121 const Teuchos::ParameterList& ic_block_closure_models,
123 const Teuchos::ParameterList& user_data,
124 const bool write_graphviz_file,
125 const std::string& graphviz_file_prefix,
126 std::map< std::string, Teuchos::RCP< PHX::FieldManager<panzer::Traits> > >& phx_ic_field_managers)
127{
128 std::vector<Teuchos::RCP<panzer::PhysicsBlock> >::const_iterator blkItr;
129 for (blkItr=physicsBlocks.begin();blkItr!=physicsBlocks.end();++blkItr) {
130 Teuchos::RCP<panzer::PhysicsBlock> pb = *blkItr;
131 std::string blockId = pb->elementBlockID();
132
133 // build a field manager object
134 Teuchos::RCP<PHX::FieldManager<panzer::Traits> > fm
135 = Teuchos::rcp(new PHX::FieldManager<panzer::Traits>);
136
137 // Choose model sublist for this element block
138 std::string closure_model_name = "";
139 if (ic_block_closure_models.isSublist(blockId))
140 closure_model_name = blockId;
141 else if (ic_block_closure_models.isSublist("Default"))
142 closure_model_name = "Default";
143 else
144 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Failed to find initial condition for element block \"" << blockId
145 << "\". You must provide an initial condition for each element block or set a default!"
146 << ic_block_closure_models);
147
148 // Only the residual is used by initial conditions
149 std::vector<bool> active_evaluation_types(Sacado::mpl::size<panzer::Traits::EvalTypes>::value,false);
150 int residual_index = Sacado::mpl::find<panzer::Traits::EvalTypes,panzer::Traits::Residual>::value;
151 active_evaluation_types[residual_index] = true;
152 pb->setActiveEvaluationTypes(active_evaluation_types);
153
154 // build and register all closure models
155 pb->buildAndRegisterClosureModelEvaluators(*fm,cm_factory,closure_models,user_data);
156
157 // use the physics block to register evaluators
158 pb->buildAndRegisterInitialConditionEvaluators(*fm, cm_factory, closure_model_name, ic_block_closure_models, lo_factory, user_data);
159
160 pb->activateAllEvaluationTypes();
161
162 // build the setup data using passed in information
163 Traits::SD setupData;
164 const WorksetDescriptor wd = blockDescriptor(blockId);
165 setupData.worksets_ = wkstContainer.getWorksets(wd);
166 setupData.orientations_ = wkstContainer.getOrientations();
167
168 int i=0;
169 for (auto eval_type=fm->begin(); eval_type != fm->end(); ++eval_type,++i) {
170 if (active_evaluation_types[i])
171 eval_type->postRegistrationSetup(setupData,*fm,false,false,nullptr);
172 }
173
174 phx_ic_field_managers[blockId] = fm;
175
176 if (write_graphviz_file)
177 fm->writeGraphvizFile(graphviz_file_prefix+"_IC_"+blockId);
178 }
179}
180
181void
183 const std::map< std::string,Teuchos::RCP< PHX::FieldManager<panzer::Traits> > >& phx_ic_field_managers,
184 Teuchos::RCP<panzer::LinearObjContainer> loc,
186 const double time_stamp)
187{
188 typedef LinearObjContainer LOC;
190
191 // allocate a ghosted container for the initial condition
192 Teuchos::RCP<LOC> ghostedloc = lo_factory.buildGhostedLinearObjContainer();
193 lo_factory.initializeGhostedContainer(LOC::X,*ghostedloc);
194
195 // allocate a counter to keep track of where this processor set initial conditions
196 Teuchos::RCP<LOC> localCounter = lo_factory.buildPrimitiveGhostedLinearObjContainer();
197 Teuchos::RCP<LOC> globalCounter = lo_factory.buildPrimitiveLinearObjContainer();
198 Teuchos::RCP<LOC> summedGhostedCounter = lo_factory.buildPrimitiveGhostedLinearObjContainer();
199
200 lo_factory.initializeGhostedContainer(LOC::F,*localCounter); // store counter in F
201 localCounter->initialize();
202
203 ped.gedc->addDataObject("Residual Scatter Container",ghostedloc);
204 ped.gedc->addDataObject("Dirichlet Counter",localCounter);
206
207 for(std::map< std::string,Teuchos::RCP< PHX::FieldManager<panzer::Traits> > >::const_iterator itr=phx_ic_field_managers.begin();
208 itr!=phx_ic_field_managers.end();++itr) {
209 std::string blockId = itr->first;
210 Teuchos::RCP< PHX::FieldManager<panzer::Traits> > fm = itr->second;
211
212 fm->preEvaluate<panzer::Traits::Residual>(ped);
213
214 // Loop over worksets in this element block
215 const WorksetDescriptor wd = blockDescriptor(blockId);
216 std::vector<panzer::Workset>& w = *wkstContainer.getWorksets(wd);
217 for (std::size_t i = 0; i < w.size(); ++i) {
218 panzer::Workset& workset = w[i];
219 workset.time = time_stamp;
220
221 fm->evaluateFields<panzer::Traits::Residual>(workset);
222 }
223 }
224
225 lo_factory.initializeGhostedContainer(LOC::F,*summedGhostedCounter); // store counter in F
226 summedGhostedCounter->initialize();
227
228 // do communication to build summed ghosted counter for dirichlet conditions
229 {
230 lo_factory.initializeContainer(LOC::F,*globalCounter); // store counter in F
231 globalCounter->initialize();
232 lo_factory.ghostToGlobalContainer(*localCounter,*globalCounter,LOC::F);
233 // Here we do the reduction across all processors so that the number of times
234 // a dirichlet condition is applied is summed into the global counter
235
236 lo_factory.globalToGhostContainer(*globalCounter,*summedGhostedCounter,LOC::F);
237 // finally we move the summed global vector into a local ghosted vector
238 // so that the dirichlet conditions can be applied to both the ghosted
239 // right hand side and the ghosted matrix
240 }
241
243 gedc.addDataObject("Residual Scatter Container",ghostedloc);
244
245 // adjust ghosted system for boundary conditions
246 for(GlobalEvaluationDataContainer::iterator itr=gedc.begin();itr!=gedc.end();itr++) {
247 Teuchos::RCP<LOC> loc2 = Teuchos::rcp_dynamic_cast<LOC>(itr->second);
248 if(loc2!=Teuchos::null) {
249 bool zeroVectorRows = false;
250 bool adjustX = true;
251 lo_factory.adjustForDirichletConditions(*localCounter,*summedGhostedCounter,*loc2, zeroVectorRows, adjustX);
252 }
253 }
254
255 // gather the ghosted solution back into the global container, which performs the sum
256 lo_factory.ghostToGlobalContainer(*ghostedloc,*loc,LOC::X);
257}
258
259// This is an anonymous namespace that hides a few helper classes for the control
260// initial condition construction. In particual an IC Equation set is defined that
261// is useful for building initial condition vectors.
262namespace {
263
264template <typename EvalT>
265class EquationSet_IC : public EquationSet_DefaultImpl<EvalT> {
266public:
267
271 EquationSet_IC(const Teuchos::RCP<Teuchos::ParameterList>& params,
272 const int& default_integration_order,
273 const CellData& cell_data,
274 const Teuchos::RCP<GlobalData>& global_data,
275 const bool build_transient_support);
276
279 void buildAndRegisterEquationSetEvaluators(PHX::FieldManager<Traits>& /* fm */,
280 const FieldLibrary& /* field_library */,
281 const Teuchos::ParameterList& /* user_data */) const {}
282
283};
284
285// ***********************************************************************
286template <typename EvalT>
287EquationSet_IC<EvalT>::
288EquationSet_IC(const Teuchos::RCP<Teuchos::ParameterList>& params,
289 const int& default_integration_order,
290 const CellData& cell_data,
291 const Teuchos::RCP<GlobalData>& global_data,
292 const bool build_transient_support) :
293 EquationSet_DefaultImpl<EvalT>(params, default_integration_order, cell_data, global_data, build_transient_support )
294{
295 // ********************
296 // Validate and parse parameter list
297 // ********************
298 Teuchos::ParameterList valid_parameters_sublist;
299 valid_parameters_sublist.set("Basis Type","HGrad","Type of Basis to use");
300 valid_parameters_sublist.set("Basis Order",1,"Order of the basis");
301
302 for(auto itr=params->begin();itr!=params->end();++itr) {
303
304 const std::string field = params->name(itr);
305 const Teuchos::ParameterEntry & entry = params->entry(itr);
306
307 // only process lists
308 if(!entry.isList()) continue;
309
310 Teuchos::ParameterList & basisPL = entry.getValue((Teuchos::ParameterList *) 0);
311 basisPL.validateParametersAndSetDefaults(valid_parameters_sublist);
312
313 std::string basis_type = basisPL.get<std::string>("Basis Type");
314 int basis_order = basisPL.get<int>("Basis Order");
315
316 this->addDOF(field,basis_type,basis_order,default_integration_order);
317 }
318
319 this->addClosureModel("");
320
321 this->setupDOFs();
322}
323
324PANZER_DECLARE_EQSET_TEMPLATE_BUILDER(EquationSet_IC, EquationSet_IC)
325
326// A user written factory that creates each equation set. The key member here
327// is buildEquationSet
328class IC_EquationSetFactory : public EquationSetFactory {
329public:
330
331 Teuchos::RCP<EquationSet_TemplateManager<Traits> >
332 buildEquationSet(const Teuchos::RCP<Teuchos::ParameterList>& params,
333 const int& default_integration_order,
334 const CellData& cell_data,
335 const Teuchos::RCP<GlobalData>& global_data,
336 const bool build_transient_support) const
337 {
338 Teuchos::RCP<EquationSet_TemplateManager<Traits> > eq_set=
339 Teuchos::rcp(new EquationSet_TemplateManager<Traits>);
340
341 bool found = false; // this is used by PANZER_BUILD_EQSET_OBJECTS
342
343 // macro checks if(ies.name=="Poisson") then an EquationSet_Energy object is constructed
344 PANZER_BUILD_EQSET_OBJECTS("IC", EquationSet_IC)
345
346 // make sure your equation set has been found
347 if(!found) {
348 std::string msg = "Error - the \"Equation Set\" called \"" + params->get<std::string>("Type") +
349 "\" is not a valid equation set identifier. Please supply the correct factory.\n";
350 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, msg);
351 }
352
353 return eq_set;
354 }
355
356};
357
358} // end anonymous namespace
359
360void
361setupControlInitialCondition(const std::map<std::string,Teuchos::RCP<const shards::CellTopology> > & block_ids_to_cell_topo,
362 const std::map<std::string,std::vector<ICFieldDescriptor> > & block_ids_to_fields,
363 WorksetContainer & wkstContainer,
364 const LinearObjFactory<Traits> & lof,
366 const Teuchos::ParameterList & ic_closure_models,
367 const Teuchos::ParameterList & user_data,
368 int workset_size,
369 double t0,
370 const Teuchos::RCP<Thyra::VectorBase<double> > & vec)
371{
372 std::vector<Teuchos::RCP<PhysicsBlock> > physics_blocks;
373 buildICPhysicsBlocks(block_ids_to_cell_topo,block_ids_to_fields,workset_size,physics_blocks);
374
375 std::map<std::string, Teuchos::RCP< PHX::FieldManager<Traits> > > phx_ic_field_managers;
377 physics_blocks,
378 cm_factory,
379 ic_closure_models,
380 lof,
381 user_data,
382 false,
383 "initial_condition_control_test",
384 phx_ic_field_managers);
385
386
387 Teuchos::RCP<LinearObjContainer> loc = lof.buildLinearObjContainer();
388 Teuchos::rcp_dynamic_cast<ThyraObjContainer<double> >(loc)->set_x_th(vec);
389
390 evaluateInitialCondition(wkstContainer, phx_ic_field_managers, loc, lof, t0);
391}
392
393
394void
395buildICPhysicsBlocks(const std::map<std::string,Teuchos::RCP<const shards::CellTopology> > & block_ids_to_cell_topo,
396 const std::map<std::string,std::vector<ICFieldDescriptor> > & block_ids_to_fields,
397 int workset_size,
398 std::vector<Teuchos::RCP<PhysicsBlock> > & physics_blocks)
399{
400 using Teuchos::RCP;
401 using Teuchos::rcp;
402
403 std::map<std::string,std::string> block_ids_to_physics_ids;
404
405 RCP<Teuchos::ParameterList> ipb = rcp(new Teuchos::ParameterList);
406
407 for(auto itr=block_ids_to_cell_topo.begin();itr!=block_ids_to_cell_topo.end();++itr) {
408 std::string eblock = itr->first;
409 RCP<const shards::CellTopology> ct = itr->second;
410
411 // get the field descriptor vector, check to make sure block is represented
412 auto fds_itr = block_ids_to_fields.find(eblock);
413 TEUCHOS_ASSERT(fds_itr!=block_ids_to_fields.end());
414
415 const std::vector<ICFieldDescriptor> & fd_vec = fds_itr->second;
416
417 std::string physics_id = "ic_"+eblock;
418 block_ids_to_physics_ids[eblock] = physics_id;
419
420 // start building a physics block named "ic_"+eblock, with one anonymous list
421 Teuchos::ParameterList & physics_block = ipb->sublist(physics_id).sublist("");
422 physics_block.set("Type","IC"); // point IC type
423
424 for(std::size_t i=0;i<fd_vec.size();i++) {
425 const ICFieldDescriptor & fd = fd_vec[i];
426
427 // number the lists, these should be anonymous
428 physics_block.sublist(fd.fieldName).set("Basis Type", fd.basisName);
429 physics_block.sublist(fd.fieldName).set("Basis Order",fd.basisOrder);
430 }
431 }
432
433 RCP<EquationSetFactory> eqset_factory = Teuchos::rcp(new IC_EquationSetFactory);
434
435 RCP<GlobalData> gd = createGlobalData();
436 buildPhysicsBlocks(block_ids_to_physics_ids,
437 block_ids_to_cell_topo,
438 ipb,1,workset_size,eqset_factory,gd,false,physics_blocks);
439}
440
441} // end namespace panzer
#define PANZER_BUILD_EQSET_OBJECTS(key, fType)
#define PANZER_DECLARE_EQSET_TEMPLATE_BUILDER(fClass, fType)
Data for determining cell topology and dimensionality.
void addClosureModel(const std::string &closure_model)
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
void buildPhysicsBlocks(const std::map< std::string, std::string > &block_ids_to_physics_ids, const std::map< std::string, Teuchos::RCP< const shards::CellTopology > > &block_ids_to_cell_topo, const Teuchos::RCP< Teuchos::ParameterList > &physics_blocks_plist, const int default_integration_order, const std::size_t workset_size, const Teuchos::RCP< const panzer::EquationSetFactory > &eqset_factory, const Teuchos::RCP< panzer::GlobalData > &global_data, const bool build_transient_support, std::vector< Teuchos::RCP< panzer::PhysicsBlock > > &physicsBlocks, const std::vector< std::string > &tangent_param_names=std::vector< std::string >())
Nonmember function for building the physics blocks from a Teuchos::ParameterList for a given list of ...
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 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)
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)
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_