11 #ifndef PANZER_SCATTER_DIRICHLET_RESIDUAL_TPETRA_IMPL_HPP
12 #define PANZER_SCATTER_DIRICHLET_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"
35 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
39 : globalIndexer_(indexer)
40 , globalDataKey_(
"Residual Scatter Container")
42 std::string scatterName = p.
get<std::string>(
"Scatter Name");
47 const std::vector<std::string>& names =
54 scatterIC_ = p.
isParameter(
"Scatter Initial Condition") ? p.
get<
bool>(
"Scatter Initial Condition") :
false;
60 side_subcell_dim_ = p.
get<
int>(
"Side Subcell Dimension");
61 local_side_id_ = p.
get<
int>(
"Local Side ID");
62 scratch_basisIds_.resize(names.size());
66 scatterFields_.resize(names.size());
67 scratch_offsets_.resize(names.size());
68 for (std::size_t eq = 0; eq < names.size(); ++eq) {
72 this->addDependentField(scatterFields_[eq]);
75 checkApplyBC_ = p.
isParameter(
"Check Apply BC") ? p.
get<
bool>(
"Check Apply BC") :
false;
77 applyBC_.resize(names.size());
78 for (std::size_t eq = 0; eq < names.size(); ++eq) {
80 this->addDependentField(applyBC_[eq]);
85 this->addEvaluatedField(*scatterHolder_);
87 if (p.
isType<std::string>(
"Global Data Key"))
88 globalDataKey_ = p.
get<std::string>(
"Global Data Key");
90 this->setName(scatterName+
" Scatter Residual");
94 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
99 fieldIds_.resize(scatterFields_.size());
100 const Workset & workset_0 = (*d.worksets_)[0];
101 std::string blockId = this->wda(workset_0).
block_id;
104 for(std::size_t fd=0;fd<scatterFields_.size();++fd) {
106 std::string fieldName = fieldMap_->find(scatterFields_[fd].fieldTag().name())->second;
107 fieldIds_[fd] = globalIndexer_->getFieldNum(fieldName);
110 const std::pair<std::vector<int>,std::vector<int> > & indicePair
111 = globalIndexer_->getGIDFieldOffsets_closure(blockId,fieldIds_[fd], side_subcell_dim_, local_side_id_);
112 const std::vector<int> &
offsets = indicePair.first;
113 const std::vector<int> & basisIdMap = indicePair.second;
115 scratch_offsets_[fd] = PHX::View<int*>(
"offsets",offsets.size());
118 scratch_basisIds_[fd] = PHX::View<int*>(
"basisIds",basisIdMap.size());
122 const std::vector<int> &
offsets = globalIndexer_->getGIDFieldOffsets(blockId,fieldIds_[fd]);
123 scratch_offsets_[fd] = PHX::View<int*>(
"offsets",offsets.size());
128 scratch_lids_ = PHX::View<LO**>(
"lids",scatterFields_[0].extent(0),
129 globalIndexer_->getElementBlockGIDCount(blockId));
133 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
138 tpetraContainer_ = Teuchos::rcp_dynamic_cast<
LOC>(d.gedc->getDataObject(globalDataKey_));
140 if(tpetraContainer_==Teuchos::null) {
143 tpetraContainer_ = Teuchos::rcp_dynamic_cast<
LOC>(loc);
145 dirichletCounter_ = Teuchos::null;
150 = Teuchos::rcp_dynamic_cast<
LOC>(d.gedc->getDataObject(
"Dirichlet Counter"),
true);
152 dirichletCounter_ = tpetraContainer->get_f();
161 template <
typename ScalarT,
typename LO,
typename GO,
typename NodeT>
162 class ScatterDirichletResidual_Residual_Functor {
164 typedef typename PHX::Device execution_space;
179 KOKKOS_INLINE_FUNCTION
180 void operator()(
const unsigned int cell)
const
184 for(std::size_t basis=0; basis <
offsets.extent(0); basis++) {
186 LO lid =
lids(cell,offset);
191 if(!
applyBC(cell,basisId))
continue;
202 template <
typename ScalarT,
typename LO,
typename GO,
typename NodeT>
203 class ScatterDirichletResidualIC_Residual_Functor {
205 typedef typename PHX::Device execution_space;
211 PHX::View<const LO**>
lids;
215 KOKKOS_INLINE_FUNCTION
216 void operator()(
const unsigned int cell)
const
220 for(std::size_t basis=0; basis <
offsets.extent(0); basis++) {
222 LO lid =
lids(cell,offset);
237 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
241 std::vector<GO> GIDs;
242 std::vector<LO> LIDs;
245 std::string blockId = this->wda(workset).block_id;
247 globalIndexer_->getElementLIDs(this->wda(workset).cell_local_ids_k,scratch_lids_);
250 tpetraContainer_->get_f() :
251 tpetraContainer_->get_x();
254 ScatterDirichletResidualIC_Residual_Functor<ScalarT,LO,GO,NodeT> functor;
255 functor.r_data = r->getLocalViewDevice(Tpetra::Access::ReadWrite);
256 functor.lids = scratch_lids_;
257 functor.dirichlet_counter = dirichletCounter_->getLocalViewDevice(Tpetra::Access::ReadWrite);
260 for(std::size_t fieldIndex = 0; fieldIndex < scatterFields_.size(); fieldIndex++) {
261 functor.offsets = scratch_offsets_[fieldIndex];
262 functor.field = scatterFields_[fieldIndex];
264 Kokkos::parallel_for(workset.num_cells,functor);
267 ScatterDirichletResidual_Residual_Functor<ScalarT,LO,GO,NodeT> functor;
268 functor.r_data = r->getLocalViewDevice(Tpetra::Access::ReadWrite);
269 functor.lids = scratch_lids_;
270 functor.dirichlet_counter = dirichletCounter_->getLocalViewDevice(Tpetra::Access::ReadWrite);
273 for(std::size_t fieldIndex = 0; fieldIndex < scatterFields_.size(); fieldIndex++) {
274 functor.offsets = scratch_offsets_[fieldIndex];
275 functor.field = scatterFields_[fieldIndex];
276 if (checkApplyBC_) functor.applyBC = applyBC_[fieldIndex];
277 functor.checkApplyBC = checkApplyBC_;
278 functor.basisIds = scratch_basisIds_[fieldIndex];
280 Kokkos::parallel_for(workset.num_cells,functor);
291 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
295 : globalIndexer_(indexer)
296 , globalDataKey_(
"Residual Scatter Container")
298 std::string scatterName = p.
get<std::string>(
"Scatter Name");
303 const std::vector<std::string>& names =
310 scatterIC_ = p.
isParameter(
"Scatter Initial Condition") ? p.
get<
bool>(
"Scatter Initial Condition") :
false;
316 side_subcell_dim_ = p.
get<
int>(
"Side Subcell Dimension");
317 local_side_id_ = p.
get<
int>(
"Local Side ID");
318 scratch_basisIds_.resize(names.size());
322 scatterFields_.resize(names.size());
323 scratch_offsets_.resize(names.size());
324 for (std::size_t eq = 0; eq < names.size(); ++eq) {
328 this->addDependentField(scatterFields_[eq]);
331 checkApplyBC_ = p.
isParameter(
"Check Apply BC") ? p.
get<
bool>(
"Check Apply BC") :
false;
333 applyBC_.resize(names.size());
334 for (std::size_t eq = 0; eq < names.size(); ++eq) {
336 this->addDependentField(applyBC_[eq]);
341 this->addEvaluatedField(*scatterHolder_);
343 if (p.
isType<std::string>(
"Global Data Key"))
344 globalDataKey_ = p.
get<std::string>(
"Global Data Key");
346 this->setName(scatterName+
" Scatter Tangent");
350 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
355 fieldIds_.resize(scatterFields_.size());
356 const Workset & workset_0 = (*d.worksets_)[0];
357 std::string blockId = this->wda(workset_0).
block_id;
360 for(std::size_t fd=0;fd<scatterFields_.size();++fd) {
362 std::string fieldName = fieldMap_->find(scatterFields_[fd].fieldTag().name())->second;
363 fieldIds_[fd] = globalIndexer_->getFieldNum(fieldName);
366 const std::pair<std::vector<int>,std::vector<int> > & indicePair
367 = globalIndexer_->getGIDFieldOffsets_closure(blockId,fieldIds_[fd], side_subcell_dim_, local_side_id_);
368 const std::vector<int> &
offsets = indicePair.first;
369 const std::vector<int> & basisIdMap = indicePair.second;
371 scratch_offsets_[fd] = PHX::View<int*>(
"offsets",offsets.size());
374 scratch_basisIds_[fd] = PHX::View<int*>(
"basisIds",basisIdMap.size());
378 const std::vector<int> &
offsets = globalIndexer_->getGIDFieldOffsets(blockId,fieldIds_[fd]);
379 scratch_offsets_[fd] = PHX::View<int*>(
"offsets",offsets.size());
384 scratch_lids_ = PHX::View<LO**>(
"lids",scatterFields_[0].extent(0),
385 globalIndexer_->getElementBlockGIDCount(blockId));
390 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
395 tpetraContainer_ = Teuchos::rcp_dynamic_cast<
LOC>(d.gedc->getDataObject(globalDataKey_));
397 if(tpetraContainer_==Teuchos::null) {
400 tpetraContainer_ = Teuchos::rcp_dynamic_cast<
LOC>(loc);
402 dirichletCounter_ = Teuchos::null;
407 = Teuchos::rcp_dynamic_cast<
LOC>(d.gedc->getDataObject(
"Dirichlet Counter"),
true);
409 dirichletCounter_ = tpetraContainer->get_f();
414 using Teuchos::rcp_dynamic_cast;
417 std::vector<std::string> activeParameters =
420 dfdpFieldsVoV_.initialize(
"ScatterResidual_Tpetra<Tangent>::dfdpFieldsVoV_",activeParameters.size());
422 for(std::size_t i=0;i<activeParameters.size();i++) {
424 rcp_dynamic_cast<
LOC>(d.gedc->getDataObject(activeParameters[i]),
true)->get_f();
425 auto dfdp_view = vec->getLocalViewDevice(Tpetra::Access::ReadWrite);
427 dfdpFieldsVoV_.addView(dfdp_view,i);
430 dfdpFieldsVoV_.syncHostToDevice();
438 template <
typename ScalarT,
typename LO,
typename GO,
typename NodeT>
439 class ScatterDirichletResidual_Tangent_Functor {
441 typedef typename PHX::Device execution_space;
451 PHX::View<const LO**>
lids;
454 ScalarFieldType
field;
459 KOKKOS_INLINE_FUNCTION
460 void operator()(
const unsigned int cell)
const
464 for(std::size_t basis=0; basis <
offsets.extent(0); basis++) {
466 LO lid =
lids(cell,offset);
471 if(!
applyBC(cell,basisId))
continue;
476 for(
int i_param=0; i_param<
num_params; i_param++)
486 template <
typename ScalarT,
typename LO,
typename GO,
typename NodeT>
487 class ScatterDirichletResidualIC_Tangent_Functor {
489 typedef typename PHX::Device execution_space;
498 PHX::View<const LO**>
lids;
502 KOKKOS_INLINE_FUNCTION
503 void operator()(
const unsigned int cell)
const
507 for(std::size_t basis=0; basis <
offsets.extent(0); basis++) {
509 LO lid =
lids(cell,offset);
515 for(
int i_param=0; i_param<
num_params; i_param++)
528 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
532 std::vector<GO> GIDs;
533 std::vector<LO> LIDs;
536 std::string blockId = this->wda(workset).block_id;
538 globalIndexer_->getElementLIDs(this->wda(workset).cell_local_ids_k,scratch_lids_);
541 tpetraContainer_->get_f() :
542 tpetraContainer_->get_x();
545 ScatterDirichletResidualIC_Tangent_Functor<ScalarT,LO,GO,NodeT> functor;
546 functor.r_data = r->getLocalViewDevice(Tpetra::Access::ReadWrite);
547 functor.lids = scratch_lids_;
548 functor.dirichlet_counter = dirichletCounter_->getLocalViewDevice(Tpetra::Access::ReadWrite);
549 functor.dfdp_fields = dfdpFieldsVoV_.getViewDevice();
552 for(std::size_t fieldIndex = 0; fieldIndex < scatterFields_.size(); fieldIndex++) {
553 functor.offsets = scratch_offsets_[fieldIndex];
554 functor.field = scatterFields_[fieldIndex];
555 functor.num_params = Kokkos::dimension_scalar(scatterFields_[fieldIndex].get_view())-1;
557 Kokkos::parallel_for(workset.num_cells,functor);
560 ScatterDirichletResidual_Tangent_Functor<ScalarT,LO,GO,NodeT> functor;
561 functor.r_data = r->getLocalViewDevice(Tpetra::Access::ReadWrite);
562 functor.lids = scratch_lids_;
563 functor.dirichlet_counter = dirichletCounter_->getLocalViewDevice(Tpetra::Access::ReadWrite);
564 functor.dfdp_fields = dfdpFieldsVoV_.getViewDevice();
567 for(std::size_t fieldIndex = 0; fieldIndex < scatterFields_.size(); fieldIndex++) {
568 functor.offsets = scratch_offsets_[fieldIndex];
569 functor.field = scatterFields_[fieldIndex];
570 if (checkApplyBC_) functor.applyBC = applyBC_[fieldIndex];
571 functor.checkApplyBC = checkApplyBC_;
572 functor.basisIds = scratch_basisIds_[fieldIndex];
573 functor.num_params = Kokkos::dimension_scalar(scatterFields_[fieldIndex].get_view())-1;
575 Kokkos::parallel_for(workset.num_cells,functor);
585 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
589 : globalIndexer_(indexer)
590 , globalDataKey_(
"Residual Scatter Container")
592 std::string scatterName = p.
get<std::string>(
"Scatter Name");
597 const std::vector<std::string>& names =
606 side_subcell_dim_ = p.
get<
int>(
"Side Subcell Dimension");
607 local_side_id_ = p.
get<
int>(
"Local Side ID");
610 scatterFields_.resize(names.size());
611 for (std::size_t eq = 0; eq < names.size(); ++eq) {
615 this->addDependentField(scatterFields_[eq]);
618 checkApplyBC_ = p.
get<
bool>(
"Check Apply BC");
620 applyBC_.resize(names.size());
621 for (std::size_t eq = 0; eq < names.size(); ++eq) {
623 this->addDependentField(applyBC_[eq]);
628 this->addEvaluatedField(*scatterHolder_);
630 if (p.
isType<std::string>(
"Global Data Key"))
631 globalDataKey_ = p.
get<std::string>(
"Global Data Key");
633 this->setName(scatterName+
" Scatter Residual (Jacobian)");
637 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
642 fieldIds_.resize(scatterFields_.size());
644 for(std::size_t fd=0;fd<scatterFields_.size();++fd) {
646 std::string fieldName = fieldMap_->find(scatterFields_[fd].fieldTag().name())->second;
647 fieldIds_[fd] = globalIndexer_->getFieldNum(fieldName);
651 num_nodes = scatterFields_[0].extent(1);
652 num_eq = scatterFields_.size();
656 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
661 tpetraContainer_ = Teuchos::rcp_dynamic_cast<
LOC>(d.gedc->getDataObject(globalDataKey_));
663 if(tpetraContainer_==Teuchos::null) {
666 tpetraContainer_ = Teuchos::rcp_dynamic_cast<
LOC>(loc);
668 dirichletCounter_ = Teuchos::null;
673 = Teuchos::rcp_dynamic_cast<
LOC>(d.gedc->getDataObject(
"Dirichlet Counter"),
true);
675 dirichletCounter_ = tpetraContainer->get_f();
681 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
685 std::vector<GO> GIDs;
688 std::string blockId = this->wda(workset).block_id;
689 const std::vector<std::size_t> & localCellIds = this->wda(workset).cell_local_ids;
703 auto LIDs = globalIndexer_->getLIDs();
704 auto LIDs_h = Kokkos::create_mirror_view(LIDs);
705 Kokkos::deep_copy(LIDs_h, LIDs);
707 for(std::size_t fieldIndex = 0; fieldIndex < scatterFields_.size(); fieldIndex++) {
708 int fieldNum = fieldIds_[fieldIndex];
709 auto scatterFields_h = Kokkos::create_mirror_view(scatterFields_[fieldIndex].get_static_view());
710 Kokkos::deep_copy(scatterFields_h, scatterFields_[fieldIndex].get_static_view());
711 for(std::size_t worksetCellIndex=0;worksetCellIndex<localCellIds.size();++worksetCellIndex) {
712 std::size_t cellLocalId = localCellIds[worksetCellIndex];
714 globalIndexer_->getElementGIDs(cellLocalId,GIDs);
717 const std::pair<std::vector<int>,std::vector<int> > & indicePair
718 = globalIndexer_->getGIDFieldOffsets_closure(blockId,fieldNum, side_subcell_dim_, local_side_id_);
719 const std::vector<int> & elmtOffset = indicePair.first;
720 const std::vector<int> & basisIdMap = indicePair.second;
723 for(std::size_t basis=0;basis<elmtOffset.size();basis++) {
724 int offset = elmtOffset[basis];
725 int lid = LIDs_h(cellLocalId, offset);
729 int basisId = basisIdMap[basis];
732 if (!applyBC_[fieldIndex](worksetCellIndex,basisId))
737 std::size_t sz = Jac->getNumEntriesInLocalRow(lid);
738 std::size_t numEntries = 0;
739 typename LOC::CrsMatrixType::nonconst_local_inds_host_view_type rowIndices(
"indices", sz);
740 typename LOC::CrsMatrixType::nonconst_values_host_view_type rowValues(
"values", sz);
743 Jac->getLocalRowCopy(lid,rowIndices,rowValues,numEntries);
745 for(std::size_t i=0;i<numEntries;i++)
748 Jac->replaceLocalValues(lid,rowIndices,rowValues);
751 GO gid = GIDs[offset];
752 const ScalarT scatterField = scatterFields_h(worksetCellIndex,basisId);
754 r_array[lid] = scatterField.val();
758 std::vector<double> jacRow(scatterField.size(),0.0);
760 for(
int sensIndex=0;sensIndex<scatterField.size();++sensIndex)
761 jacRow[sensIndex] = scatterField.fastAccessDx(sensIndex);
764 Jac->replaceGlobalValues(gid, GIDs, jacRow);
T & get(const std::string &name, T def_value)
bool is_null(const std::shared_ptr< T > &p)
FieldType
The type of discretization to use for a field pattern.
PHX::View< const int * > offsets
bool isParameter(const std::string &name) const
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
PHX::View< const int * > basisIds
Kokkos::View< double **, Kokkos::LayoutLeft, PHX::Device > r_data
PHX::View< const LO ** > lids
Kokkos::View< double **, Kokkos::LayoutLeft, PHX::Device > dirichlet_counter
Pushes residual values into the residual vector for a Newton-based solve.
std::string block_id
DEPRECATED - use: getElementBlock()
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
#define TEUCHOS_ASSERT(assertion_test)
Kokkos::View< Kokkos::View< double **, Kokkos::LayoutLeft, PHX::Device > * > dfdp_fields
panzer::Traits::Jacobian::ScalarT ScalarT