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.
GradSizeField.C
Go to the documentation of this file.
1 /*******************************************************************************
2 * Promesh *
3 * Copyright (C) 2022, IllinoisRocstar LLC. All rights reserved. *
4 * *
5 * Promesh is the property of IllinoisRocstar LLC. *
6 * *
7 * IllinoisRocstar LLC *
8 * Champaign, IL *
9 * www.illinoisrocstar.com *
10 * promesh@illinoisrocstar.com *
11 *******************************************************************************/
12 /*******************************************************************************
13 * This file is part of Promesh *
14 * *
15 * This version of Promesh is free software: you can redistribute it and/or *
16 * modify it under the terms of the GNU Lesser General Public License as *
17 * published by the Free Software Foundation, either version 3 of the License, *
18 * or (at your option) any later version. *
19 * *
20 * Promesh is distributed in the hope that it will be useful, but WITHOUT ANY *
21 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *
22 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more *
23 * details. *
24 * *
25 * You should have received a copy of the GNU Lesser General Public License *
26 * along with this program. If not, see <https://www.gnu.org/licenses/>. *
27 * *
28 *******************************************************************************/
30 
31 #include <vtkCell.h>
32 #include <vtkCellData.h>
33 #include <vtkCellIterator.h>
34 #include <vtkDoubleArray.h>
35 #include <vtkGenericCell.h>
36 #include <vtkIdList.h>
37 
38 #include "AuxiliaryFunctions.H"
39 
40 namespace NEM {
41 namespace ADP {
42 
43 // constructor
44 GradSizeField::GradSizeField(vtkDataSet *_ds, int arrayID, double _dev_mult,
45  bool _maxIsmin)
46  : SizeFieldBase(_ds, arrayID, _dev_mult, _maxIsmin, "GradientSF") {
47  std::cout << "GradSizeField constructed" << std::endl;
48 }
49 
50 // computes the gradient of point data at a cell using
51 // derivatives of shape interpolation functions
52 std::vector<double> GradSizeField::computeGradAtCell(vtkCell *cell,
53  vtkDataArray *da) {
54  vtkIdList *point_ids = cell->GetPointIds();
55  vtkIdType numPointsInCell = point_ids->GetNumberOfIds();
56  int dim = da->GetNumberOfComponents();
57 
58  // populating array with point data of cell
59  std::vector<double> values(dim * numPointsInCell);
60  for (vtkIdType i = 0; i < numPointsInCell; ++i) {
61  std::vector<double> comps(dim);
62  da->GetTuple(point_ids->GetId(i), comps.data());
63  for (int j = 0; j < dim; ++j) values[i * dim + j] = comps[j];
64  }
65  // # vals per vertex * # deriv directions (x,y,z)
66  std::vector<double> gradient(dim * 3);
67  std::vector<double> tmp(3, 0.0);
68  // getting gradient of field over cell (Jacobian matrix for data)
69  cell->Derivatives(0, tmp.data(), values.data(), dim, gradient.data());
70  /* The Derivatives member for a cell computes the inverse of the Jacobian
71  * transforming physical coordinates to parametric space, the derivatives of
72  * the shape functions in parametric space and the interpolated values of
73  * the derivatives of data for the cell in parametric space. It then
74  * computes the matrix product of the inverse Jacobian with the interpolated
75  * derivatives to transform them to physical coordinates. */
76  return gradient;
77 }
78 
79 // compute 2 norm of gradient of point data at each cell
80 std::vector<double> GradSizeField::computeL2GradAtAllCells(vtkDataSet *ds,
81  vtkDataArray *da) {
82  std::vector<double> result;
83  result.reserve(ds->GetNumberOfCells());
84 
85  vtkCellIterator *it = ds->NewCellIterator();
86  vtkSmartPointer<vtkGenericCell> cell = vtkSmartPointer<vtkGenericCell>::New();
87  for (it->InitTraversal(); !it->IsDoneWithTraversal(); it->GoToNextCell()) {
88  it->GetCell(cell);
89  result.emplace_back(nemAux::l2_Norm(computeGradAtCell(cell, da)));
90  }
91  it->Delete();
92 
93  return result;
94 }
95 
96 // compute size field and insert as cell data into mesh's dataSet
97 void GradSizeField::computeSizeField(vtkDataArray *da) {
98  // populate vector with 2 norm of gradient/value of physical variable
99  std::vector<double> values = computeL2GradAtAllCells(ds, da);
100 
101  if (values.empty()) {
102  std::cerr << "size array hasn't been populated!" << std::endl;
103  exit(1);
104  }
105 
106  mutateValues(values);
107 
108  vtkSmartPointer<vtkDoubleArray> da2 = vtkSmartPointer<vtkDoubleArray>::New();
109  da2->SetName(sfname.c_str());
110  da2->SetNumberOfComponents(1);
111  for (vtkIdType i = 0; i < ds->GetNumberOfCells(); ++i)
112  da2->InsertNextTypedTuple(&values[i]);
113  ds->GetCellData()->AddArray(da2);
114 }
115 
116 } // namespace ADP
117 } // namespace NEM
vtkSmartPointer< vtkDataSet > ds
Definition: SizeFieldGen.H:76
geoMeshBase * New(MeshType meshType)
Create a new mesh object.
vtkSmartPointer< vtkDataArray > da
Definition: SizeFieldGen.H:79
static std::vector< double > computeL2GradAtAllCells(vtkDataSet *ds, vtkDataArray *da)
Definition: GradSizeField.C:80
void mutateValues(std::vector< double > &values) const
Definition: SizeFieldGen.C:112
GradSizeField(vtkDataSet *_ds, int arrayID, double _dev_mult, bool _maxIsmin)
Definition: GradSizeField.C:44
static std::vector< double > computeGradAtCell(vtkCell *cell, vtkDataArray *da)
Definition: GradSizeField.C:52
T l2_Norm(const std::vector< T > &x)
void computeSizeField(vtkDataArray *da) override
Definition: GradSizeField.C:97