11 #ifndef PANZER_SCATTER_DIRICHLET_RESIDUAL_BLOCEDEPETRA_IMPL_HPP
12 #define PANZER_SCATTER_DIRICHLET_RESIDUAL_BLOCEDEPETRA_IMPL_HPP
15 #include "Teuchos_Assert.hpp"
17 #include "Phalanx_DataLayout.hpp"
19 #include "Epetra_Map.h"
20 #include "Epetra_Vector.h"
21 #include "Epetra_CrsMatrix.h"
30 #include "Phalanx_DataLayout_MDALayout.hpp"
32 #include "Thyra_SpmdVectorBase.hpp"
33 #include "Thyra_ProductVectorBase.hpp"
34 #include "Thyra_DefaultProductVector.hpp"
35 #include "Thyra_BlockedLinearOpBase.hpp"
36 #include "Thyra_get_Epetra_Operator.hpp"
38 #include "Teuchos_FancyOStream.hpp"
40 #include <unordered_map>
47 template<
typename TRAITS,
typename LO,
typename GO>
53 : rowIndexers_(rIndexers)
54 , colIndexers_(cIndexers)
55 , globalDataKey_(
"Residual Scatter Container")
57 std::string scatterName = p.
get<std::string>(
"Scatter Name");
62 const std::vector<std::string>& names =
69 scatterIC_ = p.
isParameter(
"Scatter Initial Condition") ? p.
get<
bool>(
"Scatter Initial Condition") :
false;
75 side_subcell_dim_ = p.
get<
int>(
"Side Subcell Dimension");
76 local_side_id_ = p.
get<
int>(
"Local Side ID");
80 scatterFields_.resize(names.size());
81 for (std::size_t eq = 0; eq < names.size(); ++eq) {
85 this->addDependentField(scatterFields_[eq]);
88 checkApplyBC_ = p.
isParameter(
"Check Apply BC") ? p.
get<
bool>(
"Check Apply BC") :
false;
90 applyBC_.resize(names.size());
91 for (std::size_t eq = 0; eq < names.size(); ++eq) {
93 this->addDependentField(applyBC_[eq]);
98 this->addEvaluatedField(*scatterHolder_);
100 if (p.
isType<std::string>(
"Global Data Key"))
101 globalDataKey_ = p.
get<std::string>(
"Global Data Key");
103 this->setName(scatterName+
" Scatter Residual");
107 template<
typename TRAITS,
typename LO,
typename GO>
112 indexerIds_.resize(scatterFields_.size());
113 subFieldIds_.resize(scatterFields_.size());
116 for(std::size_t fd=0;fd<scatterFields_.size();++fd) {
118 std::string fieldName = fieldMap_->find(scatterFields_[fd].fieldTag().name())->second;
121 subFieldIds_[fd] = rowIndexers_[indexerIds_[fd]]->getFieldNum(fieldName);
125 num_nodes = scatterFields_[0].extent(1);
129 template<
typename TRAITS,
typename LO,
typename GO>
136 using Teuchos::rcp_dynamic_cast;
141 = Teuchos::rcp_dynamic_cast<BLOC>(d.gedc->getDataObject(
"Dirichlet Counter"),
true);
147 Teuchos::RCP<const BLOC> blockedContainer = Teuchos::rcp_dynamic_cast<
const BLOC>(d.gedc->getDataObject(globalDataKey_));
148 Teuchos::RCP<const ELOC> epetraContainer = Teuchos::rcp_dynamic_cast<
const ELOC>(d.gedc->getDataObject(globalDataKey_));
151 if(blockedContainer!=Teuchos::null)
153 rcp_dynamic_cast<ProductVectorBase<double> >(blockedContainer->get_f(),
true) :
154 rcp_dynamic_cast<ProductVectorBase<double> >(blockedContainer->get_x(),
true);
155 else if(epetraContainer!=Teuchos::null)
157 Thyra::castOrCreateNonconstProductVectorBase<double>(epetraContainer->get_f_th()) :
158 Thyra::castOrCreateNonconstProductVectorBase<double>(epetraContainer->get_x_th());
164 template<
typename TRAITS,
typename LO,
typename GO>
170 using Teuchos::ptrFromRef;
171 using Teuchos::rcp_dynamic_cast;
174 using Thyra::SpmdVectorBase;
178 std::string blockId = this->wda(workset).block_id;
179 const std::vector<std::size_t> & localCellIds = this->wda(workset).cell_local_ids;
189 for(std::size_t fieldIndex = 0; fieldIndex < scatterFields_.size(); fieldIndex++) {
190 int rowIndexer = indexerIds_[fieldIndex];
191 int subFieldNum = subFieldIds_[fieldIndex];
193 rcp_dynamic_cast<SpmdVectorBase<double> >(dirichletCounter_->getNonconstVectorBlock(rowIndexer))
194 ->getNonconstLocalData(ptrFromRef(local_dc));
197 rcp_dynamic_cast<SpmdVectorBase<double> >(r_->getNonconstVectorBlock(rowIndexer))
198 ->getNonconstLocalData(ptrFromRef(local_r));
200 auto subRowIndexer = rowIndexers_[rowIndexer];
201 auto LIDs = subRowIndexer->getLIDs();
202 auto LIDs_h = Kokkos::create_mirror_view(LIDs);
203 Kokkos::deep_copy(LIDs_h, LIDs);
205 auto field = scatterFields_[fieldIndex].get_view();
206 auto field_h = Kokkos::create_mirror_view(
field);
207 Kokkos::deep_copy(field_h,
field);
209 BCFieldType::array_type::HostMirror applyBC_h;
211 auto applyBC = applyBC_[fieldIndex].get_static_view();
212 applyBC_h = Kokkos::create_mirror_view(applyBC);
213 Kokkos::deep_copy(applyBC_h, applyBC);
217 for(std::size_t worksetCellIndex=0;worksetCellIndex<localCellIds.size();++worksetCellIndex) {
218 std::size_t cellLocalId = localCellIds[worksetCellIndex];
222 const std::pair<std::vector<int>,std::vector<int> > & indicePair
223 = subRowIndexer->getGIDFieldOffsets_closure(blockId,subFieldNum, side_subcell_dim_, local_side_id_);
224 const std::vector<int> & elmtOffset = indicePair.first;
225 const std::vector<int> & basisIdMap = indicePair.second;
228 for(std::size_t basis=0;basis<elmtOffset.size();basis++) {
229 int offset = elmtOffset[basis];
230 int lid = LIDs_h(cellLocalId, offset);
234 int basisId = basisIdMap[basis];
236 if (checkApplyBC_ and !applyBC_h(worksetCellIndex,basisId))
239 local_r[lid] = field_h(worksetCellIndex,basisId);
246 const std::vector<int> & elmtOffset = subRowIndexer->getGIDFieldOffsets(blockId,subFieldNum);
249 for(std::size_t basis=0;basis<elmtOffset.size();basis++) {
250 int offset = elmtOffset[basis];
251 int lid = LIDs_h(cellLocalId, offset);
255 local_r[lid] = field_h(worksetCellIndex,basis);
270 template<
typename TRAITS,
typename LO,
typename GO>
276 : rowIndexers_(rIndexers)
277 , colIndexers_(cIndexers)
278 , globalDataKey_(
"Residual Scatter Container")
280 std::string scatterName = p.
get<std::string>(
"Scatter Name");
285 const std::vector<std::string>& names =
292 scatterIC_ = p.
isParameter(
"Scatter Initial Condition") ? p.
get<
bool>(
"Scatter Initial Condition") :
false;
298 side_subcell_dim_ = p.
get<
int>(
"Side Subcell Dimension");
299 local_side_id_ = p.
get<
int>(
"Local Side ID");
303 scatterFields_.resize(names.size());
304 for (std::size_t eq = 0; eq < names.size(); ++eq) {
308 this->addDependentField(scatterFields_[eq]);
311 checkApplyBC_ = p.
isParameter(
"Check Apply BC") ? p.
get<
bool>(
"Check Apply BC") :
false;
313 applyBC_.resize(names.size());
314 for (std::size_t eq = 0; eq < names.size(); ++eq) {
316 this->addDependentField(applyBC_[eq]);
321 this->addEvaluatedField(*scatterHolder_);
323 if (p.
isType<std::string>(
"Global Data Key"))
324 globalDataKey_ = p.
get<std::string>(
"Global Data Key");
326 this->setName(scatterName+
" Scatter Tangent");
330 template<
typename TRAITS,
typename LO,
typename GO>
335 indexerIds_.resize(scatterFields_.size());
336 subFieldIds_.resize(scatterFields_.size());
339 for(std::size_t fd=0;fd<scatterFields_.size();++fd) {
341 std::string fieldName = fieldMap_->find(scatterFields_[fd].fieldTag().name())->second;
344 subFieldIds_[fd] = rowIndexers_[indexerIds_[fd]]->getFieldNum(fieldName);
348 num_nodes = scatterFields_[0].extent(1);
352 template<
typename TRAITS,
typename LO,
typename GO>
359 using Teuchos::rcp_dynamic_cast;
364 = Teuchos::rcp_dynamic_cast<BLOC>(d.gedc->getDataObject(
"Dirichlet Counter"),
true);
370 Teuchos::RCP<const BLOC> blockedContainer = Teuchos::rcp_dynamic_cast<
const BLOC>(d.gedc->getDataObject(globalDataKey_));
371 Teuchos::RCP<const ELOC> epetraContainer = Teuchos::rcp_dynamic_cast<
const ELOC>(d.gedc->getDataObject(globalDataKey_));
374 if(blockedContainer!=Teuchos::null)
376 rcp_dynamic_cast<ProductVectorBase<double> >(blockedContainer->get_f(),
true) :
377 rcp_dynamic_cast<ProductVectorBase<double> >(blockedContainer->get_x(),
true);
378 else if(epetraContainer!=Teuchos::null)
380 Thyra::castOrCreateNonconstProductVectorBase<double>(epetraContainer->get_f_th()) :
381 Thyra::castOrCreateNonconstProductVectorBase<double>(epetraContainer->get_x_th());
387 template<
typename TRAITS,
typename LO,
typename GO>
395 using Teuchos::ptrFromRef;
396 using Teuchos::rcp_dynamic_cast;
399 using Thyra::SpmdVectorBase;
403 std::string blockId = this->wda(workset).block_id;
404 const std::vector<std::size_t> & localCellIds = this->wda(workset).cell_local_ids;
414 for(std::size_t fieldIndex = 0; fieldIndex < scatterFields_.size(); fieldIndex++) {
415 int rowIndexer = indexerIds_[fieldIndex];
416 int subFieldNum = subFieldIds_[fieldIndex];
418 rcp_dynamic_cast<SpmdVectorBase<double> >(dirichletCounter_->getNonconstVectorBlock(rowIndexer))
419 ->getNonconstLocalData(ptrFromRef(local_dc));
422 rcp_dynamic_cast<SpmdVectorBase<double> >(r_->getNonconstVectorBlock(rowIndexer))
423 ->getNonconstLocalData(ptrFromRef(local_r));
425 auto subRowIndexer = rowIndexers_[rowIndexer];
427 auto LIDs = subRowIndexer->getLIDs();
428 auto LIDs_h = Kokkos::create_mirror_view(LIDs);
429 Kokkos::deep_copy(LIDs_h, LIDs);
431 auto field = scatterFields_[fieldIndex].get_view();
432 auto field_h = Kokkos::create_mirror_view(
field);
433 Kokkos::deep_copy(field_h,
field);
435 BCFieldType::array_type::HostMirror applyBC_h;
437 auto applyBC = applyBC_[fieldIndex].get_static_view();
438 applyBC_h = Kokkos::create_mirror_view(applyBC);
439 Kokkos::deep_copy(applyBC_h, applyBC);
443 for(std::size_t worksetCellIndex=0;worksetCellIndex<localCellIds.size();++worksetCellIndex) {
444 std::size_t cellLocalId = localCellIds[worksetCellIndex];
448 const std::pair<std::vector<int>,std::vector<int> > & indicePair
449 = subRowIndexer->getGIDFieldOffsets_closure(blockId,subFieldNum, side_subcell_dim_, local_side_id_);
450 const std::vector<int> & elmtOffset = indicePair.first;
451 const std::vector<int> & basisIdMap = indicePair.second;
454 for(std::size_t basis=0;basis<elmtOffset.size();basis++) {
455 int offset = elmtOffset[basis];
456 int lid = LIDs_h(cellLocalId, offset);
460 int basisId = basisIdMap[basis];
462 if (checkApplyBC_ and !applyBC_h(worksetCellIndex,basisId))
465 local_r[lid] = field_h(worksetCellIndex,basisId).val();
472 const std::vector<int> & elmtOffset = subRowIndexer->getGIDFieldOffsets(blockId,subFieldNum);
475 for(std::size_t basis=0;basis<elmtOffset.size();basis++) {
476 int offset = elmtOffset[basis];
477 int lid = LIDs_h(cellLocalId, offset);
481 local_r[lid] = field_h(worksetCellIndex,basis).val();
495 template<
typename TRAITS,
typename LO,
typename GO>
501 : rowIndexers_(rIndexers)
502 , colIndexers_(cIndexers)
503 , globalDataKey_(
"Residual Scatter Container")
505 std::string scatterName = p.
get<std::string>(
"Scatter Name");
510 const std::vector<std::string>& names =
519 side_subcell_dim_ = p.
get<
int>(
"Side Subcell Dimension");
520 local_side_id_ = p.
get<
int>(
"Local Side ID");
523 scatterFields_.resize(names.size());
524 for (std::size_t eq = 0; eq < names.size(); ++eq) {
528 this->addDependentField(scatterFields_[eq]);
531 checkApplyBC_ = p.
get<
bool>(
"Check Apply BC");
533 applyBC_.resize(names.size());
534 for (std::size_t eq = 0; eq < names.size(); ++eq) {
536 this->addDependentField(applyBC_[eq]);
541 this->addEvaluatedField(*scatterHolder_);
543 if (p.
isType<std::string>(
"Global Data Key"))
544 globalDataKey_ = p.
get<std::string>(
"Global Data Key");
546 if(colIndexers_.size()==0)
547 colIndexers_ = rowIndexers_;
549 this->setName(scatterName+
" Scatter Residual (Jacobian)");
553 template<
typename TRAITS,
typename LO,
typename GO>
558 indexerIds_.resize(scatterFields_.size());
559 subFieldIds_.resize(scatterFields_.size());
562 for(std::size_t fd=0;fd<scatterFields_.size();++fd) {
564 std::string fieldName = fieldMap_->find(scatterFields_[fd].fieldTag().name())->second;
567 subFieldIds_[fd] = rowIndexers_[indexerIds_[fd]]->getFieldNum(fieldName);
571 num_nodes = scatterFields_[0].extent(1);
572 num_eq = scatterFields_.size();
576 template<
typename TRAITS,
typename LO,
typename GO>
582 using Teuchos::rcp_dynamic_cast;
586 = rcp_dynamic_cast<
const BLOC>(d.gedc->getDataObject(
"Dirichlet Counter"),
true);
592 blockContainer = rcp_dynamic_cast<
const BLOC>(d.gedc->getDataObject(globalDataKey_),
true);
600 template<
typename TRAITS,
typename LO,
typename GO>
606 using Teuchos::ptrFromRef;
607 using Teuchos::rcp_dynamic_cast;
609 using Thyra::SpmdVectorBase;
612 std::string blockId = this->wda(workset).block_id;
613 const std::vector<std::size_t> & localCellIds = this->wda(workset).cell_local_ids;
615 int numFieldBlocks = Teuchos::as<int>(colIndexers_.size());
617 std::vector<int> blockOffsets;
627 for(std::size_t fieldIndex = 0; fieldIndex < scatterFields_.size(); fieldIndex++) {
628 int rowIndexer = indexerIds_[fieldIndex];
629 int subFieldNum = subFieldIds_[fieldIndex];
633 rcp_dynamic_cast<SpmdVectorBase<double> >(dirichletCounter_->getNonconstVectorBlock(rowIndexer))
634 ->getNonconstLocalData(ptrFromRef(local_dc));
638 if(r_!=Teuchos::null)
639 rcp_dynamic_cast<SpmdVectorBase<double> >(r_->getNonconstVectorBlock(rowIndexer))
640 ->getNonconstLocalData(ptrFromRef(local_r));
642 auto subRowIndexer = rowIndexers_[rowIndexer];
643 auto subIndicePair = subRowIndexer->getGIDFieldOffsets_closure(blockId,subFieldNum, side_subcell_dim_, local_side_id_);
644 const std::vector<int> & subElmtOffset = subIndicePair.first;
645 const std::vector<int> & subBasisIdMap = subIndicePair.second;
647 auto rLIDs = subRowIndexer->getLIDs();
648 auto rLIDs_h = Kokkos::create_mirror_view(rLIDs);
649 Kokkos::deep_copy(rLIDs_h, rLIDs);
651 auto field = scatterFields_[fieldIndex].get_view();
652 auto field_h = Kokkos::create_mirror_view(
field);
653 Kokkos::deep_copy(field_h,
field);
655 BCFieldType::array_type::HostMirror applyBC_h;
657 auto applyBC = applyBC_[fieldIndex].get_static_view();
658 applyBC_h = Kokkos::create_mirror_view(applyBC);
659 Kokkos::deep_copy(applyBC_h, applyBC);
663 for(std::size_t worksetCellIndex=0;worksetCellIndex<localCellIds.size();++worksetCellIndex) {
664 std::size_t cellLocalId = localCellIds[worksetCellIndex];
667 for(std::size_t basis=0;basis<subElmtOffset.size();basis++) {
668 int offset = subElmtOffset[basis];
669 int lid = rLIDs_h(cellLocalId, offset);
673 int basisId = subBasisIdMap[basis];
675 if (checkApplyBC_ and !applyBC_h(worksetCellIndex,basisId))
679 for(
int colIndexer=0;colIndexer<numFieldBlocks;colIndexer++) {
680 int start = blockOffsets[colIndexer];
681 int end = blockOffsets[colIndexer+1];
687 std::pair<int,int> blockIndex = std::make_pair(rowIndexer,colIndexer);
688 Teuchos::RCP<Epetra_CrsMatrix> subJac = jacEpetraBlocks[blockIndex];
690 if(subJac==Teuchos::null) {
699 jacEpetraBlocks[blockIndex] = subJac;
703 int * rowIndices = 0;
704 double * rowValues = 0;
708 for(
int i=0;i<numEntries;i++)
712 const ScalarT scatterField = field_h(worksetCellIndex,basisId);
714 if(r_!=Teuchos::null)
715 local_r[lid] = scatterField.val();
719 std::vector<double> jacRow(scatterField.size(),0.0);
721 for(
int sensIndex=0;sensIndex<scatterField.size();++sensIndex)
722 jacRow[sensIndex] = scatterField.fastAccessDx(sensIndex);
724 for(
int colIndexer=0;colIndexer<numFieldBlocks;colIndexer++) {
725 int start = blockOffsets[colIndexer];
726 int end = blockOffsets[colIndexer+1];
731 auto subColIndexer = colIndexers_[colIndexer];
733 auto cLIDs = subColIndexer->getElementLIDs(cellLocalId);
734 auto cLIDs_h = Kokkos::create_mirror_view(cLIDs);
735 Kokkos::deep_copy(cLIDs_h, cLIDs);
740 std::pair<int,int> blockIndex = std::make_pair(rowIndexer,colIndexer);
741 Teuchos::RCP<Epetra_CrsMatrix> subJac = jacEpetraBlocks[blockIndex];
744 if(subJac==Teuchos::null) {
753 jacEpetraBlocks[blockIndex] = subJac;
757 int err = subJac->
ReplaceMyValues(lid, end-start, &jacRow[start],&cLIDs_h[0]);
759 std::stringstream ss;
760 ss <<
"Failed inserting row: " <<
" (" << lid <<
"): ";
761 for(
int i=0;i<end-start;i++)
762 ss << cLIDs_h[i] <<
" ";
764 ss <<
"Into block " << rowIndexer <<
", " << colIndexer << std::endl;
766 ss <<
"scatter field = ";
767 scatterFields_[fieldIndex].print(ss);
T & get(const std::string &name, T def_value)
bool is_null(const std::shared_ptr< T > &p)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
void postRegistrationSetup(typename TRAITS::SetupData d, PHX::FieldManager< TRAITS > &vm)
void computeBlockOffsets(const std::string &blockId, const std::vector< Teuchos::RCP< GlobalIndexer >> &ugis, std::vector< int > &blockOffsets)
int ExtractMyRowView(int MyRow, int &NumEntries, double *&Values, int *&Indices) const
bool isParameter(const std::string &name) const
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
void evaluateFields(typename TRAITS::EvalData d)
int getFieldBlock(const std::string &fieldName, const std::vector< Teuchos::RCP< const GlobalIndexer >> &ugis)
ScatterDirichletResidual_BlockedEpetra(const Teuchos::ParameterList &p)
virtual void preEvaluate(typename Traits::PreEvalData d)=0
panzer::Traits::Jacobian::ScalarT ScalarT
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)
int ReplaceMyValues(int MyRow, int NumEntries, const double *Values, const int *Indices)