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 //
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 
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),
82  panzer::GlobalDataAcceptorDefaultImpl(global_data),
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 {
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();
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 
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 {
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  {
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  {
250 
251  this->template registerEvaluator<EvalT>(fm, eval);
252  }
253  {
254  // note basis values are not constructed!
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();
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 
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 
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 
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();
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 
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 
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 
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
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:81
#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