43 #ifndef PANZER_SCATTER_RESIDUAL_TPETRA_IMPL_HPP
44 #define PANZER_SCATTER_RESIDUAL_TPETRA_IMPL_HPP
47 #include "Teuchos_Assert.hpp"
49 #include "Phalanx_DataLayout.hpp"
58 #include "Phalanx_DataLayout_MDALayout.hpp"
60 #include "Teuchos_FancyOStream.hpp"
62 #include "Tpetra_Vector.hpp"
63 #include "Tpetra_Map.hpp"
64 #include "Tpetra_CrsMatrix.hpp"
70 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
74 : globalIndexer_(indexer)
75 , globalDataKey_(
"Residual Scatter Container")
77 std::string scatterName = p.
get<std::string>(
"Scatter Name");
82 const std::vector<std::string>& names =
92 scatterFields_.resize(names.size());
93 scratch_offsets_.resize(names.size());
94 for (std::size_t eq = 0; eq < names.size(); ++eq) {
95 scatterFields_[eq] = PHX::MDField<const ScalarT,Cell,NODE>(names[eq],dl);
98 this->addDependentField(scatterFields_[eq]);
102 this->addEvaluatedField(*scatterHolder_);
104 if (p.
isType<std::string>(
"Global Data Key"))
105 globalDataKey_ = p.
get<std::string>(
"Global Data Key");
107 this->setName(scatterName+
" Scatter Residual");
111 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
116 fieldIds_.resize(scatterFields_.size());
117 const Workset & workset_0 = (*d.worksets_)[0];
118 std::string blockId = this->wda(workset_0).
block_id;
122 for(std::size_t fd=0;fd<scatterFields_.size();++fd) {
124 std::string fieldName = fieldMap_->find(scatterFields_[fd].fieldTag().name())->second;
125 fieldIds_[fd] = globalIndexer_->getFieldNum(fieldName);
127 const std::vector<int> &
offsets = globalIndexer_->getGIDFieldOffsets(blockId,fieldIds_[fd]);
128 scratch_offsets_[fd] = Kokkos::View<int*,PHX::Device>(
"offsets",offsets.size());
129 for(std::size_t i=0;i<offsets.size();i++)
130 scratch_offsets_[fd](i) = offsets[i];
132 scratch_lids_ = Kokkos::View<LO**,PHX::Device>(
"lids",scatterFields_[0].extent(0),
133 globalIndexer_->getElementBlockGIDCount(blockId));
138 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
145 tpetraContainer_ = Teuchos::rcp_dynamic_cast<LOC>(d.gedc->getDataObject(globalDataKey_));
147 if(tpetraContainer_==Teuchos::null) {
150 tpetraContainer_ = Teuchos::rcp_dynamic_cast<LOC>(loc);
159 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
163 : globalIndexer_(indexer)
164 , globalDataKey_(
"Residual Scatter Container")
166 std::string scatterName = p.
get<std::string>(
"Scatter Name");
171 const std::vector<std::string>& names =
181 scatterFields_.resize(names.size());
182 for (std::size_t eq = 0; eq < names.size(); ++eq) {
183 scatterFields_[eq] = PHX::MDField<const ScalarT,Cell,NODE>(names[eq],dl);
186 this->addDependentField(scatterFields_[eq]);
190 this->addEvaluatedField(*scatterHolder_);
192 if (p.
isType<std::string>(
"Global Data Key"))
193 globalDataKey_ = p.
get<std::string>(
"Global Data Key");
195 this->setName(scatterName+
" Scatter Tangent");
199 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
204 fieldIds_.resize(scatterFields_.size());
206 for(std::size_t fd=0;fd<scatterFields_.size();++fd) {
208 std::string fieldName = fieldMap_->find(scatterFields_[fd].fieldTag().name())->second;
209 fieldIds_[fd] = globalIndexer_->getFieldNum(fieldName);
214 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
219 using Teuchos::rcp_dynamic_cast;
224 std::vector<std::string> activeParameters =
227 dfdp_vectors_.clear();
228 for(std::size_t i=0;i<activeParameters.size();i++) {
230 rcp_dynamic_cast<LOC>(d.gedc->getDataObject(activeParameters[i]),
true)->get_f();
232 dfdp_vectors_.push_back(vec_array);
237 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
242 std::string blockId = this->wda(workset).block_id;
243 const std::vector<std::size_t> & localCellIds = this->wda(workset).cell_local_ids;
251 for(std::size_t worksetCellIndex=0;worksetCellIndex<localCellIds.size();++worksetCellIndex) {
252 std::size_t cellLocalId = localCellIds[worksetCellIndex];
254 auto LIDs = globalIndexer_->getElementLIDs(cellLocalId);
257 for (std::size_t fieldIndex = 0; fieldIndex < scatterFields_.size(); fieldIndex++) {
258 int fieldNum = fieldIds_[fieldIndex];
259 const std::vector<int> & elmtOffset = globalIndexer_->getGIDFieldOffsets(blockId,fieldNum);
262 for(std::size_t basis=0;basis<elmtOffset.size();basis++) {
263 int offset = elmtOffset[basis];
264 LO lid = LIDs[offset];
265 ScalarT value = (scatterFields_[fieldIndex])(worksetCellIndex,basis);
266 for(
int d=0;d<value.size();d++)
267 dfdp_vectors_[d][lid] += value.fastAccessDx(d);
277 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
281 : globalIndexer_(indexer)
282 , globalDataKey_(
"Residual Scatter Container")
284 std::string scatterName = p.
get<std::string>(
"Scatter Name");
289 const std::vector<std::string>& names =
299 scatterFields_.resize(names.size());
300 scratch_offsets_.resize(names.size());
301 for (std::size_t eq = 0; eq < names.size(); ++eq) {
302 scatterFields_[eq] = PHX::MDField<const ScalarT,Cell,NODE>(names[eq],dl);
305 this->addDependentField(scatterFields_[eq]);
309 this->addEvaluatedField(*scatterHolder_);
311 if (p.
isType<std::string>(
"Global Data Key"))
312 globalDataKey_ = p.
get<std::string>(
"Global Data Key");
314 this->setName(scatterName+
" Scatter Residual (Jacobian)");
318 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
323 fieldIds_.resize(scatterFields_.size());
325 const Workset & workset_0 = (*d.worksets_)[0];
326 std::string blockId = this->wda(workset_0).
block_id;
329 for(std::size_t fd=0;fd<scatterFields_.size();++fd) {
331 std::string fieldName = fieldMap_->find(scatterFields_[fd].fieldTag().name())->second;
332 fieldIds_[fd] = globalIndexer_->getFieldNum(fieldName);
334 int fieldNum = fieldIds_[fd];
335 const std::vector<int> &
offsets = globalIndexer_->getGIDFieldOffsets(blockId,fieldNum);
336 scratch_offsets_[fd] = Kokkos::View<int*,PHX::Device>(
"offsets",offsets.size());
337 for(std::size_t i=0;i<offsets.size();i++)
338 scratch_offsets_[fd](i) = offsets[i];
341 scratch_lids_ = Kokkos::View<LO**,PHX::Device>(
"lids",scatterFields_[0].extent(0),
342 globalIndexer_->getElementBlockGIDCount(blockId));
346 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
353 tpetraContainer_ = Teuchos::rcp_dynamic_cast<LOC>(d.gedc->getDataObject(globalDataKey_));
355 if(tpetraContainer_==Teuchos::null) {
358 tpetraContainer_ = Teuchos::rcp_dynamic_cast<LOC>(loc);
367 template <
typename ScalarT,
typename LO,
typename GO,
typename NodeT,
typename LocalMatrixT>
368 class ScatterResidual_Jacobian_Functor {
370 typedef typename PHX::Device execution_space;
371 typedef PHX::MDField<const ScalarT,Cell,NODE>
FieldType;
374 Kokkos::View<double**, Kokkos::LayoutLeft,PHX::Device>
r_data;
377 Kokkos::View<const LO**,PHX::Device>
lids;
382 KOKKOS_INLINE_FUNCTION
383 void operator()(
const unsigned int cell)
const
386 typename Sacado::ScalarType<ScalarT>::type vals[256];
387 int numIds =
lids.extent(1);
389 for(
int i=0;i<numIds;i++)
390 cLIDs[i] =
lids(cell,i);
393 for(std::size_t basis=0; basis <
offsets.extent(0); basis++) {
394 typename FieldType::array_type::reference_type scatterField =
field(cell,basis);
396 LO lid =
lids(cell,offset);
400 Kokkos::atomic_add(&
r_data(lid,0), scatterField.val());
403 for(
int sensIndex=0;sensIndex<numIds;++sensIndex)
404 vals[sensIndex] = scatterField.fastAccessDx(sensIndex);
407 jac.sumIntoValues(lid, cLIDs,numIds, vals,
true,
true);
412 template <
typename ScalarT,
typename LO,
typename GO,
typename NodeT>
413 class ScatterResidual_Residual_Functor {
415 typedef typename PHX::Device execution_space;
416 typedef PHX::MDField<const ScalarT,Cell,NODE>
FieldType;
418 Kokkos::View<double**, Kokkos::LayoutLeft,PHX::Device>
r_data;
420 Kokkos::View<const LO**,PHX::Device>
lids;
421 Kokkos::View<const int*,PHX::Device>
offsets;
425 KOKKOS_INLINE_FUNCTION
426 void operator()(
const unsigned int cell)
const
430 for(std::size_t basis=0; basis <
offsets.extent(0); basis++) {
432 LO lid =
lids(cell,offset);
433 Kokkos::atomic_add(&
r_data(lid,0),
field(cell,basis));
443 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
450 std::string blockId = this->wda(workset).block_id;
454 globalIndexer_->getElementLIDs(this->wda(workset).cell_local_ids_k,scratch_lids_);
456 ScatterResidual_Residual_Functor<ScalarT,LO,GO,NodeT> functor;
457 functor.r_data = r->template getLocalView<PHX::Device>();
458 functor.lids = scratch_lids_;
461 for(std::size_t fieldIndex = 0; fieldIndex < scatterFields_.size(); fieldIndex++) {
462 functor.offsets = scratch_offsets_[fieldIndex];
463 functor.field = scatterFields_[fieldIndex];
465 Kokkos::parallel_for(workset.num_cells,functor);
470 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
476 typedef typename LOC::CrsMatrixType::local_matrix_type LocalMatrixT;
479 std::string blockId = this->wda(workset).block_id;
484 globalIndexer_->getElementLIDs(this->wda(workset).cell_local_ids_k,scratch_lids_);
486 ScatterResidual_Jacobian_Functor<ScalarT,LO,GO,NodeT,LocalMatrixT> functor;
487 functor.fillResidual = (r!=Teuchos::null);
488 if(functor.fillResidual)
489 functor.r_data = r->template getLocalView<PHX::Device>();
490 functor.jac = Jac->getLocalMatrix();
491 functor.lids = scratch_lids_;
494 for(std::size_t fieldIndex = 0; fieldIndex < scatterFields_.size(); fieldIndex++) {
495 functor.offsets = scratch_offsets_[fieldIndex];
496 functor.field = scatterFields_[fieldIndex];
498 Kokkos::parallel_for(workset.num_cells,functor);
panzer::Traits::Tangent::ScalarT ScalarT
T & get(const std::string &name, T def_value)
FieldType
The type of discretization to use for a field pattern.
Kokkos::View< const LO **, PHX::Device > lids
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Kokkos::View< double **, Kokkos::LayoutLeft, PHX::Device > r_data
Pushes residual values into the residual vector for a Newton-based solve.
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...
bool isType(const std::string &name) const
Kokkos::View< const int *, PHX::Device > offsets