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");
65 scatterFields_.resize(names.size());
66 for (std::size_t eq = 0; eq < names.size(); ++eq) {
70 this->addDependentField(scatterFields_[eq]);
73 checkApplyBC_ = p.
isParameter(
"Check Apply BC") ? p.
get<
bool>(
"Check Apply BC") :
false;
75 applyBC_.resize(names.size());
76 for (std::size_t eq = 0; eq < names.size(); ++eq) {
78 this->addDependentField(applyBC_[eq]);
83 this->addEvaluatedField(*scatterHolder_);
85 if (p.
isType<std::string>(
"Global Data Key"))
86 globalDataKey_ = p.
get<std::string>(
"Global Data Key");
88 this->setName(scatterName+
" Scatter Residual");
92 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
97 fieldIds_.resize(scatterFields_.size());
100 for(std::size_t fd=0;fd<scatterFields_.size();++fd) {
102 std::string fieldName = fieldMap_->find(scatterFields_[fd].fieldTag().name())->second;
103 fieldIds_[fd] = globalIndexer_->getFieldNum(fieldName);
107 num_nodes = scatterFields_[0].extent(1);
111 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
116 tpetraContainer_ = Teuchos::rcp_dynamic_cast<
LOC>(d.gedc->getDataObject(globalDataKey_));
118 if(tpetraContainer_==Teuchos::null) {
121 tpetraContainer_ = Teuchos::rcp_dynamic_cast<
LOC>(loc);
123 dirichletCounter_ = Teuchos::null;
128 = Teuchos::rcp_dynamic_cast<
LOC>(d.gedc->getDataObject(
"Dirichlet Counter"),
true);
130 dirichletCounter_ = tpetraContainer->get_f();
136 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
140 std::vector<GO> GIDs;
141 std::vector<LO> LIDs;
144 std::string blockId = this->wda(workset).block_id;
145 const std::vector<std::size_t> & localCellIds = this->wda(workset).cell_local_ids;
148 tpetraContainer_->get_f() :
149 tpetraContainer_->get_x();
162 for(std::size_t fieldIndex = 0; fieldIndex < scatterFields_.size(); fieldIndex++) {
163 int fieldNum = fieldIds_[fieldIndex];
164 auto scatterFields_h = Kokkos::create_mirror_view(scatterFields_[fieldIndex].get_static_view());
165 Kokkos::deep_copy(scatterFields_h, scatterFields_[fieldIndex].get_static_view());
168 for(std::size_t worksetCellIndex=0;worksetCellIndex<localCellIds.size();++worksetCellIndex) {
169 std::size_t cellLocalId = localCellIds[worksetCellIndex];
171 globalIndexer_->getElementGIDs(cellLocalId,GIDs);
174 LIDs.resize(GIDs.size());
175 for(std::size_t i=0;i<GIDs.size();i++)
176 LIDs[i] = r->getMap()->getLocalElement(GIDs[i]);
180 const std::pair<std::vector<int>,std::vector<int> > & indicePair
181 = globalIndexer_->getGIDFieldOffsets_closure(blockId,fieldNum, side_subcell_dim_, local_side_id_);
182 const std::vector<int> & elmtOffset = indicePair.first;
183 const std::vector<int> & basisIdMap = indicePair.second;
186 for(std::size_t basis=0;basis<elmtOffset.size();basis++) {
187 int offset = elmtOffset[basis];
188 LO lid = LIDs[offset];
192 int basisId = basisIdMap[basis];
195 if (!applyBC_[fieldIndex](worksetCellIndex,basisId))
198 r_array[lid] = scatterFields_h(worksetCellIndex,basisId);
205 const std::vector<int> & elmtOffset = globalIndexer_->getGIDFieldOffsets(blockId,fieldNum);
208 for(std::size_t basis=0;basis<elmtOffset.size();basis++) {
209 int offset = elmtOffset[basis];
210 LO lid = LIDs[offset];
214 r_array[lid] = scatterFields_h(worksetCellIndex,basis);
229 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
233 : globalIndexer_(indexer)
234 , globalDataKey_(
"Residual Scatter Container")
236 std::string scatterName = p.
get<std::string>(
"Scatter Name");
241 const std::vector<std::string>& names =
248 scatterIC_ = p.
isParameter(
"Scatter Initial Condition") ? p.
get<
bool>(
"Scatter Initial Condition") :
false;
254 side_subcell_dim_ = p.
get<
int>(
"Side Subcell Dimension");
255 local_side_id_ = p.
get<
int>(
"Local Side ID");
259 scatterFields_.resize(names.size());
260 for (std::size_t eq = 0; eq < names.size(); ++eq) {
264 this->addDependentField(scatterFields_[eq]);
267 checkApplyBC_ = p.
isParameter(
"Check Apply BC") ? p.
get<
bool>(
"Check Apply BC") :
false;
269 applyBC_.resize(names.size());
270 for (std::size_t eq = 0; eq < names.size(); ++eq) {
272 this->addDependentField(applyBC_[eq]);
277 this->addEvaluatedField(*scatterHolder_);
279 if (p.
isType<std::string>(
"Global Data Key"))
280 globalDataKey_ = p.
get<std::string>(
"Global Data Key");
282 this->setName(scatterName+
" Scatter Tangent");
286 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
291 fieldIds_.resize(scatterFields_.size());
294 for(std::size_t fd=0;fd<scatterFields_.size();++fd) {
296 std::string fieldName = fieldMap_->find(scatterFields_[fd].fieldTag().name())->second;
297 fieldIds_[fd] = globalIndexer_->getFieldNum(fieldName);
301 num_nodes = scatterFields_[0].extent(1);
305 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
310 tpetraContainer_ = Teuchos::rcp_dynamic_cast<
LOC>(d.gedc->getDataObject(globalDataKey_));
312 if(tpetraContainer_==Teuchos::null) {
315 tpetraContainer_ = Teuchos::rcp_dynamic_cast<
LOC>(loc);
317 dirichletCounter_ = Teuchos::null;
322 = Teuchos::rcp_dynamic_cast<
LOC>(d.gedc->getDataObject(
"Dirichlet Counter"),
true);
324 dirichletCounter_ = tpetraContainer->get_f();
329 using Teuchos::rcp_dynamic_cast;
332 std::vector<std::string> activeParameters =
337 dfdp_vectors_.clear();
338 for(std::size_t i=0;i<activeParameters.size();i++) {
340 rcp_dynamic_cast<
LOC>(d.gedc->getDataObject(activeParameters[i]),
true)->get_f();
342 dfdp_vectors_.push_back(vec_array);
347 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
351 std::vector<GO> GIDs;
352 std::vector<LO> LIDs;
355 std::string blockId = this->wda(workset).block_id;
356 const std::vector<std::size_t> & localCellIds = this->wda(workset).cell_local_ids;
359 tpetraContainer_->get_f() :
360 tpetraContainer_->get_x();
372 for(std::size_t worksetCellIndex=0;worksetCellIndex<localCellIds.size();++worksetCellIndex) {
373 std::size_t cellLocalId = localCellIds[worksetCellIndex];
375 globalIndexer_->getElementGIDs(cellLocalId,GIDs);
379 for(std::size_t i=0;i<GIDs.size();i++)
380 LIDs[i] = r->getMap()->getLocalElement(GIDs[i]);
383 for(std::size_t fieldIndex = 0; fieldIndex < scatterFields_.size(); fieldIndex++) {
384 int fieldNum = fieldIds_[fieldIndex];
388 const std::pair<std::vector<int>,std::vector<int> > & indicePair
389 = globalIndexer_->getGIDFieldOffsets_closure(blockId,fieldNum, side_subcell_dim_, local_side_id_);
390 const std::vector<int> & elmtOffset = indicePair.first;
391 const std::vector<int> & basisIdMap = indicePair.second;
394 for(std::size_t basis=0;basis<elmtOffset.size();basis++) {
395 int offset = elmtOffset[basis];
396 LO lid = LIDs[offset];
400 int basisId = basisIdMap[basis];
403 if (!applyBC_[fieldIndex](worksetCellIndex,basisId))
406 ScalarT value = (scatterFields_[fieldIndex])(worksetCellIndex,basisId);
411 for(std::size_t d=0;d<dfdp_vectors_.size();d++)
412 dfdp_vectors_[d][lid] = 0.0;
414 for(
int d=0;d<value.size();d++) {
415 dfdp_vectors_[d][lid] = value.fastAccessDx(d);
423 const std::vector<int> & elmtOffset = globalIndexer_->getGIDFieldOffsets(blockId,fieldNum);
426 for(std::size_t basis=0;basis<elmtOffset.size();basis++) {
427 int offset = elmtOffset[basis];
428 LO lid = LIDs[offset];
432 ScalarT value = (scatterFields_[fieldIndex])(worksetCellIndex,basis);
437 for(std::size_t d=0;d<dfdp_vectors_.size();d++)
438 dfdp_vectors_[d][lid] = 0.0;
440 for(
int d=0;d<value.size();d++) {
441 dfdp_vectors_[d][lid] = value.fastAccessDx(d);
456 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
460 : globalIndexer_(indexer)
461 , globalDataKey_(
"Residual Scatter Container")
463 std::string scatterName = p.
get<std::string>(
"Scatter Name");
468 const std::vector<std::string>& names =
477 side_subcell_dim_ = p.
get<
int>(
"Side Subcell Dimension");
478 local_side_id_ = p.
get<
int>(
"Local Side ID");
481 scatterFields_.resize(names.size());
482 for (std::size_t eq = 0; eq < names.size(); ++eq) {
486 this->addDependentField(scatterFields_[eq]);
489 checkApplyBC_ = p.
get<
bool>(
"Check Apply BC");
491 applyBC_.resize(names.size());
492 for (std::size_t eq = 0; eq < names.size(); ++eq) {
494 this->addDependentField(applyBC_[eq]);
499 this->addEvaluatedField(*scatterHolder_);
501 if (p.
isType<std::string>(
"Global Data Key"))
502 globalDataKey_ = p.
get<std::string>(
"Global Data Key");
504 this->setName(scatterName+
" Scatter Residual (Jacobian)");
508 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
513 fieldIds_.resize(scatterFields_.size());
515 for(std::size_t fd=0;fd<scatterFields_.size();++fd) {
517 std::string fieldName = fieldMap_->find(scatterFields_[fd].fieldTag().name())->second;
518 fieldIds_[fd] = globalIndexer_->getFieldNum(fieldName);
522 num_nodes = scatterFields_[0].extent(1);
523 num_eq = scatterFields_.size();
527 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
532 tpetraContainer_ = Teuchos::rcp_dynamic_cast<
LOC>(d.gedc->getDataObject(globalDataKey_));
534 if(tpetraContainer_==Teuchos::null) {
537 tpetraContainer_ = Teuchos::rcp_dynamic_cast<
LOC>(loc);
539 dirichletCounter_ = Teuchos::null;
544 = Teuchos::rcp_dynamic_cast<
LOC>(d.gedc->getDataObject(
"Dirichlet Counter"),
true);
546 dirichletCounter_ = tpetraContainer->get_f();
552 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
556 std::vector<GO> GIDs;
559 std::string blockId = this->wda(workset).block_id;
560 const std::vector<std::size_t> & localCellIds = this->wda(workset).cell_local_ids;
574 auto LIDs = globalIndexer_->getLIDs();
575 auto LIDs_h = Kokkos::create_mirror_view(LIDs);
576 Kokkos::deep_copy(LIDs_h, LIDs);
578 for(std::size_t fieldIndex = 0; fieldIndex < scatterFields_.size(); fieldIndex++) {
579 int fieldNum = fieldIds_[fieldIndex];
580 auto scatterFields_h = Kokkos::create_mirror_view(scatterFields_[fieldIndex].get_static_view());
581 Kokkos::deep_copy(scatterFields_h, scatterFields_[fieldIndex].get_static_view());
582 for(std::size_t worksetCellIndex=0;worksetCellIndex<localCellIds.size();++worksetCellIndex) {
583 std::size_t cellLocalId = localCellIds[worksetCellIndex];
585 globalIndexer_->getElementGIDs(cellLocalId,GIDs);
588 const std::pair<std::vector<int>,std::vector<int> > & indicePair
589 = globalIndexer_->getGIDFieldOffsets_closure(blockId,fieldNum, side_subcell_dim_, local_side_id_);
590 const std::vector<int> & elmtOffset = indicePair.first;
591 const std::vector<int> & basisIdMap = indicePair.second;
594 for(std::size_t basis=0;basis<elmtOffset.size();basis++) {
595 int offset = elmtOffset[basis];
596 int lid = LIDs_h(cellLocalId, offset);
600 int basisId = basisIdMap[basis];
603 if (!applyBC_[fieldIndex](worksetCellIndex,basisId))
608 std::size_t sz = Jac->getNumEntriesInLocalRow(lid);
609 std::size_t numEntries = 0;
610 typename LOC::CrsMatrixType::nonconst_local_inds_host_view_type rowIndices(
"indices", sz);
611 typename LOC::CrsMatrixType::nonconst_values_host_view_type rowValues(
"values", sz);
614 Jac->getLocalRowCopy(lid,rowIndices,rowValues,numEntries);
616 for(std::size_t i=0;i<numEntries;i++)
619 Jac->replaceLocalValues(lid,rowIndices,rowValues);
622 GO gid = GIDs[offset];
623 const ScalarT scatterField = scatterFields_h(worksetCellIndex,basisId);
625 r_array[lid] = scatterField.val();
629 std::vector<double> jacRow(scatterField.size(),0.0);
631 for(
int sensIndex=0;sensIndex<scatterField.size();++sensIndex)
632 jacRow[sensIndex] = scatterField.fastAccessDx(sensIndex);
635 Jac->replaceGlobalValues(gid, GIDs, jacRow);
panzer::Traits::Tangent::ScalarT ScalarT
T & get(const std::string &name, T def_value)
bool is_null(const std::shared_ptr< T > &p)
void resize(const size_type n, const T &val=T())
bool isParameter(const std::string &name) const
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Pushes residual values into the residual vector for a Newton-based solve.
bool isType(const std::string &name) const
#define TEUCHOS_ASSERT(assertion_test)
panzer::Traits::Jacobian::ScalarT ScalarT