Nektar++
Loading...
Searching...
No Matches
PressDecompVCSFSI.cpp
Go to the documentation of this file.
1///////////////////////////////////////////////////////////////////////////////
2//
3// File: PressDecompVCSFSI.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: Velocity Correction Scheme for fluid-structure interaction with
32// pressure decomposition
33///////////////////////////////////////////////////////////////////////////////
34
38
39#include <boost/algorithm/string.hpp>
40
41namespace Nektar
42{
45 "PressDecompVCSFSI", PressDecompVCSFSI::create);
46
49 "SolverType", "PressDecompVCSFSI", ePressDecompVCSFSI);
50
51/**
52 * Constructor. Creates ...
53 *
54 * \param
55 * \param
56 */
60 : UnsteadySystem(pSession, pGraph), VCSFSI(pSession, pGraph)
61{
62}
63
72
73/**
74 * Destructor
75 */
79
80void PressDecompVCSFSI::v_DoInitialise(bool dumpInitialConditions)
81{
83 VelocityCorrectionScheme::v_DoInitialise(dumpInitialConditions);
84 std::set<int> dofs; // 0,1,2;3,4,5 six dofs
85 GetMovableDoFs(dofs);
86 SolvePotentials(dofs);
89 Array<OneD, NekDouble> aeroforce(12, 0.);
90 InitialiseFilter(aeroforce);
91 m_rigidSolver.SetOldFvis(aeroforce);
92}
93
94void PressDecompVCSFSI::SolvePotentials(std::set<int> &dofs)
95{
96 std::map<int, Array<OneD, NekDouble>> boundValues;
97 std::map<int, Array<OneD, NekDouble>> pPhys;
98 CalculateBCs(dofs, boundValues);
99 for (auto i : dofs)
100 {
101 pPhys[i] = Array<OneD, NekDouble>(m_pressure->GetTotPoints(), 0.);
102 SolvePa(i, boundValues[i], pPhys[i]);
103 }
104 CalculateAddedMass(boundValues, pPhys);
105}
106
108{
109 if (m_pCoef.size() == 0)
110 {
111 return;
112 }
113 std::string varname("phi0");
114 std::vector<std::string> vars;
115 std::vector<Array<OneD, NekDouble>> fields;
116 for (auto it : m_pCoef)
117 {
118 varname[3] = '0' + it.first;
119 vars.push_back(varname);
120 fields.push_back(it.second);
121 }
122 WriteFld("potential.fld", m_pressure, fields, vars);
123}
124
125void PressDecompVCSFSI::CalculateBCs(std::set<int> &dofs,
126 std::map<int, Array<OneD, NekDouble>> &bcs)
127{
128 int ndim = m_fields[0]->GetCoordim(0);
129 // number of physics points for each field
130 int numpts = 0;
132 m_pressure->GetBndConditions();
134 m_pressure->GetBndCondExpansions();
135 for (int i = 0; i < BndConds.size(); ++i)
136 {
137 if (boost::iequals(BndConds[i]->GetUserDefined(), m_MRFABCname))
138 {
139 numpts += BndExp[i]->GetTotPoints();
140 }
141 }
142 // load pivot point
143 Array<OneD, NekDouble> pivot(3, 0.);
144 if (m_movingFrameData.size() >= 21)
145 {
146 pivot[0] = m_movingFrameData[18];
147 pivot[1] = m_movingFrameData[19];
148 pivot[2] = m_movingFrameData[20];
149 }
150 // allocate boundary condition storage
151 for (auto i : dofs)
152 {
153 bcs[i] = Array<OneD, NekDouble>(numpts, 0.);
154 }
155 // calculate values
156 int offset = 0;
157 for (int i = 0; i < BndConds.size(); ++i)
158 {
159 if (boost::iequals(BndConds[i]->GetUserDefined(), m_MRFABCname))
160 {
161 int npts = BndExp[i]->GetTotPoints();
164 for (int j = 0; j < 3; ++j)
165 {
166 n[j] = Array<OneD, NekDouble>(npts, 0.);
167 x[j] = Array<OneD, NekDouble>(npts, 0.);
168 }
169 BndExp[i]->GetNormals(n);
170 BndExp[i]->GetCoords(x[0], x[1], x[2]);
171 for (int j = 0; j < 3; ++j)
172 {
173 Vmath::Sadd(npts, -pivot[j], x[j], 1, x[j], 1);
174 }
176 for (int j = 0; j < ndim; ++j)
177 {
178 if (dofs.find(j) != dofs.end())
179 {
180 Vmath::Smul(npts, -1., n[j], 1, atmp = bcs[j] + offset, 1);
181 }
182 }
183 if (dofs.find(5) != dofs.end())
184 {
185 atmp = bcs[5] + offset;
186 Vmath::Vvtvvtm(npts, &x[1][0], 1, &n[0][0], 1, &x[0][0], 1,
187 &n[1][0], 1, &atmp[0], 1);
188 }
189 offset += npts;
190 }
191 }
192}
193
195 std::map<int, Array<OneD, NekDouble>> &boundValues,
196 std::map<int, Array<OneD, NekDouble>> &pPhys)
197{
198 bool homo1D = false;
199 m_session->MatchSolverInfo("Homogeneous", "1D", homo1D, false);
200 NekDouble lz = 1.;
201 if (homo1D)
202 {
203 lz = m_fields[0]->GetHomoLen();
204 }
205 // number of physics points for each field
207 m_pressure->GetBndConditions();
209 m_pressure->GetBndCondExpansions();
210
211 int offset = 0;
212 int nfld = pPhys.size();
213 Array<OneD, NekDouble> value(nfld * nfld,
214 std::numeric_limits<NekDouble>::lowest());
215 for (int i = 0; i < BndConds.size(); ++i)
216 {
217 if (boost::iequals(BndConds[i]->GetUserDefined(), m_MRFABCname))
218 {
219 MultiRegions::ExpListSharedPtr edgeExplist = BndExp[i];
222 m_pressure->GetBndElmtExpansion(i, BndElmtExp, false);
223 Array<OneD, NekDouble> phiElm(BndElmtExp->GetTotPoints(), 0.);
224 int j = 0;
225 for (auto it : pPhys)
226 {
227 m_pressure->ExtractPhysToBndElmt(i, it.second, phiElm);
228 m_pressure->ExtractElmtToBndPhys(i, phiElm, phi[j]);
229 ++j;
230 }
231 ////phi_0 n_0, phi_0 n_1, phi_1 n_0, phi_1 n_1
232 Array<OneD, NekDouble> mularray(edgeExplist->GetTotPoints(), 0.);
233 for (int j = 0; j < nfld; ++j)
234 {
235 int k = 0;
236 for (const auto &it : boundValues)
237 {
238 Vmath::Vmul(edgeExplist->GetTotPoints(), phi[j], 1,
239 it.second + offset, 1, mularray, 1);
240 NekDouble temp = edgeExplist->Integral(mularray) / lz;
241 if (std::numeric_limits<NekDouble>::lowest() ==
242 value[k + j * nfld])
243 {
244 value[k + j * nfld] = temp;
245 }
246 else
247 {
248 value[k + j * nfld] += temp;
249 }
250 ++k;
251 }
252 }
253 offset += edgeExplist->GetTotPoints();
254 }
255 }
256 m_session->GetComm()->AllReduce(value, LibUtilities::ReduceMax);
257 for (int j = 0; j < value.size(); ++j)
258 {
259 if (std::numeric_limits<NekDouble>::lowest() == value[j])
260 {
261 value[j] = 0;
262 }
263 }
264 int NumDofs = m_spacedim + 1;
265 m_addedMass = Array<OneD, NekDouble>(NumDofs * NumDofs, 0.);
266 int i = 0;
267 for (auto it : pPhys)
268 {
269 int i1 = std::min(it.first, m_spacedim);
270 int j = 0;
271 for (auto jt : pPhys)
272 {
273 int j1 = std::min(jt.first, m_spacedim);
274 m_addedMass[i1 + j1 * NumDofs] = value[i + nfld * j];
275 ++j;
276 }
277 ++i;
278 }
279 if (m_session->GetComm()->GetRank() == 0)
280 {
281 for (int j = 0; j < NumDofs; ++j)
282 {
283 for (int k = 0; k < NumDofs; ++k)
284 {
285 std::cout << "value[" << j << ", " << k
286 << "] = " << std::scientific << std::setprecision(7)
287 << m_addedMass[k + j * NumDofs] << std::endl;
288 }
289 }
290 }
291}
292
295{
297 m_pressure->GetBndConditions();
299 m_pressure->GetBndCondExpansions();
300 int offset = 0;
301 for (int i = 0; i < BndConds.size(); ++i)
302 {
303 if (boost::iequals(BndConds[i]->GetUserDefined(), m_MRFABCname))
304 {
305 BndExp[i]->IProductWRTBase(bc + offset, BndExp[i]->UpdateCoeffs());
306 offset += BndExp[i]->GetTotPoints();
307 }
308 }
310 factors[StdRegions::eFactorLambda] = 0.0;
311 Array<OneD, NekDouble> forcing(m_pressure->GetTotPoints(), 0.);
312 m_pCoef[i] = Array<OneD, NekDouble>(m_pressure->GetNcoeffs(), 0.);
313 m_pressure->HelmSolve(forcing, m_pCoef[i], factors);
314 m_pressure->BwdTrans(m_pCoef[i], pPhys);
315}
316
317/**
318 * Correct pressure by adding potential terms
319 */
321{
322 for (const auto &it : m_pCoef)
323 {
324 NekDouble acceleration = m_movingFrameData[it.first + 12];
325 if (std::fabs(acceleration) != 0.)
326 {
327 Vmath::Svtvp(m_pressure->GetNcoeffs(), acceleration, it.second, 1,
328 m_pressure->UpdateCoeffs(), 1,
329 m_pressure->UpdateCoeffs(), 1);
330 }
331 }
332}
333
339
340} // namespace Nektar
MultiRegions::ExpListSharedPtr m_pressure
Pointer to field holding pressure field.
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
static std::string RegisterEnumValue(std::string pEnum, std::string pString, int pEnumValue)
Registers an enumeration value.
PressDecompVCSFSI(const LibUtilities::SessionReaderSharedPtr &pSession, const SpatialDomains::MeshGraphSharedPtr &pGraph)
Constructor.
void CalculateBCs(std::set< int > &dofs, std::map< int, Array< OneD, NekDouble > > &bcs)
Array< OneD, NekDouble > m_addedMass
static SolverUtils::EquationSystemSharedPtr create(const LibUtilities::SessionReaderSharedPtr &pSession, const SpatialDomains::MeshGraphSharedPtr &pGraph)
Creates an instance of this class.
static std::string solverTypeLookupId
void CalculateAddedMass(std::map< int, Array< OneD, NekDouble > > &boundValues, std::map< int, Array< OneD, NekDouble > > &pPhys)
void v_InitObject(bool DeclareField=true) override
Initialisation object for EquationSystem.
void v_DoInitialise(bool dumpInitialConditions=true) override
Virtual function for initialisation implementation.
void SolvePotentials(std::set< int > &dofs)
std::map< int, Array< OneD, NekDouble > > m_pCoef
static std::string className
Name of class.
void SolvePa(int i, Array< OneD, NekDouble > bc, Array< OneD, NekDouble > pPhys)
void v_SolveSolid(NekDouble time) override
void SetNewmarkBetaSolver(Array< OneD, NekDouble > &AddedMass)
void InitObject(const LibUtilities::SessionReaderSharedPtr session, const MultiRegions::ExpListSharedPtr &pField, Array< OneD, NekDouble > pivot)
void SetMovableDoFs(std::vector< bool > &moveDoFs)
void SetOldFvis(Array< OneD, NekDouble > force)
void SetInitialConditions(const LibUtilities::SessionReaderSharedPtr session, Array< OneD, NekDouble > MRFData)
int m_spacedim
Spatial dimension (>= expansion dim).
Array< OneD, MultiRegions::ExpListSharedPtr > m_fields
Array holding all dependent variables.
SOLVER_UTILS_EXPORT void WriteFld(const std::string &outname)
Write field data to the given filename.
LibUtilities::SessionReaderSharedPtr m_session
The session reader.
Array< OneD, NekDouble > m_movingFrameData
Moving reference frame status in the body frame X, Y, Z, Theta_x, Theta_y, Theta_z,...
SOLVER_UTILS_EXPORT void GetMovableDoFs(std::set< int > &dirDoFs)
Base class for unsteady solvers.
void InitialiseFilter(Array< OneD, NekDouble > aeroforce)
Definition VCSFSI.cpp:89
RigidSolver m_rigidSolver
Definition VCSFSI.h:79
void v_SolveSolid(NekDouble time) override
Definition VCSFSI.cpp:106
void v_InitObject(bool DeclareField=true) override
Initialisation object for EquationSystem.
void v_DoInitialise(bool dumpInitialConditions=true) override
Sets up initial conditions.
std::shared_ptr< SessionReader > SessionReaderSharedPtr
std::shared_ptr< ExpList > ExpListSharedPtr
Shared pointer to an ExpList object.
EquationSystemFactory & GetEquationSystemFactory()
std::shared_ptr< MeshGraph > MeshGraphSharedPtr
Definition MeshGraph.h:224
std::map< ConstFactorType, NekDouble > ConstFactorMap
@ ePressDecompVCSFSI
void Vmul(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Multiply vector z = x*y.
Definition Vmath.hpp:72
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 Vvtvvtm(int n, const T *v, int incv, const T *w, int incw, const T *x, int incx, const T *y, int incy, T *z, int incz)
vvtvvtm (vector times vector minus vector times vector):
Definition Vmath.hpp:456
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