Panzer Version of the Day
Loading...
Searching...
No Matches
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
16namespace panzer_stk {
17
18using Teuchos::RCP;
19using Teuchos::rcp;
20
21ParameterListCallbackBlocked::ParameterListCallbackBlocked(
22 const Teuchos::RCP<const panzer_stk::STKConnManager> & connManager,
23 const Teuchos::RCP<const panzer::BlockedDOFManager> & blocked_ugi,
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
28Teuchos::RCP<Teuchos::ParameterList>
29ParameterListCallbackBlocked::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
34 Teuchos::RCP<Teuchos::ParameterList> outputPL = rcp(new Teuchos::ParameterList);
35 Teuchos::RCP<const Teuchos::ParameterList> inputPL = rm.getParameterList();
36 Teuchos::ParameterList::ConstIterator itr;
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
46bool 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
86void 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
126void 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") {
141 pl.set<Teuchos::RCP<Tpetra::MultiVector<double,int,panzer::GlobalOrdinal,panzer::TpetraNodeType> > >(key,coordsVecTp_);
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
153void ParameterListCallbackBlocked::buildArrayToVectorTpetra(int block,const std::string & field, const bool useAux)
154{
155 if(arrayToVectorTpetra_[field]==Teuchos::null) {
156 Teuchos::RCP<const panzer::GlobalIndexer> ugi;
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
166void ParameterListCallbackBlocked::buildArrayToVectorEpetra(int block,const std::string & field, const bool useAux)
167{
168 if(arrayToVectorEpetra_[field]==Teuchos::null) {
169 Teuchos::RCP<const panzer::GlobalIndexer> ugi;
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
179void 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
237void 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
276std::string ParameterListCallbackBlocked::
277getHandledField(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
296const std::vector<double> & ParameterListCallbackBlocked::
297getCoordinateByField(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
323Teuchos::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
PHX::MDField< ScalarT, panzer::Cell, panzer::BASIS > field
A field to which we'll contribute, or in which we'll store, the result of computing this integral.