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.
omegahRefineSrv.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 <vtkInformation.h>
32 #include <vtkInformationVector.h>
33 #include <vtkObjectFactory.h>
34 #include <Omega_h_adapt.hpp>
35 #include <Omega_h_class.hpp>
36 
37 #include "Mesh/oshGeoMesh.H"
38 
39 namespace NEM {
40 namespace SRV {
41 
42 Omega_h::Verbosity ParseVerbosity(const std::string &verbosity) {
43  if (verbosity == "Silent")
44  return Omega_h::SILENT;
45  else if (verbosity == "Each Adapt")
46  return Omega_h::EACH_ADAPT;
47  else if (verbosity == "Each Rebuild")
48  return Omega_h::EACH_REBUILD;
49  else if (verbosity == "Extra Stats")
50  return Omega_h::EXTRA_STATS;
51 
52  std::cerr << verbosity << " is not a recognized verbosity level" << std::endl;
53  exit(1);
54 }
55 
56 Omega_h::VarCompareOpts ParseVarCompareOpts(const std::string &type,
57  Omega_h::Real tolerance,
58  Omega_h::Real floor) {
59  if (type == "None")
60  return {Omega_h::VarCompareOpts::NONE, tolerance, floor};
61  else if (type == "Relative")
62  return {Omega_h::VarCompareOpts::RELATIVE, tolerance, floor};
63  else if (type == "Absolute")
64  return {Omega_h::VarCompareOpts::ABSOLUTE, tolerance, floor};
65 
66  std::cerr << type << " is not a recognized variable compare type"
67  << std::endl;
68  exit(1);
69 }
70 
72 
74  this->SetNumberOfInputPorts(1);
75  this->SetNumberOfOutputPorts(1);
76  std::cout << "omegahRefineSrv constructed" << std::endl;
77 }
78 
80  std::cout << "omegahRefineSrv destructed" << std::endl;
81 }
82 
84  vtkInformation *info) {
85  info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "oshGeoMesh");
86  return 1;
87 }
88 
90  vtkInformation *info) {
91  info->Set(vtkDataObject::DATA_TYPE_NAME(), "oshGeoMesh");
92  return 1;
93 }
94 
95 int omegahRefineSrv::RequestData(vtkInformation *request,
96  vtkInformationVector **inputVector,
97  vtkInformationVector *outputVector) {
98  // get the info objects
99  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
100  vtkInformation *outInfo = outputVector->GetInformationObject(0);
101 
102  // get the input and output. Input may just have the geoMeshBase
103  // interface, but output should be an Omega_h mesh.
104  MSH::oshGeoMesh *input =
105  MSH::oshGeoMesh::SafeDownCast(inInfo->Get(vtkDataObject::DATA_OBJECT()));
106  MSH::oshGeoMesh *output =
107  MSH::oshGeoMesh::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT()));
108 
109  Omega_h::Mesh oshOutput = input->getOshMesh();
110 
111  if (!input->getOshMesh().is_valid()) return 0;
112 
113  // Attempt to classify points and cells, in case not called previously
114  Omega_h::finalize_classification(&oshOutput);
115 
116  // Define the metric input options
117  Omega_h::MetricInput metricInput;
118  metricInput.verbose = this->Verbose;
119  for (const auto &ms : this->MetricSources)
120  metricInput.add_source(
121  {ms.type, ms.knob, ms.tag_name, ms.isotropy, ms.scales});
122  metricInput.should_limit_lengths = this->ShouldLimitLengths;
123  if (this->MaxLength > 0.0) metricInput.max_length = this->MaxLength;
124  if (this->MinLength > 0.0) metricInput.min_length = this->MinLength;
125  metricInput.should_limit_gradation = this->ShouldLimitGradation;
126  if (this->MaxGradationRate > 0.0)
127  metricInput.max_gradation_rate = this->MaxGradationRate;
128  if (this->GradationConvergenceTolerance > 0.0)
129  metricInput.gradation_convergence_tolerance =
131  metricInput.should_limit_element_count = this->ShouldLimitElementCount;
132  if (this->MaxElementCount > 0.0)
133  metricInput.max_element_count = this->MaxElementCount;
134  if (this->MinElementCount > 0.0)
135  metricInput.min_element_count = this->MinElementCount;
136  if (this->ElementCountOverRelaxation > 0.0)
137  metricInput.element_count_over_relaxation =
139  if (this->NsmoothingSteps > 0)
140  metricInput.nsmoothing_steps = this->NsmoothingSteps;
141 
142  // Add implied metric and target metric
143  if (!this->MetricSources.empty())
144  Omega_h::generate_target_metric_tag(&oshOutput, metricInput);
145  Omega_h::add_implied_metric_tag(&oshOutput);
146 
147  // Define the adaptation options
148  Omega_h::AdaptOpts adaptOpts(&oshOutput);
149  if (this->MinLengthDesired > 0.0)
150  adaptOpts.min_length_desired = this->MinLengthDesired;
151  if (this->MaxLengthDesired > 0.0)
152  adaptOpts.max_length_desired = this->MaxLengthDesired;
153  if (this->MaxLengthAllowed > 0.0)
154  adaptOpts.max_length_allowed = this->MaxLengthAllowed;
155  if (this->MinQualityAllowed > 0.0)
156  adaptOpts.min_quality_allowed = this->MinQualityAllowed;
157  if (this->MinQualityDesired > 0.0)
158  adaptOpts.min_quality_desired = this->MinQualityDesired;
159  if (this->NsliverLayers > 0) adaptOpts.nsliver_layers = this->NsliverLayers;
160  adaptOpts.verbosity = ParseVerbosity(this->Verbosity);
161  if (this->LengthHistogramMin > 0.0)
162  adaptOpts.length_histogram_min = this->LengthHistogramMin;
163  if (this->LengthHistogramMax > 0.0)
164  adaptOpts.length_histogram_max = this->LengthHistogramMax;
165  if (this->NlengthHistogramBins > 0)
166  adaptOpts.nlength_histogram_bins = this->NlengthHistogramBins;
167  if (this->NqualityHistogramBins > 0)
168  adaptOpts.nquality_histogram_bins = this->NqualityHistogramBins;
169  adaptOpts.should_refine = this->ShouldRefine;
170  adaptOpts.should_coarsen = this->ShouldCoarsen;
171  adaptOpts.should_swap = this->ShouldSwap;
172  adaptOpts.should_coarsen_slivers = this->ShouldCoarsenSlivers;
173  adaptOpts.should_prevent_coarsen_flip = this->ShouldPreventCoarsenFlip;
174 
175  if (TransferOptsTypeMap.empty()) {
176  std::map<std::string, Omega_h_Transfer> transferMap;
177  const std::set<std::string> reservedTagsPoints{
178  "class_id", "class_dim", "momentum_velocity_fixed", "coordinates",
179  "warp", "metric", "target_metric", "global"};
180  for (Omega_h::Int i = 0; i < oshOutput.ntags(0); ++i) {
181  auto tag = oshOutput.get_tag(0, i);
182  if (reservedTagsPoints.find(tag->name()) == reservedTagsPoints.end()) {
183  bool inherit = true;
184  for (Omega_h::Int j = 1; j < oshOutput.dim(); ++j) {
185  if (!oshOutput.has_tag(j, tag->name())) {
186  inherit = false;
187  }
188  }
189  if (inherit) {
190  transferMap[tag->name()] = OMEGA_H_INHERIT;
191  } else if (tag->type() == OMEGA_H_REAL) {
192  transferMap[tag->name()] = OMEGA_H_LINEAR_INTERP;
193  }
194  }
195  }
196  const std::set<std::string> reservedTagsCells{"class_id", "class_dim",
197  "size", "quality"};
198  for (Omega_h::Int i = 0; i < oshOutput.ntags(oshOutput.dim()); ++i) {
199  auto tag = oshOutput.get_tag(oshOutput.dim(), i);
200  if (tag->type() == OMEGA_H_REAL &&
201  reservedTagsCells.find(tag->name()) == reservedTagsCells.end()) {
202  auto it = transferMap.find(tag->name());
203  if (it == transferMap.end()) {
204  transferMap[tag->name()] = OMEGA_H_POINTWISE;
205  }
206  }
207  }
208  adaptOpts.xfer_opts.type_map = transferMap;
209  } else {
210  adaptOpts.xfer_opts.type_map = TransferOptsTypeMap;
211  adaptOpts.xfer_opts.integral_map = TransferOptsIntegralMap;
212  for (const auto &idm : this->TransferOptsIntegralDiffuseMap)
213  adaptOpts.xfer_opts.integral_diffuse_map[idm.first] = ParseVarCompareOpts(
214  idm.second.type, idm.second.tolerance, idm.second.floor);
215  }
216 
217  // Omega_h::vtk::write_vtu("refine_test_" + std::to_string(0) + ".vtu",
218  // &oshOutput);
219 
220  // int i = 0;
221  do {
222  Omega_h::adapt(&oshOutput, adaptOpts);
223  // ++i;
224  // Omega_h::vtk::write_vtu("refine_test_" + std::to_string(i) + ".vtu",
225  // &oshOutput);
226  } while (Omega_h::approach_metric(&oshOutput, adaptOpts));
227 
228  output->setOshMesh(&oshOutput);
229 
230  return 1;
231 }
232 
233 } // namespace SRV
234 } // namespace NEM
A concrete implementation of geoMeshBase representing a Omega_h::Mesh.
Definition: oshGeoMesh.H:79
std::vector< omegahRefineMetricSource > MetricSources
int RequestData(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector) override
This is called by the superclass.
std::map< std::string, omegahRefineVarCompareOpts > TransferOptsIntegralDiffuseMap
Omega_h::Real LengthHistogramMin
Omega_h::Int NqualityHistogramBins
std::map< std::string, std::string > TransferOptsIntegralMap
const Omega_h::Mesh & getOshMesh() const
Get the Omega_h::Mesh.
Definition: oshGeoMesh.H:128
int FillOutputPortInformation(int port, vtkInformation *info) override
vtkStandardNewMacro(NucMeshSrv)
Definition: NucMeshSrv.C:50
int FillInputPortInformation(int port, vtkInformation *info) override
std::map< std::string, Omega_h_Transfer > TransferOptsTypeMap
Omega_h::VarCompareOpts ParseVarCompareOpts(const std::string &type, Omega_h::Real tolerance, Omega_h::Real floor)
Omega_h::Real GradationConvergenceTolerance
Omega_h::Verbosity ParseVerbosity(const std::string &verbosity)
A service to use the Omega_h library for refinement.
Omega_h::Real LengthHistogramMax
Omega_h::Real ElementCountOverRelaxation