11#ifndef PANZER_SCATTER_RESIDUAL_TPETRA_IMPL_HPP
12#define PANZER_SCATTER_RESIDUAL_TPETRA_IMPL_HPP
14#include "Teuchos_RCP.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"
38template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
41 const Teuchos::ParameterList& p)
45 std::string scatterName = p.get<std::string>(
"Scatter Name");
47 Teuchos::rcp(
new PHX::Tag<ScalarT>(scatterName,Teuchos::rcp(
new PHX::MDALayout<Dummy>(0))));
50 const std::vector<std::string>& names =
51 *(p.get< Teuchos::RCP< std::vector<std::string> > >(
"Dependent Names"));
54 fieldMap_ = p.get< Teuchos::RCP< std::map<std::string,std::string> > >(
"Dependent Map");
56 Teuchos::RCP<PHX::DataLayout> dl =
57 p.get< Teuchos::RCP<const panzer::PureBasis> >(
"Basis")->functional;
62 for (std::size_t eq = 0; eq < names.size(); ++eq) {
63 scatterFields_[eq] = PHX::MDField<const ScalarT,Cell,NODE>(names[eq],dl);
72 if (p.isType<std::string>(
"Global Data Key"))
75 this->setName(scatterName+
" Scatter Residual");
79template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
85 const Workset & workset_0 = (*d.worksets_)[0];
86 std::string blockId = this->
wda(workset_0).block_id;
97 Kokkos::deep_copy(
scratch_offsets_[fd], Kokkos::View<const int*, Kokkos::HostSpace, Kokkos::MemoryUnmanaged>(offsets.data(), offsets.size()));
105template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
116 Teuchos::RCP<LinearObjContainer> loc = Teuchos::rcp_dynamic_cast<LOCPair_GlobalEvaluationData>(d.gedc->getDataObject(
globalDataKey_),
true)->getGhostedLOC();
126template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
129 const Teuchos::ParameterList& p)
134 std::string scatterName = p.get<std::string>(
"Scatter Name");
136 Teuchos::rcp(
new PHX::Tag<ScalarT>(scatterName,Teuchos::rcp(
new PHX::MDALayout<Dummy>(0))));
139 const std::vector<std::string>& names =
140 *(p.get< Teuchos::RCP< std::vector<std::string> > >(
"Dependent Names"));
143 fieldMap_ = p.get< Teuchos::RCP< std::map<std::string,std::string> > >(
"Dependent Map");
145 Teuchos::RCP<PHX::DataLayout> dl =
146 p.get< Teuchos::RCP<const panzer::PureBasis> >(
"Basis")->functional;
151 for (std::size_t eq = 0; eq < names.size(); ++eq) {
152 scatterFields_[eq] = PHX::MDField<const ScalarT,Cell,NODE>(names[eq],dl);
161 if (p.isType<std::string>(
"Global Data Key"))
164 this->setName(scatterName+
" Scatter Tangent");
168template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
174 const Workset & workset_0 = (*d.worksets_)[0];
175 std::string blockId = this->
wda(workset_0).block_id;
185 Kokkos::deep_copy(
scratch_offsets_[fd], Kokkos::View<const int*, Kokkos::HostSpace, Kokkos::MemoryUnmanaged>(offsets.data(), offsets.size()));
192template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
197 using Teuchos::rcp_dynamic_cast;
202 std::vector<std::string> activeParameters =
203 rcp_dynamic_cast<ParameterList_GlobalEvaluationData>(d.gedc->getDataObject(
"PARAMETER_NAMES"))->getActiveParameters();
207 dfdpFieldsVoV_.initialize(
"ScatterResidual_Tpetra<Tangent>::dfdpFieldsVoV_",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();
218 Teuchos::RCP<LinearObjContainer> loc = Teuchos::rcp_dynamic_cast<LOCPair_GlobalEvaluationData>(d.gedc->getDataObject(
globalDataKey_),
true)->getGhostedLOC();
227template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
230 const Teuchos::ParameterList& p)
231 : globalIndexer_(indexer)
232 , globalDataKey_(
"Residual Scatter Container")
233 , my_derivative_size_(0)
234 , other_derivative_size_(0)
236 std::string scatterName = p.get<std::string>(
"Scatter Name");
238 Teuchos::rcp(
new PHX::Tag<ScalarT>(scatterName,Teuchos::rcp(
new PHX::MDALayout<Dummy>(0))));
241 const std::vector<std::string>& names =
242 *(p.get< Teuchos::RCP< std::vector<std::string> > >(
"Dependent Names"));
245 fieldMap_ = p.get< Teuchos::RCP< std::map<std::string,std::string> > >(
"Dependent Map");
247 Teuchos::RCP<PHX::DataLayout> dl =
248 p.get< Teuchos::RCP<const panzer::PureBasis> >(
"Basis")->functional;
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);
257 this->addDependentField(scatterFields_[eq]);
261 this->addEvaluatedField(*scatterHolder_);
263 if (p.isType<std::string>(
"Global Data Key"))
264 globalDataKey_ = p.get<std::string>(
"Global Data Key");
266 this->setName(scatterName+
" Scatter Residual (Jacobian)");
270template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
277 const Workset & workset_0 = (*d.worksets_)[0];
278 std::string blockId = this->
wda(workset_0).block_id;
287 const std::vector<int> & offsets =
globalIndexer_->getGIDFieldOffsets(blockId,fieldNum);
289 Kokkos::deep_copy(
scratch_offsets_[fd], Kokkos::View<const int*, Kokkos::HostSpace, Kokkos::MemoryUnmanaged>(offsets.data(), offsets.size()));
293 if (Teuchos::nonnull(workset_0.
other)) {
294 auto otherBlockId = workset_0.
other->block_id;
297 scratch_lids_ = Kokkos::View<LO**, Kokkos::LayoutRight, PHX::Device>(
299 scratch_vals_ = Kokkos::View<typename Sacado::ScalarType<ScalarT>::type**, Kokkos::LayoutRight, PHX::Device>(
304template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
315 Teuchos::RCP<LinearObjContainer> loc = Teuchos::rcp_dynamic_cast<LOCPair_GlobalEvaluationData>(d.gedc->getDataObject(
globalDataKey_),
true)->getGhostedLOC();
325template <
typename ScalarT,
typename LO,
typename GO,
typename NodeT,
typename LocalMatrixT>
326class ScatterResidual_Jacobian_Functor {
328 typedef typename PHX::ExecutionSpace execution_space;
329 typedef PHX::MDField<const ScalarT,Cell,NODE>
FieldType;
332 Kokkos::View<double**, Kokkos::LayoutLeft,PHX::Device> r_data;
335 Kokkos::View<const LO**, Kokkos::LayoutRight, PHX::Device> lids;
336 Kokkos::View<typename Sacado::ScalarType<ScalarT>::type**, Kokkos::LayoutRight, PHX::Device> vals;
337 PHX::View<const int*> offsets;
341 KOKKOS_INLINE_FUNCTION
342 void operator()(
const unsigned int cell)
const
344 int numIds = lids.extent(1);
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);
354 Kokkos::atomic_add(&r_data(lid,0), scatterField.val());
357 for(
int sensIndex=0;sensIndex<numIds;++sensIndex)
358 vals(cell,sensIndex) = scatterField.fastAccessDx(sensIndex);
361 jac.sumIntoValues(lid, &lids(cell,0), numIds, &vals(cell,0),
true,
true);
366template <
typename ScalarT,
typename LO,
typename GO,
typename NodeT>
367class ScatterResidual_Residual_Functor {
369 typedef typename PHX::ExecutionSpace execution_space;
370 typedef PHX::MDField<const ScalarT,Cell,NODE> FieldType;
372 Kokkos::View<double**, Kokkos::LayoutLeft,PHX::Device> r_data;
374 PHX::View<const LO**> lids;
375 PHX::View<const int*> offsets;
378 KOKKOS_INLINE_FUNCTION
379 void operator()(
const unsigned int cell)
const
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));
392template <
typename ScalarT,
typename LO,
typename GO,
typename NodeT>
393class ScatterResidual_Tangent_Functor {
395 typedef typename PHX::ExecutionSpace execution_space;
396 typedef PHX::MDField<const ScalarT,Cell,NODE> FieldType;
399 Kokkos::View<double**, Kokkos::LayoutLeft,PHX::Device> r_data;
401 PHX::View<const LO**> lids;
402 PHX::View<const int*> offsets;
404 std::size_t num_params;
406 Kokkos::View<Kokkos::View<double**,Kokkos::LayoutLeft,PHX::Device>*> dfdp_fields;
408 KOKKOS_INLINE_FUNCTION
409 void operator()(
const unsigned int cell)
const
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);
420 Kokkos::atomic_add(&r_data(lid,0), scatterField.val());
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));
434template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
441 std::string blockId = this->
wda(workset).block_id;
443 Teuchos::RCP<typename LOC::MultiVectorType> r =
tpetraContainer_->get_f_mv();
447 ScatterResidual_Residual_Functor<ScalarT,LO,GO,NodeT> functor;
448 functor.r_data = r->getLocalViewDevice(Tpetra::Access::ReadWrite);
452 for(std::size_t fieldIndex = 0; fieldIndex <
scatterFields_.size(); fieldIndex++) {
456 Kokkos::parallel_for(workset.num_cells,functor);
461template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
467 typedef typename LOC::CrsMatrixType::local_matrix_device_type LocalMatrixT;
470 std::string blockId = this->
wda(workset).block_id;
472 Teuchos::RCP<typename LOC::MultiVectorType> r =
tpetraContainer_->get_f_mv();
478 if (Teuchos::nonnull(workset.other)) {
480 globalIndexer_->getElementLIDs(this->
wda(workset).cell_local_ids_k,my_scratch_lids);
482 globalIndexer_->getElementLIDs(workset.other->cell_local_ids_k,other_scratch_lids);
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();
497 for(std::size_t fieldIndex = 0; fieldIndex <
scatterFields_.size(); fieldIndex++) {
501 Kokkos::parallel_for(workset.num_cells,functor);
507template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
514 std::string blockId = this->
wda(workset).block_id;
516 Teuchos::RCP<typename LOC::MultiVectorType> r =
tpetraContainer_->get_f_mv();
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);
534 for(std::size_t fieldIndex = 0; fieldIndex <
scatterFields_.size(); fieldIndex++) {
537 functor.num_params = Sacado::dimension_scalar(
scatterFields_[fieldIndex].get_view())-1;
539 Kokkos::parallel_for(workset.num_cells,functor);
546 dfdpFieldsVoV_.addView(Kokkos::View<RealT**,Kokkos::LayoutLeft,PHX::Device>(),i);
WorksetDetailsAccessor wda
Teuchos::RCP< const panzer::GlobalIndexer > globalIndexer_
Teuchos::RCP< const TpetraLinearObjContainer< double, LO, GO, NodeT > > tpetraContainer_
std::string globalDataKey_
std::vector< PHX::View< int * > > scratch_offsets_
int other_derivative_size_
Kokkos::View< typename Sacado::ScalarType< ScalarT >::type **, Kokkos::LayoutRight, PHX::Device > scratch_vals_
Teuchos::RCP< const std::map< std::string, std::string > > fieldMap_
Kokkos::View< LO **, Kokkos::LayoutRight, PHX::Device > scratch_lids_
std::vector< PHX::MDField< const ScalarT, Cell, NODE > > scatterFields_
std::vector< int > fieldIds_
Teuchos::RCP< const std::map< std::string, std::string > > fieldMap_
Teuchos::RCP< const panzer::GlobalIndexer > globalIndexer_
std::string globalDataKey_
PHX::View< int ** > scratch_lids_
Teuchos::RCP< PHX::FieldTag > scatterHolder_
std::vector< PHX::MDField< const ScalarT, Cell, NODE > > scatterFields_
std::vector< PHX::View< int * > > scratch_offsets_
Teuchos::RCP< const TpetraLinearObjContainer< double, LO, GO, NodeT > > tpetraContainer_
std::vector< int > fieldIds_
Teuchos::RCP< PHX::FieldTag > scatterHolder_
std::vector< int > fieldIds_
Teuchos::RCP< const panzer::GlobalIndexer > globalIndexer_
std::vector< PHX::View< int * > > scratch_offsets_
Teuchos::RCP< const TpetraLinearObjContainer< double, LO, GO, NodeT > > tpetraContainer_
PHX::View< int ** > scratch_lids_
std::vector< PHX::MDField< const ScalarT, Cell, NODE > > scatterFields_
std::string globalDataKey_
Teuchos::RCP< const std::map< std::string, std::string > > fieldMap_
std::vector< Teuchos::RCP< typename TpetraLinearObjContainer< double, LO, GO, NodeT >::MultiVectorType > > dfdpVectors_
PHX::ViewOfViews< 1, Kokkos::View< RealT **, Kokkos::LayoutLeft, PHX::Device > > dfdpFieldsVoV_
Storage for the tangent data.
Pushes residual values into the residual vector for a Newton-based solve.
Tpetra-backed implementation of LinearObjContainer.
Teuchos::RCP< WorksetDetails > other
FieldType
The type of discretization to use for a field pattern.