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