Nektar++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
ProcessOptiExtract.cpp
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // File: ProcessJac.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: Calculate Jacobians of elements.
33 //
34 ////////////////////////////////////////////////////////////////////////////////
35 
36 #include <boost/algorithm/string.hpp>
37 
39 #include "ProcessOptiExtract.h"
40 
41 using namespace std;
42 using namespace Nektar::NekMeshUtils;
43 
44 namespace Nektar
45 {
46 namespace Utilities
47 {
48 
49 ModuleKey ProcessOptiExtract::className =
51  ModuleKey(eProcessModule, "opti"),
52  ProcessOptiExtract::create,
53  "Pulls out blobs for linear elastic solver.");
54 
55 ProcessOptiExtract::ProcessOptiExtract(MeshSharedPtr m) : ProcessModule(m)
56 {
57  m_config["insert"] =
58  ConfigOption(false, "-1", "Name of mesh file to be combined.");
59 }
60 
62 {
63 }
64 
66 {
67  if (m_mesh->m_verbose)
68  {
69  cout << "ProcessOptiExtract: ... " << endl;
70  }
71 
72  string ins = m_config["insert"].as<string>();
73 
74  bool extract = boost::iequals(ins, "-1");
75 
76  if (extract)
77  {
78  vector<ElementSharedPtr> el = m_mesh->m_element[m_mesh->m_expDim];
79 
80  m_mesh->m_element[m_mesh->m_expDim].clear();
81  m_mesh->m_element[m_mesh->m_expDim - 1].clear();
82 
83  vector<ElementSharedPtr> invalid;
84 
85  // get invalid elements
86  for (int i = 0; i < el.size(); ++i)
87  {
88  // Create elemental geometry.
90  el[i]->GetGeom(m_mesh->m_spaceDim);
91 
92  // Generate geometric factors.
93  SpatialDomains::GeomFactorsSharedPtr gfac = geom->GetGeomFactors();
94 
95  // Get the Jacobian and, if it is negative, print a warning
96  // message.
97  if (!gfac->IsValid())
98  {
99  invalid.push_back(el[i]);
100  }
101  }
102 
103  boost::unordered_set<int> inmesh;
105  vector<ElementSharedPtr> totest;
106 
107  for (int i = 0; i < invalid.size(); i++)
108  {
109  t = inmesh.insert(invalid[i]->GetId());
110  if (t.second)
111  m_mesh->m_element[m_mesh->m_expDim].push_back(invalid[i]);
112 
113  vector<FaceSharedPtr> f = invalid[i]->GetFaceList();
114  for (int j = 0; j < f.size(); j++)
115  {
116  for (int k = 0; k < f[j]->m_elLink.size(); k++)
117  {
118  if (f[j]->m_elLink[k].first->GetId() == invalid[i]->GetId())
119  continue;
120 
121  t = inmesh.insert(f[j]->m_elLink[k].first->GetId());
122  if (t.second)
123  {
124  m_mesh->m_element[m_mesh->m_expDim].push_back(
125  f[j]->m_elLink[k].first);
126  totest.push_back(f[j]->m_elLink[k].first);
127  }
128  }
129  }
130  }
131 
132  for (int i = 0; i < 12; i++)
133  {
134  vector<ElementSharedPtr> tmp = totest;
135  totest.clear();
136  for (int j = 0; j < tmp.size(); j++)
137  {
138  vector<FaceSharedPtr> f = tmp[j]->GetFaceList();
139  for (int k = 0; k < f.size(); k++)
140  {
141  for (int l = 0; l < f[k]->m_elLink.size(); l++)
142  {
143  if (f[k]->m_elLink[l].first->GetId() == tmp[j]->GetId())
144  continue;
145 
146  t = inmesh.insert(f[k]->m_elLink[l].first->GetId());
147  if (t.second)
148  {
149  m_mesh->m_element[m_mesh->m_expDim].push_back(
150  f[k]->m_elLink[l].first);
151  totest.push_back(f[k]->m_elLink[l].first);
152  }
153  }
154  }
155  }
156  }
157 
159  m_mesh->m_vertexSet.clear();
160  m_mesh->m_edgeSet.clear();
161  m_mesh->m_faceSet.clear();
162 
163  el = m_mesh->m_element[m_mesh->m_expDim];
164 
165  if (m_mesh->m_verbose)
166  cout << el.size() << " elements in blobs" << endl;
167 
168  m_mesh->m_faceSet.clear();
169 
170  // re build face links
171  for (int i = 0; i < el.size(); ++i)
172  {
173  for (int j = 0; j < el[i]->GetFaceCount(); ++j)
174  {
175  pair<FaceSet::iterator, bool> testIns;
176  testIns = m_mesh->m_faceSet.insert(el[i]->GetFace(j));
177 
178  if (testIns.second)
179  {
180  (*(testIns.first))
181  ->m_elLink.push_back(
182  pair<ElementSharedPtr, int>(el[i], j));
183  }
184  else
185  {
186  el[i]->SetFace(j, *testIns.first);
187  // Update face to element map.
188  (*(testIns.first))
189  ->m_elLink.push_back(
190  pair<ElementSharedPtr, int>(el[i], j));
191  }
192  }
193  }
194 
195  // build surface composite from faces
196  for (int i = 0; i < el.size(); i++)
197  {
198  vector<FaceSharedPtr> f = el[i]->GetFaceList();
199  for (int j = 0; j < f.size(); j++)
200  {
201  if (f[j]->m_elLink.size() ==
202  1) // boundary element make new composite
203  {
204  ElmtConfig conf(LibUtilities::eTriangle, 1, false, false);
205 
206  vector<int> tags;
207  tags.push_back(1);
210  conf,
211  f[j]->m_vertexList,
212  tags);
213  m_mesh->m_element[m_mesh->m_expDim - 1].push_back(E);
214  }
215  }
216  }
217 
219  for (int i = 0; i < el.size(); ++i)
220  {
221  for (int j = 0; j < el[i]->GetVertexCount(); ++j)
222  {
223  pair<NodeSet::iterator, bool> testIns =
224  m_mesh->m_vertexSet.insert(el[i]->GetVertex(j));
225 
226  if (!testIns.second)
227  {
228  el[i]->SetVertex(j, *testIns.first);
229  }
230  }
231  }
232  for (int i = 0; i < el.size(); ++i)
233  {
234  for (int j = 0; j < el[i]->GetEdgeCount(); ++j)
235  {
236  pair<EdgeSet::iterator, bool> testIns;
237  EdgeSharedPtr ed = el[i]->GetEdge(j);
238  testIns = m_mesh->m_edgeSet.insert(ed);
239 
240  if (testIns.second)
241  {
242  EdgeSharedPtr ed2 = *testIns.first;
243  ed2->m_elLink.push_back(
244  pair<ElementSharedPtr, int>(el[i], j));
245  }
246  else
247  {
248  EdgeSharedPtr e2 = *(testIns.first);
249  el[i]->SetEdge(j, e2);
250  if (e2->m_edgeNodes.size() == 0 &&
251  ed->m_edgeNodes.size() > 0)
252  {
253  e2->m_curveType = ed->m_curveType;
254  e2->m_edgeNodes = ed->m_edgeNodes;
255 
256  // Reverse nodes if appropriate.
257  if (e2->m_n1->m_id != ed->m_n1->m_id)
258  {
259  reverse(e2->m_edgeNodes.begin(),
260  e2->m_edgeNodes.end());
261  }
262  }
263 
264  // Update edge to element map.
265  e2->m_elLink.push_back(
266  pair<ElementSharedPtr, int>(el[i], j));
267  }
268  }
269  }
270  for (int i = 0; i < el.size(); ++i)
271  {
272  for (int j = 0; j < el[i]->GetFaceCount(); ++j)
273  {
274  pair<FaceSet::iterator, bool> testIns;
275  testIns = m_mesh->m_faceSet.insert(el[i]->GetFace(j));
276 
277  if (testIns.second)
278  {
279  (*(testIns.first))
280  ->m_elLink.push_back(
281  pair<ElementSharedPtr, int>(el[i], j));
282  }
283  else
284  {
285  el[i]->SetFace(j, *testIns.first);
286  // Update face to element map.
287  (*(testIns.first))
288  ->m_elLink.push_back(
289  pair<ElementSharedPtr, int>(el[i], j));
290  }
291  }
292  }
293  ProcessFaces(false);
295  }
296  else
297  {
298  // insert other mesh
299  cout << ins << endl;
300  MeshSharedPtr inp_mesh = boost::shared_ptr<Mesh>(new Mesh());
302  ModuleKey(eInputModule, "xml"), inp_mesh);
303  mod->RegisterConfig("infile", ins);
304  mod->Process();
305 
306  // need to update the vertices manually then the edges and faces can
307  // be updated using more simple means.
308  map<int, NodeSharedPtr> nmap;
309 
310  NodeSet::iterator nit;
311  for (nit = inp_mesh->m_vertexSet.begin();
312  nit != inp_mesh->m_vertexSet.end();
313  nit++)
314  {
315  nmap[(*nit)->m_id] = *nit;
316  }
317  // for all the nodes in the main mesh see if they are in nmap, if so
318  // update the node
319  for (nit = m_mesh->m_vertexSet.begin();
320  nit != m_mesh->m_vertexSet.end();
321  nit++)
322  {
323  if (nmap.count((*nit)->m_id) == 1)
324  {
326  s = nmap.find((*nit)->m_id);
327  NodeSharedPtr n = s->second;
328  (*nit)->m_x = n->m_x;
329  (*nit)->m_y = n->m_y;
330  (*nit)->m_z = n->m_z;
331  }
332  }
333  EdgeSet::iterator eit;
334  for (eit = inp_mesh->m_edgeSet.begin();
335  eit != inp_mesh->m_edgeSet.end();
336  eit++)
337  {
338  EdgeSet::iterator et = m_mesh->m_edgeSet.find(*eit);
339  if (et != m_mesh->m_edgeSet.end())
340  {
341  (*et)->m_edgeNodes = (*eit)->m_edgeNodes;
342  (*et)->m_curveType = (*eit)->m_curveType;
343  }
344  }
345  FaceSet::iterator fit;
346  for (fit = inp_mesh->m_faceSet.begin();
347  fit != inp_mesh->m_faceSet.end();
348  fit++)
349  {
350  FaceSet::iterator ft = m_mesh->m_faceSet.find(*fit);
351  if (ft != m_mesh->m_faceSet.end())
352  {
353  (*ft)->m_faceNodes = (*fit)->m_faceNodes;
354  (*ft)->m_curveType = (*fit)->m_curveType;
355  }
356  }
357  }
358 }
359 }
360 }
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
STL namespace.
pair< ModuleType, string > ModuleKey
ElementFactory & GetElementFactory()
Definition: Element.cpp:47
virtual void Process()
Write mesh to output file.
virtual NEKMESHUTILS_EXPORT void ProcessFaces(bool ReprocessFaces=true)
Extract element faces.
boost::shared_ptr< Module > ModuleSharedPtr
Represents a command-line configuration option.
boost::shared_ptr< Node > NodeSharedPtr
Definition: Node.h:50
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.
boost::shared_ptr< GeomFactors > GeomFactorsSharedPtr
Pointer to a GeomFactors object.
Definition: GeomFactors.h:62
boost::shared_ptr< Element > ElementSharedPtr
Definition: Edge.h:49
std::pair< ModuleType, std::string > ModuleKey
boost::shared_ptr< Geometry > GeometrySharedPtr
Definition: Geometry.h:53
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