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.
Refine.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 *******************************************************************************/
29 #include "Refinement/Refine.H"
30 
31 #include <vtkCellData.h>
32 #include <vtkPointData.h>
33 
34 #include "AuxiliaryFunctions.H"
35 #include "Drivers/TransferDriver.H"
36 #include "Mesh/gmshMesh.H"
37 
38 namespace NEM {
39 namespace ADP {
40 
41 Refine::Refine(meshBase *_mesh, const std::string &method, int arrayID,
42  double dev_mult, bool maxIsmin, double edge_scale,
43  const std::string &_ofname, double sizeFactor, int order)
44  : mesh(_mesh), ofname(_ofname), bndrConst(false) {
45  if (method != "uniform") {
46  // creates sizeField
47  mesh->generateSizeField(method, arrayID, dev_mult, maxIsmin, sizeFactor,
48  order);
49  initAdaptive(arrayID, method);
50  } else if (method == "uniform") {
51  initUniform(edge_scale);
52  }
53 }
54 
56  // destructor for adapter also destroys size field
57  if (adapter) {
58  delete adapter;
59  adapter = nullptr;
60  }
61  /*
62  if (bSF)
63  {
64  delete bSF;
65  bSF = nullptr;
66  std::cout << "here1" << std::endl;
67  }
68  if (pwlSF)
69  {
70  delete pwlSF;
71  pwlSF = nullptr;
72  std::cout << "here2" << std::endl;
73  }
74  */
75  if (MadMesh) {
76  MAd::M_delete(MadMesh);
77  MadMesh = nullptr;
78  }
79 
80  std::cout << "Refine destroyed" << std::endl;
81 }
82 
83 void Refine::initUniform(double edge_scale) {
84  std::cout << "Uniform Refinement Selected" << std::endl;
85 
86  auto *gMesh = new gmshMesh(mesh);
87  gMesh->write("converted.msh", 2.0, false);
88 
89  MAd::pGModel gmodel = nullptr;
90 
91  MadMesh = MAd::M_new(gmodel);
92  MAd::M_load(MadMesh, "converted.msh");
94  // DISCRETE/PWLSF SIZEFIELD
95  pwlSF = new MAd::PWLSField(MadMesh);
96  // sets size as mean edge length squared for edges adjacent to given vertex
97  pwlSF->setCurrentSize();
98  pwlSF->scale(edge_scale);
99  // timing adapter construction
100  nemAux::Timer T;
101  T.start();
102  // instantiating adapter with linear sf
103  adapter = new MAd::MeshAdapter(MadMesh, pwlSF);
104 
105  // TJW
106  // option to constrain boundary edges when refining
107  if (bndrConst) adapter->setConstraint(bnd);
108 
109  T.stop();
110  std::cout << "Time for adapter construction (ms): " << T.elapsed() << "\n \n";
111  std::cout << "Refine constructed" << std::endl;
112 }
113 
114 void Refine::initAdaptive(int arrayID, const std::string &method) {
115  pwlSF = nullptr;
116  auto *gMesh = new gmshMesh(mesh);
117  gMesh->write("converted.msh", 2.0, false);
118 
119  vtkCellData *cd = mesh->getDataSet()->GetCellData();
120  int i = 0;
121  std::string array_name;
122  if (cd) {
123  array_name = mesh->getDataSet()->GetPointData()->GetArrayName(arrayID);
124  if (method == "gradient")
125  array_name.append("GradientSF");
126  else if (method == "value")
127  array_name.append("ValueSF");
128  else if (method == "Z2 Error Estimator")
129  array_name.append("Z2ErrorSF");
130  for (i = 0; i < cd->GetNumberOfArrays(); ++i) {
131  if (array_name == cd->GetArrayName(i)) break;
132  }
133  if (i == cd->GetNumberOfArrays()) {
134  std::cerr << "Error: Did not find " << array_name << " in cell data set"
135  << std::endl;
136  exit(1);
137  }
138  }
139  mesh->writeMSH("backgroundSF.msh", "cell", i, true);
140  mesh->unsetCellDataArray(array_name);
141 
142  MAd::pGModel gmodel = nullptr;
143  MadMesh = MAd::M_new(gmodel);
144  MAd::M_load(MadMesh, "converted.msh");
146 
147  bSF = new MAd::BackgroundSF("backgroundSF");
148  bSF->loadData("backgroundSF.msh");
149 
150  std::cout << "\n \n Beginning Adapter Construction" << std::endl;
151  // timing adapter construction
152  nemAux::Timer T;
153  T.start();
154  // instantiating adapter with background sizeField
155  adapter = new MAd::MeshAdapter(MadMesh, bSF);
156  T.stop();
157  std::cout << "Time for adapter construction (ms): " << T.elapsed() << "\n \n";
158  std::cout << "Refine constructed" << std::endl;
159 }
160 
161 void Refine::run(bool transferData, bool bndryConstraint) {
162  if (!adapter) {
163  std::cerr << "Adapter hasn't been constructed!" << std::endl;
164  exit(1);
165  }
166  // set boundary constraint flag
167  bndrConst = bndryConstraint;
168  // option to constrain boundary edges when refining
169  if (bndrConst) adapter->setConstraint(bnd);
170  // Output situation before refinement
171  std::cout << "Statistics before refinement: " << std::endl;
172  adapter->printStatistics(std::cout);
173 
174  // Adaptive refinement
175  std::cout << "Refining the mesh ..." << std::endl;
176  adapter->run();
177  std::cout << "Statistics after refinement: " << std::endl;
178  adapter->printStatistics(std::cout);
179 
180  // running Laplacian smoothing
181  std::cout << "Optimizing the mesh" << std::endl;
182 
183  adapter->checkTheMesh(10);
184 
185  for (int i = 0; i < 1; ++i) {
186  adapter->LaplaceSmoothing();
187  adapter->splitLongestEdges();
188  adapter->removeSlivers();
189  adapter->optimiseEdgeLength();
190  adapter->optimiseElementShape();
191  }
192  /* there is a fast laplace smoothing function available where instead of
193  * computing the optimal position it uses the cavity center. The center is the
194  * initial position passed to the routine "computeOptimalLocation" before it
195  * calculates optimal. The optimal way is run by default. If we modify
196  * line 714/718 in AdaptInterface.cc to laplOp->runFast we can use the
197  * fast method */
198 
199  // Outputs final mesh
200  std::cout << "Statistics after optimization: " << std::endl;
201  adapter->printStatistics(std::cout);
202 
203  // unclassifying boundary elements for proper output
205  // writing refined mesh to file in msh format
206  MAd::M_writeMsh(MadMesh, "refined.msh", 2);
207  meshBase *refinedVTK = meshBase::exportGmshToVtk("refined.msh");
208 
209  // mesh->setCheckQuality(1);
210 
211  if (transferData) {
212  // mesh->transfer(refinedVTK, "Consistent Interpolation");
214  mesh, refinedVTK, "Consistent Interpolation");
215  transfer->run(mesh->getNewArrayNames());
216  }
217 
218  refinedVTK->setFileName(ofname);
219  refinedVTK->report();
220  refinedVTK->write();
221 
222  delete refinedVTK;
223 }
224 
226  // finding and classifying boundary elements as 2d
227  MadMesh->classify_unclassified_entities();
228  MadMesh->destroyStandAloneEntities();
229  bnd = (MAd::pGEntity)MAd::GM_faceByTag(MadMesh->model, 0);
230  MadMesh->classify_grid_boundaries(bnd);
231 }
232 
234  // unclassifying boundary elements for proper output
235  MadMesh->unclassify_grid_boundaries();
236 }
237 
238 } // namespace ADP
239 } // namespace NEM
static meshBase * exportGmshToVtk(const std::string &fname)
construct vtkMesh from gmsh msh file (called in Create methods)
Definition: meshBase.C:409
void setFileName(const std::string &fname)
set the file name.
Definition: meshBase.H:675
A brief description of meshBase.
Definition: meshBase.H:64
MAd::pMesh MadMesh
Definition: Refine.H:56
void classifyBoundaries()
Definition: Refine.C:225
MAd::pGEntity bnd
Definition: Refine.H:61
std::string ofname
Definition: Refine.H:60
vtkSmartPointer< vtkDataSet > getDataSet() const
get this meshes&#39; dataSet
Definition: meshBase.H:308
void generateSizeField(const std::string &method, int arrayID, double dev_mlt, bool maxIsmin, double sizeFactor=1.0, int order=1)
generate size field based on method and given a point data array.
Definition: meshBase.C:396
virtual void write() const
write the mesh to file named after the private var &#39;filename&#39;.
Definition: meshBase.H:598
bool bndrConst
Definition: Refine.H:62
std::shared_ptr< meshBase > mesh
MAd::MeshAdapter * adapter
Definition: Refine.H:59
virtual void unsetCellDataArray(int arrayID)
delete array with id from dataSet&#39;s cell data
Definition: meshBase.H:391
MAd::BackgroundSF * bSF
Definition: Refine.H:57
void initAdaptive(int arrayID, const std::string &method)
Definition: Refine.C:114
void run(bool transferData, bool bndryConstraint=false)
Definition: Refine.C:161
meshBase * mesh
Definition: Refine.H:55
virtual void report() const
generate a report of the mesh
Definition: meshBase.H:540
std::vector< std::string > getNewArrayNames()
get new array names for use in transfer
Definition: meshBase.H:698
static std::shared_ptr< TransferBase > CreateTransferObject(meshBase *srcmsh, meshBase *trgmsh, const std::string &method)
void unClassifyBoundaries()
Definition: Refine.C:233
Refine(meshBase *_mesh, const std::string &method, int arrayID, double dev_mult, bool maxIsmin, double edge_scale, const std::string &_ofname, double sizeFactor=1.0, int order=1)
Definition: Refine.C:41
MAd::PWLSField * pwlSF
Definition: Refine.H:58
void initUniform(double edge_scale)
Definition: Refine.C:83
void writeMSH(std::ofstream &outputStream)
convert to gmsh format without data
Definition: meshBase.C:1078