Panzer  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Panzer_ResponseMESupport_Default.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_ResponseMESupport_Default_hpp__
12 #define __Panzer_ResponseMESupport_Default_hpp__
13 
15 #include "Teuchos_ArrayRCP.hpp"
16 #include "Teuchos_RCP.hpp"
17 #include "Teuchos_OpaqueWrapper.hpp"
18 
20 
21 #include "Thyra_DefaultSpmdVectorSpace.hpp"
22 #include "Thyra_SpmdVectorBase.hpp"
23 
24 #include "PanzerDiscFE_config.hpp"
25 #ifdef PANZER_HAVE_EPETRA_STACK
26 #include "Epetra_LocalMap.h"
27 #include "Epetra_Map.h"
28 #include "Thyra_EpetraThyraWrappers.hpp"
29 #endif
30 
31 namespace panzer {
32 
33 template <typename EvalT>
35 public:
36  ResponseMESupport_Default(const std::string & responseName,MPI_Comm comm)
37  : ResponseMESupportBase<EvalT>(responseName), useEpetra_(false),
38 #ifdef PANZER_HAVE_EPETRA_STACK
39  eComm_(comm),
40 #endif
41  useThyra_(false)
42  {
43  tComm_ = Teuchos::rcp(new Teuchos::MpiComm<Thyra::Ordinal>(Teuchos::opaqueWrapper(comm)));
44  }
45 
47 
49  virtual std::size_t localSizeRequired() const = 0;
50 
52  virtual bool vectorIsDistributed() const = 0;
53 
54 #ifdef PANZER_HAVE_EPETRA_STACK
55  // This is the epetra view of the world
57 
59  Teuchos::RCP<const Epetra_Map> getMap() const;
60 
64  void setVector(const Teuchos::RCP<Epetra_Vector> & destVec);
65 #endif
66 
67  // This is the Thyra view of the world
69 
72 
76  void setVector(const Teuchos::RCP<Thyra::VectorBase<double> > & destVec);
77 
80  { vSpace_ = vs; }
81 
84  { return tVector_; }
85 
86 protected:
89 
91  bool useEpetra() const { return useEpetra_; }
92 
94  bool useThyra() const { return useThyra_; }
95 
96 #ifdef PANZER_HAVE_EPETRA_STACK
97  Epetra_Vector & getEpetraVector() const;
99 #endif
100 
102  Thyra::ArrayRCP<double> getThyraVector() const;
103 
106  { return tVector_;}
107 
108 
109 private:
110  // hide these methods
113 
115 #ifdef PANZER_HAVE_EPETRA_STACK
116  Epetra_MpiComm eComm_;
117  mutable Teuchos::RCP<const Epetra_Map> map_;
119 #endif
120 
121  bool useThyra_;
125 };
126 
127 template < >
128 class ResponseMESupport_Default<panzer::Traits::Jacobian> : public ResponseMESupportBase<panzer::Traits::Jacobian> {
129 public:
130 
131  ResponseMESupport_Default(const std::string & responseName,MPI_Comm comm,
132  const Teuchos::RCP<const Thyra::VectorSpaceBase<double> > & derivVecSpace=Teuchos::null)
133  : ResponseMESupportBase<panzer::Traits::Jacobian>(responseName), derivVecSpace_(derivVecSpace)
134  { tComm_ = Teuchos::rcp(new Teuchos::MpiComm<Thyra::Ordinal>(Teuchos::opaqueWrapper(comm))); }
135 
137 
139  virtual std::size_t localSizeRequired() const = 0;
140 
142  virtual bool vectorIsDistributed() const = 0;
143 
145  bool supportsDerivative() const { return getDerivativeVectorSpace()!=Teuchos::null; }
146 
151  { return derivative_; }
152 
153 #ifdef PANZER_HAVE_EPETRA_STACK
154  // This is the epetra view of the world
156 
158  virtual Teuchos::RCP<Epetra_MultiVector> buildEpetraDerivative() const
159  {
162  TEUCHOS_ASSERT(supportsDerivative());
163 
164  if(eMap_==Teuchos::null)
165  eMap_ = Thyra::get_Epetra_Map(*getDerivativeVectorSpace(),Thyra::get_Epetra_Comm(*tComm_));
166 
167  return Teuchos::rcp(new Epetra_Vector(*eMap_));
168  }
169 
173  virtual void setDerivative(const Teuchos::RCP<Epetra_MultiVector> & derivative)
174  {
177  TEUCHOS_ASSERT(supportsDerivative());
178  TEUCHOS_ASSERT(eMap_!=Teuchos::null);
179 
180  derivative_ = Thyra::create_MultiVector(derivative,getDerivativeVectorSpace());
181  }
182 #endif
183 
184  // This is the Thyra view of the world
186 
189  {
192  TEUCHOS_ASSERT(supportsDerivative());
193  return Thyra::createMember(*getDerivativeVectorSpace());
194  }
195 
199  virtual void setDerivative(const Teuchos::RCP<Thyra::MultiVectorBase<double> > & derivative)
200  {
203  TEUCHOS_ASSERT(supportsDerivative());
204  derivative_ = derivative;
205  }
206 
207 protected:
210 
213  { return derivVecSpace_; }
214 
217  { derivVecSpace_ = vs; }
218 
219 private:
220  // hide these methods
223 
226 #ifdef PANZER_HAVE_EPETRA_STACK
227  mutable Teuchos::RCP<const Epetra_Map> eMap_;
228 #endif
229 
231 };
232 
233 template < >
234 class ResponseMESupport_Default<panzer::Traits::Tangent> : public ResponseMESupportBase<panzer::Traits::Tangent> {
235 public:
237 
238  ResponseMESupport_Default(const std::string & responseName,MPI_Comm comm)
239  : ResponseMESupportBase<EvalT>(responseName), useEpetra_(false),
240 #ifdef PANZER_HAVE_EPETRA_STACK
241  eComm_(comm),
242 #endif
243  useThyra_(false)
244  {
245  tComm_ = Teuchos::rcp(new Teuchos::MpiComm<Thyra::Ordinal>(Teuchos::opaqueWrapper(comm)));
246  }
247 
249 
251  virtual std::size_t localSizeRequired() const = 0;
252 
254  virtual bool vectorIsDistributed() const = 0;
255 
256 #ifdef PANZER_HAVE_EPETRA_STACK
257  // This is the epetra view of the world
259 
261  Teuchos::RCP<const Epetra_Map> getMap() const {
262  TEUCHOS_TEST_FOR_EXCEPTION(useThyra_,std::logic_error,
263  "Reponse field \"" << this->getName() << "\" has previously been initialized as a "
264  "Thyra object, now trying to initalize as a Epetra! Error!");
265  // lazily construct the map only as needed
266  if(map_==Teuchos::null) {
267  if(this->vectorIsDistributed())
268  map_ = Teuchos::rcp(new Epetra_Map(-1,(int) this->localSizeRequired(),0,eComm_));
269  else
270  map_ = Teuchos::rcp(new Epetra_LocalMap((int) this->localSizeRequired(),0,eComm_));
271  }
272  return map_;
273  }
274 
278  void setVector(const Teuchos::RCP<Epetra_MultiVector> & destVec) {
279  TEUCHOS_TEST_FOR_EXCEPTION(useThyra_,std::logic_error,
280  "Reponse field \"" << this->getName() << "\" has previously been initialized as a "
281  "Thyra object, now trying to initalize as a Epetra! Error!");
282  eVector_ = destVec;
283  useEpetra_ = true;
284  }
285 #endif
286 
287  // This is the Thyra view of the world
289 
292  TEUCHOS_TEST_FOR_EXCEPTION(useEpetra_,std::logic_error,
293  "Reponse field \"" << this->getName() << "\" has previously been initialized as an "
294  "Epetra object, now trying to initalize as a Thyra object! Error!");
295  // lazily build the space and return it
296  if(vSpace_==Teuchos::null) {
297  if(this->vectorIsDistributed())
298  vSpace_ = Thyra::defaultSpmdVectorSpace<double>(tComm_,this->localSizeRequired(),-1);
299  else
300  vSpace_ = Thyra::locallyReplicatedDefaultSpmdVectorSpace<double>(tComm_,this->localSizeRequired());
301  }
302  return vSpace_;
303  }
304 
309  TEUCHOS_TEST_FOR_EXCEPTION(useEpetra_,std::logic_error,
310  "Reponse field \"" << this->getName() << "\" has previously been initialized as an "
311  "Epetra object, now trying to initalize as a Thyra object! Error!");
312  tVector_ = destVec;
313  useThyra_ = true;
314  }
315 
316 protected:
319 
321  bool useEpetra() const { return useEpetra_; }
322 
324  bool useThyra() const { return useThyra_; }
325 
326 #ifdef PANZER_HAVE_EPETRA_STACK
327  Epetra_MultiVector & getEpetraMultiVector() const {
330  return *eVector_;
331  }
332 #endif
333 
335  Thyra::ArrayRCP< Thyra::ArrayRCP<double> > getThyraMultiVector() const {
337  const int num_col = tVector_->domain()->dim();
338  Thyra::ArrayRCP< Thyra::ArrayRCP<double> > data(num_col);
339  for (int i=0; i<num_col; ++i)
340  Teuchos::rcp_dynamic_cast<Thyra::SpmdVectorBase<double> >(tVector_->col(i),true)->getNonconstLocalData(Teuchos::outArg(data[i]));
341  return data;
342  }
343 
345  int numDeriv() const {
346 #ifdef PANZER_HAVE_EPETRA_STACK
347  if (useEpetra())
348  return eVector_->NumVectors();
349  else
350 #endif
351  return tVector_->domain()->dim();
352  }
353 
354 
355 private:
356  // hide these methods
359 
361 #ifdef PANZER_HAVE_EPETRA_STACK
362  Epetra_MpiComm eComm_;
363  mutable Teuchos::RCP<const Epetra_Map> map_;
365 #endif
366 
367  bool useThyra_;
371 };
372 
373 #ifdef Panzer_BUILD_HESSIAN_SUPPORT
374 
375 template < >
376 class ResponseMESupport_Default<panzer::Traits::Hessian> : public ResponseMESupportBase<panzer::Traits::Hessian> {
377 public:
378 
379  ResponseMESupport_Default(const std::string & responseName,MPI_Comm comm,
380  const Teuchos::RCP<const Thyra::VectorSpaceBase<double> > & derivVecSpace=Teuchos::null)
381  : ResponseMESupportBase<panzer::Traits::Hessian>(responseName), derivVecSpace_(derivVecSpace)
382  { tComm_ = Teuchos::rcp(new Teuchos::MpiComm<Thyra::Ordinal>(Teuchos::opaqueWrapper(comm))); }
383 
385 
387  virtual std::size_t localSizeRequired() const = 0;
388 
390  virtual bool vectorIsDistributed() const = 0;
391 
393  bool supportsDerivative() const { return getDerivativeVectorSpace()!=Teuchos::null; }
394 
399  { return derivative_; }
400 
403  {
406  TEUCHOS_ASSERT(supportsDerivative());
407  return Thyra::createMember(*getDerivativeVectorSpace());
408  }
409 
413  virtual void setDerivative(const Teuchos::RCP<Thyra::MultiVectorBase<double> > & derivative)
414  {
417  TEUCHOS_ASSERT(supportsDerivative());
418  derivative_ = derivative;
419  }
420 
421 protected:
424 
427  { return derivVecSpace_; }
428 
431  { derivVecSpace_ = vs; }
432 
433 private:
434  // hide these methods
437 
440 
442 };
443 
444 #endif
445 
446 }
447 
449 
450 #endif
Teuchos::RCP< const Thyra::VectorSpaceBase< double > > getDerivativeVectorSpace() const
Get the derivative vector space.
bool supportsDerivative() const
Does this response support derivative evaluation?
bool useEpetra() const
Is Epetra the right vector.
virtual void setDerivative(const Teuchos::RCP< Thyra::MultiVectorBase< double > > &derivative)
Teuchos::RCP< const Teuchos::Comm< Thyra::Ordinal > > getComm() const
Get the teuchos comm object.
virtual Teuchos::RCP< Thyra::MultiVectorBase< double > > buildDerivative() const
Get the Epetra_Map for this response, map is constructed lazily.
Teuchos::RCP< Thyra::VectorBase< double > > getVector() const
Access the response vector.
ResponseMESupport_Default(const std::string &responseName, MPI_Comm comm)
Teuchos::RCP< const Thyra::VectorSpaceBase< double > > vSpace_
bool supportsDerivative() const
Does this response support derivative evaluation?
void setDerivativeVectorSpace(const Teuchos::RCP< const Thyra::VectorSpaceBase< double > > &vs)
Set the derivative vector space.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Teuchos::RCP< const Thyra::VectorSpaceBase< double > > vSpace_
Teuchos::RCP< const Teuchos::Comm< Thyra::Ordinal > > tComm_
Teuchos::RCP< const Thyra::VectorSpaceBase< double > > derivVecSpace_
int numDeriv() const
Return the number of columns in the multivector.
virtual Teuchos::RCP< Thyra::MultiVectorBase< double > > buildDerivative() const
Get the Epetra_Map for this response, map is constructed lazily.
Teuchos::RCP< const Thyra::VectorSpaceBase< double > > getVectorSpace() const
Get the vector space for this response, vector space is constructed lazily.
virtual void setDerivative(const Teuchos::RCP< Thyra::MultiVectorBase< double > > &derivative)
ResponseMESupport_Default(const std::string &responseName, MPI_Comm comm, const Teuchos::RCP< const Thyra::VectorSpaceBase< double > > &derivVecSpace=Teuchos::null)
void setVector(const Teuchos::RCP< Thyra::MultiVectorBase< double > > &destVec)
std::string getName() const
Teuchos::RCP< const Thyra::VectorSpaceBase< double > > getDerivativeVectorSpace() const
Get the derivative vector space.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Teuchos::RCP< Thyra::MultiVectorBase< double > > getThyraMultiVector() const
Access the thyra MultiVector.
Thyra::ArrayRCP< double > getThyraVector() const
Access the thyra vector.
Teuchos::RCP< const Teuchos::Comm< Thyra::Ordinal > > tComm_
Teuchos::RCP< Thyra::MultiVectorBase< double > > getDerivative() const
Teuchos::RCP< const Teuchos::Comm< Thyra::Ordinal > > getComm() const
Get the teuchos comm object.
Teuchos::RCP< const Thyra::VectorSpaceBase< double > > derivVecSpace_
Teuchos::RCP< const Thyra::VectorSpaceBase< double > > getVectorSpace() const
Get the vector space for this response, vector space is constructed lazily.
bool useThyra() const
Is Thyra the right vector.
void setDerivativeVectorSpace(const Teuchos::RCP< const Thyra::VectorSpaceBase< double > > &vs)
Set the derivative vector space.
virtual std::size_t localSizeRequired() const =0
What is the number of values you need locally.
Teuchos::RCP< const Teuchos::Comm< Thyra::Ordinal > > getComm() const
Get the teuchos comm object.
void setVectorSpace(Teuchos::RCP< const Thyra::VectorSpaceBase< double > > vs)
set the vector space for this response
Teuchos::RCP< Thyra::VectorBase< double > > tVector_
Teuchos::RCP< const Teuchos::Comm< Thyra::Ordinal > > tComm_
#define TEUCHOS_ASSERT(assertion_test)
ResponseMESupport_Default(const std::string &responseName, MPI_Comm comm, const Teuchos::RCP< const Thyra::VectorSpaceBase< double > > &derivVecSpace=Teuchos::null)
void setVector(const Teuchos::RCP< Thyra::VectorBase< double > > &destVec)
virtual bool vectorIsDistributed() const =0
Is the vector distributed (or replicated)
ResponseMESupport_Default(const std::string &responseName, MPI_Comm comm)
Thyra::ArrayRCP< Thyra::ArrayRCP< double > > getThyraMultiVector() const
Access the thyra vector.
Teuchos::RCP< const Teuchos::Comm< Thyra::Ordinal > > getComm() const
Get the teuchos comm object.
Teuchos::RCP< Thyra::MultiVectorBase< double > > getDerivative() const