Panzer Version of the Day
Loading...
Searching...
No Matches
Panzer_Response_Probe_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_Response_Probe_impl_hpp__
12#define __Panzer_Response_Probe_impl_hpp__
13
15#include "Teuchos_Comm.hpp"
16#include "Teuchos_CommHelpers.hpp"
17#include "Teuchos_dyn_cast.hpp"
18
19#include "PanzerDiscFE_config.hpp"
20#ifdef PANZER_HAVE_EPETRA_STACK
21#include "Epetra_LocalMap.h"
22#endif
23
24#include "Sacado_Traits.hpp"
25#include "Thyra_VectorStdOps.hpp"
26
27namespace panzer {
28
29template <typename EvalT>
31Response_Probe(const std::string & responseName, MPI_Comm comm,
32 const Teuchos::RCP<const panzer::LinearObjFactory<panzer::Traits> > & linObjFact)
33 : ResponseMESupport_Default<EvalT>(responseName,comm), value(0.0),
34 have_probe(false), linObjFactory_(linObjFact)
35{
36 if(linObjFactory_!=Teuchos::null) {
37 // requires thyra object factory
38 thyraObjFactory_ = Teuchos::rcp_dynamic_cast<const panzer::ThyraObjFactory<double> >(linObjFactory_,true);
39 setSolnVectorSpace(thyraObjFactory_->getThyraDomainSpace());
40
41 // build a ghosted container, with a solution vector
42 ghostedContainer_ = linObjFactory_->buildGhostedLinearObjContainer();
43
44 // set ghosted container (work space for assembly)
46
47 if constexpr (std::is_same<EvalT,panzer::Traits::Jacobian>::value) {
48 this->setDerivativeVectorSpace(thyraObjFactory_->getThyraDomainSpace());
49 }
50 }
51}
52
53template <typename EvalT>
56{
57 value = 0.0;
58 have_probe = false;
59
60 if(ghostedContainer_!=Teuchos::null) ghostedContainer_->initialize();
61}
62
63template <typename EvalT>
66{
67 double glbValue = Sacado::scalarValue(value);
68
69 // find the minimum processor who has the probe value
70 int locProc = have_probe ? this->getComm()->getRank() : this->getComm()->getSize();
71 int glbProc = 0;
72 Teuchos::reduceAll(*this->getComm(), Teuchos::REDUCE_MIN, Thyra::Ordinal(1), &locProc, &glbProc);
73
74 TEUCHOS_ASSERT(glbProc < this->getComm()->getSize());
75
76 // now broadcast the value from proc glbProc
77 Teuchos::broadcast(*this->getComm(), glbProc, Thyra::Ordinal(1), &glbValue);
78
79 value = glbValue;
80
81 // built data in vectors
82#ifdef PANZER_HAVE_EPETRA_STACK
83 if(this->useEpetra()) {
84 // use epetra
85 this->getEpetraVector()[0] = glbValue;
86 }
87 else
88#endif
89 {
90 // use thyra
91 TEUCHOS_ASSERT(this->useThyra());
92
93 this->getThyraVector()[0] = glbValue;
94 }
95}
96
97template < >
100{
101 using Teuchos::rcp_dynamic_cast;
102
103 // A point on a cell boundary is inside a cell on more than one process, so
104 // more than one process scatters a derivative for it. The ghost to global
105 // sum below would then add each of those contributions. Pick a single owner
106 // the same way the value does, and drop everyone else's contribution.
107 // Without this dg/dx is multiplied by the number of processes sharing the
108 // point.
109 int locProc = have_probe ? this->getComm()->getRank() : this->getComm()->getSize();
110 int glbProc = 0;
111 Teuchos::reduceAll(*this->getComm(), Teuchos::REDUCE_MIN, Thyra::Ordinal(1), &locProc, &glbProc);
112 TEUCHOS_ASSERT(glbProc < this->getComm()->getSize());
113
114 if (this->getComm()->getRank() != glbProc) {
115 auto ghosted = rcp_dynamic_cast<ThyraObjContainer<double> >(ghostedContainer_);
116 Thyra::assign(ghosted->get_x_th().ptr(),0.0);
117 }
118
119 Teuchos::RCP<Thyra::MultiVectorBase<double> > dgdx_unique = getDerivative();
120
121 uniqueContainer_ = linObjFactory_->buildLinearObjContainer();
122 Teuchos::rcp_dynamic_cast<ThyraObjContainer<double> >(uniqueContainer_)->set_x_th(dgdx_unique->col(0));
123
124 linObjFactory_->ghostToGlobalContainer(*ghostedContainer_,*uniqueContainer_,LinearObjContainer::X);
125
126 uniqueContainer_ = Teuchos::null;
127}
128
129#ifdef Panzer_BUILD_HESSIAN_SUPPORT
130template < >
133{
134 using Teuchos::rcp_dynamic_cast;
135
136 Teuchos::RCP<Thyra::MultiVectorBase<double> > dgdx_unique = getDerivative();
137
138 uniqueContainer_ = linObjFactory_->buildLinearObjContainer();
139 Teuchos::rcp_dynamic_cast<ThyraObjContainer<double> >(uniqueContainer_)->set_x_th(dgdx_unique->col(0));
140
141 linObjFactory_->ghostToGlobalContainer(*ghostedContainer_,*uniqueContainer_,LinearObjContainer::X);
142
143 uniqueContainer_ = Teuchos::null;
144}
145#endif
146
147template < >
150{
151 // Nothing to scatter into: DgDp was not requested for this response.
152 if (!this->hasTargetVector())
153 return;
154
155 const int n = value.size();
156 const int num_deriv = this->numDeriv();
157 TEUCHOS_ASSERT(n == 0 || n == num_deriv);
158 if (n == 0)
159 value.resize(num_deriv);
160
161 // find the minimum processor who has the probe value
162 if (num_deriv > 0) {
163 int locProc = have_probe ? this->getComm()->getRank() : this->getComm()->getSize();
164 int glbProc = 0;
165 Teuchos::reduceAll(*this->getComm(), Teuchos::REDUCE_MIN, Thyra::Ordinal(1), &locProc, &glbProc);
166
167 TEUCHOS_ASSERT(glbProc < this->getComm()->getSize());
168
169 // now broadcast the derivatives from proc glbProc
170 Teuchos::broadcast(*this->getComm(), glbProc, Thyra::Ordinal(num_deriv), &value.fastAccessDx(0));
171 }
172
173 // copy data in vectors
174#ifdef PANZER_HAVE_EPETRA_STACK
175 if(this->useEpetra()) {
176 // use epetra
177 Epetra_MultiVector& deriv = this->getEpetraMultiVector();
178 for (int i=0; i<num_deriv; ++i)
179 deriv[i][0] = value.dx(i);
180 }
181 else
182#endif
183 {
184 // use thyra
185 TEUCHOS_ASSERT(this->useThyra());
186 Thyra::ArrayRCP< Thyra::ArrayRCP<double> > deriv = this->getThyraMultiVector();
187 for (int i=0; i<num_deriv; ++i) {
188 deriv[i][0] = value.dx(i);
189 }
190 }
191}
192
193// Do nothing unless derivatives are actually required
194template <typename EvalT>
196setSolnVectorSpace(const Teuchos::RCP<const Thyra::VectorSpaceBase<double> > & /* soln_vs */) { }
197
198// derivatives are required for
199template < >
201setSolnVectorSpace(const Teuchos::RCP<const Thyra::VectorSpaceBase<double> > & soln_vs)
202{
203 setDerivativeVectorSpace(soln_vs);
204}
205
206#ifdef Panzer_BUILD_HESSIAN_SUPPORT
207// derivatives are required for
208template < >
210setSolnVectorSpace(const Teuchos::RCP<const Thyra::VectorSpaceBase<double> > & soln_vs)
211{
212 setDerivativeVectorSpace(soln_vs);
213}
214#endif
215
216// Do nothing unless derivatives are required
217template <typename EvalT>
219adjustForDirichletConditions(const GlobalEvaluationData & /* localBCRows */, const GlobalEvaluationData & /* globalBCRows */) { }
220
221// Do nothing unless derivatives are required
222template < >
224adjustForDirichletConditions(const GlobalEvaluationData & localBCRows,const GlobalEvaluationData & globalBCRows)
225{
226 linObjFactory_->adjustForDirichletConditions(Teuchos::dyn_cast<const LinearObjContainer>(localBCRows),
227 Teuchos::dyn_cast<const LinearObjContainer>(globalBCRows),
228 *ghostedContainer_,true,true);
229}
230
231#ifdef Panzer_BUILD_HESSIAN_SUPPORT
232// Do nothing unless derivatives are required
233template < >
235adjustForDirichletConditions(const GlobalEvaluationData & localBCRows,const GlobalEvaluationData & globalBCRows)
236{
237 linObjFactory_->adjustForDirichletConditions(Teuchos::dyn_cast<const LinearObjContainer>(localBCRows),
238 Teuchos::dyn_cast<const LinearObjContainer>(globalBCRows),
239 *ghostedContainer_,true,true);
240}
241#endif
242
243}
244
245#endif
Teuchos::RCP< const panzer::ThyraObjFactory< double > > thyraObjFactory_
Teuchos::RCP< LinearObjContainer > ghostedContainer_
void setSolnVectorSpace(const Teuchos::RCP< const Thyra::VectorSpaceBase< double > > &soln_vs)
Set solution vector space.
Teuchos::RCP< const panzer::LinearObjFactory< panzer::Traits > > linObjFactory_
void adjustForDirichletConditions(const GlobalEvaluationData &localBCRows, const GlobalEvaluationData &globalBCRows)
virtual void scatterResponse()
This simply does global summation, then shoves the result into a vector.