Panzer  Version of the Day
Panzer_BCStrategy_Dirichlet_DefaultImpl_impl.hpp
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 
43 #ifndef PANZER_BCSTRATEGY_DIRICHLET_DEFAULT_IMPL_IMPL_HPP
44 #define PANZER_BCSTRATEGY_DIRICHLET_DEFAULT_IMPL_IMPL_HPP
45 
46 #include "Teuchos_ParameterList.hpp"
47 #include "Teuchos_RCP.hpp"
48 #include "Teuchos_Assert.hpp"
49 
50 #include "Phalanx_DataLayout_MDALayout.hpp"
51 #include "Phalanx_FieldManager.hpp"
52 
53 #include "Phalanx_MDField.hpp"
54 #include "Phalanx_DataLayout.hpp"
55 #include "Phalanx_DataLayout_MDALayout.hpp"
56 
57 // Evaluators
58 #include "Panzer_PhysicsBlock.hpp"
59 #include "Panzer_PureBasis.hpp"
60 #include "Panzer_Dirichlet_Residual.hpp"
63 
64 #ifdef PANZER_HAVE_EPETRA_STACK
65 #include "Panzer_GatherSolution_Epetra.hpp"
66 #include "Panzer_ScatterDirichletResidual_Epetra.hpp"
67 #endif
68 
69 #include "Panzer_GatherBasisCoordinates.hpp"
70 #include "Panzer_BasisValues_Evaluator.hpp"
71 #include "Panzer_PointValues_Evaluator.hpp"
72 #include "Panzer_DOF.hpp"
74 
75 // ***********************************************************************
76 template <typename EvalT>
79  const Teuchos::RCP<panzer::GlobalData>& global_data,
80  const bool in_check_apply_bc) :
81  panzer::BCStrategy<EvalT>(bc),
83  check_apply_bc(in_check_apply_bc),
84  descriptor_map_built(false)
85 {
86 
87 }
88 
89 // ***********************************************************************
90 template <typename EvalT>
93 {
94 
95 }
96 
97 // ***********************************************************************
98 template <typename EvalT>
101  const panzer::PhysicsBlock& pb,
103  const Teuchos::ParameterList& user_data) const
104 {
105  // for deprecated interface support
106  buildDescriptorMapFromVectors();
107 
108  buildAndRegisterGatherAndOrientationEvaluators(fm,pb,lof,user_data);
109  buildAndRegisterScatterEvaluators(fm,pb,lof,user_data);
110 }
111 
112 // ***********************************************************************
113 
114 template <typename EvalT>
117  const panzer::PhysicsBlock& pb,
119  const Teuchos::ParameterList& /* user_data */) const
120 {
121  using Teuchos::ParameterList;
122  using Teuchos::RCP;
123  using Teuchos::rcp;
124  using std::vector;
125  using std::map;
126  using std::string;
127  using std::pair;
128 
129  // for deprecated interface support
130  buildDescriptorMapFromVectors();
131 
132  // Scatter
133  // for (map<string,string>::const_iterator res_to_dof = residual_to_dof_names_map.begin();
134  // res_to_dof != residual_to_dof_names_map.end(); ++res_to_dof) {
135  for(DescriptorIterator itr=m_provided_dofs_desc.begin();
136  itr!=m_provided_dofs_desc.end(); ++itr) {
137 
138  const DOFDescriptor & desc = itr->second;
139 
140  // there is no residual to scatter
141  if(!desc.residualName.first)
142  continue;
143 
144  // std::string residualName = res_to_dof->first;
145  // std::string dofName = res_to_dof->second;
146  std::string dofName = desc.dofName;
147  std::string residualName = desc.residualName.second;
148 
149  ParameterList p("Scatter: "+residualName + " to " + dofName);
150 
151  // Set name
152  string scatter_field_name = "Dummy Scatter: " + this->m_bc.identifier() + residualName;
153  p.set("Scatter Name", scatter_field_name);
154 
155  // Set basis
156  const vector<pair<string,RCP<panzer::PureBasis> > >& dofBasisPair = pb.getProvidedDOFs();
157  RCP<panzer::PureBasis> basis;
158  for (vector<pair<string,RCP<panzer::PureBasis> > >::const_iterator it =
159  dofBasisPair.begin(); it != dofBasisPair.end(); ++it) {
160  if (it->first == dofName)
161  basis = it->second;
162  }
163 
164  TEUCHOS_TEST_FOR_EXCEPTION(Teuchos::is_null(basis), std::runtime_error,
165  "Error the name \"" << dofName
166  << "\" is not a valid DOF for the boundary condition:\n"
167  << this->m_bc << "\n");
168 
169  p.set("Basis", basis);
170 
171  RCP<vector<string> > residual_names = rcp(new vector<string>);
172  residual_names->push_back(residualName);
173  p.set("Dependent Names", residual_names);
174 
175  RCP<map<string,string> > names_map = rcp(new map<string,string>);
176  names_map->insert(std::make_pair(residualName,dofName));
177  p.set("Dependent Map", names_map);
178 
179  TEUCHOS_TEST_FOR_EXCEPTION(!pb.cellData().isSide(), std::logic_error,
180  "Error - physics block is not a side set!");
181 
182  p.set<int>("Side Subcell Dimension",
183  pb.getBaseCellTopology().getDimension() - 1);
184  p.set<int>("Local Side ID", pb.cellData().side());
185 
186  p.set("Check Apply BC",check_apply_bc);
187 
188  RCP< PHX::Evaluator<panzer::Traits> > op = lof.buildScatterDirichlet<EvalT>(p);
189 
190  this->template registerEvaluator<EvalT>(fm, op);
191 
192  // Require variables
193  {
194  using panzer::Dummy;
195  PHX::Tag<typename EvalT::ScalarT> tag(scatter_field_name,
196  rcp(new PHX::MDALayout<Dummy>(0)));
197  fm.template requireField<EvalT>(tag);
198  }
199 
200  }
201 }
202 
203 // ***********************************************************************
204 
205 template <typename EvalT>
208  const panzer::PhysicsBlock& pb,
210  const Teuchos::ParameterList& /* user_data */) const
211 {
212  using Teuchos::ParameterList;
213  using Teuchos::RCP;
214  using Teuchos::rcp;
215  using std::vector;
216  using std::map;
217  using std::string;
218  using std::pair;
219 
220  // for deprecated interface support
221  buildDescriptorMapFromVectors();
222 
223  // volume cell data object (used for handling vector valued fields)
225 
226  // **************************
227  // Coordinates for basis functions (no integration points needed)
228  // **************************
229  {
230  const std::map<std::string,Teuchos::RCP<panzer::PureBasis> > & bases = pb.getBases();
231  for (std::map<std::string,Teuchos::RCP<panzer::PureBasis> >::const_iterator it=bases.begin();
232  it!=bases.end();it++) {
233 
234  Teuchos::RCP<panzer::PureBasis> basis = it->second;
235 
236  // add basis coordinates no matter what
237  {
238  RCP< PHX::Evaluator<panzer::Traits> > basis_op
240  this->template registerEvaluator<EvalT>(fm, basis_op);
241  }
242 
243  // add point values and basis values
244  if(basis->isVectorBasis()) {
245  RCP<const panzer::PointRule> pointRule = rcp(new panzer::PointRule(basis->name()+":BasisPoints",basis->cardinality(),cellData));
246 
247  {
248  RCP< PHX::Evaluator<panzer::Traits> > eval
249  = rcp(new panzer::PointValues_Evaluator<EvalT,panzer::Traits>(pointRule,basis));
250 
251  this->template registerEvaluator<EvalT>(fm, eval);
252  }
253  {
254  // note basis values are not constructed!
255  RCP< PHX::Evaluator<panzer::Traits> > eval
256  = rcp(new panzer::BasisValues_Evaluator<EvalT,panzer::Traits>(pointRule,basis,false));
257 
258  this->template registerEvaluator<EvalT>(fm, eval);
259  }
260  }
261  }
262  }
263 
264  // Gather
265  for(DescriptorIterator itr=m_provided_dofs_desc.begin();
266  itr!=m_provided_dofs_desc.end(); ++itr) {
267 
268  // get the dofName from the descriptor
269  std::string dofName = itr->second.dofName;
270  std::string fieldDof = !itr->second.timeDerivative.first
271  ? itr->second.dofName : itr->second.timeDerivative.second;
272 
273  const vector<pair<string,RCP<panzer::PureBasis> > >& dofBasisPair = pb.getProvidedDOFs();
274  RCP<panzer::PureBasis> basis;
275  for (vector<pair<string,RCP<panzer::PureBasis> > >::const_iterator it =
276  dofBasisPair.begin(); it != dofBasisPair.end(); ++it) {
277  if (it->first == dofName)
278  basis = it->second;
279  }
280 
281  TEUCHOS_TEST_FOR_EXCEPTION(Teuchos::is_null(basis), std::runtime_error,
282  "Error the name \"" << dofName
283  << "\" is not a valid DOF for the boundary condition:\n"
284  << this->m_bc << "\n");
285 
286  {
287  ParameterList p("BC Gather");
288  RCP<vector<string> > gather_field_names_vec = rcp(new vector<string>);
289  RCP<vector<string> > gather_names_vec = rcp(new vector<string>);
290  gather_field_names_vec->push_back(fieldDof);
291  gather_names_vec->push_back(dofName);
292 
293  p.set("DOF Names", gather_field_names_vec);
294  p.set("Indexer Names", gather_names_vec);
295  p.set("Basis", basis);
296  p.set("Use Time Derivative Solution Vector",itr->second.timeDerivative.first);
297 
298  RCP< PHX::Evaluator<panzer::Traits> > op = lof.buildGather<EvalT>(p);
299  this->template registerEvaluator<EvalT>(fm, op);
300  }
301 
302  if(basis->requiresOrientations()) {
303  ParameterList p("Gather Orientation");
304  RCP<vector<string> > gather_field_names_vec = rcp(new vector<string>);
305  RCP<vector<string> > gather_names_vec = rcp(new vector<string>);
306  gather_field_names_vec->push_back(fieldDof);
307  gather_names_vec->push_back(dofName);
308 
309  p.set("DOF Names", gather_field_names_vec);
310  p.set("Indexer Names", gather_names_vec);
311  p.set("Basis", basis);
312 
313  RCP< PHX::Evaluator<panzer::Traits> > op = lof.buildGatherOrientation<EvalT>(p);
314 
315  this->template registerEvaluator<EvalT>(fm, op);
316  }
317 
318  // evaluator a vector basis at the basis points
319  if(basis->isVectorBasis()) {
320  RCP<const panzer::PointRule> pointRule = rcp(new panzer::PointRule(basis->name()+":BasisPoints",basis->cardinality(),cellData));
321 
322  ParameterList p;
323  p.set("Name",fieldDof);
324  p.set("Basis",basis.getConst());
325  p.set("Point Rule",pointRule);
326 
327  RCP< PHX::Evaluator<panzer::Traits> > eval
329  this->template registerEvaluator<EvalT>(fm, eval);
330  }
331 
332  }
333 
334  // Dirichlet Residual: residual = dof_value - target_value
335  for(DescriptorIterator itr=m_provided_dofs_desc.begin();
336  itr!=m_provided_dofs_desc.end(); ++itr) {
337 
338  const DOFDescriptor & desc = itr->second;
339 
340  // there is no residual to scatter
341  if(!desc.residualName.first)
342  continue;
343 
344  // std::string dofName = desc.dofName;
345  std::string dofName = !itr->second.timeDerivative.first
346  ? itr->second.dofName : itr->second.timeDerivative.second;
347  std::string residualName = desc.residualName.second;
348  std::string targetName = desc.targetName.second;
349 
350  const vector<pair<string,RCP<panzer::PureBasis> > >& dofBasisPair = pb.getProvidedDOFs();
351  RCP<panzer::PureBasis> basis;
352  for (vector<pair<string,RCP<panzer::PureBasis> > >::const_iterator it =
353  dofBasisPair.begin(); it != dofBasisPair.end(); ++it) {
354  if (it->first == itr->second.dofName)
355  basis = it->second;
356  }
357 
358  TEUCHOS_TEST_FOR_EXCEPTION(Teuchos::is_null(basis), std::runtime_error,
359  "Error the name \"" << itr->second.dofName
360  << "\" is not a valid DOF for the boundary condition:\n"
361  << this->m_bc << "\n");
362 
363  if(basis->isScalarBasis() || desc.coefficientResidual) {
364  ParameterList p("Dirichlet Residual: "+residualName + " to " + dofName);
365  p.set("Residual Name", residualName);
366  p.set("DOF Name", dofName);
367  p.set("Value Name", targetName);
368  p.set("Data Layout", basis->functional);
369 
370  RCP< PHX::Evaluator<panzer::Traits> > op =
372 
373  this->template registerEvaluator<EvalT>(fm, op);
374  }
375  // This assumes that dofs on faces are all named "<dof>_face"
376  else if(basis->isVectorBasis()&&basis->supportsDiv()) {
377  RCP<const panzer::PointRule> pointRule = rcp(new panzer::PointRule(basis->name()+":BasisPoints",basis->cardinality(),cellData));
378 
379  ParameterList p;
380  p.set("Residual Name", residualName);
381  p.set("DOF Name", dofName);
382  p.set("Value Name", targetName);
383  p.set("Basis", basis.getConst());
384  p.set("Point Rule", pointRule);
385 
386  RCP< PHX::Evaluator<panzer::Traits> > op =
388 
389  this->template registerEvaluator<EvalT>(fm, op);
390  }
391  else if(basis->isVectorBasis()) {
392  RCP<const panzer::PointRule> pointRule = rcp(new panzer::PointRule(basis->name()+":BasisPoints",basis->cardinality(),cellData));
393 
394  ParameterList p;
395  p.set("Residual Name", residualName);
396  p.set("DOF Name", dofName);
397  p.set("Value Name", targetName);
398  p.set("Basis", basis.getConst());
399  p.set("Point Rule", pointRule);
400 
401  RCP< PHX::Evaluator<panzer::Traits> > op =
403 
404  this->template registerEvaluator<EvalT>(fm, op);
405  }
406 
407  }
408 }
409 
410 // ***********************************************************************
411 
412 template <typename EvalT>
415 {
416  if(descriptor_map_built)
417  return;
418 
419  // build the reverse lookup (this assumes that the map is invertible, though it should be!)
420  std::map<std::string,std::string> dof_names_to_residual_map;
421  for(std::map<std::string,std::string>::const_iterator itr=residual_to_dof_names_map.begin();
422  itr!=residual_to_dof_names_map.end();++itr) {
423  dof_names_to_residual_map[itr->second] = itr->first;
424  }
425 
426  for(std::size_t i=0;i<required_dof_names.size();i++) {
427  std::string dof_name = required_dof_names[i];
428 
429  // add the DOF right away
430  const_cast<BCStrategy_Dirichlet_DefaultImpl<EvalT> *>(this)->addDOF(dof_name);
431 
432  // add target information if its required
433  if(dof_names_to_residual_map.find(dof_name)!=dof_names_to_residual_map.end()) {
434  std::string residual_name = dof_names_to_residual_map[dof_name];
435  std::string target_name = residual_to_target_field_map.find(residual_name)->second;
436 
437  // add the descriptor from the data structures: Note the const_cast is neccessary
438  // only because this is protecting deprecated code
439  const_cast<BCStrategy_Dirichlet_DefaultImpl<EvalT> *>(this)->
440  addTarget(target_name,
441  dof_name,
442  residual_name);
443  }
444  }
445 
446  descriptor_map_built = true;
447 }
448 
449 // ***********************************************************************
450 
451 template <typename EvalT>
453 addDOF(const std::string & dofName)
454 {
455  DescriptorIterator itr = m_provided_dofs_desc.find(dofName);
456  TEUCHOS_ASSERT(itr==m_provided_dofs_desc.end());
457 
458  DOFDescriptor & desc = m_provided_dofs_desc[dofName];
459  desc.dofName = dofName;
460 }
461 
462 // ***********************************************************************
463 
464 template <typename EvalT>
466 addTarget(const std::string & targetName,
467  const std::string & dofName,
468  const std::string & residualName)
469 {
470  typename std::map<std::string,DOFDescriptor>::iterator itr = m_provided_dofs_desc.find(dofName);
471  TEUCHOS_ASSERT(itr!=m_provided_dofs_desc.end());
472 
473  DOFDescriptor & desc = itr->second;
474  desc.dofName = dofName;
475  desc.coefficientResidual = false;
476  desc.targetName = std::make_pair(true,targetName);
477  desc.residualName = (residualName=="") ? std::make_pair(true,"RESIDUAL_"+dofName)
478  : std::make_pair(true,residualName);
479 }
480 
481 template <typename EvalT>
483 addCoefficientTarget(const std::string & targetName,
484  const std::string & dofName,
485  const std::string & residualName)
486 {
487  typename std::map<std::string,DOFDescriptor>::iterator itr = m_provided_dofs_desc.find(dofName);
488  TEUCHOS_ASSERT(itr!=m_provided_dofs_desc.end());
489 
490  DOFDescriptor & desc = itr->second;
491  desc.dofName = dofName;
492  desc.coefficientResidual = true;
493  desc.targetName = std::make_pair(true,targetName);
494  desc.residualName = (residualName=="") ? std::make_pair(true,"RESIDUAL_"+dofName)
495  : std::make_pair(true,residualName);
496 }
497 
498 // ***********************************************************************
499 
500 template <typename EvalT>
502 addDotTarget(const std::string & targetName,
503  const std::string & dofName,
504  const std::string & dotName,
505  const std::string & residualName)
506 {
507  typename std::map<std::string,DOFDescriptor>::iterator itr = m_provided_dofs_desc.find(dofName);
508  TEUCHOS_ASSERT(itr!=m_provided_dofs_desc.end());
509 
510  DOFDescriptor & desc = itr->second;
511  desc.dofName = dofName;
512  desc.targetName = std::make_pair(true,targetName);
513  desc.timeDerivative = (dotName=="") ? std::make_pair(true,"DXDT_"+dofName)
514  : std::make_pair(true,dotName);
515  desc.residualName = (residualName=="") ? std::make_pair(true,"RESIDUAL_"+dofName)
516  : std::make_pair(true,residualName);
517 }
518 
519 // ***********************************************************************
520 
521 #endif
Teuchos::RCP< PHX::Evaluator< Traits > > buildScatterDirichlet(const Teuchos::ParameterList &pl) const
Use preconstructed dirichlet scatter evaluators.
Object that contains information on the physics and discretization of a block of elements with the SA...
Default implementation for accessing the GlobalData object.
Interpolates basis DOF values to IP DOF values.
Teuchos::RCP< PHX::Evaluator< Traits > > buildGather(const Teuchos::ParameterList &pl) const
Use preconstructed gather evaluators.
BCStrategy_Dirichlet_DefaultImpl(const panzer::BC &bc, const Teuchos::RCP< panzer::GlobalData > &global_data, const bool check_apply_bc=false)
Interpolates basis DOF values to IP DOF Curl values.
virtual void buildAndRegisterGatherAndOrientationEvaluators(PHX::FieldManager< panzer::Traits > &fm, const panzer::PhysicsBlock &side_pb, const LinearObjFactory< panzer::Traits > &lof, const Teuchos::ParameterList &user_data) const
Teuchos::RCP< const shards::CellTopology > getCellTopology() const
Get CellTopology for the base cell.
std::map< std::string, DOFDescriptor >::const_iterator DescriptorIterator
For convenience, declare the DOFDescriptor iterator.
Data for determining cell topology and dimensionality.
void addTarget(const std::string &targetName, const std::string &dofName, const std::string &residualName="")
bool isSide() const
void addDotTarget(const std::string &targetName, const std::string &dofName, const std::string &dotName="", const std::string &residualName="")
const panzer::CellData & cellData() const
void addCoefficientTarget(const std::string &targetName, const std::string &dofName, const std::string &residualName="")
virtual void buildAndRegisterGatherScatterEvaluators(PHX::FieldManager< panzer::Traits > &fm, const panzer::PhysicsBlock &pb, const panzer::LinearObjFactory< panzer::Traits > &lof, const Teuchos::ParameterList &user_data) const
const std::vector< StrPureBasisPair > & getProvidedDOFs() const
const std::map< std::string, Teuchos::RCP< panzer::PureBasis > > & getBases() const
Returns the unique set of bases, key is the unique panzer::PureBasis::name() of the basis...
Stores input information for a boundary condition.
Definition: Panzer_BC.hpp:81
Evaluates a Dirichlet BC residual corresponding to a field value.
Gathers coordinates for the basis function from the workset and stores them in the field manager...
const shards::CellTopology getBaseCellTopology() const
Interpolates basis DOF values to IP DOF values.
std::size_t numCells() const
virtual void buildAndRegisterScatterEvaluators(PHX::FieldManager< panzer::Traits > &fm, const panzer::PhysicsBlock &side_pb, const LinearObjFactory< panzer::Traits > &lof, const Teuchos::ParameterList &user_data) const
Teuchos::RCP< PHX::Evaluator< Traits > > buildGatherOrientation(const Teuchos::ParameterList &pl) const
Use preconstructed gather evaluators.