39 #include "../MeshElements.h"
55 ProcessPerAlign::create);
67 "Tag identifying first surface.");
69 "Tag identifying first surface.");
71 "Direction in which to align (either x, y, or z)");
73 "Attempt to reorient tets and prisms");
86 int surf1 =
m_config[
"surf1"]. as<int> ();
87 int surf2 =
m_config[
"surf2"]. as<int> ();
88 string dir =
m_config[
"dir"]. as<string>();
89 bool orient =
m_config[
"orient"].as<
bool> ();
93 cerr <<
"WARNING: surf1 must be set to a positive integer. "
94 <<
"Skipping periodic alignment." << endl;
100 cerr <<
"WARNING: surf2 must be set to a positive integer. "
101 <<
"Skipping periodic alignment." << endl;
105 if (dir !=
"x" && dir !=
"y" && dir !=
"z")
107 cerr <<
"WARNING: dir must be set to either x, y or z. "
108 <<
"Skipping periodic alignment." << endl;
113 vec[0] = dir ==
"x" ? 1.0 : 0.0;
114 vec[1] = dir ==
"y" ? 1.0 : 0.0;
115 vec[2] = dir ==
"z" ? 1.0 : 0.0;
120 if (it1 ==
m_mesh->m_composite.end())
122 cerr <<
"WARNING: Couldn't find surface " << surf1
123 <<
". Skipping periodic alignment." << endl;
127 if (it2 ==
m_mesh->m_composite.end())
129 cerr <<
"WARNING: Couldn't find surface " << surf2 <<
", "
130 <<
"skipping periodic alignment." << endl;
137 if (c1->m_items.size() != c2->m_items.size())
139 cerr <<
"WARNING: Surfaces " << surf1 <<
" and " << surf2
140 <<
" have different numbers of elements. Skipping periodic"
141 <<
" alignment." << endl;
145 c1->m_reorder =
false;
146 c2->m_reorder =
false;
148 map<int, pair<FaceSharedPtr, vector<int> > > perFaces;
151 map<int, Node> centroidMap;
153 for (
int i = 0; i < c2->m_items.size(); ++i)
156 for (
int j = 0; j < c2->m_items[i]->GetVertexCount(); ++j)
158 centroid += *(c2->m_items[i]->GetVertex(j));
160 centroid /= (
NekDouble)c2->m_items[i]->GetVertexCount();
161 centroidMap[i] = centroid;
164 boost::unordered_set<int> elmtDone;
165 map<int, int> elmtPairs;
166 map<int, int> vertCheck;
168 for (
int i = 0; i < c1->m_items.size(); ++i)
171 for (
int j = 0; j < c1->m_items[i]->GetVertexCount(); ++j)
173 centroid += *(c1->m_items[i]->GetVertex(j));
175 centroid /= (
NekDouble)c1->m_items[i]->GetVertexCount();
177 for (it = centroidMap.begin(); it != centroidMap.end(); ++it)
179 if (elmtDone.count(it->first) > 0)
184 Node dx = it->second - centroid;
185 if (fabs(fabs(dx.
m_x*vec[0] + dx.
m_y*vec[1] + dx.
m_z*vec[2])/
186 sqrt(dx.
abs2()) - 1.0) < 1e-8)
193 id1 = c1->m_items[i] ->GetEdgeLink()->
m_id;
194 id2 = c2->m_items[it->first]->GetEdgeLink()->m_id;
198 id1 = c1->m_items[i] ->GetFaceLink()->m_id;
199 id2 = c2->m_items[it->first]->GetFaceLink()->m_id;
202 elmtDone.insert(it->first);
203 elmtPairs[i] = it->first;
206 int nVerts = c1->m_items[i]->GetVertexCount();
207 vector<int> perVerts(nVerts, 0), perVertsInv(nVerts, 0);
211 for (
int k = 0; k < nVerts; ++k)
213 NodeSharedPtr n1 = c1->m_items[i]->GetFaceLink()->m_vertexList[k];
216 for (l = 0; l < nVerts; ++l)
219 c2->m_items[it->first]->GetFaceLink()->m_vertexList[l];
222 if (fabs(fabs(dn.
m_x*vec[0] + dn.
m_y*vec[1] +
224 sqrt(dn.
abs2()) - 1.0) < 1e-8)
231 if (vertCheck.count(id1) == 0)
233 vertCheck[id1] = id2;
238 "Periodic vertex already "
245 "Could not identify periodic vertices.");
248 int tot1 = 0, tot2 = 0;
249 for (
int k = 0; k < nVerts; ++k)
251 tot1 += perVerts [k];
252 tot2 += perVertsInv[k];
254 ASSERTL0(tot1 == nVerts*(nVerts-1)/2 &&
255 tot2 == nVerts*(nVerts-1)/2,
256 "Error identifying periodic vertices");
261 perFaces[id1] = make_pair(
262 c2->m_items[it->first]->GetFaceLink(), perVerts);
263 perFaces[id2] = make_pair(
264 c1->m_items[i] ->GetFaceLink(), perVertsInv);
270 if (it == centroidMap.end())
272 cerr <<
"WARNING: Could not find matching edge for surface "
273 <<
"element " << c1->m_items[i]->GetId() <<
". "
274 <<
"Skipping periodic alignment." << endl;
280 vector<ElementSharedPtr> tmp = c2->m_items;
284 for (
int i = 0; i < tmp.size(); ++i)
286 c2->m_items[i] = tmp[elmtPairs[i]];
#define ASSERTL0(condition, msg)
pair< ModuleType, string > ModuleKey
map< string, ConfigOption > m_config
List of configuration values.
MeshSharedPtr m_mesh
Mesh object.
boost::shared_ptr< Node > NodeSharedPtr
Shared pointer to a Node.
boost::shared_ptr< Composite > CompositeSharedPtr
Shared pointer to a composite.
NekDouble m_x
X-coordinate.
boost::shared_ptr< Mesh > MeshSharedPtr
Shared pointer to a mesh.
NekDouble m_y
Y-coordinate.
Represents a point in the domain.
Represents a command-line configuration option.
StandardMatrixTag boost::call_traits< LhsDataType >::const_reference rhs typedef NekMatrix< LhsDataType, StandardMatrixTag >::iterator iterator
virtual void Process()
Write mesh to output file.
NekDouble m_z
Z-coordinate.
virtual ~ProcessPerAlign()
Destructor.
void ReorderPrisms(PerMap &perFaces)
Reorder node IDs so that prisms and tetrahedra are aligned correctly.
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode...
ModuleFactory & GetModuleFactory()
Abstract base class for processing modules.
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, tDescription pDesc="")
Register a class with the factory.