MAIA bb96820c
Multiphysics at AIA
Loading...
Searching...
No Matches
fvcartesianapesolver2d.cpp
Go to the documentation of this file.
1// Copyright (C) 2024 The m-AIA AUTHORS
2//
3// This file is part of m-AIA (https://git.rwth-aachen.de/aia/m-AIA/m-AIA)
4//
5// SPDX-License-Identifier: LGPL-3.0-only
6
8
9using namespace std;
10
11FvApeSolver2D::FvApeSolver2D(MInt solverId, MInt noSpecies, MBool* propertiesGroups, maia::grid::Proxy<2>& gridProxy_,
12 Geometry<2>& geometry_, const MPI_Comm comm)
13 : FvCartesianSolverXD<2, FvSysEqnNS<2>>(solverId, noSpecies, propertiesGroups, gridProxy_, geometry_, comm) {
15 Context::getSolverProperty<MFloat>("advectionVelocity", this->m_solverId, AT_, &m_advectionVelocity[0], 0);
17 Context::getSolverProperty<MFloat>("advectionVelocity", this->m_solverId, AT_, &m_advectionVelocity[1], 1);
18 IF_CONSTEXPR(nDim == 3) {
20 Context::getSolverProperty<MFloat>("advectionVelocity", this->m_solverId, AT_, &m_advectionVelocity[2], 2);
21 }
22 TRACE();
23}
24
26 // TRACE();
27 const MUint noVars = 2 + nDim;
28 const MUint surfaceVarMemory = 2 * noVars;
29 const MUint noSurfaces = a_noSurfaces();
30 // const MUint noInternalSurfaces = m_bndrySurfacesOffset;
31 // static constexpr MFloat epsilon = 0.000000000001; // pow( 10.0, -12.0 );
32
33 MFloat* const RESTRICT fluxes = ALIGNED_MF(&a_surfaceFlux(0, 0));
34 const MFloat* const RESTRICT surfaceVars = ALIGNED_F(&a_surfaceVariable(0, 0, 0));
35 const MFloat* const RESTRICT area = ALIGNED_F(&a_surfaceArea(0));
36 const MInt* const RESTRICT orientations = ALIGNED_I(&a_surfaceOrientation(0));
37 // const MInt *const RESTRICT bndryCndIds = ALIGNED_I(srfcs[0].m_bndryCndId);
38
39 // loop over all surfaces
40#ifdef _OPENMP
41#pragma omp parallel for
42#endif
43 for(MUint srfcId = 0; srfcId < noSurfaces; ++srfcId) {
44 // const MUint orientation = orientations[ srfcId ];
45
46 const MUint offset = srfcId * surfaceVarMemory;
47 const MFloat* const RESTRICT leftVars = ALIGNED_F(surfaceVars + offset);
48 const MFloat* const RESTRICT rightVars = ALIGNED_F(leftVars + noVars);
49
50 // catch the primitive variables u, v, rho and p,
51 const MFloat UL = leftVars[PV->U];
52 const MFloat VL = leftVars[PV->V];
53 const MFloat PL = leftVars[CV->RHO_E];
54
55 const MFloat UR = rightVars[PV->U];
56 const MFloat VR = rightVars[PV->V];
57 const MFloat PR = rightVars[CV->RHO_E];
58
59 // catch cell surface area A and advection velocity components
60 const MFloat A = area[srfcId];
61
62 const MFloat uBar = m_advectionVelocity[0];
63 const MFloat vBar = m_advectionVelocity[1];
64
65 const MUint fluxOffset = srfcId * noVars;
66 MFloat* const RESTRICT flux = ALIGNED_MF(fluxes + fluxOffset);
67
68 /* // APE fluxes are not yet implemented: here is a first draft of how they can be implemented
69 in 2D
70
71 //calc flux function, uses description of APE flux from Bauer 2011: Airframe noise prediction
72 using a DG method
73 //calc average density
74 const MFloat rho0 = 1.0; //not yet implemented
75 //calc speed of sound
76 const MFloat c0 = 1.0 ; //not yet implemented
77 //calc left fluxes
78 const MFloat flux_u_l = orientations[srfcId]==0? uBar * UL + vBar * VL + rho0 * PL : 0.0
79 ; const MFloat flux_v_l = orientations[srfcId]==1? uBar * UL + vBar * VL + rho0 * PL : 0.0 ;
80 const MFloat flux_p_l = (rho0 * c0 * c0 * + PL) * (orientations[srfcId]==0? UL:VL) ;
81 //calc right fluxes
82 const MFloat flux_u_r = orientations[srfcId]==0? uBar * UR + vBar * VR + rho0 * PR : 0.0
83 ; const MFloat flux_v_r = orientations[srfcId]==1? uBar * UR + vBar * VR + rho0 * PR : 0.0 ;
84 const MFloat flux_p_r = (rho0 * c0 * c0 * + PR) * (orientations[srfcId]==0? UR:VR) ;
85
86 //calc numerical flux using a Lax-Friedrichs-scheme as in Schlottke-Lakemper et al 2017
87 const MFloat lambdaMax = max(abs(orientations[srfcId]==0? UL:VL),
88 abs(orientations[srfcId]==0? UR:VR)); flux[FV->RHO_U] = 0.5 * (flux_u_l + flux_u_r + lambdaMax *
89 (UL-UR) ); flux[FV->RHO_V] = 0.5 * (flux_v_l + flux_v_r + lambdaMax * (VL-VR) );
90
91 //flux of perturbed pressure (for APE purposes we use the energy density for the perturbed
92 pressure) flux[FV->RHO_E] = 0.5 * (flux_p_l + flux_p_r + lambdaMax * (PL-PR) );
93 */
94
95 // Temporary LAE: ic 1184 is used as a testcase for flux calculation with fluxes
96 // for the 2D linear advection equation in the rhoU variable while the APE fluxes are still in
97 // development. The other state variables(RHO_V, RHO_E, etc) are unused, since the LAE are only
98 // for a one-dimensional time dependent state. Feel free to remove this as soon as APE fluxes
99 // are implemented and well tested.
100 if(m_initialCondition == 1184) {
101 flux[FV->RHO_U] =
102 orientations[srfcId] == 0 ? (uBar > 0.0 ? UL : UR) * A * uBar : (vBar > 0.0 ? UL : UR) * A * vBar;
103 flux[FV->RHO_V] = 0.0;
104 flux[FV->RHO_E] = 0.0;
105 // This silences " ... is unused"-type warnings,
106 // because these variables will be used for APE, but are not used for LAE.
107 static_cast<void>(PL);
108 static_cast<void>(PR);
109 static_cast<void>(VL);
110 static_cast<void>(VR);
111 }
112 flux[FV->RHO] = 0.0;
113 }
114}
115
116
117// This function got hijacked to calculate an unnormed L_2 error for the domain for
118// convergence/correctness analysis, it does not actually calculate a "residual".
119// Rename/Restructure this if appropriate.
121 const MInt noVars = 2 + nDim;
122
123 MFloat domainErrorSquared = 0.0;
124#ifdef _OPENMP
125#pragma omp parallel for reduction(+ : domainErrorSquared)
126#endif
127 for(MInt cellId = 0; cellId < noInternalCells(); cellId++) { // TODO labels:FV iterate only over inner cells
128 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
129 if(a_isPeriodic(cellId)) continue;
130 if(a_hasProperty(cellId, SolverCell::IsPeriodicWithRot)) continue;
131 if(a_hasProperty(cellId, SolverCell::IsCutOff)) continue;
132 if(a_hasProperty(cellId, SolverCell::IsInvalid)) continue;
133 MInt gridcellId = cellId;
134 if(a_hasProperty(cellId, SolverCell::IsSplitClone)) {
135 gridcellId = m_splitChildToSplitCell.find(cellId)->second;
136 }
137 if(c_noChildren(gridcellId) > 0) continue;
138 if(a_bndryId(cellId) > -1 && m_fvBndryCnd->m_bndryCells->a[a_bndryId(cellId)].m_linkedCellId > -1) continue;
139
140 MFloat cellErrorSquared = 0.0;
141 for(MInt var = 0; var < noVars; var++) {
142 if(var != 0) {
143 continue; // for LAE, only RHO_U is used
144 }
145 // This analytical solution matches the initial condition prescribed at the start of the
146 // simulation.
147 if(m_initialCondition == 1184) {
148 MFloat pulse_radius = 0;
149 for(MInt spaceId = 0; spaceId < nDim; spaceId++) {
150 pulse_radius += std::pow(a_coordinate(cellId, spaceId) - 0.5 - m_advectionVelocity[spaceId] * m_time, 2.0);
151 }
152 MFloat analyticalSolutionCell = m_rhoVVInfinity[var] * (1.0 + std::exp(-pulse_radius * 20.0));
153 cellErrorSquared += POW2(analyticalSolutionCell - a_variable(cellId, var));
154 }
155 }
156 domainErrorSquared += cellErrorSquared;
157 }
158 m_log << "time: " << m_time << " domainerror: " << std::sqrt(domainErrorSquared) << std::endl;
159
160 return true;
161}
FvApeSolver2D(MInt, MInt, MBool *, maia::grid::Proxy< 2 > &gridProxy_, Geometry< 2 > &geometry_, const MPI_Comm comm)
MBool maxResidual(MInt)
Computes the global root-mean-square residual. The residual is defined as time derivative of conserva...
void Ausm()
Dispatches the AUSM flux computation for different number of species.
MFloat m_advectionVelocity[nDim]
static constexpr const MInt nDim
Collector< FvBndryCell< nDim, SysEqn > > * m_bndryCells
MInt a_noSurfaces()
Returns the number of surfaces.
MBool a_isPeriodic(const MInt cellId) const
Returns IsPeriodic of the cell cellId.
FvBndryCndXD< nDim_, FvSysEqnNS< 2 > > * m_fvBndryCnd
MFloat & a_surfaceVariable(const MInt srfcId, const MInt dir, const MInt varId)
Returns the variable varId of surface srfcId in direction dir.
MInt & a_surfaceOrientation(const MInt srfcId)
Returns the orientation of surface srfcId.
MFloat & a_surfaceArea(const MInt srfcId)
Returns the area of surface srfcId.
MFloat & a_variable(const MInt cellId, const MInt varId)
Returns conservative variable v of the cell cellId for variables varId.
MFloat & a_surfaceFlux(const MInt srfcId, const MInt fVarId)
Returns the flux fVarId for surface srfcId.
MBool a_hasProperty(const MInt cellId, const Cell p) const
Returns grid cell property p of the cell cellId.
MInt c_noChildren(const MInt cellId) const
Returns the number of children of the cell cellId.
MFloat & a_coordinate(const MInt cellId, const MInt dir)
Returns the coordinate of the cell from the fvcellcollector cellId for dimension dir.
MInt & a_bndryId(const MInt cellId)
Returns the bndryId of the cell cellId.
const MInt m_solverId
a unique solver identifier
Definition: solver.h:90
constexpr Real POW2(const Real x)
Definition: functions.h:119
InfoOutFile m_log
int32_t MInt
Definition: maiatypes.h:62
uint32_t MUint
Definition: maiatypes.h:63
double MFloat
Definition: maiatypes.h:52
bool MBool
Definition: maiatypes.h:58