Panzer  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Panzer_STK_ParameterListCallbackBlocked.cpp
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 #include "PanzerAdaptersSTK_config.hpp"
12 #ifdef PANZER_HAVE_TEKO
13 
15 
16 namespace panzer_stk {
17 
18 using Teuchos::RCP;
19 using Teuchos::rcp;
20 
21 ParameterListCallbackBlocked::ParameterListCallbackBlocked(
24  const Teuchos::RCP<const panzer::BlockedDOFManager> & aux_blocked_ugi)
25  : connManager_(connManager), blocked_ugi_(blocked_ugi), aux_blocked_ugi_(aux_blocked_ugi)
26 {}
27 
29 ParameterListCallbackBlocked::request(const Teko::RequestMesg & rm)
30 {
31  TEUCHOS_ASSERT(handlesRequest(rm)); // design by contract
32 
33  // loop over parameter list and set the field by a particular key
35  Teuchos::RCP<const Teuchos::ParameterList> inputPL = rm.getParameterList();
37  for(itr=inputPL->begin();itr!=inputPL->end();++itr) {
38  std::string * str_ptr = 0; // just used as a template specifier
39  std::string field = inputPL->entry(itr).getValue(str_ptr);
40  setFieldByKey(itr->first,field,*outputPL);
41  }
42 
43  return outputPL;
44 }
45 
46 bool ParameterListCallbackBlocked::handlesRequest(const Teko::RequestMesg & rm)
47 {
48  // check if is a parameter list message, and that the parameter
49  // list contains the right fields
50  if(rm.getName()=="Parameter List") {
51  bool isHandled = true;
52  Teuchos::RCP<const Teuchos::ParameterList> pl = rm.getParameterList();
53  std::string field;
54  if(pl->isType<std::string>("x-coordinates")) {
55  field = pl->get<std::string>("x-coordinates");
56  if(!isField(field)) {
57  return false;
58  }
59  }
60  if(pl->isType<std::string>("y-coordinates")) {
61  // we assume that the fields must be the same
62  if(field != pl->get<std::string>("y-coordinates")) {
63  return false;
64  }
65  }
66  if(pl->isType<std::string>("z-coordinates")) {
67  // we assume that the fields must be the same
68  if(field != pl->get<std::string>("z-coordinates")) {
69  return false;
70  }
71  }
72  if(pl->isType<std::string>("Coordinates")){
73  field = pl->get<std::string>("Coordinates");
74  }
75 #ifdef PANZER_HAVE_EPETRA_STACK
76  if(pl->isType<std::string>("Coordinates-Epetra")){
77  field = pl->get<std::string>("Coordinates-Epetra");
78  }
79 #endif
80 
81  return isHandled;
82  }
83  else return false;
84 }
85 
86 void ParameterListCallbackBlocked::preRequest(const Teko::RequestMesg & rm)
87 {
88  TEUCHOS_ASSERT(handlesRequest(rm)); // design by contract
89 
90  const std::string& field(getHandledField(*rm.getParameterList()));
91 
92  // Check if the field is in the main UGI. If it's not, assume it's in the
93  // auxiliary UGI.
94  bool useAux(true);
95  std::vector<Teuchos::RCP<panzer::GlobalIndexer>>
96  fieldDOFMngrs = blocked_ugi_->getFieldDOFManagers();
97  for (int b(0); b < static_cast<int>(fieldDOFMngrs.size()); ++b)
98  {
99  for (int f(0); f < fieldDOFMngrs[b]->getNumFields(); ++f)
100  {
101  if (fieldDOFMngrs[b]->getFieldString(f) == field)
102  useAux = false;
103  }
104  }
105 
106  int block(-1);
107  if (useAux)
108  block =
109  aux_blocked_ugi_->getFieldBlock(aux_blocked_ugi_->getFieldNum(field));
110  else
111  block = blocked_ugi_->getFieldBlock(blocked_ugi_->getFieldNum(field));
112 
113  // Empty... Nothing to do.
114 #ifdef PANZER_HAVE_EPETRA_STACK
115  if (rm.getParameterList()->isType<std::string>("Coordinates-Epetra")) {
116  buildArrayToVectorEpetra(block, field, useAux);
117  buildCoordinatesEpetra(field, useAux);
118  } else
119 #endif
120  {
121  buildArrayToVectorTpetra(block, field, useAux);
122  buildCoordinatesTpetra(field, useAux);
123  }
124 }
125 
126 void ParameterListCallbackBlocked::setFieldByKey(const std::string & key,const std::string & field,Teuchos::ParameterList & pl) const
127 {
128  // x-, y-, z-coordinates needed for ML, Coordinates needed for MueLu
129  if(key=="x-coordinates") {
130  double * x = const_cast<double *>(&getCoordinateByField(0,field)[0]);
131  pl.set<double*>(key,x);
132  }
133  else if(key=="y-coordinates") {
134  double * y = const_cast<double *>(&getCoordinateByField(1,field)[0]);
135  pl.set<double*>(key,y);
136  }
137  else if(key=="z-coordinates") {
138  double * z = const_cast<double *>(&getCoordinateByField(2,field)[0]);
139  pl.set<double*>(key,z);
140  } else if(key == "Coordinates") {
142 #ifdef PANZER_HAVE_EPETRA_STACK
143  } else if(key == "Coordinates-Epetra") {
144  pl.set<Teuchos::RCP<Epetra_MultiVector> >("Coordinates",coordsVecEp_);
145  // pl.remove("Coordinates-Epetra");
146 #endif
147  }
148  else
149  TEUCHOS_TEST_FOR_EXCEPTION(true,std::runtime_error,
150  "ParameterListCallback cannot handle key=\"" << key << "\"");
151 }
152 
153 void ParameterListCallbackBlocked::buildArrayToVectorTpetra(int block,const std::string & field, const bool useAux)
154 {
155  if(arrayToVectorTpetra_[field]==Teuchos::null) {
157  if(useAux)
158  ugi = aux_blocked_ugi_->getFieldDOFManagers()[block];
159  else
160  ugi = blocked_ugi_->getFieldDOFManagers()[block];
161  arrayToVectorTpetra_[field] = Teuchos::rcp(new panzer::ArrayToFieldVector(ugi));
162  }
163 }
164 
165 #ifdef PANZER_HAVE_EPETRA_STACK
166 void ParameterListCallbackBlocked::buildArrayToVectorEpetra(int block,const std::string & field, const bool useAux)
167 {
168  if(arrayToVectorEpetra_[field]==Teuchos::null) {
170  if(useAux)
171  ugi = aux_blocked_ugi_->getFieldDOFManagers()[block];
172  else
173  ugi = blocked_ugi_->getFieldDOFManagers()[block];
174  arrayToVectorEpetra_[field] = Teuchos::rcp(new panzer::ArrayToFieldVectorEpetra(ugi));
175  }
176 }
177 #endif
178 
179 void ParameterListCallbackBlocked::buildCoordinatesTpetra(const std::string & field, const bool useAux)
180 {
181  std::map<std::string,Kokkos::DynRankView<double,PHX::Device> > data;
182 
183  Teuchos::RCP<const panzer::Intrepid2FieldPattern> fieldPattern = getFieldPattern(field,useAux);
184 
185  std::vector<std::string> elementBlocks;
186  if(useAux)
187  aux_blocked_ugi_->getElementBlockIds(elementBlocks);
188  else
189  blocked_ugi_->getElementBlockIds(elementBlocks);
190  for(std::size_t i=0;i<elementBlocks.size();++i) {
191  std::string blockId = elementBlocks[i];
192  std::vector<std::size_t> localCellIds;
193 
194  // allocate block of data to store coordinates
195  Kokkos::DynRankView<double,PHX::Device> & fieldData = data[blockId];
196  fieldData = Kokkos::DynRankView<double,PHX::Device>("fieldData",connManager_->getElementBlock(blockId).size(),fieldPattern->numberIds());
197 
198  if(fieldPattern->supportsInterpolatoryCoordinates()) {
199  // get degree of freedom coordiantes
200  connManager_->getDofCoords(blockId,*fieldPattern,localCellIds,fieldData);
201  }
202  else {
203  Teuchos::FancyOStream out(Teuchos::rcpFromRef(std::cout));
204  out.setOutputToRootOnly(-1);
205  out << "WARNING: In ParameterListCallback::buildCoordinates(), the Intrepid2::FieldPattern in "
206  << "block \"" << blockId << "\" does not support interpolatory coordinates. "
207  << "This may be fine if coordinates are not actually needed. However if they are then bad things "
208  << "will happen. Enjoy!" << std::endl;
209 
210  return;
211  }
212  }
213 
214  coordsVecTp_ = arrayToVectorTpetra_[field]->template getDataVector<double>(field,data);
215 
216  switch(coordsVecTp_->getNumVectors()) {
217  case 3:
218  zcoords_[field].resize(coordsVecTp_->getLocalLength());
219  coordsVecTp_->getVector(2)->get1dCopy(Teuchos::arrayViewFromVector(zcoords_[field]));
220  // Intentional fall-through.
221  case 2:
222  ycoords_[field].resize(coordsVecTp_->getLocalLength());
223  coordsVecTp_->getVector(1)->get1dCopy(Teuchos::arrayViewFromVector(ycoords_[field]));
224  // Intentional fall-through.
225  case 1:
226  xcoords_[field].resize(coordsVecTp_->getLocalLength());
227  coordsVecTp_->getVector(0)->get1dCopy(Teuchos::arrayViewFromVector(xcoords_[field]));
228  break;
229  default:
230  TEUCHOS_TEST_FOR_EXCEPTION(true,std::logic_error,
231  "ParameterListCallback::buildCoordinates: Constructed multivector has nonphysical dimensions.");
232  break;
233  }
234 }
235 
236 #ifdef PANZER_HAVE_EPETRA_STACK
237 void ParameterListCallbackBlocked::buildCoordinatesEpetra(const std::string & field, const bool useAux)
238 {
239  std::map<std::string,Kokkos::DynRankView<double,PHX::Device> > data;
240 
241  Teuchos::RCP<const panzer::Intrepid2FieldPattern> fieldPattern = getFieldPattern(field,useAux);
242 
243  std::vector<std::string> elementBlocks;
244  if(useAux)
245  aux_blocked_ugi_->getElementBlockIds(elementBlocks);
246  else
247  blocked_ugi_->getElementBlockIds(elementBlocks);
248  for(std::size_t i=0;i<elementBlocks.size();++i) {
249  std::string blockId = elementBlocks[i];
250  std::vector<std::size_t> localCellIds;
251 
252  // allocate block of data to store coordinates
253  Kokkos::DynRankView<double,PHX::Device> & fieldData = data[blockId];
254  fieldData = Kokkos::DynRankView<double,PHX::Device>("fieldData",connManager_->getElementBlock(blockId).size(),fieldPattern->numberIds());
255 
256  if(fieldPattern->supportsInterpolatoryCoordinates()) {
257  // get degree of freedom coordiantes
258  connManager_->getDofCoords(blockId,*fieldPattern,localCellIds,fieldData);
259  }
260  else {
261  Teuchos::FancyOStream out(Teuchos::rcpFromRef(std::cout));
262  out.setOutputToRootOnly(-1);
263  out << "WARNING: In ParameterListCallback::buildCoordinates(), the Intrepid2::FieldPattern in "
264  << "block \"" << blockId << "\" does not support interpolatory coordinates. "
265  << "This may be fine if coordinates are not actually needed. However if they are then bad things "
266  << "will happen. Enjoy!" << std::endl;
267 
268  return;
269  }
270  }
271 
272  coordsVecEp_ = arrayToVectorEpetra_[field]->template getDataVector<double>(field,data);
273 }
274 #endif
275 
276 std::string ParameterListCallbackBlocked::
277 getHandledField(const Teuchos::ParameterList & pl) const
278 {
279  // because this method assumes handlesRequest is true, this call will succeed
280  if(pl.isType<std::string>("x-coordinates"))
281  return pl.get<std::string>("x-coordinates");
282  else if(pl.isType<std::string>("Coordinates"))
283  return pl.get<std::string>("Coordinates");
284 #ifdef PANZER_HAVE_EPETRA_STACK
285  else if(pl.isType<std::string>("Coordinates-Epetra"))
286  return pl.get<std::string>("Coordinates-Epetra");
287 #endif
288  else
289 #ifdef PANZER_HAVE_EPETRA_STACK
290  TEUCHOS_TEST_FOR_EXCEPTION(true,std::logic_error,"Neither x-coordinates nor Coordinates or Coordinates-Epetra field provided.");
291 #else
292  TEUCHOS_TEST_FOR_EXCEPTION(true,std::logic_error,"Neither x-coordinates or Coordinates field provided.");
293 #endif
294 }
295 
296 const std::vector<double> & ParameterListCallbackBlocked::
297 getCoordinateByField(int dim,const std::string & field) const
298 {
299  TEUCHOS_ASSERT(dim>=0);
300  TEUCHOS_ASSERT(dim<=2);
301 
302  // get the coordinate vector you want
303  const std::map<std::string,std::vector<double> > * coord = nullptr;
304  if(dim==0) coord = &xcoords_;
305  else if(dim==1) coord = &ycoords_;
306  else if(dim==2) coord = &zcoords_;
307  else {
308  TEUCHOS_TEST_FOR_EXCEPTION(true,std::runtime_error,
309  "ParameterListCallbackBlocked::getCoordinateByField: dim is not in range of [0,2] for field \""
310  << field << "\".");
311  }
312 
313  std::map<std::string,std::vector<double> >::const_iterator itr;
314  itr = coord->find(field);
315 
316  TEUCHOS_TEST_FOR_EXCEPTION(itr==coord->end(),std::runtime_error,
317  "ParameterListCallbackBlocked::getCoordinateByField: Coordinates for field \"" + field +
318  "\" dimension " << dim << " have not been built!");
319 
320  return itr->second;
321 }
322 
323 Teuchos::RCP<const panzer::Intrepid2FieldPattern> ParameterListCallbackBlocked
324 ::getFieldPattern(const std::string & fieldName, const bool useAux) const
325 {
326  std::vector<std::string> elementBlocks;
327  if(useAux)
328  aux_blocked_ugi_->getElementBlockIds(elementBlocks);
329  else
330  blocked_ugi_->getElementBlockIds(elementBlocks);
331 
332  for(std::size_t e=0;e<elementBlocks.size();e++) {
333  std::string blockId = elementBlocks[e];
334 
335  if(blocked_ugi_->fieldInBlock(fieldName,blockId))
336  return Teuchos::rcp_dynamic_cast<const panzer::Intrepid2FieldPattern>(blocked_ugi_->getFieldPattern(blockId,fieldName),true);
337 
338  if(aux_blocked_ugi_->fieldInBlock(fieldName,blockId))
339  return Teuchos::rcp_dynamic_cast<const panzer::Intrepid2FieldPattern>(aux_blocked_ugi_->getFieldPattern(blockId,fieldName),true);
340  }
341 
342  return Teuchos::null;
343 }
344 
345 
346 }
347 
348 #endif
ConstIterator end() const
T & get(const std::string &name, T def_value)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
ParameterList & set(std::string const &name, T &&value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
T & getValue(T *ptr) const
virtual int numberIds() const
bool supportsInterpolatoryCoordinates() const
Does this field pattern support interpolatory coordinates?
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
params_t::ConstIterator ConstIterator
ConstIterator begin() const
const ParameterEntry & entry(ConstIterator i) const
PHX::MDField< ScalarT, panzer::Cell, panzer::BASIS > field
A field to which we&#39;ll contribute, or in which we&#39;ll store, the result of computing this integral...
bool isType(const std::string &name) const
#define TEUCHOS_ASSERT(assertion_test)