@@ -102,6 +102,160 @@ void CIncNSSolver::Preprocessing(CGeometry *geometry, CSolver **solver_container
102102 Compute_Streamwise_Periodic_Recovered_Values (config, geometry, iMesh);
103103}
104104
105+ void CIncNSSolver::GetStreamwise_Periodic_Properties (const CGeometry *geometry,
106+ CConfig *config,
107+ const unsigned short iMesh) {
108+
109+ /* ---------------------------------------------------------------------------------------------*/
110+ // 1. Evaluate massflow, area avg density & Temperature and Area at streamwise periodic outlet.
111+ // 2. Update delta_p is target massflow is chosen.
112+ // 3. Loop Heatflux markers and integrate heat across the boundary. Only if energy equation is on.
113+ /* ---------------------------------------------------------------------------------------------*/
114+
115+ /* -------------------------------------------------------------------------------------------------*/
116+ /* --- 1. Evaluate Massflow [kg/s], area-averaged density [kg/m^3] and Area [m^2] at the ---*/
117+ /* --- (there can be only one) streamwise periodic outlet/donor marker. Massflow is obviously ---*/
118+ /* --- needed for prescribed massflow but also for the additional source and heatflux ---*/
119+ /* --- boundary terms of the energy equation. Area and the avg-density are used for the ---*/
120+ /* --- Pressure-Drop update in case of a prescribed massflow. ---*/
121+ /* -------------------------------------------------------------------------------------------------*/
122+
123+ const auto nZone = geometry->GetnZone ();
124+ const auto InnerIter = config->GetInnerIter ();
125+ const auto OuterIter = config->GetOuterIter ();
126+
127+ su2double Area_Local = 0.0 ,
128+ MassFlow_Local = 0.0 ,
129+ Average_Density_Local = 0.0 ,
130+ Temperature_Local = 0.0 ;
131+
132+ for (auto iMarker = 0 ; iMarker < config->GetnMarker_All (); iMarker++) {
133+
134+ /* --- Only "outlet"/donor periodic marker ---*/
135+ if (config->GetMarker_All_KindBC (iMarker) == PERIODIC_BOUNDARY &&
136+ config->GetMarker_All_PerBound (iMarker) == 2 ) {
137+
138+ for (auto iVertex = 0ul ; iVertex < geometry->nVertex [iMarker]; iVertex++) {
139+
140+ auto iPoint = geometry->vertex [iMarker][iVertex]->GetNode ();
141+
142+ if (geometry->nodes ->GetDomain (iPoint)) {
143+
144+ /* --- A = dot_prod(n_A*n_A), with n_A beeing the area-normal. ---*/
145+
146+ const auto AreaNormal = geometry->vertex [iMarker][iVertex]->GetNormal ();
147+
148+ auto FaceArea = GeometryToolbox::Norm (nDim, AreaNormal);
149+
150+ /* --- m_dot = dot_prod(n*v) * A * rho, with n beeing unit normal. ---*/
151+ MassFlow_Local += nodes->GetProjVel (iPoint, AreaNormal) * nodes->GetDensity (iPoint);
152+
153+ Area_Local += FaceArea;
154+
155+ Average_Density_Local += FaceArea * nodes->GetDensity (iPoint);
156+
157+ /* --- Due to periodicty, temperatures are equal one the inlet(1) and outlet(2) ---*/
158+ Temperature_Local += FaceArea * nodes->GetTemperature (iPoint);
159+
160+ } // if domain
161+ } // loop vertices
162+ } // loop periodic boundaries
163+ } // loop MarkerAll
164+
165+ // MPI Communication: Sum Area, Sum rho*A & T*A and divide by AreaGlobbal, sum massflow
166+ su2double Area_Global (0 ), Average_Density_Global (0 ), MassFlow_Global (0 ), Temperature_Global (0 );
167+ SU2_MPI::Allreduce (&Area_Local, &Area_Global, 1 , MPI_DOUBLE, MPI_SUM, SU2_MPI::GetComm ());
168+ SU2_MPI::Allreduce (&Average_Density_Local, &Average_Density_Global, 1 , MPI_DOUBLE, MPI_SUM, SU2_MPI::GetComm ());
169+ SU2_MPI::Allreduce (&MassFlow_Local, &MassFlow_Global, 1 , MPI_DOUBLE, MPI_SUM, SU2_MPI::GetComm ());
170+ SU2_MPI::Allreduce (&Temperature_Local, &Temperature_Global, 1 , MPI_DOUBLE, MPI_SUM, SU2_MPI::GetComm ());
171+
172+ Average_Density_Global /= Area_Global;
173+ Temperature_Global /= Area_Global;
174+
175+ /* --- Set solver variables ---*/
176+ SPvals.Streamwise_Periodic_MassFlow = MassFlow_Global;
177+ SPvals.Streamwise_Periodic_InletTemperature = Temperature_Global;
178+
179+ /* --- As deltaP changes with prescribed massflow the const config value should only be used once. ---*/
180+ if ((nZone==1 && InnerIter==0 ) ||
181+ (nZone>1 && OuterIter==0 && InnerIter==0 )) {
182+ SPvals.Streamwise_Periodic_PressureDrop = config->GetStreamwise_Periodic_PressureDrop () / config->GetPressure_Ref ();
183+ }
184+
185+ if (config->GetKind_Streamwise_Periodic () == STREAMWISE_MASSFLOW) {
186+ /* ------------------------------------------------------------------------------------------------*/
187+ /* --- 2. Update the Pressure Drop [Pa] for the Momentum source term if Massflow is prescribed. ---*/
188+ /* --- The Pressure drop is iteratively adapted to result in the prescribed Target-Massflow. ---*/
189+ /* ------------------------------------------------------------------------------------------------*/
190+
191+ /* --- Load/define all necessary variables ---*/
192+ const su2double TargetMassFlow = config->GetStreamwise_Periodic_TargetMassFlow () / (config->GetDensity_Ref () * config->GetVelocity_Ref ());
193+ const su2double damping_factor = config->GetInc_Outlet_Damping ();
194+ su2double Pressure_Drop_new, ddP;
195+
196+ /* --- Compute update to Delta p based on massflow-difference ---*/
197+ ddP = 0.5 / ( Average_Density_Global * pow (Area_Global, 2 )) * (pow (TargetMassFlow, 2 ) - pow (MassFlow_Global, 2 ));
198+
199+ /* --- Store updated pressure difference ---*/
200+ Pressure_Drop_new = SPvals.Streamwise_Periodic_PressureDrop + damping_factor*ddP;
201+ /* --- During restarts, this routine GetStreamwise_Periodic_Properties can get called multiple times
202+ (e.g. 4x for INC_RANS restart). Each time, the pressure drop gets updated. For INC_RANS restarts
203+ it gets called 2x before the restart files are read such that the current massflow is
204+ Area*inital-velocity which can be way off!
205+ With this there is still a slight inconsitency wrt to a non-restarted simulation: The restarted "zero-th"
206+ iteration does not get a pressure-update but the continuing simulation would have an update here. This can be
207+ fully neglected if the pressure drop is converged. And for all other cases it should be minor difference at
208+ best ---*/
209+ if ((nZone==1 && InnerIter>0 ) ||
210+ (nZone>1 && OuterIter>0 )) {
211+ SPvals.Streamwise_Periodic_PressureDrop = Pressure_Drop_new;
212+ }
213+
214+ } // if massflow
215+
216+
217+ if (config->GetEnergy_Equation ()) {
218+ /* ---------------------------------------------------------------------------------------------*/
219+ /* --- 3. Compute the integrated Heatflow [W] for the energy equation source term, heatflux ---*/
220+ /* --- boundary term and recovered Temperature. The computation is not completely clear. ---*/
221+ /* --- Here the Heatflux from all Bounary markers in the config-file is used. ---*/
222+ /* ---------------------------------------------------------------------------------------------*/
223+
224+ su2double HeatFlow_Local = 0.0 , HeatFlow_Global = 0.0 ;
225+
226+ /* --- Loop over all heatflux Markers ---*/
227+ for (auto iMarker = 0 ; iMarker < config->GetnMarker_All (); iMarker++) {
228+
229+ if (config->GetMarker_All_KindBC (iMarker) == HEAT_FLUX) {
230+
231+ /* --- Identify the boundary by string name and retrive heatflux from config ---*/
232+ const auto Marker_StringTag = config->GetMarker_All_TagBound (iMarker);
233+ const auto Wall_HeatFlux = config->GetWall_HeatFlux (Marker_StringTag);
234+
235+ for (auto iVertex = 0ul ; iVertex < geometry->nVertex [iMarker]; iVertex++) {
236+
237+ auto iPoint = geometry->vertex [iMarker][iVertex]->GetNode ();
238+
239+ if (!geometry->nodes ->GetDomain (iPoint)) continue ;
240+
241+ const auto AreaNormal = geometry->vertex [iMarker][iVertex]->GetNormal ();
242+
243+ auto FaceArea = GeometryToolbox::Norm (nDim, AreaNormal);
244+
245+ HeatFlow_Local += FaceArea * (-1.0 ) * Wall_HeatFlux/config->GetHeat_Flux_Ref ();;
246+ } // loop Vertices
247+ } // loop Heatflux marker
248+ } // loop AllMarker
249+
250+ /* --- MPI Communication sum up integrated Heatflux from all processes ---*/
251+ SU2_MPI::Allreduce (&HeatFlow_Local, &HeatFlow_Global, 1 , MPI_DOUBLE, MPI_SUM, SU2_MPI::GetComm ());
252+
253+ /* --- Set the solver variable Integrated Heatflux ---*/
254+ SPvals.Streamwise_Periodic_IntegratedHeatFlow = HeatFlow_Global;
255+ } // if energy
256+ }
257+
258+
105259void CIncNSSolver::Compute_Streamwise_Periodic_Recovered_Values (CConfig *config, const CGeometry *geometry,
106260 const unsigned short iMesh) {
107261
0 commit comments