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