Nektar++
VolumeMesh.cpp
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // File: VolumeMesh.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 // Permission is hereby granted, free of charge, to any person obtaining a
14 // copy of this software and associated documentation files (the "Software"),
15 // to deal in the Software without restriction, including without limitation
16 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
17 // and/or sell copies of the Software, and to permit persons to whom the
18 // Software is furnished to do so, subject to the following conditions:
19 //
20 // The above copyright notice and this permission notice shall be included
21 // in all copies or substantial portions of the Software.
22 //
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29 // DEALINGS IN THE SOFTWARE.
30 //
31 // Description: Process volume meshing.
32 //
33 ////////////////////////////////////////////////////////////////////////////////
34 
36 
37 #include "VolumeMesh.h"
44 
45 using namespace std;
46 namespace Nektar
47 {
48 namespace NekMeshUtils
49 {
50 
51 ModuleKey VolumeMesh::className = GetModuleFactory().RegisterCreatorFunction(
52  ModuleKey(eProcessModule, "volumemesh"), VolumeMesh::create,
53  "Generates a volume mesh");
54 
55 VolumeMesh::VolumeMesh(MeshSharedPtr m) : ProcessModule(m)
56 {
57  m_config["blsurfs"] =
58  ConfigOption(false, "0", "Generate prisms on these surfs");
59  m_config["blthick"] = ConfigOption(false, "0", "Prism layer thickness");
60  m_config["bllayers"] = ConfigOption(false, "0", "Prism layers");
61  m_config["blprog"] = ConfigOption(false, "0", "Prism progression");
62 }
63 
65 {
66 }
67 
69 {
70  if (m_mesh->m_verbose)
71  cout << endl << "Volume meshing" << endl;
72 
73  bool makeBL;
74  vector<unsigned int> blSurfs;
75 
76  if (m_config["blsurfs"].beenSet)
77  {
78  makeBL = true;
79  ParseUtils::GenerateSeqVector(m_config["blsurfs"].as<string>(),
80  blSurfs);
81  }
82  else
83  {
84  makeBL = false;
85  }
86 
87  NekDouble prefix = 100;
88  if (m_mesh->m_cad->GetNumSurf() > 100)
89  {
90  prefix *= 10;
91  }
92 
93  TetMeshSharedPtr tet;
94  if (makeBL)
95  {
97  m_mesh, blSurfs, m_config["blthick"].as<NekDouble>(),
98  m_config["bllayers"].as<int>(), m_config["blprog"].as<NekDouble>(),
99  prefix + 1);
100 
101  blmesh->Mesh();
102 
103  // remesh the correct surfaces
104  vector<unsigned int> symsurfs = blmesh->GetSymSurfs();
105  vector<ElementSharedPtr> els = m_mesh->m_element[2];
106  m_mesh->m_element[2].clear();
107  for (int i = 0; i < els.size(); i++)
108  {
109  vector<unsigned int>::iterator f = find(
110  symsurfs.begin(), symsurfs.end(), els[i]->m_parentCAD->GetId());
111 
112  if (f == symsurfs.end())
113  {
114  m_mesh->m_element[2].push_back(els[i]);
115  }
116  else
117  {
118  // remove element from links
119  vector<EdgeSharedPtr> es = els[i]->GetEdgeList();
120  for (int j = 0; j < es.size(); j++)
121  {
122  vector<pair<ElementSharedPtr, int> > lk = es[j]->m_elLink;
123  es[j]->m_elLink.clear();
124  for (int k = 0; k < lk.size(); k++)
125  {
126  if (lk[k].first == els[i])
127  {
128  continue;
129  }
130  es[j]->m_elLink.push_back(lk[k]);
131  }
132  }
133  }
134  }
135 
136  for (int i = 0; i < symsurfs.size(); i++)
137  {
138  set<int> cIds;
139  vector<EdgeLoopSharedPtr> e =
140  m_mesh->m_cad->GetSurf(symsurfs[i])->GetEdges();
141  for (int k = 0; k < e.size(); k++)
142  {
143  for (int j = 0; j < e[k]->edges.size(); j++)
144  {
145  cIds.insert(e[k]->edges[j]->GetId());
146  }
147  }
148 
149  // find the curve nodes which are on this symsurf
150  map<int, vector<NodeSharedPtr> > curveNodeMap;
151  NodeSet::iterator it;
152  for (it = m_mesh->m_vertexSet.begin();
153  it != m_mesh->m_vertexSet.end(); it++)
154  {
155  vector<CADCurveSharedPtr> cc = (*it)->GetCADCurves();
156  for (int j = 0; j < cc.size(); j++)
157  {
158  set<int>::iterator f = cIds.find(cc[j]->GetId());
159  if (f != cIds.end())
160  {
161  curveNodeMap[cc[j]->GetId()].push_back((*it));
162  }
163  }
164  }
165 
166  // need to bubble sort the vectors
167  map<int, vector<NodeSharedPtr> >::iterator cit;
168  for (cit = curveNodeMap.begin(); cit != curveNodeMap.end(); cit++)
169  {
170  vector<NekDouble> ts;
171  for (int i = 0; i < cit->second.size(); i++)
172  {
173  ts.push_back(cit->second[i]->GetCADCurveInfo(cit->first));
174  }
175  bool repeat = true;
176  while (repeat)
177  {
178  repeat = false;
179  for (int i = 0; i < ts.size() - 1; i++)
180  {
181  if (ts[i] > ts[i + 1])
182  {
183  swap(ts[i], ts[i + 1]);
184  swap(cit->second[i], cit->second[i + 1]);
185  repeat = true;
186  break;
187  }
188  }
189  }
190  }
191 
192  // create quads
193  map<NodeSharedPtr, NodeSharedPtr> nmap = blmesh->GetSymNodes();
194  for (cit = curveNodeMap.begin(); cit != curveNodeMap.end(); cit++)
195  {
196  for (int j = 0; j < cit->second.size() - 1; j++)
197  {
198  map<NodeSharedPtr, NodeSharedPtr>::iterator f1 =
199  nmap.find(cit->second[j]);
200  map<NodeSharedPtr, NodeSharedPtr>::iterator f2 =
201  nmap.find(cit->second[j + 1]);
202 
203  if (f1 == nmap.end() || f2 == nmap.end())
204  {
205  continue;
206  }
207 
208  NodeSharedPtr n1 = f1->second;
209  NodeSharedPtr n2 = f2->second;
210 
211  vector<NodeSharedPtr> ns;
212  ns.push_back(cit->second[j]);
213  ns.push_back(n1);
214  ns.push_back(n2);
215  ns.push_back(cit->second[j + 1]);
216 
218  false);
219 
220  vector<int> tags;
221  tags.push_back(prefix * 2 + symsurfs[i]);
223  LibUtilities::eQuadrilateral, conf, ns, tags);
224  E->m_parentCAD = m_mesh->m_cad->GetSurf(symsurfs[i]);
225  m_mesh->m_element[2].push_back(E);
226 
227  // need to dummy process the new elements
228  for (int k = 0; k < E->GetEdgeCount(); ++k)
229  {
230  pair<EdgeSet::iterator, bool> testIns;
231  EdgeSharedPtr ed = E->GetEdge(k);
232  testIns = m_mesh->m_edgeSet.insert(ed);
233 
234  if (testIns.second)
235  {
236  EdgeSharedPtr ed2 = *testIns.first;
237  ed2->m_elLink.push_back(
238  pair<ElementSharedPtr, int>(E, k));
239  }
240  else
241  {
242  EdgeSharedPtr e2 = *(testIns.first);
243  E->SetEdge(k, e2);
244  e2->m_elLink.push_back(
245  pair<ElementSharedPtr, int>(E, k));
246  }
247  }
248  }
249  }
250 
251  // swap nodes
252  for (cit = curveNodeMap.begin(); cit != curveNodeMap.end(); cit++)
253  {
254  for (int j = 0; j < cit->second.size(); j++)
255  {
256  map<NodeSharedPtr, NodeSharedPtr>::iterator f1 =
257  nmap.find(cit->second[j]);
258  if (f1 == nmap.end())
259  {
260  continue;
261  }
262  cit->second[j] = f1->second;
263  }
264  }
265  map<int, CurveMeshSharedPtr> cm;
266  for (cit = curveNodeMap.begin(); cit != curveNodeMap.end(); cit++)
267  {
269  cit->first, m_mesh, cit->second);
270  }
271 
273  symsurfs[i], m_mesh, cm, symsurfs[i]);
274  f->Mesh();
275  }
276 
277  vector<unsigned int> blsurfs = blmesh->GetBLSurfs();
278 
279  // build the surface for tetgen to use.
280  vector<ElementSharedPtr> tetsurface = blmesh->GetPseudoSurface();
281  for (int i = 0; i < m_mesh->m_element[2].size(); i++)
282  {
283  if (m_mesh->m_element[2][i]->GetConf().m_e ==
285  {
286  continue;
287  }
288 
289  vector<unsigned int>::iterator f =
290  find(blsurfs.begin(), blsurfs.end(),
291  m_mesh->m_element[2][i]->m_parentCAD->GetId());
292 
293  if (f == blsurfs.end())
294  {
295  tetsurface.push_back(m_mesh->m_element[2][i]);
296  }
297  }
298 
299  tet = MemoryManager<TetMesh>::AllocateSharedPtr(m_mesh, prefix, tetsurface);
300  }
301  else
302  {
304  }
305 
306  tet->Mesh();
307 
309  ProcessVertices();
310  ProcessEdges();
311  ProcessFaces();
312  ProcessElements();
314 
315  if (m_mesh->m_verbose)
316  {
317  cout << endl;
318  }
319 }
320 }
321 }
Basic information about an element.
Definition: ElementConfig.h:49
STL namespace.
std::shared_ptr< Edge > EdgeSharedPtr
Shared pointer to an edge.
Definition: Edge.h:136
std::shared_ptr< Mesh > MeshSharedPtr
Shared pointer to a mesh.
Definition: Mesh.h:156
ElementFactory & GetElementFactory()
Definition: Element.cpp:44
std::shared_ptr< Node > NodeSharedPtr
Definition: CADVert.h:49
tBaseSharedPtr CreateInstance(tKey idKey, tParam... args)
Create an instance of the class referred to by idKey.
Definition: NekFactory.hpp:144
std::pair< ModuleType, std::string > ModuleKey
virtual NEKMESHUTILS_EXPORT void ProcessFaces(bool ReprocessFaces=true)
Extract element faces.
std::shared_ptr< Element > ElementSharedPtr
Definition: Edge.h:49
virtual NEKMESHUTILS_EXPORT void ProcessElements()
Generate element IDs.
Represents a command-line configuration option.
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
double NekDouble
std::map< std::string, ConfigOption > m_config
List of configuration values.
std::shared_ptr< TetMesh > TetMeshSharedPtr
Definition: TetMesh.h:86
virtual NEKMESHUTILS_EXPORT void ClearElementLinks()
Abstract base class for processing modules.
virtual NEKMESHUTILS_EXPORT void ProcessVertices()
Extract element vertices.
std::shared_ptr< FaceMesh > FaceMeshSharedPtr
Definition: FaceMesh.h:165
virtual NEKMESHUTILS_EXPORT void ProcessEdges(bool ReprocessEdges=true)
Extract element edges.
InputIterator find(InputIterator first, InputIterator last, InputIterator startingpoint, const EqualityComparable &value)
Definition: StdRegions.hpp:358
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
Definition: NekFactory.hpp:199
std::shared_ptr< BLMesh > BLMeshSharedPtr
Definition: BLMesh.h:138
virtual NEKMESHUTILS_EXPORT void ProcessComposites()
Generate composites.
ModuleFactory & GetModuleFactory()
static bool GenerateSeqVector(const std::string &str, std::vector< unsigned int > &out)
Takes a comma-separated compressed string and converts it to entries in a vector. ...
Definition: ParseUtils.cpp:108