Nektar++
Loading...
Searching...
No Matches
CheckXmlFile.cpp
Go to the documentation of this file.
1///////////////////////////////////////////////////////////////////////////////
2//
3// File: CheckXmlFile.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// Permission is hereby granted, free of charge, to any person obtaining a
14// copy of this software and associated documentation files (the "Software"),
15// to deal in the Software without restriction, including without limitation
16// the rights to use, copy, modify, merge, publish, distribute, sublicense,
17// and/or sell copies of the Software, and to permit persons to whom the
18// Software is furnished to do so, subject to the following conditions:
19//
20// The above copyright notice and this permission notice shall be included
21// in all copies or substantial portions of the Software.
22//
23// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29// DEALINGS IN THE SOFTWARE.
30//
31// Description:
32//
33///////////////////////////////////////////////////////////////////////////////
34
37
38using namespace Nektar;
39
42 std::map<int, int> &vid2cnt);
43
44int main(int argc, char *argv[])
45{
47 Array<OneD, NekDouble> xc0, xc1, xc2;
48
49 if (argc != 2)
50 {
51 std::cerr << "Usage: CheckXmlFile meshfile.xml" << std::endl;
52 return 1;
53 }
54
57
58 //----------------------------------------------
59 // Read in mesh from input file
60 std::string meshfile(argv[argc - 1]);
63 //----------------------------------------------
64
65 //----------------------------------------------
66 // Define Expansion
67 int expdim = mesh->GetMeshDimension();
68
69 switch (expdim)
70 {
71 case 1:
72 ASSERTL0(false, "1D not set up");
73 break;
74 case 2:
75 ASSERTL0(false, "2D not set up");
76 break;
77 case 3:
78 {
79 int cnt = 0, nverts = mesh->GetNvertices();
80 Array<OneD, NekDouble> xc(nverts), yc(nverts), zc(nverts);
81 std::map<int, int> vid2cnt;
82
83 for (auto [id, vert] :
84 mesh->GetGeomMap<SpatialDomains::PointGeom>())
85 {
86 // Check element rotation
87 vert->GetCoords(xc[cnt], yc[cnt], zc[cnt]);
88 vid2cnt[vert->GetGlobalID()] = cnt++;
89 }
90
91 // Check for any duplicated vertex coordinates.
92 for (int i = 0; i < nverts; ++i)
93 {
94 for (int j = i + 1; j < nverts; ++j)
95 {
96 if ((xc[i] - xc[j]) * (xc[i] - xc[j]) +
97 (yc[i] - yc[j]) * (yc[i] - yc[j]) +
98 (zc[i] - zc[j]) * (zc[i] - zc[j]) <
99 1e-10)
100 {
101 std::cerr << "ERROR: Duplicate vertices: " << i << " "
102 << j << std::endl;
103 }
104 }
105 }
106
107 bool NoRotateIssues = true;
108 bool NoOrientationIssues = true;
109 for (auto [id, tet] : mesh->GetGeomMap<SpatialDomains::TetGeom>())
110 {
111 // check rotation and dump
112 NoOrientationIssues =
113 CheckTetRotation(xc, yc, zc, tet, vid2cnt);
114
115 // Check face rotation
116 if (tet->GetFace(0)->GetVid(2) != tet->GetVid(2))
117 {
118 std::cerr << "ERROR: Face " << tet->GetFid(0) << " (vert "
119 << tet->GetFace(0)->GetVid(2)
120 << ") is not aligned with base vertex of Tet "
121 << tet->GetGlobalID() << " (vert "
122 << tet->GetVid(2) << ")" << std::endl;
123 NoRotateIssues = false;
124 }
125
126 for (int i = 1; i < 4; ++i)
127 {
128 if (tet->GetFace(i)->GetVid(2) != tet->GetVid(3))
129 {
130 std::cerr << "ERROR: Face " << tet->GetFid(i)
131 << " is not aligned with top Vertex of Tet "
132 << tet->GetGlobalID() << std::endl;
133 NoRotateIssues = false;
134 }
135 }
136 }
137 if (NoOrientationIssues)
138 {
139 std::cout << "All Tet have correct ordering for anticlockwise "
140 "rotation"
141 << std::endl;
142 }
143
144 if (NoRotateIssues)
145 {
146 std::cout << "All Tet faces are correctly aligned" << std::endl;
147 }
148
149 for ([[maybe_unused]] auto [id, pyr] :
150 mesh->GetGeomMap<SpatialDomains::PyrGeom>())
151 {
152 // Put pyramid checks in here
153 }
154
155 NoRotateIssues = true;
156 NoOrientationIssues = true;
157 for (auto [id, pri] : mesh->GetGeomMap<SpatialDomains::PrismGeom>())
158 {
159 // Check face rotation
160 if (pri->GetFace(1)->GetVid(2) != pri->GetVid(4))
161 {
162 std::cerr
163 << "ERROR: Face " << pri->GetFid(1) << " (vert "
164 << pri->GetFace(1)->GetVid(2)
165 << ") not aligned to face 1 singular vert of Prism "
166 << pri->GetGlobalID() << " (vert " << pri->GetVid(4)
167 << ")" << std::endl;
168 NoRotateIssues = false;
169 }
170
171 // Check face rotation
172 if (pri->GetFace(3)->GetVid(2) != pri->GetVid(5))
173 {
174 std::cerr
175 << "ERROR: Face " << pri->GetFid(3) << " (vert "
176 << pri->GetFace(3)->GetVid(2)
177 << ") not aligned to face 3 singular vert of Prism "
178 << pri->GetGlobalID() << " (vert " << pri->GetVid(5)
179 << ")" << std::endl;
180 NoRotateIssues = false;
181 }
182 }
183
184 if (NoRotateIssues)
185 {
186 std::cout << "All Prism Tri faces are correctly aligned"
187 << std::endl;
188 }
189
190 for ([[maybe_unused]] auto [id, hex] :
191 mesh->GetGeomMap<SpatialDomains::HexGeom>())
192 {
193 // Put hex checks in here
194 }
195 }
196
197 break;
198 default:
199 ASSERTL0(false, "Expansion dimension not recognised");
200 break;
201 }
202
203 //-----------------------------------------------
204
205 return 0;
206}
207
208struct Ord
209{
210public:
211 double x;
212 double y;
213 double z;
214};
215
218 std::map<int, int> &vid2cnt)
219{
220 bool RotationOK = true;
221 std::array<Ord, 4> v;
222 NekDouble abx, aby, abz;
223
224 v[0].x = xc[vid2cnt[tet->GetVid(0)]];
225 v[0].y = yc[vid2cnt[tet->GetVid(0)]];
226 v[0].z = zc[vid2cnt[tet->GetVid(0)]];
227
228 v[1].x = xc[vid2cnt[tet->GetVid(1)]];
229 v[1].y = yc[vid2cnt[tet->GetVid(1)]];
230 v[1].z = zc[vid2cnt[tet->GetVid(1)]];
231
232 v[2].x = xc[vid2cnt[tet->GetVid(2)]];
233 v[2].y = yc[vid2cnt[tet->GetVid(2)]];
234 v[2].z = zc[vid2cnt[tet->GetVid(2)]];
235
236 v[3].x = xc[vid2cnt[tet->GetVid(3)]];
237 v[3].y = yc[vid2cnt[tet->GetVid(3)]];
238 v[3].z = zc[vid2cnt[tet->GetVid(3)]];
239
240 // cross product of edge 0 and 2
241 abx = (v[1].y - v[0].y) * (v[2].z - v[0].z) -
242 (v[1].z - v[0].z) * (v[2].y - v[0].y);
243 aby = (v[1].z - v[0].z) * (v[2].x - v[0].x) -
244 (v[1].x - v[0].x) * (v[2].z - v[0].z);
245 abz = (v[1].x - v[0].x) * (v[2].y - v[0].y) -
246 (v[1].y - v[0].y) * (v[2].x - v[0].x);
247
248 // inner product of cross product with respect to edge 3 should be positive
249 if (((v[3].x - v[0].x) * abx + (v[3].y - v[0].y) * aby +
250 (v[3].z - v[0].z) * abz) < 0.0)
251 {
252 std::cerr << "ERROR: Element " << tet->GetGlobalID()
253 << "is NOT counter-clockwise\n"
254 << std::endl;
255 RotationOK = false;
256 }
257 return RotationOK;
258}
bool CheckTetRotation(Array< OneD, NekDouble > &xc, Array< OneD, NekDouble > &yc, Array< OneD, NekDouble > &xz, SpatialDomains::TetGeom *tet, std::map< int, int > &vid2cnt)
#define ASSERTL0(condition, msg)
static SessionReaderSharedPtr CreateInstance(int argc, char *argv[])
Creates an instance of the SessionReader class.
int GetVid(int i) const
Returns global id of vertex i of this object.
Definition Geometry.h:353
int GetGlobalID(void) const
Get the ID of this object.
Definition Geometry.h:322
static MeshGraphSharedPtr Read(const LibUtilities::SessionReaderSharedPtr pSession, LibUtilities::DomainRangeShPtr rng=LibUtilities::NullDomainRangeShPtr, bool fillGraph=true, SpatialDomains::MeshGraphSharedPtr partitionedGraph=nullptr)
std::shared_ptr< SessionReader > SessionReaderSharedPtr
std::shared_ptr< MeshGraph > MeshGraphSharedPtr
Definition MeshGraph.h:217
Definition main.py:1
double x
double y
double z