Nektar++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
InputMCF.cpp
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // File: InputCAD.cpp
4 //
5 // For more information, please see: http://www.nektar.info/
6 //
7 // The MIT License
8 //
9 // Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10 // Department of Aeronautics, Imperial College London (UK), and Scientific
11 // Computing and Imaging Institute, University of Utah (USA).
12 //
13 // License for the specific language governing rights and limitations under
14 // Permission is hereby granted, free of charge, to any person obtaining a
15 // copy of this software and associated documentation files (the "Software"),
16 // to deal in the Software without restriction, including without limitation
17 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
18 // and/or sell copies of the Software, and to permit persons to whom the
19 // Software is furnished to do so, subject to the following conditions:
20 //
21 // The above copyright notice and this permission notice shall be included
22 // in all copies or substantial portions of the Software.
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
25 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
30 // DEALINGS IN THE SOFTWARE.
31 //
32 // Description: create mesh from cad using mesh utils
33 //
34 ////////////////////////////////////////////////////////////////////////////////
35 
37 
38 #include <boost/thread.hpp>
39 
40 #include <tinyxml.h>
41 
42 #include "InputMCF.h"
43 
44 using namespace std;
45 using namespace Nektar::NekMeshUtils;
46 
47 namespace Nektar
48 {
49 namespace Utilities
50 {
51 
52 ModuleKey InputMCF::className = GetModuleFactory().RegisterCreatorFunction(
53  ModuleKey(eInputModule, "mcf"), InputMCF::create,
54  "Reads mesh configuration and will generate the mesh file.");
55 
56 /**
57  * @brief Set up InputCAD object.
58  */
59 InputMCF::InputMCF(MeshSharedPtr m) : InputModule(m)
60 {
61 }
62 
64 {
65 }
66 
67 void InputMCF::ParseFile(string nm)
68 {
69  vector<string> filename;
70  filename.push_back(nm);
73 
74  ASSERTL0(pSession->DefinesElement("NEKTAR/MESHING"), "no meshing tag");
75  ASSERTL0(pSession->DefinesElement("NEKTAR/MESHING/INFORMATION"),
76  "no information tag");
77  ASSERTL0(pSession->DefinesElement("NEKTAR/MESHING/PARAMETERS"),
78  "no parameters tag");
79 
80  TiXmlElement *mcf = pSession->GetElement("NEKTAR/MESHING");
81 
82  TiXmlElement *info = mcf->FirstChildElement("INFORMATION");
83  TiXmlElement *I = info->FirstChildElement("I");
84  map<string, string> information;
85  while (I)
86  {
87  string tmp1, tmp2;
88  I->QueryStringAttribute("PROPERTY", &tmp1);
89  I->QueryStringAttribute("VALUE", &tmp2);
90  information[tmp1] = tmp2;
91  I = I->NextSiblingElement("I");
92  }
93 
94  TiXmlElement *param = mcf->FirstChildElement("PARAMETERS");
95  TiXmlElement *P = param->FirstChildElement("P");
96  map<string, string> parameters;
97  while (P)
98  {
99  string tmp1, tmp2;
100  P->QueryStringAttribute("PARAM", &tmp1);
101  P->QueryStringAttribute("VALUE", &tmp2);
102  parameters[tmp1] = tmp2;
103  P = P->NextSiblingElement("P");
104  }
105 
106  set<string> boolparameters;
107 
108  if (pSession->DefinesElement("NEKTAR/MESHING/BOOLPARAMETERS"))
109  {
110  TiXmlElement *bparam = mcf->FirstChildElement("BOOLPARAMETERS");
111  TiXmlElement *BP = bparam->FirstChildElement("P");
112 
113  while (BP)
114  {
115  string tmp;
116  BP->QueryStringAttribute("VALUE", &tmp);
117  boolparameters.insert(tmp);
118  BP = BP->NextSiblingElement("P");
119  }
120  }
121 
122  set<string> refinement;
123  if (pSession->DefinesElement("NEKTAR/MESHING/REFINEMENT"))
124  {
125  TiXmlElement *refine = mcf->FirstChildElement("REFINEMENT");
126  TiXmlElement *L = refine->FirstChildElement("LINE");
127 
128  while (L)
129  {
130  stringstream ss;
131  TiXmlElement *T = L->FirstChildElement("X1");
132  ss << T->GetText() << ",";
133  T = L->FirstChildElement("Y1");
134  ss << T->GetText() << ",";
135  T = L->FirstChildElement("Z1");
136  ss << T->GetText() << ",";
137  T = L->FirstChildElement("X2");
138  ss << T->GetText() << ",";
139  T = L->FirstChildElement("Y2");
140  ss << T->GetText() << ",";
141  T = L->FirstChildElement("Z2");
142  ss << T->GetText() << ",";
143  T = L->FirstChildElement("R");
144  ss << T->GetText() << ",";
145  T = L->FirstChildElement("D");
146  ss << T->GetText();
147 
148  refinement.insert(ss.str());
149 
150  L = L->NextSiblingElement("LINE");
151  }
152  }
153 
155 
156  it = information.find("CADFile");
157  ASSERTL0(it != information.end(), "no cadfile defined");
158  m_cadfile = it->second;
159 
160  it = information.find("MeshType");
161  ASSERTL0(it != information.end(), "no meshtype defined");
162  m_makeBL = it->second == "3DBndLayer";
163  m_2D = it->second == "2D";
164  m_manifold = it->second == "Manifold";
165  if (it->second == "2DBndLayer")
166  {
167  m_makeBL = true;
168  m_2D = true;
169  }
170  if (!m_makeBL && !m_2D && !m_manifold)
171  {
172  ASSERTL0(it->second == "3D", "unsure on MeshType")
173  }
174 
175  it = parameters.find("MinDelta");
176  ASSERTL0(it != parameters.end(), "no mindelta defined");
177  m_minDelta = it->second;
178 
179  it = parameters.find("MaxDelta");
180  ASSERTL0(it != parameters.end(), "no maxdelta defined");
181  m_maxDelta = it->second;
182 
183  it = parameters.find("EPS");
184  ASSERTL0(it != parameters.end(), "no eps defined");
185  m_eps = it->second;
186 
187  it = parameters.find("Order");
188  ASSERTL0(it != parameters.end(), "no order defined");
189  m_order = it->second;
190 
191  if (m_makeBL)
192  {
193  it = parameters.find("BndLayerSurfaces");
194  ASSERTL0(it != parameters.end(), "no BndLayersurfs defined");
195  m_blsurfs = it->second;
196 
197  it = parameters.find("BndLayerThickness");
198  ASSERTL0(it != parameters.end(), "no BndLayerthick defined");
199  m_blthick = it->second;
200 
201  it = parameters.find("BndLayerLayers");
202  m_splitBL = it != parameters.end();
203  if (m_splitBL)
204  {
205  m_bllayers = it->second;
206  it = parameters.find("BndLayerProgression");
207  m_blprog = it != parameters.end() ? it->second : "2.0";
208  }
209  }
210 
211  m_naca = false;
212  if (m_2D && m_cadfile.find('.') == std::string::npos)
213  {
214  m_naca = true;
215 
216  stringstream ss;
217  it = parameters.find("Xmin");
218  ASSERTL0(it != parameters.end(), "no xmin defined");
219  ss << it->second << ",";
220  it = parameters.find("Ymin");
221  ASSERTL0(it != parameters.end(), "no ymin defined");
222  ss << it->second << ",";
223  it = parameters.find("Xmax");
224  ASSERTL0(it != parameters.end(), "no xmax defined");
225  ss << it->second << ",";
226  it = parameters.find("Ymax");
227  ASSERTL0(it != parameters.end(), "no zmax defined");
228  ss << it->second << ",";
229  it = parameters.find("AOA");
230  ASSERTL0(it != parameters.end(), "no aoa defined");
231  ss << it->second;
232 
233  m_nacadomain = ss.str();
234  }
235 
237  sit = boolparameters.find("SurfaceOptimiser");
238  m_surfopti = sit != boolparameters.end();
239  sit = boolparameters.find("WriteOctree");
240  m_woct = sit != boolparameters.end();
241  sit = boolparameters.find("VariationalOptimiser");
242  m_varopti = sit != boolparameters.end();
243 
244  m_refine = refinement.size() > 0;
245  if (m_refine)
246  {
247  stringstream ss;
248  for (sit = refinement.begin(); sit != refinement.end(); sit++)
249  {
250  ss << *sit;
251  ss << ":";
252  }
253  m_refinement = ss.str();
254  m_refinement.erase(m_refinement.end() - 1);
255  }
256 }
257 
259 {
260  ParseFile(m_config["infile"].as<string>());
261 
262  m_mesh->m_expDim = 3;
263  m_mesh->m_spaceDim = 3;
264  m_mesh->m_nummode = boost::lexical_cast<int>(m_order) + 1;
265 
266  ModuleSharedPtr module;
267 
268  ////**** CAD ****////
269  module = GetModuleFactory().CreateInstance(
270  ModuleKey(eProcessModule, "loadcad"), m_mesh);
271  module->RegisterConfig("filename", m_cadfile);
272 
273  if (m_2D)
274  {
275  module->RegisterConfig("2D", "");
276  }
277  if (m_naca)
278  {
279  module->RegisterConfig("NACA", m_nacadomain);
280  }
281 
282  module->SetDefaults();
283  module->Process();
284 
285  ////**** OCTREE ****////
286  module = GetModuleFactory().CreateInstance(
287  ModuleKey(eProcessModule, "loadoctree"), m_mesh);
288  module->RegisterConfig("mindel", m_minDelta);
289  module->RegisterConfig("maxdel", m_maxDelta);
290  module->RegisterConfig("eps", m_eps);
291  if (m_refine)
292  {
293  module->RegisterConfig("refinement", m_refinement);
294  }
295  if (m_woct)
296  {
297  module->RegisterConfig("writeoctree", "");
298  }
299 
300  module->SetDefaults();
301  module->Process();
302 
303  ////**** LINEAR MESHING ****////
304  if (m_2D)
305  {
306  m_mesh->m_expDim = 2;
307  m_mesh->m_spaceDim = 2;
308  module = GetModuleFactory().CreateInstance(
309  ModuleKey(eProcessModule, "2dgenerator"), m_mesh);
310  if (m_makeBL)
311  {
312  module->RegisterConfig("blcurves", m_blsurfs);
313  module->RegisterConfig("blthick", m_blthick);
314  }
315 
316  try
317  {
318  module->SetDefaults();
319  module->Process();
320  }
321  catch (runtime_error &e)
322  {
323  cout << "2D linear mesh generator failed with message:" << endl;
324  cout << e.what() << endl;
325  cout << "No mesh file has been created" << endl;
326  abort();
327  }
328  }
329  else
330  {
331  ////**** SurfaceMesh ****////
332  module = GetModuleFactory().CreateInstance(
333  ModuleKey(eProcessModule, "surfacemesh"), m_mesh);
334 
335  try
336  {
337  module->SetDefaults();
338  module->Process();
339  }
340  catch (runtime_error &e)
341  {
342  cout << "Surface meshing has failed with message:" << endl;
343  cout << e.what() << endl;
344  cout << "Any surfaces which were succsessfully meshed will be "
345  "dumped as a manifold mesh"
346  << endl;
347  m_mesh->m_expDim = 2;
348  ProcessVertices();
349  ProcessEdges();
350  ProcessFaces();
351  ProcessElements();
353  return;
354  }
355 
356  if(m_manifold)
357  {
358  //dont want to volume mesh
359  m_mesh->m_expDim = 2;
360  }
361  else
362  {
363  ////**** VolumeMesh ****////
364  module = GetModuleFactory().CreateInstance(
365  ModuleKey(eProcessModule, "volumemesh"), m_mesh);
366  if (m_makeBL)
367  {
368  module->RegisterConfig("blsurfs", m_blsurfs);
369  module->RegisterConfig("blthick", m_blthick);
370  module->RegisterConfig("bllayers", m_bllayers);
371  module->RegisterConfig("blprog", m_blprog);
372  }
373 
374  try
375  {
376  module->SetDefaults();
377  module->Process();
378  }
379  catch (runtime_error &e)
380  {
381  cout << "Volume meshing has failed with message:" << endl;
382  cout << e.what() << endl;
383  cout << "The linear surface mesh be dumped as a manifold mesh"
384  << endl;
385  m_mesh->m_expDim = 2;
386  m_mesh->m_element[3].clear();
387  ProcessVertices();
388  ProcessEdges();
389  ProcessFaces();
390  ProcessElements();
392  return;
393  }
394  }
395  }
396 
397  ////**** HOSurface ****////
398  module = GetModuleFactory().CreateInstance(
399  ModuleKey(eProcessModule, "hosurface"), m_mesh);
400  if (m_surfopti)
401  {
402  module->RegisterConfig("opti", "");
403  }
404 
405  try
406  {
407  module->SetDefaults();
408  module->Process();
409  }
410  catch (runtime_error &e)
411  {
412  cout << "High-order surface meshing has failed with message:" << endl;
413  cout << e.what() << endl;
414  cout << "The mesh will be written as normal but the incomplete surface "
415  "will remain faceted"
416  << endl;
417  return;
418  }
419 
420  ////*** VARIATIONAL OPTIMISATION ****////
421  if (m_varopti)
422  {
423  unsigned int np = boost::thread::physical_concurrency();
424  if (m_mesh->m_verbose)
425  {
426  cout << "Detecting 4 cores, will attempt to run in parrallel"
427  << endl;
428  }
429  module = GetModuleFactory().CreateInstance(
430  ModuleKey(eProcessModule, "varopti"), m_mesh);
431  module->RegisterConfig("hyperelastic", "");
432  module->RegisterConfig("maxiter", "10");
433  module->RegisterConfig("numthreads",
434  boost::lexical_cast<string>(np));
435 
436  try
437  {
438  module->SetDefaults();
439  module->Process();
440  }
441  catch (runtime_error &e)
442  {
443  cout << "Variational optimisation has failed with message:" << endl;
444  cout << e.what() << endl;
445  cout << "The mesh will be written as is, it may be invalid" << endl;
446  return;
447  }
448  }
449 
450  ////**** SPLIT BL ****////
451  if (m_splitBL)
452  {
453  module = GetModuleFactory().CreateInstance(
455  module->RegisterConfig("layers", m_bllayers);
456  module->RegisterConfig("surf", m_blsurfs);
457  module->RegisterConfig(
458  "nq", boost::lexical_cast<string>(m_mesh->m_nummode));
459  module->RegisterConfig("r", m_blprog);
460 
461  try
462  {
463  module->SetDefaults();
464  module->Process();
465  }
466  catch (runtime_error &e)
467  {
468  cout << "Boundary layer splitting has failed with message:" << endl;
469  cout << e.what() << endl;
470  cout << "The mesh will be written as is, it may be invalid" << endl;
471  return;
472  }
473  }
474 
475 
476 }
477 }
478 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:198
tBaseSharedPtr CreateInstance(tKey idKey BOOST_PP_COMMA_IF(MAX_PARAM) BOOST_PP_ENUM_BINARY_PARAMS(MAX_PARAM, tParam, x))
Create an instance of the class referred to by idKey.
Definition: NekFactory.hpp:162
STL namespace.
pair< ModuleType, string > ModuleKey
boost::shared_ptr< SessionReader > SessionReaderSharedPtr
Definition: MeshPartition.h:51
static SessionReaderSharedPtr CreateInstance(int argc, char *argv[])
Creates an instance of the SessionReader class.
virtual NEKMESHUTILS_EXPORT void ProcessFaces(bool ReprocessFaces=true)
Extract element faces.
std::string m_nacadomain
Definition: InputMCF.h:64
boost::shared_ptr< Module > ModuleSharedPtr
virtual NEKMESHUTILS_EXPORT void ProcessElements()
Generate element IDs.
void ParseFile(std::string nm)
Definition: InputMCF.cpp:67
std::map< std::string, ConfigOption > m_config
List of configuration values.
NekDouble L
Abstract base class for input modules.
StandardMatrixTag boost::call_traits< LhsDataType >::const_reference rhs typedef NekMatrix< LhsDataType, StandardMatrixTag >::iterator iterator
boost::shared_ptr< Mesh > MeshSharedPtr
Shared pointer to a mesh.
Definition: Mesh.h:147
virtual NEKMESHUTILS_EXPORT void ProcessVertices()
Extract element vertices.
virtual NEKMESHUTILS_EXPORT void ProcessEdges(bool ReprocessEdges=true)
Extract element edges.
std::string m_refinement
Definition: InputMCF.h:64
std::pair< ModuleType, std::string > ModuleKey
virtual NEKMESHUTILS_EXPORT void ProcessComposites()
Generate composites.
ModuleFactory & GetModuleFactory()
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, tDescription pDesc="")
Register a class with the factory.
Definition: NekFactory.hpp:215