42 const Teuchos::RCP<const panzer::GlobalIndexer> & ,
43 const Teuchos::ParameterList& p,
44 bool useDiscreteAdjoint)
45 : globalIndexer_(indexer)
46 , globalDataKey_(
"Residual Scatter Container")
47 , useDiscreteAdjoint_(useDiscreteAdjoint)
49 std::string scatterName = p.get<std::string>(
"Scatter Name");
51 Teuchos::rcp(
new PHX::Tag<ScalarT>(scatterName,Teuchos::rcp(
new PHX::MDALayout<Dummy>(0))));
54 const std::vector<std::string>& names =
55 *(p.get< Teuchos::RCP< std::vector<std::string> > >(
"Dependent Names"));
58 fieldMap_ = p.get< Teuchos::RCP< std::map<std::string,std::string> > >(
"Dependent Map");
60 Teuchos::RCP<PHX::DataLayout> dl =
61 p.get< Teuchos::RCP<const panzer::PureBasis> >(
"Basis")->functional;
64 scatterFields_.resize(names.size());
65 for (std::size_t eq = 0; eq < names.size(); ++eq) {
66 scatterFields_[eq] = PHX::MDField<const ScalarT,Cell,NODE>(names[eq],dl);
69 this->addDependentField(scatterFields_[eq]);
73 this->addEvaluatedField(*scatterHolder_);
75 if (p.isType<std::string>(
"Global Data Key"))
76 globalDataKey_ = p.get<std::string>(
"Global Data Key");
78 this->setName(scatterName+
" Scatter Residual");
117 std::string blockId = this->wda(workset).block_id;
118 const std::vector<std::size_t> & localCellIds = this->wda(workset).cell_local_ids;
120 Teuchos::RCP<Epetra_Vector> r = epetraContainer_->get_f();
128 auto LIDs = globalIndexer_->getLIDs();
129 auto LIDs_h = Kokkos::create_mirror_view(LIDs);
130 Kokkos::deep_copy(LIDs_h, LIDs);
132 for (std::size_t fieldIndex = 0; fieldIndex < scatterFields_.size(); fieldIndex++) {
133 int fieldNum = fieldIds_[fieldIndex];
134 auto field = PHX::as_view(scatterFields_[fieldIndex]);
135 auto field_h = Kokkos::create_mirror_view(
field);
136 Kokkos::deep_copy(field_h,
field);
138 const std::vector<int> & elmtOffset = globalIndexer_->getGIDFieldOffsets(blockId,fieldNum);
139 for(std::size_t worksetCellIndex=0;worksetCellIndex<localCellIds.size();++worksetCellIndex) {
140 std::size_t cellLocalId = localCellIds[worksetCellIndex];
143 for(std::size_t basis=0;basis<elmtOffset.size();basis++) {
144 int offset = elmtOffset[basis];
145 int lid = LIDs_h(cellLocalId, offset);
146 (*r)[lid] += field_h(worksetCellIndex,basis);
159 const Teuchos::RCP<const panzer::GlobalIndexer> & ,
160 const Teuchos::ParameterList& p,
162 : globalIndexer_(indexer)
164 std::string scatterName = p.get<std::string>(
"Scatter Name");
166 Teuchos::rcp(
new PHX::Tag<ScalarT>(scatterName,Teuchos::rcp(
new PHX::MDALayout<Dummy>(0))));
169 const std::vector<std::string>& names =
170 *(p.get< Teuchos::RCP< std::vector<std::string> > >(
"Dependent Names"));
173 fieldMap_ = p.get< Teuchos::RCP< std::map<std::string,std::string> > >(
"Dependent Map");
175 Teuchos::RCP<PHX::DataLayout> dl =
176 p.get< Teuchos::RCP<const panzer::PureBasis> >(
"Basis")->functional;
179 scatterFields_.resize(names.size());
180 for (std::size_t eq = 0; eq < names.size(); ++eq) {
181 scatterFields_[eq] = PHX::MDField<const ScalarT,Cell,NODE>(names[eq],dl);
184 this->addDependentField(scatterFields_[eq]);
188 this->addEvaluatedField(*scatterHolder_);
190 this->setName(scatterName+
" Scatter Tangent");
233 std::string blockId = this->wda(workset).block_id;
234 const std::vector<std::size_t> & localCellIds = this->wda(workset).cell_local_ids;
242 auto LIDs = globalIndexer_->getLIDs();
243 auto LIDs_h = Kokkos::create_mirror_view(LIDs);
244 Kokkos::deep_copy(LIDs_h, LIDs);
245 for (std::size_t fieldIndex = 0; fieldIndex < scatterFields_.size(); fieldIndex++) {
246 int fieldNum = fieldIds_[fieldIndex];
247 const std::vector<int> & elmtOffset = globalIndexer_->getGIDFieldOffsets(blockId,fieldNum);
248 auto scatterField_h = Kokkos::create_mirror_view(scatterFields_[fieldIndex].get_static_view());
249 Kokkos::deep_copy(scatterField_h, scatterFields_[fieldIndex].get_static_view());
251 for(std::size_t worksetCellIndex=0;worksetCellIndex<localCellIds.size();++worksetCellIndex) {
252 std::size_t cellLocalId = localCellIds[worksetCellIndex];
255 for(std::size_t basis=0;basis<elmtOffset.size();basis++) {
256 int offset = elmtOffset[basis];
257 int lid = LIDs_h(cellLocalId, offset);
260 ScalarT value = scatterField_h(worksetCellIndex,basis);
261 for(
int d=0;d<value.size();d++)
262 (*dfdp_vectors_[d])[lid] += value.fastAccessDx(d);
358 std::vector<double> jacRow;
360 bool useColumnIndexer = colGlobalIndexer_!=Teuchos::null;
363 std::string blockId = this->wda(workset).block_id;
364 const std::vector<std::size_t> & localCellIds = this->wda(workset).cell_local_ids;
366 Teuchos::RCP<Epetra_Vector> r = epetraContainer_->get_f();
367 Teuchos::RCP<Epetra_CrsMatrix> Jac = epetraContainer_->get_A();
369 const Teuchos::RCP<const panzer::GlobalIndexer>&
370 colGlobalIndexer = useColumnIndexer ? colGlobalIndexer_ : globalIndexer_;
378 auto LIDs = globalIndexer_->getLIDs();
379 auto colLIDs = colGlobalIndexer->getLIDs();
380 auto LIDs_h = Kokkos::create_mirror_view(LIDs);
381 auto colLIDs_h = Kokkos::create_mirror_view(colLIDs);
382 Kokkos::deep_copy(LIDs_h, LIDs);
383 Kokkos::deep_copy(colLIDs_h, colLIDs);
384 std::vector<
typename decltype(scatterFields_[0].get_static_view())::host_mirror_type> scatterFields_h;
385 for ( std::size_t i=0; i< scatterFields_.size(); ++i) {
386 scatterFields_h.push_back(Kokkos::create_mirror_view(scatterFields_[i].get_static_view()));
387 Kokkos::deep_copy(scatterFields_h[i], scatterFields_[i].get_static_view());
390 for(std::size_t worksetCellIndex=0;worksetCellIndex<localCellIds.size();++worksetCellIndex) {
391 std::size_t cellLocalId = localCellIds[worksetCellIndex];
393 std::vector<int> cLIDs;
394 for (
int i(0); i < static_cast<int>(colLIDs_h.extent(1)); ++i)
395 cLIDs.push_back(colLIDs_h(cellLocalId, i));
396 if (Teuchos::nonnull(workset.other)) {
397 const std::size_t other_cellLocalId = workset.other->cell_local_ids[worksetCellIndex];
398 for (
int i(0); i < static_cast<int>(colLIDs_h.extent(1)); ++i)
399 cLIDs.push_back(colLIDs_h(other_cellLocalId, i));
403 for(std::size_t fieldIndex = 0; fieldIndex < scatterFields_.size(); fieldIndex++) {
404 int fieldNum = fieldIds_[fieldIndex];
405 const std::vector<int> & elmtOffset = globalIndexer_->getGIDFieldOffsets(blockId,fieldNum);
408 for(std::size_t rowBasisNum = 0; rowBasisNum < elmtOffset.size(); rowBasisNum++) {
409 const ScalarT scatterField = (scatterFields_h[fieldIndex])(worksetCellIndex,rowBasisNum);
410 int rowOffset = elmtOffset[rowBasisNum];
411 int row = LIDs_h(cellLocalId,rowOffset);
415 r->SumIntoMyValue(row,0,scatterField.val());
418 if(useDiscreteAdjoint_) {
420 jacRow.resize(scatterField.size());
422 for(
int sensIndex=0;sensIndex<scatterField.size();++sensIndex)
423 jacRow[sensIndex] = scatterField.fastAccessDx(sensIndex);
425 for(std::size_t c=0;c<cLIDs.size();c++) {
426 int err = Jac->SumIntoMyValues(cLIDs[c], 1, &jacRow[c],&row);
427 TEUCHOS_ASSERT_EQUALITY(err,0);
431 int err = Jac->SumIntoMyValues(
433 std::min(cLIDs.size(),
static_cast<size_t>(scatterField.size())),
437 TEUCHOS_ASSERT_EQUALITY(err,0);