Panzer Version of the Day
Loading...
Searching...
No Matches
Panzer_Response_Functional_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_Functional_impl_hpp__
12#define __Panzer_Response_Functional_impl_hpp__
13
14#include "Teuchos_Comm.hpp"
15#include "Teuchos_CommHelpers.hpp"
16#include "Teuchos_dyn_cast.hpp"
17
18#include "PanzerDiscFE_config.hpp"
19#ifdef PANZER_HAVE_EPETRA_STACK
20#include "Epetra_LocalMap.h"
21#endif
22
23#include "Sacado_Traits.hpp"
24
25namespace panzer {
26
27template <typename EvalT>
30{
31 double locValue = Sacado::scalarValue(value);
32 double glbValue = 0.0;
33
34 // do global summation
35 Teuchos::reduceAll(*this->getComm(), Teuchos::REDUCE_SUM, static_cast<Thyra::Ordinal>(1), &locValue,&glbValue);
36
37 value = glbValue;
38
39 // built data in vectors
40#ifdef PANZER_HAVE_EPETRA_STACK
41 if(this->useEpetra()) {
42 // use epetra
43 this->getEpetraVector()[0] = glbValue;
44 }
45 else
46 #endif
47 {
48 // use thyra
49 TEUCHOS_ASSERT(this->useThyra());
50
51 this->getThyraVector()[0] = glbValue;
52 }
53}
54
55template < >
58{
59 using Teuchos::rcp_dynamic_cast;
60
61 Teuchos::RCP<Thyra::MultiVectorBase<double> > dgdx_unique = getDerivative();
62
63 // if its null, don't do anything
64 if(dgdx_unique==Teuchos::null)
65 return;
66
67 uniqueContainer_ = linObjFactory_->buildLinearObjContainer();
68 Teuchos::rcp_dynamic_cast<ThyraObjContainer<double> >(uniqueContainer_)->set_x_th(dgdx_unique->col(0));
69
70 linObjFactory_->ghostToGlobalContainer(*ghostedContainer_,*uniqueContainer_,LinearObjContainer::X);
71
72 uniqueContainer_ = Teuchos::null;
73}
74
75#ifdef Panzer_BUILD_HESSIAN_SUPPORT
76template < >
79{
80 using Teuchos::rcp_dynamic_cast;
81
82 Teuchos::RCP<Thyra::MultiVectorBase<double> > dgdx_unique = getDerivative();
83
84 // if its null, don't do anything
85 if(dgdx_unique==Teuchos::null)
86 return;
87
88 uniqueContainer_ = linObjFactory_->buildLinearObjContainer();
89 Teuchos::rcp_dynamic_cast<ThyraObjContainer<double> >(uniqueContainer_)->set_x_th(dgdx_unique->col(0));
90
91 linObjFactory_->ghostToGlobalContainer(*ghostedContainer_,*uniqueContainer_,LinearObjContainer::X);
92
93 uniqueContainer_ = Teuchos::null;
94}
95#endif
96
97template < >
100{
101 // Nothing to scatter into: DgDp was not requested for this response.
102 if (!this->hasTargetVector())
103 return;
104
105 const int n = value.size();
106 const int num_deriv = this->numDeriv();
107 TEUCHOS_ASSERT(n == 0 || n == num_deriv);
108 ScalarT glbValue = ScalarT(num_deriv, 0.0);
109
110 // do global summation -- it is possible to do the reduceAll() on the Fad's directly, but it is somewhat
111 // complicated for DFad (due to temporaries that might get created). Since this is just a sum, it is
112 // easier to do the reduction for each value and derivative component.
113 Teuchos::reduceAll(*this->getComm(), Teuchos::REDUCE_SUM, Thyra::Ordinal(1), &value.val(), &glbValue.val());
114 if (num_deriv > 0)
115 Teuchos::reduceAll(*this->getComm(), Teuchos::REDUCE_SUM, Thyra::Ordinal(n), value.dx(), &glbValue.fastAccessDx(0));
116
117 value = glbValue;
118
119 // copy data in vectors
120#ifdef PANZER_HAVE_EPETRA_STACK
121 if(this->useEpetra()) {
122 // use epetra
123 Epetra_MultiVector& deriv = this->getEpetraMultiVector();
124 for (int i=0; i<num_deriv; ++i)
125 deriv[i][0] = glbValue.dx(i);
126 }
127 else
128#endif
129 {
130 // use thyra
131 TEUCHOS_ASSERT(this->useThyra());
132 Thyra::ArrayRCP< Thyra::ArrayRCP<double> > deriv = this->getThyraMultiVector();
133 for (int i=0; i<num_deriv; ++i)
134 deriv[i][0] = glbValue.dx(i);
135 }
136}
137
138// Do nothing unless derivatives are actually required
139template <typename EvalT>
141setSolnVectorSpace(const Teuchos::RCP<const Thyra::VectorSpaceBase<double> > & /* soln_vs */) { }
142
143// derivatives are required for
144template < >
146setSolnVectorSpace(const Teuchos::RCP<const Thyra::VectorSpaceBase<double> > & soln_vs)
147{
148 setDerivativeVectorSpace(soln_vs);
149}
150
151// derivatives are required for
152#ifdef Panzer_BUILD_HESSIAN_SUPPORT
153template < >
155setSolnVectorSpace(const Teuchos::RCP<const Thyra::VectorSpaceBase<double> > & soln_vs)
156{
157 setDerivativeVectorSpace(soln_vs);
158}
159#endif
160
161// Do nothing unless derivatives are required
162template <typename EvalT>
164adjustForDirichletConditions(const GlobalEvaluationData & /* localBCRows */, const GlobalEvaluationData & /* globalBCRows */) { }
165
166// Do nothing unless derivatives are required
167template < >
169adjustForDirichletConditions(const GlobalEvaluationData & localBCRows,const GlobalEvaluationData & globalBCRows)
170{
171 linObjFactory_->adjustForDirichletConditions(Teuchos::dyn_cast<const LinearObjContainer>(localBCRows),
172 Teuchos::dyn_cast<const LinearObjContainer>(globalBCRows),
173 *ghostedContainer_,true,true);
174}
175
176#ifdef Panzer_BUILD_HESSIAN_SUPPORT
177// Do nothing unless derivatives are required
178template < >
180adjustForDirichletConditions(const GlobalEvaluationData & localBCRows,const GlobalEvaluationData & globalBCRows)
181{
182 linObjFactory_->adjustForDirichletConditions(Teuchos::dyn_cast<const LinearObjContainer>(localBCRows),
183 Teuchos::dyn_cast<const LinearObjContainer>(globalBCRows),
184 *ghostedContainer_,true,true);
185}
186#endif
187
188}
189
190#endif
virtual void scatterResponse()
This simply does global summation, then shoves the result into a vector.
void adjustForDirichletConditions(const GlobalEvaluationData &localBCRows, const GlobalEvaluationData &globalBCRows)
void setSolnVectorSpace(const Teuchos::RCP< const Thyra::VectorSpaceBase< double > > &soln_vs)
Set solution vector space.