11 #ifndef PANZER_SCATTER_RESIDUAL_TPETRA_IMPL_HPP
12 #define PANZER_SCATTER_RESIDUAL_TPETRA_IMPL_HPP
15 #include "Teuchos_Assert.hpp"
17 #include "Phalanx_DataLayout.hpp"
26 #include "Phalanx_DataLayout_MDALayout.hpp"
28 #include "Teuchos_FancyOStream.hpp"
30 #include "Tpetra_Vector.hpp"
31 #include "Tpetra_Map.hpp"
32 #include "Tpetra_CrsMatrix.hpp"
38 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
42 : globalIndexer_(indexer)
43 , globalDataKey_(
"Residual Scatter Container")
45 std::string scatterName = p.
get<std::string>(
"Scatter Name");
50 const std::vector<std::string>& names =
60 scatterFields_.resize(names.size());
61 scratch_offsets_.resize(names.size());
62 for (std::size_t eq = 0; eq < names.size(); ++eq) {
66 this->addDependentField(scatterFields_[eq]);
70 this->addEvaluatedField(*scatterHolder_);
72 if (p.
isType<std::string>(
"Global Data Key"))
73 globalDataKey_ = p.
get<std::string>(
"Global Data Key");
75 this->setName(scatterName+
" Scatter Residual");
79 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
84 fieldIds_.resize(scatterFields_.size());
85 const Workset & workset_0 = (*d.worksets_)[0];
86 std::string blockId = this->wda(workset_0).
block_id;
90 for(std::size_t fd=0;fd<scatterFields_.size();++fd) {
92 std::string fieldName = fieldMap_->find(scatterFields_[fd].fieldTag().name())->second;
93 fieldIds_[fd] = globalIndexer_->getFieldNum(fieldName);
95 const std::vector<int> &
offsets = globalIndexer_->getGIDFieldOffsets(blockId,fieldIds_[fd]);
96 scratch_offsets_[fd] = PHX::View<int*>(
"offsets",offsets.size());
99 scratch_lids_ = PHX::View<LO**>(
"lids",scatterFields_[0].extent(0),
100 globalIndexer_->getElementBlockGIDCount(blockId));
105 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
112 tpetraContainer_ = Teuchos::rcp_dynamic_cast<LOC>(d.gedc->getDataObject(globalDataKey_));
114 if(tpetraContainer_==Teuchos::null) {
117 tpetraContainer_ = Teuchos::rcp_dynamic_cast<LOC>(loc);
126 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
130 : globalIndexer_(indexer)
131 , globalDataKey_(
"Residual Scatter Container")
133 std::string scatterName = p.
get<std::string>(
"Scatter Name");
138 const std::vector<std::string>& names =
148 scatterFields_.resize(names.size());
149 for (std::size_t eq = 0; eq < names.size(); ++eq) {
153 this->addDependentField(scatterFields_[eq]);
157 this->addEvaluatedField(*scatterHolder_);
159 if (p.
isType<std::string>(
"Global Data Key"))
160 globalDataKey_ = p.
get<std::string>(
"Global Data Key");
162 this->setName(scatterName+
" Scatter Tangent");
166 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
171 fieldIds_.resize(scatterFields_.size());
173 for(std::size_t fd=0;fd<scatterFields_.size();++fd) {
175 std::string fieldName = fieldMap_->find(scatterFields_[fd].fieldTag().name())->second;
176 fieldIds_[fd] = globalIndexer_->getFieldNum(fieldName);
181 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
186 using Teuchos::rcp_dynamic_cast;
191 std::vector<std::string> activeParameters =
194 dfdp_vectors_.clear();
195 for(std::size_t i=0;i<activeParameters.size();i++) {
197 rcp_dynamic_cast<LOC>(d.gedc->getDataObject(activeParameters[i]),
true)->get_f();
199 dfdp_vectors_.push_back(vec_array);
204 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
209 std::string blockId = this->wda(workset).block_id;
210 const std::vector<std::size_t> & localCellIds = this->wda(workset).cell_local_ids;
218 for(std::size_t worksetCellIndex=0;worksetCellIndex<localCellIds.size();++worksetCellIndex) {
219 std::size_t cellLocalId = localCellIds[worksetCellIndex];
221 auto LIDs = globalIndexer_->getElementLIDs(cellLocalId);
224 for (std::size_t fieldIndex = 0; fieldIndex < scatterFields_.size(); fieldIndex++) {
225 int fieldNum = fieldIds_[fieldIndex];
226 const std::vector<int> & elmtOffset = globalIndexer_->getGIDFieldOffsets(blockId,fieldNum);
229 for(std::size_t basis=0;basis<elmtOffset.size();basis++) {
230 int offset = elmtOffset[basis];
231 LO lid = LIDs[offset];
232 ScalarT value = (scatterFields_[fieldIndex])(worksetCellIndex,basis);
233 for(
int d=0;d<value.size();d++)
234 dfdp_vectors_[d][lid] += value.fastAccessDx(d);
244 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
248 : globalIndexer_(indexer)
249 , globalDataKey_(
"Residual Scatter Container")
250 , my_derivative_size_(0)
251 , other_derivative_size_(0)
253 std::string scatterName = p.
get<std::string>(
"Scatter Name");
258 const std::vector<std::string>& names =
268 scatterFields_.resize(names.size());
269 scratch_offsets_.resize(names.size());
270 for (std::size_t eq = 0; eq < names.size(); ++eq) {
274 this->addDependentField(scatterFields_[eq]);
278 this->addEvaluatedField(*scatterHolder_);
280 if (p.
isType<std::string>(
"Global Data Key"))
281 globalDataKey_ = p.
get<std::string>(
"Global Data Key");
283 this->setName(scatterName+
" Scatter Residual (Jacobian)");
287 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
292 fieldIds_.resize(scatterFields_.size());
294 const Workset & workset_0 = (*d.worksets_)[0];
295 std::string blockId = this->wda(workset_0).
block_id;
298 for(std::size_t fd=0;fd<scatterFields_.size();++fd) {
300 std::string fieldName = fieldMap_->find(scatterFields_[fd].fieldTag().name())->second;
301 fieldIds_[fd] = globalIndexer_->getFieldNum(fieldName);
303 int fieldNum = fieldIds_[fd];
304 const std::vector<int> &
offsets = globalIndexer_->getGIDFieldOffsets(blockId,fieldNum);
305 scratch_offsets_[fd] = PHX::View<int*>(
"offsets",offsets.size());
309 my_derivative_size_ = globalIndexer_->getElementBlockGIDCount(blockId);
311 auto otherBlockId = workset_0.
other->block_id;
312 other_derivative_size_ = globalIndexer_->getElementBlockGIDCount(otherBlockId);
315 "lids", scatterFields_[0].extent(0), my_derivative_size_ + other_derivative_size_ );
317 "vals", scatterFields_[0].extent(0), my_derivative_size_ + other_derivative_size_ );
321 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
328 tpetraContainer_ = Teuchos::rcp_dynamic_cast<LOC>(d.gedc->getDataObject(globalDataKey_));
330 if(tpetraContainer_==Teuchos::null) {
333 tpetraContainer_ = Teuchos::rcp_dynamic_cast<LOC>(loc);
342 template <
typename ScalarT,
typename LO,
typename GO,
typename NodeT,
typename LocalMatrixT>
343 class ScatterResidual_Jacobian_Functor {
345 typedef typename PHX::Device execution_space;
358 KOKKOS_INLINE_FUNCTION
359 void operator()(
const unsigned int cell)
const
361 int numIds =
lids.extent(1);
364 for(std::size_t basis=0; basis <
offsets.extent(0); basis++) {
365 typename FieldType::array_type::reference_type scatterField =
field(cell,basis);
367 LO lid =
lids(cell,offset);
371 Kokkos::atomic_add(&
r_data(lid,0), scatterField.val());
374 for(
int sensIndex=0;sensIndex<numIds;++sensIndex)
375 vals(cell,sensIndex) = scatterField.fastAccessDx(sensIndex);
378 jac.sumIntoValues(lid, &
lids(cell,0), numIds, &
vals(cell,0),
true,
true);
383 template <
typename ScalarT,
typename LO,
typename GO,
typename NodeT>
384 class ScatterResidual_Residual_Functor {
386 typedef typename PHX::Device execution_space;
391 PHX::View<const LO**>
lids;
396 KOKKOS_INLINE_FUNCTION
397 void operator()(
const unsigned int cell)
const
401 for(std::size_t basis=0; basis <
offsets.extent(0); basis++) {
403 LO lid =
lids(cell,offset);
404 Kokkos::atomic_add(&
r_data(lid,0),
field(cell,basis));
414 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
421 std::string blockId = this->wda(workset).block_id;
425 globalIndexer_->getElementLIDs(this->wda(workset).cell_local_ids_k,scratch_lids_);
427 ScatterResidual_Residual_Functor<ScalarT,LO,GO,NodeT> functor;
428 functor.r_data = r->getLocalViewDevice(Tpetra::Access::ReadWrite);
429 functor.lids = scratch_lids_;
432 for(std::size_t fieldIndex = 0; fieldIndex < scatterFields_.size(); fieldIndex++) {
433 functor.offsets = scratch_offsets_[fieldIndex];
434 functor.field = scatterFields_[fieldIndex];
436 Kokkos::parallel_for(workset.num_cells,functor);
441 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
447 typedef typename LOC::CrsMatrixType::local_matrix_device_type LocalMatrixT;
450 std::string blockId = this->wda(workset).block_id;
459 auto my_scratch_lids = Kokkos::subview(scratch_lids_,Kokkos::ALL,std::make_pair(0,my_derivative_size_));
460 globalIndexer_->getElementLIDs(this->wda(workset).cell_local_ids_k,my_scratch_lids);
461 auto other_scratch_lids = Kokkos::subview(scratch_lids_,Kokkos::ALL,std::make_pair(my_derivative_size_,my_derivative_size_ + other_derivative_size_));
462 globalIndexer_->getElementLIDs(workset.other->cell_local_ids_k,other_scratch_lids);
465 globalIndexer_->getElementLIDs(this->wda(workset).cell_local_ids_k,scratch_lids_);
468 ScatterResidual_Jacobian_Functor<ScalarT,LO,GO,NodeT,LocalMatrixT> functor;
469 functor.fillResidual = (r!=Teuchos::null);
470 if(functor.fillResidual)
471 functor.r_data = r->getLocalViewDevice(Tpetra::Access::ReadWrite);
472 functor.jac = Jac->getLocalMatrixDevice();
473 functor.lids = scratch_lids_;
474 functor.vals = scratch_vals_;
477 for(std::size_t fieldIndex = 0; fieldIndex < scatterFields_.size(); fieldIndex++) {
478 functor.offsets = scratch_offsets_[fieldIndex];
479 functor.field = scatterFields_[fieldIndex];
481 Kokkos::parallel_for(workset.num_cells,functor);
panzer::Traits::Tangent::ScalarT ScalarT
T & get(const std::string &name, T def_value)
bool nonnull(const std::shared_ptr< T > &p)
FieldType
The type of discretization to use for a field pattern.
PHX::View< const int * > offsets
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Teuchos::RCP< WorksetDetails > other
Kokkos::View< typename Sacado::ScalarType< ScalarT >::type **, Kokkos::LayoutRight, PHX::Device > vals
Kokkos::View< double **, Kokkos::LayoutLeft, PHX::Device > r_data
std::string block_id
DEPRECATED - use: getElementBlock()
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 LO **, Kokkos::LayoutRight, PHX::Device > lids