Nektar++
Public Member Functions | Static Public Member Functions | Static Public Attributes | List of all members
Nektar::Utilities::ProcessExtrude Class Reference

This processing module extrudes a 2d mesh in the z direction. More...

#include <ProcessExtrude.h>

Inheritance diagram for Nektar::Utilities::ProcessExtrude:
[legend]

Public Member Functions

 ProcessExtrude (NekMeshUtils::MeshSharedPtr m)
 
virtual ~ProcessExtrude ()
 
virtual void Process ()
 
- Public Member Functions inherited from Nektar::NekMeshUtils::ProcessModule
NEKMESHUTILS_EXPORT ProcessModule (MeshSharedPtr p_m)
 
- Public Member Functions inherited from Nektar::NekMeshUtils::Module
NEKMESHUTILS_EXPORT Module (MeshSharedPtr p_m)
 
NEKMESHUTILS_EXPORT void RegisterConfig (std::string key, std::string value=std::string())
 Register a configuration option with a module. More...
 
NEKMESHUTILS_EXPORT void PrintConfig ()
 Print out all configuration options for a module. More...
 
NEKMESHUTILS_EXPORT void SetDefaults ()
 Sets default configuration options for those which have not been set. More...
 
NEKMESHUTILS_EXPORT MeshSharedPtr GetMesh ()
 
virtual NEKMESHUTILS_EXPORT void ProcessVertices ()
 Extract element vertices. More...
 
virtual NEKMESHUTILS_EXPORT void ProcessEdges (bool ReprocessEdges=true)
 Extract element edges. More...
 
virtual NEKMESHUTILS_EXPORT void ProcessFaces (bool ReprocessFaces=true)
 Extract element faces. More...
 
virtual NEKMESHUTILS_EXPORT void ProcessElements ()
 Generate element IDs. More...
 
virtual NEKMESHUTILS_EXPORT void ProcessComposites ()
 Generate composites. More...
 
virtual NEKMESHUTILS_EXPORT void ClearElementLinks ()
 

Static Public Member Functions

static std::shared_ptr< Modulecreate (NekMeshUtils::MeshSharedPtr m)
 Creates an instance of this class. More...
 

Static Public Attributes

static NekMeshUtils::ModuleKey className
 

Additional Inherited Members

- Protected Member Functions inherited from Nektar::NekMeshUtils::Module
NEKMESHUTILS_EXPORT void ReorderPrisms (PerMap &perFaces)
 Reorder node IDs so that prisms and tetrahedra are aligned correctly. More...
 
NEKMESHUTILS_EXPORT void PrismLines (int prism, PerMap &perFaces, std::set< int > &prismsDone, std::vector< ElementSharedPtr > &line)
 
- Protected Attributes inherited from Nektar::NekMeshUtils::Module
MeshSharedPtr m_mesh
 Mesh object. More...
 
std::map< std::string, ConfigOptionm_config
 List of configuration values. More...
 

Detailed Description

This processing module extrudes a 2d mesh in the z direction.

Definition at line 47 of file ProcessExtrude.h.

Constructor & Destructor Documentation

◆ ProcessExtrude()

Nektar::Utilities::ProcessExtrude::ProcessExtrude ( NekMeshUtils::MeshSharedPtr  m)

Definition at line 49 of file ProcessExtrude.cpp.

References Nektar::NekMeshUtils::Module::m_config.

49  : ProcessModule(m)
50 {
51  m_config["layers"] =
52  ConfigOption(false, "5", "Number of layers to extrude");
53  m_config["length"] = ConfigOption(false, "1.0", "Length of extrusion");
54 }
Represents a command-line configuration option.
NEKMESHUTILS_EXPORT ProcessModule(MeshSharedPtr p_m)
std::map< std::string, ConfigOption > m_config
List of configuration values.

◆ ~ProcessExtrude()

Nektar::Utilities::ProcessExtrude::~ProcessExtrude ( )
virtual

Definition at line 56 of file ProcessExtrude.cpp.

57 {
58 }

Member Function Documentation

◆ create()

static std::shared_ptr<Module> Nektar::Utilities::ProcessExtrude::create ( NekMeshUtils::MeshSharedPtr  m)
inlinestatic

Creates an instance of this class.

Definition at line 51 of file ProcessExtrude.h.

References Nektar::MemoryManager< DataType >::AllocateSharedPtr().

52  {
54  }
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.

◆ Process()

void Nektar::Utilities::ProcessExtrude::Process ( )
virtual

Implements Nektar::NekMeshUtils::Module.

Definition at line 60 of file ProcessExtrude.cpp.

References ASSERTL0, Nektar::LibUtilities::NekFactory< tKey, tBase, tParam >::CreateInstance(), Nektar::LibUtilities::eHexahedron, Nektar::LibUtilities::ePrism, Nektar::LibUtilities::eQuadrilateral, Nektar::LibUtilities::eTriangle, Nektar::NekMeshUtils::GetElementFactory(), Nektar::NekConstants::kNekZeroTol, Nektar::NekMeshUtils::Module::m_config, Nektar::NekMeshUtils::Module::m_mesh, class_topology::Node, Nektar::NekMeshUtils::Module::ProcessComposites(), Nektar::NekMeshUtils::Module::ProcessEdges(), Nektar::NekMeshUtils::Module::ProcessElements(), and Nektar::NekMeshUtils::Module::ProcessFaces().

61 {
62  int nLayers = m_config["layers"].as<int>();
63  NekDouble length = m_config["length"].as<NekDouble>();
64 
65  NekDouble dz = length / nLayers;
66 
67  ASSERTL0(m_mesh->m_spaceDim == 2,
68  "Extrude should only be called for a two dimensional mesh");
69 
70  // Increment space and expansion dimensions.
71  m_mesh->m_spaceDim++;
72  m_mesh->m_expDim++;
73 
74  // Grab a copy of the existing two-dimensional elements.
75  vector<ElementSharedPtr> el = m_mesh->m_element[2];
76 
77  // Grab a copy of existing composites.
78  CompositeMap oldComp = m_mesh->m_composite;
79  if (m_mesh->m_verbose)
80  {
81  cout << "Boundary composites" << endl;
82  for (auto &it : oldComp)
83  {
84  if (it.second->m_tag != "E")
85  {
86  continue;
87  }
88  cout << it.first << "\t" << it.second->m_tag;
89  for (int i = 0; i < it.second->m_items.size(); ++i)
90  {
91  cout << "\t" << it.second->m_items[i]->GetId()
92  << " (" << it.second->m_items[i]->GetVertex(0)
93  << ", " << it.second->m_items[i]->GetVertex(1) << ")";
94  vector<NodeSharedPtr> vv = it.second->m_items[i]->GetVertexList();
95  cout << "\t(" << vv[0]->GetID()<< ", " << vv[1]->GetID() <<")";
96  }
97  cout << endl;
98  }
99  }
100 
101  // Reset mesh.
102  for (int d = 0; d <= 3; ++d)
103  {
104  m_mesh->m_element[d].clear();
105  }
106 
107  NodeSet nodes = m_mesh->m_vertexSet;
108 
109  map<int, NodeSharedPtr> id2node;
110 
111  for (auto &n : nodes)
112  {
113  id2node[n->m_id] = n;
114  }
115  // Save z plane coordinate
116  NekDouble z0 = 0;
117 
118  // Create vertices for subsequent layers.
119  for (int i = 1; i < nLayers + 1; ++i)
120  {
121  for (auto &n : nodes)
122  {
123  z0 = n->m_z;
124  NodeSharedPtr newNode(
125  new Node(i * nodes.size() + n->m_id, n->m_x, n->m_y,
126  n->m_z + i * dz));
127  m_mesh->m_vertexSet.insert(newNode);
128  id2node[i * nodes.size() + n->m_id] = newNode;
129  }
130  }
131 
132  EdgeSet es = m_mesh->m_edgeSet; // copy edges for curvature
133 
134  for (int j = 0; j < nLayers; ++j)
135  {
136  for (int i = 0; i < el.size(); ++i)
137  {
138  vector<NodeSharedPtr> verts = el[i]->GetVertexList();
139  if (verts.size() == 4)
140  {
141  vector<NodeSharedPtr> nodeList(8);
142  nodeList[0] = id2node[verts[0]->m_id + j * nodes.size()];
143  nodeList[1] = id2node[verts[1]->m_id + j * nodes.size()];
144  nodeList[2] = id2node[verts[2]->m_id + j * nodes.size()];
145  nodeList[3] = id2node[verts[3]->m_id + j * nodes.size()];
146  nodeList[4] = id2node[verts[0]->m_id + (j + 1) * nodes.size()];
147  nodeList[5] = id2node[verts[1]->m_id + (j + 1) * nodes.size()];
148  nodeList[6] = id2node[verts[2]->m_id + (j + 1) * nodes.size()];
149  nodeList[7] = id2node[verts[3]->m_id + (j + 1) * nodes.size()];
150 
151 
152  vector<int> tags(1);
153  tags[0] = 0;
154 
155  ElmtConfig conf(LibUtilities::eHexahedron, 1, false, false,
156  false);
158  LibUtilities::eHexahedron, conf, nodeList, tags);
159 
160  m_mesh->m_element[3].push_back(E);
161  }
162  else
163  {
164  vector<NodeSharedPtr> nodeList(6);
165  nodeList[0] = id2node[verts[0]->m_id + (j + 1) * nodes.size()];
166  nodeList[1] = id2node[verts[1]->m_id + (j + 1) * nodes.size()];
167  nodeList[2] = id2node[verts[1]->m_id + j * nodes.size()];
168  nodeList[3] = id2node[verts[0]->m_id + j * nodes.size()];
169  nodeList[4] = id2node[verts[2]->m_id + (j + 1) * nodes.size()];
170  nodeList[5] = id2node[verts[2]->m_id + j * nodes.size()];
171 
172  vector<int> tags(1);
173  tags[0] = 1;
174 
175  ElmtConfig conf(LibUtilities::ePrism, 1, false, false, false);
177  LibUtilities::ePrism, conf, nodeList, tags);
178 
179  m_mesh->m_element[3].push_back(E);
180  }
181  }
182  }
183 
184  ProcessEdges();
185  ProcessFaces();
186  ProcessElements();
188 
189  // Copy edge information
190  for (auto &edge : es)
191  {
192  if (edge->m_edgeNodes.size() > 0)
193  {
194  for (int j = 0; j < nLayers + 1; ++j)
195  {
196  vector<NodeSharedPtr> ns(edge->m_edgeNodes.size());
197  for (int i = 0; i < ns.size(); i++)
198  {
199  NodeSharedPtr n = edge->m_edgeNodes[i];
200  ns[i] = std::shared_ptr<Node>(
201  new Node(0, n->m_x, n->m_y, n->m_z + j * dz));
202  }
203 
204  EdgeSharedPtr e = std::shared_ptr<Edge>(
205  new Edge(id2node[edge->m_n1->m_id + j * nodes.size()],
206  id2node[edge->m_n2->m_id + j * nodes.size()]));
207 
208  auto f = m_mesh->m_edgeSet.find(e);
209  ASSERTL0(f != m_mesh->m_edgeSet.end(), "could not find edge");
210 
211  // Copy edge type
212  (*f)->m_curveType = edge->m_curveType;
213  // Copy points
214  if ((*f)->m_n1 == e->m_n1)
215  {
216  (*f)->m_edgeNodes = ns;
217  }
218  else
219  {
220  reverse(ns.begin(), ns.end());
221  (*f)->m_edgeNodes = ns;
222  }
223  }
224  }
225  }
226 
227  // Get composites max id
228  unsigned int maxCompId = 0;
229  for (auto &it : oldComp)
230  {
231  if(it.second->m_id >= maxCompId)
232  {
233  maxCompId = it.second->m_id;
234  }
235  }
236 
237  // First rename surface to volume composites to out of range
238  int outCompId = maxCompId + 1;
239  std::vector<int> toErase;
240  for (auto &it2 : m_mesh->m_composite)
241  {
242  if (it2.second->m_id > maxCompId)
243  {
244  // done!
245  break;
246  }
247  if (it2.second->m_tag == "H" || it2.second->m_tag == "R")
248  {
249  it2.second->m_id = outCompId;
250  m_mesh->m_composite.insert(std::make_pair(outCompId,
251  it2.second));
252  toErase.push_back(it2.first);
253  outCompId += 1;
254  }
255  }
256 
257  for (auto &e : toErase)
258  {
259  m_mesh->m_composite.erase(e);
260  }
261 
262  toErase.clear();
263 
264  // Then copy surface to volume composites names
265  for (auto &it2 : m_mesh->m_composite)
266  {
267  if (it2.second->m_tag == "H" || it2.second->m_tag == "R")
268  {
269  for (auto &it1 : oldComp)
270  {
271  if (it2.second->m_tag == "H" && it1.second->m_tag == "Q")
272  {
273  it2.second->m_id = it1.second->m_id;
274  m_mesh->m_composite.insert(std::make_pair(it1.second->m_id,
275  it2.second));
276  toErase.push_back(it2.first);
277  oldComp.erase(it1.first);
278  break;
279  }
280  else if (it2.second->m_tag == "R" && it1.second->m_tag == "T")
281  {
282  it2.second->m_id = it1.second->m_id;
283  m_mesh->m_composite.insert(std::make_pair(it1.second->m_id,
284  it2.second));
285  toErase.push_back(it2.first);
286  oldComp.erase(it1.first);
287  break;
288  }
289  }
290  }
291  }
292 
293  for (auto &e : toErase)
294  {
295  m_mesh->m_composite.erase(e);
296  }
297 
298  // Add new composite to be filled with all boundary faces
299  CompositeSharedPtr comp(new Composite());
300  comp->m_id = ++maxCompId;
301  unsigned int compAllFaceId = maxCompId; // save it so we can remove it later on
302  comp->m_tag = "F";
303  m_mesh->m_composite.insert(std::make_pair(maxCompId, comp));
304 
305  // Add all boundary faces to the composite
306  auto allFaceC = m_mesh->m_composite.find(maxCompId);
307  if (m_mesh->m_verbose)
308  {
309  cout << "Faces boundary list" << endl;
310  }
311  for (auto &it : m_mesh->m_faceSet)
312  {
313  // Add to composite if boundary face
314  if ( it->m_elLink.size() < 2 )
315  {
316  if(it->m_vertexList.size() == 3)
317  {
318  // Triangle
319  ElmtConfig conf(LibUtilities::eTriangle, 1, false, false);
320  vector<int> tags(1);
321  tags[0] = 1;
323  LibUtilities::eTriangle, conf, it->m_vertexList, tags);
324  E->SetId(it->m_id);
325  allFaceC->second->m_items.push_back(E);
326  }
327  else if(it->m_vertexList.size() == 4)
328  {
329  // Quad
330  ElmtConfig conf(LibUtilities::eQuadrilateral, 1, false, false);
331  vector<int> tags(1);
332  tags[0] = 0;
334  LibUtilities::eQuadrilateral, conf, it->m_vertexList, tags);
335  E->SetId(it->m_id);
336  allFaceC->second->m_items.push_back(E);
337  }
338  }
339  }
340 
341  // Create boundary composites
342  for (auto &itOc : oldComp)
343  {
344  CompositeSharedPtr comp(new Composite());
345  comp->m_id = itOc.second->m_id;
346  comp->m_tag = "F";
347  m_mesh->m_composite.insert(std::make_pair(itOc.second->m_id, comp));
348  }
349  // Create periodic composites
350  for (int i = 0; i < 2; i++)
351  {
352  CompositeSharedPtr comp(new Composite());
353  comp->m_id = ++maxCompId;
354  comp->m_tag = "F";
355  m_mesh->m_composite.insert(std::make_pair(maxCompId, comp));
356  }
357 
358  // Populates boundary composites
359  for (auto &itQ : allFaceC->second->m_items)
360  {
361  // Check if this quad belongs to previous boundary
362  for (auto &itOc : oldComp)
363  {
364  for (int iEd = 0; iEd < itOc.second->m_items.size(); ++iEd)
365  {
366  int inCommon = 0 ;
367  for (int iV = 0; iV < itQ->GetVertexList().size(); iV++)
368  {
369  for( int j = 0; j < 2; j++)
370  {
371  if (abs(itQ->GetVertex(iV)->m_x -
372  itOc.second->m_items[iEd]->GetVertex(j)->m_x) <
374  abs(itQ->GetVertex(iV)->m_y -
375  itOc.second->m_items[iEd]->GetVertex(j)->m_y) <
377  {
378  ++inCommon;
379  }
380  }
381  }
382  // If the face contains 4 xy pairs in common with 1 edge it
383  // must be an extruded edge and it should be added to the
384  // corresponding composite
385  if(inCommon == 4)
386  {
387  if (m_mesh->m_verbose)
388  {
389  cout << "Face " << itQ->GetId() << "\t"
390  << "Composite " << itOc.second->m_id << "\t"
391  << endl;
392  }
393  auto newC = m_mesh->m_composite.find(itOc.second->m_id);
394  // Quad
396  false);
397  vector<int> tags(1);
398  tags[0] = 0;
400  LibUtilities::eQuadrilateral, conf, itQ->GetVertexList(),
401  tags);
402  E->SetId(itQ->GetId());
403  newC->second->m_items.push_back(E);
404  }
405  }
406 
407 
408  }
409 
410  // Populates periodic composites
411  NekDouble zdist = 0.0;
412  for (int iV = 0; iV < itQ->GetVertexList().size(); iV++)
413  {
414  zdist += itQ->GetVertex(iV)->m_z;
415  }
416  zdist = zdist / itQ->GetVertexList().size();
417  unsigned int compPerId = 0;
418  if(std::abs(zdist - z0) < NekConstants::kNekZeroTol)
419  {
420  compPerId = maxCompId-1;
421  }
422  else if(std::abs(zdist - z0 - length) < NekConstants::kNekZeroTol)
423  {
424  compPerId = maxCompId;
425  }
426  if(compPerId > 0 && itQ->GetVertexList().size() == 3)
427  {
428  // Triangle
429  auto perC = m_mesh->m_composite.find(compPerId);
430  ElmtConfig conf(LibUtilities::eTriangle, 1, false, false);
431  vector<int> tags(1);
432  tags[0] = 1;
434  LibUtilities::eTriangle, conf, itQ->GetVertexList(), tags);
435  E->SetId(itQ->GetId());
436  perC->second->m_items.push_back(E);
437  }
438  else if(compPerId > 0 && itQ->GetVertexList().size() == 4)
439  {
440  // Quad
441  auto perC = m_mesh->m_composite.find(compPerId);
442  ElmtConfig conf(LibUtilities::eQuadrilateral, 1, false, false);
443  vector<int> tags(1);
444  tags[0] = 0;
446  LibUtilities::eQuadrilateral, conf, itQ->GetVertexList(), tags);
447  E->SetId(itQ->GetId());
448  perC->second->m_items.push_back(E);
449  }
450  }
451  // Remove all faces composite
452  m_mesh->m_composite.erase(compAllFaceId);
453 
454 
455 
456 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
Basic information about an element.
Definition: ElementConfig.h:49
Represents an edge which joins two points.
Definition: Edge.h:58
std::unordered_set< EdgeSharedPtr, EdgeHash > EdgeSet
Definition: Edge.h:159
std::map< unsigned int, CompositeSharedPtr > CompositeMap
Container of composites; key is the composite id, value is the composite.
Definition: Composite.h:73
std::shared_ptr< Edge > EdgeSharedPtr
Shared pointer to an edge.
Definition: Edge.h:136
ElementFactory & GetElementFactory()
Definition: Element.cpp:44
std::shared_ptr< Node > NodeSharedPtr
Definition: CADVert.h:49
std::unordered_set< NodeSharedPtr, NodeHash > NodeSet
Definition: Node.h:447
tBaseSharedPtr CreateInstance(tKey idKey, tParam... args)
Create an instance of the class referred to by idKey.
Definition: NekFactory.hpp:144
A composite is a collection of elements.
Definition: Composite.h:50
static const NekDouble kNekZeroTol
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.
double NekDouble
std::map< std::string, ConfigOption > m_config
List of configuration values.
std::shared_ptr< Composite > CompositeSharedPtr
Shared pointer to a composite.
Definition: Composite.h:70
virtual NEKMESHUTILS_EXPORT void ProcessEdges(bool ReprocessEdges=true)
Extract element edges.
virtual NEKMESHUTILS_EXPORT void ProcessComposites()
Generate composites.

Member Data Documentation

◆ className

ModuleKey Nektar::Utilities::ProcessExtrude::className
static
Initial value:

Definition at line 55 of file ProcessExtrude.h.