Panzer  Version of the Day
Panzer_Response_ExtremeValue_impl.hpp
Go to the documentation of this file.
1 #ifndef __Panzer_Response_ExtremeValue_impl_hpp__
2 #define __Panzer_Response_ExtremeValue_impl_hpp__
3 
4 #include "Teuchos_Comm.hpp"
5 #include "Teuchos_CommHelpers.hpp"
6 #include "Teuchos_dyn_cast.hpp"
7 
8 #include "Epetra_LocalMap.h"
9 
10 #include "Sacado_Traits.hpp"
11 
12 namespace panzer {
13 
14 template <typename EvalT>
17 {
18  double locValue = Sacado::ScalarValue<ScalarT>::eval(value);
19  double glbValue = 0.0;
20 
21  // do global summation
22  if(useMax_)
23  Teuchos::reduceAll(*this->getComm(), Teuchos::REDUCE_MAX, static_cast<Thyra::Ordinal>(1), &locValue,&glbValue);
24  else
25  Teuchos::reduceAll(*this->getComm(), Teuchos::REDUCE_MIN, static_cast<Thyra::Ordinal>(1), &locValue,&glbValue);
26 
27  value = glbValue;
28 
29  // built data in vectors
30  if(this->useEpetra()) {
31  // use epetra
32  this->getEpetraVector()[0] = glbValue;
33  }
34  else {
35  // use thyra
36  TEUCHOS_ASSERT(this->useThyra());
37 
38  this->getThyraVector()[0] = glbValue;
39  }
40 }
41 
42 template < >
45 {
46  using Teuchos::rcp_dynamic_cast;
47 
48  Teuchos::RCP<Thyra::MultiVectorBase<double> > dgdx_unique = getDerivative();
49 
50  uniqueContainer_ = linObjFactory_->buildLinearObjContainer();
51  Teuchos::rcp_dynamic_cast<ThyraObjContainer<double> >(uniqueContainer_)->set_x_th(dgdx_unique->col(0));
52 
53  linObjFactory_->ghostToGlobalContainer(*ghostedContainer_,*uniqueContainer_,LinearObjContainer::X);
54 
55  uniqueContainer_ = Teuchos::null;
56 }
57 
58 #ifdef Panzer_BUILD_HESSIAN_SUPPORT
59 template < >
62 {
63  using Teuchos::rcp_dynamic_cast;
64 
65  Teuchos::RCP<Thyra::MultiVectorBase<double> > dgdx_unique = getDerivative();
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 #endif
75 
76 template < >
79 {
80  const int n = value.size();
81  const int num_deriv = this->numDeriv();
82  TEUCHOS_ASSERT(n == 0 || n == num_deriv);
83  ScalarT glbValue = ScalarT(num_deriv, 0.0);
84 
85  // do global min/max on value
86  if(useMax_)
87  Teuchos::reduceAll(*this->getComm(), Teuchos::REDUCE_MAX, Thyra::Ordinal(1), &value.val(), &glbValue.val());
88  else
89  Teuchos::reduceAll(*this->getComm(), Teuchos::REDUCE_MIN, Thyra::Ordinal(1), &value.val(), &glbValue.val());
90 
91  // find the minimum processor who's local value == the global min/max value
92  if (num_deriv > 0) {
93  int locProc = value.val() == glbValue.val() ? this->getComm()->getRank() : this->getComm()->getSize();
94  int glbProc = 0;
95  Teuchos::reduceAll(*this->getComm(), Teuchos::REDUCE_MIN, Thyra::Ordinal(1), &locProc, &glbProc);
96 
97  // now broadcast the derivatives from proc glbProc
98  Teuchos::broadcast(*this->getComm(), glbProc, Thyra::Ordinal(n), &glbValue.fastAccessDx(0));
99  }
100 
101  value = glbValue;
102 
103  // copy data in vectors
104  if(this->useEpetra()) {
105  // use epetra
106  Epetra_MultiVector& deriv = this->getEpetraMultiVector();
107  for (int i=0; i<num_deriv; ++i)
108  deriv[i][0] = glbValue.dx(i);
109  }
110  else {
111  // use thyra
112  TEUCHOS_ASSERT(this->useThyra());
113  Thyra::ArrayRCP< Thyra::ArrayRCP<double> > deriv = this->getThyraMultiVector();
114  for (int i=0; i<num_deriv; ++i)
115  deriv[i][0] = glbValue.dx(i);
116  }
117 }
118 
119 // Do nothing unless derivatives are actually required
120 template <typename EvalT>
123 
124 // derivatives are required for
125 template < >
128 {
129  setDerivativeVectorSpace(soln_vs);
130 }
131 
132 #ifdef Panzer_BUILD_HESSIAN_SUPPORT
133 // derivatives are required for
134 template < >
137 {
138  setDerivativeVectorSpace(soln_vs);
139 }
140 #endif
141 
142 // Do nothing unless derivatives are required
143 template <typename EvalT>
145 adjustForDirichletConditions(const GlobalEvaluationData & localBCRows,const GlobalEvaluationData & globalBCRows) { }
146 
147 // Do nothing unless derivatives are required
148 template < >
151 {
152  linObjFactory_->adjustForDirichletConditions(Teuchos::dyn_cast<const LinearObjContainer>(localBCRows),
153  Teuchos::dyn_cast<const LinearObjContainer>(globalBCRows),
154  *ghostedContainer_,true,true);
155 }
156 
157 #ifdef Panzer_BUILD_HESSIAN_SUPPORT
158 // Do nothing unless derivatives are required
159 template < >
161 adjustForDirichletConditions(const GlobalEvaluationData & localBCRows,const GlobalEvaluationData & globalBCRows)
162 {
163  linObjFactory_->adjustForDirichletConditions(Teuchos::dyn_cast<const LinearObjContainer>(localBCRows),
164  Teuchos::dyn_cast<const LinearObjContainer>(globalBCRows),
165  *ghostedContainer_,true,true);
166 }
167 #endif
168 
169 }
170 
171 #endif
virtual void scatterResponse()
This simply does global summation, then shoves the result into a vector.
TEUCHOS_DEPRECATED void reduceAll(const Comm< Ordinal > &comm, const EReductionType reductType, const Packet &send, Packet *globalReduct)
void setSolnVectorSpace(const Teuchos::RCP< const Thyra::VectorSpaceBase< double > > &soln_vs)
Set solution vector space.
void adjustForDirichletConditions(const GlobalEvaluationData &localBCRows, const GlobalEvaluationData &globalBCRows)
#define TEUCHOS_ASSERT(assertion_test)