14#include "Teuchos_FancyOStream.hpp"
15#include "Teuchos_ArrayView.hpp"
16#include "Teuchos_CommHelpers.hpp"
18#include "Tpetra_Map.hpp"
19#include "Tpetra_Vector.hpp"
20#include "Tpetra_Import.hpp"
22#include "Kokkos_DynRankView.hpp"
29template <
typename ScalarT,
typename ArrayT>
32 const ArrayT & data,Tpetra::MultiVector<ScalarT,int,panzer::GlobalOrdinal,panzer::TpetraNodeType> & dataVector)
34 typedef Tpetra::Map<int,panzer::GlobalOrdinal,panzer::TpetraNodeType> Map;
36 TEUCHOS_TEST_FOR_EXCEPTION(!ugi.
fieldInBlock(fieldName,blockId),std::runtime_error,
37 "panzer::updateGhostedDataReducedVector: field name = \""+fieldName+
"\" is not in element block = \"" +blockId +
"\"!");
39 Teuchos::RCP<const Map> dataMap = dataVector.getMap();
42 const std::vector<panzer::LocalOrdinal> & elements = ugi.
getElementBlock(blockId);
45 TEUCHOS_TEST_FOR_EXCEPTION(data.extent(0)!=elements.size(),std::runtime_error,
46 "panzer::updateGhostedDataReducedVector: data cell dimension does not match up with block cell count");
48 int rank = data.rank();
49 auto dataVector_host = dataVector.getLocalViewHost(Tpetra::Access::ReadWrite);
50 auto data_host = Kokkos::create_mirror_view(data);
51 Kokkos::deep_copy(data_host,data);
55 std::vector<panzer::GlobalOrdinal> gids;
56 for(std::size_t e=0;e<elements.size();e++) {
59 for(std::size_t f=0;f<fieldOffsets.size();f++) {
60 std::size_t localIndex = dataMap->getLocalElement(gids[fieldOffsets[f]]);
61 dataVector_host(localIndex,0) = data_host(e,f);
66 std::size_t entries = data.extent(2);
68 TEUCHOS_TEST_FOR_EXCEPTION(dataVector.getNumVectors()!=entries,std::runtime_error,
69 "panzer::updateGhostedDataReducedVector: number of columns in data vector inconsistent with data array");
72 std::vector<panzer::GlobalOrdinal> gids;
73 for(std::size_t e=0;e<elements.size();e++) {
76 for(std::size_t f=0;f<fieldOffsets.size();f++) {
77 std::size_t localIndex = dataMap->getLocalElement(gids[fieldOffsets[f]]);
78 for(std::size_t v=0;v<entries;v++)
79 dataVector_host(localIndex,v) = data_host(e,f,v);
84 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::runtime_error,
85 "panzer::updateGhostedDataReducedVector: data array rank must be 2 or 3");
88template <
typename ScalarT,
typename ArrayT>
89Teuchos::RCP<Tpetra::MultiVector<ScalarT,int,panzer::GlobalOrdinal,panzer::TpetraNodeType> >
92 TEUCHOS_ASSERT(data.size()>0);
94 int fieldNum =
ugi_->getFieldNum(fieldName);
95 std::vector<std::string> blockIds;
96 ugi_->getElementBlockIds(blockIds);
99 int rank = data.begin()->second.rank();
104 numCols = data.begin()->second.extent(2);
106 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::runtime_error,
107 "ArrayToFieldVector::getGhostedDataVector: data array must have rank 2 or 3. This array has rank " << rank <<
".");
121 Teuchos::RCP<Tpetra::MultiVector<ScalarT,int,panzer::GlobalOrdinal,panzer::TpetraNodeType> > finalReducedVec
122 = Teuchos::rcp(
new Tpetra::MultiVector<ScalarT,int,panzer::GlobalOrdinal,panzer::TpetraNodeType>(reducedMap,numCols));
123 for(std::size_t b=0;b<blockIds.size();b++) {
124 std::string block = blockIds[b];
127 if(!
ugi_->fieldInBlock(fieldName,block))
131 typename std::map<std::string,ArrayT>::const_iterator blockItr = data.find(block);
132 TEUCHOS_TEST_FOR_EXCEPTION(blockItr==data.end(),std::runtime_error,
133 "ArrayToFieldVector::getDataVector: can not find block \""+block+
"\".");
135 const ArrayT & d = blockItr->second;
136 updateGhostedDataReducedVector<ScalarT,ArrayT>(fieldName,block,*
ugi_,d,*finalReducedVec);
148 Teuchos::RCP<Tpetra::MultiVector<ScalarT,int,panzer::GlobalOrdinal,panzer::TpetraNodeType> > finalVec
149 = Teuchos::rcp(
new Tpetra::MultiVector<ScalarT,int,panzer::GlobalOrdinal,panzer::TpetraNodeType>(map,numCols));
152 Tpetra::Import<int,panzer::GlobalOrdinal,panzer::TpetraNodeType> importer(reducedMap,map);
153 finalVec->doImport(*finalReducedVec,importer,Tpetra::INSERT);
154 PHX::Device::execution_space().fence();
159template <
typename ScalarT,
typename ArrayT>
160Teuchos::RCP<Tpetra::MultiVector<ScalarT,int,panzer::GlobalOrdinal,panzer::TpetraNodeType> >
167 Teuchos::RCP<const Tpetra::MultiVector<ScalarT,int,panzer::GlobalOrdinal,panzer::TpetraNodeType> > sourceVec
168 = getGhostedDataVector<ScalarT,ArrayT>(fieldName,data);
171 int fieldNum =
ugi_->getFieldNum(fieldName);
172 Teuchos::RCP<const Map> destMap =
fieldMaps_[fieldNum];
178 Teuchos::RCP<Tpetra::MultiVector<ScalarT,int,panzer::GlobalOrdinal,panzer::TpetraNodeType> > destVec
179 = Teuchos::rcp(
new Tpetra::MultiVector<ScalarT,int,panzer::GlobalOrdinal,panzer::TpetraNodeType>(destMap,sourceVec->getNumVectors()));
182 Tpetra::Import<int,panzer::GlobalOrdinal,panzer::TpetraNodeType> importer(sourceVec->getMap(),destMap);
183 destVec->doImport(*sourceVec,importer,Tpetra::INSERT);
184 PHX::Device::execution_space().fence();
Teuchos::RCP< Tpetra::MultiVector< ScalarT, int, panzer::GlobalOrdinal, panzer::TpetraNodeType > > getGhostedDataVector(const std::string &fieldName, const std::map< std::string, ArrayT > &data) const
Teuchos::RCP< const GlobalIndexer > ugi_
DOF mapping.
std::map< int, Teuchos::RCP< const Map > > fieldMaps_
(unghosted) field vector (as needed)
Teuchos::RCP< const IntVector > gh_reducedFieldVector_
std::map< int, Teuchos::RCP< const Map > > gh_fieldMaps_
Maps for each field (as needed)
Teuchos::RCP< const IntVector > gh_fieldVector_
ghosted reduced field vector
std::map< int, Teuchos::RCP< const Map > > gh_reducedFieldMaps_
ghosted field vector
Teuchos::RCP< const IntVector > fieldVector_
Maps for each field (as needed)
Teuchos::RCP< Tpetra::MultiVector< ScalarT, int, panzer::GlobalOrdinal, panzer::TpetraNodeType > > getDataVector(const std::string &fieldName, const std::map< std::string, ArrayT > &data) const
void buildFieldVector(const Tpetra::Vector< int, int, panzer::GlobalOrdinal, panzer::TpetraNodeType > &source) const
build unghosted field vector from ghosted field vector
virtual const std::vector< panzer::LocalOrdinal > & getElementBlock(const std::string &blockId) const =0
virtual const std::vector< int > & getGIDFieldOffsets(const std::string &blockId, int fieldNum) const =0
Use the field pattern so that you can find a particular field in the GIDs array.
virtual void getElementGIDs(panzer::LocalOrdinal localElmtId, std::vector< panzer::GlobalOrdinal > &gids, const std::string &blockIdHint="") const =0
Get the global IDs for a particular element. This function overwrites the gids variable.
virtual int getFieldNum(const std::string &str) const =0
Get the number used for access to this field.
virtual bool fieldInBlock(const std::string &field, const std::string &block) const =0
Teuchos::RCP< const Tpetra::Map< int, panzer::GlobalOrdinal, panzer::TpetraNodeType > > getFieldMap(int fieldNum, const Tpetra::Vector< int, int, panzer::GlobalOrdinal, panzer::TpetraNodeType > &fieldTVector)
void updateGhostedDataReducedVector(const std::string &fieldName, const std::string blockId, const GlobalIndexer &ugi, const ArrayT &data, Tpetra::MultiVector< ScalarT, int, panzer::GlobalOrdinal, panzer::TpetraNodeType > &dataVector)