Panzer Version of the Day
Loading...
Searching...
No Matches
Panzer_GlobalIndexer_EpetraUtilities_impl.hpp
Go to the documentation of this file.
1// @HEADER
2// *****************************************************************************
3// Panzer: A partial differential equation assembly
4// engine for strongly coupled complex multiphysics systems
5//
6// Copyright 2011 NTESS and the Panzer contributors.
7// SPDX-License-Identifier: BSD-3-Clause
8// *****************************************************************************
9// @HEADER
10
11#ifndef PANZER_UNIQUEGLOBALINDEXER_EPETRAUTILITIES_IMPL_HPP
12#define PANZER_UNIQUEGLOBALINDEXER_EPETRAUTILITIES_IMPL_HPP
13
14#include <vector>
15#include <map>
16
17#include "Teuchos_FancyOStream.hpp"
18#include "Teuchos_ArrayView.hpp"
19#include "Teuchos_CommHelpers.hpp"
20
21#include "Epetra_Map.h"
22#include "Epetra_IntVector.h"
23#include "Epetra_MultiVector.h"
24#include "Epetra_Import.h"
25#include "Epetra_MpiComm.h"
26
27#include "Epetra_CombineMode.h"
28#include "Epetra_DataAccess.h"
29
30#include <sstream>
31#include <cmath>
32
33namespace panzer {
34
35template <typename ScalarT,typename ArrayT>
36void updateGhostedDataReducedVectorEpetra(const std::string & fieldName,const std::string blockId,
37 const GlobalIndexer & ugi,
38 const ArrayT & data,Epetra_MultiVector & dataVector)
39{
40 typedef Epetra_BlockMap Map;
41
42 TEUCHOS_TEST_FOR_EXCEPTION(!ugi.fieldInBlock(fieldName,blockId),std::runtime_error,
43 "panzer::updateGhostedDataReducedVector: field name = \""+fieldName+"\" is not in element block = \"" +blockId +"\"!");
44
45 Teuchos::RCP<const Map> dataMap = Teuchos::rcpFromRef(dataVector.Map());
46
47 int fieldNum = ugi.getFieldNum(fieldName);
48 const std::vector<panzer::LocalOrdinal> & elements = ugi.getElementBlock(blockId);
49 const std::vector<int> & fieldOffsets = ugi.getGIDFieldOffsets(blockId,fieldNum);
50
51 TEUCHOS_TEST_FOR_EXCEPTION(data.extent(0)!=elements.size(),std::runtime_error,
52 "panzer::updateGhostedDataReducedVector: data cell dimension does not match up with block cell count");
53
54 int rank = data.rank();
55
56 if(rank==2) {
57 // loop over elements distributing relevent data to vector
58 std::vector<panzer::GlobalOrdinal> gids;
59 for(std::size_t e=0;e<elements.size();e++) {
60 ugi.getElementGIDs(elements[e],gids);
61
62 for(std::size_t f=0;f<fieldOffsets.size();f++) {
63 std::size_t localIndex = dataMap->LID(gids[fieldOffsets[f]]); // hash table lookup
64 dataVector.ReplaceMyValue(localIndex,0,data(e,f));
65 }
66 }
67 }
68 else if(rank==3) {
69 std::size_t entries = data.extent(2);
70
71 TEUCHOS_TEST_FOR_EXCEPTION(dataVector.NumVectors()!=static_cast<int>(entries),std::runtime_error,
72 "panzer::updateGhostedDataReducedVector: number of columns in data vector inconsistent with data array");
73
74 // loop over elements distributing relevent data to vector
75 std::vector<panzer::GlobalOrdinal> gids;
76 for(std::size_t e=0;e<elements.size();e++) {
77 ugi.getElementGIDs(elements[e],gids);
78
79 for(std::size_t f=0;f<fieldOffsets.size();f++) {
80 std::size_t localIndex = dataMap->LID(gids[fieldOffsets[f]]); // hash table lookup
81 for(std::size_t v=0;v<entries;v++)
82 dataVector.ReplaceMyValue(localIndex,v,data(e,f,v));
83 }
84 }
85 }
86 else
87 TEUCHOS_TEST_FOR_EXCEPTION(true,std::runtime_error,
88 "panzer::updateGhostedDataReducedVector: data array rank must be 2 or 3");
89}
90
91template <typename ScalarT,typename ArrayT>
92Teuchos::RCP<Epetra_MultiVector>
94 const std::map<std::string,ArrayT> & data) const
95{
96 TEUCHOS_ASSERT(data.size()>0); // there must be at least one "data" item
97
98 int fieldNum = ugi_->getFieldNum(fieldName);
99 std::vector<std::string> blockIds;
100 ugi_->getElementBlockIds(blockIds);
101
102 // get rank of first data array, determine column count
103 int rank = data.begin()->second.rank();
104 int numCols = 0;
105 if(rank==2)
106 numCols = 1;
107 else if(rank==3)
108 numCols = data.begin()->second.extent(2);
109 else {
110 TEUCHOS_TEST_FOR_EXCEPTION(true,std::runtime_error,
111 "ArrayToFieldVectorEpetra::getGhostedDataVector: data array must have rank 2 or 3. This array has rank " << rank << ".");
112 }
113
114
115 // first build and fill in final reduced field vector
117
118 // build field maps as needed
119 Teuchos::RCP<const Map> reducedMap = gh_reducedFieldMaps_[fieldNum];
120 if(gh_reducedFieldMaps_[fieldNum]==Teuchos::null) {
122 gh_reducedFieldMaps_[fieldNum] = reducedMap;
123 }
124
125 Teuchos::RCP<MultiVector> finalReducedVec
126 = Teuchos::rcp(new MultiVector(*reducedMap,numCols));
127 for(std::size_t b=0;b<blockIds.size();b++) {
128 std::string block = blockIds[b];
129
130 // make sure field is in correct block
131 if(!ugi_->fieldInBlock(fieldName,block))
132 continue;
133
134 // extract data vector
135 typename std::map<std::string,ArrayT>::const_iterator blockItr = data.find(block);
136 TEUCHOS_TEST_FOR_EXCEPTION(blockItr==data.end(),std::runtime_error,
137 "ArrayToFieldVectorEpetra::getDataVector: can not find block \""+block+"\".");
138
139 const ArrayT & d = blockItr->second;
140 updateGhostedDataReducedVectorEpetra<ScalarT,ArrayT>(fieldName,block,*ugi_,d,*finalReducedVec);
141 }
142
143 // build final (not reduced vector)
145
146 Teuchos::RCP<const Map> map = gh_fieldMaps_[fieldNum];
147 if(gh_fieldMaps_[fieldNum]==Teuchos::null) {
149 gh_fieldMaps_[fieldNum] = map;
150 }
151
152 Teuchos::RCP<MultiVector> finalVec
153 = Teuchos::rcp(new MultiVector(*map,numCols));
154
155 // do import from finalReducedVec
156 Epetra_Import importer(*map,*reducedMap);
157 finalVec->Import(*finalReducedVec,importer,Insert);
158
159 return finalVec;
160}
161
162template <typename ScalarT,typename ArrayT>
163Teuchos::RCP<Epetra_MultiVector>
164ArrayToFieldVectorEpetra::getDataVector(const std::string & fieldName,
165 const std::map<std::string,ArrayT> & data) const
166{
167 // if neccessary build field vector
168 if(fieldVector_==Teuchos::null)
170
171 Teuchos::RCP<const MultiVector> sourceVec
172 = getGhostedDataVector<ScalarT,ArrayT>(fieldName,data);
173
174 // use lazy construction for each field
175 int fieldNum = ugi_->getFieldNum(fieldName);
176 Teuchos::RCP<const Map> destMap = fieldMaps_[fieldNum];
177 if(fieldMaps_[fieldNum]==Teuchos::null) {
178 destMap = panzer::getFieldMapEpetra(fieldNum,*fieldVector_);
179 fieldMaps_[fieldNum] = destMap;
180 }
181
182 Teuchos::RCP<MultiVector> destVec
183 = Teuchos::rcp(new MultiVector(*destMap,sourceVec->NumVectors()));
184
185 // do import
186 Epetra_Import importer(*destMap,sourceVec->Map());
187 destVec->Import(*sourceVec,importer,Insert);
188
189 return destVec;
190}
191
192} // end namspace panzer
193
194#endif
Insert
const Epetra_BlockMap & Map() const
int NumVectors() const
int ReplaceMyValue(int MyRow, int VectorIndex, double ScalarValue)
Teuchos::RCP< const GlobalIndexer > ugi_
DOF mapping.
std::map< int, Teuchos::RCP< const Map > > gh_reducedFieldMaps_
ghosted field vector
std::map< int, Teuchos::RCP< const Map > > gh_fieldMaps_
Maps for each field (as needed)
void buildFieldVector(const Epetra_IntVector &source) const
build unghosted field vector from ghosted field vector
Teuchos::RCP< const IntVector > gh_fieldVector_
ghosted reduced field vector
Teuchos::RCP< Epetra_MultiVector > getGhostedDataVector(const std::string &fieldName, const std::map< std::string, ArrayT > &data) const
Teuchos::RCP< const IntVector > fieldVector_
Maps for each field (as needed)
std::map< int, Teuchos::RCP< const Map > > fieldMaps_
(unghosted) field vector (as needed)
Teuchos::RCP< Epetra_MultiVector > getDataVector(const std::string &fieldName, const std::map< std::string, ArrayT > &data) const
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
void updateGhostedDataReducedVectorEpetra(const std::string &fieldName, const std::string blockId, const GlobalIndexer &ugi, const ArrayT &data, Epetra_MultiVector &dataVector)
Teuchos::RCP< const Epetra_BlockMap > getFieldMapEpetra(int fieldNum, const Epetra_IntVector &fieldVector)