Panzer Version of the Day
Loading...
Searching...
No Matches
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
14#include "Teuchos_ParameterList.hpp"
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
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// ***********************************************************************
44template <typename EvalT>
47 const Teuchos::RCP<panzer::GlobalData>& global_data,
48 const bool in_check_apply_bc) :
49 panzer::BCStrategy<EvalT>(bc),
51 check_apply_bc(in_check_apply_bc),
52 descriptor_map_built(false)
53{
54
55}
56
57// ***********************************************************************
58template <typename EvalT>
64
65// ***********************************************************************
66template <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
82template <typename EvalT>
85 const panzer::PhysicsBlock& pb,
87 const Teuchos::ParameterList& /* user_data */) const
88{
89 using Teuchos::ParameterList;
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();
125 RCP<panzer::PureBasis> basis;
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
156 RCP< PHX::Evaluator<panzer::Traits> > op = lof.buildScatterDirichlet<EvalT>(p);
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
173template <typename EvalT>
176 const panzer::PhysicsBlock& pb,
178 const Teuchos::ParameterList& /* user_data */) const
179{
180 using Teuchos::ParameterList;
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 {
206 RCP< PHX::Evaluator<panzer::Traits> > basis_op
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 {
216 RCP< PHX::Evaluator<panzer::Traits> > eval
217 = rcp(new panzer::PointValues_Evaluator<EvalT,panzer::Traits>(pointRule,basis));
218
219 this->template registerEvaluator<EvalT>(fm, eval);
220 }
221 {
222 // note basis values are not constructed!
223 RCP< PHX::Evaluator<panzer::Traits> > eval
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();
242 RCP<panzer::PureBasis> basis;
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
266 RCP< PHX::Evaluator<panzer::Traits> > op = lof.buildGather<EvalT>(p);
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
281 RCP< PHX::Evaluator<panzer::Traits> > op = lof.buildGatherOrientation<EvalT>(p);
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
295 RCP< PHX::Evaluator<panzer::Traits> > eval
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();
319 RCP<panzer::PureBasis> basis;
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
338 RCP< PHX::Evaluator<panzer::Traits> > op =
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
354 RCP< PHX::Evaluator<panzer::Traits> > op =
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
369 RCP< PHX::Evaluator<panzer::Traits> > op =
371
372 this->template registerEvaluator<EvalT>(fm, op);
373 }
374
375 }
376}
377
378// ***********************************************************************
379
380template <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
419template <typename EvalT>
421addDOF(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
432template <typename EvalT>
434addTarget(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
449template <typename EvalT>
451addCoefficientTarget(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
468template <typename EvalT>
470addDotTarget(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
virtual void buildAndRegisterGatherAndOrientationEvaluators(PHX::FieldManager< panzer::Traits > &fm, const panzer::PhysicsBlock &side_pb, const LinearObjFactory< panzer::Traits > &lof, const Teuchos::ParameterList &user_data) const
std::map< std::string, DOFDescriptor >::const_iterator DescriptorIterator
For convenience, declare the DOFDescriptor iterator.
virtual void buildAndRegisterScatterEvaluators(PHX::FieldManager< panzer::Traits > &fm, const panzer::PhysicsBlock &side_pb, const LinearObjFactory< panzer::Traits > &lof, const Teuchos::ParameterList &user_data) 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
BCStrategy_Dirichlet_DefaultImpl(const panzer::BC &bc, const Teuchos::RCP< panzer::GlobalData > &global_data, const bool check_apply_bc=false)
void addCoefficientTarget(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="")
void addTarget(const std::string &targetName, const std::string &dofName, const std::string &residualName="")
Stores input information for a boundary condition.
Definition Panzer_BC.hpp:48
Interpolates basis DOF values to IP DOF values.
Data for determining cell topology and dimensionality.
Teuchos::RCP< const shards::CellTopology > getCellTopology() const
Get CellTopology for the base cell.
std::size_t numCells() const
Interpolates basis DOF values to IP DOF Curl values.
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.
Default implementation for accessing the GlobalData object.
Teuchos::RCP< PHX::Evaluator< Traits > > buildScatterDirichlet(const Teuchos::ParameterList &pl) const
Use preconstructed dirichlet scatter evaluators.
Teuchos::RCP< PHX::Evaluator< Traits > > buildGatherOrientation(const Teuchos::ParameterList &pl) const
Use preconstructed gather evaluators.
Teuchos::RCP< PHX::Evaluator< Traits > > buildGather(const Teuchos::ParameterList &pl) const
Use preconstructed gather evaluators.
Object that contains information on the physics and discretization of a block of elements with the SA...
const shards::CellTopology getBaseCellTopology() 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.
const panzer::CellData & cellData() const
const std::vector< StrPureBasisPair > & getProvidedDOFs() const
Interpolates basis DOF values to IP DOF values.