Nektar++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ProcessDetectSurf.cpp
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // File: ProcessDetectSurf.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: Extract one or more surfaces from mesh.
33 //
34 ////////////////////////////////////////////////////////////////////////////////
35 
38 #include "ProcessDetectSurf.h"
39 
40 using namespace std;
41 using namespace Nektar::NekMeshUtils;
42 
43 namespace Nektar
44 {
45 namespace Utilities
46 {
47 
48 ModuleKey ProcessDetectSurf::className =
50  ModuleKey(eProcessModule, "detect"),
51  ProcessDetectSurf::create,
52  "Process elements to detect a surface.");
53 
54 ProcessDetectSurf::ProcessDetectSurf(MeshSharedPtr m) : ProcessModule(m)
55 {
56  m_config["vol"] =
57  ConfigOption(false, "-1", "Tag identifying surface to process.");
58 }
59 
61 {
62 }
63 
64 struct EdgeInfo
65 {
66  EdgeInfo() : count(0)
67  {
68  }
69  int count;
71  unsigned int group;
72 };
73 
75 {
76  if (m_mesh->m_expDim > 2)
77  {
78  cerr << "Surface detection only implemented for 2D meshes" << endl;
79  return;
80  }
81 
82  int i, j;
83  string surf = m_config["vol"].as<string>();
84 
85  // Obtain vector of surface IDs from string.
86  vector<unsigned int> surfs;
87  if (surf != "-1")
88  {
89  ParseUtils::GenerateSeqVector(surf.c_str(), surfs);
90  sort(surfs.begin(), surfs.end());
91  }
92 
93  // If we're running in verbose mode print out a list of surfaces.
94  if (m_mesh->m_verbose)
95  {
96  cout << "ProcessDetectSurf: detecting surfaces";
97  if (surfs.size() > 0)
98  {
99  cout << " for surface" << (surfs.size() == 1 ? "" : "s") << " "
100  << surf << endl;
101  }
102  }
103 
104  vector<ElementSharedPtr> &el = m_mesh->m_element[m_mesh->m_expDim];
105  map<int, EdgeInfo> edgeCount;
106  set<int> doneIds;
107  map<int, int> idMap;
108 
109  // Iterate over list of surface elements.
110  for (i = 0; i < el.size(); ++i)
111  {
112  // Work out whether this lies on our surface of interest.
113  if (surfs.size() > 0)
114  {
115  vector<int> inter, tags = el[i]->GetTagList();
116 
117  sort(tags.begin(), tags.end());
118  set_intersection(surfs.begin(),
119  surfs.end(),
120  tags.begin(),
121  tags.end(),
122  back_inserter(inter));
123 
124  // It doesn't continue to next element.
125  if (inter.size() != 1)
126  {
127  continue;
128  }
129  }
130 
131  // List all edges.
132  ElementSharedPtr elmt = el[i];
133  for (j = 0; j < elmt->GetEdgeCount(); ++j)
134  {
135  EdgeSharedPtr e = elmt->GetEdge(j);
136  int eId = e->m_id;
137  edgeCount[eId].count++;
138  edgeCount[eId].edge = e;
139  }
140 
141  doneIds.insert(elmt->GetId());
142  ASSERTL0(idMap.count(elmt->GetId()) == 0, "Shouldn't happen");
143  idMap[elmt->GetId()] = i;
144  }
145 
147  unsigned int maxId = 0;
148 
149  for (cIt = m_mesh->m_composite.begin(); cIt != m_mesh->m_composite.end();
150  ++cIt)
151  {
152  maxId = (std::max)(cIt->first, maxId);
153  }
154 
155  ++maxId;
156 
158 
159  while (doneIds.size() > 0)
160  {
161  ElementSharedPtr start =
162  m_mesh->m_element[m_mesh->m_expDim][idMap[*(doneIds.begin())]];
163 
164  vector<ElementSharedPtr> block;
165  FindContiguousSurface(start, doneIds, block);
166  ASSERTL0(block.size() > 0, "Contiguous block not found");
167 
168  // Loop over all edges in block.
169  for (i = 0; i < block.size(); ++i)
170  {
171  // Find edge info.
172  ElementSharedPtr elmt = block[i];
173 
174  for (j = 0; j < elmt->GetEdgeCount(); ++j)
175  {
176  eIt = edgeCount.find(elmt->GetEdge(j)->m_id);
177  ASSERTL0(eIt != edgeCount.end(), "Couldn't find edge");
178  eIt->second.group = maxId;
179  }
180  }
181 
182  ++maxId;
183  }
184 
185  for (eIt = edgeCount.begin(); eIt != edgeCount.end(); ++eIt)
186  {
187  if (eIt->second.count > 1)
188  {
189  continue;
190  }
191 
192  unsigned int compId = eIt->second.group;
193  CompositeMap::iterator cIt = m_mesh->m_composite.find(compId);
194 
195  if (cIt == m_mesh->m_composite.end())
196  {
197  CompositeSharedPtr comp(new Composite());
198  comp->m_id = compId;
199  comp->m_tag = "E";
200  cIt =
201  m_mesh->m_composite.insert(std::make_pair(compId, comp)).first;
202  }
203 
204  vector<int> tags(1);
205  tags[0] = compId;
206  vector<NodeSharedPtr> nodeList(2);
207  nodeList[0] = eIt->second.edge->m_n1;
208  nodeList[1] = eIt->second.edge->m_n2;
209 
210  ElmtConfig conf(LibUtilities::eSegment, 1, false, false);
212  LibUtilities::eSegment, conf, nodeList, tags);
213  elmt->SetEdgeLink(eIt->second.edge);
214 
215  cIt->second->m_items.push_back(elmt);
216  }
217 }
218 
220  set<int> &doneIds,
221  vector<ElementSharedPtr> &block)
222 {
223  block.push_back(start);
224  doneIds.erase(start->GetId());
225 
226  vector<EdgeSharedPtr> edges = start->GetEdgeList();
227 
228  for (int i = 0; i < edges.size(); ++i)
229  {
230  for (int j = 0; j < edges[i]->m_elLink.size(); ++j)
231  {
232  ElementSharedPtr elmt = edges[i]->m_elLink[j].first;
233  if (elmt == start)
234  {
235  continue;
236  }
237 
238  if (doneIds.count(elmt->GetId()) == 0)
239  {
240  continue;
241  }
242 
243  FindContiguousSurface(elmt, doneIds, block);
244  }
245  }
246 }
247 }
248 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:161
Basic information about an element.
Definition: Element.h:58
pair< ModuleType, string > ModuleKey
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
map< string, ConfigOption > m_config
List of configuration values.
STL namespace.
MeshSharedPtr m_mesh
Mesh object.
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< Composite > CompositeSharedPtr
Shared pointer to a composite.
Definition: Composite.h:121
virtual void Process()
Write mesh to output file.
boost::shared_ptr< GeometryVector > Composite
Definition: MeshGraph.h:114
Represents a command-line configuration option.
boost::shared_ptr< Edge > EdgeSharedPtr
Shared pointer to an edge.
Definition: Edge.h:196
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:137
boost::shared_ptr< Element > ElementSharedPtr
Definition: Edge.h:52
ModuleFactory & GetModuleFactory()
Abstract base class for processing modules.
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, tDescription pDesc="")
Register a class with the factory.
Definition: NekFactory.hpp:215
void FindContiguousSurface(ElementSharedPtr start, set< int > &doneIds, vector< ElementSharedPtr > &block)