Nektar++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
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 // 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: Process volume meshing.
33 //
34 ////////////////////////////////////////////////////////////////////////////////
35 
37 
38 #include "VolumeMesh.h"
45 
46 using namespace std;
47 namespace Nektar
48 {
49 namespace NekMeshUtils
50 {
51 
52 ModuleKey VolumeMesh::className = GetModuleFactory().RegisterCreatorFunction(
53  ModuleKey(eProcessModule, "volumemesh"), VolumeMesh::create,
54  "Generates a volume mesh");
55 
56 VolumeMesh::VolumeMesh(MeshSharedPtr m) : ProcessModule(m)
57 {
58  m_config["blsurfs"] =
59  ConfigOption(false, "0", "Generate prisms on these surfs");
60  m_config["blthick"] = ConfigOption(false, "0", "Prism layer thickness");
61  m_config["bllayers"] = ConfigOption(false, "0", "Prism layers");
62  m_config["blprog"] = ConfigOption(false, "0", "Prism progression");
63 }
64 
66 {
67 }
68 
70 {
71  if (m_mesh->m_verbose)
72  cout << endl << "Volume meshing" << endl;
73 
74  bool makeBL;
75  vector<unsigned int> blSurfs;
76 
77  if (m_config["blsurfs"].beenSet)
78  {
79  makeBL = true;
80  ParseUtils::GenerateSeqVector(m_config["blsurfs"].as<string>().c_str(),
81  blSurfs);
82  }
83  else
84  {
85  makeBL = false;
86  }
87 
88  NekDouble prefix = 100;
89  if (m_mesh->m_cad->GetNumSurf() > 100)
90  {
91  prefix *= 10;
92  }
93 
94  TetMeshSharedPtr tet;
95  if (makeBL)
96  {
98  m_mesh, blSurfs, m_config["blthick"].as<NekDouble>(),
99  m_config["bllayers"].as<int>(), m_config["blprog"].as<NekDouble>(),
100  prefix + 1);
101 
102  blmesh->Mesh();
103 
104  // remesh the correct surfaces
105  vector<unsigned int> symsurfs = blmesh->GetSymSurfs();
106  vector<ElementSharedPtr> els = m_mesh->m_element[2];
107  m_mesh->m_element[2].clear();
108  for (int i = 0; i < els.size(); i++)
109  {
111  symsurfs.begin(), symsurfs.end(), els[i]->m_parentCAD->GetId());
112 
113  if (f == symsurfs.end())
114  {
115  m_mesh->m_element[2].push_back(els[i]);
116  }
117  else
118  {
119  // remove element from links
120  vector<EdgeSharedPtr> es = els[i]->GetEdgeList();
121  for (int j = 0; j < es.size(); j++)
122  {
123  vector<pair<ElementSharedPtr, int> > lk = es[j]->m_elLink;
124  es[j]->m_elLink.clear();
125  for (int k = 0; k < lk.size(); k++)
126  {
127  if (lk[k].first == els[i])
128  {
129  continue;
130  }
131  es[j]->m_elLink.push_back(lk[k]);
132  }
133  }
134  }
135  }
136 
137  for (int i = 0; i < symsurfs.size(); i++)
138  {
139  set<int> cIds;
140  vector<CADSystem::EdgeLoopSharedPtr> e =
141  m_mesh->m_cad->GetSurf(symsurfs[i])->GetEdges();
142  for (int k = 0; k < e.size(); k++)
143  {
144  for (int j = 0; j < e[k]->edges.size(); j++)
145  {
146  cIds.insert(e[k]->edges[j]->GetId());
147  }
148  }
149 
150  // find the curve nodes which are on this symsurf
151  map<int, vector<NodeSharedPtr> > curveNodeMap;
153  for (it = m_mesh->m_vertexSet.begin();
154  it != m_mesh->m_vertexSet.end(); it++)
155  {
156  vector<pair<int, CADCurveSharedPtr> > cc =
157  (*it)->GetCADCurves();
158  for (int j = 0; j < cc.size(); j++)
159  {
160  set<int>::iterator f = cIds.find(cc[j].first);
161  if (f != cIds.end())
162  {
163  curveNodeMap[cc[j].first].push_back((*it));
164  }
165  }
166  }
167 
168  // need to bubble sort the vectors
169  map<int, vector<NodeSharedPtr> >::iterator cit;
170  for (cit = curveNodeMap.begin(); cit != curveNodeMap.end(); cit++)
171  {
172  vector<NekDouble> ts;
173  for (int i = 0; i < cit->second.size(); i++)
174  {
175  ts.push_back(cit->second[i]->GetCADCurveInfo(cit->first));
176  }
177  bool repeat = true;
178  while (repeat)
179  {
180  repeat = false;
181  for (int i = 0; i < ts.size() - 1; i++)
182  {
183  if (ts[i] > ts[i + 1])
184  {
185  swap(ts[i], ts[i + 1]);
186  swap(cit->second[i], cit->second[i + 1]);
187  repeat = true;
188  break;
189  }
190  }
191  }
192  }
193 
194  // create quads
195  map<NodeSharedPtr, NodeSharedPtr> nmap = blmesh->GetSymNodes();
196  for (cit = curveNodeMap.begin(); cit != curveNodeMap.end(); cit++)
197  {
198  for (int j = 0; j < cit->second.size() - 1; j++)
199  {
201  nmap.find(cit->second[j]);
203  nmap.find(cit->second[j + 1]);
204 
205  if (f1 == nmap.end() || f2 == nmap.end())
206  {
207  continue;
208  }
209 
210  NodeSharedPtr n1 = f1->second;
211  NodeSharedPtr n2 = f2->second;
212 
213  vector<NodeSharedPtr> ns;
214  ns.push_back(cit->second[j]);
215  ns.push_back(n1);
216  ns.push_back(n2);
217  ns.push_back(cit->second[j + 1]);
218 
220  false);
221 
222  vector<int> tags;
223  tags.push_back(prefix * 2 + symsurfs[i]);
225  LibUtilities::eQuadrilateral, conf, ns, tags);
226  E->m_parentCAD = m_mesh->m_cad->GetSurf(symsurfs[i]);
227  m_mesh->m_element[2].push_back(E);
228 
229  // need to dummy process the new elements
230  for (int k = 0; k < E->GetEdgeCount(); ++k)
231  {
232  pair<EdgeSet::iterator, bool> testIns;
233  EdgeSharedPtr ed = E->GetEdge(k);
234  testIns = m_mesh->m_edgeSet.insert(ed);
235 
236  if (testIns.second)
237  {
238  EdgeSharedPtr ed2 = *testIns.first;
239  ed2->m_elLink.push_back(
240  pair<ElementSharedPtr, int>(E, k));
241  }
242  else
243  {
244  EdgeSharedPtr e2 = *(testIns.first);
245  E->SetEdge(k, e2);
246  e2->m_elLink.push_back(
247  pair<ElementSharedPtr, int>(E, k));
248  }
249  }
250  }
251  }
252 
253  // swap nodes
254  for (cit = curveNodeMap.begin(); cit != curveNodeMap.end(); cit++)
255  {
256  for (int j = 0; j < cit->second.size(); j++)
257  {
259  nmap.find(cit->second[j]);
260  if (f1 == nmap.end())
261  {
262  continue;
263  }
264  cit->second[j] = f1->second;
265  }
266  }
267  map<int, CurveMeshSharedPtr> cm;
268  for (cit = curveNodeMap.begin(); cit != curveNodeMap.end(); cit++)
269  {
271  cit->first, m_mesh, cit->second);
272  }
273 
275  symsurfs[i], m_mesh, cm, symsurfs[i]);
276  f->Mesh();
277  }
278 
279  vector<unsigned int> blsurfs = blmesh->GetBLSurfs();
280 
281  // build the surface for tetgen to use.
282  vector<ElementSharedPtr> tetsurface = blmesh->GetPseudoSurface();
283  for (int i = 0; i < m_mesh->m_element[2].size(); i++)
284  {
285  if (m_mesh->m_element[2][i]->GetConf().m_e ==
287  {
288  continue;
289  }
290 
292  find(blsurfs.begin(), blsurfs.end(),
293  m_mesh->m_element[2][i]->m_parentCAD->GetId());
294 
295  if (f == blsurfs.end())
296  {
297  tetsurface.push_back(m_mesh->m_element[2][i]);
298  }
299  }
300 
301  tet = MemoryManager<TetMesh>::AllocateSharedPtr(m_mesh, prefix, tetsurface);
302  }
303  else
304  {
306  }
307 
308  tet->Mesh();
309 
311  ProcessVertices();
312  ProcessEdges();
313  ProcessFaces();
314  ProcessElements();
316 
317  if (m_mesh->m_verbose)
318  {
319  cout << endl;
320  }
321 }
322 }
323 }
Basic information about an element.
Definition: ElementConfig.h:50
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
static boost::shared_ptr< DataType > AllocateSharedPtr()
Allocate a shared pointer from the memory pool.
STL namespace.
pair< ModuleType, string > ModuleKey
ElementFactory & GetElementFactory()
Definition: Element.cpp:47
static bool GenerateSeqVector(const char *const str, std::vector< unsigned int > &vec)
Definition: ParseUtils.hpp:79
boost::shared_ptr< BLMesh > BLMeshSharedPtr
Definition: BLMesh.h:141
virtual NEKMESHUTILS_EXPORT void ProcessFaces(bool ReprocessFaces=true)
Extract element faces.
boost::shared_ptr< FaceMesh > FaceMeshSharedPtr
Definition: FaceMesh.h:161
virtual NEKMESHUTILS_EXPORT void ProcessElements()
Generate element IDs.
Represents a command-line configuration option.
boost::shared_ptr< Node > NodeSharedPtr
Definition: Node.h:50
boost::shared_ptr< TetMesh > TetMeshSharedPtr
Definition: TetMesh.h:89
double NekDouble
std::map< std::string, ConfigOption > m_config
List of configuration values.
virtual NEKMESHUTILS_EXPORT void ClearElementLinks()
boost::shared_ptr< Edge > EdgeSharedPtr
Shared pointer to an edge.
Definition: Edge.h:135
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
Abstract base class for processing modules.
virtual NEKMESHUTILS_EXPORT void ProcessVertices()
Extract element vertices.
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:316
boost::shared_ptr< Element > ElementSharedPtr
Definition: Edge.h:49
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