Nektar++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
ProcessExtrude.cpp
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // File: ProcessExtrude.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: Extrude a two-dimensional mesh to a three-dimensional mesh.
33 //
34 ////////////////////////////////////////////////////////////////////////////////
35 
37 #include "ProcessExtrude.h"
38 
39 using namespace std;
40 using namespace Nektar::NekMeshUtils;
41 
42 namespace Nektar
43 {
44 namespace Utilities
45 {
46 ModuleKey ProcessExtrude::className =
48  ModuleKey(eProcessModule, "extrude"), ProcessExtrude::create);
49 
50 ProcessExtrude::ProcessExtrude(MeshSharedPtr m) : ProcessModule(m)
51 {
52  m_config["layers"] =
53  ConfigOption(false, "5", "Number of layers to extrude");
54  m_config["length"] = ConfigOption(false, "1.0", "Length of extrusion");
55 }
56 
58 {
59 }
60 
62 {
63  int nLayers = m_config["layers"].as<int>();
64  NekDouble length = m_config["length"].as<NekDouble>();
65 
66  NekDouble dz = length / nLayers;
67 
68  ASSERTL0(m_mesh->m_spaceDim == 2,
69  "Extrude should only be called for a two dimensional mesh");
70 
71  // Increment space and expansion dimensions.
72  m_mesh->m_spaceDim++;
73  m_mesh->m_expDim++;
74 
75  // Grab a copy of the existing two-dimensional elements.
76  vector<ElementSharedPtr> el = m_mesh->m_element[2];
77 
78  // Reset mesh.
79  for (int d = 0; d <= 3; ++d)
80  {
81  m_mesh->m_element[d].clear();
82  }
83 
84  NodeSet nodes = m_mesh->m_vertexSet;
85 
86  map<int, NodeSharedPtr> id2node;
87 
89  for (it = nodes.begin(); it != nodes.end(); ++it)
90  {
91  id2node[(*it)->m_id] = *it;
92  }
93 
94  // Create vertices for subsequent layers.
95  for (int i = 1; i < nLayers + 1; ++i)
96  {
97  for (it = nodes.begin(); it != nodes.end(); ++it)
98  {
99  NodeSharedPtr n = *it;
100  NodeSharedPtr newNode(
101  new Node(i * nodes.size() + n->m_id, n->m_x, n->m_y, i * dz));
102  m_mesh->m_vertexSet.insert(newNode);
103  id2node[i * nodes.size() + n->m_id] = newNode;
104  }
105  }
106 
107  EdgeSet es = m_mesh->m_edgeSet; // copy edges for curvature
108 
109  for (int j = 0; j < nLayers; ++j)
110  {
111  for (int i = 0; i < el.size(); ++i)
112  {
113  vector<NodeSharedPtr> verts = el[i]->GetVertexList();
114  if (verts.size() == 4)
115  {
116  vector<NodeSharedPtr> nodeList(8);
117  nodeList[0] = id2node[verts[0]->m_id + j * nodes.size()];
118  nodeList[1] = id2node[verts[1]->m_id + j * nodes.size()];
119  nodeList[2] = id2node[verts[1]->m_id + (j + 1) * nodes.size()];
120  nodeList[3] = id2node[verts[0]->m_id + (j + 1) * nodes.size()];
121  nodeList[4] = id2node[verts[3]->m_id + j * nodes.size()];
122  nodeList[5] = id2node[verts[2]->m_id + j * nodes.size()];
123  nodeList[6] = id2node[verts[2]->m_id + (j + 1) * nodes.size()];
124  nodeList[7] = id2node[verts[3]->m_id + (j + 1) * nodes.size()];
125 
126  vector<int> tags(1);
127  tags[0] = 0;
128 
129  ElmtConfig conf(LibUtilities::eHexahedron, 1, false, false);
131  LibUtilities::eHexahedron, conf, nodeList, tags);
132 
133  m_mesh->m_element[3].push_back(E);
134  }
135  else
136  {
137  vector<NodeSharedPtr> nodeList(6);
138  nodeList[0] = id2node[verts[0]->m_id + (j + 1) * nodes.size()];
139  nodeList[1] = id2node[verts[1]->m_id + (j + 1) * nodes.size()];
140  nodeList[2] = id2node[verts[1]->m_id + j * nodes.size()];
141  nodeList[3] = id2node[verts[0]->m_id + j * nodes.size()];
142  nodeList[4] = id2node[verts[2]->m_id + (j + 1) * nodes.size()];
143  nodeList[5] = id2node[verts[2]->m_id + j * nodes.size()];
144 
145  vector<int> tags(1);
146  tags[0] = 1;
147 
148  ElmtConfig conf(LibUtilities::ePrism, 1, false, false);
150  LibUtilities::ePrism, conf, nodeList, tags);
151 
152  m_mesh->m_element[3].push_back(E);
153  }
154  }
155  }
156 
157  ProcessEdges();
158  ProcessFaces();
159  ProcessElements();
161 
162  EdgeSet::iterator eit;
163  for (eit = es.begin(); eit != es.end(); eit++)
164  {
165  if ((*eit)->m_edgeNodes.size() > 0)
166  {
167  for (int j = 0; j < nLayers + 1; ++j)
168  {
169  vector<NodeSharedPtr> ns((*eit)->m_edgeNodes.size());
170  for (int i = 0; i < ns.size(); i++)
171  {
172  NodeSharedPtr n = (*eit)->m_edgeNodes[i];
173  ns[i] = boost::shared_ptr<Node>(
174  new Node(0, n->m_x, n->m_y, j * dz));
175  }
176 
177  EdgeSharedPtr e = boost::shared_ptr<Edge>(
178  new Edge(id2node[(*eit)->m_n1->m_id + j * nodes.size()],
179  id2node[(*eit)->m_n2->m_id + j * nodes.size()]));
180 
181  EdgeSet::iterator f = m_mesh->m_edgeSet.find(e);
182  ASSERTL0(f != m_mesh->m_edgeSet.end(), "could not find edge");
183 
184  if ((*f)->m_n1 == e->m_n1)
185  {
186  (*f)->m_edgeNodes = ns;
187  }
188  else
189  {
190  reverse(ns.begin(), ns.end());
191  (*f)->m_edgeNodes = ns;
192  }
193  }
194  }
195  }
196 }
197 }
198 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:198
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
Represents an edge which joins two points.
Definition: Edge.h:58
STL namespace.
pair< ModuleType, string > ModuleKey
ElementFactory & GetElementFactory()
Definition: Element.cpp:47
boost::unordered_set< NodeSharedPtr, NodeHash > NodeSet
Definition: Node.h:441
virtual NEKMESHUTILS_EXPORT void ProcessFaces(bool ReprocessFaces=true)
Extract element faces.
virtual NEKMESHUTILS_EXPORT void ProcessElements()
Generate element IDs.
Represents a command-line configuration option.
boost::shared_ptr< Node > NodeSharedPtr
Definition: Node.h:50
double NekDouble
std::map< std::string, ConfigOption > m_config
List of configuration values.
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 ProcessEdges(bool ReprocessEdges=true)
Extract element edges.
boost::shared_ptr< Element > ElementSharedPtr
Definition: Edge.h:49
boost::unordered_set< EdgeSharedPtr, EdgeHash > EdgeSet
Definition: Edge.h:161
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