NEMoSys  0.63.0
A modular, extensible resource with robust automated mesh generation, mesh quality analysis, adaptive mesh refinement, and data transfer between arbitrary meshes.
GaussCubature Class Reference

Detailed Description

Definition at line 57 of file Cubature.H.

Public Member Functions

 GaussCubature (vtkDataSet *_dataSet)
 
 GaussCubature (vtkDataSet *_dataSet, const std::vector< int > &arrayIDs)
 
 ~GaussCubature ()
 
 GaussCubature (const GaussCubature &that)=delete
 
GaussCubatureoperator= (const GaussCubature &that)=delete
 
void constructGaussMesh ()
 
pntDataPairVec getGaussPointsAndDataAtCell (int cellID)
 Returns coordinates of gauss points and associated data at cell. More...
 
void interpolateToGaussPoints ()
 Interpolate values to gauss points for arrays specified in arrayIDs at construction time. More...
 
void interpolateToGaussPoints (const std::vector< std::string > &newArrayNames)
 Interpolate values to gauss points for arrays specified in arrayIDs at construction time and specify new names (in order). More...
 
std::vector< std::vector< double > > integrateOverAllCells ()
 Integrate arrays specified by arrayIDs over all cells. More...
 
std::vector< std::vector< double > > integrateOverAllCells (const std::vector< std::string > &newArrayNames, bool computeRMSE)
 Same as integrateOverAllCells() but with integral value array names specified by newArrayNames and an optional flag to compute the root mean square error (RMSE) integral over an array with error values, an error metric normalized by cell volume. More...
 
void setArrayIDs (const std::vector< int > &_arrayIDs)
 
double computeJacobian (vtkSmartPointer< vtkGenericCell > genCell, int cellType) const
 
double computeCellVolume (vtkSmartPointer< vtkGenericCell > genCell, int cellType) const
 
vtkDataSet * getDataSet () const
 
vtkSmartPointer< vtkPolyData > getGaussMesh () const
 
vtkQuadratureSchemeDefinition ** getDict () const
 
std::vector< int > getNumComponents () const
 
std::vector< int > getArrayIDs () const
 
int getTotalComponents () const
 
void writeGaussMesh (const char *name) const
 

Static Public Member Functions

static GaussCubatureCreate (vtkDataSet *_dataSet)
 
static GaussCubatureCreate (vtkDataSet *_dataSet, const std::vector< int > &arrayIDs)
 
static std::unique_ptr< GaussCubatureCreateUnique (vtkDataSet *_dataSet)
 
static std::unique_ptr< GaussCubatureCreateUnique (vtkDataSet *_dataSet, const std::vector< int > &arrayIDs)
 
static std::shared_ptr< GaussCubatureCreateShared (vtkDataSet *_dataSet)
 
static std::shared_ptr< GaussCubatureCreateShared (vtkDataSet *_dataSet, const std::vector< int > &arrayIDs)
 

Private Member Functions

int getOffset (int cellID) const
 
int interpolateToGaussPointsAtCell (int cellID, vtkSmartPointer< vtkGenericCell > genCell, const std::vector< vtkSmartPointer< vtkDataArray >> &das, std::vector< vtkSmartPointer< vtkDoubleArray >> &daGausses) const
 
void integrateOverCell (int cellID, vtkSmartPointer< vtkGenericCell > genCell, vtkSmartPointer< vtkPointData > pd, std::vector< vtkSmartPointer< vtkDoubleArray >> &integralData, std::vector< std::vector< double >> &totalIntegralData) const
 
void integrateOverCell (int cellID, vtkSmartPointer< vtkGenericCell > genCell, vtkSmartPointer< vtkPointData > pd, std::vector< vtkSmartPointer< vtkDoubleArray >> &integralData, std::vector< std::vector< double >> &totalIntegralData, const std::vector< std::string > &newArrayNames, bool normalizeByVol) const
 

Private Attributes

vtkSmartPointer< vtkDataSet > dataSet
 
int numVolCells
 
vtkSmartPointer< vtkPolyData > gaussMesh
 
vtkQuadratureSchemeDefinition ** dict
 
std::vector< int > arrayIDs
 
std::vector< int > numComponents
 
int totalComponents
 

Constructor & Destructor Documentation

◆ GaussCubature() [1/3]

GaussCubature::GaussCubature ( vtkDataSet *  _dataSet)
explicit

Definition at line 107 of file Cubature.C.

References constructGaussMesh(), and dataSet.

Referenced by Create().

108  : dataSet(_dataSet), numVolCells(0), totalComponents(0)
109 {
110  dataSet->GetCellData()->RemoveArray("QuadratureOffSet");
112 }
void constructGaussMesh()
Definition: Cubature.C:166
int totalComponents
Definition: Cubature.H:147
vtkSmartPointer< vtkDataSet > dataSet
Definition: Cubature.H:137
int numVolCells
Definition: Cubature.H:139

◆ GaussCubature() [2/3]

GaussCubature::GaussCubature ( vtkDataSet *  _dataSet,
const std::vector< int > &  arrayIDs 
)

Definition at line 114 of file Cubature.C.

References constructGaussMesh(), dataSet, and interpolateToGaussPoints().

116  : dataSet(_dataSet), numVolCells(0), arrayIDs(_arrayIDs),
117  totalComponents(0)
118 {
119  dataSet->GetCellData()->RemoveArray("QuadratureOffSet");
122 }
void interpolateToGaussPoints()
Interpolate values to gauss points for arrays specified in arrayIDs at construction time...
Definition: Cubature.C:467
void constructGaussMesh()
Definition: Cubature.C:166
int totalComponents
Definition: Cubature.H:147
vtkSmartPointer< vtkDataSet > dataSet
Definition: Cubature.H:137
std::vector< int > arrayIDs
Definition: Cubature.H:145
int numVolCells
Definition: Cubature.H:139

◆ ~GaussCubature()

GaussCubature::~GaussCubature ( )
inline

Definition at line 62 of file Cubature.H.

62 { delete[] dict; }
vtkQuadratureSchemeDefinition ** dict
Definition: Cubature.H:143

◆ GaussCubature() [3/3]

GaussCubature::GaussCubature ( const GaussCubature that)
delete

Member Function Documentation

◆ computeCellVolume()

double GaussCubature::computeCellVolume ( vtkSmartPointer< vtkGenericCell >  genCell,
int  cellType 
) const

Definition at line 301 of file Cubature.C.

Referenced by integrateOverCell().

303 {
304  switch (cellType)
305  {
306  case VTK_TRIANGLE:
307  {
308  return vtkMeshQuality::TriangleArea(genCell);
309  }
310  case VTK_QUAD:
311  {
312  return vtkMeshQuality::QuadArea(genCell);
313  }
314  case VTK_TETRA:
315  {
316  return vtkMeshQuality::TetVolume(genCell);
317  }
318  case VTK_HEXAHEDRON:
319  {
320  return vtkMeshQuality::HexVolume(genCell);
321  }
322  default:
323  {
324  std::cerr << "Error: Cell type: " << cellType << "found "
325  << "with no quadrature definition provided" << std::endl;
326  exit(1);
327  }
328  }
329 }
VTKCellType cellType
Definition: inpGeoMesh.C:129

◆ computeJacobian()

double GaussCubature::computeJacobian ( vtkSmartPointer< vtkGenericCell >  genCell,
int  cellType 
) const

Definition at line 333 of file Cubature.C.

Referenced by integrateOverCell().

335 {
336  switch (cellType)
337  {
338  case VTK_TRIANGLE:
339  {
340  return vtkMeshQuality::TriangleArea(genCell);
341  }
342  case VTK_QUAD:
343  {
344  return vtkMeshQuality::QuadArea(genCell) / 4.0;
345  }
346  case VTK_TETRA:
347  {
348  return vtkMeshQuality::TetVolume(genCell);
349  }
350  case VTK_HEXAHEDRON:
351  {
352  return vtkMeshQuality::HexVolume(genCell) / 8.0;
353  }
354  default:
355  {
356  std::cerr << "Error: Cell type: " << cellType << "found "
357  << "with no quadrature definition provided" << std::endl;
358  exit(1);
359  }
360  }
361 }
VTKCellType cellType
Definition: inpGeoMesh.C:129

◆ constructGaussMesh()

void GaussCubature::constructGaussMesh ( )

Definition at line 166 of file Cubature.C.

References arrayIDs, cellType, dataSet, dict, gaussMesh, HEX8, HEX8W, NEM::MSH::New(), numVolCells, TET4, TET4W, TRI3, and TRI3W.

Referenced by GaussCubature().

167 {
168  // check whether arrayIDs exist in mesh
169  {
170  vtkSmartPointer<vtkPointData> pd = dataSet->GetPointData();
171  int numArr = pd->GetNumberOfArrays();
172  for (int arrayID : arrayIDs)
173  {
174  if (arrayID >= numArr)
175  {
176  std::cerr << "Array ID " << arrayID << " not found in dataset"
177  << std::endl;
178  exit(1);
179  }
180  }
181  }
182 
183  // Get the dictionary key
184  auto key = vtkQuadratureSchemeDefinition::DICTIONARY();
185 
186  // Get the cell types used by the data set
187  auto cellTypes = vtkSmartPointer<vtkCellTypes>::New();
188  dataSet->GetCellTypes(cellTypes);
189  int nCellTypes = cellTypes->GetNumberOfTypes();
190 
191  // create offset array and store the dictionary within
192  auto offsets = vtkSmartPointer<vtkIdTypeArray>::New();
193  std::string basename = "QuadratureOffset";
194  offsets->SetName(basename.c_str());
196  info = offsets->GetInformation();
197 
198  for (int typeId = 0; typeId < nCellTypes; ++typeId)
199  {
200  int cellType = cellTypes->GetCellType(typeId);
201  // Initialize quadrature scheme definition for given cell type
203  switch (cellType)
204  {
205  case VTK_TRIANGLE:
206  def->Initialize(VTK_TRIANGLE, 3, 3, TRI3, TRI3W);
207  break;
208  case VTK_TETRA:
209  def->Initialize(VTK_TETRA, 4, 4, TET4, TET4W);
210  break;
211  case VTK_HEXAHEDRON:
212  def->Initialize(VTK_HEXAHEDRON, 8, 8, HEX8, HEX8W);
213  break;
214  default:
215  std::cerr << "Error: Cell type: " << cellType << " found "
216  << "with no quadrature definition provided" << std::endl;
217  exit(1);
218  }
219  // the definition must appear in the dictionary associated with
220  // the offset array
221  key->Set(info, def, cellType);
222  }
223  // get dictionary size
224  int dictSize = key->Size(info);
225  dict = new vtkQuadratureSchemeDefinition *[dictSize];
226  key->GetRange(info, dict, 0, 0, dictSize);
227  vtkIdType numCells = dataSet->GetNumberOfCells();
228 
229  offsets->SetNumberOfTuples(numCells);
230 
231 #ifdef HAVE_OPENMP
232  std::vector<vtkIdType> chunkOffsets(omp_get_max_threads() + 1, 0);
233  #pragma omp parallel default(none) shared(numCells, chunkOffsets, offsets)
234  {
235  vtkIdType subOffset = 0;
236  auto genCell = vtkSmartPointer<vtkGenericCell>::New();
237 
238  #pragma omp single
239  {
240  // GetCell method is thread safe when first called from single thread
241  dataSet->GetCell(0, genCell);
242  }
243 
244  #pragma omp for schedule(static)
245  for (vtkIdType cellId = 0; cellId < numCells; ++cellId) {
246  offsets->SetValue(cellId, subOffset);
247 
248  dataSet->GetCell(cellId, genCell);
249  int cellType = genCell->GetCellType();
250  if (cellType >= VTK_TETRA) numVolCells += 1;
251 
252  vtkQuadratureSchemeDefinition *celldef = dict[cellType];
253  subOffset += celldef->GetNumberOfQuadraturePoints();
254  }
255 
256  int tid = omp_get_thread_num();
257  chunkOffsets[tid + 1] = subOffset;
258  #pragma omp barrier
259  #pragma omp single
260  {
261  for (int i = 1; i < chunkOffsets.size(); ++i) {
262  chunkOffsets[i] = chunkOffsets[i] + chunkOffsets[i - 1];
263  }
264  }
265 
266  #pragma omp for schedule(static)
267  for (vtkIdType cellId = 0; cellId < numCells; ++cellId) {
268  vtkIdType offset = chunkOffsets[tid] + offsets->GetValue(cellId);
269  offsets->SetValue(cellId, offset);
270  }
271  }
272 #else
273  vtkIdType offset = 0;
274 
275  for (int cellid = 0; cellid < numCells; ++cellid) {
276  offsets->SetValue(cellid, offset);
277  int cellType = dataSet->GetCell(cellid)->GetCellType();
278  if (cellType >= VTK_TETRA) {
279  numVolCells += 1;
280  }
281  vtkQuadratureSchemeDefinition *celldef = dict[cellType];
282  offset += celldef->GetNumberOfQuadraturePoints();
283  }
284 #endif
285 
286  dataSet->GetCellData()->AddArray(offsets);
287 
289 
290  pointGen->SetInputArrayToProcess
291  (0, 0, 0,
292  vtkDataObject::FIELD_ASSOCIATION_CELLS,
293  "QuadratureOffset");
294  pointGen->SetInputData(dataSet);
296  gaussMesh = vtkPolyData::SafeDownCast(pointGen->GetOutput());
297  pointGen->Update();
298 }
double TET4W[]
Definition: Cubature.C:77
geoMeshBase * New(MeshType meshType)
Create a new mesh object.
double TET4[]
Definition: Cubature.C:68
double HEX8[]
Definition: Cubature.C:79
double HEX8W[]
Definition: Cubature.C:104
VTKCellType cellType
Definition: inpGeoMesh.C:129
vtkSmartPointer< vtkDataSet > dataSet
Definition: Cubature.H:137
vtkSmartPointer< vtkPolyData > gaussMesh
Definition: Cubature.H:141
double TRI3[]
Definition: Cubature.C:58
double TRI3W[]
Definition: Cubature.C:65
std::vector< int > arrayIDs
Definition: Cubature.H:145
int numVolCells
Definition: Cubature.H:139
vtkQuadratureSchemeDefinition ** dict
Definition: Cubature.H:143

◆ Create() [1/2]

GaussCubature * GaussCubature::Create ( vtkDataSet *  _dataSet)
static

Definition at line 124 of file Cubature.C.

References GaussCubature().

Referenced by CreateShared(), and CreateUnique().

125 {
126  return new GaussCubature(_dataSet);
127 }
GaussCubature(vtkDataSet *_dataSet)
Definition: Cubature.C:107

◆ Create() [2/2]

GaussCubature * GaussCubature::Create ( vtkDataSet *  _dataSet,
const std::vector< int > &  arrayIDs 
)
static

Definition at line 129 of file Cubature.C.

References GaussCubature().

131 {
132  return new GaussCubature(_dataSet, arrayIDs);
133 }
GaussCubature(vtkDataSet *_dataSet)
Definition: Cubature.C:107

◆ CreateShared() [1/2]

std::shared_ptr< GaussCubature > GaussCubature::CreateShared ( vtkDataSet *  _dataSet)
static

Definition at line 149 of file Cubature.C.

References Create().

150 {
151  std::shared_ptr<GaussCubature> cuby;
152  cuby.reset(GaussCubature::Create(_dataSet));
153  return cuby;
154 }
static GaussCubature * Create(vtkDataSet *_dataSet)
Definition: Cubature.C:124

◆ CreateShared() [2/2]

std::shared_ptr< GaussCubature > GaussCubature::CreateShared ( vtkDataSet *  _dataSet,
const std::vector< int > &  arrayIDs 
)
static

Definition at line 157 of file Cubature.C.

References Create().

159 {
160  std::shared_ptr<GaussCubature> cuby;
161  cuby.reset(GaussCubature::Create(_dataSet, arrayIDs));
162  return cuby;
163 }
static GaussCubature * Create(vtkDataSet *_dataSet)
Definition: Cubature.C:124

◆ CreateUnique() [1/2]

std::unique_ptr< GaussCubature > GaussCubature::CreateUnique ( vtkDataSet *  _dataSet)
static

Definition at line 135 of file Cubature.C.

References Create().

Referenced by meshBase::integrateOverMesh(), and PatchRecovery::PatchRecovery().

136 {
137  return std::unique_ptr<GaussCubature>(GaussCubature::Create(_dataSet));
138 }
static GaussCubature * Create(vtkDataSet *_dataSet)
Definition: Cubature.C:124

◆ CreateUnique() [2/2]

std::unique_ptr< GaussCubature > GaussCubature::CreateUnique ( vtkDataSet *  _dataSet,
const std::vector< int > &  arrayIDs 
)
static

Definition at line 141 of file Cubature.C.

References Create().

143 {
144  return std::unique_ptr<GaussCubature>(
145  GaussCubature::Create(_dataSet, arrayIDs));
146 }
static GaussCubature * Create(vtkDataSet *_dataSet)
Definition: Cubature.C:124

◆ getArrayIDs()

std::vector<int> GaussCubature::getArrayIDs ( ) const
inline

Definition at line 118 of file Cubature.H.

118 { return arrayIDs; }
std::vector< int > arrayIDs
Definition: Cubature.H:145

◆ getDataSet()

vtkDataSet* GaussCubature::getDataSet ( ) const
inline

Definition at line 113 of file Cubature.H.

113 { return dataSet; }
vtkSmartPointer< vtkDataSet > dataSet
Definition: Cubature.H:137

◆ getDict()

vtkQuadratureSchemeDefinition** GaussCubature::getDict ( ) const
inline

Definition at line 116 of file Cubature.H.

116 { return dict; }
vtkQuadratureSchemeDefinition ** dict
Definition: Cubature.H:143

◆ getGaussMesh()

vtkSmartPointer<vtkPolyData> GaussCubature::getGaussMesh ( ) const
inline

Definition at line 115 of file Cubature.H.

115 { return gaussMesh; }
vtkSmartPointer< vtkPolyData > gaussMesh
Definition: Cubature.H:141

◆ getGaussPointsAndDataAtCell()

pntDataPairVec GaussCubature::getGaussPointsAndDataAtCell ( int  cellID)
Parameters
cellIdcell id
Returns
pntDataPairVec (see alias in Cubature.H)

Definition at line 374 of file Cubature.C.

References arrayIDs, data, dataSet, dict, gaussMesh, getOffset(), interpolateToGaussPoints(), interpolateToGaussPointsAtCell(), numComponents, and totalComponents.

375 {
376  if (arrayIDs.empty())
377  {
378  std::cerr << "no array have been selected for interpolation" << std::endl;
379  exit(1);
380  }
381 
382  int numDataArr = gaussMesh->GetPointData()->GetNumberOfArrays();
383 
384  if (numDataArr == 0)
385  {
387  }
388 
389  // get number of gauss points in cell from dictionary
390  int numGaussPoints = dict[dataSet->GetCell(
391  cellID)->GetCellType()]
392  ->GetNumberOfQuadraturePoints();
393  // get offset from nodeMesh for lookup of gauss points in polyData
394  int offset = getOffset(cellID);
395 
396  //pntDataPairVec container;
397  pntDataPairVec container(numGaussPoints);
398 
399  vtkSmartPointer<vtkPointData> pd = gaussMesh->GetPointData();
400  for (int i = 0; i < numGaussPoints; ++i)
401  {
402  double x_tmp[3];
403  gaussMesh->GetPoint(offset + i, x_tmp);
404  std::vector<double> gaussPnt(x_tmp, x_tmp + 3);
405  std::vector<double> data(totalComponents);
406  int currcomp = 0;
407  for (int j = 0; j < numComponents.size(); ++j)
408  {
409  double *comps = new double[numComponents[j]];
410  pd->GetArray(j)->GetTuple(offset + i, comps);
411  for (int k = 0; k < numComponents[j]; ++k)
412  {
413  data[currcomp] = comps[k];
414  ++currcomp;
415  }
416  delete[] comps;
417  }
418  container[i] = std::make_pair(gaussPnt, data);
419  }
420  return container;
421 }
data_type data
Edge/face with sorted point ids (a, b, c, ...) is located at some index i in data[b], with data[b][i].first == [a, c] (for edges, third point id treated as -1).
std::vector< int > numComponents
Definition: Cubature.H:146
std::vector< pntDataPair > pntDataPairVec
Definition: Cubature.H:55
void interpolateToGaussPoints()
Interpolate values to gauss points for arrays specified in arrayIDs at construction time...
Definition: Cubature.C:467
int totalComponents
Definition: Cubature.H:147
int getOffset(int cellID) const
Definition: Cubature.C:364
vtkSmartPointer< vtkDataSet > dataSet
Definition: Cubature.H:137
vtkSmartPointer< vtkPolyData > gaussMesh
Definition: Cubature.H:141
std::vector< int > arrayIDs
Definition: Cubature.H:145
vtkQuadratureSchemeDefinition ** dict
Definition: Cubature.H:143

◆ getNumComponents()

std::vector<int> GaussCubature::getNumComponents ( ) const
inline

Definition at line 117 of file Cubature.H.

117 { return numComponents; }
std::vector< int > numComponents
Definition: Cubature.H:146

◆ getOffset()

int GaussCubature::getOffset ( int  cellID) const
private

Definition at line 364 of file Cubature.C.

References dataSet.

Referenced by getGaussPointsAndDataAtCell(), integrateOverCell(), and interpolateToGaussPointsAtCell().

365 {
366  vtkIdType offsets[1];
367  vtkIdTypeArray::FastDownCast(
368  dataSet->GetCellData()->GetArray("QuadratureOffset"))
369  ->GetTypedTuple(cellID, offsets);
370  return offsets[0];
371 }
vtkSmartPointer< vtkDataSet > dataSet
Definition: Cubature.H:137

◆ getTotalComponents()

int GaussCubature::getTotalComponents ( ) const
inline

Definition at line 119 of file Cubature.H.

119 { return totalComponents; }
int totalComponents
Definition: Cubature.H:147

◆ integrateOverAllCells() [1/2]

std::vector< std::vector< double > > GaussCubature::integrateOverAllCells ( )
Returns
Integral data (first index - array, second index - component)

Definition at line 697 of file Cubature.C.

References arrayIDs, dataSet, gaussMesh, id, integrateOverCell(), interpolateToGaussPoints(), NEM::MSH::New(), and numComponents.

Referenced by meshBase::integrateOverMesh().

698 {
699  int numCells = dataSet->GetNumberOfCells();
700 
701  if (gaussMesh->GetPointData()->GetNumberOfArrays() == 0)
702  {
704  }
705 
706  vtkSmartPointer<vtkPointData> pd = gaussMesh->GetPointData();
707  std::vector<vtkSmartPointer<vtkDoubleArray>> cellIntegralData(arrayIDs.size());
708  std::vector<std::vector<double>> totalIntegralData(arrayIDs.size());
709  for (int id = 0; id < arrayIDs.size(); ++id)
710  {
711  std::string arrName(
712  dataSet->GetPointData()->GetArrayName(arrayIDs[id]));
713  arrName.append("Integral");
714  vtkSmartPointer<vtkDoubleArray> integralDatum = vtkSmartPointer<vtkDoubleArray>::New();
715  integralDatum->SetName(&arrName[0u]);
716  integralDatum->SetNumberOfComponents(numComponents[id]);
717  integralDatum->SetNumberOfTuples(dataSet->GetNumberOfCells());
718  cellIntegralData[id] = integralDatum;
719  totalIntegralData[id].resize(numComponents[id], 0);
720  }
721 
722 #ifdef HAVE_OPENMP
723  #pragma omp parallel default(none) shared(numCells, pd, cellIntegralData, totalIntegralData, cerr)
724  {
725  auto genCell = vtkSmartPointer<vtkGenericCell>::New();
726 
727  #pragma omp single
728  {
729  // GetCell method is thread safe when first called from single thread
730  dataSet->GetCell(0, genCell);
731  }
732  auto partialIntegralData = totalIntegralData;
733 
734  #pragma omp for schedule(static)
735  for (int i = 0; i < numCells; ++i) {
736  integrateOverCell(i, genCell, pd, cellIntegralData, partialIntegralData);
737  }
738 
739  #pragma omp critical
740  {
741  // total integral data has same dimensions as cell integral data ...
742  // sum partial integrals
743  for (int id = 0; id < partialIntegralData.size(); ++id) {
744  for (int k = 0; k < partialIntegralData[id].size(); ++k) {
745  totalIntegralData[id][k] += partialIntegralData[id][k];
746  }
747  }
748  }
749  }
750 #else
751  auto genCell = vtkSmartPointer<vtkGenericCell>::New();
752  for (int i = 0; i < numCells; ++i) {
753  integrateOverCell(i, genCell, pd, cellIntegralData, totalIntegralData);
754  }
755 #endif
756 
757  for (int id = 0; id < arrayIDs.size(); ++id) {
758  dataSet->GetCellData()->AddArray(cellIntegralData[id]);
759  }
760  return totalIntegralData;
761 }
std::vector< int > numComponents
Definition: Cubature.H:146
geoMeshBase * New(MeshType meshType)
Create a new mesh object.
void interpolateToGaussPoints()
Interpolate values to gauss points for arrays specified in arrayIDs at construction time...
Definition: Cubature.C:467
vtkIdType id
id in .inp file
Definition: inpGeoMesh.C:128
vtkSmartPointer< vtkDataSet > dataSet
Definition: Cubature.H:137
vtkSmartPointer< vtkPolyData > gaussMesh
Definition: Cubature.H:141
std::vector< int > arrayIDs
Definition: Cubature.H:145
void integrateOverCell(int cellID, vtkSmartPointer< vtkGenericCell > genCell, vtkSmartPointer< vtkPointData > pd, std::vector< vtkSmartPointer< vtkDoubleArray >> &integralData, std::vector< std::vector< double >> &totalIntegralData) const
Definition: Cubature.C:586

◆ integrateOverAllCells() [2/2]

std::vector< std::vector< double > > GaussCubature::integrateOverAllCells ( const std::vector< std::string > &  newArrayNames,
bool  computeRMSE 
)
Parameters
newArrayNamesintegral value array names
computeRMSEcompute RMSE (see above)
Returns
Integral data (first index - array, second index - component)

Definition at line 765 of file Cubature.C.

References dataSet, gaussMesh, id, integrateOverCell(), interpolateToGaussPoints(), and NEM::MSH::New().

768 {
769  interpolateToGaussPoints(newArrayNames);
770 
771  vtkSmartPointer<vtkPointData> pd = gaussMesh->GetPointData();
772  std::vector<vtkSmartPointer<vtkDoubleArray>> cellIntegralData(newArrayNames.size());
773  std::vector<std::vector<double>> totalIntegralData(newArrayNames.size());
774  for (int id = 0; id < newArrayNames.size(); ++id)
775  {
776  std::string name = newArrayNames[id] + "Integral";
777  vtkSmartPointer<vtkDoubleArray> integralDatum = vtkSmartPointer<vtkDoubleArray>::New();
778  integralDatum->SetName(&name[0u]);
779  int numComponent = pd->GetArray(
780  &(newArrayNames[id])[0u])->GetNumberOfComponents();
781  integralDatum->SetNumberOfComponents(numComponent);
782  integralDatum->SetNumberOfTuples(dataSet->GetNumberOfCells());
783  cellIntegralData[id] = integralDatum;
784  totalIntegralData[id].resize(numComponent, 0);
785  }
786 
787  int numCells = dataSet->GetNumberOfCells();
788 
789 #ifdef HAVE_OPENMP
790  #pragma omp parallel default(none) \
791  shared(numCells, pd, cellIntegralData, totalIntegralData, newArrayNames, computeRMSE)
792  {
793  auto genCell = vtkSmartPointer<vtkGenericCell>::New();
794  #pragma omp single
795  {
796  // GetCell method is thread safe when first called from single thread
797  dataSet->GetCell(0, genCell);
798  }
799  auto partialIntegralData = totalIntegralData;
800  #pragma omp for schedule(static)
801  for (int i = 0; i < numCells; ++i) {
802  integrateOverCell(i, genCell, pd, cellIntegralData, partialIntegralData,
803  newArrayNames, computeRMSE);
804  }
805  #pragma omp critical
806  {
807  // total integral data has same dimensions as cell integral data ...
808  // sum partial integrals
809  for(int id = 0; id < partialIntegralData.size(); ++id) {
810  for(int k = 0; k < partialIntegralData[id].size(); ++k) {
811  totalIntegralData[id][k] += partialIntegralData[id][k];
812  }
813  }
814  }
815  }
816 #else
817  vtkSmartPointer<vtkGenericCell> genCell = vtkSmartPointer<vtkGenericCell>::New();
818  for (int i = 0; i < numCells; ++i) {
819  integrateOverCell(i, genCell, pd, cellIntegralData, totalIntegralData,
820  newArrayNames, computeRMSE);
821  }
822 #endif
823 
824  for (int id = 0; id < newArrayNames.size(); ++id)
825  {
826  dataSet->GetCellData()->AddArray(cellIntegralData[id]);
827  }
828  return totalIntegralData;
829 }
geoMeshBase * New(MeshType meshType)
Create a new mesh object.
void interpolateToGaussPoints()
Interpolate values to gauss points for arrays specified in arrayIDs at construction time...
Definition: Cubature.C:467
vtkIdType id
id in .inp file
Definition: inpGeoMesh.C:128
vtkSmartPointer< vtkDataSet > dataSet
Definition: Cubature.H:137
vtkSmartPointer< vtkPolyData > gaussMesh
Definition: Cubature.H:141
void integrateOverCell(int cellID, vtkSmartPointer< vtkGenericCell > genCell, vtkSmartPointer< vtkPointData > pd, std::vector< vtkSmartPointer< vtkDoubleArray >> &integralData, std::vector< std::vector< double >> &totalIntegralData) const
Definition: Cubature.C:586

◆ integrateOverCell() [1/2]

void GaussCubature::integrateOverCell ( int  cellID,
vtkSmartPointer< vtkGenericCell >  genCell,
vtkSmartPointer< vtkPointData >  pd,
std::vector< vtkSmartPointer< vtkDoubleArray >> &  integralData,
std::vector< std::vector< double >> &  totalIntegralData 
) const
private

Definition at line 586 of file Cubature.C.

References arrayIDs, cellType, computeJacobian(), data, dataSet, dict, and getOffset().

Referenced by integrateOverAllCells(), and interpolateToGaussPoints().

591 {
592  // putting cell from nodeMesh into genCell
593  dataSet->GetCell(cellID, genCell);
594  // getting cellType for looking up numGaussPoints in dictionary
595  // as well as computing scaled Jacobian
596  int cellType = genCell->GetCellType();
597 
598  // get number of gauss points in cell from dictionary
599  int numGaussPoints;
600  const double* quadWeights;
601  numGaussPoints = dict[cellType]->GetNumberOfQuadraturePoints();
602  quadWeights = dict[cellType]->GetQuadratureWeights();
603 
604  // computing Jacobian for integration
605  double jacobian = computeJacobian(genCell, cellType);
606  // get quadrature weights for this cell type
607  // get offset from nodeMesh for lookup of gauss points in polyData
608  int offset = getOffset(cellID);
609  // holds integrated data for each array
610  std::vector<std::vector<double>> data(arrayIDs.size());
611  // integration loop
612  for (int j = 0; j < integralData.size(); ++j) {
613  int numComponent = integralData[j]->GetNumberOfComponents();
614  data[j].resize(numComponent, 0.0);
615  auto comps = new double[numComponent];
616  for (int i = 0; i < numGaussPoints; ++i) {
617  pd->GetArray(j)->GetTuple(offset + i, comps);
618  for (int k = 0; k < numComponent; ++k) {
619  // TODO: generalize to support surface integration
620  if (genCell->GetCellDimension() == 3) {
621  data[j][k] += comps[k] * quadWeights[i];//*jacobian;
622  } else
623  data[j][k] += 0.0;
624  }
625  }
626  delete[] comps;
627  for (int k = 0; k < numComponent; ++k) {
628  data[j][k] *= jacobian;
629  totalIntegralData[j][k] += data[j][k];
630  }
631  // adding integrated value to data of cell
632  integralData[j]->SetTuple(cellID, data[j].data());
633  }
634 }
double computeJacobian(vtkSmartPointer< vtkGenericCell > genCell, int cellType) const
Definition: Cubature.C:333
data_type data
Edge/face with sorted point ids (a, b, c, ...) is located at some index i in data[b], with data[b][i].first == [a, c] (for edges, third point id treated as -1).
VTKCellType cellType
Definition: inpGeoMesh.C:129
int getOffset(int cellID) const
Definition: Cubature.C:364
vtkSmartPointer< vtkDataSet > dataSet
Definition: Cubature.H:137
std::vector< int > arrayIDs
Definition: Cubature.H:145
vtkQuadratureSchemeDefinition ** dict
Definition: Cubature.H:143

◆ integrateOverCell() [2/2]

void GaussCubature::integrateOverCell ( int  cellID,
vtkSmartPointer< vtkGenericCell >  genCell,
vtkSmartPointer< vtkPointData >  pd,
std::vector< vtkSmartPointer< vtkDoubleArray >> &  integralData,
std::vector< std::vector< double >> &  totalIntegralData,
const std::vector< std::string > &  newArrayNames,
bool  normalizeByVol 
) const
private

Definition at line 638 of file Cubature.C.

References arrayIDs, cellType, computeCellVolume(), computeJacobian(), data, dataSet, dict, and getOffset().

645 {
646  // putting cell from nodeMesh into genCell
647  dataSet->GetCell(cellID, genCell);
648  // getting cellType for looking up numGaussPoints in dictionary
649  int cellType = dataSet->GetCell(cellID)->GetCellType();
650  // get number of gauss points in cell from dictionary
651  int numGaussPoints = dict[cellType]->GetNumberOfQuadraturePoints();
652  // computing Jacobian for integration
653  double jacobian = computeJacobian(genCell, cellType);
654  // computing volume for RMSE
655  double volume = computeCellVolume(genCell, cellType);
656  // get quadrature weights for this cell type
657  const double *quadWeights = dict[cellType]->GetQuadratureWeights();
658  // get offset from nodeMesh for lookup of gauss points in polyData
659  int offset = getOffset(cellID);
660  // holds integrated data for each array
661  std::vector<std::vector<double>> data(arrayIDs.size());
662  // integration loop
663  for (int j = 0; j < integralData.size(); ++j)
664  {
665  int numComponent = integralData[j]->GetNumberOfComponents();
666  data[j].resize(numComponent);
667  auto *comps = new double[numComponent];
668  for (int i = 0; i < numGaussPoints; ++i)
669  {
670  pd->GetArray(&(newArrayNames[j])[0u])->GetTuple(offset + i, comps);
671  for (int k = 0; k < numComponent; ++k)
672  {
673  // TODO: generalize to support surface integration
674  if (genCell->GetCellDimension() == 3)
675  {
676  data[j][k] += comps[k] * quadWeights[i];
677  }
678  else
679  data[j][k] += 0.0;
680  }
681  }
682  delete[] comps;
683  // taking sqrt of integrated value (RMSE)
684  for (int k = 0; k < numComponent; ++k)
685  {
686  data[j][k] *= jacobian;
687  data[j][k] = (computeRMSE ? std::sqrt(data[j][k] / volume) : data[j][k]);
688  //if (computeRMSE)
689  // data[j][k] = std::sqrt(data[j][k] / volume);
690  totalIntegralData[j][k] += data[j][k];
691  }
692  // adding integrated value to data of cell
693  integralData[j]->SetTuple(cellID, data[j].data());
694  }
695 }
double computeJacobian(vtkSmartPointer< vtkGenericCell > genCell, int cellType) const
Definition: Cubature.C:333
data_type data
Edge/face with sorted point ids (a, b, c, ...) is located at some index i in data[b], with data[b][i].first == [a, c] (for edges, third point id treated as -1).
double computeCellVolume(vtkSmartPointer< vtkGenericCell > genCell, int cellType) const
Definition: Cubature.C:301
VTKCellType cellType
Definition: inpGeoMesh.C:129
int getOffset(int cellID) const
Definition: Cubature.C:364
vtkSmartPointer< vtkDataSet > dataSet
Definition: Cubature.H:137
std::vector< int > arrayIDs
Definition: Cubature.H:145
vtkQuadratureSchemeDefinition ** dict
Definition: Cubature.H:143

◆ interpolateToGaussPoints() [1/2]

void GaussCubature::interpolateToGaussPoints ( )

Definition at line 467 of file Cubature.C.

References arrayIDs, dataSet, gaussMesh, id, interpolateToGaussPointsAtCell(), NEM::MSH::New(), numComponents, and totalComponents.

Referenced by GaussCubature(), getGaussPointsAndDataAtCell(), and integrateOverAllCells().

468 {
469  if (arrayIDs.empty())
470  {
471  std::cerr << "no arrays selected for interpolation" << std::endl;
472  exit(1);
473  }
474 
475  std::vector<vtkSmartPointer<vtkDoubleArray>> daGausses(arrayIDs.size());
476  std::vector<vtkSmartPointer<vtkDataArray>> das(arrayIDs.size());
477  numComponents.resize(arrayIDs.size());
478  // initializing arrays storing interpolated data
479  for (int id = 0; id < arrayIDs.size(); ++id)
480  {
481  // get desired point data array to be interpolated to gauss points
482  vtkSmartPointer<vtkDataArray> da = dataSet->GetPointData()->GetArray(
483  arrayIDs[id]);
484  // get tuple length of given data
485  int numComponent = da->GetNumberOfComponents();
486  // declare data array to be populated with values at gauss points
487  vtkSmartPointer<vtkDoubleArray> daGauss = vtkSmartPointer<vtkDoubleArray>::New();
488  // names and sizing
489  daGauss->SetName(
490  dataSet->GetPointData()->GetArrayName(arrayIDs[id]));
491  daGauss->SetNumberOfComponents(numComponent);
492  daGauss->SetNumberOfTuples(gaussMesh->GetNumberOfPoints());
493  das[id] = da;
494  daGausses[id] = daGauss;
495  numComponents[id] = numComponent;
496  totalComponents += numComponent;
497  }
498  int numCells = dataSet->GetNumberOfCells();
499 #ifdef HAVE_OPENMP
500  #pragma omp parallel default(none) shared(numCells, das, daGausses)
501  {
502  vtkSmartPointer<vtkGenericCell> genCell =
504  #pragma omp single
505  {
506  // GetCell method is thread safe when first called from single thread
507  dataSet->GetCell(0, genCell);
508  }
509  #pragma omp for schedule(static)
510  for (int i = 0; i < numCells; ++i) {
511  interpolateToGaussPointsAtCell(i, genCell, das, daGausses);
512  }
513  }
514 #else
515  // generic cell to store given cell in dataSet
516  vtkSmartPointer<vtkGenericCell> genCell = vtkSmartPointer<vtkGenericCell>::New();
517  for (int i = 0; i < dataSet->GetNumberOfCells(); ++i)
518  {
519  interpolateToGaussPointsAtCell(i, genCell, das, daGausses);
520  }
521 #endif
522  for (int id = 0; id < arrayIDs.size(); ++id)
523  {
524  gaussMesh->GetPointData()->AddArray(daGausses[id]);
525  }
526 }
std::vector< int > numComponents
Definition: Cubature.H:146
geoMeshBase * New(MeshType meshType)
Create a new mesh object.
int totalComponents
Definition: Cubature.H:147
vtkIdType id
id in .inp file
Definition: inpGeoMesh.C:128
int interpolateToGaussPointsAtCell(int cellID, vtkSmartPointer< vtkGenericCell > genCell, const std::vector< vtkSmartPointer< vtkDataArray >> &das, std::vector< vtkSmartPointer< vtkDoubleArray >> &daGausses) const
Definition: Cubature.C:425
vtkSmartPointer< vtkDataSet > dataSet
Definition: Cubature.H:137
vtkSmartPointer< vtkPolyData > gaussMesh
Definition: Cubature.H:141
std::vector< int > arrayIDs
Definition: Cubature.H:145

◆ interpolateToGaussPoints() [2/2]

void GaussCubature::interpolateToGaussPoints ( const std::vector< std::string > &  newArrayNames)
Parameters
newArrayNamesname of transferred data from arrayIDs[i] will be named newArrayNames[i]

Definition at line 529 of file Cubature.C.

References arrayIDs, dataSet, gaussMesh, id, integrateOverCell(), interpolateToGaussPointsAtCell(), and NEM::MSH::New().

530  {
531  if (newArrayNames.empty()) {
532  std::cerr << "no arrays selected for interpolation" << std::endl;
533  exit(1);
534  }
535 
536  std::vector<vtkSmartPointer<vtkDoubleArray>> daGausses(newArrayNames.size());
537  std::vector<vtkSmartPointer<vtkDataArray>> das(newArrayNames.size());
538  // initializing arrays storing interpolated data
539  for (int id = 0; id < newArrayNames.size(); ++id) {
540  // get desired point data array to be interpolated to gauss points
541  vtkSmartPointer<vtkDataArray> da =
542  dataSet->GetPointData()->GetArray(&(newArrayNames[id])[0u]);
543  // get tuple length of given data
544  int numComponent = da->GetNumberOfComponents();
545  // declare data array to be populated with values at gauss points
546  vtkSmartPointer<vtkDoubleArray> daGauss = vtkSmartPointer<vtkDoubleArray>::New();
547  // names and sizing
548  daGauss->SetName(&(newArrayNames[id])[0u]);
549  daGauss->SetNumberOfComponents(numComponent);
550  daGauss->SetNumberOfTuples(gaussMesh->GetNumberOfPoints());
551  das[id] = da;
552  daGausses[id] = daGauss;
553  }
554  int numCells = dataSet->GetNumberOfCells();
555 #ifdef HAVE_OPENMP
556  #pragma omp parallel default(none) shared(numCells, das, daGausses)
557  {
558  // generic cell to store given cell in dataSet
559  vtkSmartPointer<vtkGenericCell> genCell =
561  #pragma omp single
562  {
563  // GetCell method is thread safe when first called from single thread
564  dataSet->GetCell(0, genCell);
565  }
566  #pragma omp for schedule(static)
567  for (int i = 0; i < numCells; ++i) {
568  interpolateToGaussPointsAtCell(i, genCell, das, daGausses);
569  }
570  }
571 #else
572  // generic cell to store given cell in dataSet
573  vtkSmartPointer<vtkGenericCell> genCell =
575  for (int i = 0; i < dataSet->GetNumberOfCells(); ++i) {
576  interpolateToGaussPointsAtCell(i, genCell, das, daGausses);
577  }
578 #endif
579  for (int id = 0; id < arrayIDs.size(); ++id)
580  {
581  gaussMesh->GetPointData()->AddArray(daGausses[id]);
582  }
583 }
geoMeshBase * New(MeshType meshType)
Create a new mesh object.
vtkIdType id
id in .inp file
Definition: inpGeoMesh.C:128
int interpolateToGaussPointsAtCell(int cellID, vtkSmartPointer< vtkGenericCell > genCell, const std::vector< vtkSmartPointer< vtkDataArray >> &das, std::vector< vtkSmartPointer< vtkDoubleArray >> &daGausses) const
Definition: Cubature.C:425
vtkSmartPointer< vtkDataSet > dataSet
Definition: Cubature.H:137
vtkSmartPointer< vtkPolyData > gaussMesh
Definition: Cubature.H:141
std::vector< int > arrayIDs
Definition: Cubature.H:145

◆ interpolateToGaussPointsAtCell()

int GaussCubature::interpolateToGaussPointsAtCell ( int  cellID,
vtkSmartPointer< vtkGenericCell >  genCell,
const std::vector< vtkSmartPointer< vtkDataArray >> &  das,
std::vector< vtkSmartPointer< vtkDoubleArray >> &  daGausses 
) const
private

Definition at line 425 of file Cubature.C.

References cellType, dataSet, dict, getOffset(), and id.

Referenced by getGaussPointsAndDataAtCell(), and interpolateToGaussPoints().

429 {
430  // putting current cell into genCell
431  dataSet->GetCell(cellID, genCell);
432  // getting cellType information for lookup in map
433  int cellType = dataSet->GetCellType(cellID);
434  // get quadrature weights for this cell type
435  const double *shapeFunctionWeights = dict[cellType]->GetShapeFunctionWeights();
436  // number of gauss points in this cell
437  int numGaussPoints = dict[cellType]->GetNumberOfQuadraturePoints();
438  // get offset from nodeMesh for lookup of gauss points in polyData
439  int offset = getOffset(cellID);
440  // interpolation loop
441  for (int j = 0; j < numGaussPoints; ++j)
442  {
443  for (int id = 0; id < das.size(); ++id)
444  {
445  int numComponent = das[id]->GetNumberOfComponents();
446  auto *comps = new double[numComponent];
447  std::vector<double> interps(numComponent, 0.0);
448  for (int m = 0; m < genCell->GetNumberOfPoints(); ++m)
449  {
450  int pntId = genCell->GetPointId(m);
451  das[id]->GetTuple(pntId, comps);
452  for (int h = 0; h < numComponent; ++h)
453  {
454  interps[h] += comps[h] *
455  shapeFunctionWeights[j * genCell->GetNumberOfPoints() + m];
456  }
457  }
458  delete[] comps;
459  // adding interpolated value to data of cell
460  daGausses[id]->SetTuple(j + offset, interps.data());
461  }
462  }
463  return numGaussPoints;
464 }
vtkIdType id
id in .inp file
Definition: inpGeoMesh.C:128
VTKCellType cellType
Definition: inpGeoMesh.C:129
int getOffset(int cellID) const
Definition: Cubature.C:364
vtkSmartPointer< vtkDataSet > dataSet
Definition: Cubature.H:137
vtkQuadratureSchemeDefinition ** dict
Definition: Cubature.H:143

◆ operator=()

GaussCubature& GaussCubature::operator= ( const GaussCubature that)
delete

◆ setArrayIDs()

void GaussCubature::setArrayIDs ( const std::vector< int > &  _arrayIDs)
inline

Definition at line 105 of file Cubature.H.

References cellType.

105 { arrayIDs = _arrayIDs; }
std::vector< int > arrayIDs
Definition: Cubature.H:145

◆ writeGaussMesh()

void GaussCubature::writeGaussMesh ( const char *  name) const

Definition at line 832 of file Cubature.C.

References gaussMesh.

833 {
834  if (gaussMesh)
835  writeVTFile<vtkXMLPolyDataWriter>(name, gaussMesh);
836  else
837  {
838  std::cerr << "Gauss point mesh has not been constructed" << std::endl;
839  exit(1);
840  }
841 }
vtkSmartPointer< vtkPolyData > gaussMesh
Definition: Cubature.H:141

Member Data Documentation

◆ arrayIDs

std::vector<int> GaussCubature::arrayIDs
private

◆ dataSet

◆ dict

vtkQuadratureSchemeDefinition** GaussCubature::dict
private

◆ gaussMesh

vtkSmartPointer<vtkPolyData> GaussCubature::gaussMesh
private

◆ numComponents

std::vector<int> GaussCubature::numComponents
private

◆ numVolCells

int GaussCubature::numVolCells
private

Definition at line 139 of file Cubature.H.

Referenced by constructGaussMesh().

◆ totalComponents

int GaussCubature::totalComponents
private

Definition at line 147 of file Cubature.H.

Referenced by getGaussPointsAndDataAtCell(), and interpolateToGaussPoints().


The documentation for this class was generated from the following files: