34 using Eigen::VectorXd;
42 const std::vector<int> &arrayIDs)
50 std::vector<std::vector<double>> &coords,
51 std::vector<VectorXd> &
data,
52 const std::vector<int> &numComponents,
55 for (
const auto &i : pntsAndData)
57 coords[pntNum] = i.first;
60 for (
int numComponent : numComponents)
62 for (
int k = 0; k < numComponent; ++k)
64 data[currcomp](pntNum) = i.second[currcomp];
76 std::vector<double> minMaxXYZ(6);
77 for (
int i = 0; i < 3; ++i)
79 minMaxXYZ[2 * i] = coords[0][i];
80 minMaxXYZ[2 * i + 1] = minMaxXYZ[2 * i];
83 for (
const auto &coord : coords)
85 for (
int j = 0; j < 3; ++j)
88 if (minMaxXYZ[2 * j] > coord[j])
90 minMaxXYZ[2 * j] = coord[j];
93 else if (minMaxXYZ[2 * j + 1] < coord[j])
95 minMaxXYZ[2 * j + 1] = coord[j];
104 std::vector<double> &genNodeCoord)
const 107 for (
int j = 0; j < 3; ++j)
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;
120 std::cout <<
"WARNING: mesh is assumed to be properly numbered" << std::endl;
122 vtkSmartPointer<vtkDataSet> dataSet =
cubature->getDataSet();
123 int numPoints = dataSet->GetNumberOfPoints();
127 vtkQuadratureSchemeDefinition **dict =
cubature->getDict();
128 std::vector<int> numComponents =
cubature->getNumComponents();
130 int totalComponents =
cubature->getTotalComponents();
132 std::vector<vtkSmartPointer<vtkDoubleArray>> newPntData(numComponents.size());
135 for (
int i = 0; i < numComponents.size(); ++i)
137 std::string name = dataSet->GetPointData()
138 ->GetArrayName(
cubature->getArrayIDs()[i]);
141 newPntData[i]->SetName(name.c_str());
142 newPntData[i]->SetNumberOfComponents(numComponents[i]);
143 newPntData[i]->SetNumberOfTuples(numPoints);
148 for (
int i = 0; i < numPoints; ++i)
151 dataSet->GetPointCells(i, patchCellIDs);
153 int numPatchPoints = 0;
154 for (
int k = 0; k < patchCellIDs->GetNumberOfIds(); ++k)
157 patchCellIDs->GetId(k))->GetCellType();
158 numPatchPoints += dict[
cellType]->GetNumberOfQuadraturePoints();
161 if (patchCellIDs->GetNumberOfIds() < 2)
163 std::cerr <<
"Only " << patchCellIDs->GetNumberOfIds()
164 <<
" cell in patch of point " << i << std::endl;
168 std::vector<std::vector<double>> coords(numPatchPoints);
170 std::vector<VectorXd>
data(totalComponents);
171 for (
int k = 0; k < totalComponents; ++k)
173 data[k].resize(numPatchPoints);
177 for (
int j = 0; j < patchCellIDs->GetNumberOfIds(); ++j)
180 patchCellIDs->GetId(j));
185 std::vector<double> genNodeCoord(3);
186 dataSet->GetPoint(i, genNodeCoord.data());
192 std::unique_ptr<polyApprox> patchPolyApprox
196 for (
int k = 0; k < numComponents.size(); ++k)
198 auto *comps =
new double[numComponents[k]];
199 for (
int l = 0; l < numComponents[k]; ++l)
202 comps[l] = patchPolyApprox->
eval(genNodeCoord);
206 newPntData[k]->InsertTuple(i, comps);
212 for (
int k = 0; k < patchCellIDs->GetNumberOfIds(); ++k)
214 std::cout <<
"point " << i <<
" patch cell: " << patchCellIDs->GetId(k)
218 std::unique_ptr<orthoPoly3D> patchPolyApprox
221 for (
int k = 0; k < numComponents.size(); ++k)
223 auto *comps =
new double[numComponents[k]];
224 for (
int l = 0; l < numComponents[k]; ++l)
226 std::cout <<
"computing coefficients of ortho polys" << std::endl;
227 patchPolyApprox->
computeA(data[currComp]);
228 comps[l] = patchPolyApprox->
eval(genNodeCoord);
229 patchPolyApprox->
resetA();
232 newPntData[k]->InsertTuple(i, comps);
237 for (
int k = 0; k < numComponents.size(); ++k)
239 dataSet->GetPointData()->AddArray(newPntData[k]);
247 std::cout <<
"WARNING: mesh is assumed to be properly numbered" << std::endl;
249 vtkSmartPointer<vtkDataSet> dataSet =
cubature->getDataSet();
250 std::vector<int> arrayIDs =
cubature->getArrayIDs();
251 int numPoints = dataSet->GetNumberOfPoints();
255 vtkQuadratureSchemeDefinition **dict =
cubature->getDict();
256 std::vector<int> numComponents =
cubature->getNumComponents();
258 int totalComponents =
cubature->getTotalComponents();
260 std::vector<vtkSmartPointer<vtkDoubleArray>> newPntData(numComponents.size());
262 std::vector<vtkSmartPointer<vtkDoubleArray>> errorPntData(
263 numComponents.size());
265 vtkSmartPointer<vtkPointData> pd = dataSet->GetPointData();
267 std::vector<std::string> errorNames(numComponents.size());
270 for (
int i = 0; i < numComponents.size(); ++i)
272 std::string name = pd->GetArrayName(arrayIDs[i]);
273 std::string newName = name +
"New";
275 newPntData[i]->SetName(newName.c_str());
276 newPntData[i]->SetNumberOfComponents(numComponents[i]);
277 newPntData[i]->SetNumberOfTuples(numPoints);
279 std::string errName = name +
"Error";
281 errorPntData[i]->SetName(errName.c_str());
282 errorPntData[i]->SetNumberOfComponents(numComponents[i]);
283 errorPntData[i]->SetNumberOfTuples(numPoints);
284 errorNames[i] = errName;
289 nodeSizes->SetName(
"nodeSizes");
290 nodeSizes->SetNumberOfComponents(1);
291 nodeSizes->SetNumberOfTuples(numPoints);
297 for (
int i = 0; i < numPoints; ++i)
300 dataSet->GetPointCells(i, patchCellIDs);
303 int numPatchPoints = 0;
306 for (
int k = 0; k < patchCellIDs->GetNumberOfIds(); ++k)
309 dataSet->GetCell(patchCellIDs->GetId(k), genCell);
311 patchCellIDs->GetId(k))->GetCellType();
312 numPatchPoints += dict[
cellType]->GetNumberOfQuadraturePoints();
315 nodeSize += std::sqrt(genCell->GetLength2());
318 nodeSize /= patchCellIDs->GetNumberOfIds();
319 nodeSizes->InsertTuple(i, &nodeSize);
321 std::vector<std::vector<double>> coords(numPatchPoints);
323 std::vector<VectorXd>
data(totalComponents);
324 for (
int k = 0; k < totalComponents; ++k)
326 data[k].resize(numPatchPoints);
330 for (
int j = 0; j < patchCellIDs->GetNumberOfIds(); ++j)
333 patchCellIDs->GetId(j));
338 std::vector<double> genNodeCoord(3);
339 dataSet->GetPoint(i, genNodeCoord.data());
343 std::unique_ptr<polyApprox> patchPolyApprox
347 for (
int k = 0; k < numComponents.size(); ++k)
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)
356 comps[l] = patchPolyApprox->
eval(genNodeCoord);
357 errorComps[l] = std::pow(comps[l] - refComps[l], 2);
361 newPntData[k]->InsertTuple(i, comps);
362 errorPntData[k]->InsertTuple(i, errorComps);
368 for (
int k = 0; k < numComponents.size(); ++k)
371 pd->AddArray(errorPntData[k]);
374 pd->AddArray(nodeSizes);
375 return cubature->integrateOverAllCells(errorNames,
true);
static std::unique_ptr< polyApprox > CreateUnique(int order, const std::vector< std::vector< double >> &coords)
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< double > getMinMaxCoords(const std::vector< std::vector< double >> &coords) const
std::vector< std::vector< double > > computeNodalError()
double eval(const std::vector< double > &coord) const
void computeCoeff(const Eigen::VectorXd &data)
geoMeshBase * New(MeshType meshType)
Create a new mesh object.
std::vector< pntDataPair > pntDataPairVec
double eval(const std::vector< double > &coord)
static std::unique_ptr< orthoPoly3D > CreateUnique(int _order, const std::vector< std::vector< double >> &coords)
void recoverNodalSolution(bool ortho)
PatchRecovery(vtkDataSet *_dataSet, int _order, const std::vector< int > &arrayIDs)
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
std::unique_ptr< GaussCubature > cubature
void computeA(const Eigen::VectorXd &sigma)
static std::unique_ptr< GaussCubature > CreateUnique(vtkDataSet *_dataSet)