Nektar++
Loading...
Searching...
No Matches
Movement/Zones.cpp
Go to the documentation of this file.
1////////////////////////////////////////////////////////////////////////////////
2//
3// File: Zones.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: Zones used in the non-conformal interfaces
33// and ALE implementations
34//
35////////////////////////////////////////////////////////////////////////////////
36
40#include <tinyxml.h>
41
43{
44
45ZoneBase::ZoneBase(MovementType type, int indx, int domainID,
46 CompositeMap domain, int coordDim)
47 : m_type(type), m_id(indx), m_domainID(domainID), m_domain(domain),
48 m_coordDim(coordDim)
49{
50 for (auto &comp : domain)
51 {
52 for (auto &geom : comp.second->m_geomVec)
53 {
54 m_elements.emplace_back(geom);
55
56 // Fill constituent elements (i.e. faces and edges)
57 switch (geom->GetShapeDim())
58 {
59 case 3:
60 for (int i = 0; i < geom->GetNumFaces(); ++i)
61 {
62 m_constituentElements[2].insert(geom->GetFace(i));
63 }
64 /* fall through */
65 case 2:
66 for (int i = 0; i < geom->GetNumEdges(); ++i)
67 {
68 m_constituentElements[1].insert(geom->GetEdge(i));
69 }
70 /* fall through */
71 case 1:
72 m_constituentElements[0].insert(geom);
73 /* fall through */
74 default:
75 break;
76 }
77 }
78 }
79
80 // The seenVerts/Edges/Faces keeps track of geometry so duplicates aren't
81 // emplaced in to the storage vector
82 std::unordered_set<int> seenVerts, seenEdges, seenFaces;
83
84 // Fill verts/edges/faces vector storage that are to be moved each timestep
85 for (auto &comp : m_domain)
86 {
87 for (auto &geom : comp.second->m_geomVec)
88 {
89 for (int i = 0; i < geom->GetNumVerts(); ++i)
90 {
91 PointGeom *vert = geom->GetVertex(i);
92
93 if (seenVerts.find(vert->GetGlobalID()) != seenVerts.end())
94 {
95 continue;
96 }
97
98 seenVerts.insert(vert->GetGlobalID());
99 m_verts.emplace_back(vert);
100 }
101
102 for (int i = 0; i < geom->GetNumEdges(); ++i)
103 {
104 SegGeom *edge = static_cast<SegGeom *>(geom->GetEdge(i));
105
106 if (seenEdges.find(edge->GetGlobalID()) != seenEdges.end())
107 {
108 continue;
109 }
110
111 seenEdges.insert(edge->GetGlobalID());
112
113 CurveSharedPtr curve = edge->GetCurve();
114 if (!curve)
115 {
116 continue;
117 }
118
119 m_curves.emplace_back(curve);
120 }
121
122 for (int i = 0; i < geom->GetNumFaces(); ++i)
123 {
124 Geometry2D *face = static_cast<Geometry2D *>(geom->GetFace(i));
125
126 if (seenFaces.find(face->GetGlobalID()) != seenFaces.end())
127 {
128 continue;
129 }
130
131 seenFaces.insert(face->GetGlobalID());
132
133 CurveSharedPtr curve = face->GetCurve();
134 if (!curve)
135 {
136 continue;
137 }
138
139 m_curves.emplace_back(curve);
140 }
141 }
142 }
143
144 // Copy points so we know original positions.
145 for (auto &pt : m_verts)
146 {
147 m_origVerts.emplace_back(*pt);
148 }
149
150 for (auto &curve : m_curves)
151 {
152 for (auto &pt : curve->m_points)
153 {
154 m_origVerts.emplace_back(*pt);
155 }
156 }
157}
158
159ZoneRotate::ZoneRotate(int id, int domainID, const CompositeMap &domain,
160 const int coordDim, const NekPoint<NekDouble> &origin,
161 const DNekVec &axis,
162 const LibUtilities::EquationSharedPtr &angularVelEqn,
163 const NekDouble rampTime, const NekDouble sector,
164 const Array<OneD, NekDouble> &base)
165 : ZoneBase(MovementType::eRotate, id, domainID, domain, coordDim),
166 m_origin(origin), m_axis(axis), m_angularVelEqn(angularVelEqn),
167 m_rampTime(rampTime), m_sector(sector), m_base(base)
168{
169 // Construct rotation matrix
170 m_W(0, 1) = -m_axis[2];
171 m_W(0, 2) = m_axis[1];
172 m_W(1, 0) = m_axis[2];
173 m_W(1, 2) = -m_axis[0];
174 m_W(2, 0) = -m_axis[1];
175 m_W(2, 1) = m_axis[0];
176
177 m_W2 = m_W * m_W;
178}
179
181{
182 // Clear bboxes (these will be regenerated next time GetBoundingBox is
183 // called)
184 for (auto &el : m_elements)
185 {
186 el->ClearBoundingBox();
187
188 int nfaces = el->GetNumFaces();
189 for (int i = 0; i < nfaces; ++i)
190 {
191 el->GetFace(i)->ClearBoundingBox();
192 }
193
194 int nedges = el->GetNumEdges();
195 for (int i = 0; i < nedges; ++i)
196 {
197 el->GetEdge(i)->ClearBoundingBox();
198 }
199 }
200}
201
203{
204 if (time < m_rampTime)
205 {
206 return m_angularVelEqn->Evaluate(0, 0, 0, time) * time / m_rampTime;
207 }
208 else
209 {
210 return m_angularVelEqn->Evaluate(0, 0, 0, time);
211 }
212}
213
214// Calculate angle rotated at given time
216{
217 // This works for a linear ramp
218 if (time < m_rampTime)
219 {
220 m_angle = GetAngularVel(time) * (time) / 2;
221 }
222 else
223 {
225 GetAngularVel(time) * (time - m_rampTime);
226 }
227 return m_angle;
228}
229
230// Calculate new location of points using Rodrigues formula
232{
233 NekDouble angle = GetAngle(time);
234
235 if (angle == 0.0)
236 {
237 return false;
238 }
239
240 // Identity matrix
241 DNekMat rot(3, 3, 0.0);
242 rot(0, 0) = 1.0;
243 rot(1, 1) = 1.0;
244 rot(2, 2) = 1.0;
245
246 // Rodrigues' rotation formula in matrix form
247 rot = rot + sin(angle) * m_W + (1 - cos(angle)) * m_W2;
248
249 int cnt = 0;
250 for (auto &vert : m_verts)
251 {
253 DNekVec pntVec = {pnt[0], pnt[1], pnt[2]};
254
255 DNekVec newLoc = rot * pntVec;
256
257 vert->UpdatePosition(newLoc(0) + m_origin[0], newLoc(1) + m_origin[1],
258 newLoc(2) + m_origin[2]);
259 cnt++;
260 }
261
262 for (auto &curve : m_curves)
263 {
264 for (auto &vert : curve->m_points)
265 {
267 DNekVec pntVec = {pnt[0], pnt[1], pnt[2]};
268
269 DNekVec newLoc = rot * pntVec;
270
271 vert->UpdatePosition(newLoc(0) + m_origin[0],
272 newLoc(1) + m_origin[1],
273 newLoc(2) + m_origin[2]);
274 cnt++;
275 }
276 }
277
279
280 return true;
281}
282
284 const NekDouble &angle)
285{
286 // Identity matrix
287 DNekMat rot(3, 3, 0.0);
288 rot(0, 0) = 1.0;
289 rot(1, 1) = 1.0;
290 rot(2, 2) = 1.0;
291
292 // Rodrigues' rotation formula in matrix form
293 rot = rot + sin(angle) * m_W + (1 - cos(angle)) * m_W2;
294
295 DNekVec pntVec = {gloCoord[0] - m_origin[0], gloCoord[1] - m_origin[1],
296 gloCoord[2] - m_origin[2]};
297
298 DNekVec newLoc = rot * pntVec;
299
300 gloCoord[0] = newLoc(0) + m_origin[0];
301 gloCoord[1] = newLoc(1) + m_origin[1];
302 gloCoord[2] = newLoc(2) + m_origin[2];
303}
304
306 int id, int domainID, const CompositeMap &domain, const int coordDim,
308 const Array<OneD, LibUtilities::EquationSharedPtr> &displacementEqns)
309 : ZoneBase(MovementType::eTranslate, id, domainID, domain, coordDim),
310 m_velocityEqns(velocityEqns), m_displacementEqns(displacementEqns)
311{
312 int NumVerts = m_origVerts.size();
313 // Bounding length
315 // Bounding box
317 // NekDouble minx, miny, minz, maxx, maxy, maxz;
320 // Initialise max and min
321 for (int j = 0; j < 3; ++j)
322 {
323 min[j] = std::numeric_limits<double>::max();
324 max[j] = -std::numeric_limits<double>::max();
325 }
326 // Loop over all original vertexes to get the box and length
327 for (int i = 0; i < NumVerts; ++i)
328 {
329 PointGeom p = m_origVerts[i];
330 p.GetCoords(x[0], x[1], x[2]);
331 for (int j = 0; j < 3; ++j)
332 {
333 min[j] = (x[j] < min[j] ? x[j] : min[j]);
334 max[j] = (x[j] > max[j] ? x[j] : max[j]);
335 }
336 }
337 for (int j = 0; j < 3; ++j)
338 {
339 m_ZoneBox[j] = min[j];
340 m_ZoneBox[j + 3] = max[j];
341 m_ZoneLength[j] = max[j] - min[j];
342 }
343}
344
345std::vector<NekDouble> ZoneTranslate::GetVel(NekDouble &time) const
346{
347 std::vector<NekDouble> vel(m_coordDim);
348 for (int i = 0; i < m_coordDim; ++i)
349 {
350 vel[i] = m_velocityEqns[i]->Evaluate(0, 0, 0, time);
351 }
352
353 return vel;
354}
355
356std::vector<NekDouble> ZoneTranslate::GetDisp(NekDouble &time)
357{
358 m_disp = std::vector<NekDouble>(m_coordDim);
359 for (int i = 0; i < m_coordDim; ++i)
360 {
361 m_disp[i] = m_displacementEqns[i]->Evaluate(0, 0, 0, time);
362 }
363 return m_disp;
364}
365
367{
368 auto disp = GetDisp(time);
369
370 int cnt = 0;
371 for (auto &vert : m_verts)
372 {
373 Array<OneD, NekDouble> newLoc(3, 0.0);
374 auto pnt = m_origVerts[cnt];
375
376 for (int i = 0; i < m_coordDim; ++i)
377 {
378 newLoc[i] = pnt(i) + disp[i];
379 }
380
381 vert->UpdatePosition(newLoc[0], newLoc[1], newLoc[2]);
382 cnt++;
383 }
384
385 for (auto &curve : m_curves)
386 {
387 for (auto &vert : curve->m_points)
388 {
389 Array<OneD, NekDouble> newLoc(3, 0.0);
390 auto pnt = m_origVerts[cnt];
391
392 for (int i = 0; i < m_coordDim; ++i)
393 {
394 newLoc[i] = pnt(i) + disp[i];
395 }
396
397 vert->UpdatePosition(newLoc[0], newLoc[1], newLoc[2]);
398 cnt++;
399 }
400 }
401
403
404 return true;
405}
406
407bool ZoneFixed::v_Move([[maybe_unused]] NekDouble time)
408{
409 return false;
410}
411
412std::vector<NekDouble> ZoneFixed::v_GetDisp() const
413{
414 std::vector<NekDouble> disp(m_coordDim);
415 for (int i = 0; i < m_coordDim; ++i)
416 {
417 disp[i] = 0.0;
418 }
419
420 return disp;
421}
423{
424 return 0.0;
425}
426
427} // namespace Nektar::SpatialDomains
2D geometry information
Definition Geometry2D.h:50
int GetGlobalID(void) const
Get the ID of this object.
Definition Geometry.h:322
PointGeom * GetVertex(int i) const
Returns vertex i of this object.
Definition Geometry.h:361
CurveSharedPtr GetCurve()
Definition SegGeom.h:80
std::shared_ptr< Equation > EquationSharedPtr
Definition Equation.h:131
std::shared_ptr< Curve > CurveSharedPtr
Definition Curve.hpp:60
MovementType
Enum of zone movement type.
Definition Zones.h:48
std::map< int, CompositeSharedPtr > CompositeMap
Definition MeshGraph.h:179
scalarT< T > max(scalarT< T > lhs, scalarT< T > rhs)
Definition scalar.hpp:305
scalarT< T > min(scalarT< T > lhs, scalarT< T > rhs)
Definition scalar.hpp:300
Zone base: Contains the shared functions and variables.
Definition Zones.h:62
ZoneBase(MovementType type, int indx, int domainID, CompositeMap domain, int coordDim)
Constructor.
std::array< std::set< Geometry * >, 3 > m_constituentElements
Array of all dimension elements i.e. faces = [2], edges = [1], geom = [0].
Definition Zones.h:158
int m_coordDim
Coordinate dimension.
Definition Zones.h:162
void ClearBoundingBoxes()
Clears all bounding boxes associated with the zones elements.
std::vector< PointGeom > m_origVerts
Vector of all points in the zone at initialisation.
Definition Zones.h:168
std::vector< CurveSharedPtr > m_curves
Vector of all curves in the zone.
Definition Zones.h:166
CompositeMap m_domain
Zone domain.
Definition Zones.h:153
std::vector< Geometry * > m_elements
Vector of highest dimension zone elements.
Definition Zones.h:155
std::vector< PointGeomUniquePtr > m_verts
Vector of all points in the zone.
Definition Zones.h:164
std::vector< NekDouble > v_GetDisp() const override
Returns the displacement of the zone.
bool v_Move(NekDouble time) final
Virtual function for movement of the zone at.
NekDouble v_GetAngle() const override
Returns the displacement of the zone.
DNekVec m_axis
Axis rotation is performed around.
Definition Zones.h:254
NekDouble GetAngle(const NekDouble &time)
Returns the rotation angle of the zone.
DNekMat m_W
W matrix Rodrigues' rotation formula, cross product of axis.
Definition Zones.h:266
NekPoint< NekDouble > m_origin
Origin point rotation is performed around.
Definition Zones.h:252
NekDouble GetAngularVel(const NekDouble &time) const
Return the angular velocity of the zone at.
LibUtilities::EquationSharedPtr m_angularVelEqn
Equation defining angular velocity as a function of time.
Definition Zones.h:256
void Rotate(Array< OneD, NekDouble > &gloCoord, const NekDouble &angle)
Rotates the given global coordinate by the given angle.
NekDouble m_angle
Rotate angle.
Definition Zones.h:258
NekDouble m_rampTime
Ramp time.
Definition Zones.h:260
ZoneRotate(int id, int domainID, const CompositeMap &domain, const int coordDim, const NekPoint< NekDouble > &origin, const DNekVec &axis, const LibUtilities::EquationSharedPtr &angularVelEqn, const NekDouble rampTime, const NekDouble sector, const Array< OneD, NekDouble > &base)
bool v_Move(NekDouble time) final
Virtual function for movement of the zone at.
DNekMat m_W2
W^2 matrix Rodrigues' rotation formula, cross product of axis squared.
Definition Zones.h:268
std::vector< NekDouble > GetDisp(NekDouble &time)
Returns the displacement of the zone.
Array< OneD, NekDouble > m_ZoneLength
Definition Zones.h:345
std::vector< NekDouble > m_disp
Definition Zones.h:343
bool v_Move(NekDouble time) final
Virtual function for movement of the zone at.
Array< OneD, LibUtilities::EquationSharedPtr > m_displacementEqns
Definition Zones.h:342
Array< OneD, LibUtilities::EquationSharedPtr > m_velocityEqns
Definition Zones.h:341
std::vector< NekDouble > GetVel(NekDouble &time) const
Returns the velocity of the zone.
ZoneTranslate(int id, int domainID, const CompositeMap &domain, const int coordDim, const Array< OneD, LibUtilities::EquationSharedPtr > &velocityEqns, const Array< OneD, LibUtilities::EquationSharedPtr > &displacementEqns)
Array< OneD, NekDouble > m_ZoneBox
Definition Zones.h:344