Panzer Version of the Day
Loading...
Searching...
No Matches
Panzer_AssemblyEngine_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_ASSEMBLY_ENGINE_IMPL_HPP
12#define PANZER_ASSEMBLY_ENGINE_IMPL_HPP
13
14#include "Phalanx_FieldManager.hpp"
18#include <sstream>
19
20//===========================================================================
21//===========================================================================
22template <typename EvalT>
24AssemblyEngine(const Teuchos::RCP<panzer::FieldManagerBuilder>& fmb,
25 const Teuchos::RCP<const panzer::LinearObjFactory<panzer::Traits> > & lof)
26 : m_field_manager_builder(fmb), m_lin_obj_factory(lof), countersInitialized_(false)
27{
28
29}
30
31//===========================================================================
32//===========================================================================
33template <typename EvalT>
36{
37 typedef LinearObjContainer LOC;
38
39 // make sure this container gets a dirichlet adjustment
40 in.ghostedContainer_->setRequiresDirichletAdjustment(true);
41
43
44 if ( flags.getValue() & EvaluationFlags::Initialize ) {
45 PANZER_FUNC_TIME_MONITOR_DIFF("panzer::AssemblyEngine::evaluate_gather("+PHX::print<EvalT>()+")", eval_gather);
46
48 gedc.initialize(); // make sure all ghosted data is ready to go
49 gedc.globalToGhost(LOC::X | LOC::DxDt);
50
51 // Push solution, x and dxdt into ghosted domain
52 m_lin_obj_factory->globalToGhostContainer(*in.container_,*in.ghostedContainer_,LOC::X | LOC::DxDt);
53 m_lin_obj_factory->beginFill(*in.ghostedContainer_);
54 }
55
56 // *********************
57 // Volumetric fill
58 // *********************
59 if ( flags.getValue() & EvaluationFlags::VolumetricFill) {
60 PANZER_FUNC_TIME_MONITOR_DIFF("panzer::AssemblyEngine::evaluate_volume("+PHX::print<EvalT>()+")", eval_vol);
61 this->evaluateVolume(in);
62 }
63
64 // *********************
65 // BC fill
66 // *********************
67 // NOTE: We have to split neumann and dirichlet bcs since dirichlet
68 // bcs overwrite equations where neumann sum into equations. Make
69 // sure all neumann are done before dirichlet.
70
71 if ( flags.getValue() & EvaluationFlags::BoundaryFill) {
72 {
73 PANZER_FUNC_TIME_MONITOR_DIFF("panzer::AssemblyEngine::evaluate_neumannbcs("+PHX::print<EvalT>()+")",eval_neumannbcs);
74 this->evaluateNeumannBCs(in);
75 }
76
77 {
78 PANZER_FUNC_TIME_MONITOR_DIFF("panzer::AssemblyEngine::evaluate_interfacebcs("+PHX::print<EvalT>()+")",eval_interfacebcs);
79 this->evaluateInterfaceBCs(in);
80 }
81
82 // Dirchlet conditions require a global matrix
83 {
84 PANZER_FUNC_TIME_MONITOR_DIFF("panzer::AssemblyEngine::evaluate_dirichletbcs("+PHX::print<EvalT>()+")",eval_dirichletbcs);
85 this->evaluateDirichletBCs(in);
86 }
87 }
88
89 if ( flags.getValue() & EvaluationFlags::Scatter) {
90 PANZER_FUNC_TIME_MONITOR_DIFF("panzer::AssemblyEngine::evaluate_scatter("+PHX::print<EvalT>()+")",eval_scatter);
91 {
92 PANZER_FUNC_TIME_MONITOR_DIFF("panzer::AssemblyEngine::lof->ghostToGlobalContainer("+PHX::print<EvalT>()+")",lof_gtgc);
93 m_lin_obj_factory->ghostToGlobalContainer(*in.ghostedContainer_,*in.container_,LOC::F | LOC::Mat);
94 }
95 {
96 PANZER_FUNC_TIME_MONITOR_DIFF("panzer::AssemblyEngine::gedc.ghostToGlobal("+PHX::print<EvalT>()+")",gedc_gtg);
97 m_lin_obj_factory->beginFill(*in.container_);
98 gedc.ghostToGlobal(LOC::F | LOC::Mat);
99 m_lin_obj_factory->endFill(*in.container_);
100 }
101 m_lin_obj_factory->endFill(*in.ghostedContainer_);
102 }
103
104 return;
105}
106
107//===========================================================================
108//===========================================================================
109template <typename EvalT>
110Teuchos::RCP<panzer::LinearObjContainer> panzer::AssemblyEngine<EvalT>::
112{
113 typedef LinearObjContainer LOC;
114
115 // make sure this container gets a dirichlet adjustment
116 in.ghostedContainer_->setRequiresDirichletAdjustment(true);
117
120 gedc.initialize(); // make sure all ghosted data is ready to go
121 gedc.globalToGhost(LOC::X | LOC::DxDt);
122
123 // Push solution, x and dxdt into ghosted domain
124 m_lin_obj_factory->globalToGhostContainer(*in.container_,*in.ghostedContainer_,LOC::X | LOC::DxDt);
125 m_lin_obj_factory->beginFill(*in.ghostedContainer_);
126
127 // Dirchlet conditions require a global matrix
128 Teuchos::RCP<LOC> counter = this->evaluateDirichletBCs(in);
129
130 m_lin_obj_factory->ghostToGlobalContainer(*in.ghostedContainer_,*in.container_,LOC::F | LOC::Mat);
131
132 m_lin_obj_factory->beginFill(*in.container_);
133 gedc.ghostToGlobal(LOC::F | LOC::Mat);
134 m_lin_obj_factory->endFill(*in.container_);
135
136 m_lin_obj_factory->endFill(*in.ghostedContainer_);
137
138 return counter;
139}
140
141//===========================================================================
142//===========================================================================
143template <typename EvalT>
146{
147 const std::vector< Teuchos::RCP< PHX::FieldManager<panzer::Traits> > > &
148 volume_field_managers = m_field_manager_builder->getVolumeFieldManagers();
149 const std::vector<WorksetDescriptor> & wkstDesc = m_field_manager_builder->getVolumeWorksetDescriptors();
150
151 Teuchos::RCP<panzer::WorksetContainer> wkstContainer = m_field_manager_builder->getWorksetContainer();
152
154 ped.gedc->addDataObject("Solution Gather Container",in.ghostedContainer_);
155 ped.gedc->addDataObject("Residual Scatter Container",in.ghostedContainer_);
159
160 // Loop over volume field managers
161 for (std::size_t block = 0; block < volume_field_managers.size(); ++block) {
162 const WorksetDescriptor & wd = wkstDesc[block];
163 Teuchos::RCP< PHX::FieldManager<panzer::Traits> > fm = volume_field_managers[block];
164 std::vector<panzer::Workset>& w = *wkstContainer->getWorksets(wd);
165
166 fm->template preEvaluate<EvalT>(ped);
167
168 // Loop over worksets in this element block
169 for (std::size_t i = 0; i < w.size(); ++i) {
170 panzer::Workset& workset = w[i];
171
172 workset.alpha = in.alpha;
173 workset.beta = in.beta;
174 workset.time = in.time;
175 workset.step_size = in.step_size;
176 workset.stage_number = in.stage_number;
177 workset.gather_seeds = in.gather_seeds;
179
180
181 fm->template evaluateFields<EvalT>(workset);
182 }
183
184 // double s = 0.;
185 // double p = 0.;
186 // fm->template analyzeGraph<EvalT>(s,p);
187 // std::cout << "Analyze Graph: " << PHX::print<EvalT>() << ",b=" << block << ", s=" << s << ", p=" << p << std::endl;
188
189 fm->template postEvaluate<EvalT>(NULL);
190 }
191}
192
193//===========================================================================
194//===========================================================================
195template <typename EvalT>
201
202//===========================================================================
203//===========================================================================
204template <typename EvalT>
210
211//===========================================================================
212//===========================================================================
213template <typename EvalT>
214Teuchos::RCP<panzer::LinearObjContainer> panzer::AssemblyEngine<EvalT>::
216{
217 typedef LinearObjContainer LOC;
218
219 if(!countersInitialized_) {
220 localCounter_ = m_lin_obj_factory->buildPrimitiveGhostedLinearObjContainer();
221 globalCounter_ = m_lin_obj_factory->buildPrimitiveLinearObjContainer();
222 summedGhostedCounter_ = m_lin_obj_factory->buildPrimitiveGhostedLinearObjContainer();
223 countersInitialized_ = true;
224
225 m_lin_obj_factory->initializeGhostedContainer(LinearObjContainer::F,*localCounter_); // store counter in F
226 m_lin_obj_factory->initializeContainer( LinearObjContainer::F,*globalCounter_); // store counter in X
227 m_lin_obj_factory->initializeGhostedContainer(LinearObjContainer::F,*summedGhostedCounter_); // store counter in X
228 }
229
230 {
231 localCounter_->initialize();
232 summedGhostedCounter_->initialize();
233 globalCounter_->initialize();
234 }
235
236 // apply dirichlet conditions, make sure to keep track of the local counter
237 this->evaluateBCs(panzer::BCT_Dirichlet, in,localCounter_);
238
239 // do communication to build summed ghosted counter for dirichlet conditions
240 {
241 m_lin_obj_factory->ghostToGlobalContainer(*localCounter_,*globalCounter_,LOC::F);
242 // Here we do the reduction across all processors so that the number of times
243 // a dirichlet condition is applied is summed into the global counter
244
245 m_lin_obj_factory->globalToGhostContainer(*globalCounter_,*summedGhostedCounter_,LOC::F);
246 // finally we move the summed global vector into a local ghosted vector
247 // so that the dirichlet conditions can be applied to both the ghosted
248 // right hand side and the ghosted matrix
249 }
250
252 gedc.addDataObject("Residual Scatter Container",in.ghostedContainer_);
254
255 // adjust ghosted system for boundary conditions
256 for(GlobalEvaluationDataContainer::iterator itr=gedc.begin();itr!=gedc.end();itr++) {
257
258 if(itr->second->requiresDirichletAdjustment()) {
259 Teuchos::RCP<LinearObjContainer> loc = Teuchos::rcp_dynamic_cast<LinearObjContainer>(itr->second);
260 if(loc!=Teuchos::null) {
261 m_lin_obj_factory->adjustForDirichletConditions(*localCounter_,*summedGhostedCounter_,*loc);
262 }
263 else {
264 // it was not a linear object container, so if you want an adjustment it better be a GED_BCAdjustment object
265 Teuchos::RCP<GlobalEvaluationData_BCAdjustment> bc_adjust = Teuchos::rcp_dynamic_cast<GlobalEvaluationData_BCAdjustment>(itr->second,true);
266 bc_adjust->adjustForDirichletConditions(*localCounter_,*summedGhostedCounter_);
267 }
268 }
269 }
270
271 return globalCounter_;
272}
273
274//===========================================================================
275//===========================================================================
276template <typename EvalT>
278evaluateBCs(const panzer::BCType bc_type,
280 const Teuchos::RCP<LinearObjContainer> preEval_loc)
281{
282 Teuchos::RCP<panzer::WorksetContainer> wkstContainer = m_field_manager_builder->getWorksetContainer();
283
285 ped.gedc->addDataObject("Dirichlet Counter",preEval_loc);
286 ped.gedc->addDataObject("Solution Gather Container",in.ghostedContainer_);
287 ped.gedc->addDataObject("Residual Scatter Container",in.ghostedContainer_);
291
292 // this helps work around issues when constructing a mass
293 // matrix using an evaluation of only the transient terms.
294 // In particular, the terms associated with the dirichlet
295 // conditions.
296 double betaValue = in.beta; // default to the passed in beta
298 betaValue = in.dirichlet_beta;
299 }
300
301 {
302 const std::map<panzer::BC,
303 std::map<unsigned,PHX::FieldManager<panzer::Traits> >,
304 panzer::LessBC>& bc_field_managers =
305 m_field_manager_builder->getBCFieldManagers();
306
307 // Must do all neumann before all dirichlet so we need a double loop
308 // here over all bcs
309 typedef typename std::map<panzer::BC,
310 std::map<unsigned,PHX::FieldManager<panzer::Traits> >,
311 panzer::LessBC>::const_iterator bcfm_it_type;
312
313 // loop over bcs
314 for (bcfm_it_type bcfm_it = bc_field_managers.begin();
315 bcfm_it != bc_field_managers.end(); ++bcfm_it) {
316
317 const panzer::BC& bc = bcfm_it->first;
318 const std::map<unsigned,PHX::FieldManager<panzer::Traits> > bc_fm =
319 bcfm_it->second;
320
322 Teuchos::RCP<const std::map<unsigned,panzer::Workset> > bc_wkst_ptr = wkstContainer->getSideWorksets(desc);
323 TEUCHOS_TEST_FOR_EXCEPTION(bc_wkst_ptr == Teuchos::null, std::logic_error,
324 "Failed to find corresponding bc workset!");
325 const std::map<unsigned,panzer::Workset>& bc_wkst = *bc_wkst_ptr;
326
327 // Only process bcs of the appropriate type (neumann or dirichlet)
328 if (bc.bcType() == bc_type) {
329 std::ostringstream timerName;
330 timerName << "panzer::AssemblyEngine::evaluateBCs: " << bc.identifier();
331#ifdef PANZER_TEUCHOS_TIME_MONITOR
332 auto timer1 = Teuchos::TimeMonitor::getNewTimer(timerName.str());
333 Teuchos::TimeMonitor tm1(*timer1);
334#endif
335
336 // Loop over local faces
337 for (std::map<unsigned,PHX::FieldManager<panzer::Traits> >::const_iterator side = bc_fm.begin(); side != bc_fm.end(); ++side) {
338 std::ostringstream timerSideName;
339 timerSideName << "panzer::AssemblyEngine::evaluateBCs: " << bc.identifier() << ", side=" << side->first;
340#ifdef PANZER_TEUCHOS_TIME_MONITOR
341 auto timer2 = Teuchos::TimeMonitor::getNewTimer(timerSideName.str());
342 Teuchos::TimeMonitor tm2(*timer2);
343#endif
344
345 // extract field manager for this side
346 unsigned local_side_index = side->first;
347 PHX::FieldManager<panzer::Traits>& local_side_fm =
348 const_cast<PHX::FieldManager<panzer::Traits>& >(side->second);
349
350 // extract workset for this side: only one workset per face
351 std::map<unsigned,panzer::Workset>::const_iterator wkst_it =
352 bc_wkst.find(local_side_index);
353
354 TEUCHOS_TEST_FOR_EXCEPTION(wkst_it == bc_wkst.end(), std::logic_error,
355 "Failed to find corresponding bc workset side!");
356
357 panzer::Workset& workset =
358 const_cast<panzer::Workset&>(wkst_it->second);
359
360 // run prevaluate
361 local_side_fm.template preEvaluate<EvalT>(ped);
362
363 // build and evaluate fields for the workset: only one workset per face
364 workset.alpha = in.alpha;
365 workset.beta = betaValue;
366 workset.time = in.time;
367 workset.step_size = in.step_size;
368 workset.stage_number = in.stage_number;
369 workset.gather_seeds = in.gather_seeds;
371
372 local_side_fm.template evaluateFields<EvalT>(workset);
373
374 // run postevaluate for consistency
375 local_side_fm.template postEvaluate<EvalT>(NULL);
376
377 }
378 }
379 }
380 }
381
382}
383
384#endif
Teuchos::RCP< panzer::LinearObjContainer > ghostedContainer_
Teuchos::RCP< panzer::LinearObjContainer > container_
void fillGlobalEvaluationDataContainer(GlobalEvaluationDataContainer &gedc) const
Using internal map fill the global evaluation data container object.
Teuchos::RCP< LinearObjContainer > evaluateOnlyDirichletBCs(const panzer::AssemblyEngineInArgs &input_arguments)
void evaluate(const panzer::AssemblyEngineInArgs &input_arguments, const EvaluationFlags flags=EvaluationFlags(EvaluationFlags::All))
void evaluateVolume(const panzer::AssemblyEngineInArgs &input_arguments)
void evaluateNeumannBCs(const panzer::AssemblyEngineInArgs &input_arguments)
void evaluateInterfaceBCs(const panzer::AssemblyEngineInArgs &input_arguments)
AssemblyEngine(const Teuchos::RCP< panzer::FieldManagerBuilder > &fmb, const Teuchos::RCP< const panzer::LinearObjFactory< panzer::Traits > > &lof)
Teuchos::RCP< LinearObjContainer > evaluateDirichletBCs(const panzer::AssemblyEngineInArgs &input_arguments)
This method returns the global counter used to indicate which rows are boundary conditions.
void evaluateBCs(const panzer::BCType bc_type, const panzer::AssemblyEngineInArgs &input_arguments, const Teuchos::RCP< LinearObjContainer > preEval_loc=Teuchos::null)
Stores input information for a boundary condition.
Definition Panzer_BC.hpp:48
BCType bcType() const
Returns the boundary condition type (Dirichlet or Neumann or Interface).
std::string identifier() const
A unique string identifier for this boundary condition.
void addDataObject(const std::string &key, const Teuchos::RCP< GlobalEvaluationData > &ged)
void initialize()
Call initialize on all containers.
void globalToGhost(int p)
Call global to ghost on all the containers.
void ghostToGlobal(int p)
Call ghost to global on all the containers.
std::unordered_map< std::string, Teuchos::RCP< GlobalEvaluationData > >::iterator iterator
virtual void initialize()=0
std::vector< double > gather_seeds
WorksetDescriptor bcDescriptor(const panzer::BC &bc)
BCType
Type of boundary condition.
Definition Panzer_BC.hpp:41
@ BCT_Dirichlet
Definition Panzer_BC.hpp:42
@ BCT_Neumann
Definition Panzer_BC.hpp:43
@ BCT_Interface
Definition Panzer_BC.hpp:44
Teuchos::RCP< GlobalEvaluationDataContainer > gedc
std::string second_sensitivities_name
std::string first_sensitivities_name