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.
TemplateMeshDriver.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 #define _USE_MATH_DEFINES
31 
32 //#include <cstdio>
33 #include <gmsh.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <time.h>
37 #include <fstream>
38 #include <iomanip>
39 #include <iostream>
40 #include <streambuf>
41 
42 #include "AuxiliaryFunctions.H"
43 
44 namespace NEM {
45 namespace DRV {
46 
47 TemplateMeshDriver::Opts::Opts(std::string templateName)
48  : templateName(std::move(templateName)) {}
49 
51  : file_(std::move(file)), opts_(std::move(opts)) {
52  std::cout << "TemplateMeshDriver created" << std::endl;
53 }
54 
56  : TemplateMeshDriver(Files{{}}, Opts{{}}) {}
57 
59  std::cout << "TemplateMeshDriver destroyed" << std::endl;
60 }
61 
63  return file_;
64 }
65 
66 void TemplateMeshDriver::setFiles(Files file) { this->file_ = std::move(file); }
67 
69  return opts_;
70 }
71 
72 void TemplateMeshDriver::setOpts(Opts opts) { this->opts_ = std::move(opts); }
73 
74 jsoncons::string_view TemplateMeshDriver::getProgramType() const {
75  return programType;
76 }
77 
79  static const std::map<std::string, std::string> tpl_map = {
80  {"Spiral Tape Pipe", "spiral_tape_pipe.tpl"}};
81 
82  std::string params_name{};
83  // Generate parameters file for template
84  if (this->opts_.templateName == "Spiral Tape Pipe") {
85  params_name = spiralTapePipe(this->opts_.templateParams);
86  } else {
87  std::cerr << "Error: Template name not found" << std::endl;
88  exit(-1);
89  }
90 
91  gmsh::initialize();
92  gmsh::option::setNumber("General.Terminal", 1);
93 
94  std::cout << "Generating mesh from template" << std::endl;
95  nemAux::Timer T;
96  T.start();
97  // Execute the template script
98  executeTemplate(tpl_map.at(this->opts_.templateName), this->file_.outputFile,
99  params_name);
100  T.stop();
101  std::cout << "Meshing time = " << (T.elapsed() / 1000.0) << " seconds\n";
102 }
103 
104 void TemplateMeshDriver::executeTemplate(std::string tplName,
105  std::string outName,
106  std::string params) {
107  // Decrypt the tpl and return the file name
108  std::string name = decrypt(tplName);
109  // Insert the name of the parameters file into the decrypted tpl
110  insertParams(name, params);
111 
112  // Open and mesh the tpl
113  gmsh::open(name);
114  std::remove(name.c_str());
115  // gmsh::fltk::run();
116  gmsh::model::mesh::generate(2);
117  gmsh::model::mesh::generate(3);
118  gmsh::model::mesh::removeDuplicateNodes();
119  gmsh::write(outName + ".msh");
120  gmsh::finalize();
121 }
122 
123 std::string TemplateMeshDriver::spiralTapePipe(jsoncons::json inputjson) {
124  std::cout << "Reading Template Parameters" << std::endl;
125 
126  double rx = 1; // Ellipse radius x-dir
127  double ry = 1; // Ellipse radius y-dir
128  double thickness = 0.05; // Thickness of spiral tape in y-dir
129  double extrude_len = 3; // Extrusion length
130  double n_turns = 0.5; // Number of spiral turns
131  double width_percent = 0.85; // Percentage of x-dir diameter for tape width
132  double mSize_min = 0.048; // Minimum mesh size, size a walls
133  double mSize_max = 0.1; // Maximum mesh size, size in bulk
134  double dist_min = 0.05; // Distance from walls with mSize_min
135  double dist_max = 0.2; // Distance from walls with mSize_max
136  double bl_wall_n = 0.0038; // Boundary layer mesh size normal to wall
137  double bl_far = 0.08; // Mesh size away from wall
138  double bl_thickness = 0.02; // Boundary layer mesh thickness
139  double ratio = 1.3; // Mesh size ratio normal to wall
140  double extrude_layers = 20; // Number of extruded elements during extrusion
141 
142  int element_order = 1; // Finite element order
143  int fan_points = 3; // Number of fan points in boundary layer at corners
144 
145  if (inputjson.contains("rx")) rx = inputjson["rx"].as_double();
146  if (inputjson.contains("ry")) ry = inputjson["ry"].as_double();
147  if (inputjson.contains("thickness"))
148  thickness = inputjson["thickness"].as_double();
149  if (inputjson.contains("extrude_len"))
150  extrude_len = inputjson["extrude_len"].as_double();
151  if (inputjson.contains("n_turns")) n_turns = inputjson["n_turns"].as_double();
152  if (inputjson.contains("width_percent"))
153  width_percent = inputjson["width_percent"].as_double();
154 
155  if (inputjson.contains("dist_min"))
156  dist_min = inputjson["dist_min"].as_double();
157  if (inputjson.contains("dist_max"))
158  dist_max = inputjson["dist_max"].as_double();
159  if (inputjson.contains("mSize_min"))
160  mSize_min = inputjson["mSize_min"].as_double();
161  if (inputjson.contains("mSize_max"))
162  mSize_max = inputjson["mSize_max"].as_double();
163  if (inputjson.contains("bl_wall_n"))
164  bl_wall_n = inputjson["bl_wall_n"].as_double();
165  if (inputjson.contains("bl_far")) bl_far = inputjson["bl_far"].as_double();
166  if (inputjson.contains("bl_thickness"))
167  bl_thickness = inputjson["bl_thickness"].as_double();
168  if (inputjson.contains("ratio")) ratio = inputjson["ratio"].as_double();
169  if (inputjson.contains("fan_points"))
170  fan_points = inputjson["fan_points"].as<int>();
171  if (inputjson.contains("extrude_layers"))
172  extrude_layers = inputjson["extrude_layers"].as_double();
173  if (inputjson.contains("element_order"))
174  element_order = inputjson["element_order"].as<int>();
175 
176  std::ofstream out;
177 
178  time_t t = time(0);
179  struct tm *now = localtime(&t);
180  char paramsName[80];
181  strftime(paramsName, 80, "params_%Y-%m-%d-%H:%M:%S.txt", now);
182 
183  out.open(paramsName);
184  out << "rx = " << rx << ";" << std::endl;
185  out << "ry = " << ry << ";" << std::endl;
186  out << "thickness = " << thickness << ";" << std::endl;
187  out << "extrude_len = " << extrude_len << ";" << std::endl;
188  out << "n_turns = " << n_turns << ";" << std::endl;
189  out << "width_percent = " << width_percent << ";" << std::endl;
190 
191  out << "dist_min = " << dist_min << ";" << std::endl;
192  out << "dist_max = " << dist_max << ";" << std::endl;
193  out << "mSize_min = " << mSize_min << ";" << std::endl;
194  out << "mSize_max = " << mSize_max << ";" << std::endl;
195  out << "bl_wall_n = " << bl_wall_n << ";" << std::endl;
196  out << "bl_far = " << bl_far << ";" << std::endl;
197  out << "bl_thickness = " << bl_thickness << ";" << std::endl;
198  out << "ratio = " << ratio << ";" << std::endl;
199  out << "fan_points = " << fan_points << ";" << std::endl;
200  out << "extrude_layers = " << extrude_layers << ";" << std::endl;
201  out << "element_order = " << element_order << ";" << std::endl;
202  out.close();
203 
204  return paramsName;
205 }
206 
207 void TemplateMeshDriver::insertParams(std::string file,
208  std::string params_name) {
209  std::ifstream in(file);
210  std::string str;
211  std::vector<std::string> text;
212  while (!in.eof()) {
213  std::getline(in, str, '\n');
214 
215  text.push_back(str);
216  std::string a = "SetFactory(\"built-in\");";
217  std::string b = "SetFactory(\"OpenCASCADE\");";
218  if (a.compare(str) == 0 || b.compare(str) == 0) {
219  text.push_back("Include \"" + params_name + "\";");
220  }
221  }
222  in.close();
223 
224  std::ofstream out(file);
225  for (int i = 0; i < text.size(); ++i) {
226  out << text[i] << std::endl;
227  }
228  out.close();
229 }
230 
231 // TODO: This method should have empty implementation in public_hub
232 std::string TemplateMeshDriver::decrypt(std::string filename) {
233  std::ifstream in(filename, std::ios_base::binary);
234  if (!in.is_open()) {
235  std::cerr << "Error: Template file " << filename << " is not open!"
236  << std::endl;
237  exit(-1);
238  } else {
239  unsigned vsize;
240  in.read(reinterpret_cast<char *>(&vsize), sizeof(unsigned));
241  std::vector<double> stuff(vsize);
242  in.read(reinterpret_cast<char *>(&stuff[0]), vsize * sizeof(double));
243 
244  std::string result;
245  for (double &d : stuff) {
246  int inv_d = (int)std::sqrt(d);
247  result += inv_d;
248  }
249 
250  size_t lastindex = filename.find_last_of(".");
251  std::string rawname = filename.substr(0, lastindex);
252  std::string name = rawname + ".geo";
253  std::ofstream ascii(name);
254  ascii << result << std::endl;
255  ascii.close();
256 
257  return name;
258  }
259 }
260 
261 // TODO: This method should have empty implementation in public_hub
262 void TemplateMeshDriver::encrypt(std::string inFile, std::string outFile) {
263  std::ifstream file(inFile);
264  std::string str;
265  file.seekg(0, std::ios::end);
266  str.reserve(file.tellg());
267  file.seekg(0, std::ios::beg);
268  str.assign((std::istreambuf_iterator<char>(file)),
269  std::istreambuf_iterator<char>());
270 
271  int a;
272  double b;
273  std::vector<double> line;
274  for (char const &c : str) {
275  a = (int)c;
276  b = std::pow(a, 2);
277  line.push_back(b);
278  }
279  unsigned linesize = line.size();
280  std::ofstream o(outFile, std::ios_base::binary);
281  o.write(reinterpret_cast<char *>(&linesize), sizeof(unsigned));
282  o.write(reinterpret_cast<char *>(&line[0]), line.size() * sizeof(double));
283  o.close();
284  line.clear();
285 }
286 
287 } // namespace DRV
288 } // namespace NEM
std::string outputFile
Definition: NemDriver.H:78
const Files & getFiles() const
static void executeTemplate(std::string tplName, std::string outName, std::string params)
Executes the template file.
STL namespace.
const Opts & getOpts() const
jsoncons::string_view getProgramType() const override
static std::string spiralTapePipe(jsoncons::json inputjson)
Reads the parameters for Spiral Tape geometry/mesh from the input JSON file and generates the appropr...
void execute() const override
Run the workflow represented by the driver.
Driver class to generate meshes according to a template.
static void insertParams(std::string file, std::string params_name)
Inserts the parameters file name into the template file at the appropriate line.
static std::string decrypt(std::string filename)
Decrypts the template file.
static void encrypt(std::string inFile, std::string outFile)
Encrypts the template file.
static constexpr const char * programType