Nektar++
IncBaseCondition.cpp
Go to the documentation of this file.
1///////////////////////////////////////////////////////////////////////////////
2//
3// File: IncBaseCondition.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: Abstract base class for Extrapolate.
32//
33///////////////////////////////////////////////////////////////////////////////
34
37
38namespace Nektar
39{
41 {1.0, 0.0, 0.0}, {2.0, -1.0, 0.0}, {3.0, -3.0, 1.0}};
43 {1.0, 0.0, 0.0}, {2.0, -0.5, 0.0}, {3.0, -1.5, 1.0 / 3.0}};
45 11.0 / 6.0};
46
48{
49 static IncBCFactory instance;
50 return instance;
51}
52
54 [[maybe_unused]] const LibUtilities::SessionReaderSharedPtr pSession,
55 [[maybe_unused]] Array<OneD, MultiRegions::ExpListSharedPtr> pFields,
58 [[maybe_unused]] int nbnd, [[maybe_unused]] int spacedim,
59 [[maybe_unused]] int bnddim)
60 : m_spacedim(spacedim), m_bnddim(bnddim), m_nbnd(nbnd), m_field(pFields[0])
61{
62}
63
65{
66}
67
70{
71 m_npoints = m_BndExp.begin()->second->GetNpoints();
72 m_numCalls = 0;
73 if (pSession->DefinesParameter("ExtrapolateOrder"))
74 {
75 m_intSteps = std::round(pSession->GetParameter("ExtrapolateOrder"));
76 m_intSteps = std::min(3, std::max(0, m_intSteps));
77 }
78 else if (pSession->DefinesSolverInfo("TimeIntegrationMethod"))
79 {
80 if (pSession->GetSolverInfo("TimeIntegrationMethod") == "IMEXOrder1")
81 {
82 m_intSteps = 1;
83 }
84 else if (pSession->GetSolverInfo("TimeIntegrationMethod") ==
85 "IMEXOrder2")
86 {
87 m_intSteps = 2;
88 }
89 else
90 {
91 m_intSteps = 3;
92 }
93 }
94 else
95 {
96 m_intSteps = 0;
97 }
98}
99
101{
102 if (m_BndExp.begin()->second->GetExpType() == MultiRegions::e2DH1D)
103 {
104 if (m_field->GetZIDs()[0] == 0)
105 {
106 npointsPlane0 = m_BndExp.begin()->second->GetPlane(0)->GetNpoints();
107 }
108 else
109 {
110 npointsPlane0 = 0;
111 }
112 }
113 else
114 {
115 npointsPlane0 = m_BndExp.begin()->second->GetNpoints();
116 }
117}
118
120 std::map<std::string, NekDouble> &params)
121{
122 MultiRegions::ExpListSharedPtr bndexp = m_BndExp.begin()->second;
123 if (m_coords.size() == 0)
124 {
126 for (size_t k = 0; k < m_spacedim; ++k)
127 {
129 }
130 if (m_spacedim == 2)
131 {
132 bndexp->GetCoords(m_coords[0], m_coords[1]);
133 }
134 else
135 {
136 bndexp->GetCoords(m_coords[0], m_coords[1], m_coords[2]);
137 }
138 // move the centre to the location of pivot
139 std::vector<std::string> xyz = {"X0", "Y0", "Z0"};
140 for (int i = 0; i < m_spacedim; ++i)
141 {
142 if (params.find(xyz[i]) != params.end())
143 {
144 Vmath::Sadd(m_npoints, -params[xyz[i]], m_coords[i], 1,
145 m_coords[i], 1);
146 }
147 }
148 }
149}
150
152 const int numCalls, Array<OneD, Array<OneD, Array<OneD, NekDouble>>> &array)
153{
154 if (m_intSteps == 1)
155 {
156 return;
157 }
158 int nint = std::min(numCalls, m_intSteps);
159 int nlevels = array.size();
160 int dim = array[0].size();
161 int nPts = array[0][0].size();
162 // Check integer for time levels
163 // Note that ExtrapolateArray assumes m_pressureCalls is >= 1
164 // meaning v_EvaluatePressureBCs has been called previously
165 ASSERTL0(nint > 0, "nint must be > 0 when calling ExtrapolateArray.");
166 // Update array
167 RollOver(array);
168 // Extrapolate to outarray
169 for (int i = 0; i < dim; ++i)
170 {
171 Vmath::Smul(nPts, StifflyStable_Betaq_Coeffs[nint - 1][nint - 1],
172 array[nint - 1][i], 1, array[nlevels - 1][i], 1);
173 }
174 for (int n = 0; n < nint - 1; ++n)
175 {
176 for (int i = 0; i < dim; ++i)
177 {
178 Vmath::Svtvp(nPts, StifflyStable_Betaq_Coeffs[nint - 1][n],
179 array[n][i], 1, array[nlevels - 1][i], 1,
180 array[nlevels - 1][i], 1);
181 }
182 }
183}
184
186 std::map<std::string, NekDouble> &params,
187 int npts0)
188{
189 if (npts0 == 0)
190 {
191 return;
192 }
194 for (size_t k = 0; k < m_spacedim; ++k)
195 {
196 acceleration[k] = Array<OneD, NekDouble>(npts0, 0.0);
197 }
198
199 // set up pressure condition
200 if (params.find("Omega_z") != params.end())
201 {
202 NekDouble Wz2 = params["Omega_z"] * params["Omega_z"];
203 NekDouble dWz = 0.;
204 if (params.find("DOmega_z") != params.end())
205 {
206 dWz = params["DOmega_z"];
207 }
208 Vmath::Svtsvtp(npts0, Wz2, m_coords[0], 1, dWz, m_coords[1], 1, N[0],
209 1);
210 Vmath::Svtsvtp(npts0, Wz2, m_coords[1], 1, -dWz, m_coords[0], 1, N[1],
211 1);
212 }
213 std::vector<std::string> vars = {"A_x", "A_y", "A_z"};
214 for (int k = 0; k < m_bnddim; ++k)
215 {
216 if (params.find(vars[k]) != params.end())
217 {
218 Vmath::Sadd(npts0, -params[vars[k]], N[k], 1, N[k], 1);
219 }
220 }
221}
222
224 const Array<OneD, const Array<OneD, NekDouble>> &fields,
226 std::map<std::string, NekDouble> &params)
227{
228 if (m_intSteps == 0 || params.find("Kinvis") == params.end() ||
229 params["Kinvis"] <= 0. || fields.size() == 0)
230 {
231 return;
232 }
233 NekDouble kinvis = params["Kinvis"];
234 m_bndElmtExps->SetWaveSpace(m_field->GetWaveSpace());
237 // Loop all boundary conditions
238 int nq = m_bndElmtExps->GetTotPoints();
239 for (int i = 0; i < m_spacedim; i++)
240 {
241 Q[i] = Array<OneD, NekDouble>(nq, 0.0);
242 }
243
244 for (int i = 0; i < m_spacedim; i++)
245 {
246 m_field->ExtractPhysToBndElmt(m_nbnd, fields[i], Velocity[i]);
247 }
248
249 // CurlCurl
250 m_bndElmtExps->CurlCurl(Velocity, Q);
251
253 for (int i = 0; i < m_bnddim; i++)
254 {
255 m_field->ExtractElmtToBndPhys(m_nbnd, Q[i],
256 m_viscous[m_intSteps - 1][i]);
257 }
259 for (int i = 0; i < m_bnddim; i++)
260 {
261 Vmath::Svtvp(m_npoints, -kinvis, m_viscous[m_intSteps - 1][i], 1, N[i],
262 1, N[i], 1);
263 }
264}
265
268{
269 int nlevels = input.size();
271 tmp = input[nlevels - 1];
272 for (int n = nlevels - 1; n > 0; --n)
273 {
274 input[n] = input[n - 1];
275 }
276 input[0] = tmp;
277}
278
280 Array<OneD, Array<OneD, NekDouble>> &velocities,
281 std::map<std::string, NekDouble> &params, int npts0)
282{
283 if (npts0 == 0)
284 {
285 return;
286 }
287 // for the wall we need to calculate:
288 // [V_wall]_xyz = [V_frame]_xyz + [Omega X r]_xyz
289 // Note all vectors must be in moving frame coordinates xyz
290 // not in inertial frame XYZ
291
292 // vx = OmegaY*z-OmegaZ*y
293 // vy = OmegaZ*x-OmegaX*z
294 // vz = OmegaX*y-OmegaY*x
295 if (params.find("Omega_z") != params.end())
296 {
297 NekDouble Wz = params["Omega_z"];
298 if (m_BndExp.find(0) != m_BndExp.end())
299 {
300 Vmath::Smul(npts0, -Wz, m_coords[1], 1, velocities[0], 1);
301 }
302 if (m_BndExp.find(1) != m_BndExp.end())
303 {
304 Vmath::Smul(npts0, Wz, m_coords[0], 1, velocities[1], 1);
305 }
306 }
307 if (m_bnddim == 3)
308 {
309 if (params.find("Omega_x") != params.end())
310 {
311 NekDouble Wx = params["Omega_x"];
312 if (m_BndExp.find(2) != m_BndExp.end())
313 {
314 Vmath::Smul(npts0, Wx, m_coords[1], 1, velocities[2], 1);
315 }
316 if (m_BndExp.find(1) != m_BndExp.end())
317 {
318 Vmath::Svtvp(npts0, -Wx, m_coords[2], 1, velocities[1], 1,
319 velocities[1], 1);
320 }
321 }
322 if (params.find("Omega_y") != params.end())
323 {
324 NekDouble Wy = params["Omega_x"];
325 if (m_BndExp.find(0) != m_BndExp.end())
326 {
327 Vmath::Svtvp(npts0, Wy, m_coords[2], 1, velocities[0], 1,
328 velocities[0], 1);
329 }
330 if (m_BndExp.find(2) != m_BndExp.end())
331 {
332 Vmath::Svtvp(npts0, -Wy, m_coords[0], 1, velocities[2], 1,
333 velocities[2], 1);
334 }
335 }
336 }
337
338 // add the translation velocity
339 std::vector<std::string> vars = {"U", "V", "W"};
340 for (int k = 0; k < m_bnddim; ++k)
341 {
342 if (params.find(vars[k]) != params.end() &&
343 m_BndExp.find(k) != m_BndExp.end())
344 {
345 Vmath::Sadd(npts0, params[vars[k]], velocities[k], 1, velocities[k],
346 1);
347 }
348 }
349}
350
352 [[maybe_unused]] const Array<OneD, const Array<OneD, NekDouble>> &fields,
353 [[maybe_unused]] const Array<OneD, const Array<OneD, NekDouble>> &Adv,
354 [[maybe_unused]] std::map<std::string, NekDouble> &params)
355{
356}
357
358} // namespace Nektar
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:208
std::map< int, MultiRegions::ExpListSharedPtr > m_BndExp
Array< OneD, Array< OneD, Array< OneD, NekDouble > > > m_viscous
MultiRegions::ExpListSharedPtr m_field
static NekDouble StifflyStable_Alpha_Coeffs[3][3]
int m_bnddim
bounday dimensionality
void InitialiseCoords(std::map< std::string, NekDouble > &params)
IncBaseCondition(const LibUtilities::SessionReaderSharedPtr pSession, Array< OneD, MultiRegions::ExpListSharedPtr > pFields, Array< OneD, SpatialDomains::BoundaryConditionShPtr > cond, Array< OneD, MultiRegions::ExpListSharedPtr > exp, int nbnd, int spacedim, int bnddim)
virtual void v_Update(const Array< OneD, const Array< OneD, NekDouble > > &fields, const Array< OneD, const Array< OneD, NekDouble > > &Adv, std::map< std::string, NekDouble > &params)
void ExtrapolateArray(const int numCalls, Array< OneD, Array< OneD, Array< OneD, NekDouble > > > &array)
void RigidBodyVelocity(Array< OneD, Array< OneD, NekDouble > > &velocities, std::map< std::string, NekDouble > &params, int npts0)
MultiRegions::ExpListSharedPtr m_bndElmtExps
void RollOver(Array< OneD, Array< OneD, Array< OneD, NekDouble > > > &input)
void AddRigidBodyAcc(Array< OneD, Array< OneD, NekDouble > > &N, std::map< std::string, NekDouble > &params, int npts0)
virtual void v_Initialise(const LibUtilities::SessionReaderSharedPtr &pSession)
static NekDouble StifflyStable_Betaq_Coeffs[3][3]
static NekDouble StifflyStable_Gamma0_Coeffs[3]
void SetNumPointsOnPlane0(int &npointsPlane0)
void AddVisPressureBCs(const Array< OneD, const Array< OneD, NekDouble > > &fields, Array< OneD, Array< OneD, NekDouble > > &N, std::map< std::string, NekDouble > &params)
Array< OneD, Array< OneD, NekDouble > > m_coords
Provides a generic Factory class.
std::shared_ptr< SessionReader > SessionReaderSharedPtr
std::shared_ptr< ExpList > ExpListSharedPtr
Shared pointer to an ExpList object.
IncBCFactory & GetIncBCFactory()
double NekDouble
void Svtsvtp(int n, const T alpha, const T *x, int incx, const T beta, const T *y, int incy, T *z, int incz)
Svtsvtp (scalar times vector plus scalar times vector):
Definition: Vmath.hpp:473
void Svtvp(int n, const T alpha, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Svtvp (scalar times vector plus vector): z = alpha*x + y.
Definition: Vmath.hpp:396
void Smul(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha*x.
Definition: Vmath.hpp:100
void Sadd(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Add vector y = alpha + x.
Definition: Vmath.hpp:194