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.
PatchRecovery Class Reference

Detailed Description

Definition at line 44 of file patchRecovery.H.

Public Member Functions

 PatchRecovery (vtkDataSet *_dataSet, int _order, const std::vector< int > &arrayIDs)
 
 ~PatchRecovery ()=default
 
 PatchRecovery (const PatchRecovery &that)=delete
 
PatchRecoveryoperator= (const PatchRecovery &that)=delete
 
void recoverNodalSolution (bool ortho)
 
std::vector< std::vector< double > > computeNodalError ()
 

Private Member Functions

std::vector< double > getMinMaxCoords (const std::vector< std::vector< double >> &coords) const
 
void regularizeCoords (std::vector< std::vector< double >> &coords, std::vector< double > &genNodeCoord) const
 
void extractAxesAndData (const pntDataPairVec &pntsAndData, std::vector< std::vector< double >> &coords, std::vector< Eigen::VectorXd > &data, const std::vector< int > &numComponents, int &pntNum) const
 

Private Attributes

std::unique_ptr< GaussCubaturecubature
 
int order
 

Constructor & Destructor Documentation

◆ PatchRecovery() [1/2]

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

Definition at line 41 of file patchRecovery.C.

References GaussCubature::CreateUnique(), and cubature.

43  : order(_order)
44 {
45  cubature = GaussCubature::CreateUnique(_dataSet, arrayIDs);
46 }
std::unique_ptr< GaussCubature > cubature
Definition: patchRecovery.H:67
static std::unique_ptr< GaussCubature > CreateUnique(vtkDataSet *_dataSet)
Definition: Cubature.C:135

◆ ~PatchRecovery()

PatchRecovery::~PatchRecovery ( )
default

◆ PatchRecovery() [2/2]

PatchRecovery::PatchRecovery ( const PatchRecovery that)
delete

Member Function Documentation

◆ computeNodalError()

std::vector< std::vector< double > > PatchRecovery::computeNodalError ( )

Definition at line 245 of file patchRecovery.C.

References cellType, polyApprox::computeCoeff(), polyApprox::CreateUnique(), cubature, data, polyApprox::eval(), extractAxesAndData(), NEM::MSH::New(), order, regularizeCoords(), and polyApprox::resetCoeff().

Referenced by NEM::ADP::Z2ErrorSizeField::computeNodalError().

246 {
247  std::cout << "WARNING: mesh is assumed to be properly numbered" << std::endl;
248  // getting node mesh from cubature
249  vtkSmartPointer<vtkDataSet> dataSet = cubature->getDataSet();
250  std::vector<int> arrayIDs = cubature->getArrayIDs();
251  int numPoints = dataSet->GetNumberOfPoints();
252  // initializing id list for patch cells
253  vtkSmartPointer<vtkIdList> patchCellIDs = vtkSmartPointer<vtkIdList>::New();
254  // getting cubature scheme dictionary for indexing
255  vtkQuadratureSchemeDefinition **dict = cubature->getDict();
256  std::vector<int> numComponents = cubature->getNumComponents();
257  // getting number of doubles representing all data at a given point
258  int totalComponents = cubature->getTotalComponents();
259  // storage for new point data
260  std::vector<vtkSmartPointer<vtkDoubleArray>> newPntData(numComponents.size());
261  // storage for error data
262  std::vector<vtkSmartPointer<vtkDoubleArray>> errorPntData(
263  numComponents.size());
264  // reference point data
265  vtkSmartPointer<vtkPointData> pd = dataSet->GetPointData();
266 
267  std::vector<std::string> errorNames(numComponents.size());
268 
269  // initializing double arrays for new data
270  for (int i = 0; i < numComponents.size(); ++i)
271  {
272  std::string name = pd->GetArrayName(arrayIDs[i]);
273  std::string newName = name + "New";
274  newPntData[i] = vtkSmartPointer<vtkDoubleArray>::New();
275  newPntData[i]->SetName(newName.c_str());
276  newPntData[i]->SetNumberOfComponents(numComponents[i]);
277  newPntData[i]->SetNumberOfTuples(numPoints);
278 
279  std::string errName = name + "Error";
280  errorPntData[i] = vtkSmartPointer<vtkDoubleArray>::New();
281  errorPntData[i]->SetName(errName.c_str());
282  errorPntData[i]->SetNumberOfComponents(numComponents[i]);
283  errorPntData[i]->SetNumberOfTuples(numPoints);
284  errorNames[i] = errName;
285  }
286 
287  // storage for nodal average element sizes
288  vtkSmartPointer<vtkDoubleArray> nodeSizes = vtkSmartPointer<vtkDoubleArray>::New();
289  nodeSizes->SetName("nodeSizes");
290  nodeSizes->SetNumberOfComponents(1);
291  nodeSizes->SetNumberOfTuples(numPoints);
292 
293  // storage for generic cell if needed
294  vtkSmartPointer<vtkGenericCell> genCell = vtkSmartPointer<vtkGenericCell>::New();
295 
296  // looping over all points, looping over patches per point
297  for (int i = 0; i < numPoints; ++i)
298  {
299  // get ids of cells in patch of node
300  dataSet->GetPointCells(i, patchCellIDs);
301  // get total number of gauss points in patch and assign element size to
302  // patch generating node
303  int numPatchPoints = 0;
304  // also get average size of elements in patch
305  double nodeSize = 0;
306  for (int k = 0; k < patchCellIDs->GetNumberOfIds(); ++k)
307  {
308  // put current patch cell into genCell
309  dataSet->GetCell(patchCellIDs->GetId(k), genCell);
310  int cellType = dataSet->GetCell(
311  patchCellIDs->GetId(k))->GetCellType();
312  numPatchPoints += dict[cellType]->GetNumberOfQuadraturePoints();
313  //nodeSize += cbrt(
314  // 2.356194490192344 * cubature->computeCellVolume(genCell, cellType));
315  nodeSize += std::sqrt(genCell->GetLength2());
316  }
317  // patch-averaged node size
318  nodeSize /= patchCellIDs->GetNumberOfIds();
319  nodeSizes->InsertTuple(i, &nodeSize);
320  // coordinates of each gauss point in patch
321  std::vector<std::vector<double>> coords(numPatchPoints);
322  // vector of components of data at all gauss points in patch
323  std::vector<VectorXd> data(totalComponents);
324  for (int k = 0; k < totalComponents; ++k)
325  {
326  data[k].resize(numPatchPoints);
327  }
328 
329  int pntNum = 0;
330  for (int j = 0; j < patchCellIDs->GetNumberOfIds(); ++j)
331  {
332  pntDataPairVec pntsAndData = cubature->getGaussPointsAndDataAtCell(
333  patchCellIDs->GetId(j));
334  extractAxesAndData(pntsAndData, coords, data, numComponents, pntNum);
335  }
336 
337  // get coordinate of node that generates patch
338  std::vector<double> genNodeCoord(3);
339  dataSet->GetPoint(i, genNodeCoord.data());
340  // regularizing coordinates for preconditioning of basis matrix
341  regularizeCoords(coords, genNodeCoord);
342  // construct polyApprox from coords
343  std::unique_ptr<polyApprox> patchPolyApprox
344  = polyApprox::CreateUnique(order, coords);
345  // = new orthoPoly3D(order, coords);
346  int currComp = 0;
347  for (int k = 0; k < numComponents.size(); ++k)
348  {
349  auto *comps = new double[numComponents[k]];
350  auto *refComps = new double[numComponents[k]];
351  auto *errorComps = new double[numComponents[k]];
352  pd->GetArray(arrayIDs[k])->GetTuple(i, refComps);
353  for (int l = 0; l < numComponents[k]; ++l)
354  {
355  patchPolyApprox->computeCoeff(data[currComp]);
356  comps[l] = patchPolyApprox->eval(genNodeCoord);
357  errorComps[l] = std::pow(comps[l] - refComps[l], 2);
358  patchPolyApprox->resetCoeff();
359  ++currComp;
360  }
361  newPntData[k]->InsertTuple(i, comps);
362  errorPntData[k]->InsertTuple(i, errorComps);
363  delete[] comps;
364  delete[] refComps;
365  delete[] errorComps;
366  }
367  }
368  for (int k = 0; k < numComponents.size(); ++k)
369  {
370  //pd->AddArray(newPntData[k]);
371  pd->AddArray(errorPntData[k]);
372  }
373 
374  pd->AddArray(nodeSizes);
375  return cubature->integrateOverAllCells(errorNames, true);
376 }
static std::unique_ptr< polyApprox > CreateUnique(int order, const std::vector< std::vector< double >> &coords)
Definition: polyApprox.C:78
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 eval(const std::vector< double > &coord) const
Definition: polyApprox.C:102
void computeCoeff(const Eigen::VectorXd &data)
Definition: polyApprox.C:85
geoMeshBase * New(MeshType meshType)
Create a new mesh object.
std::vector< pntDataPair > pntDataPairVec
Definition: Cubature.H:55
void resetCoeff()
Definition: polyApprox.C:95
VTKCellType cellType
Definition: inpGeoMesh.C:129
void regularizeCoords(std::vector< std::vector< double >> &coords, std::vector< double > &genNodeCoord) const
void extractAxesAndData(const pntDataPairVec &pntsAndData, std::vector< std::vector< double >> &coords, std::vector< Eigen::VectorXd > &data, const std::vector< int > &numComponents, int &pntNum) const
Definition: patchRecovery.C:49
std::unique_ptr< GaussCubature > cubature
Definition: patchRecovery.H:67

◆ extractAxesAndData()

void PatchRecovery::extractAxesAndData ( const pntDataPairVec pntsAndData,
std::vector< std::vector< double >> &  coords,
std::vector< Eigen::VectorXd > &  data,
const std::vector< int > &  numComponents,
int &  pntNum 
) const
private

Definition at line 49 of file patchRecovery.C.

Referenced by computeNodalError(), and recoverNodalSolution().

54 {
55  for (const auto &i : pntsAndData)
56  {
57  coords[pntNum] = i.first;
58  //nemAux::printVec(coords[pntNum]);
59  int currcomp = 0;
60  for (int numComponent : numComponents)
61  {
62  for (int k = 0; k < numComponent; ++k)
63  {
64  data[currcomp](pntNum) = i.second[currcomp];
65  ++currcomp;
66  }
67  }
68  pntNum += 1;
69  }
70 }

◆ getMinMaxCoords()

std::vector< double > PatchRecovery::getMinMaxCoords ( const std::vector< std::vector< double >> &  coords) const
private

Definition at line 74 of file patchRecovery.C.

Referenced by regularizeCoords().

75 {
76  std::vector<double> minMaxXYZ(6);
77  for (int i = 0; i < 3; ++i)
78  {
79  minMaxXYZ[2 * i] = coords[0][i];
80  minMaxXYZ[2 * i + 1] = minMaxXYZ[2 * i];
81  }
82 
83  for (const auto &coord : coords)
84  {
85  for (int j = 0; j < 3; ++j)
86  {
87  // min
88  if (minMaxXYZ[2 * j] > coord[j])
89  {
90  minMaxXYZ[2 * j] = coord[j];
91  }
92  // max
93  else if (minMaxXYZ[2 * j + 1] < coord[j])
94  {
95  minMaxXYZ[2 * j + 1] = coord[j];
96  }
97  }
98  }
99  return minMaxXYZ;
100 }

◆ operator=()

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

◆ recoverNodalSolution()

void PatchRecovery::recoverNodalSolution ( bool  ortho)

Definition at line 118 of file patchRecovery.C.

References cellType, orthoPoly3D::computeA(), polyApprox::computeCoeff(), polyApprox::CreateUnique(), orthoPoly3D::CreateUnique(), cubature, data, polyApprox::eval(), orthoPoly3D::eval(), extractAxesAndData(), NEM::MSH::New(), order, regularizeCoords(), orthoPoly3D::resetA(), and polyApprox::resetCoeff().

119 {
120  std::cout << "WARNING: mesh is assumed to be properly numbered" << std::endl;
121  // getting node mesh from cubature
122  vtkSmartPointer<vtkDataSet> dataSet = cubature->getDataSet();
123  int numPoints = dataSet->GetNumberOfPoints();
124  // initializing id list for patch cells
125  vtkSmartPointer<vtkIdList> patchCellIDs = vtkSmartPointer<vtkIdList>::New();
126  // getting cubature scheme dictionary for indexing
127  vtkQuadratureSchemeDefinition **dict = cubature->getDict();
128  std::vector<int> numComponents = cubature->getNumComponents();
129  // getting number of doubles representing all data at point
130  int totalComponents = cubature->getTotalComponents();
131  // storage for new point data
132  std::vector<vtkSmartPointer<vtkDoubleArray>> newPntData(numComponents.size());
133 
134  // initializing double arrays for new data
135  for (int i = 0; i < numComponents.size(); ++i)
136  {
137  std::string name = dataSet->GetPointData()
138  ->GetArrayName(cubature->getArrayIDs()[i]);
139  name += "New";
140  newPntData[i] = vtkSmartPointer<vtkDoubleArray>::New();
141  newPntData[i]->SetName(name.c_str());
142  newPntData[i]->SetNumberOfComponents(numComponents[i]);
143  newPntData[i]->SetNumberOfTuples(numPoints);
144  }
145 
146  // int totPatchPoints = 0;
147  // looping over all points, looping over patches per point
148  for (int i = 0; i < numPoints; ++i) //FIXME
149  {
150  // get ids of cells in patch of node
151  dataSet->GetPointCells(i, patchCellIDs);
152  // get total number of gauss points in patch
153  int numPatchPoints = 0;
154  for (int k = 0; k < patchCellIDs->GetNumberOfIds(); ++k)
155  {
156  int cellType = dataSet->GetCell(
157  patchCellIDs->GetId(k))->GetCellType();
158  numPatchPoints += dict[cellType]->GetNumberOfQuadraturePoints();
159  }
160 
161  if (patchCellIDs->GetNumberOfIds() < 2)
162  {
163  std::cerr << "Only " << patchCellIDs->GetNumberOfIds()
164  << " cell in patch of point " << i << std::endl;
165  }
166 
167  // coordinates of each gauss point in patch
168  std::vector<std::vector<double>> coords(numPatchPoints);
169  // vector of components of data at all gauss points in patch
170  std::vector<VectorXd> data(totalComponents);
171  for (int k = 0; k < totalComponents; ++k)
172  {
173  data[k].resize(numPatchPoints);
174  }
175 
176  int pntNum = 0;
177  for (int j = 0; j < patchCellIDs->GetNumberOfIds(); ++j)
178  {
179  pntDataPairVec pntsAndData = cubature->getGaussPointsAndDataAtCell(
180  patchCellIDs->GetId(j));
181  extractAxesAndData(pntsAndData, coords, data, numComponents, pntNum);
182  }
183 
184  // get coordinate of node that generates patch
185  std::vector<double> genNodeCoord(3);
186  dataSet->GetPoint(i, genNodeCoord.data());
187  // regularizing coordinates for preconditioning of basis matrix
188  regularizeCoords(coords, genNodeCoord);
189  if (!ortho)
190  {
191  // construct polyApprox from coords
192  std::unique_ptr<polyApprox> patchPolyApprox
193  = polyApprox::CreateUnique(order, coords);
194  // = new orthoPoly3D(order, coords);
195  int currComp = 0;
196  for (int k = 0; k < numComponents.size(); ++k)
197  {
198  auto *comps = new double[numComponents[k]];
199  for (int l = 0; l < numComponents[k]; ++l)
200  {
201  patchPolyApprox->computeCoeff(data[currComp]);
202  comps[l] = patchPolyApprox->eval(genNodeCoord);
203  patchPolyApprox->resetCoeff();
204  ++currComp;
205  }
206  newPntData[k]->InsertTuple(i, comps);
207  delete[] comps;
208  }
209  }
210  else
211  {
212  for (int k = 0; k < patchCellIDs->GetNumberOfIds(); ++k)
213  {
214  std::cout << "point " << i << " patch cell: " << patchCellIDs->GetId(k)
215  << std::endl;
216  }
217 
218  std::unique_ptr<orthoPoly3D> patchPolyApprox
219  = orthoPoly3D::CreateUnique(order, coords);
220  int currComp = 0;
221  for (int k = 0; k < numComponents.size(); ++k)
222  {
223  auto *comps = new double[numComponents[k]];
224  for (int l = 0; l < numComponents[k]; ++l)
225  {
226  std::cout << "computing coefficients of ortho polys" << std::endl;
227  patchPolyApprox->computeA(data[currComp]);
228  comps[l] = patchPolyApprox->eval(genNodeCoord);
229  patchPolyApprox->resetA();
230  ++currComp;
231  }
232  newPntData[k]->InsertTuple(i, comps);
233  delete[] comps;
234  }
235  }
236  }
237  for (int k = 0; k < numComponents.size(); ++k)
238  {
239  dataSet->GetPointData()->AddArray(newPntData[k]);
240  }
241 }
static std::unique_ptr< polyApprox > CreateUnique(int order, const std::vector< std::vector< double >> &coords)
Definition: polyApprox.C:78
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 eval(const std::vector< double > &coord) const
Definition: polyApprox.C:102
void computeCoeff(const Eigen::VectorXd &data)
Definition: polyApprox.C:85
geoMeshBase * New(MeshType meshType)
Create a new mesh object.
std::vector< pntDataPair > pntDataPairVec
Definition: Cubature.H:55
void resetCoeff()
Definition: polyApprox.C:95
double eval(const std::vector< double > &coord)
Definition: orthoPoly3D.C:309
static std::unique_ptr< orthoPoly3D > CreateUnique(int _order, const std::vector< std::vector< double >> &coords)
Definition: orthoPoly3D.C:245
VTKCellType cellType
Definition: inpGeoMesh.C:129
void regularizeCoords(std::vector< std::vector< double >> &coords, std::vector< double > &genNodeCoord) const
void extractAxesAndData(const pntDataPairVec &pntsAndData, std::vector< std::vector< double >> &coords, std::vector< Eigen::VectorXd > &data, const std::vector< int > &numComponents, int &pntNum) const
Definition: patchRecovery.C:49
std::unique_ptr< GaussCubature > cubature
Definition: patchRecovery.H:67
void resetA()
Definition: orthoPoly3D.C:299
void computeA(const Eigen::VectorXd &sigma)
Definition: orthoPoly3D.C:254

◆ regularizeCoords()

void PatchRecovery::regularizeCoords ( std::vector< std::vector< double >> &  coords,
std::vector< double > &  genNodeCoord 
) const
private

Definition at line 103 of file patchRecovery.C.

References getMinMaxCoords().

Referenced by computeNodalError(), and recoverNodalSolution().

105 {
106  std::vector<double> minMaxXYZ = getMinMaxCoords(coords);
107  for (int j = 0; j < 3; ++j)
108  {
109  double coord_min = minMaxXYZ[2 * j];
110  double bound = minMaxXYZ[2 * j + 1] - coord_min;
111  for (auto &&coord : coords)
112  coord[j] = -1 + 2 * (coord[j] - coord_min) / bound;
113  genNodeCoord[j] = -1 + 2 * (genNodeCoord[j] - coord_min) / bound;
114  }
115 }
std::vector< double > getMinMaxCoords(const std::vector< std::vector< double >> &coords) const
Definition: patchRecovery.C:74

Member Data Documentation

◆ cubature

std::unique_ptr<GaussCubature> PatchRecovery::cubature
private

Definition at line 67 of file patchRecovery.H.

Referenced by computeNodalError(), PatchRecovery(), and recoverNodalSolution().

◆ order

int PatchRecovery::order
private

Definition at line 68 of file patchRecovery.H.

Referenced by computeNodalError(), and recoverNodalSolution().


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