38 const Teuchos::ParameterList& p)
39 : globalIndexer_(indexer)
40 , globalDataKey_(
"Residual Scatter Container")
42 std::string scatterName = p.get<std::string>(
"Scatter Name");
44 Teuchos::rcp(
new PHX::Tag<ScalarT>(scatterName,Teuchos::rcp(
new PHX::MDALayout<Dummy>(0))));
47 const std::vector<std::string>& names =
48 *(p.get< Teuchos::RCP< std::vector<std::string> > >(
"Dependent Names"));
51 fieldMap_ = p.get< Teuchos::RCP< std::map<std::string,std::string> > >(
"Dependent Map");
54 scatterIC_ = p.isParameter(
"Scatter Initial Condition") ? p.get<
bool>(
"Scatter Initial Condition") :
false;
56 Teuchos::RCP<PHX::DataLayout> dl = (!scatterIC_) ?
57 p.get< Teuchos::RCP<panzer::PureBasis> >(
"Basis")->functional :
58 p.get< Teuchos::RCP<const panzer::PureBasis> >(
"Basis")->functional ;
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) {
69 scatterFields_[eq] = PHX::MDField<const ScalarT,Cell,NODE>(names[eq],dl);
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) {
79 applyBC_[eq] = PHX::MDField<const bool,Cell,NODE>(std::string(
"APPLY_BC_")+fieldMap_->find(names[eq])->second,dl);
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");
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());
116 Kokkos::deep_copy(scratch_offsets_[fd], Kokkos::View<const int*, Kokkos::HostSpace, Kokkos::MemoryUnmanaged>(
offsets.data(),
offsets.size()));
118 scratch_basisIds_[fd] = PHX::View<int*>(
"basisIds",basisIdMap.size());
119 Kokkos::deep_copy(scratch_basisIds_[fd], Kokkos::View<const int*, Kokkos::HostSpace, Kokkos::MemoryUnmanaged>(basisIdMap.data(), basisIdMap.size()));
122 const std::vector<int> &
offsets = globalIndexer_->getGIDFieldOffsets(blockId,fieldIds_[fd]);
123 scratch_offsets_[fd] = PHX::View<int*>(
"offsets",
offsets.size());
124 Kokkos::deep_copy(scratch_offsets_[fd], Kokkos::View<const int*, Kokkos::HostSpace, Kokkos::MemoryUnmanaged>(
offsets.data(),
offsets.size()));
128 scratch_lids_ = PHX::View<LO**>(
"lids",scatterFields_[0].extent(0),
129 globalIndexer_->getElementBlockGIDCount(blockId));
243 std::vector<GO> GIDs;
244 std::vector<LO> LIDs;
247 std::string blockId = this->wda(workset).block_id;
249 globalIndexer_->getElementLIDs(this->wda(workset).cell_local_ids_k,scratch_lids_);
251 Teuchos::RCP<typename LOC::MultiVectorType> r = (!scatterIC_) ?
252 tpetraContainer_->get_f_mv() :
253 tpetraContainer_->get_x_mv();
256 ScatterDirichletResidualIC_Residual_Functor<ScalarT,LO,GO,NodeT> functor;
257 functor.r_data = r->getLocalViewDevice(Tpetra::Access::ReadWrite);
258 functor.lids = scratch_lids_;
259 if (dirichletCounter_ != Teuchos::null)
260 functor.dirichlet_counter = dirichletCounter_->getLocalViewDevice(Tpetra::Access::ReadWrite);
263 for(std::size_t fieldIndex = 0; fieldIndex < scatterFields_.size(); fieldIndex++) {
264 functor.offsets = scratch_offsets_[fieldIndex];
265 functor.field = scatterFields_[fieldIndex];
267 Kokkos::parallel_for(workset.num_cells,functor);
270 ScatterDirichletResidual_Residual_Functor<ScalarT,LO,GO,NodeT> functor;
271 functor.r_data = r->getLocalViewDevice(Tpetra::Access::ReadWrite);
272 functor.lids = scratch_lids_;
273 if (dirichletCounter_ != Teuchos::null)
274 functor.dirichlet_counter = dirichletCounter_->getLocalViewDevice(Tpetra::Access::ReadWrite);
277 for(std::size_t fieldIndex = 0; fieldIndex < scatterFields_.size(); fieldIndex++) {
278 functor.offsets = scratch_offsets_[fieldIndex];
279 functor.field = scatterFields_[fieldIndex];
280 if (checkApplyBC_) functor.applyBC = applyBC_[fieldIndex];
281 functor.checkApplyBC = checkApplyBC_;
282 functor.basisIds = scratch_basisIds_[fieldIndex];
284 Kokkos::parallel_for(workset.num_cells,functor);
298 const Teuchos::ParameterList& p)
299 : globalIndexer_(indexer)
300 , globalDataKey_(
"Residual Scatter Container")
302 std::string scatterName = p.get<std::string>(
"Scatter Name");
304 Teuchos::rcp(
new PHX::Tag<ScalarT>(scatterName,Teuchos::rcp(
new PHX::MDALayout<Dummy>(0))));
307 const std::vector<std::string>& names =
308 *(p.get< Teuchos::RCP< std::vector<std::string> > >(
"Dependent Names"));
311 fieldMap_ = p.get< Teuchos::RCP< std::map<std::string,std::string> > >(
"Dependent Map");
314 scatterIC_ = p.isParameter(
"Scatter Initial Condition") ? p.get<
bool>(
"Scatter Initial Condition") :
false;
316 Teuchos::RCP<PHX::DataLayout> dl = (!scatterIC_) ?
317 p.get< Teuchos::RCP<panzer::PureBasis> >(
"Basis")->functional :
318 p.get< Teuchos::RCP<const panzer::PureBasis> >(
"Basis")->functional ;
320 side_subcell_dim_ = p.get<
int>(
"Side Subcell Dimension");
321 local_side_id_ = p.get<
int>(
"Local Side ID");
322 scratch_basisIds_.resize(names.size());
326 scatterFields_.resize(names.size());
327 scratch_offsets_.resize(names.size());
328 for (std::size_t eq = 0; eq < names.size(); ++eq) {
329 scatterFields_[eq] = PHX::MDField<const ScalarT,Cell,NODE>(names[eq],dl);
332 this->addDependentField(scatterFields_[eq]);
335 checkApplyBC_ = p.isParameter(
"Check Apply BC") ? p.get<
bool>(
"Check Apply BC") :
false;
337 applyBC_.resize(names.size());
338 for (std::size_t eq = 0; eq < names.size(); ++eq) {
339 applyBC_[eq] = PHX::MDField<const bool,Cell,NODE>(std::string(
"APPLY_BC_")+fieldMap_->find(names[eq])->second,dl);
340 this->addDependentField(applyBC_[eq]);
345 this->addEvaluatedField(*scatterHolder_);
347 if (p.isType<std::string>(
"Global Data Key"))
348 globalDataKey_ = p.get<std::string>(
"Global Data Key");
350 this->setName(scatterName+
" Scatter Tangent");
359 fieldIds_.resize(scatterFields_.size());
360 const Workset & workset_0 = (*d.worksets_)[0];
361 std::string blockId = this->wda(workset_0).
block_id;
364 for(std::size_t fd=0;fd<scatterFields_.size();++fd) {
366 std::string fieldName = fieldMap_->find(scatterFields_[fd].fieldTag().name())->second;
367 fieldIds_[fd] = globalIndexer_->getFieldNum(fieldName);
370 const std::pair<std::vector<int>,std::vector<int> > & indicePair
371 = globalIndexer_->getGIDFieldOffsets_closure(blockId,fieldIds_[fd], side_subcell_dim_, local_side_id_);
372 const std::vector<int> &
offsets = indicePair.first;
373 const std::vector<int> & basisIdMap = indicePair.second;
375 scratch_offsets_[fd] = PHX::View<int*>(
"offsets",
offsets.size());
376 Kokkos::deep_copy(scratch_offsets_[fd], Kokkos::View<const int*, Kokkos::HostSpace, Kokkos::MemoryUnmanaged>(
offsets.data(),
offsets.size()));
378 scratch_basisIds_[fd] = PHX::View<int*>(
"basisIds",basisIdMap.size());
379 Kokkos::deep_copy(scratch_basisIds_[fd], Kokkos::View<const int*, Kokkos::HostSpace, Kokkos::MemoryUnmanaged>(basisIdMap.data(), basisIdMap.size()));
382 const std::vector<int> &
offsets = globalIndexer_->getGIDFieldOffsets(blockId,fieldIds_[fd]);
383 scratch_offsets_[fd] = PHX::View<int*>(
"offsets",
offsets.size());
384 Kokkos::deep_copy(scratch_offsets_[fd], Kokkos::View<const int*, Kokkos::HostSpace, Kokkos::MemoryUnmanaged>(
offsets.data(),
offsets.size()));
388 scratch_lids_ = PHX::View<LO**>(
"lids",scatterFields_[0].extent(0),
389 globalIndexer_->getElementBlockGIDCount(blockId));
399 tpetraContainer_ = Teuchos::rcp_dynamic_cast<LOC>(d.gedc->getDataObject(globalDataKey_));
401 if(tpetraContainer_==Teuchos::null) {
403 Teuchos::RCP<LinearObjContainer> loc = Teuchos::rcp_dynamic_cast<LOCPair_GlobalEvaluationData>(d.gedc->getDataObject(globalDataKey_),
true)->getGhostedLOC();
404 tpetraContainer_ = Teuchos::rcp_dynamic_cast<LOC>(loc);
406 dirichletCounter_ = Teuchos::null;
410 Teuchos::RCP<LOC> tpetraContainer
411 = Teuchos::rcp_dynamic_cast<LOC>(d.gedc->getDataObject(
"Dirichlet Counter"),
true);
413 dirichletCounter_ = tpetraContainer->get_f_mv();
414 TEUCHOS_ASSERT(!Teuchos::is_null(dirichletCounter_));
418 using Teuchos::rcp_dynamic_cast;
421 std::vector<std::string> activeParameters =
422 rcp_dynamic_cast<ParameterList_GlobalEvaluationData>(d.gedc->getDataObject(
"PARAMETER_NAMES"))->getActiveParameters();
426 dfdpFieldsVoV_.initialize(
"ScatterResidual_Tpetra<Tangent>::dfdpFieldsVoV_",activeParameters.size());
428 dfdpVectors_.resize(activeParameters.size());
429 for(std::size_t i=0;i<activeParameters.size();i++)
430 dfdpVectors_[i] = rcp_dynamic_cast<LOC>(d.gedc->getDataObject(activeParameters[i]),
true)->get_f_mv();
534 std::vector<GO> GIDs;
535 std::vector<LO> LIDs;
538 std::string blockId = this->wda(workset).block_id;
540 globalIndexer_->getElementLIDs(this->wda(workset).cell_local_ids_k,scratch_lids_);
542 Teuchos::RCP<typename LOC::MultiVectorType> r = (!scatterIC_) ?
543 tpetraContainer_->get_f_mv() :
544 tpetraContainer_->get_x_mv();
548 for(std::size_t i=0;i<dfdpVectors_.size();i++)
549 dfdpFieldsVoV_.addView(dfdpVectors_[i]->getLocalViewDevice(Tpetra::Access::ReadWrite),i);
550 dfdpFieldsVoV_.syncHostToDevice();
553 ScatterDirichletResidualIC_Tangent_Functor<ScalarT,LO,GO,NodeT> functor;
554 functor.r_data = r->getLocalViewDevice(Tpetra::Access::ReadWrite);
555 functor.lids = scratch_lids_;
556 if (dirichletCounter_ != Teuchos::null)
557 functor.dirichlet_counter = dirichletCounter_->getLocalViewDevice(Tpetra::Access::ReadWrite);
558 functor.dfdp_fields = dfdpFieldsVoV_.getViewDevice();
561 for(std::size_t fieldIndex = 0; fieldIndex < scatterFields_.size(); fieldIndex++) {
562 functor.offsets = scratch_offsets_[fieldIndex];
563 functor.field = scatterFields_[fieldIndex];
564 functor.num_params = Sacado::dimension_scalar(scatterFields_[fieldIndex].get_view())-1;
566 Kokkos::parallel_for(workset.num_cells,functor);
569 ScatterDirichletResidual_Tangent_Functor<ScalarT,LO,GO,NodeT> functor;
570 functor.r_data = r->getLocalViewDevice(Tpetra::Access::ReadWrite);
571 functor.lids = scratch_lids_;
572 if (dirichletCounter_ != Teuchos::null)
573 functor.dirichlet_counter = dirichletCounter_->getLocalViewDevice(Tpetra::Access::ReadWrite);
574 functor.dfdp_fields = dfdpFieldsVoV_.getViewDevice();
577 for(std::size_t fieldIndex = 0; fieldIndex < scatterFields_.size(); fieldIndex++) {
578 functor.offsets = scratch_offsets_[fieldIndex];
579 functor.field = scatterFields_[fieldIndex];
580 if (checkApplyBC_) functor.applyBC = applyBC_[fieldIndex];
581 functor.checkApplyBC = checkApplyBC_;
582 functor.basisIds = scratch_basisIds_[fieldIndex];
583 functor.num_params = Sacado::dimension_scalar(scatterFields_[fieldIndex].get_view())-1;
585 Kokkos::parallel_for(workset.num_cells,functor);
592 for(std::size_t i=0;i<dfdpVectors_.size();i++)
593 dfdpFieldsVoV_.addView(Kokkos::View<RealT**,Kokkos::LayoutLeft,PHX::Device>(),i);
603 const Teuchos::ParameterList& p)
604 : globalIndexer_(indexer)
605 , globalDataKey_(
"Residual Scatter Container")
607 std::string scatterName = p.get<std::string>(
"Scatter Name");
609 Teuchos::rcp(
new PHX::Tag<ScalarT>(scatterName,Teuchos::rcp(
new PHX::MDALayout<Dummy>(0))));
612 const std::vector<std::string>& names =
613 *(p.get< Teuchos::RCP< std::vector<std::string> > >(
"Dependent Names"));
616 fieldMap_ = p.get< Teuchos::RCP< std::map<std::string,std::string> > >(
"Dependent Map");
618 Teuchos::RCP<PHX::DataLayout> dl =
619 p.get< Teuchos::RCP<panzer::PureBasis> >(
"Basis")->functional;
621 side_subcell_dim_ = p.get<
int>(
"Side Subcell Dimension");
622 local_side_id_ = p.get<
int>(
"Local Side ID");
625 scatterFields_.resize(names.size());
626 for (std::size_t eq = 0; eq < names.size(); ++eq) {
627 scatterFields_[eq] = PHX::MDField<const ScalarT,Cell,NODE>(names[eq],dl);
630 this->addDependentField(scatterFields_[eq]);
633 checkApplyBC_ = p.get<
bool>(
"Check Apply BC");
635 applyBC_.resize(names.size());
636 for (std::size_t eq = 0; eq < names.size(); ++eq) {
637 applyBC_[eq] = PHX::MDField<const bool,Cell,NODE>(std::string(
"APPLY_BC_")+fieldMap_->find(names[eq])->second,dl);
638 this->addDependentField(applyBC_[eq]);
643 this->addEvaluatedField(*scatterHolder_);
645 if (p.isType<std::string>(
"Global Data Key"))
646 globalDataKey_ = p.get<std::string>(
"Global Data Key");
648 this->setName(scatterName+
" Scatter Residual (Jacobian)");
700 std::vector<GO> GIDs;
703 std::string blockId = this->wda(workset).block_id;
704 const std::vector<std::size_t> & localCellIds = this->wda(workset).cell_local_ids;
706 Teuchos::RCP<typename LOC::MultiVectorType> r = tpetraContainer_->get_f_mv();
707 Teuchos::RCP<typename LOC::CrsMatrixType> Jac = tpetraContainer_->get_A();
709 using HostView =
typename LOC::MultiVectorType::host_view_type;
710 const bool haveResidual = Teuchos::nonnull(r);
711 const bool haveDirichletCounter = Teuchos::nonnull(dirichletCounter_);
715 r_view = r->getLocalViewHost(Tpetra::Access::ReadWrite);
717 if (haveDirichletCounter)
718 dc_view = dirichletCounter_->getLocalViewHost(Tpetra::Access::ReadWrite);
723 if (Jac != Teuchos::null) {
724 const std::size_t maxRowEntries = Jac->getLocalMaxNumRowEntries();
725 if (rowIndices_.extent(0) < maxRowEntries) {
726 rowIndices_ =
typename LOC::CrsMatrixType::nonconst_local_inds_host_view_type(
"indices", maxRowEntries);
727 rowValues_ =
typename LOC::CrsMatrixType::nonconst_values_host_view_type(
"values", maxRowEntries);
737 auto LIDs = globalIndexer_->getLIDs();
740 if constexpr (lidsAreHostResident_) {
742 lids_h_ = Kokkos::create_mirror_view(Kokkos::HostSpace(),LIDs);
745 if (lids_h_.extent(0) != LIDs.extent(0) || lids_h_.extent(1) != LIDs.extent(1))
746 lids_h_ = Kokkos::create_mirror_view(Kokkos::HostSpace(),LIDs);
747 Kokkos::deep_copy(lids_h_, LIDs);
749 auto& LIDs_h = lids_h_;
751 if (scatterFields_h_.size() != scatterFields_.size())
752 scatterFields_h_.resize(scatterFields_.size());
754 for(std::size_t fieldIndex = 0; fieldIndex < scatterFields_.size(); fieldIndex++) {
755 int fieldNum = fieldIds_[fieldIndex];
756 const auto scatterFieldsDevice = scatterFields_[fieldIndex].get_static_view();
757 if (scatterFields_h_[fieldIndex].extent(0) != scatterFieldsDevice.extent(0) ||
758 scatterFields_h_[fieldIndex].extent(1) != scatterFieldsDevice.extent(1))
759 scatterFields_h_[fieldIndex] = Kokkos::create_mirror_view(scatterFieldsDevice);
760 auto& scatterFields_h = scatterFields_h_[fieldIndex];
761 Kokkos::deep_copy(scatterFields_h, scatterFieldsDevice);
762 for(std::size_t worksetCellIndex=0;worksetCellIndex<localCellIds.size();++worksetCellIndex) {
763 std::size_t cellLocalId = localCellIds[worksetCellIndex];
765 globalIndexer_->getElementGIDs(cellLocalId,GIDs);
768 const std::pair<std::vector<int>,std::vector<int> > & indicePair
769 = globalIndexer_->getGIDFieldOffsets_closure(blockId,fieldNum, side_subcell_dim_, local_side_id_);
770 const std::vector<int> & elmtOffset = indicePair.first;
771 const std::vector<int> & basisIdMap = indicePair.second;
774 for(std::size_t basis=0;basis<elmtOffset.size();basis++) {
775 int offset = elmtOffset[basis];
776 int lid = LIDs_h(cellLocalId, offset);
780 int basisId = basisIdMap[basis];
783 if (!applyBC_[fieldIndex](worksetCellIndex,basisId))
788 std::size_t numEntries = 0;
790 Jac->getLocalRowCopy(lid,rowIndices_,rowValues_,numEntries);
792 for(std::size_t i=0;i<numEntries;i++)
796 const auto rowRange = std::make_pair(std::size_t(0),numEntries);
797 Jac->replaceLocalValues(lid,
798 Kokkos::subview(rowIndices_,rowRange),
799 Kokkos::subview(rowValues_,rowRange));
802 GO gid = GIDs[offset];
803 const ScalarT scatterField = scatterFields_h(worksetCellIndex,basisId);
806 r_view(lid,0) = scatterField.val();
807 if (haveDirichletCounter)
808 dc_view(lid,0) = 1.0;
811 jacRow_.resize(scatterField.size());
813 for(
int sensIndex=0;sensIndex<scatterField.size();++sensIndex)
814 jacRow_[sensIndex] = scatterField.fastAccessDx(sensIndex);
815 TEUCHOS_ASSERT(jacRow_.size()==GIDs.size());
817 Jac->replaceGlobalValues(gid, GIDs, jacRow_);