38 const Teuchos::RCP<const panzer::GlobalIndexer> & indexer,
39 const Teuchos::ParameterList& p)
40 : globalIndexer_(indexer)
41 , has_tangent_fields_(false)
43 typedef std::vector< std::vector<std::string> > vvstring;
48 const std::vector<std::string> & names = input.
getDofNames();
49 Teuchos::RCP<const panzer::PureBasis> basis = input.
getBasis();
57 gatherFields_.resize(names.size());
58 for (std::size_t fd = 0; fd < names.size(); ++fd) {
60 PHX::MDField<ScalarT,Cell,NODE>(names[fd],basis->functional);
61 this->addEvaluatedField(gatherFields_[fd]);
65 if (tangent_field_names.size()>0) {
66 TEUCHOS_ASSERT(gatherFields_.size() == tangent_field_names.size());
68 has_tangent_fields_ =
true;
69 tangentFields_.resize(gatherFields_.size());
70 for (std::size_t fd = 0; fd < gatherFields_.size(); ++fd) {
71 tangentFields_[fd].resize(tangent_field_names[fd].size());
72 for (std::size_t i=0; i<tangent_field_names[fd].size(); ++i) {
73 tangentFields_[fd][i] =
74 PHX::MDField<const ScalarT,Cell,NODE>(tangent_field_names[fd][i],basis->functional);
75 this->addDependentField(tangentFields_[fd][i]);
81 std::string firstName =
"<none>";
85 std::string n =
"GatherSolution (Tpetra): "+firstName+
" (Residual)";
95 TEUCHOS_ASSERT(gatherFields_.size() == indexerNames_.size());
97 fieldIds_.resize(gatherFields_.size());
99 const Workset & workset_0 = (*d.worksets_)[0];
100 std::string blockId = this->wda(workset_0).
block_id;
101 scratch_offsets_.resize(gatherFields_.size());
103 for (std::size_t fd = 0; fd < gatherFields_.size(); ++fd) {
104 const std::string& fieldName = indexerNames_[fd];
105 fieldIds_[fd] = globalIndexer_->getFieldNum(fieldName);
107 int fieldNum = fieldIds_[fd];
108 const std::vector<int> &
offsets = globalIndexer_->getGIDFieldOffsets(blockId,fieldNum);
109 scratch_offsets_[fd] = PHX::View<int*>(
"offsets",
offsets.size());
110 Kokkos::deep_copy(scratch_offsets_[fd], Kokkos::View<const int*, Kokkos::HostSpace, Kokkos::MemoryUnmanaged>(
offsets.data(),
offsets.size()));
113 scratch_lids_ = PHX::View<LO**>(
"lids",gatherFields_[0].extent(0),
114 globalIndexer_->getElementBlockGIDCount(blockId));
116 indexerNames_.clear();
128 std::string post = useTimeDerivativeSolutionVector_ ?
" - Xdot" :
" - X";
129 if(d.gedc->containsDataObject(globalDataKey_+post)) {
130 x_vector = Teuchos::rcp_dynamic_cast<RO_GED>(d.gedc->getDataObject(globalDataKey_+post),
true)->
getGhostedVector_Tpetra();
134 Teuchos::RCP<GlobalEvaluationData> ged = d.gedc->getDataObject(globalDataKey_);
137 tpetraContainer_ = Teuchos::rcp_dynamic_cast<LOC>(ged);
139 if(tpetraContainer_==Teuchos::null) {
140 Teuchos::RCP<LOCPair_GlobalEvaluationData> loc_pair = Teuchos::rcp_dynamic_cast<LOCPair_GlobalEvaluationData>(ged);
141 if(loc_pair!=Teuchos::null)
142 tpetraContainer_ = Teuchos::rcp_dynamic_cast<LOC>(loc_pair->getGhostedLOC());
145 if(tpetraContainer_!=Teuchos::null) {
146 x_vector = useTimeDerivativeSolutionVector_ ? tpetraContainer_->get_dxdt_mv()
147 : tpetraContainer_->get_x_mv();
153 x_vector = Teuchos::rcp_dynamic_cast<RO_GED>(ged,
true)->getGhostedVector_Tpetra();
162 std::string blockId = this->wda(workset).block_id;
163 const std::vector<std::size_t> & localCellIds = this->wda(workset).cell_local_ids;
165 auto x_data = x_vector->getLocalViewDevice(Tpetra::Access::ReadOnly);
167 globalIndexer_->getElementLIDs(this->wda(workset).cell_local_ids_k,scratch_lids_);
176 auto lids = scratch_lids_;
177 for (std::size_t fieldIndex=0; fieldIndex<gatherFields_.size();fieldIndex++) {
178 auto offsets = scratch_offsets_[fieldIndex];
179 auto gather_field = gatherFields_[fieldIndex].get_static_view();
181 Kokkos::parallel_for(localCellIds.size(), KOKKOS_LAMBDA (std::size_t worksetCellIndex) {
183 for(std::size_t basis=0;basis<
offsets.extent(0);basis++) {
185 LO lid =
lids(worksetCellIndex,offset);
188 gather_field(worksetCellIndex,basis) = x_data(lid,0);
201 const Teuchos::RCP<const panzer::GlobalIndexer> & indexer,
202 const Teuchos::ParameterList& p)
203 : globalIndexer_(indexer)
204 , has_tangent_fields_(false)
206 typedef std::vector< std::vector<std::string> > vvstring;
211 const std::vector<std::string> & names = input.
getDofNames();
212 Teuchos::RCP<const panzer::PureBasis> basis = input.
getBasis();
220 gatherFields_.resize(names.size());
221 for (std::size_t fd = 0; fd < names.size(); ++fd) {
223 PHX::MDField<ScalarT,Cell,NODE>(names[fd],basis->functional);
224 this->addEvaluatedField(gatherFields_[fd]);
227 this->addUnsharedField(gatherFields_[fd].fieldTag().clone());
231 if (tangent_field_names.size()>0) {
232 TEUCHOS_ASSERT(gatherFields_.size() == tangent_field_names.size());
234 has_tangent_fields_ =
true;
235 tangentFields_.resize(gatherFields_.size());
236 for (std::size_t fd = 0; fd < gatherFields_.size(); ++fd) {
237 tangentFields_[fd].resize(tangent_field_names[fd].size());
238 for (std::size_t i=0; i<tangent_field_names[fd].size(); ++i) {
239 tangentFields_[fd][i] =
240 PHX::MDField<const RealT,Cell,NODE>(tangent_field_names[fd][i],basis->functional);
241 this->addDependentField(tangentFields_[fd][i]);
247 std::string firstName =
"<none>";
249 firstName = names[0];
251 std::string n =
"GatherSolution (Tpetra): "+firstName+
" (Tangent)";
261 TEUCHOS_ASSERT(gatherFields_.size() == indexerNames_.size());
263 fieldIds_.resize(gatherFields_.size());
269 tangentInnerVectorSizes_ = PHX::View<size_t*>(
"tangentInnerVectorSizes_",gatherFields_.size());
270 auto tangentInnerVectorSizes_host = Kokkos::create_mirror_view(tangentInnerVectorSizes_);
271 size_t inner_vector_max_size = 0;
272 for (std::size_t fd = 0; fd < tangentFields_.size(); ++fd) {
273 inner_vector_max_size = std::max(inner_vector_max_size,tangentFields_[fd].size());
274 tangentInnerVectorSizes_host(fd) = tangentFields_[fd].size();
276 Kokkos::deep_copy(tangentInnerVectorSizes_,tangentInnerVectorSizes_host);
278 gatherFieldsVoV_.initialize(
"GatherSolution_Tpetra<Tangent>::gatherFieldsVoV_",gatherFields_.size());
279 tangentFieldsVoV_.initialize(
"GatherSolution_Tpetra<Tangent>::tangentFieldsVoV_",gatherFields_.size(),inner_vector_max_size);
281 for (std::size_t fd = 0; fd < gatherFields_.size(); ++fd) {
282 const std::string& fieldName = indexerNames_[fd];
283 fieldIds_[fd] = globalIndexer_->getFieldNum(fieldName);
284 gatherFieldsVoV_.addView(gatherFields_[fd].get_static_view(),fd);
286 if (has_tangent_fields_) {
287 for (std::size_t i=0; i<tangentFields_[fd].size(); ++i) {
288 tangentFieldsVoV_.addView(tangentFields_[fd][i].get_static_view(),fd,i);
293 gatherFieldsVoV_.syncHostToDevice();
294 tangentFieldsVoV_.syncHostToDevice();
296 indexerNames_.clear();
308 std::string post = useTimeDerivativeSolutionVector_ ?
" - Xdot" :
" - X";
309 if(d.gedc->containsDataObject(globalDataKey_+post)) {
310 x_vector = Teuchos::rcp_dynamic_cast<RO_GED>(d.gedc->getDataObject(globalDataKey_+post),
true)->
getGhostedVector_Tpetra();
314 Teuchos::RCP<GlobalEvaluationData> ged = d.gedc->getDataObject(globalDataKey_);
317 tpetraContainer_ = Teuchos::rcp_dynamic_cast<LOC>(ged);
319 if(tpetraContainer_==Teuchos::null) {
320 Teuchos::RCP<LOCPair_GlobalEvaluationData> loc_pair = Teuchos::rcp_dynamic_cast<LOCPair_GlobalEvaluationData>(ged);
321 if(loc_pair!=Teuchos::null)
322 tpetraContainer_ = Teuchos::rcp_dynamic_cast<LOC>(loc_pair->getGhostedLOC());
325 if(tpetraContainer_!=Teuchos::null) {
326 x_vector = useTimeDerivativeSolutionVector_ ? tpetraContainer_->get_dxdt_mv()
327 : tpetraContainer_->get_x_mv();
333 x_vector = Teuchos::rcp_dynamic_cast<RO_GED>(ged,
true)->getGhostedVector_Tpetra();
342 std::string blockId = this->wda(workset).block_id;
344 typedef typename PHX::MDField<ScalarT,Cell,NODE>::array_type::reference_type reference_type;
345 auto cellLocalIdsKokkos = this->wda(workset).getLocalCellIDs();
346 auto lids = globalIndexer_->getLIDs();
347 auto gidFieldOffsetsVoV = Teuchos::rcp_dynamic_cast<const panzer::DOFManager>(globalIndexer_,
true)->getGIDFieldOffsetsKokkos(blockId,fieldIds_);
348 auto gidFieldOffsets = gidFieldOffsetsVoV.getViewDevice();
349 auto gatherFieldsDevice = gatherFieldsVoV_.getViewDevice();
350 auto x_view = x_vector->getLocalViewDevice(Tpetra::Access::ReadOnly);
351 auto tangentInnerVectorSizes = this->tangentInnerVectorSizes_;
353 if (has_tangent_fields_) {
354 auto tangentFieldsDevice = tangentFieldsVoV_.getViewDevice();
355 Kokkos::parallel_for(
"GatherSolutionTpetra<Tangent>",cellLocalIdsKokkos.extent(0),KOKKOS_LAMBDA(
const int worksetCellIndex) {
356 for (
size_t fieldIndex = 0; fieldIndex < gidFieldOffsets.extent(0); ++fieldIndex) {
357 for(
size_t basis=0;basis<gidFieldOffsets(fieldIndex).extent(0);basis++) {
358 int offset = gidFieldOffsets(fieldIndex)(basis);
359 LO lid =
lids(cellLocalIdsKokkos(worksetCellIndex),offset);
360 auto gf_ref = (gatherFieldsDevice[fieldIndex])(worksetCellIndex,basis);
361 gf_ref.val() = x_view(lid,0);
362 for (std::size_t i=0; i<tangentInnerVectorSizes(fieldIndex); ++i) {
363 gf_ref.fastAccessDx(i) = tangentFieldsDevice(fieldIndex,i)(worksetCellIndex,basis);
370 Kokkos::parallel_for(
"GatherSolutionTpetra<Tangent>",cellLocalIdsKokkos.extent(0),KOKKOS_LAMBDA(
const int worksetCellIndex) {
371 for (
size_t fieldIndex = 0; fieldIndex < gidFieldOffsets.extent(0); ++fieldIndex) {
372 for(
size_t basis=0;basis<gidFieldOffsets(fieldIndex).extent(0);basis++) {
373 int offset = gidFieldOffsets(fieldIndex)(basis);
374 LO lid =
lids(cellLocalIdsKokkos(worksetCellIndex),offset);
375 reference_type gf_ref = (gatherFieldsDevice[fieldIndex])(worksetCellIndex,basis);
376 gf_ref.val() = x_view(lid,0);
390 const Teuchos::RCP<const panzer::GlobalIndexer> & indexer,
391 const Teuchos::ParameterList& p)
392 : globalIndexer_(indexer)
399 const std::vector<std::string> & names = input.
getDofNames();
400 Teuchos::RCP<const panzer::PureBasis> basis = input.
getBasis();
411 gatherFields_.resize(names.size());
412 scratch_offsets_.resize(names.size());
413 for (std::size_t fd = 0; fd < names.size(); ++fd) {
414 PHX::MDField<ScalarT,Cell,NODE> f(names[fd],basis->functional);
415 gatherFields_[fd] = f;
416 this->addEvaluatedField(gatherFields_[fd]);
419 this->addUnsharedField(gatherFields_[fd].fieldTag().clone());
423 std::string firstName =
"<none>";
425 firstName = names[0];
428 if(disableSensitivities_) {
429 std::string n =
"GatherSolution (Tpetra, No Sensitivities): "+firstName+
" (Jacobian)";
433 std::string n =
"GatherSolution (Tpetra): "+firstName+
" (Jacobian) ";
444 TEUCHOS_ASSERT(gatherFields_.size() == indexerNames_.size());
446 fieldIds_.resize(gatherFields_.size());
448 const Workset & workset_0 = (*d.worksets_)[0];
449 std::string blockId = this->wda(workset_0).
block_id;
451 for (std::size_t fd = 0; fd < gatherFields_.size(); ++fd) {
453 const std::string& fieldName = indexerNames_[fd];
454 fieldIds_[fd] = globalIndexer_->getFieldNum(fieldName);
456 int fieldNum = fieldIds_[fd];
457 const std::vector<int> &
offsets = globalIndexer_->getGIDFieldOffsets(blockId,fieldNum);
458 scratch_offsets_[fd] = PHX::View<int*>(
"offsets",
offsets.size());
459 Kokkos::deep_copy(scratch_offsets_[fd], Kokkos::View<const int*, Kokkos::HostSpace, Kokkos::MemoryUnmanaged>(
offsets.data(),
offsets.size()));
462 scratch_lids_ = PHX::View<LO**>(
"lids",gatherFields_[0].extent(0),
463 globalIndexer_->getElementBlockGIDCount(blockId));
465 indexerNames_.clear();
475 using Teuchos::rcp_dynamic_cast;
482 if(!disableSensitivities_) {
483 if(d.first_sensitivities_name==sensitivitiesName_)
484 applySensitivities_ =
true;
486 applySensitivities_ =
false;
489 applySensitivities_ =
false;
493 RCP<GlobalEvaluationData> ged;
496 std::string post = useTimeDerivativeSolutionVector_ ?
" - Xdot" :
" - X";
497 if(d.gedc->containsDataObject(globalDataKey_+post)) {
498 ged = d.gedc->getDataObject(globalDataKey_+post);
500 RCP<RO_GED> ro_ged = rcp_dynamic_cast<RO_GED>(ged,
true);
502 x_vector = ro_ged->getGhostedVector_Tpetra();
507 ged = d.gedc->getDataObject(globalDataKey_);
511 RCP<LOC> tpetraContainer = rcp_dynamic_cast<LOC>(ged);
512 RCP<LOCPair_GlobalEvaluationData> loc_pair = rcp_dynamic_cast<LOCPair_GlobalEvaluationData>(ged);
514 if(loc_pair!=Teuchos::null) {
515 Teuchos::RCP<LinearObjContainer> loc = loc_pair->getGhostedLOC();
517 tpetraContainer = rcp_dynamic_cast<LOC>(loc);
520 if(tpetraContainer!=Teuchos::null) {
521 if (useTimeDerivativeSolutionVector_)
522 x_vector = tpetraContainer->get_dxdt_mv();
524 x_vector = tpetraContainer->get_x_mv();
532 RCP<RO_GED> ro_ged = rcp_dynamic_cast<RO_GED>(ged,
true);
534 x_vector = ro_ged->getGhostedVector_Tpetra();
544 std::string blockId = this->wda(workset).block_id;
550 double seed_value = 0.0;
551 if (applySensitivities_) {
552 if (useTimeDerivativeSolutionVector_) {
553 seed_value = workset.alpha;
555 else if (gatherSeedIndex_<0) {
556 seed_value = workset.beta;
558 else if(!useTimeDerivativeSolutionVector_) {
559 seed_value = workset.gather_seeds[gatherSeedIndex_];
562 TEUCHOS_ASSERT(
false);
569 functor_data.dos = 0;
570 if (this->wda.getDetailsIndex() == 1)
573 functor_data.dos = globalIndexer_->getElementBlockGIDCount(workset.details(0).block_id);
576 globalIndexer_->getElementLIDs(this->wda(workset).cell_local_ids_k,scratch_lids_);
581 functor_data.x_data = x_vector->getLocalViewDevice(Tpetra::Access::ReadOnly);
582 functor_data.seed_value = seed_value;
583 functor_data.lids = scratch_lids_;
586 for(std::size_t fieldIndex=0;
587 fieldIndex<gatherFields_.size();fieldIndex++) {
590 functor_data.offsets = scratch_offsets_[fieldIndex];
591 functor_data.field = gatherFields_[fieldIndex];
593 Kokkos::parallel_for(workset.num_cells,*
this);
595 functor_data.x_data = Kokkos::View<const double**, Kokkos::LayoutLeft,PHX::Device>();
605 for(std::size_t basis=0;basis<functor_data.offsets.extent(0);basis++) {
606 int offset = functor_data.offsets(basis);
607 LO lid = functor_data.lids(worksetCellIndex,offset);
610 if (functor_data.dos == 0)
611 functor_data.field(worksetCellIndex,basis).val() = functor_data.x_data(lid,0);
613 functor_data.field(worksetCellIndex,basis) =
ScalarT(functor_data.x_data(lid,0));
616 functor_data.field(worksetCellIndex,basis).fastAccessDx(functor_data.dos + offset) = functor_data.seed_value;