Panzer Version of the Day
Loading...
Searching...
No Matches
Panzer_ScatterResidual_Tpetra_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_SCATTER_RESIDUAL_TPETRA_IMPL_HPP
12#define PANZER_SCATTER_RESIDUAL_TPETRA_IMPL_HPP
13
14#include "Teuchos_RCP.hpp"
15#include "Teuchos_Assert.hpp"
16
17#include "Phalanx_DataLayout.hpp"
18
20#include "Panzer_PureBasis.hpp"
25
26#include "Phalanx_DataLayout_MDALayout.hpp"
27
28#include "Teuchos_FancyOStream.hpp"
29
30#include "Tpetra_Vector.hpp"
31#include "Tpetra_Map.hpp"
32#include "Tpetra_CrsMatrix.hpp"
33
34// **********************************************************************
35// Specialization: Residual
36// **********************************************************************
37
38template<typename TRAITS,typename LO,typename GO,typename NodeT>
40ScatterResidual_Tpetra(const Teuchos::RCP<const panzer::GlobalIndexer> & indexer,
41 const Teuchos::ParameterList& p)
42 : globalIndexer_(indexer)
43 , globalDataKey_("Residual Scatter Container")
44{
45 std::string scatterName = p.get<std::string>("Scatter Name");
46 scatterHolder_ =
47 Teuchos::rcp(new PHX::Tag<ScalarT>(scatterName,Teuchos::rcp(new PHX::MDALayout<Dummy>(0))));
48
49 // get names to be evaluated
50 const std::vector<std::string>& names =
51 *(p.get< Teuchos::RCP< std::vector<std::string> > >("Dependent Names"));
52
53 // grab map from evaluated names to field names
54 fieldMap_ = p.get< Teuchos::RCP< std::map<std::string,std::string> > >("Dependent Map");
55
56 Teuchos::RCP<PHX::DataLayout> dl =
57 p.get< Teuchos::RCP<const panzer::PureBasis> >("Basis")->functional;
58
59 // build the vector of fields that this is dependent on
60 scatterFields_.resize(names.size());
61 scratch_offsets_.resize(names.size());
62 for (std::size_t eq = 0; eq < names.size(); ++eq) {
63 scatterFields_[eq] = PHX::MDField<const ScalarT,Cell,NODE>(names[eq],dl);
64
65 // tell the field manager that we depend on this field
66 this->addDependentField(scatterFields_[eq]);
67 }
68
69 // this is what this evaluator provides
70 this->addEvaluatedField(*scatterHolder_);
71
72 if (p.isType<std::string>("Global Data Key"))
73 globalDataKey_ = p.get<std::string>("Global Data Key");
74
75 this->setName(scatterName+" Scatter Residual");
76}
77
78// **********************************************************************
79template<typename TRAITS,typename LO,typename GO,typename NodeT>
81postRegistrationSetup(typename TRAITS::SetupData d,
83{
84 fieldIds_.resize(scatterFields_.size());
85 const Workset & workset_0 = (*d.worksets_)[0];
86 std::string blockId = this->wda(workset_0).block_id;
87
88
89 // load required field numbers for fast use
90 for(std::size_t fd=0;fd<scatterFields_.size();++fd) {
91 // get field ID from DOF manager
92 std::string fieldName = fieldMap_->find(scatterFields_[fd].fieldTag().name())->second;
93 fieldIds_[fd] = globalIndexer_->getFieldNum(fieldName);
94
95 const std::vector<int> & offsets = globalIndexer_->getGIDFieldOffsets(blockId,fieldIds_[fd]);
96 scratch_offsets_[fd] = PHX::View<int*>("offsets",offsets.size());
97 Kokkos::deep_copy(scratch_offsets_[fd], Kokkos::View<const int*, Kokkos::HostSpace, Kokkos::MemoryUnmanaged>(offsets.data(), offsets.size()));
98 }
99 scratch_lids_ = PHX::View<LO**>("lids",scatterFields_[0].extent(0),
100 globalIndexer_->getElementBlockGIDCount(blockId));
101
102}
103
104// **********************************************************************
105template<typename TRAITS,typename LO,typename GO,typename NodeT>
107preEvaluate(typename TRAITS::PreEvalData d)
108{
110
111 // extract linear object container
112 tpetraContainer_ = Teuchos::rcp_dynamic_cast<LOC>(d.gedc->getDataObject(globalDataKey_));
113
114 if(tpetraContainer_==Teuchos::null) {
115 // extract linear object container
116 Teuchos::RCP<LinearObjContainer> loc = Teuchos::rcp_dynamic_cast<LOCPair_GlobalEvaluationData>(d.gedc->getDataObject(globalDataKey_),true)->getGhostedLOC();
117 tpetraContainer_ = Teuchos::rcp_dynamic_cast<LOC>(loc);
118 }
119}
120
121
122// **********************************************************************
123// Specialization: Tangent
124// **********************************************************************
125
126template<typename TRAITS,typename LO,typename GO,typename NodeT>
128ScatterResidual_Tpetra(const Teuchos::RCP<const panzer::GlobalIndexer> & indexer,
129 const Teuchos::ParameterList& p)
130 : globalIndexer_(indexer)
131 , globalDataKey_("Residual Scatter Container")
132{
133
134 std::string scatterName = p.get<std::string>("Scatter Name");
135 scatterHolder_ =
136 Teuchos::rcp(new PHX::Tag<ScalarT>(scatterName,Teuchos::rcp(new PHX::MDALayout<Dummy>(0))));
137
138 // get names to be evaluated
139 const std::vector<std::string>& names =
140 *(p.get< Teuchos::RCP< std::vector<std::string> > >("Dependent Names"));
141
142 // grab map from evaluated names to field names
143 fieldMap_ = p.get< Teuchos::RCP< std::map<std::string,std::string> > >("Dependent Map");
144
145 Teuchos::RCP<PHX::DataLayout> dl =
146 p.get< Teuchos::RCP<const panzer::PureBasis> >("Basis")->functional;
147
148 // build the vector of fields that this is dependent on
149 scatterFields_.resize(names.size());
150 scratch_offsets_.resize(names.size());
151 for (std::size_t eq = 0; eq < names.size(); ++eq) {
152 scatterFields_[eq] = PHX::MDField<const ScalarT,Cell,NODE>(names[eq],dl);
153
154 // tell the field manager that we depend on this field
155 this->addDependentField(scatterFields_[eq]);
156 }
157
158 // this is what this evaluator provides
159 this->addEvaluatedField(*scatterHolder_);
160
161 if (p.isType<std::string>("Global Data Key"))
162 globalDataKey_ = p.get<std::string>("Global Data Key");
163
164 this->setName(scatterName+" Scatter Tangent");
165}
166
167// **********************************************************************
168template<typename TRAITS,typename LO,typename GO,typename NodeT>
170postRegistrationSetup(typename TRAITS::SetupData d,
172{
173 fieldIds_.resize(scatterFields_.size());
174 const Workset & workset_0 = (*d.worksets_)[0];
175 std::string blockId = this->wda(workset_0).block_id;
176
177 // load required field numbers for fast use
178 for(std::size_t fd=0;fd<scatterFields_.size();++fd) {
179 // get field ID from DOF manager
180 std::string fieldName = fieldMap_->find(scatterFields_[fd].fieldTag().name())->second;
181 fieldIds_[fd] = globalIndexer_->getFieldNum(fieldName);
182
183 const std::vector<int> & offsets = globalIndexer_->getGIDFieldOffsets(blockId,fieldIds_[fd]);
184 scratch_offsets_[fd] = PHX::View<int*>("offsets",offsets.size());
185 Kokkos::deep_copy(scratch_offsets_[fd], Kokkos::View<const int*, Kokkos::HostSpace, Kokkos::MemoryUnmanaged>(offsets.data(), offsets.size()));
186 }
187 scratch_lids_ = PHX::View<LO**>("lids",scatterFields_[0].extent(0),
188 globalIndexer_->getElementBlockGIDCount(blockId));
189}
190
191// **********************************************************************
192template<typename TRAITS,typename LO,typename GO,typename NodeT>
194preEvaluate(typename TRAITS::PreEvalData d)
195{
196 using Teuchos::RCP;
197 using Teuchos::rcp_dynamic_cast;
198
200
201 // this is the list of parameters and their names that this scatter has to account for
202 std::vector<std::string> activeParameters =
203 rcp_dynamic_cast<ParameterList_GlobalEvaluationData>(d.gedc->getDataObject("PARAMETER_NAMES"))->getActiveParameters();
204
205 // Only the outer view is allocated here. The device views of the df/dp
206 // vectors are acquired and released in evaluateFields().
207 dfdpFieldsVoV_.initialize("ScatterResidual_Tpetra<Tangent>::dfdpFieldsVoV_",activeParameters.size());
208
209 dfdpVectors_.resize(activeParameters.size());
210 for(std::size_t i=0;i<activeParameters.size();i++)
211 dfdpVectors_[i] = rcp_dynamic_cast<LOC>(d.gedc->getDataObject(activeParameters[i]),true)->get_f_mv();
212
213 // extract linear object container
214 tpetraContainer_ = Teuchos::rcp_dynamic_cast<LOC>(d.gedc->getDataObject(globalDataKey_));
215
216 if(tpetraContainer_==Teuchos::null) {
217 // extract linear object container
218 Teuchos::RCP<LinearObjContainer> loc = Teuchos::rcp_dynamic_cast<LOCPair_GlobalEvaluationData>(d.gedc->getDataObject(globalDataKey_),true)->getGhostedLOC();
219 tpetraContainer_ = Teuchos::rcp_dynamic_cast<LOC>(loc);
220 }
221}
222
223// **********************************************************************
224// Specialization: Jacobian
225// **********************************************************************
226
227template<typename TRAITS,typename LO,typename GO,typename NodeT>
229ScatterResidual_Tpetra(const Teuchos::RCP<const GlobalIndexer> & indexer,
230 const Teuchos::ParameterList& p)
231 : globalIndexer_(indexer)
232 , globalDataKey_("Residual Scatter Container")
233 , my_derivative_size_(0)
234 , other_derivative_size_(0)
235{
236 std::string scatterName = p.get<std::string>("Scatter Name");
237 scatterHolder_ =
238 Teuchos::rcp(new PHX::Tag<ScalarT>(scatterName,Teuchos::rcp(new PHX::MDALayout<Dummy>(0))));
239
240 // get names to be evaluated
241 const std::vector<std::string>& names =
242 *(p.get< Teuchos::RCP< std::vector<std::string> > >("Dependent Names"));
243
244 // grab map from evaluated names to field names
245 fieldMap_ = p.get< Teuchos::RCP< std::map<std::string,std::string> > >("Dependent Map");
246
247 Teuchos::RCP<PHX::DataLayout> dl =
248 p.get< Teuchos::RCP<const panzer::PureBasis> >("Basis")->functional;
249
250 // build the vector of fields that this is dependent on
251 scatterFields_.resize(names.size());
252 scratch_offsets_.resize(names.size());
253 for (std::size_t eq = 0; eq < names.size(); ++eq) {
254 scatterFields_[eq] = PHX::MDField<const ScalarT,Cell,NODE>(names[eq],dl);
255
256 // tell the field manager that we depend on this field
257 this->addDependentField(scatterFields_[eq]);
258 }
259
260 // this is what this evaluator provides
261 this->addEvaluatedField(*scatterHolder_);
262
263 if (p.isType<std::string>("Global Data Key"))
264 globalDataKey_ = p.get<std::string>("Global Data Key");
265
266 this->setName(scatterName+" Scatter Residual (Jacobian)");
267}
268
269// **********************************************************************
270template<typename TRAITS,typename LO,typename GO,typename NodeT>
272postRegistrationSetup(typename TRAITS::SetupData d,
274{
275 fieldIds_.resize(scatterFields_.size());
276
277 const Workset & workset_0 = (*d.worksets_)[0];
278 std::string blockId = this->wda(workset_0).block_id;
279
280 // load required field numbers for fast use
281 for(std::size_t fd=0;fd<scatterFields_.size();++fd) {
282 // get field ID from DOF manager
283 std::string fieldName = fieldMap_->find(scatterFields_[fd].fieldTag().name())->second;
284 fieldIds_[fd] = globalIndexer_->getFieldNum(fieldName);
285
286 int fieldNum = fieldIds_[fd];
287 const std::vector<int> & offsets = globalIndexer_->getGIDFieldOffsets(blockId,fieldNum);
288 scratch_offsets_[fd] = PHX::View<int*>("offsets",offsets.size());
289 Kokkos::deep_copy(scratch_offsets_[fd], Kokkos::View<const int*, Kokkos::HostSpace, Kokkos::MemoryUnmanaged>(offsets.data(), offsets.size()));
290 }
291
292 my_derivative_size_ = globalIndexer_->getElementBlockGIDCount(blockId);
293 if (Teuchos::nonnull(workset_0.other)) {
294 auto otherBlockId = workset_0.other->block_id;
295 other_derivative_size_ = globalIndexer_->getElementBlockGIDCount(otherBlockId);
296 }
297 scratch_lids_ = Kokkos::View<LO**, Kokkos::LayoutRight, PHX::Device>(
298 "lids", scatterFields_[0].extent(0), my_derivative_size_ + other_derivative_size_ );
299 scratch_vals_ = Kokkos::View<typename Sacado::ScalarType<ScalarT>::type**, Kokkos::LayoutRight, PHX::Device>(
300 "vals", scatterFields_[0].extent(0), my_derivative_size_ + other_derivative_size_ );
301}
302
303// **********************************************************************
304template<typename TRAITS,typename LO,typename GO,typename NodeT>
306preEvaluate(typename TRAITS::PreEvalData d)
307{
309
310 // extract linear object container
311 tpetraContainer_ = Teuchos::rcp_dynamic_cast<LOC>(d.gedc->getDataObject(globalDataKey_));
312
313 if(tpetraContainer_==Teuchos::null) {
314 // extract linear object container
315 Teuchos::RCP<LinearObjContainer> loc = Teuchos::rcp_dynamic_cast<LOCPair_GlobalEvaluationData>(d.gedc->getDataObject(globalDataKey_),true)->getGhostedLOC();
316 tpetraContainer_ = Teuchos::rcp_dynamic_cast<LOC>(loc);
317 }
318}
319
320
321// **********************************************************************
322namespace panzer {
323namespace {
324
325template <typename ScalarT,typename LO,typename GO,typename NodeT,typename LocalMatrixT>
326class ScatterResidual_Jacobian_Functor {
327public:
328 typedef typename PHX::Device execution_space;
329 typedef PHX::MDField<const ScalarT,Cell,NODE> FieldType;
330
332 Kokkos::View<double**, Kokkos::LayoutLeft,PHX::Device> r_data;
333 LocalMatrixT jac; // Kokkos jacobian type
334
335 Kokkos::View<const LO**, Kokkos::LayoutRight, PHX::Device> lids; // local indices for unknowns.
336 Kokkos::View<typename Sacado::ScalarType<ScalarT>::type**, Kokkos::LayoutRight, PHX::Device> vals;
337 PHX::View<const int*> offsets; // how to get a particular field
338 FieldType field;
339
340
341 KOKKOS_INLINE_FUNCTION
342 void operator()(const unsigned int cell) const
343 {
344 int numIds = lids.extent(1);
345
346 // loop over the basis functions (currently they are nodes)
347 for(std::size_t basis=0; basis < offsets.extent(0); basis++) {
348 typename FieldType::array_type::reference_type scatterField = field(cell,basis);
349 int offset = offsets(basis);
350 LO lid = lids(cell,offset);
351
352 // Sum residual
353 if(fillResidual)
354 Kokkos::atomic_add(&r_data(lid,0), scatterField.val());
355
356 // loop over the sensitivity indices: all DOFs on a cell
357 for(int sensIndex=0;sensIndex<numIds;++sensIndex)
358 vals(cell,sensIndex) = scatterField.fastAccessDx(sensIndex);
359
360 // Sum Jacobian
361 jac.sumIntoValues(lid, &lids(cell,0), numIds, &vals(cell,0), true, true);
362 } // end basis
363 }
364};
365
366template <typename ScalarT,typename LO,typename GO,typename NodeT>
367class ScatterResidual_Residual_Functor {
368public:
369 typedef typename PHX::Device execution_space;
370 typedef PHX::MDField<const ScalarT,Cell,NODE> FieldType;
371
372 Kokkos::View<double**, Kokkos::LayoutLeft,PHX::Device> r_data;
373
374 PHX::View<const LO**> lids; // local indices for unknowns
375 PHX::View<const int*> offsets; // how to get a particular field
377
378 KOKKOS_INLINE_FUNCTION
379 void operator()(const unsigned int cell) const
380 {
381
382 // loop over the basis functions (currently they are nodes)
383 for(std::size_t basis=0; basis < offsets.extent(0); basis++) {
384 int offset = offsets(basis);
385 LO lid = lids(cell,offset);
386 Kokkos::atomic_add(&r_data(lid,0), field(cell,basis));
387
388 } // end basis
389 }
390};
391
392template <typename ScalarT,typename LO,typename GO,typename NodeT>
393class ScatterResidual_Tangent_Functor {
394public:
395 typedef typename PHX::Device execution_space;
396 typedef PHX::MDField<const ScalarT,Cell,NODE> FieldType;
397
398 bool fillResidual;
399 Kokkos::View<double**, Kokkos::LayoutLeft,PHX::Device> r_data;
400
401 Kokkos::View<const LO**> lids; // local indices for unknowns.
402 PHX::View<const int*> offsets; // how to get a particular field
404 std::size_t num_params;
405
406 Kokkos::View<Kokkos::View<double**,Kokkos::LayoutLeft,PHX::Device>*> dfdp_fields; // tangent fields
407
408 KOKKOS_INLINE_FUNCTION
409 void operator()(const unsigned int cell) const
410 {
411
412 // loop over the basis functions (currently they are nodes)
413 for(std::size_t basis=0; basis < offsets.extent(0); basis++) {
414 typename FieldType::array_type::reference_type scatterField = field(cell,basis);
415 int offset = offsets(basis);
416 LO lid = lids(cell,offset);
417
418 // Sum residual
419 if(fillResidual)
420 Kokkos::atomic_add(&r_data(lid,0), scatterField.val());
421
422 // loop over the tangents
423 for(std::size_t i_param=0; i_param<num_params; i_param++)
424 Kokkos::atomic_add(&dfdp_fields(i_param)(lid,0), scatterField.fastAccessDx(i_param));
425
426 } // end basis
427 }
428};
429
430}
431}
432
433// **********************************************************************
434template<typename TRAITS,typename LO,typename GO,typename NodeT>
436evaluateFields(typename TRAITS::EvalData workset)
437{
439
440 // for convenience pull out some objects from workset
441 std::string blockId = this->wda(workset).block_id;
442
443 Teuchos::RCP<typename LOC::MultiVectorType> r = tpetraContainer_->get_f_mv();
444
445 globalIndexer_->getElementLIDs(this->wda(workset).cell_local_ids_k,scratch_lids_);
446
447 ScatterResidual_Residual_Functor<ScalarT,LO,GO,NodeT> functor;
448 functor.r_data = r->getLocalViewDevice(Tpetra::Access::ReadWrite);
449 functor.lids = scratch_lids_;
450
451 // for each field, do a parallel for loop
452 for(std::size_t fieldIndex = 0; fieldIndex < scatterFields_.size(); fieldIndex++) {
453 functor.offsets = scratch_offsets_[fieldIndex];
454 functor.field = scatterFields_[fieldIndex];
455
456 Kokkos::parallel_for(workset.num_cells,functor);
457 }
458}
459
460// **********************************************************************
461template<typename TRAITS,typename LO,typename GO,typename NodeT>
463evaluateFields(typename TRAITS::EvalData workset)
464{
466
467 typedef typename LOC::CrsMatrixType::local_matrix_device_type LocalMatrixT;
468
469 // for convenience pull out some objects from workset
470 std::string blockId = this->wda(workset).block_id;
471
472 Teuchos::RCP<typename LOC::MultiVectorType> r = tpetraContainer_->get_f_mv();
473 Teuchos::RCP<typename LOC::CrsMatrixType> Jac = tpetraContainer_->get_A();
474
475 // Cache scratch lids. For interface bc problems the derivative
476 // dimension extent spans two cells. Use subviews to get the self
477 // lids and the other lids.
478 if (Teuchos::nonnull(workset.other)) {
479 auto my_scratch_lids = Kokkos::subview(scratch_lids_,Kokkos::ALL,std::make_pair(0,my_derivative_size_));
480 globalIndexer_->getElementLIDs(this->wda(workset).cell_local_ids_k,my_scratch_lids);
481 auto other_scratch_lids = Kokkos::subview(scratch_lids_,Kokkos::ALL,std::make_pair(my_derivative_size_,my_derivative_size_ + other_derivative_size_));
482 globalIndexer_->getElementLIDs(workset.other->cell_local_ids_k,other_scratch_lids);
483 }
484 else {
485 globalIndexer_->getElementLIDs(this->wda(workset).cell_local_ids_k,scratch_lids_);
486 }
487
488 ScatterResidual_Jacobian_Functor<ScalarT,LO,GO,NodeT,LocalMatrixT> functor;
489 functor.fillResidual = (r!=Teuchos::null);
490 if(functor.fillResidual)
491 functor.r_data = r->getLocalViewDevice(Tpetra::Access::ReadWrite);
492 functor.jac = Jac->getLocalMatrixDevice();
493 functor.lids = scratch_lids_;
494 functor.vals = scratch_vals_;
495
496 // for each field, do a parallel for loop
497 for(std::size_t fieldIndex = 0; fieldIndex < scatterFields_.size(); fieldIndex++) {
498 functor.offsets = scratch_offsets_[fieldIndex];
499 functor.field = scatterFields_[fieldIndex];
500
501 Kokkos::parallel_for(workset.num_cells,functor);
502 }
503
504}
505
506// **********************************************************************
507template<typename TRAITS,typename LO,typename GO,typename NodeT>
509evaluateFields(typename TRAITS::EvalData workset)
510{
512
513 // for convenience pull out some objects from workset
514 std::string blockId = this->wda(workset).block_id;
515
516 Teuchos::RCP<typename LOC::MultiVectorType> r = tpetraContainer_->get_f_mv();
517
518 globalIndexer_->getElementLIDs(this->wda(workset).getLocalCellIDs(),scratch_lids_);
519
520 // Acquire the df/dp device views for the duration of this method only. See
521 // the release loop at the end of this method.
522 for(std::size_t i=0;i<dfdpVectors_.size();i++)
523 dfdpFieldsVoV_.addView(dfdpVectors_[i]->getLocalViewDevice(Tpetra::Access::ReadWrite),i);
524 dfdpFieldsVoV_.syncHostToDevice();
525
526 ScatterResidual_Tangent_Functor<ScalarT,LO,GO,NodeT> functor;
527 functor.fillResidual = (r!=Teuchos::null);
528 if(functor.fillResidual)
529 functor.r_data = r->getLocalViewDevice(Tpetra::Access::ReadWrite);
530 functor.lids = scratch_lids_;
531 functor.dfdp_fields = dfdpFieldsVoV_.getViewDevice();
532
533 // for each field, do a parallel for loop
534 for(std::size_t fieldIndex = 0; fieldIndex < scatterFields_.size(); fieldIndex++) {
535 functor.offsets = scratch_offsets_[fieldIndex];
536 functor.field = scatterFields_[fieldIndex];
537 functor.num_params = Sacado::dimension_scalar(scatterFields_[fieldIndex].get_view())-1;
538
539 Kokkos::parallel_for(workset.num_cells,functor);
540 }
541
542 // Release the df/dp device views. Holding a device view past the return of
543 // this method makes any subsequent host access to the same vector throw, e.g.
544 // AssemblyEngine::evaluateDirichletBCs() -> adjustForDirichletConditions().
545 for(std::size_t i=0;i<dfdpVectors_.size();i++)
546 dfdpFieldsVoV_.addView(Kokkos::View<RealT**,Kokkos::LayoutLeft,PHX::Device>(),i);
547}
548
549// **********************************************************************
550
551#endif
PHX::View< const int * > offsets
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.
Kokkos::View< Kokkos::View< double **, Kokkos::LayoutLeft, PHX::Device > * > dfdp_fields
PHX::View< const LO ** > lids
Kokkos::View< double **, Kokkos::LayoutLeft, PHX::Device > r_data
Kokkos::View< typename Sacado::ScalarType< ScalarT >::type **, Kokkos::LayoutRight, PHX::Device > vals
Pushes residual values into the residual vector for a Newton-based solve.
Tpetra-backed implementation of LinearObjContainer.
virtual void initialize()
Zeroes out whichever of x, dxdt, f, and A are currently set.
const Teuchos::RCP< MultiVectorType > get_f_mv() const
std::string block_id
DEPRECATED - use: getElementBlock()
Teuchos::RCP< WorksetDetails > other
FieldType
The type of discretization to use for a field pattern.