11 #ifndef PANZER_SCATTER_DIRICHLET_RESIDUAL_EPETRA_IMPL_HPP
12 #define PANZER_SCATTER_DIRICHLET_RESIDUAL_EPETRA_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 "Teuchos_FancyOStream.hpp"
39 template<
typename TRAITS,
typename LO,
typename GO>
44 : globalIndexer_(indexer)
45 , globalDataKey_(
"Residual Scatter Container")
47 std::string scatterName = p.
get<std::string>(
"Scatter Name");
52 const std::vector<std::string>& names =
59 scatterIC_ = p.
isParameter(
"Scatter Initial Condition") ? p.
get<
bool>(
"Scatter Initial Condition") :
false;
65 side_subcell_dim_ = p.
get<
int>(
"Side Subcell Dimension");
66 local_side_id_ = p.
get<
int>(
"Local Side ID");
70 scatterFields_.resize(names.size());
71 for (std::size_t eq = 0; eq < names.size(); ++eq) {
75 this->addDependentField(scatterFields_[eq]);
78 checkApplyBC_ = p.
isParameter(
"Check Apply BC") ? p.
get<
bool>(
"Check Apply BC") :
false;
80 applyBC_.resize(names.size());
81 for (std::size_t eq = 0; eq < names.size(); ++eq) {
83 this->addDependentField(applyBC_[eq]);
88 this->addEvaluatedField(*scatterHolder_);
90 if (p.
isType<std::string>(
"Global Data Key"))
91 globalDataKey_ = p.
get<std::string>(
"Global Data Key");
93 this->setName(scatterName+
" Scatter Residual");
97 template<
typename TRAITS,
typename LO,
typename GO>
102 fieldIds_.resize(scatterFields_.size());
105 for(std::size_t fd=0;fd<scatterFields_.size();++fd) {
107 std::string fieldName = fieldMap_->find(scatterFields_[fd].fieldTag().name())->second;
108 fieldIds_[fd] = globalIndexer_->getFieldNum(fieldName);
112 num_nodes = scatterFields_[0].extent(1);
116 template<
typename TRAITS,
typename LO,
typename GO>
123 if(epetraContainer_==Teuchos::null) {
128 dirichletCounter_ = Teuchos::null;
135 dirichletCounter_ = epetraContainer->
get_f();
141 template<
typename TRAITS,
typename LO,
typename GO>
146 std::string blockId = this->wda(workset).block_id;
147 const std::vector<std::size_t> & localCellIds = this->wda(workset).cell_local_ids;
151 epetraContainer->
get_f() :
152 epetraContainer->
get_x();
159 auto LIDs = globalIndexer_->getLIDs();
160 auto LIDs_h = Kokkos::create_mirror_view(LIDs);
161 Kokkos::deep_copy(LIDs_h, LIDs);
165 for(std::size_t fieldIndex = 0; fieldIndex < scatterFields_.size(); fieldIndex++) {
166 int fieldNum = fieldIds_[fieldIndex];
167 auto field = PHX::as_view(scatterFields_[fieldIndex]);
168 auto field_h = Kokkos::create_mirror_view(
field);
169 Kokkos::deep_copy(field_h,
field);
171 for(std::size_t worksetCellIndex=0;worksetCellIndex<localCellIds.size();++worksetCellIndex) {
172 std::size_t cellLocalId = localCellIds[worksetCellIndex];
176 const std::pair<std::vector<int>,std::vector<int> > & indicePair
177 = globalIndexer_->getGIDFieldOffsets_closure(blockId,fieldNum, side_subcell_dim_, local_side_id_);
178 const std::vector<int> & elmtOffset = indicePair.first;
179 const std::vector<int> & basisIdMap = indicePair.second;
182 for(std::size_t basis=0;basis<elmtOffset.size();basis++) {
183 int offset = elmtOffset[basis];
184 int lid = LIDs_h(cellLocalId, offset);
188 int basisId = basisIdMap[basis];
191 if (!applyBC_[fieldIndex](worksetCellIndex,basisId))
194 (*r)[lid] = field_h(worksetCellIndex,basisId);
197 if(dirichletCounter_!=Teuchos::null)
198 (*dirichletCounter_)[lid] = 1.0;
202 const std::vector<int> & elmtOffset = globalIndexer_->getGIDFieldOffsets(blockId,fieldNum);
205 for(std::size_t basis=0;basis<elmtOffset.size();basis++) {
206 int offset = elmtOffset[basis];
207 int lid = LIDs_h(cellLocalId, offset);
211 (*r)[lid] = field_h(worksetCellIndex,basis);
214 if(dirichletCounter_!=Teuchos::null)
215 (*dirichletCounter_)[lid] = 1.0;
227 template<
typename TRAITS,
typename LO,
typename GO>
232 : globalIndexer_(indexer)
233 , globalDataKey_(
"Residual Scatter Container")
235 std::string scatterName = p.
get<std::string>(
"Scatter Name");
240 const std::vector<std::string>& names =
247 scatterIC_ = p.
isParameter(
"Scatter Initial Condition") ? p.
get<
bool>(
"Scatter Initial Condition") :
false;
253 side_subcell_dim_ = p.
get<
int>(
"Side Subcell Dimension");
254 local_side_id_ = p.
get<
int>(
"Local Side ID");
258 scatterFields_.resize(names.size());
259 for (std::size_t eq = 0; eq < names.size(); ++eq) {
263 this->addDependentField(scatterFields_[eq]);
266 checkApplyBC_ = p.
isParameter(
"Check Apply BC") ? p.
get<
bool>(
"Check Apply BC") :
false;
268 applyBC_.resize(names.size());
269 for (std::size_t eq = 0; eq < names.size(); ++eq) {
271 this->addDependentField(applyBC_[eq]);
276 this->addEvaluatedField(*scatterHolder_);
278 if (p.
isType<std::string>(
"Global Data Key"))
279 globalDataKey_ = p.
get<std::string>(
"Global Data Key");
281 this->setName(scatterName+
" Scatter Tangent");
285 template<
typename TRAITS,
typename LO,
typename GO>
290 fieldIds_.resize(scatterFields_.size());
293 for(std::size_t fd=0;fd<scatterFields_.size();++fd) {
295 std::string fieldName = fieldMap_->find(scatterFields_[fd].fieldTag().name())->second;
296 fieldIds_[fd] = globalIndexer_->getFieldNum(fieldName);
300 num_nodes = scatterFields_[0].extent(1);
304 template<
typename TRAITS,
typename LO,
typename GO>
311 if(epetraContainer_==Teuchos::null) {
316 dirichletCounter_ = Teuchos::null;
323 dirichletCounter_ = epetraContainer->
get_f();
328 using Teuchos::rcp_dynamic_cast;
331 std::vector<std::string> activeParameters =
336 dfdp_vectors_.clear();
337 for(std::size_t i=0;i<activeParameters.size();i++) {
339 dfdp_vectors_.push_back(vec);
344 template<
typename TRAITS,
typename LO,
typename GO>
349 std::string blockId = this->wda(workset).block_id;
350 const std::vector<std::size_t> & localCellIds = this->wda(workset).cell_local_ids;
354 epetraContainer->
get_f() :
355 epetraContainer->
get_x();
362 auto LIDs = globalIndexer_->getLIDs();
363 auto LIDs_h = Kokkos::create_mirror_view(LIDs);
364 Kokkos::deep_copy(LIDs_h, LIDs);
365 for(std::size_t fieldIndex = 0; fieldIndex < scatterFields_.size(); fieldIndex++) {
366 int fieldNum = fieldIds_[fieldIndex];
367 auto scatterField_h = Kokkos::create_mirror_view(scatterFields_[fieldIndex].get_static_view());
368 Kokkos::deep_copy(scatterField_h, scatterFields_[fieldIndex].get_static_view());
371 for(std::size_t worksetCellIndex=0;worksetCellIndex<localCellIds.size();++worksetCellIndex) {
372 std::size_t cellLocalId = localCellIds[worksetCellIndex];
376 const std::pair<std::vector<int>,std::vector<int> > & indicePair
377 = globalIndexer_->getGIDFieldOffsets_closure(blockId,fieldNum, side_subcell_dim_, local_side_id_);
378 const std::vector<int> & elmtOffset = indicePair.first;
379 const std::vector<int> & basisIdMap = indicePair.second;
382 for(std::size_t basis=0;basis<elmtOffset.size();basis++) {
383 int offset = elmtOffset[basis];
384 int lid = LIDs_h(cellLocalId, offset);
388 int basisId = basisIdMap[basis];
391 if (!applyBC_[fieldIndex](worksetCellIndex,basisId))
394 ScalarT value = scatterField_h(worksetCellIndex,basisId);
399 for(std::size_t d=0;d<dfdp_vectors_.size();d++)
400 (*dfdp_vectors_[d])[lid] = 0.0;
402 for(
int d=0;d<value.size();d++) {
403 (*dfdp_vectors_[d])[lid] = value.fastAccessDx(d);
407 if(dirichletCounter_!=Teuchos::null)
408 (*dirichletCounter_)[lid] = 1.0;
412 const std::vector<int> & elmtOffset = globalIndexer_->getGIDFieldOffsets(blockId,fieldNum);
415 for(std::size_t basis=0;basis<elmtOffset.size();basis++) {
416 int offset = elmtOffset[basis];
417 int lid = LIDs_h(cellLocalId, offset);
421 ScalarT value = scatterField_h(worksetCellIndex,basis);
426 for(std::size_t d=0;d<dfdp_vectors_.size();d++)
427 (*dfdp_vectors_[d])[lid] = 0.0;
429 for(
int d=0;d<value.size();d++) {
430 (*dfdp_vectors_[d])[lid] = value.fastAccessDx(d);
434 if(dirichletCounter_!=Teuchos::null)
435 (*dirichletCounter_)[lid] = 1.0;
446 template<
typename TRAITS,
typename LO,
typename GO>
451 : globalIndexer_(indexer)
452 , colGlobalIndexer_(cIndexer)
453 , globalDataKey_(
"Residual Scatter Container")
454 , preserveDiagonal_(false)
456 std::string scatterName = p.
get<std::string>(
"Scatter Name");
461 const std::vector<std::string>& names =
470 side_subcell_dim_ = p.
get<
int>(
"Side Subcell Dimension");
471 local_side_id_ = p.
get<
int>(
"Local Side ID");
474 scatterFields_.resize(names.size());
475 for (std::size_t eq = 0; eq < names.size(); ++eq) {
479 this->addDependentField(scatterFields_[eq]);
482 checkApplyBC_ = p.
get<
bool>(
"Check Apply BC");
484 applyBC_.resize(names.size());
485 for (std::size_t eq = 0; eq < names.size(); ++eq) {
487 this->addDependentField(applyBC_[eq]);
492 this->addEvaluatedField(*scatterHolder_);
494 if (p.
isType<std::string>(
"Global Data Key"))
495 globalDataKey_ = p.
get<std::string>(
"Global Data Key");
497 if (p.
isType<
bool>(
"Preserve Diagonal"))
498 preserveDiagonal_ = p.
get<
bool>(
"Preserve Diagonal");
500 this->setName(scatterName+
" Scatter Residual (Jacobian)");
504 template<
typename TRAITS,
typename LO,
typename GO>
509 fieldIds_.resize(scatterFields_.size());
512 for(std::size_t fd=0;fd<scatterFields_.size();++fd) {
514 std::string fieldName = fieldMap_->find(scatterFields_[fd].fieldTag().name())->second;
515 fieldIds_[fd] = globalIndexer_->getFieldNum(fieldName);
519 num_nodes = scatterFields_[0].extent(1);
520 num_eq = scatterFields_.size();
524 template<
typename TRAITS,
typename LO,
typename GO>
531 if(epetraContainer_==Teuchos::null) {
536 dirichletCounter_ = Teuchos::null;
543 dirichletCounter_ = epetraContainer->
get_f();
549 template<
typename TRAITS,
typename LO,
typename GO>
555 bool useColumnIndexer = colGlobalIndexer_!=Teuchos::null;
557 colGlobalIndexer = useColumnIndexer ? colGlobalIndexer_ : globalIndexer_;
560 std::string blockId = this->wda(workset).block_id;
561 const std::vector<std::size_t> & localCellIds = this->wda(workset).cell_local_ids;
574 auto LIDs = globalIndexer_->getLIDs();
575 auto colLIDs = colGlobalIndexer->
getLIDs();
576 auto LIDs_h = Kokkos::create_mirror_view(LIDs);
577 auto colLIDs_h = Kokkos::create_mirror_view(colLIDs);
578 Kokkos::deep_copy(LIDs_h, LIDs);
579 Kokkos::deep_copy(colLIDs_h, colLIDs);
581 std::vector<
typename decltype(scatterFields_[0].get_static_view())::HostMirror> scatterFields_h;
582 for ( std::size_t i=0; i< scatterFields_.size(); ++i) {
583 scatterFields_h.push_back(Kokkos::create_mirror_view(scatterFields_[i].get_static_view()));
584 Kokkos::deep_copy(scatterFields_h[i], scatterFields_[i].get_static_view());
587 for(std::size_t worksetCellIndex=0;worksetCellIndex<localCellIds.size();++worksetCellIndex) {
588 std::size_t cellLocalId = localCellIds[worksetCellIndex];
593 for(std::size_t fieldIndex = 0; fieldIndex < scatterFields_.size(); fieldIndex++) {
594 int fieldNum = fieldIds_[fieldIndex];
597 const std::pair<std::vector<int>,std::vector<int> > & indicePair
598 = globalIndexer_->getGIDFieldOffsets_closure(blockId,fieldNum, side_subcell_dim_, local_side_id_);
599 const std::vector<int> & elmtOffset = indicePair.first;
600 const std::vector<int> & basisIdMap = indicePair.second;
603 for(std::size_t basis=0;basis<elmtOffset.size();basis++) {
604 int offset = elmtOffset[basis];
605 int row = LIDs_h(cellLocalId, offset);
609 int basisId = basisIdMap[basis];
612 if (!applyBC_[fieldIndex](worksetCellIndex,basisId))
618 int * rowIndices = 0;
619 double * rowValues = 0;
623 for(
int i=0;i<numEntries;i++) {
624 if(preserveDiagonal_) {
625 if(row!=rowIndices[i])
634 const ScalarT scatterField = (scatterFields_h[fieldIndex])(worksetCellIndex,basisId);
637 (*r)[row] = scatterField.val();
638 if(dirichletCounter_!=Teuchos::null) {
640 (*dirichletCounter_)[row] = 1.0;
644 std::vector<double> jacRow(scatterField.size(),0.0);
646 if(!preserveDiagonal_) {
648 &colLIDs_h(cellLocalId,0));
panzer::Traits::Tangent::ScalarT ScalarT
const Teuchos::RCP< Epetra_Vector > get_x() const
T & get(const std::string &name, T def_value)
bool is_null(const std::shared_ptr< T > &p)
virtual int getElementBlockGIDCount(const std::size_t &blockIndex) const =0
How any GIDs are associate with each element in a particular element block.
const Kokkos::View< const panzer::LocalOrdinal **, Kokkos::LayoutRight, PHX::Device > getLIDs() const
const Teuchos::RCP< Epetra_CrsMatrix > get_A() const
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)
panzer::Traits::Jacobian::ScalarT ScalarT
const Teuchos::RCP< Epetra_Vector > get_f() const
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)
Pushes residual values into the residual vector for a Newton-based solve.