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//
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
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// ***********************************************************************
76template <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// ***********************************************************************
90template <typename EvalT>
96
97// ***********************************************************************
98template <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
114template <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
205template <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
412template <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
451template <typename EvalT>
453addDOF(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
464template <typename EvalT>
466addTarget(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
481template <typename EvalT>
483addCoefficientTarget(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
500template <typename EvalT>
502addDotTarget(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
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:81
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.