From 22ea138a43114cd654a4dc5236ef8921b4887a70 Mon Sep 17 00:00:00 2001 From: fmpmorgado Date: Wed, 13 Jan 2021 22:22:04 +0000 Subject: [PATCH 01/23] Changes on SYM_BC. Working with 2D cases --- .../include/solvers/CFVMFlowSolverBase.hpp | 2 +- SU2_CFD/include/solvers/CNEMOEulerSolver.hpp | 12 + .../include/variables/CNEMOEulerVariable.hpp | 6 + SU2_CFD/src/integration/CIntegration.cpp | 11 +- SU2_CFD/src/output/CNEMOCompOutput.cpp | 2 +- SU2_CFD/src/solvers/CNEMOEulerSolver.cpp | 283 ++++++++++-------- SU2_CFD/src/variables/CNEMOEulerVariable.cpp | 3 + 7 files changed, 191 insertions(+), 128 deletions(-) diff --git a/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp b/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp index 7ea8b5e651d..227ed3a8c38 100644 --- a/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp +++ b/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp @@ -319,7 +319,7 @@ class CFVMFlowSolverBase : public CSolver { * \param[in] val_marker - Surface marker where the boundary condition is applied. */ inline void BC_Euler_Wall(CGeometry* geometry, CSolver** solver_container, CNumerics* conv_numerics, - CNumerics* visc_numerics, CConfig* config, unsigned short val_marker) final { + CNumerics* visc_numerics, CConfig* config, unsigned short val_marker) override { /*--- Call the equivalent symmetry plane boundary condition. ---*/ BC_Sym_Plane(geometry, solver_container, conv_numerics, visc_numerics, config, val_marker); } diff --git a/SU2_CFD/include/solvers/CNEMOEulerSolver.hpp b/SU2_CFD/include/solvers/CNEMOEulerSolver.hpp index 5a2c20efb92..8c374cf6836 100644 --- a/SU2_CFD/include/solvers/CNEMOEulerSolver.hpp +++ b/SU2_CFD/include/solvers/CNEMOEulerSolver.hpp @@ -246,6 +246,18 @@ class CNEMOEulerSolver : public CFVMFlowSolverBaseBC_Far_Field(geometry, solver_container, conv_bound_numerics, visc_bound_numerics, config, iMarker); break; - case SYMMETRY_PLANE: - solver_container[MainSolver]->BC_Sym_Plane(geometry, solver_container, conv_bound_numerics, visc_bound_numerics, config, iMarker); - break; case ELECTRODE_BOUNDARY: solver_container[MainSolver]->BC_Electrode(geometry, solver_container, conv_bound_numerics, config, iMarker); break; @@ -184,6 +181,14 @@ void CIntegration::Space_Integration(CGeometry *geometry, solver_container[MainSolver]->BC_Periodic(geometry, solver_container, conv_bound_numerics, config); } + /*--- Placing Symmetry Plane BC last, so we only require to double + the residuals to use a ghost nodes approach. --- */ + + for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { + KindBC = config->GetMarker_All_KindBC(iMarker); + if (KindBC == SYMMETRY_PLANE) solver_container[MainSolver]->BC_Sym_Plane(geometry, solver_container, conv_bound_numerics, visc_bound_numerics, config, iMarker); + } + } void CIntegration::Time_Integration(CGeometry *geometry, CSolver **solver_container, CConfig *config, diff --git a/SU2_CFD/src/output/CNEMOCompOutput.cpp b/SU2_CFD/src/output/CNEMOCompOutput.cpp index 836e7820025..1705d4771af 100644 --- a/SU2_CFD/src/output/CNEMOCompOutput.cpp +++ b/SU2_CFD/src/output/CNEMOCompOutput.cpp @@ -561,7 +561,7 @@ void CNEMOCompOutput::LoadVolumeData(CConfig *config, CGeometry *geometry, CSolv void CNEMOCompOutput::LoadSurfaceData(CConfig *config, CGeometry *geometry, CSolver **solver, unsigned long iPoint, unsigned short iMarker, unsigned long iVertex){ - if ((config->GetKind_Solver() == NEMO_NAVIER_STOKES)) { + if ((config->GetKind_Solver() == NEMO_NAVIER_STOKES && config->GetMarker_All_KindBC(iMarker) != EULER && config->GetMarker_All_KindBC(iMarker) != SYMMETRY_PLANE)) { SetVolumeOutputValue("SKIN_FRICTION-X", iPoint, solver[FLOW_SOL]->GetCSkinFriction(iMarker, iVertex, 0)); SetVolumeOutputValue("SKIN_FRICTION-Y", iPoint, solver[FLOW_SOL]->GetCSkinFriction(iMarker, iVertex, 1)); if (nDim == 3) diff --git a/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp b/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp index cdaf44c453d..961b6b42ed0 100644 --- a/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp +++ b/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp @@ -256,6 +256,16 @@ CNEMOEulerSolver::CNEMOEulerSolver(CGeometry *geometry, CConfig *config, } } + /*--- Initialize boolean vector with nodes in symmetry plane ---*/ + for (unsigned long iMarker = 0; iMarker < geometry->GetnMarker(); iMarker++) { + if (config->GetMarker_All_KindBC(iMarker) == SYMMETRY_PLANE){ + for (unsigned long iVertex = 0; iVertex < geometry->GetnVertex(iMarker); iVertex++) { + unsigned long iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + nodes->SetSymmetry(iPoint); + } + } + } + /*--- Warning message about non-physical points ---*/ if (config->GetComm_Level() == COMM_FULL) { @@ -498,6 +508,8 @@ void CNEMOEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_contai Lambda = fabs(Mean_ProjVel) + Mean_SoundSpeed; nodes->AddMax_Lambda_Inv(iPoint,Lambda); + if (nodes->GetSymmetry(iPoint)) nodes->AddMax_Lambda_Inv(iPoint,Lambda); + /*--- Viscous contribution ---*/ if (!viscous) continue; @@ -521,6 +533,10 @@ void CNEMOEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_contai Lambda = (Lambda_1 + Lambda_2)*Area*Area/Mean_Density; nodes->AddMax_Lambda_Visc(iPoint, Lambda); + + if (nodes->GetSymmetry(iPoint)) + if(nodes->GetSymmetry(jPoint)) nodes->AddMax_Lambda_Visc(iPoint,3*Lambda); + else nodes->AddMax_Lambda_Visc(iPoint, Lambda); } } @@ -539,10 +555,17 @@ void CNEMOEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_contai if (!geometry->nodes->GetDomain(iPoint)) continue; Normal = geometry->vertex[iMarker][iVertex]->GetNormal(); - Area = GeometryToolbox::Norm(nDim, Normal); + + su2double Norm[3]; + Norm[0]=Normal[0]; + Norm[1]=Normal[1]; + + if(nodes->GetSymmetry(iPoint)==true) {Norm[0]=Normal[0]*2; Norm[1]=0;} + + Area = GeometryToolbox::Norm(nDim, Norm); /*--- Mean Values ---*/ - Mean_ProjVel = nodes->GetProjVel(iPoint,Normal); + Mean_ProjVel = nodes->GetProjVel(iPoint,Norm); Mean_SoundSpeed = nodes->GetSoundSpeed(iPoint) * Area; /*--- Adjustment for grid movement ---*/ @@ -587,6 +610,7 @@ void CNEMOEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_contai for (iPoint = 0; iPoint < nPointDomain; iPoint++) { Vol = geometry->nodes->GetVolume(iPoint); + if(nodes->GetSymmetry(iPoint)==true) Vol=2*Vol; if (Vol != 0.0) { Local_Delta_Time = nodes->GetLocalCFL(iPoint)*Vol / nodes->GetMax_Lambda_Inv(iPoint); @@ -1257,6 +1281,7 @@ void CNEMOEulerSolver::ExplicitEuler_Iteration(CGeometry *geometry, CSolver **so Vol = (geometry->nodes->GetVolume(iPoint) + geometry->nodes->GetPeriodicVolume(iPoint)); + if (nodes->GetSymmetry(iPoint)==true) Vol*=2; Delta = nodes->GetDelta_Time(iPoint) / Vol; @@ -1812,126 +1837,21 @@ void CNEMOEulerSolver::SetNondimensionalization(CConfig *config, unsigned short void CNEMOEulerSolver::BC_Sym_Plane(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { - - unsigned short iDim, jDim, iSpecies, iVar, jVar; unsigned long iPoint, iVertex; + su2double Normal[3]; + + geometry->vertex[val_marker][0]->GetNormal(Normal); - su2double *Normal = nullptr, Area, UnitNormal[3], *NormalArea, - **Jacobian_b, **DubDu, - rho, cs, P, rhoE, rhoEve, conc, *u, *dPdU; - - bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); - - /*--- Allocate arrays ---*/ - Normal = new su2double[nDim]; - NormalArea = new su2double[nDim]; - Jacobian_b = new su2double*[nVar]; - DubDu = new su2double*[nVar]; - u = new su2double[nDim]; - - for (iVar = 0; iVar < nVar; iVar++) { - Jacobian_b[iVar] = new su2double[nVar]; - DubDu[iVar] = new su2double[nVar]; - } - - /*--- Get species molar mass ---*/ - auto& Ms = FluidModel->GetSpeciesMolarMass(); - - /*--- Loop over all the vertices on this boundary (val_marker) ---*/ - for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { + cout<nVertex[val_marker]; iVertex++) { iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); - /*--- Check if the node belongs to the domain (i.e, not a halo node) ---*/ - if (geometry->nodes->GetDomain(iPoint)) { - - /*--- Normal vector for this vertex (negative for outward convention) ---*/ - geometry->vertex[val_marker][iVertex]->GetNormal(Normal); - - /*--- Calculate parameters from the geometry ---*/ - Area = GeometryToolbox::Norm(nDim, Normal); + auto residual = LinSysRes.GetBlock(iPoint); + residual[6]=0; + LinSysRes.AddBlock(iPoint, residual); - for (iDim = 0; iDim < nDim; iDim++){ - NormalArea[iDim] = -Normal[iDim]; - UnitNormal[iDim] = -Normal[iDim]/Area; - } - - /*--- Retrieve the pressure on the vertex ---*/ - P = nodes->GetPressure(iPoint); - - /*--- Apply the flow-tangency b.c. to the convective flux ---*/ - for (iSpecies = 0; iSpecies < nSpecies; iSpecies++) - Residual[iSpecies] = 0.0; - for (iDim = 0; iDim < nDim; iDim++){ - Residual[nSpecies+iDim] = P * UnitNormal[iDim] * Area; - } - Residual[nSpecies+nDim] = 0.0; - Residual[nSpecies+nDim+1] = 0.0; - - /*--- Add value to the residual ---*/ - LinSysRes.AddBlock(iPoint, Residual); - - /*--- If using implicit time-stepping, calculate b.c. contribution to Jacobian ---*/ - if (implicit) { - - /*--- Initialize Jacobian ---*/ - for (iVar = 0; iVar < nVar; iVar++) - for (jVar = 0; jVar < nVar; jVar++) - Jacobian_i[iVar][jVar] = 0.0; - - /*--- Calculate state i ---*/ - rho = nodes->GetDensity(iPoint); - rhoE = nodes->GetSolution(iPoint,nSpecies+nDim); - rhoEve = nodes->GetSolution(iPoint,nSpecies+nDim+1); - dPdU = nodes->GetdPdU(iPoint); - for (iDim = 0; iDim < nDim; iDim++) - u[iDim] = nodes->GetVelocity(iPoint,iDim); - - conc = 0.0; - for (iSpecies = 0; iSpecies < nSpecies; iSpecies++) { - cs = nodes->GetMassFraction(iPoint,iSpecies); - conc += cs * rho/Ms[iSpecies]; - - /////// NEW ////// - for (iDim = 0; iDim < nDim; iDim++) { - Jacobian_i[nSpecies+iDim][iSpecies] = dPdU[iSpecies] * UnitNormal[iDim]; - Jacobian_i[iSpecies][nSpecies+iDim] = cs * UnitNormal[iDim]; - } - } - - for (iDim = 0; iDim < nDim; iDim++) { - for (jDim = 0; jDim < nDim; jDim++) { - Jacobian_i[nSpecies+iDim][nSpecies+jDim] = u[iDim]*UnitNormal[jDim] - + dPdU[nSpecies+jDim]*UnitNormal[iDim]; - } - Jacobian_i[nSpecies+iDim][nSpecies+nDim] = dPdU[nSpecies+nDim] *UnitNormal[iDim]; - Jacobian_i[nSpecies+iDim][nSpecies+nDim+1] = dPdU[nSpecies+nDim+1]*UnitNormal[iDim]; - - Jacobian_i[nSpecies+nDim][nSpecies+iDim] = (rhoE+P)/rho * UnitNormal[iDim]; - Jacobian_i[nSpecies+nDim+1][nSpecies+iDim] = rhoEve/rho * UnitNormal[iDim]; - } - - /*--- Integrate over the dual-grid area ---*/ - for (iVar = 0; iVar < nVar; iVar++) - for (jVar = 0; jVar < nVar; jVar++) - Jacobian_i[iVar][jVar] = Jacobian_i[iVar][jVar] * Area; - - /*--- Apply the contribution to the system ---*/ - Jacobian.AddBlock(iPoint,iPoint,Jacobian_i); - - } - } } - delete [] Normal; - delete [] NormalArea; - delete [] u; - - for (iVar = 0; iVar < nVar; iVar++) { - delete [] Jacobian_b[iVar]; - delete [] DubDu[iVar]; - } - - delete [] Jacobian_b; - delete [] DubDu; } void CNEMOEulerSolver::BC_Far_Field(CGeometry *geometry, CSolver **solver_container, @@ -2860,13 +2780,130 @@ void CNEMOEulerSolver::BC_Supersonic_Outlet(CGeometry *geometry, CSolver **solut } -//void CNEMOEulerSolver::BC_Sym_Plane(CGeometry *geometry, CSolver **solver_container, -// CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { -// -// /*--- Call the Euler wall routine ---*/ -// BC_Euler_Wall(geometry, solver_container, conv_numerics, visc_numerics, config, val_marker); -// -//} +void CNEMOEulerSolver::BC_Euler_Wall(CGeometry *geometry, CSolver **solver_container, + CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { + + unsigned short iDim, jDim, iSpecies, iVar, jVar; + unsigned long iPoint, iVertex; + + su2double *Normal = nullptr, Area, UnitNormal[3], *NormalArea, + **Jacobian_b, **DubDu, + rho, cs, P, rhoE, rhoEve, conc, *u, *dPdU; + + bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); + + /*--- Allocate arrays ---*/ + Normal = new su2double[nDim]; + NormalArea = new su2double[nDim]; + Jacobian_b = new su2double*[nVar]; + DubDu = new su2double*[nVar]; + u = new su2double[nDim]; + + for (iVar = 0; iVar < nVar; iVar++) { + Jacobian_b[iVar] = new su2double[nVar]; + DubDu[iVar] = new su2double[nVar]; + } + + /*--- Get species molar mass ---*/ + auto& Ms = FluidModel->GetSpeciesMolarMass(); + + /*--- Loop over all the vertices on this boundary (val_marker) ---*/ + for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { + iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); + + /*--- Check if the node belongs to the domain (i.e, not a halo node) ---*/ + if (geometry->nodes->GetDomain(iPoint)) { + + /*--- Normal vector for this vertex (negative for outward convention) ---*/ + geometry->vertex[val_marker][iVertex]->GetNormal(Normal); + + /*--- Calculate parameters from the geometry ---*/ + Area = GeometryToolbox::Norm(nDim, Normal); + + for (iDim = 0; iDim < nDim; iDim++){ + NormalArea[iDim] = -Normal[iDim]; + UnitNormal[iDim] = -Normal[iDim]/Area; + } + + /*--- Retrieve the pressure on the vertex ---*/ + P = nodes->GetPressure(iPoint); + + /*--- Apply the flow-tangency b.c. to the convective flux ---*/ + for (iSpecies = 0; iSpecies < nSpecies; iSpecies++) + Residual[iSpecies] = 0.0; + for (iDim = 0; iDim < nDim; iDim++){ + Residual[nSpecies+iDim] = P * UnitNormal[iDim] * Area; + } + Residual[nSpecies+nDim] = 0.0; + Residual[nSpecies+nDim+1] = 0.0; + + /*--- Add value to the residual ---*/ + LinSysRes.AddBlock(iPoint, Residual); + + /*--- If using implicit time-stepping, calculate b.c. contribution to Jacobian ---*/ + if (implicit) { + + /*--- Initialize Jacobian ---*/ + for (iVar = 0; iVar < nVar; iVar++) + for (jVar = 0; jVar < nVar; jVar++) + Jacobian_i[iVar][jVar] = 0.0; + + /*--- Calculate state i ---*/ + rho = nodes->GetDensity(iPoint); + rhoE = nodes->GetSolution(iPoint,nSpecies+nDim); + rhoEve = nodes->GetSolution(iPoint,nSpecies+nDim+1); + dPdU = nodes->GetdPdU(iPoint); + for (iDim = 0; iDim < nDim; iDim++) + u[iDim] = nodes->GetVelocity(iPoint,iDim); + + conc = 0.0; + for (iSpecies = 0; iSpecies < nSpecies; iSpecies++) { + cs = nodes->GetMassFraction(iPoint,iSpecies); + conc += cs * rho/Ms[iSpecies]; + + /////// NEW ////// + for (iDim = 0; iDim < nDim; iDim++) { + Jacobian_i[nSpecies+iDim][iSpecies] = dPdU[iSpecies] * UnitNormal[iDim]; + Jacobian_i[iSpecies][nSpecies+iDim] = cs * UnitNormal[iDim]; + } + } + + for (iDim = 0; iDim < nDim; iDim++) { + for (jDim = 0; jDim < nDim; jDim++) { + Jacobian_i[nSpecies+iDim][nSpecies+jDim] = u[iDim]*UnitNormal[jDim] + + dPdU[nSpecies+jDim]*UnitNormal[iDim]; + } + Jacobian_i[nSpecies+iDim][nSpecies+nDim] = dPdU[nSpecies+nDim] *UnitNormal[iDim]; + Jacobian_i[nSpecies+iDim][nSpecies+nDim+1] = dPdU[nSpecies+nDim+1]*UnitNormal[iDim]; + + Jacobian_i[nSpecies+nDim][nSpecies+iDim] = (rhoE+P)/rho * UnitNormal[iDim]; + Jacobian_i[nSpecies+nDim+1][nSpecies+iDim] = rhoEve/rho * UnitNormal[iDim]; + } + + /*--- Integrate over the dual-grid area ---*/ + for (iVar = 0; iVar < nVar; iVar++) + for (jVar = 0; jVar < nVar; jVar++) + Jacobian_i[iVar][jVar] = Jacobian_i[iVar][jVar] * Area; + + /*--- Apply the contribution to the system ---*/ + Jacobian.AddBlock(iPoint,iPoint,Jacobian_i); + + } + } + } + delete [] Normal; + delete [] NormalArea; + delete [] u; + + for (iVar = 0; iVar < nVar; iVar++) { + delete [] Jacobian_b[iVar]; + delete [] DubDu[iVar]; + } + + delete [] Jacobian_b; + delete [] DubDu; + +} void CNEMOEulerSolver::SetResidual_DualTime(CGeometry *geometry, CSolver **solution_container, diff --git a/SU2_CFD/src/variables/CNEMOEulerVariable.cpp b/SU2_CFD/src/variables/CNEMOEulerVariable.cpp index 8a13254516a..c58d71d7520 100644 --- a/SU2_CFD/src/variables/CNEMOEulerVariable.cpp +++ b/SU2_CFD/src/variables/CNEMOEulerVariable.cpp @@ -139,6 +139,9 @@ CNEMOEulerVariable::CNEMOEulerVariable(su2double val_pressure, bool interp = config->GetSolutionInterpolation(); + /* Boolean to check if nodes are in Symmetry Plane BC */ + symmetry.resize(nPoint) = false; + /*--- Do not initialize variables for solution interpolation, since it makes the interpolation super slow and is not necessary ---*/ if (!interp) { From f7ed7688ea5306a616cbe99b766e943d9a5270de Mon Sep 17 00:00:00 2001 From: fmpmorgado Date: Fri, 15 Jan 2021 00:07:39 +0000 Subject: [PATCH 02/23] 2D fully working. Missing 3D still --- SU2_CFD/src/solvers/CNEMOEulerSolver.cpp | 71 ++++++++++++++++++------ 1 file changed, 54 insertions(+), 17 deletions(-) diff --git a/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp b/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp index 961b6b42ed0..4bb39c12860 100644 --- a/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp +++ b/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp @@ -465,13 +465,27 @@ void CNEMOEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_contai } SU2_OMP_BARRIER - const su2double *Normal = nullptr; + // const su2double *Normal = nullptr; + su2double Normal[3]; su2double Area, Vol, Mean_SoundSpeed, Mean_ProjVel, Lambda, Local_Delta_Time, Local_Delta_Time_Visc; su2double Mean_LaminarVisc, Mean_EddyVisc, Mean_Density, Lambda_1, Lambda_2; su2double Mean_ThermalCond, Mean_ThermalCond_ve, cv; + su2double Normal_Sym[3], UnitNormal_Sym[3]; unsigned long iEdge, iVertex, iPoint, jPoint; unsigned short iDim, iMarker; + /*--- Save Normal if Symmetry plane exists ---*/ + for (iMarker = 0; iMarker < geometry->GetnMarker(); iMarker++) { + if (config->GetMarker_All_KindBC(iMarker) == SYMMETRY_PLANE){ + geometry->vertex[iMarker][0]->GetNormal(Normal_Sym); + + Area = GeometryToolbox::Norm(nDim, Normal_Sym); + + for(iDim = 0; iDim < nDim; iDim++) + UnitNormal_Sym[iDim] = -Normal_Sym[iDim]/Area; + } + } + /*--- Loop domain points. ---*/ SU2_OMP_FOR_DYN(omp_chunk_size) for (iPoint = 0; iPoint < nPointDomain; ++iPoint) { @@ -488,7 +502,12 @@ void CNEMOEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_contai jPoint = geometry->nodes->GetPoint(iPoint,iNeigh); iEdge = geometry->nodes->GetEdge(iPoint,iNeigh); - Normal = geometry->edges->GetNormal(iEdge); + geometry->edges->GetNormal(iEdge,Normal); + + if(nodes->GetSymmetry(iPoint) && nodes->GetSymmetry(jPoint)) + for(iDim = 0; iDim < nDim; iDim++) + Normal[iDim] += Normal[iDim]*UnitNormal_Sym[iDim]; + Area = GeometryToolbox::Norm(nDim, Normal); /*--- Mean Values ---*/ @@ -554,18 +573,16 @@ void CNEMOEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_contai if (!geometry->nodes->GetDomain(iPoint)) continue; - Normal = geometry->vertex[iMarker][iVertex]->GetNormal(); - - su2double Norm[3]; - Norm[0]=Normal[0]; - Norm[1]=Normal[1]; - - if(nodes->GetSymmetry(iPoint)==true) {Norm[0]=Normal[0]*2; Norm[1]=0;} + geometry->vertex[iMarker][iVertex]->GetNormal(Normal); - Area = GeometryToolbox::Norm(nDim, Norm); + if(nodes->GetSymmetry(iPoint)==true && config->GetMarker_All_KindBC(iMarker) == SYMMETRY_PLANE) { + for(iDim = 0; iDim < nDim; iDim++) + Normal[iDim] += Normal[iDim]*UnitNormal_Sym[iDim]; + } + Area = GeometryToolbox::Norm(nDim, Normal); /*--- Mean Values ---*/ - Mean_ProjVel = nodes->GetProjVel(iPoint,Norm); + Mean_ProjVel = nodes->GetProjVel(iPoint,Normal); Mean_SoundSpeed = nodes->GetSoundSpeed(iPoint) * Area; /*--- Adjustment for grid movement ---*/ @@ -579,6 +596,8 @@ void CNEMOEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_contai /*--- Inviscid contribution ---*/ Lambda = fabs(Mean_ProjVel) + Mean_SoundSpeed; nodes->AddMax_Lambda_Inv(iPoint,Lambda); + + if(nodes->GetSymmetry(iPoint)==true) nodes->AddMax_Lambda_Inv(iPoint,Lambda); /*--- Viscous contribution ---*/ if (!viscous) continue; @@ -592,11 +611,16 @@ void CNEMOEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_contai cv = (nodes->GetRhoCv_tr(iPoint) + nodes->GetRhoCv_ve(iPoint)) / Mean_Density; + // if(nodes->GetSymmetry(iPoint)==true && config->GetMarker_All_KindBC(iMarker) == SYMMETRY_PLANE) Area/=2; Lambda_1 = (4.0/3.0)*(Mean_LaminarVisc+Mean_EddyVisc); Lambda_2 = (Mean_ThermalCond+Mean_ThermalCond_ve)/cv; Lambda = (Lambda_1 + Lambda_2)*Area*Area/Mean_Density; nodes->AddMax_Lambda_Visc(iPoint,Lambda); + if(nodes->GetSymmetry(iPoint)==true) + if(config->GetMarker_All_KindBC(iMarker) != SYMMETRY_PLANE) nodes->AddMax_Lambda_Visc(iPoint,3*Lambda); + else nodes->AddMax_Lambda_Visc(iPoint, Lambda); + } } } @@ -1838,20 +1862,33 @@ void CNEMOEulerSolver::SetNondimensionalization(CConfig *config, unsigned short void CNEMOEulerSolver::BC_Sym_Plane(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { unsigned long iPoint, iVertex; - su2double Normal[3]; - + unsigned short iDim, iVar; + su2double Area, Normal[3], UnitNormal[3]; + const su2double* Residual_Old; + geometry->vertex[val_marker][0]->GetNormal(Normal); - cout<nVertex[val_marker]; iVertex++) { + iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); - auto residual = LinSysRes.GetBlock(iPoint); - residual[6]=0; - LinSysRes.AddBlock(iPoint, residual); + Residual_Old = LinSysRes.GetBlock(iPoint); + + for(iVar = 0; iVar < nVar; iVar++) + Res_Conv[iVar] = Residual_Old[iVar]; + for(iDim = 0; iDim < nDim; iDim++) + Res_Conv[nSpecies+iDim]+=2*Residual_Old[nSpecies+iDim]*UnitNormal[iDim]; + + LinSysRes.AddBlock(iPoint, Res_Conv); } + } void CNEMOEulerSolver::BC_Far_Field(CGeometry *geometry, CSolver **solver_container, From cab2b594d5789a4397b2b22b6abb4b6385b7818c Mon Sep 17 00:00:00 2001 From: CatarinaGarbacz Date: Fri, 15 Jan 2021 21:56:49 +0000 Subject: [PATCH 03/23] fix SU2 INTERP stuff after merge --- Common/include/CConfig.hpp | 31 +++++++++++ Common/include/adt/CADTElemClass.hpp | 23 ++++++-- Common/include/fem/fem_standard_element.hpp | 21 ++++++- Common/include/option_structure.hpp | 13 +++-- Common/src/CConfig.cpp | 62 ++++++++++++++++++--- Common/src/adt/CADTElemClass.cpp | 15 +++++ Common/src/fem/fem_standard_element.cpp | 44 +++++++++++++++ Makefile.am | 4 ++ configure.ac | 5 ++ meson.build | 2 + 10 files changed, 200 insertions(+), 20 deletions(-) diff --git a/Common/include/CConfig.hpp b/Common/include/CConfig.hpp index 0504371c8a2..c6ce0c8eecb 100644 --- a/Common/include/CConfig.hpp +++ b/Common/include/CConfig.hpp @@ -667,6 +667,7 @@ class CConfig { unsigned long StartConv_Iter; /*!< \brief Start convergence criteria at iteration. */ su2double Cauchy_Eps; /*!< \brief Epsilon used for the convergence. */ bool Restart, /*!< \brief Restart solution (for direct, adjoint, and linearized problems).*/ + Wrt_Binary_Restart, /*!< \brief Write binary SU2 native restart files.*/ Read_Binary_Restart, /*!< \brief Read binary SU2 native restart files.*/ Restart_Flow; /*!< \brief Restart flow solution for adjoint and linearized problems. */ unsigned short nMarker_Monitoring, /*!< \brief Number of markers to monitor. */ @@ -1158,6 +1159,9 @@ class CConfig { string GasModel, /*!< \brief Gas Model. */ *Wall_Catalytic; /*!< \brief Pointer to catalytic walls. */ + bool interpolate_solution; /*!< \brief Flag for solution interpolation */ + string Interpolated_Restart_FileName; /*!< \brief Name of interpolated restart file. */ + /*! * \brief Set the default values of config options not set in the config file using another config object. * \param config - Config object to use the default values from. @@ -1314,6 +1318,11 @@ class CConfig { */ CConfig(char case_filename[MAX_STRING_SIZE], CConfig *config); + /*! + * \brief Constructor of the class which reads the input file. + */ + CConfig(char case_filename[MAX_STRING_SIZE], unsigned short val_software, unsigned short val_iZone, unsigned short val_nZone, unsigned short val_nDim, bool verb_high); + /*! * \brief Destructor of the class. */ @@ -5117,12 +5126,34 @@ class CConfig { */ void SetRestart(bool val_restart) { Restart = val_restart; } + /*! + * \brief Sets the mesh filename for interpolation. + */ + void SetMesh_FileName(string val_filename) { Mesh_FileName = val_filename; } + + /*! + * \brief Get the interpolation target mesh name. + * \return Mesh filename to be interpolated. + */ + string GetTarget_Mesh_FileName(void) { return Target_Mesh_FileName; } + + /*! + * \brief Flag for whether binary SU2 native restart files are written. + * \return Flag for whether binary SU2 native restart files are written, if TRUE then the code will output binary restart files. + */ + bool GetWrt_Binary_Restart(void) const { return Wrt_Binary_Restart; } + /*! * \brief Flag for whether binary SU2 native restart files are read. * \return Flag for whether binary SU2 native restart files are read, if TRUE then the code will load binary restart files. */ bool GetRead_Binary_Restart(void) const { return Read_Binary_Restart; } + /*! + * \brief Indicates if solution interpolation will be used. + */ + bool GetSolutionInterpolation(void) const { return interpolate_solution; } + /*! * \brief Provides the number of varaibles. * \return Number of variables. diff --git a/Common/include/adt/CADTElemClass.hpp b/Common/include/adt/CADTElemClass.hpp index 2b4142948b7..1fc4ed5a334 100644 --- a/Common/include/adt/CADTElemClass.hpp +++ b/Common/include/adt/CADTElemClass.hpp @@ -79,6 +79,12 @@ class CADTElemClass : public CADTBaseClass { * \param[in] globalTree Whether or not a global tree must be built. If false a local ADT is built. */ + + /*! + * \brief Default constructor of the class, disabled. + */ + CADTElemClass() = default; + CADTElemClass(unsigned short val_nDim, vector &val_coor, vector &val_connElem, @@ -87,6 +93,14 @@ class CADTElemClass : public CADTBaseClass { vector &val_elemID, const bool globalTree); + void CreateADT(unsigned short val_nDim, + vector &val_coor, + vector &val_connElem, + vector &val_VTKElem, + vector &val_markerID, + vector &val_elemID, + const bool globalTree); + /*! * \brief Function, which determines the element that contains the given coordinate. * \note This simply forwards the call to the implementation function selecting the right @@ -132,7 +146,6 @@ class CADTElemClass : public CADTBaseClass { FrontLeavesNew[iThread], coor, dist, markerID, elemID, rankID); } -private: /*! * \brief Implementation of DetermineContainingElement. * \note Working variables (first two) passed explicitly for thread safety. @@ -159,6 +172,9 @@ class CADTElemClass : public CADTBaseClass { unsigned long &elemID, int &rankID) const; +private: + + /*! * \brief Function, which checks whether or not the given coordinate is inside the given element. @@ -395,9 +411,6 @@ class CADTElemClass : public CADTBaseClass { su2double &dist2Tria, su2double &r, su2double &s) const; - /*! - * \brief Default constructor of the class, disabled. - */ - CADTElemClass() = delete; + }; \ No newline at end of file diff --git a/Common/include/fem/fem_standard_element.hpp b/Common/include/fem/fem_standard_element.hpp index 13ea78a149b..518eb509299 100644 --- a/Common/include/fem/fem_standard_element.hpp +++ b/Common/include/fem/fem_standard_element.hpp @@ -1014,7 +1014,7 @@ class CFEMStandardElement : public CFEMStandardElementBase { * \brief Function, which makes available the number of DOFs for this standard element. * \return The number of DOFs of this standard element. */ - inline unsigned short GetNDOFs(void) const {return nDOFs;} + inline unsigned short GetNDOFs(void) const {return nDOFs;} /*! * \brief Function, which makes available the polynomial degree for this standard element. @@ -1589,7 +1589,7 @@ class CFEMStandardBoundaryFace : public CFEMStandardElementBase { the residuals of the symmetrizing terms can be computed with a single matrix multiplication. */ - + vector matVandermondeFaceInv; /*!< \brief TODO what is this? */ vector subConnForPlotting; /*!< \brief Local subconnectivity of the high order element. Used for plotting. */ public: @@ -1703,6 +1703,16 @@ class CFEMStandardBoundaryFace : public CFEMStandardElementBase { */ inline unsigned short GetNDOFsFace(void) const {return nDOFsFace;} + /*! + * \brief What is this? + */ + inline const vector* GetRDOFsFace(void) {return &rDOFsFace;} + + /*! + * \brief What is this? + */ + inline const vector* GetSDOFsFace(void) {return &sDOFsFace;} + /*! * \brief Function, which makes available the number of linear subfaces used for plotting, among others. @@ -1761,6 +1771,13 @@ class CFEMStandardBoundaryFace : public CFEMStandardElementBase { su2double WorkEstimateMetisWallFunctions(CConfig *config, const unsigned short nPointsWF); + /*! + * \brief What is this? + */ + void FaceBasisFunctionsAndDerivativesInPoint(const su2double *parCoor, + vector &lagBasis, + vector > &dLagBasis); + private: /*! * \brief Function, which copies the data of the given object into the current object. diff --git a/Common/include/option_structure.hpp b/Common/include/option_structure.hpp index cba956f992c..3b2dc7c4637 100644 --- a/Common/include/option_structure.hpp +++ b/Common/include/option_structure.hpp @@ -64,12 +64,13 @@ using MapType = CEmptyMap; * \brief Different software components of SU2 */ enum SU2_COMPONENT { - SU2_CFD = 1, /*!< \brief Running the SU2_CFD software. */ - SU2_DEF = 2, /*!< \brief Running the SU2_DEF software. */ - SU2_DOT = 3, /*!< \brief Running the SU2_DOT software. */ - SU2_MSH = 4, /*!< \brief Running the SU2_MSH software. */ - SU2_GEO = 5, /*!< \brief Running the SU2_GEO software. */ - SU2_SOL = 6 /*!< \brief Running the SU2_SOL software. */ + SU2_CFD = 1, /*!< \brief Running the SU2_CFD software. */ + SU2_DEF = 2, /*!< \brief Running the SU2_DEF software. */ + SU2_DOT = 3, /*!< \brief Running the SU2_DOT software. */ + SU2_MSH = 4, /*!< \brief Running the SU2_MSH software. */ + SU2_GEO = 5, /*!< \brief Running the SU2_GEO software. */ + SU2_SOL = 6, /*!< \brief Running the SU2_SOL software. */ + SU2_INTERP = 7 /*!< \brief Running the SU2_INTERP software. */ }; const unsigned int EXIT_DIVERGENCE = 2; /*!< \brief Exit code (divergence). */ diff --git a/Common/src/CConfig.cpp b/Common/src/CConfig.cpp index f43b4a037ee..3ca67889ddf 100644 --- a/Common/src/CConfig.cpp +++ b/Common/src/CConfig.cpp @@ -253,6 +253,44 @@ CConfig::CConfig(char case_filename[MAX_STRING_SIZE], CConfig *config) { } } +CConfig::CConfig(char case_filename[MAX_STRING_SIZE], unsigned short val_software, unsigned short val_iZone, unsigned short val_nZone, unsigned short val_nDim, bool verb_high) { + + caseName = PrintingToolbox::split(string(case_filename),'.')[0]; + + base_config = false; + + iZone = val_iZone; + nZone = val_nZone; + + Init(); + + /*--- Parsing the config file ---*/ + + SetConfig_Parsing(case_filename); + + /*--- Set the default values for all of the options that weren't set ---*/ + + SetDefault(); + + /*--- Set number of zone ---*/ + + SetnZone(); + + /*--- Configuration file postprocessing ---*/ + + SetPostprocessing(val_software, val_iZone, val_nDim); + + /*--- Configuration file boundaries/markers setting ---*/ + + SetMarkers(val_software); + + /*--- Configuration file output ---*/ + + if ((rank == MASTER_NODE) && verb_high) + SetOutput(val_software, val_iZone); + +} + SU2_MPI::Comm CConfig::GetMPICommunicator() const { return SU2_Communicator; @@ -2783,8 +2821,17 @@ void CConfig::SetConfig_Options() { /* DESCRIPTION: Size of the edge groups colored for thread parallel edge loops (0 forces the reducer strategy). */ addUnsignedLongOption("EDGE_COLORING_GROUP_SIZE", edgeColorGroupSize, 512); - /* END_CONFIG_OPTIONS */ + /* DESCRIPTION: Interpolating solutions between two meshes */ + addBoolOption("INTERPOLATE_SOLUTION", interpolate_solution, false); + + /* DESCRIPTION: Interpolated output file restart flow */ + addStringOption("INTERPOLATED_RESTART_FILENAME", Interpolated_Restart_FileName, string("interpolated_restart_flow.dat")); + + /* DESCRIPTION: Target mesh for solution interpolation */ + addStringOption("TARGET_MESH_FILENAME", Target_Mesh_FileName, string("target_mesh.su2")); + + /* END_CONFIG_OPTIONS */ } void CConfig::SetConfig_Parsing(char case_filename[MAX_STRING_SIZE]) { @@ -3059,12 +3106,13 @@ void CConfig::SetHeader(unsigned short val_software) const{ cout << "| / __| | | |_ ) Release 7.0.8 \"Blackbird\" |" << endl; cout << "| \\__ \\ |_| |/ / |" << endl; switch (val_software) { - case SU2_CFD: cout << "| |___/\\___//___| Suite (Computational Fluid Dynamics Code) |" << endl; break; - case SU2_DEF: cout << "| |___/\\___//___| Suite (Mesh Deformation Code) |" << endl; break; - case SU2_DOT: cout << "| |___/\\___//___| Suite (Gradient Projection Code) |" << endl; break; - case SU2_MSH: cout << "| |___/\\___//___| Suite (Mesh Adaptation Code) |" << endl; break; - case SU2_GEO: cout << "| |___/\\___//___| Suite (Geometry Definition Code) |" << endl; break; - case SU2_SOL: cout << "| |___/\\___//___| Suite (Solution Exporting Code) |" << endl; break; + case SU2_CFD: cout << "| |___/\\___//___| Suite (Computational Fluid Dynamics Code) |" << endl; break; + case SU2_DEF: cout << "| |___/\\___//___| Suite (Mesh Deformation Code) |" << endl; break; + case SU2_DOT: cout << "| |___/\\___//___| Suite (Gradient Projection Code) |" << endl; break; + case SU2_MSH: cout << "| |___/\\___//___| Suite (Mesh Adaptation Code) |" << endl; break; + case SU2_GEO: cout << "| |___/\\___//___| Suite (Geometry Definition Code) |" << endl; break; + case SU2_SOL: cout << "| |___/\\___//___| Suite (Solution Exporting Code) |" << endl; break; + case SU2_INTERP: cout << "| |___/\\___//___| Suite (Solution Interpolation Code) |" << endl; break; } cout << "| |" << endl; diff --git a/Common/src/adt/CADTElemClass.cpp b/Common/src/adt/CADTElemClass.cpp index 271d3b45c96..6f11884f61a 100644 --- a/Common/src/adt/CADTElemClass.cpp +++ b/Common/src/adt/CADTElemClass.cpp @@ -42,6 +42,21 @@ CADTElemClass::CADTElemClass(unsigned short val_nDim, vector &val_elemID, const bool globalTree) { + + /* Call CreateADT to do the actual work. */ +CreateADT(val_nDim, val_coor, val_connElem, val_VTKElem, + val_markerID, val_elemID, globalTree); +} + +void CADTElemClass::CreateADT(unsigned short val_nDim, + vector &val_coor, + vector &val_connElem, + vector &val_VTKElem, + vector &val_markerID, + vector &val_elemID, + const bool globalTree ) { + + /* Copy the dimension of the problem into nDim. */ nDim = val_nDim; diff --git a/Common/src/fem/fem_standard_element.cpp b/Common/src/fem/fem_standard_element.cpp index 8c1e057e92e..b2ffc96e92e 100644 --- a/Common/src/fem/fem_standard_element.cpp +++ b/Common/src/fem/fem_standard_element.cpp @@ -1811,6 +1811,50 @@ su2double CFEMStandardElementBase::ViscousPenaltyParameter( return penParam; } +void CFEMStandardBoundaryFace::FaceBasisFunctionsAndDerivativesInPoint( + const su2double *parCoor, + vector &lagBasis, + vector > &dLagBasis) { + + /* Allocate the memory for the help vectors for computing the Vandermonde + matrices and its derivatives. */ + vector > rPoints(dLagBasis.size(), vector(1)); + vector > VDr(dLagBasis.size(), vector(nDOFsFace)); + + vector V(nDOFsFace); + + /* Copy the parametric coordinates in rPoints, such that the functions to + compute the Vandermonde matrices can be used. */ + for(unsigned long i=0; i Date: Fri, 15 Jan 2021 23:08:25 +0000 Subject: [PATCH 04/23] Working in 3D, missing comments --- .../include/variables/CNEMOEulerVariable.hpp | 6 +- SU2_CFD/src/solvers/CNEMOEulerSolver.cpp | 87 ++++++++++++------- SU2_CFD/src/variables/CNEMOEulerVariable.cpp | 2 +- 3 files changed, 58 insertions(+), 37 deletions(-) diff --git a/SU2_CFD/include/variables/CNEMOEulerVariable.hpp b/SU2_CFD/include/variables/CNEMOEulerVariable.hpp index c55ad5e937b..fd8bd9b7636 100644 --- a/SU2_CFD/include/variables/CNEMOEulerVariable.hpp +++ b/SU2_CFD/include/variables/CNEMOEulerVariable.hpp @@ -82,7 +82,7 @@ class CNEMOEulerVariable : public CVariable { su2double Tve_Freestream; /*!< \brief Freestream vib-el temperature. */ - VectorType symmetry = false; + VectorType symmetry; public: @@ -588,8 +588,8 @@ class CNEMOEulerVariable : public CVariable { */ inline unsigned short GetRhoCvveIndex(void) { return RHOCVVE_INDEX; } - inline bool GetSymmetry(unsigned long iPoint) { return symmetry[iPoint]; } + inline unsigned short GetSymmetry(unsigned long iPoint) { return symmetry[iPoint]; } - inline void SetSymmetry(unsigned long iPoint) {symmetry[iPoint] = true;} + inline void SetSymmetry(unsigned long iPoint) {symmetry[iPoint] += 1;} }; diff --git a/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp b/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp index 4bb39c12860..b5a57f60898 100644 --- a/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp +++ b/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp @@ -465,8 +465,7 @@ void CNEMOEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_contai } SU2_OMP_BARRIER - // const su2double *Normal = nullptr; - su2double Normal[3]; + su2double Normal[3], Normal_Product; su2double Area, Vol, Mean_SoundSpeed, Mean_ProjVel, Lambda, Local_Delta_Time, Local_Delta_Time_Visc; su2double Mean_LaminarVisc, Mean_EddyVisc, Mean_Density, Lambda_1, Lambda_2; su2double Mean_ThermalCond, Mean_ThermalCond_ve, cv; @@ -474,18 +473,6 @@ void CNEMOEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_contai unsigned long iEdge, iVertex, iPoint, jPoint; unsigned short iDim, iMarker; - /*--- Save Normal if Symmetry plane exists ---*/ - for (iMarker = 0; iMarker < geometry->GetnMarker(); iMarker++) { - if (config->GetMarker_All_KindBC(iMarker) == SYMMETRY_PLANE){ - geometry->vertex[iMarker][0]->GetNormal(Normal_Sym); - - Area = GeometryToolbox::Norm(nDim, Normal_Sym); - - for(iDim = 0; iDim < nDim; iDim++) - UnitNormal_Sym[iDim] = -Normal_Sym[iDim]/Area; - } - } - /*--- Loop domain points. ---*/ SU2_OMP_FOR_DYN(omp_chunk_size) for (iPoint = 0; iPoint < nPointDomain; ++iPoint) { @@ -504,10 +491,6 @@ void CNEMOEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_contai iEdge = geometry->nodes->GetEdge(iPoint,iNeigh); geometry->edges->GetNormal(iEdge,Normal); - if(nodes->GetSymmetry(iPoint) && nodes->GetSymmetry(jPoint)) - for(iDim = 0; iDim < nDim; iDim++) - Normal[iDim] += Normal[iDim]*UnitNormal_Sym[iDim]; - Area = GeometryToolbox::Norm(nDim, Normal); /*--- Mean Values ---*/ @@ -527,7 +510,8 @@ void CNEMOEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_contai Lambda = fabs(Mean_ProjVel) + Mean_SoundSpeed; nodes->AddMax_Lambda_Inv(iPoint,Lambda); - if (nodes->GetSymmetry(iPoint)) nodes->AddMax_Lambda_Inv(iPoint,Lambda); + if (nodes->GetSymmetry(iPoint)==1) nodes->AddMax_Lambda_Inv(iPoint,Lambda); + else if(nodes->GetSymmetry(iPoint)==2) nodes->AddMax_Lambda_Inv(iPoint,3*Lambda); /*--- Viscous contribution ---*/ if (!viscous) continue; @@ -554,8 +538,11 @@ void CNEMOEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_contai nodes->AddMax_Lambda_Visc(iPoint, Lambda); if (nodes->GetSymmetry(iPoint)) - if(nodes->GetSymmetry(jPoint)) nodes->AddMax_Lambda_Visc(iPoint,3*Lambda); + if(nodes->GetSymmetry(iPoint)==1 && nodes->GetSymmetry(jPoint)) nodes->AddMax_Lambda_Visc(iPoint,3*Lambda); + else if (nodes->GetSymmetry(iPoint) == 2 && nodes->GetSymmetry(jPoint)==1) nodes->AddMax_Lambda_Visc(iPoint,7*Lambda); + else if (nodes->GetSymmetry(iPoint) == 2 && nodes->GetSymmetry(jPoint)==2) nodes->AddMax_Lambda_Visc(iPoint,15*Lambda); else nodes->AddMax_Lambda_Visc(iPoint, Lambda); + } } @@ -565,6 +552,15 @@ void CNEMOEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_contai if ((config->GetMarker_All_KindBC(iMarker) != INTERNAL_BOUNDARY) && (config->GetMarker_All_KindBC(iMarker) != PERIODIC_BOUNDARY)) { + if (config->GetMarker_All_KindBC(iMarker) == SYMMETRY_PLANE){ + geometry->vertex[iMarker][0]->GetNormal(Normal_Sym); + + Area = GeometryToolbox::Norm(nDim, Normal_Sym); + + for(iDim = 0; iDim < nDim; iDim++) + UnitNormal_Sym[iDim] = Normal_Sym[iDim]/Area; + } + SU2_OMP_FOR_STAT(OMP_MIN_SIZE) for (iVertex = 0; iVertex < geometry->GetnVertex(iMarker); iVertex++) { @@ -575,9 +571,14 @@ void CNEMOEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_contai geometry->vertex[iMarker][iVertex]->GetNormal(Normal); - if(nodes->GetSymmetry(iPoint)==true && config->GetMarker_All_KindBC(iMarker) == SYMMETRY_PLANE) { + if(nodes->GetSymmetry(iPoint) && config->GetMarker_All_KindBC(iMarker) == SYMMETRY_PLANE) { + Normal_Product = 0.0; + + for(iDim = 0; iDim < nDim; iDim++) + Normal_Product+= Normal[iDim]*UnitNormal_Sym[iDim]; + for(iDim = 0; iDim < nDim; iDim++) - Normal[iDim] += Normal[iDim]*UnitNormal_Sym[iDim]; + Normal[iDim] -= Normal_Product*UnitNormal_Sym[iDim]; } Area = GeometryToolbox::Norm(nDim, Normal); @@ -596,10 +597,13 @@ void CNEMOEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_contai /*--- Inviscid contribution ---*/ Lambda = fabs(Mean_ProjVel) + Mean_SoundSpeed; nodes->AddMax_Lambda_Inv(iPoint,Lambda); - - if(nodes->GetSymmetry(iPoint)==true) nodes->AddMax_Lambda_Inv(iPoint,Lambda); + + if(nodes->GetSymmetry(iPoint)==1) nodes->AddMax_Lambda_Inv(iPoint,Lambda); + else if (nodes->GetSymmetry(iPoint)==2) nodes->AddMax_Lambda_Inv(iPoint,3*Lambda); /*--- Viscous contribution ---*/ + + if (!viscous) continue; /*--- Calculate viscous mean quantities ---*/ @@ -611,15 +615,16 @@ void CNEMOEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_contai cv = (nodes->GetRhoCv_tr(iPoint) + nodes->GetRhoCv_ve(iPoint)) / Mean_Density; - // if(nodes->GetSymmetry(iPoint)==true && config->GetMarker_All_KindBC(iMarker) == SYMMETRY_PLANE) Area/=2; Lambda_1 = (4.0/3.0)*(Mean_LaminarVisc+Mean_EddyVisc); Lambda_2 = (Mean_ThermalCond+Mean_ThermalCond_ve)/cv; Lambda = (Lambda_1 + Lambda_2)*Area*Area/Mean_Density; nodes->AddMax_Lambda_Visc(iPoint,Lambda); - if(nodes->GetSymmetry(iPoint)==true) - if(config->GetMarker_All_KindBC(iMarker) != SYMMETRY_PLANE) nodes->AddMax_Lambda_Visc(iPoint,3*Lambda); - else nodes->AddMax_Lambda_Visc(iPoint, Lambda); + if(nodes->GetSymmetry(iPoint)) + if(config->GetMarker_All_KindBC(iMarker) != SYMMETRY_PLANE && nodes->GetSymmetry(iPoint)==1) nodes->AddMax_Lambda_Visc(iPoint,3*Lambda); + else if(config->GetMarker_All_KindBC(iMarker) != SYMMETRY_PLANE && nodes->GetSymmetry(iPoint)==2) nodes->AddMax_Lambda_Visc(iPoint,15*Lambda); + else if(config->GetMarker_All_KindBC(iMarker) == SYMMETRY_PLANE && nodes->GetSymmetry(iPoint)==2) nodes->AddMax_Lambda_Visc(iPoint,7*Lambda); + else nodes->AddMax_Lambda_Visc(iPoint, Lambda); } } @@ -634,7 +639,7 @@ void CNEMOEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_contai for (iPoint = 0; iPoint < nPointDomain; iPoint++) { Vol = geometry->nodes->GetVolume(iPoint); - if(nodes->GetSymmetry(iPoint)==true) Vol=2*Vol; + if(nodes->GetSymmetry(iPoint)) Vol*=2*nodes->GetSymmetry(iPoint); if (Vol != 0.0) { Local_Delta_Time = nodes->GetLocalCFL(iPoint)*Vol / nodes->GetMax_Lambda_Inv(iPoint); @@ -1030,6 +1035,17 @@ void CNEMOEulerSolver::Upwind_Residual(CGeometry *geometry, CSolver **solver_con // Jacobian.SubtractBlock(jPoint, iPoint, Jacobian_i); // Jacobian.SubtractBlock(jPoint, jPoint, Jacobian_j); //} + + + //if (nodes->GetSymmetry(iPoint) || nodes->GetSymmetry(jPoint)) + su2double Normal[3]; + + Normal[0]=geometry->edges->GetNormal(iEdge)[0]; + Normal[1]=geometry->edges->GetNormal(iEdge)[1]; + Normal[2]=geometry->edges->GetNormal(iEdge)[2]; + + su2double Area = GeometryToolbox::Norm(nDim, Normal); + } } @@ -1305,10 +1321,10 @@ void CNEMOEulerSolver::ExplicitEuler_Iteration(CGeometry *geometry, CSolver **so Vol = (geometry->nodes->GetVolume(iPoint) + geometry->nodes->GetPeriodicVolume(iPoint)); - if (nodes->GetSymmetry(iPoint)==true) Vol*=2; + if (nodes->GetSymmetry(iPoint)) Vol*=2*nodes->GetSymmetry(iPoint); Delta = nodes->GetDelta_Time(iPoint) / Vol; - + //Delta = 0.0326993 local_Res_TruncError = nodes->GetResTruncError(iPoint); local_Residual = LinSysRes.GetBlock(iPoint); @@ -1863,7 +1879,7 @@ void CNEMOEulerSolver::BC_Sym_Plane(CGeometry *geometry, CSolver **solver_contai CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { unsigned long iPoint, iVertex; unsigned short iDim, iVar; - su2double Area, Normal[3], UnitNormal[3]; + su2double Area, Normal[3], UnitNormal[3], Normal_Product; const su2double* Residual_Old; geometry->vertex[val_marker][0]->GetNormal(Normal); @@ -1883,8 +1899,13 @@ void CNEMOEulerSolver::BC_Sym_Plane(CGeometry *geometry, CSolver **solver_contai for(iVar = 0; iVar < nVar; iVar++) Res_Conv[iVar] = Residual_Old[iVar]; + Normal_Product = 0.0; + + for(iDim = 0; iDim < nDim; iDim++) + Normal_Product+= Res_Conv[nSpecies+iDim]*UnitNormal[iDim]; + for(iDim = 0; iDim < nDim; iDim++) - Res_Conv[nSpecies+iDim]+=2*Residual_Old[nSpecies+iDim]*UnitNormal[iDim]; + Res_Conv[nSpecies+iDim]-=2*Normal_Product*UnitNormal[iDim]; LinSysRes.AddBlock(iPoint, Res_Conv); } diff --git a/SU2_CFD/src/variables/CNEMOEulerVariable.cpp b/SU2_CFD/src/variables/CNEMOEulerVariable.cpp index c58d71d7520..ecc1343fae3 100644 --- a/SU2_CFD/src/variables/CNEMOEulerVariable.cpp +++ b/SU2_CFD/src/variables/CNEMOEulerVariable.cpp @@ -140,7 +140,7 @@ CNEMOEulerVariable::CNEMOEulerVariable(su2double val_pressure, bool interp = config->GetSolutionInterpolation(); /* Boolean to check if nodes are in Symmetry Plane BC */ - symmetry.resize(nPoint) = false; + symmetry.resize(nPoint) = 0; /*--- Do not initialize variables for solution interpolation, since it makes the interpolation super slow and is not necessary ---*/ if (!interp) { From 9fb212c67fd148b1066059218cc541255909ddb6 Mon Sep 17 00:00:00 2001 From: CatarinaGarbacz Date: Sun, 17 Jan 2021 19:33:58 +0000 Subject: [PATCH 05/23] frozen mixture option also working with mutation++ --- Common/src/CConfig.cpp | 4 ---- SU2_CFD/src/fluid/CMutationTCLib.cpp | 1 + 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/Common/src/CConfig.cpp b/Common/src/CConfig.cpp index 3ca67889ddf..a30dcb99a44 100644 --- a/Common/src/CConfig.cpp +++ b/Common/src/CConfig.cpp @@ -3603,10 +3603,6 @@ void CConfig::SetPostprocessing(unsigned short val_software, unsigned short val_ SU2_MPI::Error("ARGON is not working with SU2_NONEQ fluid model!", CURRENT_FUNCTION); } - if (GetKind_FluidModel() == MUTATIONPP && GetFrozen() == true){ - SU2_MPI::Error("The option of FROZEN_MIXTURE is not yet working with Mutation++ support.", CURRENT_FUNCTION); - } - if(GetBoolTurbomachinery()){ nBlades = new su2double[nZone]; FreeStreamTurboNormal= new su2double[3]; diff --git a/SU2_CFD/src/fluid/CMutationTCLib.cpp b/SU2_CFD/src/fluid/CMutationTCLib.cpp index 131eb397f6a..9f5786eee63 100644 --- a/SU2_CFD/src/fluid/CMutationTCLib.cpp +++ b/SU2_CFD/src/fluid/CMutationTCLib.cpp @@ -49,6 +49,7 @@ CMutationTCLib::CMutationTCLib(const CConfig* config, unsigned short val_nDim): transport_model = "Gupta-Yos"; opt.setStateModel("ChemNonEqTTv"); + if (frozen) opt.setMechanism("none"); opt.setViscosityAlgorithm(transport_model); opt.setThermalConductivityAlgorithm(transport_model); From 120d6cfa9dec142ec7c2b5804f40386f99817740 Mon Sep 17 00:00:00 2001 From: fmpmorgado Date: Mon, 18 Jan 2021 12:19:51 +0000 Subject: [PATCH 06/23] Re-organized code and placed some comments --- .../include/variables/CNEMOEulerVariable.hpp | 16 ++-- SU2_CFD/src/solvers/CNEMOEulerSolver.cpp | 79 ++++++------------- 2 files changed, 37 insertions(+), 58 deletions(-) diff --git a/SU2_CFD/include/variables/CNEMOEulerVariable.hpp b/SU2_CFD/include/variables/CNEMOEulerVariable.hpp index fd8bd9b7636..21a81bc998d 100644 --- a/SU2_CFD/include/variables/CNEMOEulerVariable.hpp +++ b/SU2_CFD/include/variables/CNEMOEulerVariable.hpp @@ -82,7 +82,7 @@ class CNEMOEulerVariable : public CVariable { su2double Tve_Freestream; /*!< \brief Freestream vib-el temperature. */ - VectorType symmetry; + VectorType symmetry; /*!< \brief Nodes in symmetry planes. */ public: @@ -534,6 +534,16 @@ class CNEMOEulerVariable : public CVariable { */ inline su2double GetGamma(unsigned long iPoint) { return Gamma(iPoint); } + /*! + * \brief Retrieves the number of symmetry planes at the specified node. + */ + inline unsigned short GetSymmetry(unsigned long iPoint) { return symmetry[iPoint]; } + + /*! + * \brief Increases the number of symmetry planes at the specified node by one. + */ + inline void SetSymmetry(unsigned long iPoint) {symmetry[iPoint] += 1;} + /*---------------------------------------*/ /*--- NEMO indices ---*/ /*---------------------------------------*/ @@ -587,9 +597,5 @@ class CNEMOEulerVariable : public CVariable { * \brief Retrieves the value of the RhoCvve in the primitive variable vector. */ inline unsigned short GetRhoCvveIndex(void) { return RHOCVVE_INDEX; } - - inline unsigned short GetSymmetry(unsigned long iPoint) { return symmetry[iPoint]; } - - inline void SetSymmetry(unsigned long iPoint) {symmetry[iPoint] += 1;} }; diff --git a/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp b/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp index b5a57f60898..041bc986d7e 100644 --- a/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp +++ b/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp @@ -465,11 +465,10 @@ void CNEMOEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_contai } SU2_OMP_BARRIER - su2double Normal[3], Normal_Product; + su2double Normal[3]; su2double Area, Vol, Mean_SoundSpeed, Mean_ProjVel, Lambda, Local_Delta_Time, Local_Delta_Time_Visc; su2double Mean_LaminarVisc, Mean_EddyVisc, Mean_Density, Lambda_1, Lambda_2; su2double Mean_ThermalCond, Mean_ThermalCond_ve, cv; - su2double Normal_Sym[3], UnitNormal_Sym[3]; unsigned long iEdge, iVertex, iPoint, jPoint; unsigned short iDim, iMarker; @@ -508,10 +507,10 @@ void CNEMOEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_contai /*--- Inviscid contribution ---*/ Lambda = fabs(Mean_ProjVel) + Mean_SoundSpeed; - nodes->AddMax_Lambda_Inv(iPoint,Lambda); - if (nodes->GetSymmetry(iPoint)==1) nodes->AddMax_Lambda_Inv(iPoint,Lambda); - else if(nodes->GetSymmetry(iPoint)==2) nodes->AddMax_Lambda_Inv(iPoint,3*Lambda); + if (nodes->GetSymmetry(iPoint) == 0) nodes->AddMax_Lambda_Inv(iPoint,Lambda); + else if (nodes->GetSymmetry(iPoint) == 1) nodes->AddMax_Lambda_Inv(iPoint, 2*Lambda); + else if (nodes->GetSymmetry(iPoint) == 2) nodes->AddMax_Lambda_Inv(iPoint, 4*Lambda); /*--- Viscous contribution ---*/ if (!viscous) continue; @@ -535,13 +534,13 @@ void CNEMOEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_contai Lambda_2 = (Mean_ThermalCond+Mean_ThermalCond_ve)/cv; Lambda = (Lambda_1 + Lambda_2)*Area*Area/Mean_Density; - nodes->AddMax_Lambda_Visc(iPoint, Lambda); if (nodes->GetSymmetry(iPoint)) - if(nodes->GetSymmetry(iPoint)==1 && nodes->GetSymmetry(jPoint)) nodes->AddMax_Lambda_Visc(iPoint,3*Lambda); - else if (nodes->GetSymmetry(iPoint) == 2 && nodes->GetSymmetry(jPoint)==1) nodes->AddMax_Lambda_Visc(iPoint,7*Lambda); - else if (nodes->GetSymmetry(iPoint) == 2 && nodes->GetSymmetry(jPoint)==2) nodes->AddMax_Lambda_Visc(iPoint,15*Lambda); - else nodes->AddMax_Lambda_Visc(iPoint, Lambda); + if(nodes->GetSymmetry(iPoint) == 1 && nodes->GetSymmetry(jPoint)) nodes->AddMax_Lambda_Visc(iPoint, 4*Lambda); + else if (nodes->GetSymmetry(iPoint) == 2 && nodes->GetSymmetry(jPoint) == 1) nodes->AddMax_Lambda_Visc(iPoint, 8*Lambda); + else if (nodes->GetSymmetry(iPoint) == 2 && nodes->GetSymmetry(jPoint) == 2) nodes->AddMax_Lambda_Visc(iPoint, 16*Lambda); + else nodes->AddMax_Lambda_Visc(iPoint, 2*Lambda); + else nodes->AddMax_Lambda_Visc(iPoint, Lambda); } @@ -551,15 +550,6 @@ void CNEMOEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_contai for (iMarker = 0; iMarker < geometry->GetnMarker(); iMarker++) { if ((config->GetMarker_All_KindBC(iMarker) != INTERNAL_BOUNDARY) && (config->GetMarker_All_KindBC(iMarker) != PERIODIC_BOUNDARY)) { - - if (config->GetMarker_All_KindBC(iMarker) == SYMMETRY_PLANE){ - geometry->vertex[iMarker][0]->GetNormal(Normal_Sym); - - Area = GeometryToolbox::Norm(nDim, Normal_Sym); - - for(iDim = 0; iDim < nDim; iDim++) - UnitNormal_Sym[iDim] = Normal_Sym[iDim]/Area; - } SU2_OMP_FOR_STAT(OMP_MIN_SIZE) for (iVertex = 0; iVertex < geometry->GetnVertex(iMarker); iVertex++) { @@ -571,14 +561,10 @@ void CNEMOEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_contai geometry->vertex[iMarker][iVertex]->GetNormal(Normal); - if(nodes->GetSymmetry(iPoint) && config->GetMarker_All_KindBC(iMarker) == SYMMETRY_PLANE) { - Normal_Product = 0.0; - + /*--- Set Normal to zero if node is in the Symmetry Plane marker ---*/ + if(config->GetMarker_All_KindBC(iMarker) == SYMMETRY_PLANE) { for(iDim = 0; iDim < nDim; iDim++) - Normal_Product+= Normal[iDim]*UnitNormal_Sym[iDim]; - - for(iDim = 0; iDim < nDim; iDim++) - Normal[iDim] -= Normal_Product*UnitNormal_Sym[iDim]; + Normal[iDim]=0; } Area = GeometryToolbox::Norm(nDim, Normal); @@ -596,14 +582,13 @@ void CNEMOEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_contai /*--- Inviscid contribution ---*/ Lambda = fabs(Mean_ProjVel) + Mean_SoundSpeed; - nodes->AddMax_Lambda_Inv(iPoint,Lambda); - if(nodes->GetSymmetry(iPoint)==1) nodes->AddMax_Lambda_Inv(iPoint,Lambda); - else if (nodes->GetSymmetry(iPoint)==2) nodes->AddMax_Lambda_Inv(iPoint,3*Lambda); + if (nodes->GetSymmetry(iPoint) == 0) nodes->AddMax_Lambda_Inv(iPoint,Lambda); + else if (nodes->GetSymmetry(iPoint) == 1) nodes->AddMax_Lambda_Inv(iPoint, 2*Lambda); + else if (nodes->GetSymmetry(iPoint) == 2) nodes->AddMax_Lambda_Inv(iPoint, 4*Lambda); /*--- Viscous contribution ---*/ - if (!viscous) continue; /*--- Calculate viscous mean quantities ---*/ @@ -618,13 +603,13 @@ void CNEMOEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_contai Lambda_1 = (4.0/3.0)*(Mean_LaminarVisc+Mean_EddyVisc); Lambda_2 = (Mean_ThermalCond+Mean_ThermalCond_ve)/cv; Lambda = (Lambda_1 + Lambda_2)*Area*Area/Mean_Density; - nodes->AddMax_Lambda_Visc(iPoint,Lambda); if(nodes->GetSymmetry(iPoint)) - if(config->GetMarker_All_KindBC(iMarker) != SYMMETRY_PLANE && nodes->GetSymmetry(iPoint)==1) nodes->AddMax_Lambda_Visc(iPoint,3*Lambda); - else if(config->GetMarker_All_KindBC(iMarker) != SYMMETRY_PLANE && nodes->GetSymmetry(iPoint)==2) nodes->AddMax_Lambda_Visc(iPoint,15*Lambda); - else if(config->GetMarker_All_KindBC(iMarker) == SYMMETRY_PLANE && nodes->GetSymmetry(iPoint)==2) nodes->AddMax_Lambda_Visc(iPoint,7*Lambda); - else nodes->AddMax_Lambda_Visc(iPoint, Lambda); + if(config->GetMarker_All_KindBC(iMarker) != SYMMETRY_PLANE && nodes->GetSymmetry(iPoint) == 1) nodes->AddMax_Lambda_Visc(iPoint, 4*Lambda); + else if(config->GetMarker_All_KindBC(iMarker) == SYMMETRY_PLANE && nodes->GetSymmetry(iPoint) == 2) nodes->AddMax_Lambda_Visc(iPoint, 8*Lambda); + else if(config->GetMarker_All_KindBC(iMarker) != SYMMETRY_PLANE && nodes->GetSymmetry(iPoint) == 2) nodes->AddMax_Lambda_Visc(iPoint, 16*Lambda); + else nodes->AddMax_Lambda_Visc(iPoint, 2*Lambda); + else nodes->AddMax_Lambda_Visc(iPoint, Lambda); } } @@ -1035,17 +1020,6 @@ void CNEMOEulerSolver::Upwind_Residual(CGeometry *geometry, CSolver **solver_con // Jacobian.SubtractBlock(jPoint, iPoint, Jacobian_i); // Jacobian.SubtractBlock(jPoint, jPoint, Jacobian_j); //} - - - //if (nodes->GetSymmetry(iPoint) || nodes->GetSymmetry(jPoint)) - su2double Normal[3]; - - Normal[0]=geometry->edges->GetNormal(iEdge)[0]; - Normal[1]=geometry->edges->GetNormal(iEdge)[1]; - Normal[2]=geometry->edges->GetNormal(iEdge)[2]; - - su2double Area = GeometryToolbox::Norm(nDim, Normal); - } } @@ -1324,7 +1298,6 @@ void CNEMOEulerSolver::ExplicitEuler_Iteration(CGeometry *geometry, CSolver **so if (nodes->GetSymmetry(iPoint)) Vol*=2*nodes->GetSymmetry(iPoint); Delta = nodes->GetDelta_Time(iPoint) / Vol; - //Delta = 0.0326993 local_Res_TruncError = nodes->GetResTruncError(iPoint); local_Residual = LinSysRes.GetBlock(iPoint); @@ -1882,15 +1855,15 @@ void CNEMOEulerSolver::BC_Sym_Plane(CGeometry *geometry, CSolver **solver_contai su2double Area, Normal[3], UnitNormal[3], Normal_Product; const su2double* Residual_Old; - geometry->vertex[val_marker][0]->GetNormal(Normal); + /*--- Loop over all the vertices on this boundary marker ---*/ + for(iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { - Area = GeometryToolbox::Norm(nDim, Normal); + geometry->vertex[val_marker][iVertex]->GetNormal(Normal); - for(iDim = 0; iDim < nDim; iDim++) - UnitNormal[iDim] = -Normal[iDim]/Area; + Area = GeometryToolbox::Norm(nDim, Normal); - /*--- Loop over all the vertices on this boundary marker ---*/ - for(iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { + for(iDim = 0; iDim < nDim; iDim++) + UnitNormal[iDim] = Normal[iDim]/Area; iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); From eb5b9816574ddd38a847334064eafe69eec701de Mon Sep 17 00:00:00 2001 From: fmpmorgado Date: Mon, 18 Jan 2021 15:13:35 +0000 Subject: [PATCH 07/23] Solved conflict issues and misleading comments --- SU2_CFD/src/solvers/CNEMOEulerSolver.cpp | 2 +- SU2_CFD/src/variables/CNEMOEulerVariable.cpp | 53 ++++++++++---------- 2 files changed, 28 insertions(+), 27 deletions(-) diff --git a/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp b/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp index 624aac225f1..e26ec306d63 100644 --- a/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp +++ b/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp @@ -256,7 +256,7 @@ CNEMOEulerSolver::CNEMOEulerSolver(CGeometry *geometry, CConfig *config, } } - /*--- Initialize boolean vector with nodes in symmetry plane ---*/ + /*--- Count number of symmetry planes where each Vertex is inserted ---*/ for (unsigned long iMarker = 0; iMarker < geometry->GetnMarker(); iMarker++) { if (config->GetMarker_All_KindBC(iMarker) == SYMMETRY_PLANE){ for (unsigned long iVertex = 0; iVertex < geometry->GetnVertex(iMarker); iVertex++) { diff --git a/SU2_CFD/src/variables/CNEMOEulerVariable.cpp b/SU2_CFD/src/variables/CNEMOEulerVariable.cpp index 8228cdb4571..a6eccac8cb8 100644 --- a/SU2_CFD/src/variables/CNEMOEulerVariable.cpp +++ b/SU2_CFD/src/variables/CNEMOEulerVariable.cpp @@ -144,44 +144,45 @@ CNEMOEulerVariable::CNEMOEulerVariable(su2double val_pressure, bool interp = config->GetSolutionInterpolation(); - /* Boolean to check if nodes are in Symmetry Plane BC */ + /* Vector to count number of symmetry planes at each node. */ symmetry.resize(nPoint) = 0; /*--- Do not initialize variables for solution interpolation, since it makes the interpolation super slow and is not necessary ---*/ if (!interp) { - /*--- Loop over all points --*/ - for(unsigned long iPoint = 0; iPoint < nPoint; ++iPoint){ + /*--- Loop over all points --*/ + for(unsigned long iPoint = 0; iPoint < nPoint; ++iPoint){ - /*--- Reset velocity^2 [m2/s2] to zero ---*/ - sqvel = 0.0; + /*--- Reset velocity^2 [m2/s2] to zero ---*/ + sqvel = 0.0; - /*--- Set mixture state ---*/ - fluidmodel->SetTDStatePTTv(val_pressure, val_massfrac, val_temperature, val_temperature_ve); + /*--- Set mixture state ---*/ + fluidmodel->SetTDStatePTTv(val_pressure, val_massfrac, val_temperature, val_temperature_ve); - /*--- Compute necessary quantities ---*/ - rho = fluidmodel->GetDensity(); - soundspeed = fluidmodel->ComputeSoundSpeed(); - for (iDim = 0; iDim < nDim; iDim++){ - sqvel += val_mach[iDim]*soundspeed * val_mach[iDim]*soundspeed; - } - energies = fluidmodel->ComputeMixtureEnergies(); + /*--- Compute necessary quantities ---*/ + rho = fluidmodel->GetDensity(); + soundspeed = fluidmodel->ComputeSoundSpeed(); + for (iDim = 0; iDim < nDim; iDim++){ + sqvel += val_mach[iDim]*soundspeed * val_mach[iDim]*soundspeed; + } + energies = fluidmodel->ComputeMixtureEnergies(); - /*--- Initialize Solution & Solution_Old vectors ---*/ - for (iSpecies = 0; iSpecies < nSpecies; iSpecies++) - Solution(iPoint,iSpecies) = rho*val_massfrac[iSpecies]; - for (iDim = 0; iDim < nDim; iDim++) - Solution(iPoint,nSpecies+iDim) = rho*val_mach[iDim]*soundspeed; + /*--- Initialize Solution & Solution_Old vectors ---*/ + for (iSpecies = 0; iSpecies < nSpecies; iSpecies++) + Solution(iPoint,iSpecies) = rho*val_massfrac[iSpecies]; + for (iDim = 0; iDim < nDim; iDim++) + Solution(iPoint,nSpecies+iDim) = rho*val_mach[iDim]*soundspeed; - Solution(iPoint,nSpecies+nDim) = rho*(energies[0]+0.5*sqvel); - Solution(iPoint,nSpecies+nDim+1) = rho*(energies[1]); + Solution(iPoint,nSpecies+nDim) = rho*(energies[0]+0.5*sqvel); + Solution(iPoint,nSpecies+nDim+1) = rho*(energies[1]); - Solution_Old = Solution; + Solution_Old = Solution; - /*--- Assign primitive variables ---*/ - Primitive(iPoint,T_INDEX) = val_temperature; - Primitive(iPoint,TVE_INDEX) = val_temperature_ve; - Primitive(iPoint,P_INDEX) = val_pressure; + /*--- Assign primitive variables ---*/ + Primitive(iPoint,T_INDEX) = val_temperature; + Primitive(iPoint,TVE_INDEX) = val_temperature_ve; + Primitive(iPoint,P_INDEX) = val_pressure; + } } } From b86663cd7a31c9e05d9ac550b27a537ef18ff259 Mon Sep 17 00:00:00 2001 From: fmpmorgado Date: Tue, 19 Jan 2021 11:18:42 +0000 Subject: [PATCH 08/23] Simplification of if conditions to calculate the used eigenvalue --- SU2_CFD/src/solvers/CNEMOEulerSolver.cpp | 28 ++++++++---------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp b/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp index e26ec306d63..f8a510d9a0b 100644 --- a/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp +++ b/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp @@ -508,9 +508,7 @@ void CNEMOEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_contai /*--- Inviscid contribution ---*/ Lambda = fabs(Mean_ProjVel) + Mean_SoundSpeed; - if (nodes->GetSymmetry(iPoint) == 0) nodes->AddMax_Lambda_Inv(iPoint,Lambda); - else if (nodes->GetSymmetry(iPoint) == 1) nodes->AddMax_Lambda_Inv(iPoint, 2*Lambda); - else if (nodes->GetSymmetry(iPoint) == 2) nodes->AddMax_Lambda_Inv(iPoint, 4*Lambda); + nodes->AddMax_Lambda_Inv(iPoint,pow(2,nodes->GetSymmetry(iPoint))*Lambda); /*--- Viscous contribution ---*/ if (!viscous) continue; @@ -535,13 +533,10 @@ void CNEMOEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_contai Lambda = (Lambda_1 + Lambda_2)*Area*Area/Mean_Density; - if (nodes->GetSymmetry(iPoint)) - if(nodes->GetSymmetry(iPoint) == 1 && nodes->GetSymmetry(jPoint)) nodes->AddMax_Lambda_Visc(iPoint, 4*Lambda); - else if (nodes->GetSymmetry(iPoint) == 2 && nodes->GetSymmetry(jPoint) == 1) nodes->AddMax_Lambda_Visc(iPoint, 8*Lambda); - else if (nodes->GetSymmetry(iPoint) == 2 && nodes->GetSymmetry(jPoint) == 2) nodes->AddMax_Lambda_Visc(iPoint, 16*Lambda); - else nodes->AddMax_Lambda_Visc(iPoint, 2*Lambda); - else nodes->AddMax_Lambda_Visc(iPoint, Lambda); - + if (nodes->GetSymmetry(jPoint) > nodes->GetSymmetry(iPoint)) + nodes->AddMax_Lambda_Visc(iPoint, pow(2,(nodes->GetSymmetry(iPoint)*nodes->GetSymmetry(jPoint)))*Lambda); + else nodes->AddMax_Lambda_Visc(iPoint, pow(2,(nodes->GetSymmetry(iPoint)+nodes->GetSymmetry(jPoint)))*Lambda); + } } @@ -583,9 +578,7 @@ void CNEMOEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_contai /*--- Inviscid contribution ---*/ Lambda = fabs(Mean_ProjVel) + Mean_SoundSpeed; - if (nodes->GetSymmetry(iPoint) == 0) nodes->AddMax_Lambda_Inv(iPoint,Lambda); - else if (nodes->GetSymmetry(iPoint) == 1) nodes->AddMax_Lambda_Inv(iPoint, 2*Lambda); - else if (nodes->GetSymmetry(iPoint) == 2) nodes->AddMax_Lambda_Inv(iPoint, 4*Lambda); + nodes->AddMax_Lambda_Inv(iPoint,pow(2,nodes->GetSymmetry(iPoint))*Lambda); /*--- Viscous contribution ---*/ @@ -604,12 +597,9 @@ void CNEMOEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_contai Lambda_2 = (Mean_ThermalCond+Mean_ThermalCond_ve)/cv; Lambda = (Lambda_1 + Lambda_2)*Area*Area/Mean_Density; - if(nodes->GetSymmetry(iPoint)) - if(config->GetMarker_All_KindBC(iMarker) != SYMMETRY_PLANE && nodes->GetSymmetry(iPoint) == 1) nodes->AddMax_Lambda_Visc(iPoint, 4*Lambda); - else if(config->GetMarker_All_KindBC(iMarker) == SYMMETRY_PLANE && nodes->GetSymmetry(iPoint) == 2) nodes->AddMax_Lambda_Visc(iPoint, 8*Lambda); - else if(config->GetMarker_All_KindBC(iMarker) != SYMMETRY_PLANE && nodes->GetSymmetry(iPoint) == 2) nodes->AddMax_Lambda_Visc(iPoint, 16*Lambda); - else nodes->AddMax_Lambda_Visc(iPoint, 2*Lambda); - else nodes->AddMax_Lambda_Visc(iPoint, Lambda); + if(nodes->GetSymmetry(iPoint) && config->GetMarker_All_KindBC(iMarker) == SYMMETRY_PLANE) + nodes->AddMax_Lambda_Visc(iPoint,pow(2,2*nodes->GetSymmetry(iPoint)-1)*Lambda); + else nodes->AddMax_Lambda_Visc(iPoint,pow(2,2*nodes->GetSymmetry(iPoint))*Lambda); } } From 84da6e2952b19cacb74c3d18fd69dd4e036ab295 Mon Sep 17 00:00:00 2001 From: fmpmorgado Date: Tue, 19 Jan 2021 16:25:21 +0000 Subject: [PATCH 09/23] Simplifying conditions in time-step calculation --- SU2_CFD/src/solvers/CNEMOEulerSolver.cpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp b/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp index f8a510d9a0b..7169ff35c14 100644 --- a/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp +++ b/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp @@ -508,7 +508,7 @@ void CNEMOEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_contai /*--- Inviscid contribution ---*/ Lambda = fabs(Mean_ProjVel) + Mean_SoundSpeed; - nodes->AddMax_Lambda_Inv(iPoint,pow(2,nodes->GetSymmetry(iPoint))*Lambda); + nodes->AddMax_Lambda_Inv(iPoint, Lambda); /*--- Viscous contribution ---*/ if (!viscous) continue; @@ -533,10 +533,11 @@ void CNEMOEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_contai Lambda = (Lambda_1 + Lambda_2)*Area*Area/Mean_Density; - if (nodes->GetSymmetry(jPoint) > nodes->GetSymmetry(iPoint)) - nodes->AddMax_Lambda_Visc(iPoint, pow(2,(nodes->GetSymmetry(iPoint)*nodes->GetSymmetry(jPoint)))*Lambda); - else nodes->AddMax_Lambda_Visc(iPoint, pow(2,(nodes->GetSymmetry(iPoint)+nodes->GetSymmetry(jPoint)))*Lambda); - + /*--- Still not sure for the case iPoint == 2 && jPoint == 0 ---*/ + if(nodes->GetSymmetry(iPoint) == 1 && nodes->GetSymmetry(jPoint) == 0) nodes->AddMax_Lambda_Visc(iPoint, Lambda/2.0); + else if (nodes->GetSymmetry(iPoint) == 2 && nodes->GetSymmetry(jPoint) == 1) nodes->AddMax_Lambda_Visc(iPoint, Lambda/2.0); + else nodes->AddMax_Lambda_Visc(iPoint, Lambda); + } } @@ -578,7 +579,7 @@ void CNEMOEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_contai /*--- Inviscid contribution ---*/ Lambda = fabs(Mean_ProjVel) + Mean_SoundSpeed; - nodes->AddMax_Lambda_Inv(iPoint,pow(2,nodes->GetSymmetry(iPoint))*Lambda); + nodes->AddMax_Lambda_Inv(iPoint, Lambda); /*--- Viscous contribution ---*/ @@ -597,9 +598,8 @@ void CNEMOEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_contai Lambda_2 = (Mean_ThermalCond+Mean_ThermalCond_ve)/cv; Lambda = (Lambda_1 + Lambda_2)*Area*Area/Mean_Density; - if(nodes->GetSymmetry(iPoint) && config->GetMarker_All_KindBC(iMarker) == SYMMETRY_PLANE) - nodes->AddMax_Lambda_Visc(iPoint,pow(2,2*nodes->GetSymmetry(iPoint)-1)*Lambda); - else nodes->AddMax_Lambda_Visc(iPoint,pow(2,2*nodes->GetSymmetry(iPoint))*Lambda); + if(nodes->GetSymmetry(iPoint) && config->GetMarker_All_KindBC(iMarker) == SYMMETRY_PLANE) nodes->AddMax_Lambda_Visc(iPoint, Lambda/2.0); + else nodes->AddMax_Lambda_Visc(iPoint, Lambda); } } @@ -614,7 +614,6 @@ void CNEMOEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_contai for (iPoint = 0; iPoint < nPointDomain; iPoint++) { Vol = geometry->nodes->GetVolume(iPoint); - if(nodes->GetSymmetry(iPoint)) Vol*=2*nodes->GetSymmetry(iPoint); if (Vol != 0.0) { Local_Delta_Time = nodes->GetLocalCFL(iPoint)*Vol / nodes->GetMax_Lambda_Inv(iPoint); From 201a8699f50ce6d154939c4f8538256bdb8e4c97 Mon Sep 17 00:00:00 2001 From: CatarinaGarbacz Date: Tue, 19 Jan 2021 17:18:03 +0000 Subject: [PATCH 10/23] recovering some forgotten stuff --- SU2_CFD/src/variables/CNEMOEulerVariable.cpp | 68 +++++++++++--------- configure.ac | 4 +- 2 files changed, 40 insertions(+), 32 deletions(-) diff --git a/SU2_CFD/src/variables/CNEMOEulerVariable.cpp b/SU2_CFD/src/variables/CNEMOEulerVariable.cpp index b69125940f3..0227586c254 100644 --- a/SU2_CFD/src/variables/CNEMOEulerVariable.cpp +++ b/SU2_CFD/src/variables/CNEMOEulerVariable.cpp @@ -141,40 +141,46 @@ CNEMOEulerVariable::CNEMOEulerVariable(su2double val_pressure, /* Under-relaxation parameter. */ LocalCFL.resize(nPoint) = su2double(0.0); - - /*--- Loop over all points --*/ - for(unsigned long iPoint = 0; iPoint < nPoint; ++iPoint){ - /*--- Reset velocity^2 [m2/s2] to zero ---*/ - sqvel = 0.0; - - /*--- Set mixture state ---*/ - fluidmodel->SetTDStatePTTv(val_pressure, val_massfrac, val_temperature, val_temperature_ve); - - /*--- Compute necessary quantities ---*/ - rho = fluidmodel->GetDensity(); - soundspeed = fluidmodel->ComputeSoundSpeed(); - for (iDim = 0; iDim < nDim; iDim++){ - sqvel += val_mach[iDim]*soundspeed * val_mach[iDim]*soundspeed; - } - energies = fluidmodel->ComputeMixtureEnergies(); + bool interp = config->GetSolutionInterpolation(); + + /*--- Do not initialize variables for solution interpolation, since it makes the interpolation super slow and is not necessary ---*/ + if (!interp) { + + /*--- Loop over all points --*/ + for(unsigned long iPoint = 0; iPoint < nPoint; ++iPoint){ - /*--- Initialize Solution & Solution_Old vectors ---*/ - for (iSpecies = 0; iSpecies < nSpecies; iSpecies++) - Solution(iPoint,iSpecies) = rho*val_massfrac[iSpecies]; - for (iDim = 0; iDim < nDim; iDim++) - Solution(iPoint,nSpecies+iDim) = rho*val_mach[iDim]*soundspeed; + /*--- Reset velocity^2 [m2/s2] to zero ---*/ + sqvel = 0.0; - Solution(iPoint,nSpecies+nDim) = rho*(energies[0]+0.5*sqvel); - Solution(iPoint,nSpecies+nDim+1) = rho*(energies[1]); - - Solution_Old = Solution; - - /*--- Assign primitive variables ---*/ - Primitive(iPoint,T_INDEX) = val_temperature; - Primitive(iPoint,TVE_INDEX) = val_temperature_ve; - Primitive(iPoint,P_INDEX) = val_pressure; - } + /*--- Set mixture state ---*/ + fluidmodel->SetTDStatePTTv(val_pressure, val_massfrac, val_temperature, val_temperature_ve); + + /*--- Compute necessary quantities ---*/ + rho = fluidmodel->GetDensity(); + soundspeed = fluidmodel->ComputeSoundSpeed(); + for (iDim = 0; iDim < nDim; iDim++){ + sqvel += val_mach[iDim]*soundspeed * val_mach[iDim]*soundspeed; + } + energies = fluidmodel->ComputeMixtureEnergies(); + + /*--- Initialize Solution & Solution_Old vectors ---*/ + for (iSpecies = 0; iSpecies < nSpecies; iSpecies++) + Solution(iPoint,iSpecies) = rho*val_massfrac[iSpecies]; + for (iDim = 0; iDim < nDim; iDim++) + Solution(iPoint,nSpecies+iDim) = rho*val_mach[iDim]*soundspeed; + + Solution(iPoint,nSpecies+nDim) = rho*(energies[0]+0.5*sqvel); + Solution(iPoint,nSpecies+nDim+1) = rho*(energies[1]); + + Solution_Old = Solution; + + /*--- Assign primitive variables ---*/ + Primitive(iPoint,T_INDEX) = val_temperature; + Primitive(iPoint,TVE_INDEX) = val_temperature_ve; + Primitive(iPoint,P_INDEX) = val_pressure; + } + } } void CNEMOEulerVariable::SetVelocity2(unsigned long iPoint) { diff --git a/configure.ac b/configure.ac index a3881c0bbaa..ca1b96c3202 100644 --- a/configure.ac +++ b/configure.ac @@ -113,7 +113,7 @@ AC_ARG_ENABLE(GEO, [build_GEO=$enableval], [build_GEO="yes"]) AC_ARG_ENABLE(INTERP, AS_HELP_STRING([--disable-INTERP], [build the SU2_INTERP executable (default = yes)]), - [build_GEO=$enableval], [build_GEO="yes"]) + [build_INTERP=$enableval], [build_INTERP="yes"]) AC_ARG_ENABLE(PY_WRAPPER, AS_HELP_STRING([--enable-PY_WRAPPER], [wrap the SU2 code with Python (default = no)]), [build_PY_WRAPPER="yes"], [build_PY_WRAPPER="no"]) @@ -298,6 +298,7 @@ then build_DEF=no build_SOL=no build_GEO=no + build_INTERP=no build_PY=no fi @@ -317,6 +318,7 @@ AM_CONDITIONAL([BUILD_DOT],[test $build_DOT != "no"]) AM_CONDITIONAL([BUILD_DEF],[test $build_DEF != "no"]) AM_CONDITIONAL([BUILD_SOL],[test $build_SOL != "no"]) AM_CONDITIONAL([BUILD_GEO],[test $build_GEO != "no"]) +AM_CONDITIONAL([BUILD_INTERP],[test $build_INTERP != "no"]) AM_CONDITIONAL([BUILD_PY],[test $build_PY != "no"]) AM_CONDITIONAL([BUILD_PY_WRAPPER], [test $build_PY_WRAPPER != "no"]) From beaaf88211d47008377bb853e3259fa8a4351094 Mon Sep 17 00:00:00 2001 From: fmpmorgado Date: Tue, 19 Jan 2021 18:49:36 +0000 Subject: [PATCH 11/23] Changing variable type for symmetry vector --- SU2_CFD/include/variables/CNEMOEulerVariable.hpp | 4 ++-- SU2_CFD/src/variables/CNEMOEulerVariable.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/SU2_CFD/include/variables/CNEMOEulerVariable.hpp b/SU2_CFD/include/variables/CNEMOEulerVariable.hpp index effb1a74aab..39b9396dbd8 100644 --- a/SU2_CFD/include/variables/CNEMOEulerVariable.hpp +++ b/SU2_CFD/include/variables/CNEMOEulerVariable.hpp @@ -527,12 +527,12 @@ class CNEMOEulerVariable : public CVariable { /*! * \brief Retrieves the number of symmetry planes at the specified node. */ - inline unsigned short GetSymmetry(unsigned long iPoint) { return symmetry[iPoint]; } + inline su2double GetSymmetry(unsigned long iPoint) { return symmetry[iPoint]; } /*! * \brief Increases the number of symmetry planes at the specified node by one. */ - inline void SetSymmetry(unsigned long iPoint) {symmetry[iPoint] += 1;} + inline void SetSymmetry(unsigned long iPoint) {symmetry[iPoint] += 1.0;} /*---------------------------------------*/ /*--- NEMO indices ---*/ diff --git a/SU2_CFD/src/variables/CNEMOEulerVariable.cpp b/SU2_CFD/src/variables/CNEMOEulerVariable.cpp index a6eccac8cb8..62c3e1c5cbb 100644 --- a/SU2_CFD/src/variables/CNEMOEulerVariable.cpp +++ b/SU2_CFD/src/variables/CNEMOEulerVariable.cpp @@ -145,7 +145,7 @@ CNEMOEulerVariable::CNEMOEulerVariable(su2double val_pressure, bool interp = config->GetSolutionInterpolation(); /* Vector to count number of symmetry planes at each node. */ - symmetry.resize(nPoint) = 0; + symmetry.resize(nPoint) = su2double(0.0); /*--- Do not initialize variables for solution interpolation, since it makes the interpolation super slow and is not necessary ---*/ if (!interp) { From c9f57a650b4e0660aeeea35a4b3e7609f8ac8ec9 Mon Sep 17 00:00:00 2001 From: fmpmorgado Date: Tue, 19 Jan 2021 21:17:51 +0000 Subject: [PATCH 12/23] Adressing compilation issues in clusters --- SU2_CFD/src/solvers/CNEMOEulerSolver.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp b/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp index 7169ff35c14..d454f1b81c5 100644 --- a/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp +++ b/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp @@ -598,7 +598,7 @@ void CNEMOEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_contai Lambda_2 = (Mean_ThermalCond+Mean_ThermalCond_ve)/cv; Lambda = (Lambda_1 + Lambda_2)*Area*Area/Mean_Density; - if(nodes->GetSymmetry(iPoint) && config->GetMarker_All_KindBC(iMarker) == SYMMETRY_PLANE) nodes->AddMax_Lambda_Visc(iPoint, Lambda/2.0); + if(nodes->GetSymmetry(iPoint) > 0 && config->GetMarker_All_KindBC(iMarker) == SYMMETRY_PLANE) nodes->AddMax_Lambda_Visc(iPoint, Lambda/2.0); else nodes->AddMax_Lambda_Visc(iPoint, Lambda); } @@ -1364,7 +1364,7 @@ void CNEMOEulerSolver::ExplicitEuler_Iteration(CGeometry *geometry, CSolver **so Vol = (geometry->nodes->GetVolume(iPoint) + geometry->nodes->GetPeriodicVolume(iPoint)); - if (nodes->GetSymmetry(iPoint)) Vol*=2*nodes->GetSymmetry(iPoint); + if (nodes->GetSymmetry(iPoint) > 0) Vol*=2*nodes->GetSymmetry(iPoint); Delta = nodes->GetDelta_Time(iPoint) / Vol; local_Res_TruncError = nodes->GetResTruncError(iPoint); From 7f20f86580d3c06bcec9da04913eab810d6c8378 Mon Sep 17 00:00:00 2001 From: fmpmorgado Date: Wed, 20 Jan 2021 12:31:15 +0000 Subject: [PATCH 13/23] Removing INTERP to align with develop and feature_NEMO update --- Common/include/CConfig.hpp | 36 - Common/include/adt/CADTElemClass.hpp | 23 +- Common/include/fem/fem_standard_element.hpp | 21 +- Common/include/option_structure.hpp | 1 - Common/src/CConfig.cpp | 48 - Common/src/adt/CADTElemClass.cpp | 15 - Common/src/fem/fem_standard_element.cpp | 44 - Makefile.am | 4 - .../include/fem_interpolation_structure.hpp | 713 --- SU2_CFD/obj/Makefile.am | 3 +- SU2_CFD/src/fem_interpolation_structure.cpp | 3902 ----------------- SU2_CFD/src/meson.build | 2 - SU2_CFD/src/solvers/CNEMOEulerSolver.cpp | 64 +- SU2_CFD/src/variables/CNEMOEulerVariable.cpp | 67 +- SU2_INTERP/include/SU2_INTERP.hpp | 50 - SU2_INTERP/obj/Makefile.am | 62 - SU2_INTERP/src/SU2_INTERP.cpp | 130 - SU2_INTERP/src/meson.build | 10 - configure.ac | 7 +- meson.build | 2 - 20 files changed, 71 insertions(+), 5133 deletions(-) delete mode 100644 SU2_CFD/include/fem_interpolation_structure.hpp delete mode 100644 SU2_CFD/src/fem_interpolation_structure.cpp delete mode 100644 SU2_INTERP/include/SU2_INTERP.hpp delete mode 100644 SU2_INTERP/obj/Makefile.am delete mode 100644 SU2_INTERP/src/SU2_INTERP.cpp delete mode 100644 SU2_INTERP/src/meson.build diff --git a/Common/include/CConfig.hpp b/Common/include/CConfig.hpp index c6ce0c8eecb..72e3eefa963 100644 --- a/Common/include/CConfig.hpp +++ b/Common/include/CConfig.hpp @@ -667,7 +667,6 @@ class CConfig { unsigned long StartConv_Iter; /*!< \brief Start convergence criteria at iteration. */ su2double Cauchy_Eps; /*!< \brief Epsilon used for the convergence. */ bool Restart, /*!< \brief Restart solution (for direct, adjoint, and linearized problems).*/ - Wrt_Binary_Restart, /*!< \brief Write binary SU2 native restart files.*/ Read_Binary_Restart, /*!< \brief Read binary SU2 native restart files.*/ Restart_Flow; /*!< \brief Restart flow solution for adjoint and linearized problems. */ unsigned short nMarker_Monitoring, /*!< \brief Number of markers to monitor. */ @@ -1158,9 +1157,6 @@ class CConfig { monoatomic; /*!< \brief Flag for monoatomic mixture. */ string GasModel, /*!< \brief Gas Model. */ *Wall_Catalytic; /*!< \brief Pointer to catalytic walls. */ - - bool interpolate_solution; /*!< \brief Flag for solution interpolation */ - string Interpolated_Restart_FileName; /*!< \brief Name of interpolated restart file. */ /*! * \brief Set the default values of config options not set in the config file using another config object. @@ -1318,11 +1314,6 @@ class CConfig { */ CConfig(char case_filename[MAX_STRING_SIZE], CConfig *config); - /*! - * \brief Constructor of the class which reads the input file. - */ - CConfig(char case_filename[MAX_STRING_SIZE], unsigned short val_software, unsigned short val_iZone, unsigned short val_nZone, unsigned short val_nDim, bool verb_high); - /*! * \brief Destructor of the class. */ @@ -5121,39 +5112,12 @@ class CConfig { */ bool GetRestart(void) const { return Restart; } - /*! - * \brief Sets the restart information. - */ - void SetRestart(bool val_restart) { Restart = val_restart; } - - /*! - * \brief Sets the mesh filename for interpolation. - */ - void SetMesh_FileName(string val_filename) { Mesh_FileName = val_filename; } - - /*! - * \brief Get the interpolation target mesh name. - * \return Mesh filename to be interpolated. - */ - string GetTarget_Mesh_FileName(void) { return Target_Mesh_FileName; } - - /*! - * \brief Flag for whether binary SU2 native restart files are written. - * \return Flag for whether binary SU2 native restart files are written, if TRUE then the code will output binary restart files. - */ - bool GetWrt_Binary_Restart(void) const { return Wrt_Binary_Restart; } - /*! * \brief Flag for whether binary SU2 native restart files are read. * \return Flag for whether binary SU2 native restart files are read, if TRUE then the code will load binary restart files. */ bool GetRead_Binary_Restart(void) const { return Read_Binary_Restart; } - /*! - * \brief Indicates if solution interpolation will be used. - */ - bool GetSolutionInterpolation(void) const { return interpolate_solution; } - /*! * \brief Provides the number of varaibles. * \return Number of variables. diff --git a/Common/include/adt/CADTElemClass.hpp b/Common/include/adt/CADTElemClass.hpp index 1fc4ed5a334..2b4142948b7 100644 --- a/Common/include/adt/CADTElemClass.hpp +++ b/Common/include/adt/CADTElemClass.hpp @@ -79,12 +79,6 @@ class CADTElemClass : public CADTBaseClass { * \param[in] globalTree Whether or not a global tree must be built. If false a local ADT is built. */ - - /*! - * \brief Default constructor of the class, disabled. - */ - CADTElemClass() = default; - CADTElemClass(unsigned short val_nDim, vector &val_coor, vector &val_connElem, @@ -93,14 +87,6 @@ class CADTElemClass : public CADTBaseClass { vector &val_elemID, const bool globalTree); - void CreateADT(unsigned short val_nDim, - vector &val_coor, - vector &val_connElem, - vector &val_VTKElem, - vector &val_markerID, - vector &val_elemID, - const bool globalTree); - /*! * \brief Function, which determines the element that contains the given coordinate. * \note This simply forwards the call to the implementation function selecting the right @@ -146,6 +132,7 @@ class CADTElemClass : public CADTBaseClass { FrontLeavesNew[iThread], coor, dist, markerID, elemID, rankID); } +private: /*! * \brief Implementation of DetermineContainingElement. * \note Working variables (first two) passed explicitly for thread safety. @@ -172,9 +159,6 @@ class CADTElemClass : public CADTBaseClass { unsigned long &elemID, int &rankID) const; -private: - - /*! * \brief Function, which checks whether or not the given coordinate is inside the given element. @@ -411,6 +395,9 @@ class CADTElemClass : public CADTBaseClass { su2double &dist2Tria, su2double &r, su2double &s) const; - + /*! + * \brief Default constructor of the class, disabled. + */ + CADTElemClass() = delete; }; \ No newline at end of file diff --git a/Common/include/fem/fem_standard_element.hpp b/Common/include/fem/fem_standard_element.hpp index 518eb509299..13ea78a149b 100644 --- a/Common/include/fem/fem_standard_element.hpp +++ b/Common/include/fem/fem_standard_element.hpp @@ -1014,7 +1014,7 @@ class CFEMStandardElement : public CFEMStandardElementBase { * \brief Function, which makes available the number of DOFs for this standard element. * \return The number of DOFs of this standard element. */ - inline unsigned short GetNDOFs(void) const {return nDOFs;} + inline unsigned short GetNDOFs(void) const {return nDOFs;} /*! * \brief Function, which makes available the polynomial degree for this standard element. @@ -1589,7 +1589,7 @@ class CFEMStandardBoundaryFace : public CFEMStandardElementBase { the residuals of the symmetrizing terms can be computed with a single matrix multiplication. */ - vector matVandermondeFaceInv; /*!< \brief TODO what is this? */ + vector subConnForPlotting; /*!< \brief Local subconnectivity of the high order element. Used for plotting. */ public: @@ -1703,16 +1703,6 @@ class CFEMStandardBoundaryFace : public CFEMStandardElementBase { */ inline unsigned short GetNDOFsFace(void) const {return nDOFsFace;} - /*! - * \brief What is this? - */ - inline const vector* GetRDOFsFace(void) {return &rDOFsFace;} - - /*! - * \brief What is this? - */ - inline const vector* GetSDOFsFace(void) {return &sDOFsFace;} - /*! * \brief Function, which makes available the number of linear subfaces used for plotting, among others. @@ -1771,13 +1761,6 @@ class CFEMStandardBoundaryFace : public CFEMStandardElementBase { su2double WorkEstimateMetisWallFunctions(CConfig *config, const unsigned short nPointsWF); - /*! - * \brief What is this? - */ - void FaceBasisFunctionsAndDerivativesInPoint(const su2double *parCoor, - vector &lagBasis, - vector > &dLagBasis); - private: /*! * \brief Function, which copies the data of the given object into the current object. diff --git a/Common/include/option_structure.hpp b/Common/include/option_structure.hpp index 3b2dc7c4637..5ddb84253d4 100644 --- a/Common/include/option_structure.hpp +++ b/Common/include/option_structure.hpp @@ -70,7 +70,6 @@ enum SU2_COMPONENT { SU2_MSH = 4, /*!< \brief Running the SU2_MSH software. */ SU2_GEO = 5, /*!< \brief Running the SU2_GEO software. */ SU2_SOL = 6, /*!< \brief Running the SU2_SOL software. */ - SU2_INTERP = 7 /*!< \brief Running the SU2_INTERP software. */ }; const unsigned int EXIT_DIVERGENCE = 2; /*!< \brief Exit code (divergence). */ diff --git a/Common/src/CConfig.cpp b/Common/src/CConfig.cpp index a30dcb99a44..759640ff46e 100644 --- a/Common/src/CConfig.cpp +++ b/Common/src/CConfig.cpp @@ -253,44 +253,6 @@ CConfig::CConfig(char case_filename[MAX_STRING_SIZE], CConfig *config) { } } -CConfig::CConfig(char case_filename[MAX_STRING_SIZE], unsigned short val_software, unsigned short val_iZone, unsigned short val_nZone, unsigned short val_nDim, bool verb_high) { - - caseName = PrintingToolbox::split(string(case_filename),'.')[0]; - - base_config = false; - - iZone = val_iZone; - nZone = val_nZone; - - Init(); - - /*--- Parsing the config file ---*/ - - SetConfig_Parsing(case_filename); - - /*--- Set the default values for all of the options that weren't set ---*/ - - SetDefault(); - - /*--- Set number of zone ---*/ - - SetnZone(); - - /*--- Configuration file postprocessing ---*/ - - SetPostprocessing(val_software, val_iZone, val_nDim); - - /*--- Configuration file boundaries/markers setting ---*/ - - SetMarkers(val_software); - - /*--- Configuration file output ---*/ - - if ((rank == MASTER_NODE) && verb_high) - SetOutput(val_software, val_iZone); - -} - SU2_MPI::Comm CConfig::GetMPICommunicator() const { return SU2_Communicator; @@ -2822,15 +2784,6 @@ void CConfig::SetConfig_Options() { /* DESCRIPTION: Size of the edge groups colored for thread parallel edge loops (0 forces the reducer strategy). */ addUnsignedLongOption("EDGE_COLORING_GROUP_SIZE", edgeColorGroupSize, 512); - /* DESCRIPTION: Interpolating solutions between two meshes */ - addBoolOption("INTERPOLATE_SOLUTION", interpolate_solution, false); - - /* DESCRIPTION: Interpolated output file restart flow */ - addStringOption("INTERPOLATED_RESTART_FILENAME", Interpolated_Restart_FileName, string("interpolated_restart_flow.dat")); - - /* DESCRIPTION: Target mesh for solution interpolation */ - addStringOption("TARGET_MESH_FILENAME", Target_Mesh_FileName, string("target_mesh.su2")); - /* END_CONFIG_OPTIONS */ } @@ -3112,7 +3065,6 @@ void CConfig::SetHeader(unsigned short val_software) const{ case SU2_MSH: cout << "| |___/\\___//___| Suite (Mesh Adaptation Code) |" << endl; break; case SU2_GEO: cout << "| |___/\\___//___| Suite (Geometry Definition Code) |" << endl; break; case SU2_SOL: cout << "| |___/\\___//___| Suite (Solution Exporting Code) |" << endl; break; - case SU2_INTERP: cout << "| |___/\\___//___| Suite (Solution Interpolation Code) |" << endl; break; } cout << "| |" << endl; diff --git a/Common/src/adt/CADTElemClass.cpp b/Common/src/adt/CADTElemClass.cpp index 6f11884f61a..271d3b45c96 100644 --- a/Common/src/adt/CADTElemClass.cpp +++ b/Common/src/adt/CADTElemClass.cpp @@ -42,21 +42,6 @@ CADTElemClass::CADTElemClass(unsigned short val_nDim, vector &val_elemID, const bool globalTree) { - - /* Call CreateADT to do the actual work. */ -CreateADT(val_nDim, val_coor, val_connElem, val_VTKElem, - val_markerID, val_elemID, globalTree); -} - -void CADTElemClass::CreateADT(unsigned short val_nDim, - vector &val_coor, - vector &val_connElem, - vector &val_VTKElem, - vector &val_markerID, - vector &val_elemID, - const bool globalTree ) { - - /* Copy the dimension of the problem into nDim. */ nDim = val_nDim; diff --git a/Common/src/fem/fem_standard_element.cpp b/Common/src/fem/fem_standard_element.cpp index b2ffc96e92e..8c1e057e92e 100644 --- a/Common/src/fem/fem_standard_element.cpp +++ b/Common/src/fem/fem_standard_element.cpp @@ -1811,50 +1811,6 @@ su2double CFEMStandardElementBase::ViscousPenaltyParameter( return penParam; } -void CFEMStandardBoundaryFace::FaceBasisFunctionsAndDerivativesInPoint( - const su2double *parCoor, - vector &lagBasis, - vector > &dLagBasis) { - - /* Allocate the memory for the help vectors for computing the Vandermonde - matrices and its derivatives. */ - vector > rPoints(dLagBasis.size(), vector(1)); - vector > VDr(dLagBasis.size(), vector(nDOFsFace)); - - vector V(nDOFsFace); - - /* Copy the parametric coordinates in rPoints, such that the functions to - compute the Vandermonde matrices can be used. */ - for(unsigned long i=0; ifem_interpolation_structure.cpp file. - * \author B. Munguía, J. Mukhopadhaya, E. van der Weide - * \version 6.1.0 "Falcon" - * - * The current SU2 release has been coordinated by the - * SU2 International Developers Society - * with selected contributions from the open-source community. - * - * The main research teams contributing to the current release are: - * - Prof. Juan J. Alonso's group at Stanford University. - * - Prof. Piero Colonna's group at Delft University of Technology. - * - Prof. Nicolas R. Gauger's group at Kaiserslautern University of Technology. - * - Prof. Alberto Guardone's group at Polytechnic University of Milan. - * - Prof. Rafael Palacios' group at Imperial College London. - * - Prof. Vincent Terrapon's group at the University of Liege. - * - Prof. Edwin van der Weide's group at the University of Twente. - * - Lab. of New Concepts in Aeronautics at Tech. Institute of Aeronautics. - * - * Copyright 2012-2018, Francisco D. Palacios, Thomas D. Economon, - * Tim Albring, and the SU2 contributors. - * - * SU2 is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * SU2 is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with SU2. If not, see . - */ - -#pragma once - -#include "../../Common/include/adt/CADTElemClass.hpp" -#include "../../Common/include/CConfig.hpp" -#include "../../Common/include/geometry/CGeometry.hpp" -#include "../../Common/include/geometry/CPhysicalGeometry.hpp" -#include "../../Common/include/fem/fem_geometry_structure.hpp" -#include "../../SU2_CFD/include/output/COutput.hpp" -#include "../../SU2_CFD/include/output/COutputFactory.hpp" -#include "../../SU2_CFD/include/solvers/CSolver.hpp" - -#include "../../SU2_CFD/include/solvers/CEulerSolver.hpp" -#include "../../SU2_CFD/include/solvers/CIncEulerSolver.hpp" -#include "../../SU2_CFD/include/solvers/CNSSolver.hpp" -#include "../../SU2_CFD/include/solvers/CIncNSSolver.hpp" -#include "../../SU2_CFD/include/solvers/CNEMOEulerSolver.hpp" -#include "../../SU2_CFD/include/solvers/CNEMONSSolver.hpp" -#include "../../SU2_CFD/include/solvers/CTurbSASolver.hpp" -#include "../../SU2_CFD/include/solvers/CTurbSSTSolver.hpp" -#include "../../SU2_CFD/include/solvers/CTransLMSolver.hpp" -#include "../../SU2_CFD/include/solvers/CAdjEulerSolver.hpp" -#include "../../SU2_CFD/include/solvers/CAdjNSSolver.hpp" -#include "../../SU2_CFD/include/solvers/CAdjTurbSolver.hpp" -#include "../../SU2_CFD/include/solvers/CHeatSolver.hpp" -#include "../../SU2_CFD/include/solvers/CFEASolver.hpp" -#include "../../SU2_CFD/include/solvers/CTemplateSolver.hpp" -#include "../../SU2_CFD/include/solvers/CDiscAdjSolver.hpp" -#include "../../SU2_CFD/include/solvers/CDiscAdjFEASolver.hpp" -#include "../../SU2_CFD/include/solvers/CFEM_DG_EulerSolver.hpp" -#include "../../SU2_CFD/include/solvers/CFEM_DG_NSSolver.hpp" -#include "../../SU2_CFD/include/solvers/CMeshSolver.hpp" -#include "../../SU2_CFD/include/solvers/CDiscAdjMeshSolver.hpp" -#include "../../SU2_CFD/include/solvers/CBaselineSolver.hpp" -#include "../../SU2_CFD/include/solvers/CBaselineSolver_FEM.hpp" -#include "../../SU2_CFD/include/solvers/CRadP1Solver.hpp" - -using namespace std; - -/*! - * \brief Enumerated type for the solution format. - */ -enum SolutionFormatT -{ - VertexCentered = 1, - CellCentered = 2, - FEM = 3, - DG_FEM = 4 -}; - -/*! - * \class CFEMInterpolationVolElem - * \brief Class to store volume elements for interpolation of FEM solution. - * \version 6.1.0 "Falcon" - */ -class CFEMInterpolationVolElem { -public: - unsigned long mElemID; /*!< \brief ID of this element. */ - unsigned short mVTK_TYPE; /*!< \brief Element type using the VTK convention. */ - unsigned short mNPolyGrid; /*!< \brief Polynomial degree for the geometry of the element. */ - unsigned short mNPolySol; /*!< \brief Polynomial degree for the solution of the element. */ - unsigned short mNDOFsGrid; /*!< \brief Number of DOFs for the geometry of the element. */ - unsigned short mNDOFsSol; /*!< \brief Number of DOFs for the solution of the element. */ - unsigned long mOffsetSolDOFsDG; /*!< \brief Offset for the solution DOFs, only for DG formulation. */ - vector mConnGrid; /*!< \brief The node numbers for the grid DOFs. */ - /*! - * \brief Constructor of the class. - */ - CFEMInterpolationVolElem(void){} - - /*! - * \brief Destructor of the class. - */ - ~CFEMInterpolationVolElem(void){} - - /*! - * \brief Copy constructor. - */ - CFEMInterpolationVolElem(const CFEMInterpolationVolElem &other) {Copy(other);} - - /*! - * \brief Assignment operator. - */ - CFEMInterpolationVolElem& operator=(const CFEMInterpolationVolElem &other) {Copy(other); return (*this);} - - /*! - * \brief Function, which makes available the corner points of all faces of the element. - */ - void GetCornerPointsAllFaces(unsigned short &nFaces, - unsigned short nPointsPerFace[], - unsigned long faceConn[6][4]) const; - - /*! - * \brief Function, which makes available the corner points of the requested face of the element. - */ - void GetCornerPointsFace(const unsigned short faceIDInElement, - unsigned short &nCornerPoints, - unsigned long cornerPoints[]) const; - - /*! - * \brief Function, which sets the data of this element. - */ - void StoreElemData(const unsigned long elemID, - const unsigned short VTK_Type, - const unsigned short nPolyGrid, - const unsigned short nPolySol, - const unsigned short nDOFsGrid, - const unsigned short nDOFsSol, - const unsigned long offsetSolDOFsDG, - const unsigned long *connGrid); - -private: - /*! - * \brief Function, which makes a deep copy. - */ - void Copy(const CFEMInterpolationVolElem &other); -}; - -/*! - * \class CFEMInterpolationFaceOfElem - * \brief Class to store face of element for interpolation of FEM solution. - * \version 6.1.0 "Falcon" - */ -class CFEMInterpolationFaceOfElem { -public: - unsigned short nCornerPoints; /*!< \brief Number of corner points of the face. */ - unsigned long cornerPoints[4]; /*!< \brief ID's of the corner points. */ - unsigned long elemID; /*!< \brief Element ID. */ - unsigned short faceID; /*!< \brief Face ID inside the element ID. */ - - /*! - * \brief Constructor of the class. - */ - CFEMInterpolationFaceOfElem(void); - - /*! - * \brief Destructor of the class. - */ - ~CFEMInterpolationFaceOfElem(void){} - - /*! - * \brief Copy constructor. - */ - CFEMInterpolationFaceOfElem(const CFEMInterpolationFaceOfElem &other){Copy(other);} - - /*! - * \brief Assignment operator. - */ - CFEMInterpolationFaceOfElem& operator=(const CFEMInterpolationFaceOfElem &other){Copy(other); return (*this);} - - /*! - * \brief Less than operator. Needed for the sorting and searching. - */ - bool operator<(const CFEMInterpolationFaceOfElem &other) const; - - /*! - * \brief Member function, which creates a unique numbering for the corner points. A sort in increasing order is OK for this purpose. - */ - void CreateUniqueNumbering(void){sort(cornerPoints, cornerPoints+nCornerPoints);} - -private: - /*! - * \brief Copy function, which copies the data of the given object into the current object. - */ - void Copy(const CFEMInterpolationFaceOfElem &other); -}; - -/*! - * \class CFEMInterpolationSurfElem - * \brief Class to store surface elements for interpolation of FEM solution. - * \version 6.1.0 "Falcon" - */ -class CFEMInterpolationSurfElem { -public: - unsigned short mVTK_TYPE; /*!< \brief Element type using the VTK convention. */ - unsigned short mNPolyGrid; /*!< \brief Polynomial degree for the geometry of the element. */ - unsigned short mNDOFsGrid; /*!< \brief Number of DOFs for the geometry of the element. */ - vector mConnGrid; /*!< \brief The node numbers for the grid DOFs. */ - - /*! - * \brief Constructor of the class. - */ - CFEMInterpolationSurfElem(void){} - - /*! - * \brief Destructor of the class. - */ - ~CFEMInterpolationSurfElem(void){} - - /*! - * \brief Copy constructor. - */ - CFEMInterpolationSurfElem(const CFEMInterpolationSurfElem &other) {Copy(other);} - - /*! - * \brief Assignment operator. - */ - CFEMInterpolationSurfElem& operator=(const CFEMInterpolationSurfElem &other) {Copy(other); return (*this);} - - /*! - * \brief Function, which converts the parametric coordinates of the surface element to the parametric weights of the adjacent volume element. - */ - void ConvertParCoorToVolume(const CFEMInterpolationVolElem *volElem, - const unsigned short faceIDInElement, - su2double *parCoor) const; - - /*! - * \brief Function, which makes available the corner points of the surface element. - */ - void GetCornerPoints(unsigned short &nCornerPoints, - unsigned long cornerPoints[]) const; - - /*! - * \brief Function, which sets the data of this element. - */ - void StoreElemData(const unsigned short VTK_Type, - const unsigned short nPolyGrid, - const unsigned short nDOFsGrid, - const unsigned long *connGrid); - -private: - /*! - * \brief Function, which makes a deep copy. - */ - void Copy(const CFEMInterpolationSurfElem &other); -}; - -/*! - * \class CFEMInterpolationGridZone - * \brief Class to store grid zone information for interpolation of FEM solution. - * \version 6.1.0 "Falcon" - */ -class CFEMInterpolationGridZone { -public: - vector mSurfElems; /*!< \brief Vector of the surface elements. */ - vector mVolElems; /*!< \brief Vector of the volume elements. */ - vector > mCoor; /*!< \brief Vector of vector of the coordinates of the DOFs. - * The first index is the number of spatial dimensions. */ - /*! - * \brief Constructor of the class. - */ - CFEMInterpolationGridZone(void){} - - /*! - * \brief Destructor of the class. - */ - ~CFEMInterpolationGridZone(void){} - - /*! - * \brief Copy constructor. - */ - CFEMInterpolationGridZone(const CFEMInterpolationGridZone &other) {Copy(other);} - - /*! - * \brief Assignment operator. - */ - CFEMInterpolationGridZone& operator=(const CFEMInterpolationGridZone &other) {Copy(other); return (*this);} - - /*! - * \brief Function, which copies data from the SU2 geometry structure to the interpolation zone data structure for a single zone. - */ - void CopySU2GeometryToGrid(CConfig* config, - CGeometry* geometry); - - /*! - * \brief Function, which determines the coordinates for the points to be interpolated. - */ - void DetermineCoorInterpolation(CConfig* config, - vector &coorInterpol, - const SolutionFormatT solFormatWrite); - - /*! - * \brief Function, which makes available the number of dimensions. - */ - unsigned short GetnDim(void) const {return nDim;} - - /*! - * \brief Function, which makes available the number of zones. - */ - size_t GetnZones(void) const {return nZone;} - - /*! - * \brief Function, which makes available the number of grid DOFs. - */ - size_t GetNGridDOFs(void) const {return mCoor[0].size();} - - /*! - * \brief Function, which determines the number of solution DOFs, depending on the given solution format. - */ - size_t GetNSolDOFs(const SolutionFormatT solFormat) const; - - /*! - * \brief Function, which makes available the number of DG solution DOFs. - */ - size_t GetNSolDOFsDG(void) const {return mVolElems.back().mOffsetSolDOFsDG + mVolElems.back().mNDOFsSol;} - - /*! - * \brief Function, which makes available the number of volume elements. - */ - size_t GetNVolumeElem(void) const {return mVolElems.size();} - - /*! - * \brief Function, which determines whether or not high order elements are present in the zone. - */ - bool HighOrderElementsInZone(void) const; - -private: - unsigned short nDim, /*!< \brief Number of spatial dimensions. */ - nZone; /*!< \brief Number of zones. */ - - /*! - * \brief Function, which makes a deep copy. - */ - void Copy(const CFEMInterpolationGridZone &other); - - /*! - * \brief Function, which determines the information for the given SU2 element type. - */ - void DetermineElementInfo(int su2ElemType, - int &VTKType, - int &nPolyGrid, - int &nPolySol, - int &nDOFsGrid, - int &nDOFsSol); - - /*! - * \brief Function, which determines the number of DOFs for the given element type and polynomial degree. - */ - int DetermineNDOFs(const int VTKType, - const int nPoly); - -}; - -/*! - * \class CFEMInterpolationGrid - * \brief Class to store grid for interpolation of the FEM solution. - * \version 6.1.0 "Falcon" - */ -class CFEMInterpolationGrid { -public: - /*! - * \brief Constructor of the class. - */ - CFEMInterpolationGrid(void); - - /*! - * \overload - * \brief Constructor of the class. - * \param[in] config - Definition of the particular problem. - * \param[in] geometry - The grid for interpolation. - */ - CFEMInterpolationGrid(CConfig** config, - CGeometry**** geometry, - unsigned short mnZone, - const SolutionFormatT mnSolutionFormat); - - /*! - * \brief Destructor of the class. - */ - ~CFEMInterpolationGrid(void); - - /*! - * \brief Function, which determines the coordinates for the points to be interpolated. - */ - void DetermineCoorInterpolation(CConfig** config, - vector > &coorInterpol, - const SolutionFormatT solFormatWrite); - - /*! - * \brief Function, which determines the solution format from the grid information and the given number of solution DOFs. - */ - void DetermineSolutionFormat(const int nSolDOFs); - - /*! - * \brief Function, which makes available the number of dimensions. - */ - unsigned short GetnDim(void) const {return nDim;} - - /*! - * \brief Function, which makes available the number of zones. - */ - size_t GetnZones(void) const {return nZone;} - - /*! - * \brief Make available the given zone as a const pointer. - */ - const CFEMInterpolationGridZone *GetGridZone(const unsigned short zone) const {return &mGridZones[zone];} - - /*! - * \brief Make available the solution format of this grid. - */ - SolutionFormatT GetSolutionFormat(void) const {return mSolutionFormat;} - -private: - unsigned short nDim, /*!< \brief Number of spatial dimensions. */ - nZone; /*!< \brief Number of zones. */ - vector mGridZones; /*!< \brief Vector of grid zones. */ - SolutionFormatT mSolutionFormat; /*!< \brief The solution format of the corresponding solution. */ -}; - -/*! - * \class CFEMInterpolationSol - * \brief Class to perform interpolation of the FEM solution. - * \version 6.1.0 "Falcon" - */ -class CFEMInterpolationSol { -public: - /*! - * \brief Constructor of the class. - */ - CFEMInterpolationSol(void); - - /*! - * \overload - * \brief Constructor of the class. - * \param[in] config - Definition of the particular problem. - * \param[in] geometry - The grid for interpolation. - * \param[in] solution - The solution structure for interpolation. - */ - CFEMInterpolationSol(CConfig** config, - CGeometry**** geometry, - CSolver***** solution, - unsigned short nZone); - - /*! - * \brief Destructor of the class. - */ - ~CFEMInterpolationSol(void); - - /*! - * \brief Make available the number of variables in the solution file. - * \return Number of variables in the solution file. - */ - size_t GetnVar(void) const {return nVar;} - - /*! - * \brief Main function for the interpolation of the given coordinates in the given grid and solution. - */ - void InterpolateSolution(CConfig** config, - const vector > &coorInterpol, - const CFEMInterpolationGrid *inputGrid, - const CFEMInterpolationSol *inputSol, - const CFEMInterpolationGrid *outputGrid); - - /*! - * \brief Make available the solution DOFs. - * \return Number of DOFs in the solution. - */ - const vector > &GetSolDOFs(void) const {return mSolDOFs;} - - /*! - * \brief Function, which copies data from the interpolation sol data structure to the SU2 solution structure. - */ - void CopySolToSU2Solution(CConfig** config, - CGeometry**** geometry, - CSolver***** solution, - unsigned short nZone); -private: - unsigned short nVar; /*!< \brief Number of variables in the solution. */ - vector > mSolDOFs; /*!< \brief Double vector, which contains the solution variables in the DOFs. */ - - /*! - * \brief Function, which applies a curvature correction to the coordinates to obtain a better representation of these coordinates on the target grid. - */ - void ApplyCurvatureCorrection(CConfig* config, - const unsigned short zoneID, - const unsigned short nDim, - const CFEMInterpolationGridZone *inputGridZone, - const CFEMInterpolationGridZone *outputGridZone, - const vector &coorOriginal, - vector &coorCorrected); - - /*! - * \brief Function, which builds the ADT of a surface grid. - */ - void BuildSurfaceADT(CConfig* config, - const CFEMInterpolationGridZone *gridZone, - CADTElemClass &surfaceADT, - vector &standardBoundaryFacesGrid, - vector &standardBoundaryFacesSol, - vector &indInStandardBoundaryFaces, - vector &adjElemID, - vector &faceIDInElement); - - /*! - * \brief Function, which performs the containment search in a high order element. - */ - void HighOrderContainmentSearch(const su2double *coor, - const unsigned long parElem, - const unsigned short subElem, - const su2double *weightsSubElem, - CFEMStandardElement *standardElementGrid, - const CFEMInterpolationVolElem *volElem, - const vector > &coorGrid, - su2double *parCoor); - - /*! - * \brief Function, which performs the minimum distance search for a high order surface element. - */ - void HighOrderMinDistanceSearch(const su2double *coor, - const unsigned long parElem, - const unsigned short subElem, - const su2double *weightsSubElem, - CFEMStandardBoundaryFace *standardBoundaryFaceGrid, - const CFEMInterpolationSurfElem *surfElem, - const vector > &coorGrid, - su2double *parCoor, - su2double *wallCoor); - - /*! - * \brief Function, which carries out the actual interpolation of the solution. - */ - void SolInterpolate(CFEMStandardElement *standardElementSol, - const CFEMInterpolationSol *inputSol, - const unsigned long zoneOffsetInputSol, - const CFEMInterpolationVolElem *volElem, - const SolutionFormatT solFormatInput, - const su2double *parCoor, - vector &solDOF); - - /*! - * \brief Function, which carries out the surface minimum distance search for the interpolation. - */ - void SurfaceInterpolationSolution(CConfig* config, - const unsigned short zoneID, - const vector &coorInterpol, - const vector &coorCorrected, - const CFEMInterpolationGridZone *gridZone, - const CFEMInterpolationSol *inputSol, - const unsigned long zoneOffsetInputSol, - const unsigned long zoneOffsetOutputSol, - const SolutionFormatT solFormatInput, - const vector &pointsMinDistSearch, - vector &standardElementsSol, - const vector &indInStandardElements); - - /*! - * \brief Function, which carries out the volume containment search for the interpolation. - */ - void VolumeInterpolationSolution(CConfig* config, - const unsigned short zoneID, - const vector &coorInterpol, - const vector &coorCorrected, - const CFEMInterpolationGridZone *gridZone, - const CFEMInterpolationSol *inputSol, - const unsigned long zoneOffsetInputSol, - const unsigned long zoneOffsetOutputSol, - const SolutionFormatT solFormatInput, - vector &pointsSearchFailed, - vector &standardElementsGrid, - vector &standardElementsSol, - vector &indInStandardElements); -}; - -/*! - * \class CFEMInterpolationDriver - * \brief Class to drive interpolation of the FEM solution. - * \version 6.1.0 "Falcon" - */ -class CFEMInterpolationDriver { -private: - int rank, /*!< \brief MPI Rank. */ - size; /*!< \brief MPI Size. */ - - COutput *output; /*!< \brief Pointer to the COutput class. */ - CGeometry ****input_geometry_container; /*!< \brief Input geometry for which there is a solution */ - CGeometry ****output_geometry_container; /*!< \brief Output geometry that solution is going to be interpolated onto */ - CSolver *****input_solver_container; /*!< \brief Input solution that needs to be interpolated onto new mesh */ - CSolver *****output_solver_container; /*!< \brief Interpolated solution on new mesh */ - CConfig **input_config_container; /*!< \brief Definition of the input problem. */ - CConfig **output_config_container; /*!< \brief Definition of the output problem. */ - CConfig *driver_config; /*!< \brief Definition of the driver configuration. */ - char* config_file_name; /*!< \brief Configuration file name of the problem.*/ - - bool fsi, /*!< \brief FSI simulation flag.*/ - input_fem_solver, /*!< \brief FEM fluid solver simulation flag for input simulation */ - output_fem_solver; /*!< \brief FEM fluid solver simulation flag for output simulation */ - - unsigned short iZone, /*!< \brief Iterator on zones.*/ - iSol, /*!< \brief Iterator on solutions.*/ - nZone, /*!< \brief Total number of zones in the problem. */ - nDim, /*!< \brief Number of dimensions.*/ - iInst, /*!< \brief Iterator on instance levels.*/ - *nInst; /*!< \brief Total number of instances in the problem (per zone). */ - - unsigned long DOFsPerPoint; /*!< \brief Number of unknowns at each vertex, i.e., number of equations solved. */ - - CFEMInterpolationGrid *input_grid, /*!< \brief Generalized input grid */ - *output_grid; /*!< \brief Generalized output grid */ - CFEMInterpolationSol *input_solution, /*!< \brief Generalized input solution */ - *output_solution; /*!< \brief Interpolated output solution */ - - -public: - - /*! - * \brief Constructor of the class. - * \param[in] confFile - Configuration file name. - * \param[in] val_nZone - Total number of zones. - * \param[in] val_nDim - Number of dimensions. - * \param[in] val_periodic - Bool for periodic BCs. - * \param[in] MPICommunicator - MPI communicator for SU2. - */ - CFEMInterpolationDriver(char* confFile, - unsigned short val_nZone, - unsigned short val_nDim, - bool val_periodic, - SU2_Comm MPICommunicator); - - /*! - * \brief Destructor of the class. - */ - ~CFEMInterpolationDriver(void); - - /*! - * \brief Read in the config and mesh files. - */ - void Input_Preprocessing(CConfig **config_container, CGeometry ****geometry_container, bool val_periodic); - - /*! - * \brief Construction of the edge-based data structure and the multigrid structure. - */ - void Geometrical_Preprocessing(CConfig **config_container, CGeometry ****geometry_container); - - /*! - * \brief Do the geometrical preprocessing for the DG FEM solver. - */ - void Geometrical_Preprocessing_DGFEM(CConfig **config_container, CGeometry ****geometry_container); - - /*! - * \brief Deallocation of solution classes. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void Solver_Preprocessing(CSolver ****solver_container, CGeometry ***geometry, CConfig *config, unsigned short val_iInst); - - /*! - * \brief Restart of the solvers from the restart files. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void Solver_Restart(CSolver ****solver_container, CGeometry ***geometry, CConfig *config, bool update_geo, unsigned short val_iInst); - - /*! - * \brief Interpolation of solution from input geometry and solution to output geometry and solution - */ - void Interpolate(void); - - /*! - * \brief Deallocation of solution classes. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void Solver_Postprocessing(CSolver ****solver_container, CGeometry ***geometry, CConfig *config, unsigned short val_iInst); - - /*! - * \brief Output the solution in solution file. - */ - void Output(); - - /*! - * \brief Definition and allocation of all solution classes. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - */ - void Solver_Deletion(CSolver ****solver_container, CConfig *config, unsigned short val_iInst); - - /*! - * \brief Deallocation routine - */ - void Postprocessing(); - -}; diff --git a/SU2_CFD/obj/Makefile.am b/SU2_CFD/obj/Makefile.am index bcfe31808d4..82fec33ab91 100644 --- a/SU2_CFD/obj/Makefile.am +++ b/SU2_CFD/obj/Makefile.am @@ -214,8 +214,7 @@ libSU2Core_sources = ../src/definition_structure.cpp \ ../src/variables/CAdjEulerVariable.cpp \ ../src/variables/CDiscAdjVariable.cpp \ ../src/variables/CIncNSVariable.cpp \ - ../src/variables/CEulerVariable.cpp \ - ../src/fem_interpolation_structure.cpp + ../src/variables/CEulerVariable.cpp su2_cfd_sources = \ ../src/SU2_CFD.cpp diff --git a/SU2_CFD/src/fem_interpolation_structure.cpp b/SU2_CFD/src/fem_interpolation_structure.cpp deleted file mode 100644 index 31013620193..00000000000 --- a/SU2_CFD/src/fem_interpolation_structure.cpp +++ /dev/null @@ -1,3902 +0,0 @@ -/*! - * \file fem_interpolation_structure.cpp - * \brief Functions for interpolation for the FEM solver. - * \author B. Munguía, J. Mukhopadhaya, E. van der Weide - * \version 6.1.0 "Falcon" - * - * The current SU2 release has been coordinated by the - * SU2 International Developers Society - * with selected contributions from the open-source community. - *f - * The main research teams contributing to the current release are: - * - Prof. Juan J. Alonso's group at Stanford University. - * - Prof. Piero Colonna's group at Delft University of Technology. - * - Prof. Nicolas R. Gauger's group at Kaiserslautern University of Technology. - * - Prof. Alberto Guardone's group at Polytechnic University of Milan. - * - Prof. Rafael Palacios' group at Imperial College London. - * - Prof. Vincent Terrapon's group at the University of Liege. - * - Prof. Edwin van der Weide's group at the University of Twente. - * - Lab. of New Concepts in Aeronautics at Tech. Institute of Aeronautics. - * - * Copyright 2012-2018, Francisco D. Palacios, Thomas D. Economon, - * Tim Albring, and the SU2 contributors. - * - * SU2 is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * SU2 is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with SU2. If not, see . - */ - -#include "../include/fem_interpolation_structure.hpp" - -CFEMInterpolationDriver::CFEMInterpolationDriver(char* confFile, - unsigned short val_nZone, - unsigned short val_nDim, - bool val_periodic, - SU2_Comm MPICommunicator):config_file_name(confFile), nZone(val_nZone), nDim(val_nDim), fsi(false), input_fem_solver(false), output_fem_solver(false) { - - char zone_file_name[MAX_STRING_SIZE]; - - SU2_MPI::SetComm(MPICommunicator); - - rank = SU2_MPI::GetRank(); - size = SU2_MPI::GetSize(); - - input_geometry_container = NULL; - output_geometry_container = NULL; - input_solver_container = NULL; - output_solver_container = NULL; - input_config_container = NULL; - output_config_container = NULL; - output = NULL; - nInst = NULL; - - /*--- Definition of the containers for all possible zones. ---*/ - - input_geometry_container = new CGeometry***[nZone]; - output_geometry_container = new CGeometry***[nZone]; - input_solver_container = new CSolver****[nZone]; - output_solver_container = new CSolver****[nZone]; - input_config_container = new CConfig*[nZone]; - output_config_container = new CConfig*[nZone]; - nInst = new unsigned short[nZone]; - - for (iZone = 0; iZone < nZone; iZone++) { - input_solver_container[iZone] = NULL; - output_solver_container[iZone] = NULL; - input_geometry_container[iZone] = NULL; - output_geometry_container[iZone] = NULL; - input_config_container[iZone] = NULL; - output_config_container[iZone] = NULL; - nInst[iZone] = 1; - } - - /*--- Initialize the configuration of the driver ---*/ - - driver_config = new CConfig(config_file_name, SU2_CFD, ZONE_0, nZone, nDim, false); - - /*--- Loop over all zones to initialize the various classes. In most - cases, nZone is equal to one. This represents the solution of a partial - differential equation on a single block, unstructured mesh. ---*/ - - for (iZone = 0; iZone < nZone; iZone++) { - - /*--- Definition of the configuration option class for all zones. In this - constructor, the input configuration file is parsed and all options are - read and stored. ---*/ - - if (driver_config->GetnConfigFiles() > 0) { - strcpy(zone_file_name, driver_config->GetConfigFilename(iZone).c_str()); - input_config_container[iZone] = new CConfig(zone_file_name, SU2_CFD, iZone, nZone, nDim, true); - output_config_container[iZone] = new CConfig(zone_file_name, SU2_CFD, iZone, nZone, nDim, false); - } - else{ - input_config_container[iZone] = new CConfig(config_file_name, SU2_CFD, iZone, nZone, nDim, true); - output_config_container[iZone] = new CConfig(config_file_name, SU2_CFD, iZone, nZone, nDim, false); - } - - /*--- Set the MPI communicator ---*/ - - input_config_container[iZone]->SetMPICommunicator(MPICommunicator); - output_config_container[iZone]->SetMPICommunicator(MPICommunicator); - - /* --- For the output config, disable restart reading and change grid file to target mesh ---*/ - - input_config_container[iZone]->SetRestart(true); - output_config_container[iZone]->SetRestart(false); - output_config_container[iZone]->SetMesh_FileName(output_config_container[iZone]->GetTarget_Mesh_FileName()); - - input_config_container[iZone]->SetMGLevels(0); - output_config_container[iZone]->SetMGLevels(0); - - } - - /*--- Set the multizone part of the problem. ---*/ - if (driver_config->GetnConfigFiles() > 0){ - for (iZone = 0; iZone < nZone; iZone++) { - /*--- Set the interface markers for multizone ---*/ - input_config_container[iZone]->SetMultizone(driver_config, input_config_container); - output_config_container[iZone]->SetMultizone(driver_config, output_config_container); - } - } - - /*--- Preprocessing of the config and mesh files. In this routine, the config file is read - and it is determined whether a problem is single physics or multiphysics. . ---*/ - - Input_Preprocessing(input_config_container, input_geometry_container, val_periodic); - Input_Preprocessing(output_config_container, output_geometry_container, val_periodic); - - /*--- Preprocessing of the geometry for all zones. In this routine, the edge- - based data structure is constructed, i.e. node and cell neighbors are - identified and linked, and face areas are computed ---*/ - - if (rank == MASTER_NODE) - cout << endl <<"---------------------- Input Geometry Preprocessing ---------------------" << endl; - - /*--- Determine whether or not the FEM solver is used, which decides the - type of geometry classes that are instantiated. Only adapted for single-zone problems ---*/ - input_fem_solver = ((input_config_container[ZONE_0]->GetKind_Solver() == FEM_EULER) || - (input_config_container[ZONE_0]->GetKind_Solver() == FEM_NAVIER_STOKES) || - (input_config_container[ZONE_0]->GetKind_Solver() == FEM_RANS) || - (input_config_container[ZONE_0]->GetKind_Solver() == FEM_LES) || - (input_config_container[ZONE_0]->GetKind_Solver() == DISC_ADJ_FEM_EULER) || - (input_config_container[ZONE_0]->GetKind_Solver() == DISC_ADJ_FEM_NS) || - (input_config_container[ZONE_0]->GetKind_Solver() == DISC_ADJ_FEM_RANS)); - - if( input_fem_solver ) { - switch( input_config_container[ZONE_0]->GetKind_FEM_Flow() ) { - case DG: { - Geometrical_Preprocessing_DGFEM(input_config_container, input_geometry_container); - break; - } - } - } - else { - Geometrical_Preprocessing(input_config_container, input_geometry_container); - } - - for (iZone = 0; iZone < nZone; iZone++) { - - for (iInst = 0; iInst < nInst[iZone]; iInst++){ - - /*--- Computation of positive surface area in the z-plane which is used for - the calculation of force coefficient (non-dimensionalization). ---*/ - - input_geometry_container[iZone][iInst][MESH_0]->SetPositive_ZArea(input_config_container[iZone]); - - } - - } - - if (rank == MASTER_NODE) - cout << endl <<"---------------------- Output Geometry Preprocessing --------------------" << endl; - - /*--- Determine whether or not the FEM solver is used, which decides the - type of geometry classes that are instantiated. Only adapted for single-zone problems ---*/ - output_fem_solver = ((output_config_container[ZONE_0]->GetKind_Solver() == FEM_EULER) || - (output_config_container[ZONE_0]->GetKind_Solver() == FEM_NAVIER_STOKES) || - (output_config_container[ZONE_0]->GetKind_Solver() == FEM_RANS) || - (output_config_container[ZONE_0]->GetKind_Solver() == FEM_LES) || - (output_config_container[ZONE_0]->GetKind_Solver() == DISC_ADJ_FEM_EULER) || - (output_config_container[ZONE_0]->GetKind_Solver() == DISC_ADJ_FEM_NS) || - (output_config_container[ZONE_0]->GetKind_Solver() == DISC_ADJ_FEM_RANS)); - - if( output_fem_solver ) { - switch( output_config_container[ZONE_0]->GetKind_FEM_Flow() ) { - case DG: { - Geometrical_Preprocessing_DGFEM(output_config_container, output_geometry_container); - break; - } - } - } - else { - Geometrical_Preprocessing(output_config_container, output_geometry_container); - } - - for (iZone = 0; iZone < nZone; iZone++) { - - for (iInst = 0; iInst < nInst[iZone]; iInst++){ - - /*--- Computation of positive surface area in the z-plane which is used for - the calculation of force coefficient (non-dimensionalization). ---*/ - - output_geometry_container[iZone][iInst][MESH_0]->SetPositive_ZArea(output_config_container[iZone]); - - } - - } - - - /*--- Definition of the solver class: solver_container[#ZONES][#INSTANCES][#MG_GRIDS][#EQ_SYSTEMS]. - The solver classes are specific to a particular set of governing equations, - and they contain the subroutines with instructions for computing each spatial - term of the PDE, i.e. loops over the edges to compute convective and viscous - fluxes, loops over the nodes to compute source terms, and routines for - imposing various boundary condition type for the PDE. ---*/ - - for (iZone = 0; iZone < nZone; iZone++) { - - if (rank == MASTER_NODE) - cout << endl <<"---------------------- Input Solver Preprocessing -----------------------" << endl; - - input_solver_container[iZone] = new CSolver*** [nInst[iZone]]; - - - for (iInst = 0; iInst < nInst[iZone]; iInst++){ - input_solver_container[iZone][iInst] = NULL; - input_solver_container[iZone][iInst] = new CSolver** [MESH_0+1]; - input_solver_container[iZone][iInst][MESH_0] = NULL; - input_solver_container[iZone][iInst][MESH_0] = new CSolver* [MAX_SOLS]; - for (iSol = 0; iSol < MAX_SOLS; iSol++) - input_solver_container[iZone][iInst][MESH_0][iSol] = NULL; - - Solver_Preprocessing(input_solver_container[iZone], input_geometry_container[iZone], - input_config_container[iZone], iInst); - - } // End of loop over iInst - - } - - for (iZone = 0; iZone < nZone; iZone++) { - - if (rank == MASTER_NODE) - cout << endl <<"---------------------- Output Solver Preprocessing ----------------------" << endl; - - output_solver_container[iZone] = new CSolver*** [nInst[iZone]]; - - - for (iInst = 0; iInst < nInst[iZone]; iInst++){ - output_solver_container[iZone][iInst] = NULL; - output_solver_container[iZone][iInst] = new CSolver** [MESH_0+1]; - output_solver_container[iZone][iInst][MESH_0] = NULL; - output_solver_container[iZone][iInst][MESH_0] = new CSolver* [MAX_SOLS]; - for (iSol = 0; iSol < MAX_SOLS; iSol++) - output_solver_container[iZone][iInst][MESH_0][iSol] = NULL; - - Solver_Preprocessing(output_solver_container[iZone], output_geometry_container[iZone], - output_config_container[iZone], iInst); - - } // End of loop over iInst - - } - - /*--- Definition of the output class (one for all zones). The output class - manages the writing of all restart, volume solution, surface solution, - surface comma-separated value, and convergence history files (both in serial - and in parallel). ---*/ - - output = COutputFactory::CreateOutput(NEMO_NAVIER_STOKES, input_config_container[ZONE_0],nDim); - - input_grid = NULL; - output_grid = NULL; - input_solution = NULL; - output_solution = NULL; - -} - -void CFEMInterpolationDriver::Postprocessing() { - - if (rank == MASTER_NODE) - cout << endl <<"--------------------- Interpolation Postprocessing ----------------------" << endl; - - for (iZone = 0; iZone < nZone; iZone++) { - for (iInst = 0; iInst < nInst[iZone]; iInst++){ - - Solver_Deletion(input_solver_container[iZone], - input_config_container[iZone], - iInst); - Solver_Deletion(output_solver_container[iZone], - output_config_container[iZone], - iInst); - } - - delete [] input_solver_container[iZone]; - delete [] output_solver_container[iZone]; - } - delete [] input_solver_container; - delete [] output_solver_container; - if (rank == MASTER_NODE) cout << "Deleted CSolver containers." << endl; - - - for (iZone = 0; iZone < nZone; iZone++) { - if (input_geometry_container[iZone] != NULL) { - for (iInst = 0; iInst < nInst[iZone]; iInst++){ - if (input_geometry_container[iZone][iInst][MESH_0] != NULL) delete input_geometry_container[iZone][iInst][MESH_0]; - if (input_geometry_container[iZone][iInst] != NULL) delete [] input_geometry_container[iZone][iInst]; - } - delete [] input_geometry_container[iZone]; - } - } - delete [] input_geometry_container; - - for (iZone = 0; iZone < nZone; iZone++) { - if (output_geometry_container[iZone] != NULL) { - for (iInst = 0; iInst < nInst[iZone]; iInst++){ - if (output_geometry_container[iZone][iInst][MESH_0] != NULL) delete output_geometry_container[iZone][iInst][MESH_0]; - if (output_geometry_container[iZone][iInst] != NULL) delete [] output_geometry_container[iZone][iInst]; - } - delete [] output_geometry_container[iZone]; - } - } - delete [] output_geometry_container; - if (rank == MASTER_NODE) cout << "Deleted CGeometry containers." << endl; - - /*--- Deallocate config container ---*/ - if (input_config_container!= NULL) { - for (iZone = 0; iZone < nZone; iZone++) { - if (input_config_container[iZone] != NULL) { - delete input_config_container[iZone]; - } - } - delete [] input_config_container; - } - if (output_config_container!= NULL) { - for (iZone = 0; iZone < nZone; iZone++) { - if (output_config_container[iZone] != NULL) { - delete output_config_container[iZone]; - } - } - delete [] output_config_container; - } - - if (rank == MASTER_NODE) cout << "Deleted CConfig containers." << endl; - - if (nInst != NULL) delete [] nInst; - if (rank == MASTER_NODE) cout << "Deleted nInst container." << endl; - - - // if (input_grid != NULL) delete [] input_grid; - // if (output_grid != NULL) delete [] output_grid; - // if (input_solution != NULL) delete [] input_solution; - // if (output_solution != NULL) delete [] output_solution; - // if (rank == MASTER_NODE) cout << "Deleted interpolation containers." << endl; - - - /*--- Deallocate output container ---*/ - if (output!= NULL) delete output; - if (rank == MASTER_NODE) cout << "Deleted COutput class." << endl; - - if (rank == MASTER_NODE) cout << "-------------------------------------------------------------------------" << endl; - -} - -void CFEMInterpolationDriver::Input_Preprocessing(CConfig **config_container, CGeometry ****geometry_container, bool val_periodic) { - - bool fem_solver = false; - - for (iZone = 0; iZone < nZone; iZone++) { - - /*--- Determine whether or not the FEM solver is used, which decides the - type of geometry classes that are instantiated. ---*/ - fem_solver = ((config_container[iZone]->GetKind_Solver() == FEM_EULER) || - (config_container[iZone]->GetKind_Solver() == FEM_NAVIER_STOKES) || - (config_container[iZone]->GetKind_Solver() == FEM_RANS) || - (config_container[iZone]->GetKind_Solver() == FEM_LES) || - (config_container[iZone]->GetKind_Solver() == DISC_ADJ_FEM_EULER) || - (config_container[iZone]->GetKind_Solver() == DISC_ADJ_FEM_NS) || - (config_container[iZone]->GetKind_Solver() == DISC_ADJ_FEM_RANS)); - - /*--- Read the number of instances for each zone ---*/ - - nInst[iZone] = config_container[iZone]->GetnTimeInstances(); - - geometry_container[iZone] = new CGeometry** [nInst[iZone]]; - - for (iInst = 0; iInst < nInst[iZone]; iInst++){ - - config_container[iZone]->SetiInst(iInst); - - /*--- Definition of the geometry class to store the primal grid in the - partitioning process. ---*/ - - CGeometry *geometry_aux = nullptr; - - /*--- All ranks process the grid and call ParMETIS for partitioning ---*/ - - geometry_aux = new CPhysicalGeometry(config_container[iZone], iZone, nZone); - - /*--- Color the initial grid and set the send-receive domains (ParMETIS) ---*/ - - if ( fem_solver ) geometry_aux->SetColorFEMGrid_Parallel(config_container[iZone]); - else geometry_aux->SetColorGrid_Parallel(config_container[iZone]); - - /*--- Allocate the memory of the current domain, and divide the grid - between the ranks. ---*/ - - geometry_container[iZone][iInst] = NULL; - geometry_container[iZone][iInst] = new CGeometry *[MESH_0+1]; - geometry_container[iZone][iInst][MESH_0] = NULL; - - - if( fem_solver ) { - switch( config_container[iZone]->GetKind_FEM_Flow() ) { - case DG: { - geometry_container[iZone][iInst][MESH_0] = new CMeshFEM_DG(geometry_aux, config_container[iZone]); - break; - } - - default: { - SU2_MPI::Error("Unknown FEM flow solver.", CURRENT_FUNCTION); - break; - } - } - } - else { - - /*--- Until we finish the new periodic BC implementation, use the old - partitioning routines for cases with periodic BCs. The old routines - will be entirely removed eventually in favor of the new methods. ---*/ - -// if (val_periodic) { - geometry_container[iZone][iInst][MESH_0] = new CPhysicalGeometry(geometry_aux, config_container[iZone]); -// } else { -// geometry_container[iZone][iInst][MESH_0] = new CPhysicalGeometry(geometry_aux, config_container[iZone]); -// } - } - - /*--- Deallocate the memory of geometry_aux and solver_aux ---*/ - - delete geometry_aux; - - /*--- Add the Send/Receive boundaries ---*/ - geometry_container[iZone][iInst][MESH_0]->SetSendReceive(config_container[iZone]); - - /*--- Add the Send/Receive boundaries ---*/ - geometry_container[iZone][iInst][MESH_0]->SetBoundaries(config_container[iZone]); - - /*--- Create the point-to-point MPI communication structures for the fvm solver. ---*/ - if (!fem_solver) geometry_container[iZone][iInst][MESH_0]->PreprocessP2PComms(geometry_container[iZone][iInst][MESH_0], config_container[iZone]); - } - - } - -} - -void CFEMInterpolationDriver::Geometrical_Preprocessing(CConfig **config_container, CGeometry ****geometry_container) { - - bool fea = false; - - for (iZone = 0; iZone < nZone; iZone++) { - - fea = ((config_container[iZone]->GetKind_Solver() == FEM_ELASTICITY) || - (config_container[iZone]->GetKind_Solver() == DISC_ADJ_FEM)); - - for (iInst = 0; iInst < nInst[iZone]; iInst++){ - - /*--- Compute elements surrounding points, points surrounding points ---*/ - - /*--- Compute elements surrounding points, points surrounding points ---*/ - - if (rank == MASTER_NODE) cout << "Setting point connectivity." << endl; - geometry_container[iZone][iInst][MESH_0]->SetPoint_Connectivity(); - - /*--- Renumbering points using Reverse Cuthill McKee ordering ---*/ - - if (rank == MASTER_NODE) cout << "Renumbering points (Reverse Cuthill McKee Ordering)." << endl; - geometry_container[iZone][iInst][MESH_0]->SetRCM_Ordering(config_container[iZone]); - - /*--- recompute elements surrounding points, points surrounding points ---*/ - - if (rank == MASTER_NODE) cout << "Recomputing point connectivity." << endl; - geometry_container[iZone][iInst][MESH_0]->SetPoint_Connectivity(); - - /*--- Compute elements surrounding elements ---*/ - - if (rank == MASTER_NODE) cout << "Setting element connectivity." << endl; - geometry_container[iZone][iInst][MESH_0]->SetElement_Connectivity(); - - /*--- Check the orientation before computing geometrical quantities ---*/ - - geometry_container[iZone][iInst][MESH_0]->SetBoundVolume(); - if (config_container[iZone]->GetReorientElements()) { - if (rank == MASTER_NODE) cout << "Checking the numerical grid orientation." << endl; - geometry_container[iZone][iInst][MESH_0]->Check_IntElem_Orientation(config_container[iZone]); - geometry_container[iZone][iInst][MESH_0]->Check_BoundElem_Orientation(config_container[iZone]); - } - - /*--- Create the edge structure ---*/ - - if (rank == MASTER_NODE) cout << "Identifying edges and vertices." << endl; - geometry_container[iZone][iInst][MESH_0]->SetEdges(); - geometry_container[iZone][iInst][MESH_0]->SetVertex(config_container[iZone]); - - /*--- Compute cell center of gravity ---*/ - - if ((rank == MASTER_NODE) && (!fea)) cout << "Computing centers of gravity." << endl; - geometry_container[iZone][iInst][MESH_0]->SetCoord_CG(); - - /*--- Create the control volume structures ---*/ - - if ((rank == MASTER_NODE) && (!fea)) cout << "Setting the control volume structure." << endl; - geometry_container[iZone][iInst][MESH_0]->SetControlVolume(config_container[iZone], ALLOCATE); - geometry_container[iZone][iInst][MESH_0]->SetBoundControlVolume(config_container[iZone], ALLOCATE); - - /*--- Compute the max length. ---*/ - - if ((rank == MASTER_NODE) && (!fea)) cout << "Finding max control volume width." << endl; - geometry_container[iZone][iInst][MESH_0]->SetMaxLength(config_container[iZone]); - - /*--- Visualize a dual control volume if requested ---*/ - - if ((config_container[iZone]->GetVisualize_CV() >= 0) && - (config_container[iZone]->GetVisualize_CV() < (long)geometry_container[iZone][iInst][MESH_0]->GetnPointDomain())) - geometry_container[iZone][iInst][MESH_0]->VisualizeControlVolume(config_container[iZone], UPDATE); - - /*--- Identify closest normal neighbor ---*/ - - if (rank == MASTER_NODE) cout << "Searching for the closest normal neighbors to the surfaces." << endl; - geometry_container[iZone][iInst][MESH_0]->FindNormal_Neighbor(config_container[iZone]); - - /*--- Store the global to local mapping. ---*/ - - if (rank == MASTER_NODE) cout << "Storing a mapping from global to local point index." << endl; - geometry_container[iZone][iInst][MESH_0]->SetGlobal_to_Local_Point(); - - /*--- Compute the surface curvature ---*/ - - if ((rank == MASTER_NODE) && (!fea)) cout << "Compute the surface curvature." << endl; - geometry_container[iZone][iInst][MESH_0]->ComputeSurf_Curvature(config_container[iZone]); - - /*--- Check for periodicity and disable MG if necessary. ---*/ - - if (rank == MASTER_NODE) cout << "Checking for periodicity." << endl; - geometry_container[iZone][iInst][MESH_0]->Check_Periodicity(config_container[iZone]); - - } - - } - -} - -void CFEMInterpolationDriver::Geometrical_Preprocessing_DGFEM(CConfig **config_container, CGeometry ****geometry_container) { - - //*--- Loop over the number of zones of the fine grid. ---*/ - - for(unsigned short iZone = 0; iZone < nZone; iZone++) { - - /*--- Loop over the time instances of this zone. ---*/ - for(unsigned short iInst = 0; iInst < nInst[iZone]; iInst++) { - - /*--- Carry out a dynamic cast to CMeshFEM_DG, such that it is not needed to - define all virtual functions in the base class CGeometry. ---*/ - CMeshFEM_DG *DGMesh = dynamic_cast(geometry_container[iZone][iInst][MESH_0]); - - /*--- Determine the standard elements for the volume elements. ---*/ - if (rank == MASTER_NODE) cout << "Creating standard volume elements." << endl; - DGMesh->CreateStandardVolumeElements(config_container[iZone]); - - /*--- Create the face information needed to compute the contour integral - for the elements in the Discontinuous Galerkin formulation. ---*/ - if (rank == MASTER_NODE) cout << "Creating face information." << endl; - DGMesh->CreateFaces(config_container[iZone]); - - /*--- Compute the metric terms of the volume elements. ---*/ - if (rank == MASTER_NODE) cout << "Computing metric terms volume elements." << endl; - DGMesh->MetricTermsVolumeElements(config_container[iZone]); - - /*--- Compute the metric terms of the surface elements. ---*/ - if (rank == MASTER_NODE) cout << "Computing metric terms surface elements." << endl; - DGMesh->MetricTermsSurfaceElements(config_container[iZone]); - - /*--- Compute a length scale of the volume elements. ---*/ - if (rank == MASTER_NODE) cout << "Computing length scale volume elements." << endl; - DGMesh->LengthScaleVolumeElements(); - - /*--- Compute the coordinates of the integration points. ---*/ - if (rank == MASTER_NODE) cout << "Computing coordinates of the integration points." << endl; - DGMesh->CoordinatesIntegrationPoints(); - - /*--- Compute the coordinates of the location of the solution DOFs. This is different - from the grid points when a different polynomial degree is used to represent the - geometry and solution. ---*/ - if (rank == MASTER_NODE) cout << "Computing coordinates of the solution DOFs." << endl; - DGMesh->CoordinatesSolDOFs(); - - /*--- Initialize the static mesh movement, if necessary. ---*/ - const unsigned short Kind_Grid_Movement = config_container[iZone]->GetKind_GridMovement(); - const bool initStaticMovement = (config_container[iZone]->GetGrid_Movement() && - (Kind_Grid_Movement == MOVING_WALL || - Kind_Grid_Movement == ROTATING_FRAME || - Kind_Grid_Movement == STEADY_TRANSLATION)); - - if(initStaticMovement){ - if (rank == MASTER_NODE) cout << "Initialize Static Mesh Movement" << endl; - DGMesh->InitStaticMeshMovement(config_container[iZone], Kind_Grid_Movement, iZone); - } - - /*--- Perform the preprocessing tasks when wall functions are used. ---*/ - if (rank == MASTER_NODE) cout << "Preprocessing for the wall functions. " << endl; - DGMesh->WallFunctionPreprocessing(config_container[iZone]); - - /*--- Store the global to local mapping. ---*/ - if (rank == MASTER_NODE) cout << "Storing a mapping from global to local DOF index." << endl; - geometry_container[iZone][iInst][MESH_0]->SetGlobal_to_Local_Point(); - } - - /*--- Loop to create the coarser grid levels. ---*/ - - for(unsigned short iMGlevel=1; iMGlevel<=config_container[ZONE_0]->GetnMGLevels(); iMGlevel++) { - - SU2_MPI::Error("Geometrical_Preprocessing_DGFEM: Coarse grid levels not implemented yet.", - CURRENT_FUNCTION); - } - } -} - -void CFEMInterpolationDriver::Solver_Preprocessing(CSolver ****solver_container, CGeometry ***geometry, - CConfig *config, unsigned short val_iInst) { - - bool euler, ns, turbulent, - fem_euler, fem_ns, fem_turbulent, fem_transition, - adj_euler, adj_ns, adj_turb, - heat_fvm, - fem, disc_adj_fem, - spalart_allmaras, neg_spalart_allmaras, menter_sst, transition, - template_solver, disc_adj, disc_adj_turb, disc_adj_heat, - fem_dg_flow, fem_dg_shock_persson, - e_spalart_allmaras, comp_spalart_allmaras, e_comp_spalart_allmaras, - nemo_euler, nemo_ns; - - /*--- Count the number of DOFs per solution point. ---*/ - - DOFsPerPoint = 0; - - /*--- Initialize some useful booleans ---*/ - - euler = false; ns = false; turbulent = false; - fem_euler = false; fem_ns = false; fem_turbulent = false; - adj_euler = false; adj_ns = false; adj_turb = false; - spalart_allmaras = false; menter_sst = false; disc_adj_turb = false; - neg_spalart_allmaras = false; - disc_adj = false; - fem = false; disc_adj_fem = false; - heat_fvm = false; disc_adj_heat = false; - transition = false; fem_transition = false; - template_solver = false; - - fem_dg_flow = false; fem_dg_shock_persson = false; - e_spalart_allmaras = false; comp_spalart_allmaras = false; e_comp_spalart_allmaras = false; - - nemo_euler = false; nemo_ns = false; - - - bool compressible = (config->GetKind_Regime() == COMPRESSIBLE); - bool incompressible = (config->GetKind_Regime() == INCOMPRESSIBLE); - - /*--- Assign booleans ---*/ - - switch (config->GetKind_Solver()) { - case TEMPLATE_SOLVER: template_solver = true; break; - case EULER : euler = true; break; - case NEMO_EULER: nemo_euler = true; break; - case NAVIER_STOKES: ns = true; heat_fvm = config->GetWeakly_Coupled_Heat(); break; - case NEMO_NAVIER_STOKES: nemo_ns = true; break; - case RANS : ns = true; turbulent = true; if (config->GetKind_Trans_Model() == LM) transition = true; heat_fvm = config->GetWeakly_Coupled_Heat(); break; - case FEM_EULER : fem_euler = true; break; - case FEM_NAVIER_STOKES: fem_ns = true; break; - case FEM_RANS : fem_ns = true; fem_turbulent = true; if(config->GetKind_Trans_Model() == LM) fem_transition = true; break; - case FEM_LES : fem_ns = true; break; - case HEAT_EQUATION: heat_fvm = true; break; - case FEM_ELASTICITY: fem = true; break; - case ADJ_EULER : euler = true; adj_euler = true; break; - case ADJ_NAVIER_STOKES : ns = true; turbulent = (config->GetKind_Turb_Model() != NONE); adj_ns = true; break; - case ADJ_RANS : ns = true; turbulent = true; adj_ns = true; adj_turb = (!config->GetFrozen_Visc_Cont()); break; - case DISC_ADJ_EULER: euler = true; disc_adj = true; break; - case DISC_ADJ_NAVIER_STOKES: ns = true; disc_adj = true; heat_fvm = config->GetWeakly_Coupled_Heat(); break; - case DISC_ADJ_RANS: ns = true; turbulent = true; disc_adj = true; disc_adj_turb = (!config->GetFrozen_Visc_Disc()); heat_fvm = config->GetWeakly_Coupled_Heat(); break; - case DISC_ADJ_FEM_EULER: fem_euler = true; disc_adj = true; break; - case DISC_ADJ_FEM_NS: fem_ns = true; disc_adj = true; break; - case DISC_ADJ_FEM_RANS: fem_ns = true; fem_turbulent = true; disc_adj = true; if(config->GetKind_Trans_Model() == LM) fem_transition = true; break; - case DISC_ADJ_FEM: fem = true; disc_adj_fem = true; break; - case DISC_ADJ_HEAT: heat_fvm = true; disc_adj_heat = true; break; - } - - /*--- Determine the kind of FEM solver used for the flow. ---*/ - - switch( config->GetKind_FEM_Flow() ) { - case DG: fem_dg_flow = true; break; - } - - /*--- Determine the kind of shock capturing method for FEM DG solver. ---*/ - - switch( config->GetKind_FEM_DG_Shock() ) { - case PERSSON: fem_dg_shock_persson = true; break; - } - - /*--- Assign turbulence model booleans ---*/ - - if (turbulent || fem_turbulent){ - switch (config->GetKind_Turb_Model()) { - case SA: spalart_allmaras = true; break; - case SA_NEG: neg_spalart_allmaras = true; break; - case SST: menter_sst = true; break; - case SA_E: e_spalart_allmaras = true; break; - case SA_COMP: comp_spalart_allmaras = true; break; - case SA_E_COMP: e_comp_spalart_allmaras = true; break; - default: SU2_MPI::Error("Specified turbulence model unavailable or none selected", CURRENT_FUNCTION); break; - } - } - - /*--- Definition of the Class for the solution: solver_container[DOMAIN][INSTANCE][MESH_0][EQUATION]. Note that euler, ns - and potential are incompatible, they use the same position in sol container ---*/ - - - /*--- Allocate solution for a template problem ---*/ - - if (template_solver) { - solver_container[val_iInst][MESH_0][TEMPLATE_SOL] = new CTemplateSolver(geometry[val_iInst][MESH_0], config); - DOFsPerPoint += solver_container[val_iInst][MESH_0][TEMPLATE_SOL]->GetnVar(); - } - - /*--- Allocate solution for direct problem, and run the preprocessing and postprocessing ---*/ - - if (euler) { - if (compressible) { - solver_container[val_iInst][MESH_0][FLOW_SOL] = new CEulerSolver(geometry[val_iInst][MESH_0], config, MESH_0); - solver_container[val_iInst][MESH_0][FLOW_SOL]->Preprocessing(geometry[val_iInst][MESH_0], solver_container[val_iInst][MESH_0], config, MESH_0, NO_RK_ITER, RUNTIME_FLOW_SYS, false); - } - if (incompressible) { - solver_container[val_iInst][MESH_0][FLOW_SOL] = new CIncEulerSolver(geometry[val_iInst][MESH_0], config, MESH_0); - solver_container[val_iInst][MESH_0][FLOW_SOL]->Preprocessing(geometry[val_iInst][MESH_0], solver_container[val_iInst][MESH_0], config, MESH_0, NO_RK_ITER, RUNTIME_FLOW_SYS, false); - } - DOFsPerPoint += solver_container[val_iInst][MESH_0][FLOW_SOL]->GetnVar(); - } - if (nemo_euler) { - if (compressible) { - solver_container[val_iInst][MESH_0][FLOW_SOL] = new CNEMOEulerSolver(geometry[val_iInst][MESH_0], config, MESH_0); - solver_container[val_iInst][MESH_0][FLOW_SOL]->Preprocessing(geometry[val_iInst][MESH_0], solver_container[val_iInst][MESH_0], config, MESH_0, NO_RK_ITER, RUNTIME_FLOW_SYS, false); - } - DOFsPerPoint += solver_container[val_iInst][MESH_0][FLOW_SOL]->GetnVar(); - } - if (ns) { - if (compressible) { - solver_container[val_iInst][MESH_0][FLOW_SOL] = new CNSSolver(geometry[val_iInst][MESH_0], config, MESH_0); - } - if (incompressible) { - solver_container[val_iInst][MESH_0][FLOW_SOL] = new CIncNSSolver(geometry[val_iInst][MESH_0], config, MESH_0); - } - DOFsPerPoint += solver_container[val_iInst][MESH_0][FLOW_SOL]->GetnVar(); - } - if (nemo_ns) { - if (compressible) { - solver_container[val_iInst][MESH_0][FLOW_SOL] = new CNEMONSSolver(geometry[val_iInst][MESH_0], config, MESH_0); - } - DOFsPerPoint += solver_container[val_iInst][MESH_0][FLOW_SOL]->GetnVar(); - } - if (turbulent) { - if (spalart_allmaras || e_spalart_allmaras || comp_spalart_allmaras || e_comp_spalart_allmaras || neg_spalart_allmaras) { - solver_container[val_iInst][MESH_0][TURB_SOL] = new CTurbSASolver(geometry[val_iInst][MESH_0], config, MESH_0, solver_container[val_iInst][MESH_0][FLOW_SOL]->GetFluidModel() ); - solver_container[val_iInst][MESH_0][FLOW_SOL]->Preprocessing(geometry[val_iInst][MESH_0], solver_container[val_iInst][MESH_0], config, MESH_0, NO_RK_ITER, RUNTIME_FLOW_SYS, false); - solver_container[val_iInst][MESH_0][TURB_SOL]->Postprocessing(geometry[val_iInst][MESH_0], solver_container[val_iInst][MESH_0], config, MESH_0); - } - else if (menter_sst) { - solver_container[val_iInst][MESH_0][TURB_SOL] = new CTurbSSTSolver(geometry[val_iInst][MESH_0], config, MESH_0); - solver_container[val_iInst][MESH_0][FLOW_SOL]->Preprocessing(geometry[val_iInst][MESH_0], solver_container[val_iInst][MESH_0], config, MESH_0, NO_RK_ITER, RUNTIME_FLOW_SYS, false); - solver_container[val_iInst][MESH_0][TURB_SOL]->Postprocessing(geometry[val_iInst][MESH_0], solver_container[val_iInst][MESH_0], config, MESH_0); - solver_container[val_iInst][MESH_0][FLOW_SOL]->Preprocessing(geometry[val_iInst][MESH_0], solver_container[val_iInst][MESH_0], config, MESH_0, NO_RK_ITER, RUNTIME_FLOW_SYS, false); - } - DOFsPerPoint += solver_container[val_iInst][MESH_0][TURB_SOL]->GetnVar(); - if (transition) { - solver_container[val_iInst][MESH_0][TRANS_SOL] = new CTransLMSolver(geometry[val_iInst][MESH_0], config, MESH_0); - DOFsPerPoint += solver_container[val_iInst][MESH_0][TRANS_SOL]->GetnVar(); - } - } - if (fem_euler) { - if( fem_dg_flow ) { - if( fem_dg_shock_persson ) { - solver_container[val_iInst][MESH_0][FLOW_SOL] = new CFEM_DG_NSSolver(geometry[val_iInst][MESH_0], config, MESH_0); - } - else { - solver_container[val_iInst][MESH_0][FLOW_SOL] = new CFEM_DG_EulerSolver(geometry[val_iInst][MESH_0], config, MESH_0); - } - } - } - if (fem_ns) { - if( fem_dg_flow ) - solver_container[val_iInst][MESH_0][FLOW_SOL] = new CFEM_DG_NSSolver(geometry[val_iInst][MESH_0], config, MESH_0); - } - if (fem_turbulent) { - SU2_MPI::Error("Finite element turbulence model not yet implemented.", CURRENT_FUNCTION); - - if(fem_transition) - SU2_MPI::Error("Finite element transition model not yet implemented.", CURRENT_FUNCTION); - } - if (heat_fvm) { - solver_container[val_iInst][MESH_0][HEAT_SOL] = new CHeatSolver(geometry[val_iInst][MESH_0], config, MESH_0); - DOFsPerPoint += solver_container[val_iInst][MESH_0][HEAT_SOL]->GetnVar(); - } - if (fem) { - solver_container[val_iInst][MESH_0][FEA_SOL] = new CFEASolver(geometry[val_iInst][MESH_0], config); - if (MESH_0 == MESH_0) DOFsPerPoint += solver_container[val_iInst][MESH_0][FEA_SOL]->GetnVar(); - } - - /*--- Allocate solution for adjoint problem ---*/ - - if (adj_euler) { - if (compressible) { - solver_container[val_iInst][MESH_0][ADJFLOW_SOL] = new CAdjEulerSolver(geometry[val_iInst][MESH_0], config, MESH_0); - } - if (incompressible) { - SU2_MPI::Error("Continuous adjoint for the incompressible solver is not currently available.", CURRENT_FUNCTION); - } - DOFsPerPoint += solver_container[val_iInst][MESH_0][ADJFLOW_SOL]->GetnVar(); - } - if (adj_ns) { - if (compressible) { - solver_container[val_iInst][MESH_0][ADJFLOW_SOL] = new CAdjNSSolver(geometry[val_iInst][MESH_0], config, MESH_0); - } - if (incompressible) { - SU2_MPI::Error("Continuous adjoint for the incompressible solver is not currently available.", CURRENT_FUNCTION); - } - DOFsPerPoint += solver_container[val_iInst][MESH_0][ADJFLOW_SOL]->GetnVar(); - } - if (adj_turb) { - solver_container[val_iInst][MESH_0][ADJTURB_SOL] = new CAdjTurbSolver(geometry[val_iInst][MESH_0], config, MESH_0); - DOFsPerPoint += solver_container[val_iInst][MESH_0][ADJTURB_SOL]->GetnVar(); - } - - if (disc_adj) { - solver_container[val_iInst][MESH_0][ADJFLOW_SOL] = new CDiscAdjSolver(geometry[val_iInst][MESH_0], config, solver_container[val_iInst][MESH_0][FLOW_SOL], RUNTIME_FLOW_SYS, MESH_0); - DOFsPerPoint += solver_container[val_iInst][MESH_0][ADJFLOW_SOL]->GetnVar(); - if (disc_adj_turb) { - solver_container[val_iInst][MESH_0][ADJTURB_SOL] = new CDiscAdjSolver(geometry[val_iInst][MESH_0], config, solver_container[val_iInst][MESH_0][TURB_SOL], RUNTIME_TURB_SYS, MESH_0); - DOFsPerPoint += solver_container[val_iInst][MESH_0][ADJTURB_SOL]->GetnVar(); - } - if (heat_fvm) { - solver_container[val_iInst][MESH_0][ADJHEAT_SOL] = new CDiscAdjSolver(geometry[val_iInst][MESH_0], config, solver_container[val_iInst][MESH_0][HEAT_SOL], RUNTIME_HEAT_SYS, MESH_0); - DOFsPerPoint += solver_container[val_iInst][MESH_0][ADJHEAT_SOL]->GetnVar(); - } - } - - if (disc_adj_fem) { - solver_container[val_iInst][MESH_0][ADJFEA_SOL] = new CDiscAdjFEASolver(geometry[val_iInst][MESH_0], config, solver_container[val_iInst][MESH_0][FEA_SOL], RUNTIME_FEA_SYS, MESH_0); - DOFsPerPoint += solver_container[val_iInst][MESH_0][ADJFEA_SOL]->GetnVar(); - } - - if (disc_adj_heat) { - solver_container[val_iInst][MESH_0][ADJHEAT_SOL] = new CDiscAdjSolver(geometry[val_iInst][MESH_0], config, solver_container[val_iInst][MESH_0][HEAT_SOL], RUNTIME_HEAT_SYS, MESH_0); - DOFsPerPoint += solver_container[val_iInst][MESH_0][ADJHEAT_SOL]->GetnVar(); - } - - - - /*--- Check for restarts and use the LoadRestart() routines. ---*/ - - bool update_geo = true; - if (config->GetFSI_Simulation()) update_geo = false; - - Solver_Restart(solver_container, geometry, config, update_geo, val_iInst); - -} - -void CFEMInterpolationDriver::Solver_Restart(CSolver ****solver_container, CGeometry ***geometry, - CConfig *config, bool update_geo, unsigned short val_iInst) { - - bool euler, ns, turbulent, - adj_euler, adj_ns, adj_turb, - heat_fvm, fem, fem_euler, fem_ns, fem_dg_flow, - template_solver, disc_adj, disc_adj_fem, disc_adj_turb, disc_adj_heat, - nemo_euler, nemo_ns; - int val_iter = 0; - - /*--- Initialize some useful booleans ---*/ - - euler = false; ns = false; turbulent = false; - adj_euler = false; adj_ns = false; adj_turb = false; - fem_euler = false; fem_ns = false; fem_dg_flow = false; - disc_adj = false; - fem = false; disc_adj_fem = false; - disc_adj_turb = false; - heat_fvm = false; disc_adj_heat = false; - template_solver = false; - nemo_euler = false; nemo_ns = false; - - /*--- Check for restarts and use the LoadRestart() routines. ---*/ - - bool restart = config->GetRestart(); - bool restart_flow = config->GetRestart_Flow(); - bool no_restart = false; - - /*--- Adjust iteration number for unsteady restarts. ---*/ - - bool dual_time = ((config->GetTime_Marching() == DT_STEPPING_1ST) || - (config->GetTime_Marching() == DT_STEPPING_2ND)); - bool time_stepping = config->GetTime_Marching() == TIME_STEPPING; - bool adjoint = (config->GetDiscrete_Adjoint() || config->GetContinuous_Adjoint()); - bool dynamic = (config->GetDynamic_Analysis() == DYNAMIC); // Dynamic simulation (FSI). - - if (dual_time) { - if (adjoint) val_iter = SU2_TYPE::Int(config->GetUnst_AdjointIter())-1; - else if (config->GetTime_Marching() == DT_STEPPING_1ST) - val_iter = SU2_TYPE::Int(config->GetRestart_Iter())-1; - else val_iter = SU2_TYPE::Int(config->GetRestart_Iter())-2; - } - - if (time_stepping) { - if (adjoint) val_iter = SU2_TYPE::Int(config->GetUnst_AdjointIter())-1; - else val_iter = SU2_TYPE::Int(config->GetRestart_Iter())-1; - } - - /*--- Assign booleans ---*/ - - switch (config->GetKind_Solver()) { - case TEMPLATE_SOLVER: template_solver = true; break; - case EULER : euler = true; break; - case NEMO_EULER: nemo_euler = true; break; - case NAVIER_STOKES: ns = true; heat_fvm = config->GetWeakly_Coupled_Heat(); break; - case NEMO_NAVIER_STOKES: nemo_ns = true; break; - case RANS : ns = true; turbulent = true; heat_fvm = config->GetWeakly_Coupled_Heat(); break; - case FEM_EULER : fem_euler = true; break; - case FEM_NAVIER_STOKES: fem_ns = true; break; - case FEM_RANS : fem_ns = true; break; - case FEM_LES : fem_ns = true; break; - case HEAT_EQUATION: heat_fvm = true; break; - case FEM_ELASTICITY: fem = true; break; - case ADJ_EULER : euler = true; adj_euler = true; break; - case ADJ_NAVIER_STOKES : ns = true; turbulent = (config->GetKind_Turb_Model() != NONE); adj_ns = true; break; - case ADJ_RANS : ns = true; turbulent = true; adj_ns = true; adj_turb = (!config->GetFrozen_Visc_Cont()); break; - case DISC_ADJ_EULER: euler = true; disc_adj = true; break; - case DISC_ADJ_NAVIER_STOKES: ns = true; disc_adj = true; heat_fvm = config->GetWeakly_Coupled_Heat(); break; - case DISC_ADJ_RANS: ns = true; turbulent = true; disc_adj = true; disc_adj_turb = (!config->GetFrozen_Visc_Disc()); heat_fvm = config->GetWeakly_Coupled_Heat(); break; - case DISC_ADJ_FEM_EULER: fem_euler = true; disc_adj = true; break; - case DISC_ADJ_FEM_NS: fem_ns = true; disc_adj = true; break; - case DISC_ADJ_FEM_RANS: fem_ns = true; turbulent = true; disc_adj = true; disc_adj_turb = (!config->GetFrozen_Visc_Disc()); break; - case DISC_ADJ_FEM: fem = true; disc_adj_fem = true; break; - case DISC_ADJ_HEAT: heat_fvm = true; disc_adj_heat = true; break; - - } - - /*--- Determine the kind of FEM solver used for the flow. ---*/ - - switch( config->GetKind_FEM_Flow() ) { - case DG: fem_dg_flow = true; break; - } - - /*--- Load restarts for any of the active solver containers. Note that - these restart routines fill the fine grid and interpolate to all MG levels. ---*/ - - if (restart || restart_flow) { - if (euler || ns) { - solver_container[val_iInst][MESH_0][FLOW_SOL]->LoadRestart(geometry[val_iInst], solver_container[val_iInst], config, val_iter, update_geo); - } - if (nemo_euler || nemo_ns) { - solver_container[val_iInst][MESH_0][FLOW_SOL]->LoadRestart(geometry[val_iInst], solver_container[val_iInst], config, val_iter, update_geo); - } - if (turbulent) { - solver_container[val_iInst][MESH_0][TURB_SOL]->LoadRestart(geometry[val_iInst], solver_container[val_iInst], config, val_iter, update_geo); - } -// if (fem) { -// if (dynamic) val_iter = SU2_TYPE::Int(config->GetDyn_RestartIter())-1; -// solver_container[val_iInst][MESH_0][FEA_SOL]->LoadRestart(geometry[val_iInst], solver_container[val_iInst], config, val_iter, update_geo); -// } - if (fem_euler || fem_ns) { - if (fem_dg_flow) - solver_container[val_iInst][MESH_0][FLOW_SOL]->LoadRestart(geometry[val_iInst], solver_container[val_iInst], config, val_iter, update_geo); - } - if (heat_fvm) { - solver_container[val_iInst][MESH_0][HEAT_SOL]->LoadRestart(geometry[val_iInst], solver_container[val_iInst], config, val_iter, update_geo); - } - } - - if (restart) { - if (template_solver) { - no_restart = true; - } - if (heat_fvm) { - solver_container[val_iInst][MESH_0][HEAT_SOL]->LoadRestart(geometry[val_iInst], solver_container[val_iInst], config, val_iter, update_geo); - } - if (adj_euler || adj_ns) { - solver_container[val_iInst][MESH_0][ADJFLOW_SOL]->LoadRestart(geometry[val_iInst], solver_container[val_iInst], config, val_iter, update_geo); - } - if (adj_turb) { - no_restart = true; - } - if (disc_adj) { - solver_container[val_iInst][MESH_0][ADJFLOW_SOL]->LoadRestart(geometry[val_iInst], solver_container[val_iInst], config, val_iter, update_geo); - if (disc_adj_turb) - solver_container[val_iInst][MESH_0][ADJTURB_SOL]->LoadRestart(geometry[val_iInst], solver_container[val_iInst], config, val_iter, update_geo); - if (disc_adj_heat) - solver_container[val_iInst][MESH_0][ADJHEAT_SOL]->LoadRestart(geometry[val_iInst], solver_container[val_iInst], config, val_iter, update_geo); - } -// if (disc_adj_fem) { -// if (dynamic) val_iter = SU2_TYPE::Int(config->GetDyn_RestartIter())-1; -// solver_container[val_iInst][MESH_0][ADJFEA_SOL]->LoadRestart(geometry[val_iInst], solver_container[val_iInst], config, val_iter, update_geo); -// } - if (disc_adj_heat) { - solver_container[val_iInst][MESH_0][ADJHEAT_SOL]->LoadRestart(geometry[val_iInst], solver_container[val_iInst], config, val_iter, update_geo); - } - } - - /*--- Exit if a restart was requested for a solver that is not available. ---*/ - - if (no_restart) { - SU2_MPI::Error(string("A restart capability has not been implemented yet for this solver.\n") + - string("Please set RESTART_SOL= NO and try again."), CURRENT_FUNCTION); - } - - /*--- Think about calls to pre / post-processing here, plus realizability checks. ---*/ - -} - -void CFEMInterpolationDriver::Interpolate() { - - if (rank == MASTER_NODE) - cout << endl <<"----------------------------- Interpolation -----------------------------" << endl; - - if (rank == MASTER_NODE) cout << "Copying geometry to interpolation grid structure....." << flush; - input_grid = new CFEMInterpolationGrid(input_config_container,input_geometry_container,nZone,VertexCentered); - output_grid = new CFEMInterpolationGrid(output_config_container,output_geometry_container,nZone,VertexCentered); - if (rank == MASTER_NODE) cout << " Done." << endl << flush; - - if (rank == MASTER_NODE) cout << "Reading solution file....." << flush; - input_solution = new CFEMInterpolationSol(input_config_container,input_geometry_container,input_solver_container,nZone); - if (rank == MASTER_NODE) cout << " Done." << endl << flush; - - if (rank == MASTER_NODE) cout << "Determining coordinates for the points to be interpolated....."<< flush; - vector > coorInterpolation; - output_grid->DetermineCoorInterpolation(output_config_container, coorInterpolation, VertexCentered); - if (rank == MASTER_NODE) cout << " Done." << endl << flush; - - output_solution = new CFEMInterpolationSol(); - output_solution->InterpolateSolution(output_config_container, coorInterpolation, input_grid, input_solution, output_grid); - if (rank == MASTER_NODE) cout << "Copying solution to solver container....." << flush; - output_solution->CopySolToSU2Solution(output_config_container, output_geometry_container, output_solver_container, nZone); - if (rank == MASTER_NODE) cout << " Done." << endl << flush; - - for (iZone = 0; iZone < nZone; iZone++) { - - for (iInst = 0; iInst < nInst[iZone]; iInst++){ - - Solver_Postprocessing(output_solver_container[iZone], output_geometry_container[iZone], - output_config_container[iZone], iInst); - - } // End of loop over iInst - - } - -} - -void CFEMInterpolationDriver::Solver_Postprocessing(CSolver ****solver_container, CGeometry ***geometry, - CConfig *config, unsigned short val_iInst) { - - bool euler, ns, turbulent, - fem_euler, fem_ns, fem_turbulent, fem_transition, - adj_euler, adj_ns, adj_turb, - heat_fvm, - fem, disc_adj_fem, - spalart_allmaras, neg_spalart_allmaras, menter_sst, transition, - template_solver, disc_adj, disc_adj_turb, disc_adj_heat, - fem_dg_flow, fem_dg_shock_persson, - e_spalart_allmaras, comp_spalart_allmaras, e_comp_spalart_allmaras, - nemo_euler, nemo_ns; - - /*--- Count the number of DOFs per solution point. ---*/ - - DOFsPerPoint = 0; - - /*--- Initialize some useful booleans ---*/ - - euler = false; ns = false; turbulent = false; - fem_euler = false; fem_ns = false; fem_turbulent = false; - adj_euler = false; adj_ns = false; adj_turb = false; - spalart_allmaras = false; menter_sst = false; disc_adj_turb = false; - neg_spalart_allmaras = false; - disc_adj = false; - fem = false; disc_adj_fem = false; - heat_fvm = false; disc_adj_heat = false; - transition = false; fem_transition = false; - template_solver = false; - fem_dg_flow = false; fem_dg_shock_persson = false; - e_spalart_allmaras = false; comp_spalart_allmaras = false; e_comp_spalart_allmaras = false; - nemo_euler = false; nemo_ns = false; - - bool compressible = (config->GetKind_Regime() == COMPRESSIBLE); - bool incompressible = (config->GetKind_Regime() == INCOMPRESSIBLE); - - /*--- Assign booleans ---*/ - - switch (config->GetKind_Solver()) { - case TEMPLATE_SOLVER: template_solver = true; break; - case EULER : euler = true; break; - case NEMO_EULER: nemo_euler = true; break; - case NAVIER_STOKES: ns = true; heat_fvm = config->GetWeakly_Coupled_Heat(); break; - case NEMO_NAVIER_STOKES: nemo_ns = true; break; - case RANS : ns = true; turbulent = true; if (config->GetKind_Trans_Model() == LM) transition = true; heat_fvm = config->GetWeakly_Coupled_Heat(); break; - case FEM_EULER : fem_euler = true; break; - case FEM_NAVIER_STOKES: fem_ns = true; break; - case FEM_RANS : fem_ns = true; fem_turbulent = true; if(config->GetKind_Trans_Model() == LM) fem_transition = true; break; - case FEM_LES : fem_ns = true; break; - case HEAT_EQUATION: heat_fvm = true; break; - case FEM_ELASTICITY: fem = true; break; - case ADJ_EULER : euler = true; adj_euler = true; break; - case ADJ_NAVIER_STOKES : ns = true; turbulent = (config->GetKind_Turb_Model() != NONE); adj_ns = true; break; - case ADJ_RANS : ns = true; turbulent = true; adj_ns = true; adj_turb = (!config->GetFrozen_Visc_Cont()); break; - case DISC_ADJ_EULER: euler = true; disc_adj = true; break; - case DISC_ADJ_NAVIER_STOKES: ns = true; disc_adj = true; heat_fvm = config->GetWeakly_Coupled_Heat(); break; - case DISC_ADJ_RANS: ns = true; turbulent = true; disc_adj = true; disc_adj_turb = (!config->GetFrozen_Visc_Disc()); heat_fvm = config->GetWeakly_Coupled_Heat(); break; - case DISC_ADJ_FEM_EULER: fem_euler = true; disc_adj = true; break; - case DISC_ADJ_FEM_NS: fem_ns = true; disc_adj = true; break; - case DISC_ADJ_FEM_RANS: fem_ns = true; fem_turbulent = true; disc_adj = true; if(config->GetKind_Trans_Model() == LM) fem_transition = true; break; - case DISC_ADJ_FEM: fem = true; disc_adj_fem = true; break; - case DISC_ADJ_HEAT: heat_fvm = true; disc_adj_heat = true; break; - } - - /*--- Determine the kind of FEM solver used for the flow. ---*/ - - switch( config->GetKind_FEM_Flow() ) { - case DG: fem_dg_flow = true; break; - } - - /*--- Determine the kind of shock capturing method for FEM DG solver. ---*/ - - switch( config->GetKind_FEM_DG_Shock() ) { - case PERSSON: fem_dg_shock_persson = true; break; - } - - /*--- Assign turbulence model booleans ---*/ - - if (turbulent || fem_turbulent){ - switch (config->GetKind_Turb_Model()) { - case SA: spalart_allmaras = true; break; - case SA_NEG: neg_spalart_allmaras = true; break; - case SST: menter_sst = true; break; - case SA_E: e_spalart_allmaras = true; break; - case SA_COMP: comp_spalart_allmaras = true; break; - case SA_E_COMP: e_comp_spalart_allmaras = true; break; - default: SU2_MPI::Error("Specified turbulence model unavailable or none selected", CURRENT_FUNCTION); break; - } - } - - /*--- Definition of the Class for the solution: solver_container[DOMAIN][INSTANCE][MESH_0][EQUATION]. Note that euler, ns - and potential are incompatible, they use the same position in sol container ---*/ - - /*--- Allocate solution for direct problem, and run the preprocessing and postprocessing ---*/ - - if (euler) { - if (compressible) { - solver_container[val_iInst][MESH_0][FLOW_SOL]->Preprocessing(geometry[val_iInst][MESH_0], solver_container[val_iInst][MESH_0], config, MESH_0, NO_RK_ITER, RUNTIME_FLOW_SYS, false); - } - if (incompressible) { - solver_container[val_iInst][MESH_0][FLOW_SOL]->Preprocessing(geometry[val_iInst][MESH_0], solver_container[val_iInst][MESH_0], config, MESH_0, NO_RK_ITER, RUNTIME_FLOW_SYS, false); - } - } - if (nemo_euler) { - if (compressible) { - solver_container[val_iInst][MESH_0][FLOW_SOL]->Preprocessing(geometry[val_iInst][MESH_0], solver_container[val_iInst][MESH_0], config, MESH_0, NO_RK_ITER, RUNTIME_FLOW_SYS, false); - } - } - if (ns) { - if (compressible) { - solver_container[val_iInst][MESH_0][FLOW_SOL]->Preprocessing(geometry[val_iInst][MESH_0], solver_container[val_iInst][MESH_0], config, MESH_0, NO_RK_ITER, RUNTIME_FLOW_SYS, false); - } - if (incompressible) { - solver_container[val_iInst][MESH_0][FLOW_SOL]->Preprocessing(geometry[val_iInst][MESH_0], solver_container[val_iInst][MESH_0], config, MESH_0, NO_RK_ITER, RUNTIME_FLOW_SYS, false); - } - } - if (nemo_ns) { - if (compressible) { - solver_container[val_iInst][MESH_0][FLOW_SOL]->Preprocessing(geometry[val_iInst][MESH_0], solver_container[val_iInst][MESH_0], config, MESH_0, NO_RK_ITER, RUNTIME_FLOW_SYS, false); - } - } - if (turbulent) { - if (spalart_allmaras || e_spalart_allmaras || comp_spalart_allmaras || e_comp_spalart_allmaras || neg_spalart_allmaras) { - solver_container[val_iInst][MESH_0][FLOW_SOL]->Preprocessing(geometry[val_iInst][MESH_0], solver_container[val_iInst][MESH_0], config, MESH_0, NO_RK_ITER, RUNTIME_FLOW_SYS, false); - solver_container[val_iInst][MESH_0][TURB_SOL]->Postprocessing(geometry[val_iInst][MESH_0], solver_container[val_iInst][MESH_0], config, MESH_0); - solver_container[val_iInst][MESH_0][FLOW_SOL]->Preprocessing(geometry[val_iInst][MESH_0], solver_container[val_iInst][MESH_0], config, MESH_0, NO_RK_ITER, RUNTIME_FLOW_SYS, false); - } - else if (menter_sst) { - solver_container[val_iInst][MESH_0][FLOW_SOL]->Preprocessing(geometry[val_iInst][MESH_0], solver_container[val_iInst][MESH_0], config, MESH_0, NO_RK_ITER, RUNTIME_FLOW_SYS, false); - solver_container[val_iInst][MESH_0][TURB_SOL]->Postprocessing(geometry[val_iInst][MESH_0], solver_container[val_iInst][MESH_0], config, MESH_0); - solver_container[val_iInst][MESH_0][FLOW_SOL]->Preprocessing(geometry[val_iInst][MESH_0], solver_container[val_iInst][MESH_0], config, MESH_0, NO_RK_ITER, RUNTIME_FLOW_SYS, false); - } - } - -} - -void CFEMInterpolationDriver::Output() { - - unsigned long ExtIter = input_config_container[ZONE_0]->GetExtIter_OffSet(); - - - if (rank == MASTER_NODE) cout << endl << "-------------------------- File Output Summary --------------------------"; - - /*--- Execute the routine for writing restart, volume solution, - surface solution, and surface comma-separated value files. ---*/ - output->PreprocessHistoryOutput(output_config_container[0], false); - output->PreprocessVolumeOutput(output_config_container[0]); - output->SetResult_Files( output_geometry_container[0][0][0], output_config_container[0],output_solver_container[0][0][0], ExtIter, true); - - - if (rank == MASTER_NODE) cout << "-------------------------------------------------------------------------" << endl << endl; - - -} - -void CFEMInterpolationDriver::Solver_Deletion(CSolver ****solver_container, - CConfig *config, unsigned short val_iInst) { - unsigned short iMGlevel; - bool euler, ns, turbulent, - adj_euler, adj_ns, adj_turb, - heat_fvm, fem, - spalart_allmaras, neg_spalart_allmaras, menter_sst, transition, - template_solver, disc_adj, disc_adj_turb, disc_adj_fem, disc_adj_heat, - e_spalart_allmaras, comp_spalart_allmaras, e_comp_spalart_allmaras, - nemo_euler, nemo_ns; - - /*--- Initialize some useful booleans ---*/ - - euler = false; ns = false; turbulent = false; - adj_euler = false; adj_ns = false; adj_turb = false; - spalart_allmaras = false; menter_sst = false; disc_adj_turb = false; - neg_spalart_allmaras = false; - disc_adj = false; - fem = false; disc_adj_fem = false; - heat_fvm = false; disc_adj_heat = false; - transition = false; - template_solver = false; - e_spalart_allmaras = false; comp_spalart_allmaras = false; e_comp_spalart_allmaras = false; - nemo_euler = false; nemo_ns = false; - - /*--- Assign booleans ---*/ - - - switch (config->GetKind_Solver()) { - case TEMPLATE_SOLVER: template_solver = true; break; - case EULER : euler = true; break; - case NEMO_EULER: nemo_euler = true; break; - case NAVIER_STOKES: ns = true; heat_fvm = config->GetWeakly_Coupled_Heat(); break; - case NEMO_NAVIER_STOKES: nemo_ns = true; break; - case RANS : ns = true; turbulent = true; if (config->GetKind_Trans_Model() == LM) transition = true; heat_fvm = config->GetWeakly_Coupled_Heat(); break; - case FEM_EULER : euler = true; break; - case FEM_NAVIER_STOKES: - case FEM_LES: ns = true; break; - case FEM_RANS: ns = true; turbulent = true; if (config->GetKind_Trans_Model() == LM) transition = true; break; - case HEAT_EQUATION: heat_fvm = true; break; - case FEM_ELASTICITY: fem = true; break; - case ADJ_EULER : euler = true; adj_euler = true; break; - case ADJ_NAVIER_STOKES : ns = true; turbulent = (config->GetKind_Turb_Model() != NONE); adj_ns = true; break; - case ADJ_RANS : ns = true; turbulent = true; adj_ns = true; adj_turb = (!config->GetFrozen_Visc_Cont()); break; - case DISC_ADJ_EULER: euler = true; disc_adj = true; break; - case DISC_ADJ_NAVIER_STOKES: ns = true; disc_adj = true; heat_fvm = config->GetWeakly_Coupled_Heat(); break; - case DISC_ADJ_RANS: ns = true; turbulent = true; disc_adj = true; disc_adj_turb = (!config->GetFrozen_Visc_Disc()); heat_fvm = config->GetWeakly_Coupled_Heat(); break; - case DISC_ADJ_FEM_EULER: euler = true; disc_adj = true; break; - case DISC_ADJ_FEM_NS: ns = true; disc_adj = true; break; - case DISC_ADJ_FEM_RANS: ns = true; turbulent = true; disc_adj = true; disc_adj_turb = (!config->GetFrozen_Visc_Disc()); break; - case DISC_ADJ_FEM: fem = true; disc_adj_fem = true; break; - case DISC_ADJ_HEAT: heat_fvm = true; disc_adj_heat = true; break; - } - /*--- Assign turbulence model booleans ---*/ - - if (turbulent){ - switch (config->GetKind_Turb_Model()) { - case SA: spalart_allmaras = true; break; - case SA_NEG: neg_spalart_allmaras = true; break; - case SST: menter_sst = true; break; - case SA_E: e_spalart_allmaras = true; break; - case SA_COMP: comp_spalart_allmaras = true; break; - case SA_E_COMP: e_comp_spalart_allmaras = true; break; - } - } - - /*--- Definition of the Class for the solution: solver_container[DOMAIN][MESH_LEVEL][EQUATION]. Note that euler, ns - and potential are incompatible, they use the same position in sol container ---*/ - - - /*--- DeAllocate solution for a template problem ---*/ - - if (template_solver) { - delete solver_container[val_iInst][MESH_0][TEMPLATE_SOL]; - } - - /*--- DeAllocate solution for adjoint problem ---*/ - - if (adj_euler || adj_ns || disc_adj) { - delete solver_container[val_iInst][MESH_0][ADJFLOW_SOL]; - if (disc_adj_turb || adj_turb) { - delete solver_container[val_iInst][MESH_0][ADJTURB_SOL]; - } - if (heat_fvm) { - delete solver_container[val_iInst][MESH_0][ADJHEAT_SOL]; - } - } - - if (disc_adj_heat) { - delete solver_container[val_iInst][MESH_0][ADJHEAT_SOL]; - } - - /*--- DeAllocate solution for direct problem ---*/ - - if (euler || ns) { - delete solver_container[val_iInst][MESH_0][FLOW_SOL]; - } - - - if (nemo_euler || nemo_ns) { - - delete solver_container[val_iInst][MESH_0][FLOW_SOL]; - } - - - if (turbulent) { - if (spalart_allmaras || neg_spalart_allmaras || menter_sst || e_spalart_allmaras || comp_spalart_allmaras || e_comp_spalart_allmaras) { - delete solver_container[val_iInst][MESH_0][TURB_SOL]; - } - if (transition) { - delete solver_container[val_iInst][MESH_0][TRANS_SOL]; - } - } - if (heat_fvm) { - delete solver_container[val_iInst][MESH_0][HEAT_SOL]; - } - if (fem) { - delete solver_container[val_iInst][MESH_0][FEA_SOL]; - } - if (disc_adj_fem) { - delete solver_container[val_iInst][MESH_0][ADJFEA_SOL]; - } - - delete [] solver_container[val_iInst][MESH_0]; - - delete [] solver_container[val_iInst]; - -} - - -CFEMInterpolationSol::CFEMInterpolationSol(void){} - -CFEMInterpolationSol::CFEMInterpolationSol(CConfig** config, - CGeometry**** geometry, - CSolver***** solution, - unsigned short nZone) -{ - - // Load solution data into interpolation sol class. - unsigned short iZone, iVar; - unsigned short nVar_Template = 0, - nVar_Flow = 0, - nVar_NEMO = 0, - nVar_Trans = 0, - nVar_Turb = 0, - nVar_Adj_Flow = 0, - nVar_Adj_Turb = 0, - nVar_FEM = 0, - nVar_Heat = 0; - - bool euler, ns, turbulent, - fem_euler, fem_ns, fem_turbulent, fem_transition, - adj_euler, adj_ns, adj_turb, - heat_fvm, - fem, disc_adj_fem, - spalart_allmaras, neg_spalart_allmaras, menter_sst, transition, - template_solver, disc_adj, disc_adj_turb, disc_adj_heat, - fem_dg_flow, fem_dg_shock_persson, - e_spalart_allmaras, comp_spalart_allmaras, e_comp_spalart_allmaras, - nemo_euler, nemo_ns; - - euler = false; ns = false; turbulent = false; - fem_euler = false; fem_ns = false; fem_turbulent = false; - adj_euler = false; adj_ns = false; adj_turb = false; - spalart_allmaras = false; menter_sst = false; disc_adj_turb = false; - neg_spalart_allmaras = false; - disc_adj = false; - fem = false; disc_adj_fem = false; - heat_fvm = false; disc_adj_heat = false; - transition = false; fem_transition = false; - template_solver = false; - fem_dg_flow = false; fem_dg_shock_persson = false; - e_spalart_allmaras = false; comp_spalart_allmaras = false; e_comp_spalart_allmaras = false; - nemo_euler = false; nemo_ns = false; - - // Allocate memory for the solution. - unsigned long nDOFsTot = 0; - for(iZone = 0; iZone < nZone; iZone++){ - nDOFsTot += geometry[iZone][INST_0][MESH_0]->GetnPoint(); - } - mSolDOFs.resize(nDOFsTot); - - unsigned long offsetDOFs = 0; - for(iZone = 0; iZone < nZone; iZone++){ - // Determine type of problem. - switch (config[iZone]->GetKind_Solver()) { - case TEMPLATE_SOLVER: template_solver = true; break; - case EULER : euler = true; break; - case NEMO_EULER: nemo_euler = true; break; - case NAVIER_STOKES: ns = true; heat_fvm = config[iZone]->GetWeakly_Coupled_Heat(); break; - case NEMO_NAVIER_STOKES: nemo_ns = true; break; - case RANS : ns = true; turbulent = true; if (config[iZone]->GetKind_Trans_Model() == LM) transition = true; heat_fvm = config[iZone]->GetWeakly_Coupled_Heat(); break; - case FEM_EULER : fem_euler = true; break; - case FEM_NAVIER_STOKES: fem_ns = true; break; - case FEM_RANS : fem_ns = true; fem_turbulent = true; if(config[iZone]->GetKind_Trans_Model() == LM) fem_transition = true; break; - case FEM_LES : fem_ns = true; break; - case HEAT_EQUATION: heat_fvm = true; break; - case FEM_ELASTICITY: fem = true; break; - case ADJ_EULER : euler = true; adj_euler = true; break; - case ADJ_NAVIER_STOKES : ns = true; turbulent = (config[iZone]->GetKind_Turb_Model() != NONE); adj_ns = true; break; - case ADJ_RANS : ns = true; turbulent = true; adj_ns = true; adj_turb = (!config[iZone]->GetFrozen_Visc_Cont()); break; - case DISC_ADJ_EULER: euler = true; disc_adj = true; break; - case DISC_ADJ_NAVIER_STOKES: ns = true; disc_adj = true; heat_fvm = config[iZone]->GetWeakly_Coupled_Heat(); break; - case DISC_ADJ_RANS: ns = true; turbulent = true; disc_adj = true; disc_adj_turb = (!config[iZone]->GetFrozen_Visc_Disc()); heat_fvm = config[iZone]->GetWeakly_Coupled_Heat(); break; - case DISC_ADJ_FEM_EULER: fem_euler = true; disc_adj = true; break; - case DISC_ADJ_FEM_NS: fem_ns = true; disc_adj = true; break; - case DISC_ADJ_FEM_RANS: fem_ns = true; fem_turbulent = true; disc_adj = true; if(config[iZone]->GetKind_Trans_Model() == LM) fem_transition = true; break; - case DISC_ADJ_FEM: fem = true; disc_adj_fem = true; break; - case DISC_ADJ_HEAT: heat_fvm = true; disc_adj_heat = true; break; - } - - switch( config[iZone]->GetKind_FEM_Flow() ) { - case DG: fem_dg_flow = true; break; - } - - switch( config[iZone]->GetKind_FEM_DG_Shock() ) { - case PERSSON: fem_dg_shock_persson = true; break; - } - - // Get number of variables. - if(template_solver){ - nVar_Template = solution[iZone][INST_0][MESH_0][TEMPLATE_SOL]->GetnVar(); - nVar = nVar_Template; - } - - if(euler || fem_euler){ - nVar_Flow = solution[iZone][INST_0][MESH_0][FLOW_SOL]->GetnVar(); - nVar = nVar_Flow; - } - - if (nemo_euler) { - nVar_NEMO = solution[iZone][INST_0][MESH_0][FLOW_SOL]->GetnVar(); - nVar = nVar_NEMO; - } - - if(ns){ - nVar_Flow = solution[iZone][INST_0][MESH_0][FLOW_SOL]->GetnVar(); - if(turbulent){ - nVar_Turb = solution[iZone][INST_0][MESH_0][TURB_SOL]->GetnVar(); - } - if(transition){ - nVar_Trans = solution[iZone][INST_0][MESH_0][TRANS_SOL]->GetnVar(); - } - nVar = nVar_Flow + nVar_Turb + nVar_Trans; - } - - if (nemo_ns) { - nVar_NEMO = solution[iZone][INST_0][MESH_0][FLOW_SOL]->GetnVar(); - nVar = nVar_NEMO; - } - - if(fem_ns){ - nVar_Flow = solution[iZone][INST_0][MESH_0][FLOW_SOL]->GetnVar(); - if(turbulent){ - SU2_MPI::Error("Finite element turbulence model not yet implemented.", CURRENT_FUNCTION); - } - if(transition){ - SU2_MPI::Error("Finite element transition model not yet implemented.", CURRENT_FUNCTION); - } - nVar = nVar_Flow + nVar_Turb + nVar_Trans; - } - - if(adj_euler){ - nVar_Adj_Flow = solution[iZone][INST_0][MESH_0][ADJFLOW_SOL]->GetnVar(); - nVar = nVar_Adj_Flow; - } - - if(adj_ns){ - nVar_Adj_Flow = solution[iZone][INST_0][MESH_0][ADJFLOW_SOL]->GetnVar(); - if(adj_turb){ - nVar_Adj_Turb = solution[iZone][INST_0][MESH_0][ADJTURB_SOL]->GetnVar(); - } - nVar = nVar_Adj_Flow + nVar_Adj_Turb; - } - - if(fem){ - nVar_FEM = solution[iZone][INST_0][MESH_0][FEA_SOL]->GetnVar(); - nVar = nVar_FEM; - } - - if(heat_fvm){ - nVar_Heat = solution[iZone][INST_0][MESH_0][HEAT_SOL]->GetnVar(); - nVar = nVar_Heat; - } - - // Copy data. - unsigned long iDOF, jDOF = 0; - nDOFsTot = geometry[iZone][INST_0][MESH_0]->GetnPoint(); - for(iDOF = offsetDOFs; iDOF < offsetDOFs + nDOFsTot; iDOF++, jDOF++){ - mSolDOFs[iDOF].resize(nVar); - - if(template_solver){ - for(iVar = 0; iVar < nVar_Template; iVar++){ - mSolDOFs[iDOF][iVar] = solution[iZone][INST_0][MESH_0][TEMPLATE_SOL]->GetNodes()->GetSolution(jDOF,iVar); - } - } - - if(euler || fem_euler || ns || fem_ns){ - for(iVar = 0; iVar < nVar_Flow; iVar++){ - mSolDOFs[iDOF][iVar] = solution[iZone][INST_0][MESH_0][FLOW_SOL]->GetNodes()->GetSolution(jDOF,iVar); - } - } - - if(nemo_euler || nemo_ns){ - for(iVar = 0; iVar < nVar_NEMO; iVar++){ - mSolDOFs[iDOF][iVar] = solution[iZone][INST_0][MESH_0][FLOW_SOL]->GetNodes()->GetSolution(jDOF,iVar); - } - } - - if(turbulent){ - unsigned short jVar = 0; - for(iVar = nVar_Flow; iVar < nVar_Flow + nVar_Turb; iVar++, jVar++){ - mSolDOFs[iDOF][iVar] = solution[iZone][INST_0][MESH_0][TURB_SOL]->GetNodes()->GetSolution(jDOF,jVar); - } - } - - if(transition){ - unsigned short jVar = 0; - for(iVar = nVar_Flow + nVar_Turb; iVar < nVar_Flow + nVar_Turb + nVar_Trans; iVar++, jVar++){ - mSolDOFs[iDOF][iVar] = solution[iZone][INST_0][MESH_0][TRANS_SOL]->GetNodes()->GetSolution(jDOF,jVar); - } - } - - if(adj_euler || adj_ns){ - for(iVar = 0; iVar < nVar_Adj_Flow; iVar++){ - mSolDOFs[iDOF][iVar] = solution[iZone][INST_0][MESH_0][ADJFLOW_SOL]->GetNodes()->GetSolution(jDOF,iVar); - } - } - - if(adj_turb){ - unsigned short jVar = 0; - for(iVar = nVar_Adj_Flow; iVar < nVar_Adj_Flow + nVar_Adj_Turb; iVar++, jVar++){ - mSolDOFs[iDOF][iVar] = solution[iZone][INST_0][MESH_0][ADJTURB_SOL]->GetNodes()->GetSolution(jDOF,jVar); - } - } - - if(fem){ - for(iVar = 0; iVar < nVar_FEM; iVar++){ - mSolDOFs[iDOF][iVar] = solution[iZone][INST_0][MESH_0][FEA_SOL]->GetNodes()->GetSolution(jDOF,iVar); - } - } - - if(heat_fvm){ - for(iVar = 0; iVar < nVar_Heat; iVar++){ - mSolDOFs[iDOF][iVar] = solution[iZone][INST_0][MESH_0][HEAT_SOL]->GetNodes()->GetSolution(jDOF,iVar); - } - } - } - - offsetDOFs += nDOFsTot; - } - -} - - -CFEMInterpolationSol::~CFEMInterpolationSol(void){} - -void CFEMInterpolationSol::InterpolateSolution( - CConfig** config, - const vector > &coorInterpol, - const CFEMInterpolationGrid *inputGrid, - const CFEMInterpolationSol *inputSol, - const CFEMInterpolationGrid *outputGrid) -{ - // Determine the total number of DOFs for which memory must be allocated. - const unsigned short nZones = inputGrid->GetnZones(); - const unsigned short nDim = inputGrid->GetnDim(); - unsigned long nDOFsTot = 0; - for(unsigned short zone=0; zoneGetnVar(); - - mSolDOFs.resize(nDOFsTot); - for(unsigned long l=0; lGetSolutionFormat(); - - // Initialize the zone offset for the input and output solution to zero. - unsigned long zoneOffsetInputSol = 0; - unsigned long zoneOffsetOutputSol = 0; - - cout << "----nZones----" << nZones <GetGridZone(zone); - const CFEMInterpolationGridZone *outputGridZone = outputGrid->GetGridZone(zone); - - - // Apply a correction to the coordinates when curved boundaries - // are present. - vector coorInterpolZone; - ApplyCurvatureCorrection(config[zone], zone, nDim, inputGridZone, outputGridZone, - coorInterpol[zone], coorInterpolZone); - // Define the vectors of the standard elements and the vector to store the - // standard element for the volume elements. - vector standardElementsGrid; - vector standardElementsSol; - vector indInStandardElements; - - // First carry out a volume interpolation. Keep track of the points that - // do not fall within the grid (typically due to a different discrete - // representation of the boundary of the domain). - - vector pointsForMinDistance; - VolumeInterpolationSolution(config[zone], zone, coorInterpol[zone], coorInterpolZone, - inputGridZone, inputSol, - zoneOffsetInputSol, zoneOffsetOutputSol, - solFormatInput, pointsForMinDistance, - standardElementsGrid, standardElementsSol, - indInStandardElements); - - // Carry out a surface interpolation, via a minimum distance search, - // for the points that could not be interpolated via the regular volume - // interpolation. Print a warning about this. - if( pointsForMinDistance.size() ) - { - cout << "Zone " << zone << ": " << pointsForMinDistance.size() - << " DOFs for which the containment search failed." << endl; - cout << "A minimum distance search to the boundary of the " - << "domain is used for these points. " << endl; - - SurfaceInterpolationSolution(config[zone], zone, coorInterpol[zone], coorInterpolZone, - inputGridZone, inputSol, - zoneOffsetInputSol, zoneOffsetOutputSol, - solFormatInput, pointsForMinDistance, - standardElementsSol, indInStandardElements); - } - - - // Update the zone offset for the input and output solution. - zoneOffsetInputSol += inputGridZone->GetNSolDOFs(solFormatInput); - zoneOffsetOutputSol += coorInterpol[zone].size()/nDim; - - } -} - -void CFEMInterpolationSol::ApplyCurvatureCorrection( - CConfig* config, - const unsigned short zoneID, - const unsigned short nDim, - const CFEMInterpolationGridZone *inputGridZone, - const CFEMInterpolationGridZone *outputGridZone, - const vector &coorOriginal, - vector &coorCorrected) -{ - // Easier storage of the surface elements and coordinates of the grid zones. - const vector &inputGridSurfElems = inputGridZone->mSurfElems; - const vector > &inputGridCoor = inputGridZone->mCoor; - - const vector &outputGridSurfElems = outputGridZone->mSurfElems; - const vector > &outputGridCoor = outputGridZone->mCoor; - - /*--------------------------------------------------------------------------*/ - /*--- Step 1. Build the surface ADTs for both the input grid and the ---*/ - /*--- output grid. ---*/ - /*--------------------------------------------------------------------------*/ - - // Write a message that the surface ADT's are built for this zone. - cout << "Grid zone " << zoneID+1 - << ": Building ADTs of the surface grids ...." << flush; - - // Define the variables needed for the call to BuildSurfaceADT. - vector adjElemID; - vector faceIDInElement; - - vector standardBoundaryFacesGrid; - vector standardBoundaryFacesSol; - vector inputGridIndInStandardBoundaryFaces; - - // Build the surface ADT for the input grid. - CADTElemClass inputGridADT; - BuildSurfaceADT(config, inputGridZone, inputGridADT, standardBoundaryFacesGrid, - standardBoundaryFacesSol, inputGridIndInStandardBoundaryFaces, - adjElemID, faceIDInElement); - - // Build the surface ADT for the output grid. - vector outputGridIndInStandardBoundaryFaces; - CADTElemClass outputGridADT; - BuildSurfaceADT(config, outputGridZone, outputGridADT, standardBoundaryFacesGrid, - standardBoundaryFacesSol, outputGridIndInStandardBoundaryFaces, - adjElemID, faceIDInElement); - - // Write a message that the ADT's were built. - cout << " Done." << endl << flush; - - /*--------------------------------------------------------------------------*/ - /*--- Step 2. Carry out the wall distance searches for both the input ---*/ - /*--- and the output grid and apply the curvature correction. ---*/ - /*--------------------------------------------------------------------------*/ - - // Initialize the corrected coordinates. - coorCorrected = coorOriginal; - - // Determine the write frequency. - const unsigned long nDOFs = coorOriginal.size()/nDim; - - unsigned long writeFreq = nDOFs/5; - if(writeFreq > 10000) writeFreq = 10000; - if(writeFreq < 100) writeFreq = 100; - - writeFreq = writeFreq/10; - if(writeFreq == 0) writeFreq = 1; - writeFreq *= 10; - - // Define the vectors used in the tree search. Pre-allocate some memory - // for efficiency reasons. - vector BBoxTargets(200); - vector frontLeaves(200), frontLeavesNew(200); - - - /* ---------------------------------------------------------------------------------------------------------------------------------------------------------------- - ------------------------------------------------------------------------------------------------------------------------------------------------------------------- - ---------The next block of code was raising an error (in CFEMStandardElementBase::MatMulRowMajor) difficult to track. For now, the ApplyCurvatureCorrection ------- - to curved boundaries routine gets deactivated --------------------------------------------------------------------------------------------------------------------- - ------------------------------------------------------------------------------------------------------------------------------------------------------------------- - ----------------------------------------------------------------------------------------------------------------------------------------------------------------- */ - - // Loop over the DOFs to be corrected. - //for(unsigned long l=0; l &standardBoundaryFacesGrid, - vector &standardBoundaryFacesSol, - vector &indInStandardBoundaryFaces, - vector &adjElemID, - vector &faceIDInElement) -{ - // Easier storage of the volume elements, surface elements and coordinates of the grid zone. - const vector &volElems = gridZone->mVolElems; - const vector &surfElems = gridZone->mSurfElems; - const vector > &coorGrid = gridZone->mCoor; - const unsigned short nDim = coorGrid.size(); - const unsigned long nPoints = coorGrid[0].size(); - - /*--------------------------------------------------------------------------*/ - /*--- Step 1. Determine the volume elements adjacent to the boundary */ - /*--- surface elements. */ - /*--------------------------------------------------------------------------*/ - - // Define the vector, to store the local faces. - vector localFaces; - - // Loop over the volume elements to build the vector of faces. - for(unsigned long l=0; l::const_iterator low; - low = lower_bound(localFaces.begin(), localFaces.end(), thisFace); - - // Store the information in adjElemID and faceIDInElement. - adjElemID[l] = low->elemID; - faceIDInElement[l] = low->faceID; - } - else - SU2_MPI::Error("Boundary face not found in volume elements. The grid is not valid.", CURRENT_FUNCTION); - } - - // Release the memory of localFaces again, because it is not needed anymore. - vector().swap(localFaces); - - /*--------------------------------------------------------------------------*/ - /*--- Step 2. Build the actual ADT of the surface elements. */ - /*--------------------------------------------------------------------------*/ - - // Initialize an array for the mesh points, which eventually contains the - // mapping from the local nodes to the number used in the connectivity of the - // boundary faces. However, in a first pass it is an indicator whether - // or not a mesh point is on a boundary. - vector meshToSurface(nPoints, 0); - - // Define the vectors, which store the mapping from the subface to the - // parent face, subface ID within the parent face, the face type and - // the connectivity of the subfaces. - vector parentFace; - vector subFaceIDInParent; - vector VTK_TypeFace; - vector faceConn; - - // Loop over the surface elements to create the connectivity of the subelements. - indInStandardBoundaryFaces.resize(surfElems.size()); - for(unsigned long l=0; l surfaceCoor; - unsigned long nSurfacePoints = 0; - for(unsigned long i=0; i &coorInterpol, - const vector &coorCorrected, - const CFEMInterpolationGridZone *gridZone, - const CFEMInterpolationSol *inputSol, - const unsigned long zoneOffsetInputSol, - const unsigned long zoneOffsetOutputSol, - const SolutionFormatT solFormatInput, - vector &pointsSearchFailed, - vector &standardElementsGrid, - vector &standardElementsSol, - vector &indInStandardElements) -{ - /*--------------------------------------------------------------------------*/ - /*--- Step 1. Build the local ADT of the volume elements. Note that the ---*/ - /*--- ADT is built with the linear subelements. This is done to ---*/ - /*--- avoid relatively many expensive Newton solves for high ---*/ - /*--- order elements. ---*/ - /*--------------------------------------------------------------------------*/ - - - // Write a message that the volume ADT is built for this zone. - cout << "Grid zone " << zoneID+1 << ": Building ADT of the volume grid...." - << flush; - - // Easier storage of the volume elements and coordinates of the grid zone. - const vector &volElems = gridZone->mVolElems; - const vector > &coorGrid = gridZone->mCoor; - const unsigned short nDim = coorGrid.size(); - - // Allocate the memory for the vector, which stores the index in the standard - // elements for the volume elements. - indInStandardElements.resize(volElems.size()); - - // Define the vectors, which store the mapping from the subelement to the - // parent element, subelement ID within the parent element, the element - // type and the connectivity of the subelements. - vector parentElement; - vector subElementIDInParent; - vector VTK_TypeElem; - vector elemConn; - - // Loop over the volume elements to create the connectivity of the subelements. - for(unsigned long l=0; l volCoor; - volCoor.reserve(nDim*coorGrid[0].size()); - for(unsigned long l=0; l().swap(subElementIDInParent); - vector().swap(VTK_TypeElem); - vector().swap(parentElement); - vector().swap(elemConn); - vector().swap(volCoor); - - // Write a message that the ADT was built. - cout << " Done." << endl << flush; - - /*--------------------------------------------------------------------------*/ - /*--- Step 2. Search for donor elements for the given coordinates. ---*/ - /*--------------------------------------------------------------------------*/ - - // Determine the write frequency. - const unsigned long nDOFsInterpol = coorInterpol.size()/nDim; - - unsigned long writeFreq = nDOFsInterpol/5; - if(writeFreq > 10000) writeFreq = 10000; - if(writeFreq < 100) writeFreq = 100; - - writeFreq = writeFreq/10; - if(writeFreq == 0) writeFreq = 1; - writeFreq *= 10; - - // Define the local vector to store the failed searches for each thread. - vector localPointsFailed; - - // Define the vectors used in the tree search. Pre-allocate some memory - // for efficiency reasons. - vector frontLeaves(200), frontLeavesNew(200); - - // Loop over the DOFs to be interpolated. - for(unsigned long l=0; l > &coorGrid, - su2double *parCoor) -{ - // Easier storage of the number of dimensions. - const unsigned short nDim = coorGrid.size(); - - // Definition of the maximum number of iterations in the Newton solver - // and the tolerance level. */ - const unsigned short maxIt = 50; - const su2double tolNewton = 1.e-10; - - /*--------------------------------------------------------------------------*/ - /* Step 1: Create an initial guess for the parametric coordinates from */ - /* interpolation in the linear sub-element of the parent element. */ - /*--------------------------------------------------------------------------*/ - - // Define the variables to store the number of DOFs and the connectivity - // of the sub element in which the given coordinate resides. - unsigned short nDOFsPerSubElem = 0; - const unsigned short *connSubElems; - - // Check if the sub element is of the first sub-element type. - const unsigned short nSubElemType1 = standardElementGrid->GetNSubElemsType1(); - if(subElem < nSubElemType1) { - - // Determine the element type and set nDOFsPerSubElem. - switch( standardElementGrid->GetVTK_Type1() ) { - case TRIANGLE: nDOFsPerSubElem = 3; break; - case QUADRILATERAL: nDOFsPerSubElem = 4; break; - case TETRAHEDRON: nDOFsPerSubElem = 4; break; - case PYRAMID: nDOFsPerSubElem = 5; break; - case PRISM: nDOFsPerSubElem = 6; break; - case HEXAHEDRON: nDOFsPerSubElem = 8; break; - default: break; // Just to avoid a compiler warning. - } - - // Set the connectivity for the correct subelement. - connSubElems = standardElementGrid->GetSubConnType1() - + subElem*nDOFsPerSubElem; - } - else { - - // The sub-element is of the second sub-element type. Determine the - // element type and set nDOFsPerSubElem. - switch( standardElementGrid->GetVTK_Type2() ) { - case TRIANGLE: nDOFsPerSubElem = 3; break; - case QUADRILATERAL: nDOFsPerSubElem = 4; break; - case TETRAHEDRON: nDOFsPerSubElem = 4; break; - case PYRAMID: nDOFsPerSubElem = 5; break; - case PRISM: nDOFsPerSubElem = 6; break; - case HEXAHEDRON: nDOFsPerSubElem = 8; break; - default: break; // Just to avoid a compiler warning. - } - - // Set the connectivity for the correct subelement. - connSubElems = standardElementGrid->GetSubConnType2() - + (subElem-nSubElemType1)*nDOFsPerSubElem; - } - - // Get the parametric coordinates of the DOFs from the standard element. - const vector *locDOFs[] = {standardElementGrid->GetRDOFs(), - standardElementGrid->GetSDOFs(), - standardElementGrid->GetTDOFs()}; - - /* Create the initial guess of the parametric coordinates by interpolation - in the sub-element. */ - for(unsigned short iDim=0; iDimdata(); - for(unsigned short i=0; iGetNDOFs(); - - vector lagBasis(nDOFs); - vector > dLagBasis(nDim, vector(nDOFs)); - - // Abbreviate the grid DOFs of this element a bit easier. - const unsigned long *DOFs = volElem->mConnGrid.data(); - - // Loop over the maximum number of iterations. - unsigned short itCount; - for(itCount=0; itCountBasisFunctionsAndDerivativesInPoint(parCoor, lagBasis, - dLagBasis); - - // Make a distinction between 2D and 3D in order to have the most - // efficient code. - bool converged = false; - switch( nDim ) { - case 2: { - // Two dimensional computation. Compute the values of the function - // and minus the Jacobian matrix. - su2double f0 = coor[0], f1 = coor[1]; - su2double a00 = 0.0, a01 = 0.0, a10 = 0.0, a11 = 0.0; - for(unsigned short i=0; i &coorInterpol, - const vector &coorCorrected, - const CFEMInterpolationGridZone *gridZone, - const CFEMInterpolationSol *inputSol, - const unsigned long zoneOffsetInputSol, - const unsigned long zoneOffsetOutputSol, - const SolutionFormatT solFormatInput, - const vector &pointsMinDistSearch, - vector &standardElementsSol, - const vector &indInStandardElements) -{ - // Easier storage of the volume elements, the surface elements - // and coordinates of the grid zone. - const vector &volElems = gridZone->mVolElems; - const vector &surfElems = gridZone->mSurfElems; - const vector > &coorGrid = gridZone->mCoor; - const unsigned short nDim = coorGrid.size(); - - /*--------------------------------------------------------------------------*/ - /*--- Step 1. Build the local ADT of the surface elements. Note that the ---*/ - /*--- ADT is built with the linear subelements. This is done to ---*/ - /*--- avoid relatively many expensive Newton solves for high ---*/ - /*--- order elements. ---*/ - /*--------------------------------------------------------------------------*/ - - // Write a message that the surface ADT is built for this zone. - cout << "Grid zone " << zoneID+1 << ": Building ADT of the surface grid...." - << flush; - - // Define the vectors to store the adjacent element and the face ID - // inside the element. - vector adjElemID; - vector faceIDInElement; - - // Define the vectors of the standard boundary faces and the vector to store - // the standard boundary face for the surface elements. - vector standardBoundaryFacesGrid; - vector standardBoundaryFacesSol; - vector indInStandardBoundaryFaces; - - // Build the surface ADT. - CADTElemClass surfaceADT; - BuildSurfaceADT(config, gridZone, surfaceADT, standardBoundaryFacesGrid, - standardBoundaryFacesSol, indInStandardBoundaryFaces, - adjElemID, faceIDInElement); - - // Write a message that the ADT was built. - cout << " Done." << endl << flush; - - /*--------------------------------------------------------------------------*/ - /*--- Step 2. Search for donor elements for the given coordinates. ---*/ - /*--------------------------------------------------------------------------*/ - - // Determine the write frequency. - unsigned long writeFreq = pointsMinDistSearch.size()/5; - if(writeFreq > 10000) writeFreq = 10000; - if(writeFreq < 100) writeFreq = 100; - - writeFreq = writeFreq/10; - if(writeFreq == 0) writeFreq = 1; - writeFreq *= 10; - - // Define the vectors used in the tree search. Pre-allocate some memory - // for efficiency reasons. - vector BBoxTargets(200); - vector frontLeaves(200), frontLeavesNew(200); - - // Loop over the points for which a minimum distance search must be carried out. - for(unsigned long l=0; l > &coorGrid, - su2double *parCoor, - su2double *wallCoor) -{ - // Easier storage of the number of dimensions. - const unsigned short nDim = coorGrid.size(); - - // Definition of the maximum number of iterations in the Newton solver - // and the tolerance level. */ - //const unsigned short maxIt = 50; - //const su2double tolNewton = 1.e-10; - - /*--------------------------------------------------------------------------*/ - /* Step 1: Create an initial guess for the parametric coordinates from */ - /* interpolation in the linear sub-element of the parent element. */ - /*--------------------------------------------------------------------------*/ - - // Get the required information for the linear sub-element from the - // standard boundary face. - const unsigned short nDOFsPerFace = standardBoundaryFaceGrid->GetNDOFsPerSubFace(); - const unsigned short *connSubFace = standardBoundaryFaceGrid->GetSubFaceConn() - + subElem*nDOFsPerFace; - - // Get the parametric coordinates of the DOFs from the standard boundary face. - const vector *locDOFs[] = {standardBoundaryFaceGrid->GetRDOFsFace(), - standardBoundaryFaceGrid->GetSDOFsFace()}; - - // Create the initial guess of the parametric coordinates by interpolation - // in the sub-element. Note that the number of parametric dimensions of a - // surface element is one less than the number of physical dimensions. - for(unsigned short iDim=0; iDim<(nDim-1); ++iDim) { - parCoor[iDim] = 0.0; - const su2double *coorDOFs = locDOFs[iDim]->data(); - for(unsigned short i=0; iGetNDOFsFace(); - - vector lagBasis(nDOFs); - vector > dLagBasis(nDim-1, vector(nDOFs)); - - // Easier storage of the DOFs of the face. - const unsigned long *DOFs = surfElem->mConnGrid.data(); - - // Compute the Lagrangian basis functions and its derivatives in - // the current parametric coordinate. - standardBoundaryFaceGrid->FaceBasisFunctionsAndDerivativesInPoint(parCoor, lagBasis, - dLagBasis); - - // Compute the coordinates of the wall point. Make a distinction between - // 2D and 3D for efficiency reasons. - switch( nDim ) { - case 2: { - // Two dimensional computation. Compute the values of the coordinates. - wallCoor[0] = wallCoor[1] = 0.0; - for(unsigned short i=0; i &solDOF) -{ - // Easier storage of the solution DOFs of the input grid. - const vector > &solInput = inputSol->GetSolDOFs(); - - // Determine the number of DOFs in the donor element. - const unsigned short nDOFs = standardElementSol->GetNDOFs(); - - // Determine the interpolation weights inside this element. - vector wSol(nDOFs); - standardElementSol->BasisFunctionsInPoint(parCoor, wSol); - - // Initialize the solution to be interpolated to zero. - for(unsigned short var=0; varmConnGrid[k]; - for(unsigned short var=0; varmElemID; - for(unsigned short var=0; varmOffsetSolDOFsDG + k; - for(unsigned short var=0; varGetKind_Solver()) { - case TEMPLATE_SOLVER: template_solver = true; break; - case EULER : euler = true; break; - case NEMO_EULER: nemo_euler = true; break; - case NAVIER_STOKES: ns = true; heat_fvm = config[iZone]->GetWeakly_Coupled_Heat(); break; - case NEMO_NAVIER_STOKES: nemo_ns = true; break; - case RANS : ns = true; turbulent = true; if (config[iZone]->GetKind_Trans_Model() == LM) transition = true; heat_fvm = config[iZone]->GetWeakly_Coupled_Heat(); break; - case FEM_EULER : fem_euler = true; break; - case FEM_NAVIER_STOKES: fem_ns = true; break; - case FEM_RANS : fem_ns = true; fem_turbulent = true; if(config[iZone]->GetKind_Trans_Model() == LM) fem_transition = true; break; - case FEM_LES : fem_ns = true; break; - case HEAT_EQUATION: heat_fvm = true; break; - case FEM_ELASTICITY: fem = true; break; - case ADJ_EULER : euler = true; adj_euler = true; break; - case ADJ_NAVIER_STOKES : ns = true; turbulent = (config[iZone]->GetKind_Turb_Model() != NONE); adj_ns = true; break; - case ADJ_RANS : ns = true; turbulent = true; adj_ns = true; adj_turb = (!config[iZone]->GetFrozen_Visc_Cont()); break; - case DISC_ADJ_EULER: euler = true; disc_adj = true; break; - case DISC_ADJ_NAVIER_STOKES: ns = true; disc_adj = true; heat_fvm = config[iZone]->GetWeakly_Coupled_Heat(); break; - case DISC_ADJ_RANS: ns = true; turbulent = true; disc_adj = true; disc_adj_turb = (!config[iZone]->GetFrozen_Visc_Disc()); heat_fvm = config[iZone]->GetWeakly_Coupled_Heat(); break; - case DISC_ADJ_FEM_EULER: fem_euler = true; disc_adj = true; break; - case DISC_ADJ_FEM_NS: fem_ns = true; disc_adj = true; break; - case DISC_ADJ_FEM_RANS: fem_ns = true; fem_turbulent = true; disc_adj = true; if(config[iZone]->GetKind_Trans_Model() == LM) fem_transition = true; break; - case DISC_ADJ_FEM: fem = true; disc_adj_fem = true; break; - case DISC_ADJ_HEAT: heat_fvm = true; disc_adj_heat = true; break; - } - - switch( config[iZone]->GetKind_FEM_Flow() ) { - case DG: fem_dg_flow = true; break; - } - - switch( config[iZone]->GetKind_FEM_DG_Shock() ) { - case PERSSON: fem_dg_shock_persson = true; break; - } - - // Get number of variables. - if(template_solver){ - nVar_Template = solution[iZone][INST_0][MESH_0][TEMPLATE_SOL]->GetnVar(); - } - - if(euler || fem_euler){ - nVar_Flow = solution[iZone][INST_0][MESH_0][FLOW_SOL]->GetnVar(); - } - - if(ns){ - nVar_Flow = solution[iZone][INST_0][MESH_0][FLOW_SOL]->GetnVar(); - if(turbulent){ - nVar_Turb = solution[iZone][INST_0][MESH_0][TURB_SOL]->GetnVar(); - } - if(transition){ - nVar_Trans = solution[iZone][INST_0][MESH_0][TRANS_SOL]->GetnVar(); - } - } - - if (nemo_euler || nemo_ns) { - nVar_NEMO = solution[iZone][INST_0][MESH_0][FLOW_SOL]->GetnVar(); - } - - if(fem_ns){ - nVar_Flow = solution[iZone][INST_0][MESH_0][FLOW_SOL]->GetnVar(); - if(turbulent){ - SU2_MPI::Error("Finite element turbulence model not yet implemented.", CURRENT_FUNCTION); - } - if(transition){ - SU2_MPI::Error("Finite element transition model not yet implemented.", CURRENT_FUNCTION); - } - } - - if(adj_euler){ - nVar_Adj_Flow = solution[iZone][INST_0][MESH_0][ADJFLOW_SOL]->GetnVar(); - } - - if(adj_ns){ - nVar_Adj_Flow = solution[iZone][INST_0][MESH_0][ADJFLOW_SOL]->GetnVar(); - if(adj_turb){ - nVar_Adj_Turb = solution[iZone][INST_0][MESH_0][ADJTURB_SOL]->GetnVar(); - } - } - - if(fem){ - nVar_FEM = solution[iZone][INST_0][MESH_0][FEA_SOL]->GetnVar(); - } - - if(heat_fvm){ - nVar_Heat = solution[iZone][INST_0][MESH_0][HEAT_SOL]->GetnVar(); - } - - // Copy data. - unsigned long iDOF, jDOF = 0; - unsigned long nDOFsTot = geometry[iZone][INST_0][MESH_0]->GetnPoint(); - for(iDOF = offsetDOFs; iDOF < offsetDOFs + nDOFsTot; iDOF++, jDOF++){ - - if(template_solver){ - for(iVar = 0; iVar < nVar_Template; iVar++){ - solution[iZone][INST_0][MESH_0][TEMPLATE_SOL]->GetNodes()->SetSolution(jDOF,iVar, mSolDOFs[iDOF][iVar]); - } - } - - if(euler || fem_euler || ns || fem_ns){ - for(iVar = 0; iVar < nVar_Flow; iVar++){ - solution[iZone][INST_0][MESH_0][FLOW_SOL]->GetNodes()->SetSolution(jDOF,iVar, mSolDOFs[iDOF][iVar]); - } - } - - if(nemo_euler || nemo_ns){ - for(iVar = 0; iVar < nVar_NEMO; iVar++){ - solution[iZone][INST_0][MESH_0][FLOW_SOL]->GetNodes()->SetSolution(jDOF,iVar, mSolDOFs[iDOF][iVar]); - } - } - - if(turbulent){ - unsigned short jVar = 0; - for(iVar = nVar_Flow; iVar < nVar_Flow + nVar_Turb; iVar++, jVar++){ - solution[iZone][INST_0][MESH_0][TURB_SOL]->GetNodes()->SetSolution(jDOF,jVar, mSolDOFs[iDOF][iVar]); - } - } - - if(transition){ - unsigned short jVar = 0; - for(iVar = nVar_Flow + nVar_Turb; iVar < nVar_Flow + nVar_Turb + nVar_Trans; iVar++, jVar++){ - solution[iZone][INST_0][MESH_0][TRANS_SOL]->GetNodes()->SetSolution(jDOF,jVar, mSolDOFs[iDOF][iVar]); - } - } - - if(adj_euler || adj_ns){ - for(iVar = 0; iVar < nVar_Adj_Flow; iVar++){ - solution[iZone][INST_0][MESH_0][ADJFLOW_SOL]->GetNodes()->SetSolution(jDOF,iVar, mSolDOFs[iDOF][iVar]); - } - } - - if(adj_turb){ - unsigned short jVar = 0; - for(iVar = nVar_Adj_Flow; iVar < nVar_Adj_Flow + nVar_Adj_Turb; iVar++, jVar++){ - solution[iZone][INST_0][MESH_0][ADJTURB_SOL]->GetNodes()->SetSolution(jDOF,jVar, mSolDOFs[iDOF][iVar]); - } - } - - if(fem){ - for(iVar = 0; iVar < nVar_FEM; iVar++){ - solution[iZone][INST_0][MESH_0][FEA_SOL]->GetNodes()->SetSolution(jDOF,iVar, mSolDOFs[iDOF][iVar]); - } - } - - if(heat_fvm){ - for(iVar = 0; iVar < nVar_Heat; iVar++){ - solution[iZone][INST_0][MESH_0][HEAT_SOL]->GetNodes()->SetSolution(jDOF,iVar, mSolDOFs[iDOF][iVar]); - } - } - } - - offsetDOFs += nDOFsTot; - } - -} - -CFEMInterpolationFaceOfElem::CFEMInterpolationFaceOfElem() -{ - nCornerPoints = 0; - cornerPoints[0] = cornerPoints[1] = cornerPoints[2] = cornerPoints[3] = ULONG_MAX; - elemID = ULONG_MAX; - faceID = 0; -} - -bool CFEMInterpolationFaceOfElem::operator<(const CFEMInterpolationFaceOfElem &other) const -{ - if(nCornerPoints != other.nCornerPoints) return nCornerPoints < other.nCornerPoints; - - for(unsigned short i=0; iGetCornerPointsFace(faceIDInElement, nCornerPoints, cornerPointsVol); - - // Determine the element type and set the parametric coordinates r and s - // accordingly. - su2double r = 0.0, s = 0.0; - switch( mVTK_TYPE ) - { - case LINE: - { - // Line element. Either the directions coincide or run opposite. - if( (cornerPointsSurf[0] == cornerPointsVol[0]) && - (cornerPointsSurf[1] == cornerPointsVol[1])) r = parCoor[0]; - else if((cornerPointsSurf[0] == cornerPointsVol[1]) && - (cornerPointsSurf[1] == cornerPointsVol[0])) r = -parCoor[0]; - else - SU2_MPI::Error("Lines do not match. This should not happen.", CURRENT_FUNCTION); - break; - } - - case TRIANGLE: - { - // Element is a triangle. Determine the orientation and set the parametric - // coordinates accordingly. - if(cornerPointsSurf[0] == cornerPointsVol[0]) - { - if((cornerPointsSurf[1] == cornerPointsVol[1]) && - (cornerPointsSurf[2] == cornerPointsVol[2])) - { - r = parCoor[0]; - s = parCoor[1]; - } - else if((cornerPointsSurf[1] == cornerPointsVol[2]) && - (cornerPointsSurf[2] == cornerPointsVol[1])) - { - r = parCoor[1]; - s = parCoor[0]; - } - else - SU2_MPI::Error("Triangles do not match. This should not happen.", CURRENT_FUNCTION); - } - else if(cornerPointsSurf[0] == cornerPointsVol[1]) - { - if((cornerPointsSurf[1] == cornerPointsVol[2]) && - (cornerPointsSurf[2] == cornerPointsVol[0]) ) - { - r = -1.0 - parCoor[0] - parCoor[1]; - s = parCoor[0]; - } - else if((cornerPointsSurf[1] == cornerPointsVol[0]) && - (cornerPointsSurf[2] == cornerPointsVol[2])) - { - r = -1.0 - parCoor[0] - parCoor[1]; - s = parCoor[1]; - } - else - SU2_MPI::Error("Triangles do not match. This should not happen.", CURRENT_FUNCTION); - } - else if(cornerPointsSurf[0] == cornerPointsVol[2]) - { - if((cornerPointsSurf[1] == cornerPointsVol[0]) && - (cornerPointsSurf[2] == cornerPointsVol[1]) ) - { - r = parCoor[1]; - s = -1.0 - parCoor[0] - parCoor[1]; - } - else if((cornerPointsSurf[1] == cornerPointsVol[1]) && - (cornerPointsSurf[2] == cornerPointsVol[0])) - { - r = parCoor[0]; - s = -1.0 - parCoor[0] - parCoor[1]; - } - else - SU2_MPI::Error("Triangles do not match. This should not happen.", CURRENT_FUNCTION); - } - else - SU2_MPI::Error("Triangles do not match. This should not happen.", CURRENT_FUNCTION); - break; - } - - case QUADRILATERAL: - { - // Element is a quadrilateral. Determine the orientation and set the parametric - // coordinates accordingly. - if(cornerPointsSurf[0] == cornerPointsVol[0]) - { - if((cornerPointsSurf[1] == cornerPointsVol[1]) && - (cornerPointsSurf[2] == cornerPointsVol[2]) && - (cornerPointsSurf[3] == cornerPointsVol[3])) - { - r = parCoor[0]; - s = parCoor[1]; - } - else if((cornerPointsSurf[1] == cornerPointsVol[3]) && - (cornerPointsSurf[2] == cornerPointsVol[2]) && - (cornerPointsSurf[3] == cornerPointsVol[1])) - { - r = parCoor[1]; - s = parCoor[0]; - } - else - SU2_MPI::Error("Quadrilaterals do not match. This should not happen.", CURRENT_FUNCTION); - } - else if(cornerPointsSurf[0] == cornerPointsVol[1]) - { - if((cornerPointsSurf[1] == cornerPointsVol[0]) && - (cornerPointsSurf[2] == cornerPointsVol[3]) && - (cornerPointsSurf[3] == cornerPointsVol[2])) - { - r = -parCoor[0]; - s = parCoor[1]; - } - else if((cornerPointsSurf[1] == cornerPointsVol[2]) && - (cornerPointsSurf[2] == cornerPointsVol[3]) && - (cornerPointsSurf[3] == cornerPointsVol[0])) - { - r = -parCoor[1]; - s = parCoor[0]; - } - else - SU2_MPI::Error("Quadrilaterals do not match. This should not happen.", CURRENT_FUNCTION); - } - else if(cornerPointsSurf[0] == cornerPointsVol[2]) - { - if((cornerPointsSurf[1] == cornerPointsVol[1]) && - (cornerPointsSurf[2] == cornerPointsVol[0]) && - (cornerPointsSurf[3] == cornerPointsVol[3])) - { - r = -parCoor[1]; - s = -parCoor[0]; - } - else if((cornerPointsSurf[1] == cornerPointsVol[3]) && - (cornerPointsSurf[2] == cornerPointsVol[0]) && - (cornerPointsSurf[3] == cornerPointsVol[1])) - { - r = -parCoor[0]; - s = -parCoor[1]; - } - else - SU2_MPI::Error("Quadrilaterals do not match. This should not happen.", CURRENT_FUNCTION); - } - else if(cornerPointsSurf[0] == cornerPointsVol[3]) - { - if((cornerPointsSurf[1] == cornerPointsVol[0]) && - (cornerPointsSurf[2] == cornerPointsVol[1]) && - (cornerPointsSurf[3] == cornerPointsVol[2])) - { - r = parCoor[1]; - s = -parCoor[0]; - } - else if((cornerPointsSurf[1] == cornerPointsVol[2]) && - (cornerPointsSurf[2] == cornerPointsVol[1]) && - (cornerPointsSurf[3] == cornerPointsVol[0])) - { - r = parCoor[0]; - s = -parCoor[1]; - } - } - else - SU2_MPI::Error("Quadrilaterals do not match. This should not happen.", CURRENT_FUNCTION); - break; - } - - default: - { - SU2_MPI::Error("This should not happen.", CURRENT_FUNCTION); - } - } - - //---------------------------------------------------------------------------- - // Step 2: Transform the parametric face coordinates of the face to - // parametric volume coordinates. - //---------------------------------------------------------------------------- - - // Determine the volume element type and act accordingly. - switch( volElem->mVTK_TYPE ) - { - case TRIANGLE: - { - // Volume element is a triangle. Determine the face ID and set the - // parametric volume coordinates from the surface coordinates. - switch(faceIDInElement ) - { - case 0: parCoor[0] = r; parCoor[1] = -1.0; break; - case 1: parCoor[0] = -r; parCoor[1] = r; break; - case 2: parCoor[0] = -1.0; parCoor[1] = -r; break; - default: - SU2_MPI::Error("Invalid face ID of a triangle. This should not happen.", CURRENT_FUNCTION); - } - break; - } - - case QUADRILATERAL: - { - // Volume element is a quadrilatral. Determine the face ID and set the - // parametric volume coordinates from the surface coordinates. - switch(faceIDInElement ) - { - case 0: parCoor[0] = r; parCoor[1] = -1.0; break; - case 1: parCoor[0] = 1.0; parCoor[1] = r; break; - case 2: parCoor[0] = -r; parCoor[1] = 1.0; break; - case 3: parCoor[0] = -1.0; parCoor[1] = -r; break; - default: - SU2_MPI::Error("Invalid face ID of a quadrilatral. This should not happen.", CURRENT_FUNCTION); - } - break; - } - - case TETRAHEDRON: - { - // Volume element is a tetrahedron. Determine the face ID and set the - // parametric volume coordinates from the surface coordinates. - switch(faceIDInElement ) - { - case 0: parCoor[0] = r; parCoor[1] = s; parCoor[2] = -1.0; break; - case 1: parCoor[0] = s; parCoor[1] = -1.0; parCoor[2] = r; break; - case 2: parCoor[0] = -1.0; parCoor[1] = r; parCoor[2] = s; break; - case 3: parCoor[0] = -1.0-r-s; parCoor[1] = s; parCoor[2] = r; break; - default: - SU2_MPI::Error("Invalid face ID of a tetrahedron. This should not happen.", CURRENT_FUNCTION); - } - break; - } - - case PYRAMID: - { - // Volume element is a pyramid. Determine the face ID and set the - // parametric volume coordinates from the surface coordinates. - switch(faceIDInElement ) - { - case 0: parCoor[0] = r; parCoor[1] = s; parCoor[2] = -1.0; break; - case 1: parCoor[0] = 0.5*(1.0+r) + s; parCoor[1] = 0.5*(r-1.0); parCoor[2] = r; break; - case 2: parCoor[0] = 0.5*(1.0+s) + r; parCoor[1] = 0.5*(1.0-s); parCoor[2] = s; break; - case 3: parCoor[0] = 0.5*(s-1.0); parCoor[1] = 0.5*(1.0+s) + r; parCoor[2] = s; break; - case 4: parCoor[0] = 0.5*(r-1.0); parCoor[1] = 0.5*(1.0+r) + s; parCoor[2] = r; break; - default: - SU2_MPI::Error("Invalid face ID of a pyramid. This should not happen.", CURRENT_FUNCTION); - } - break; - } - - case PRISM: - { - // Volume element is a prism. Determine the face ID and set the - // parametric volume coordinates from the surface coordinates. - switch(faceIDInElement ) - { - case 0: parCoor[0] = r; parCoor[1] = s; parCoor[2] = -1.0; break; - case 1: parCoor[0] = s; parCoor[1] = r; parCoor[2] = 1.0; break; - case 2: parCoor[0] = s; parCoor[1] = -1.0; parCoor[2] = r; break; - case 3: parCoor[0] = -1.0; parCoor[1] = r; parCoor[2] = s; break; - case 4: parCoor[0] = -s; parCoor[1] = s; parCoor[2] = r; break; - default: - SU2_MPI::Error("Invalid face ID of a prism. This should not happen.", CURRENT_FUNCTION); - } - break; - } - - case HEXAHEDRON: - { - // Volume element is a hexahedron. Determine the face ID and set the - // parametric volume coordinates from the surface coordinates. - switch(faceIDInElement ) - { - case 0: parCoor[0] = r; parCoor[1] = s; parCoor[2] = -1.0; break; - case 1: parCoor[0] = s; parCoor[1] = r; parCoor[2] = 1.0; break; - case 2: parCoor[0] = s; parCoor[1] = -1.0; parCoor[2] = r; break; - case 3: parCoor[0] = r; parCoor[1] = 1.0; parCoor[2] = s; break; - case 4: parCoor[0] = -1.0; parCoor[1] = r; parCoor[2] = s; break; - case 5: parCoor[0] = 1.0; parCoor[1] = s; parCoor[2] = r; break; - default: - SU2_MPI::Error("Invalid face ID of a hexahedron. This should not happen.", CURRENT_FUNCTION); - } - break; - } - - default: - { - SU2_MPI::Error("This should not happen.", CURRENT_FUNCTION); - } - } -} - -void CFEMInterpolationSurfElem::GetCornerPoints(unsigned short &nCornerPoints, - unsigned long cornerPoints[]) const -{ - // Get the local ID's, relative to the element, of the corner points. - switch( mVTK_TYPE ) - { - case LINE: - { - nCornerPoints = 2; - cornerPoints[0] = 0; cornerPoints[1] = mNPolyGrid; - break; - } - - case TRIANGLE: - { - nCornerPoints = 3; - cornerPoints[0] = 0; cornerPoints[1] = mNPolyGrid; cornerPoints[2] = mNDOFsGrid-1; - break; - } - - case QUADRILATERAL: - { - unsigned short nn2 = mNPolyGrid*(mNPolyGrid+1); - nCornerPoints = 4; - cornerPoints[0] = 0; cornerPoints[1] = mNPolyGrid; - cornerPoints[2] = mNDOFsGrid-1; cornerPoints[3] = nn2; - break; - } - - default: - { - SU2_MPI::Error("This should not happen.", CURRENT_FUNCTION); - break; - } - } - - // Convert the local ID's to global ID's. - for(unsigned short j=0; jGetnElem(); - mVolElems.resize(nElem); - - // Loop over the elements. - unsigned long nSolDOFs = 0; - for(iElem = 0; iElem < nElem; iElem++){ - int VTKType, nPolyGrid, nPolySol, nDOFsGrid, nDOFsSol; - - // Determine the VTK type of the element - VTKType = geometry->elem[iElem]->GetVTK_Type(); - - // Determine the polynomial degree of the grid and solution. GetNPoly returns 0 if not FEM. - nPolyGrid = geometry->elem[iElem]->GetNPolyGrid(); - nPolySol = geometry->elem[iElem]->GetNPolySol(); - if(nPolyGrid == 0){ - nPolyGrid = 1; - nPolySol = nPolyGrid; - } - - // Determine the number of DOFs for the grid and solution. - nDOFsGrid = DetermineNDOFs(VTKType, nPolyGrid); - nDOFsSol = DetermineNDOFs(VTKType, nPolySol); - - // Allocate the memory for the connectivity and read it. - vector connSU2(nDOFsGrid); - for(iNode = 0; iNode < nDOFsGrid; iNode++) - connSU2[iNode] = geometry->elem[iElem]->GetNode(iNode); - - // Store the data for this element. - mVolElems[iElem].StoreElemData(iElem, VTKType, nPolyGrid, nPolySol, nDOFsGrid, - nDOFsSol, nSolDOFs, connSU2.data()); - - // Update nSolDOFs. - nSolDOFs += nDOFsSol; - - } - - // Allocate the memory for the coordinates. - nPoint = geometry->GetnPoint(); - nDim = geometry->GetnDim(); - mCoor.resize(nDim); - for(iDim = 0; iDim < nDim; iDim++){ - mCoor[iDim].resize(nPoint); - // Copy the coordinates. - for(iPoint = 0; iPoint < nPoint; iPoint++){ - mCoor[iDim][iPoint] = geometry->nodes->GetCoord(iPoint,iDim); - } - } - - // Allocate the memory for the surface elements. - nElem=0; - for (iMarker = 0; iMarker < geometry->GetnMarker(); iMarker++) { - nElem +=geometry->GetnElem_Bound(iMarker); } - mSurfElems.resize(nElem); - - // Loop over the boundary markers to store the surface connectivity. - // Note that the surface connectivity is stored as one entity. The - // information of the boundary markers is not kept. - nElem = 0; - nMarker = config->GetnMarker_All(); - for(iMarker = 0; iMarker < nMarker; iMarker++){ - for(iElem = 0; iElem < geometry->GetnElem_Bound(iMarker); iElem++, nElem++){ - int VTKType, nPolyGrid, nDOFsGrid; - - // Determine the VTK type of the element - VTKType = geometry->bound[iMarker][iElem]->GetVTK_Type(); - - // Determine the polynomial degree of the grid and solution. GetNPoly returns 0 if not FEM. - nPolyGrid = geometry->bound[iMarker][iElem]->GetNPolyGrid(); - if(nPolyGrid == 0){ - nPolyGrid = 1; - } - - // Determine the number of DOFs for the grid and solution. - nDOFsGrid = DetermineNDOFs(VTKType, nPolyGrid); - - // Allocate the memory for the connectivity and read it. - vector connSU2(nDOFsGrid); - for(iNode = 0; iNode < nDOFsGrid; iNode++) - connSU2[iNode] = geometry->bound[iMarker][iElem]->GetNode(iNode); - - // Store the data for this element. - mSurfElems[nElem].StoreElemData(VTKType, nPolyGrid, nDOFsGrid, - connSU2.data()); - } - } - -} - -void CFEMInterpolationGridZone::DetermineCoorInterpolation(CConfig* config, - vector &coorInterpol, - const SolutionFormatT solFormatWrite) -{ - // Determine the number of dimensions. - const unsigned short nDim = mCoor.size(); - - // Make a distinction between the requested formats. - switch( solFormatWrite ) - { - case VertexCentered: - case FEM: - { - // Vertex centered scheme. The coordinates for interpolation are simply the - // coordinates of the grid. - const unsigned long nPoints = mCoor[0].size(); - coorInterpol.resize(nDim*nPoints); - - unsigned long ii = 0; - for(unsigned long i=0; i standardElementsGrid; - vector standardElementsSol; - - // Loop over the elements to determine the coordinates of its DOFs. - unsigned long ii = 0; - for(unsigned long i=0; i 1) highOrder = true; - - // Return highOrder. - return highOrder; -} - -void CFEMInterpolationGridZone::DetermineElementInfo(int su2ElemType, - int &VTKType, - int &nPolyGrid, - int &nPolySol, - int &nDOFsGrid, - int &nDOFsSol) -{ - // Check if the su2ElemType is larger than 10000. If that is the case then - // the polynomial degree of the grid and solution is different. - if(su2ElemType > 10000) - { - nPolySol = su2ElemType/10000 - 1; - su2ElemType = su2ElemType%10000; - nPolyGrid = su2ElemType/100 + 1; - } - else - { - nPolyGrid = su2ElemType/100 + 1; - nPolySol = nPolyGrid; - } - - // Determine the VTK type of the element. - VTKType = su2ElemType%100; - - // Determine the number of DOFs for the grid and solution. - nDOFsGrid = DetermineNDOFs(VTKType, nPolyGrid); - nDOFsSol = DetermineNDOFs(VTKType, nPolySol); -} - -int CFEMInterpolationGridZone::DetermineNDOFs(const int VTKType, - const int nPoly) -{ - // Initialization. - const int nDOFsEdge = nPoly + 1; - int nDOFs = 0; - - // Determine the element type and set the number of DOFs from the polynomial - // degree of the element. - switch( VTKType ) - { - case LINE: - nDOFs = nDOFsEdge; - break; - - case TRIANGLE: - nDOFs = nDOFsEdge*(nDOFsEdge+1)/2; - break; - - case QUADRILATERAL: - nDOFs = nDOFsEdge*nDOFsEdge; - break; - - case TETRAHEDRON: - nDOFs = nDOFsEdge*(nDOFsEdge+1)*(nDOFsEdge+2)/6; - break; - - case PYRAMID: - nDOFs = nDOFsEdge*(nDOFsEdge+1)*(2*nDOFsEdge+1)/6; - break; - - case PRISM: - nDOFs = nDOFsEdge*nDOFsEdge*(nDOFsEdge+1)/2; - break; - - case HEXAHEDRON: - nDOFs = nDOFsEdge*nDOFsEdge*nDOFsEdge; - break; - - default: - SU2_MPI::Error("Unsupported element type encountered.", CURRENT_FUNCTION); - } - - // Return nDOFs. - return nDOFs; -} - -CFEMInterpolationGrid::CFEMInterpolationGrid(void){} - -CFEMInterpolationGrid::CFEMInterpolationGrid(CConfig** config, - CGeometry**** geometry, - unsigned short mnZone, - const SolutionFormatT mnSolutionFormat) -{ - unsigned short iZone; - - nDim = geometry[ZONE_0][INST_0][MESH_0]->GetnDim(); - nZone = mnZone; - - // Loop over the number of zones to copy the data from geometry to grid class. - mGridZones.resize(nZone); - for(iZone = 0; iZone < nZone; iZone++) - mGridZones[iZone].CopySU2GeometryToGrid(config[iZone], geometry[iZone][INST_0][MESH_0]); - - // Store the solution format - mSolutionFormat = mnSolutionFormat; -} - -CFEMInterpolationGrid::~CFEMInterpolationGrid(void){} - -void CFEMInterpolationGrid::DetermineCoorInterpolation(CConfig** config, - vector > &coorInterpol, - const SolutionFormatT solFormatWrite) -{ - // Allocate the first index for coorInterpol. - coorInterpol.resize(mGridZones.size()); - - // Loop over the zones and determine the coordinates for which the - // interpolation must be carried out. - for(unsigned long i=0; i::const_iterator ZI =mGridZones.begin(); - ZI!=mGridZones.end(); ++ZI) - { - nElem += ZI->GetNVolumeElem(); - nGridDOFs += ZI->GetNGridDOFs(); - nSolDOFsDG += ZI->GetNSolDOFsDG(); - - if( ZI->HighOrderElementsInZone() ) highOrder = true; - } - - // Determine the format of the solution file. - if(nSolDOFs == (int) nGridDOFs) - { - // A vertex centered scheme is used, i.e. VertexCentered or FEM. - // When high order elements are present, set the format the FEM, - // otherwise VertexCentered is most logical (linear FEM gives the - // same result). - if( highOrder ) mSolutionFormat = FEM; - else mSolutionFormat = VertexCentered; - } - else - { - // An element based format is used, which is either CellCentered or DG_FEM. - // For CellCentered the number of solution DOFs is equal to the number of - // elements. For DG_FEM the number of solution DOFs is equal to nSolDOFsDG. - if( nSolDOFs == (int) nElem) mSolutionFormat = CellCentered; - else if(nSolDOFs == (int) nSolDOFsDG) mSolutionFormat = DG_FEM; - else - { - // Unknown format. Write an error message and exit. - SU2_MPI::Error("Unknown solution format.", CURRENT_FUNCTION); - } - } -} - -void CFEMInterpolationFaceOfElem::Copy(const CFEMInterpolationFaceOfElem &other) -{ - nCornerPoints = other.nCornerPoints; - for(unsigned short i=0; iGetSolutionInterpolation(); + for (iPoint = 0; iPoint < nPoint; iPoint++) { - /*--- Do not initialize variables for solution interpolation, since it makes the interpolation super slow and is not necessary ---*/ - if (!interp) { - for (iPoint = 0; iPoint < nPoint; iPoint++) { - - nonPhys = nodes->SetPrimVar(iPoint, FluidModel); - - /*--- Set mixture state ---*/ - FluidModel->SetTDStatePTTv(Pressure_Inf, MassFrac_Inf, Temperature_Inf, Temperature_ve_Inf); - - /*--- Compute other freestream quantities ---*/ - Density_Inf = FluidModel->GetDensity(); - Soundspeed_Inf = FluidModel->GetSoundSpeed(); - - sqvel = 0.0; - for (iDim = 0; iDim < nDim; iDim++){ - sqvel += Mvec_Inf[iDim]*Soundspeed_Inf * Mvec_Inf[iDim]*Soundspeed_Inf; - } - const auto& Energies_Inf = FluidModel->ComputeMixtureEnergies(); - - /*--- Initialize Solution & Solution_Old vectors ---*/ - for (iSpecies = 0; iSpecies < nSpecies; iSpecies++) { - Solution[iSpecies] = Density_Inf*MassFrac_Inf[iSpecies]; - } - for (iDim = 0; iDim < nDim; iDim++) { - Solution[nSpecies+iDim] = Density_Inf*Mvec_Inf[iDim]*Soundspeed_Inf; - } - Solution[nSpecies+nDim] = Density_Inf*(Energies_Inf[0] + 0.5*sqvel); - Solution[nSpecies+nDim+1] = Density_Inf*Energies_Inf[1]; - nodes->SetSolution(iPoint,Solution); - nodes->SetSolution_Old(iPoint,Solution); - - if(nonPhys) - counter_local++; + nonPhys = nodes->SetPrimVar(iPoint, FluidModel); + + /*--- Set mixture state ---*/ + FluidModel->SetTDStatePTTv(Pressure_Inf, MassFrac_Inf, Temperature_Inf, Temperature_ve_Inf); + + /*--- Compute other freestream quantities ---*/ + Density_Inf = FluidModel->GetDensity(); + Soundspeed_Inf = FluidModel->GetSoundSpeed(); + + sqvel = 0.0; + for (iDim = 0; iDim < nDim; iDim++){ + sqvel += Mvec_Inf[iDim]*Soundspeed_Inf * Mvec_Inf[iDim]*Soundspeed_Inf; + } + const auto& Energies_Inf = FluidModel->ComputeMixtureEnergies(); + + /*--- Initialize Solution & Solution_Old vectors ---*/ + for (iSpecies = 0; iSpecies < nSpecies; iSpecies++) { + Solution[iSpecies] = Density_Inf*MassFrac_Inf[iSpecies]; + } + for (iDim = 0; iDim < nDim; iDim++) { + Solution[nSpecies+iDim] = Density_Inf*Mvec_Inf[iDim]*Soundspeed_Inf; } + Solution[nSpecies+nDim] = Density_Inf*(Energies_Inf[0] + 0.5*sqvel); + Solution[nSpecies+nDim+1] = Density_Inf*Energies_Inf[1]; + nodes->SetSolution(iPoint,Solution); + nodes->SetSolution_Old(iPoint,Solution); + + if(nonPhys) + counter_local++; } + /*--- Count number of symmetry planes where each Vertex is inserted ---*/ for (unsigned long iMarker = 0; iMarker < geometry->GetnMarker(); iMarker++) { diff --git a/SU2_CFD/src/variables/CNEMOEulerVariable.cpp b/SU2_CFD/src/variables/CNEMOEulerVariable.cpp index 0227586c254..ba8720b0acb 100644 --- a/SU2_CFD/src/variables/CNEMOEulerVariable.cpp +++ b/SU2_CFD/src/variables/CNEMOEulerVariable.cpp @@ -142,45 +142,42 @@ CNEMOEulerVariable::CNEMOEulerVariable(su2double val_pressure, /* Under-relaxation parameter. */ LocalCFL.resize(nPoint) = su2double(0.0); - bool interp = config->GetSolutionInterpolation(); + /* Vector to count number of symmetry planes at each node. */ + symmetry.resize(nPoint) = su2double(0.0); - /*--- Do not initialize variables for solution interpolation, since it makes the interpolation super slow and is not necessary ---*/ - if (!interp) { + /*--- Loop over all points --*/ + for(unsigned long iPoint = 0; iPoint < nPoint; ++iPoint){ - /*--- Loop over all points --*/ - for(unsigned long iPoint = 0; iPoint < nPoint; ++iPoint){ + /*--- Reset velocity^2 [m2/s2] to zero ---*/ + sqvel = 0.0; - /*--- Reset velocity^2 [m2/s2] to zero ---*/ - sqvel = 0.0; - - /*--- Set mixture state ---*/ - fluidmodel->SetTDStatePTTv(val_pressure, val_massfrac, val_temperature, val_temperature_ve); - - /*--- Compute necessary quantities ---*/ - rho = fluidmodel->GetDensity(); - soundspeed = fluidmodel->ComputeSoundSpeed(); - for (iDim = 0; iDim < nDim; iDim++){ - sqvel += val_mach[iDim]*soundspeed * val_mach[iDim]*soundspeed; - } - energies = fluidmodel->ComputeMixtureEnergies(); - - /*--- Initialize Solution & Solution_Old vectors ---*/ - for (iSpecies = 0; iSpecies < nSpecies; iSpecies++) - Solution(iPoint,iSpecies) = rho*val_massfrac[iSpecies]; - for (iDim = 0; iDim < nDim; iDim++) - Solution(iPoint,nSpecies+iDim) = rho*val_mach[iDim]*soundspeed; - - Solution(iPoint,nSpecies+nDim) = rho*(energies[0]+0.5*sqvel); - Solution(iPoint,nSpecies+nDim+1) = rho*(energies[1]); - - Solution_Old = Solution; + /*--- Set mixture state ---*/ + fluidmodel->SetTDStatePTTv(val_pressure, val_massfrac, val_temperature, val_temperature_ve); + + /*--- Compute necessary quantities ---*/ + rho = fluidmodel->GetDensity(); + soundspeed = fluidmodel->ComputeSoundSpeed(); + for (iDim = 0; iDim < nDim; iDim++){ + sqvel += val_mach[iDim]*soundspeed * val_mach[iDim]*soundspeed; + } + energies = fluidmodel->ComputeMixtureEnergies(); + + /*--- Initialize Solution & Solution_Old vectors ---*/ + for (iSpecies = 0; iSpecies < nSpecies; iSpecies++) + Solution(iPoint,iSpecies) = rho*val_massfrac[iSpecies]; + for (iDim = 0; iDim < nDim; iDim++) + Solution(iPoint,nSpecies+iDim) = rho*val_mach[iDim]*soundspeed; - /*--- Assign primitive variables ---*/ - Primitive(iPoint,T_INDEX) = val_temperature; - Primitive(iPoint,TVE_INDEX) = val_temperature_ve; - Primitive(iPoint,P_INDEX) = val_pressure; - } - } + Solution(iPoint,nSpecies+nDim) = rho*(energies[0]+0.5*sqvel); + Solution(iPoint,nSpecies+nDim+1) = rho*(energies[1]); + + Solution_Old = Solution; + + /*--- Assign primitive variables ---*/ + Primitive(iPoint,T_INDEX) = val_temperature; + Primitive(iPoint,TVE_INDEX) = val_temperature_ve; + Primitive(iPoint,P_INDEX) = val_pressure; + } } void CNEMOEulerVariable::SetVelocity2(unsigned long iPoint) { diff --git a/SU2_INTERP/include/SU2_INTERP.hpp b/SU2_INTERP/include/SU2_INTERP.hpp deleted file mode 100644 index f4bb251ba35..00000000000 --- a/SU2_INTERP/include/SU2_INTERP.hpp +++ /dev/null @@ -1,50 +0,0 @@ -/*! - * \file SU2_SOL.hpp - * \brief Headers of the main subroutines of the code SU2_SOL. - * The subroutines and functions are in the SU2_SOL.cpp file. - * \author F. Palacios, T. Economon - * \version 6.1.0 "Falcon" - * - * The current SU2 release has been coordinated by the - * SU2 International Developers Society - * with selected contributions from the open-source community. - * - * The main research teams contributing to the current release are: - * - Prof. Juan J. Alonso's group at Stanford University. - * - Prof. Piero Colonna's group at Delft University of Technology. - * - Prof. Nicolas R. Gauger's group at Kaiserslautern University of Technology. - * - Prof. Alberto Guardone's group at Polytechnic University of Milan. - * - Prof. Rafael Palacios' group at Imperial College London. - * - Prof. Vincent Terrapon's group at the University of Liege. - * - Prof. Edwin van der Weide's group at the University of Twente. - * - Lab. of New Concepts in Aeronautics at Tech. Institute of Aeronautics. - * - * Copyright 2012-2018, Francisco D. Palacios, Thomas D. Economon, - * Tim Albring, and the SU2 contributors. - * - * SU2 is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * SU2 is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with SU2. If not, see . - */ - -#pragma once - -#include - -#include "../../SU2_CFD/include/fem_interpolation_structure.hpp" -#include "../../SU2_CFD/include/solvers/CSolver.hpp" -#include "../../SU2_CFD/include/output/COutput.hpp" -#include "../../Common/include/geometry/CGeometry.hpp" -#include "../../Common/include/CConfig.hpp" - - -using namespace std; diff --git a/SU2_INTERP/obj/Makefile.am b/SU2_INTERP/obj/Makefile.am deleted file mode 100644 index 17a9054d99a..00000000000 --- a/SU2_INTERP/obj/Makefile.am +++ /dev/null @@ -1,62 +0,0 @@ -################################################################################ -# -# \file Makefile.am -# \brief Makefile for SU2_SOL -# \author M. Colonno, T. Economon, F. Palacios -# \version 6.1.0 "Falcon" -# -# The current SU2 release has been coordinated by the -# SU2 International Developers Society -# with selected contributions from the open-source community. -# -# The main research teams contributing to the current release are: -# - Prof. Juan J. Alonso's group at Stanford University. -# - Prof. Piero Colonna's group at Delft University of Technology. -# - Prof. Nicolas R. Gauger's group at Kaiserslautern University of Technology. -# - Prof. Alberto Guardone's group at Polytechnic University of Milan. -# - Prof. Rafael Palacios' group at Imperial College London. -# - Prof. Vincent Terrapon's group at the University of Liege. -# - Prof. Edwin van der Weide's group at the University of Twente. -# - Lab. of New Concepts in Aeronautics at Tech. Institute of Aeronautics. -# -# Copyright 2012-2018, Francisco D. Palacios, Thomas D. Economon, -# Tim Albring, and the SU2 contributors. -# -# SU2 is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# SU2 is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with SU2. If not, see . -# -################################################################################ - -AUTOMAKE_OPTIONS = subdir-objects -ACLOCAL_AMFLAGS = ${ACLOCAL_FLAGS} - -bin_PROGRAMS = ../bin/SU2_INTERP - -___bin_SU2_INTERP_SOURCES = \ - ../include/SU2_INTERP.hpp \ - ../src/SU2_INTERP.cpp - -___bin_SU2_INTERP_CXXFLAGS = -___bin_SU2_INTERP_LDADD = \ - ../../SU2_CFD/obj/libSU2Core.a \ - ../../Common/lib/libSU2.a - -# always link to built dependencies from ./externals -___bin_SU2_INTERP_CXXFLAGS += @su2_externals_INCLUDES@ -___bin_SU2_INTERP_LDADD += @su2_externals_LIBS@ -___bin_SU2_INTERP_LDADD += @su2_externals_LIBPTHREAD@ - -# if BUILD_MUTATIONPP -___bin_SU2_INTERP_CXXFLAGS += @MUTATIONPP_CXX@ -___bin_SU2_INTERP_LDADD += @MUTATIONPP_LD@ -# endif diff --git a/SU2_INTERP/src/SU2_INTERP.cpp b/SU2_INTERP/src/SU2_INTERP.cpp deleted file mode 100644 index a5de9a48b0e..00000000000 --- a/SU2_INTERP/src/SU2_INTERP.cpp +++ /dev/null @@ -1,130 +0,0 @@ -/*! - * \file SU2_INTERP.cpp - * \brief Main file for the solution export/conversion code (SU2_SOL). - * \author F. Palacios, T. Economon - * \version 6.1.0 "Falcon" - * - * The current SU2 release has been coordinated by the - * SU2 International Developers Society - * with selected contributions from the open-source community. - * - * The main research teams contributing to the current release are: - * - Prof. Juan J. Alonso's group at Stanford University. - * - Prof. Piero Colonna's group at Delft University of Technology. - * - Prof. Nicolas R. Gauger's group at Kaiserslautern University of Technology. - * - Prof. Alberto Guardone's group at Polytechnic University of Milan. - * - Prof. Rafael Palacios' group at Imperial College London. - * - Prof. Vincent Terrapon's group at the University of Liege. - * - Prof. Edwin van der Weide's group at the University of Twente. - * - Lab. of New Concepts in Aeronautics at Tech. Institute of Aeronautics. - * - * Copyright 2012-2018, Francisco D. Palacios, Thomas D. Economon, - * Tim Albring, and the SU2 contributors. - * - * SU2 is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * SU2 is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with SU2. If not, see . - */ - -#include "../include/SU2_INTERP.hpp" - -using namespace std; - -int main(int argc, char *argv[]) { - - - unsigned short nZone = SINGLE_ZONE, nDim; - su2double StartTime = 0.0, StopTime = 0.0, UsedTime = 0.0; - char config_file_name[MAX_STRING_SIZE]; - int rank = MASTER_NODE; - int size = SINGLE_NODE; - bool periodic = false; - - - /*--- MPI initialization ---*/ - -#ifdef HAVE_MPI - SU2_MPI::Init(&argc,&argv); - SU2_MPI::Comm MPICommunicator(MPI_COMM_WORLD); -#else - SU2_Comm MPICommunicator(0); -#endif - - rank = SU2_MPI::GetRank(); - size = SU2_MPI::GetSize(); - - - - if (argc == 2) { strcpy(config_file_name, argv[1]); } - else { strcpy(config_file_name, "default.cfg"); } - - - /*--- Read the name and format of the input mesh file to get from the mesh - file the number of zones and dimensions from the numerical grid (required - for variables allocation). ---*/ - - CConfig *config = NULL; - config = new CConfig(config_file_name, SU2_CFD); - - if (config->GetnConfigFiles() > 0) - nZone = config->GetnConfigFiles(); - else - nZone = config->GetnZone(config->GetMesh_FileName(), config->GetMesh_FileFormat()); - nDim = config->GetnDim(config->GetMesh_FileName(), config->GetMesh_FileFormat()); - //periodic = CConfig::GetPeriodic(config->GetMesh_FileName(), config->GetMesh_FileFormat(), config); - - - CFEMInterpolationDriver *InterpolationDriver = NULL; - -#ifdef HAVE_MPI - StartTime = MPI_Wtime(); -#else - StartTime = su2double(clock())/su2double(CLOCKS_PER_SEC); -#endif - - - InterpolationDriver = new CFEMInterpolationDriver(config_file_name, nZone, nDim, periodic, MPICommunicator); - - InterpolationDriver->Interpolate(); - - InterpolationDriver->Output(); - - InterpolationDriver->Postprocessing(); - - -#ifdef HAVE_MPI - StopTime = MPI_Wtime(); -#else - StopTime = su2double(clock())/su2double(CLOCKS_PER_SEC); -#endif - - /*--- Compute/print the total time for performance benchmarking. ---*/ - - UsedTime = StopTime-StartTime; - if (rank == MASTER_NODE) { - cout << "\nCompleted in " << fixed << UsedTime << " seconds on "<< size; - if (size == 1) cout << " core." << endl; else cout << " cores." << endl; - } - - /*--- Exit the solver cleanly ---*/ - - if (rank == MASTER_NODE) - cout << endl <<"------------------------ Exit Success (SU2_INTERP) ----------------------" << endl << endl; - - /*--- Finalize MPI parallelization ---*/ - -#ifdef HAVE_MPI - SU2_MPI::Finalize(); -#endif - - return EXIT_SUCCESS; -} \ No newline at end of file diff --git a/SU2_INTERP/src/meson.build b/SU2_INTERP/src/meson.build deleted file mode 100644 index be77f3f8db0..00000000000 --- a/SU2_INTERP/src/meson.build +++ /dev/null @@ -1,10 +0,0 @@ -su2_interp_src = ['SU2_INTERP.cpp'] -if get_option('enable-normal') - su2_interp = executable('SU2_INTERP', - su2_interp_src, - install: true, - dependencies: [su2_deps, common_dep, su2_cfd_dep], - cpp_args :[default_warning_flags, su2_cpp_args]) - - -endif \ No newline at end of file diff --git a/configure.ac b/configure.ac index ca1b96c3202..e7cbc28ce24 100644 --- a/configure.ac +++ b/configure.ac @@ -110,10 +110,7 @@ AC_ARG_ENABLE(SOL, [build_SOL=$enableval], [build_SOL="yes"]) AC_ARG_ENABLE(GEO, AS_HELP_STRING([--disable-GEO], [build the SU2_GEO executable (default = yes)]), - [build_GEO=$enableval], [build_GEO="yes"]) -AC_ARG_ENABLE(INTERP, - AS_HELP_STRING([--disable-INTERP], [build the SU2_INTERP executable (default = yes)]), - [build_INTERP=$enableval], [build_INTERP="yes"]) + [build_GEO=$enableval], [build_GEO="yes"]) AC_ARG_ENABLE(PY_WRAPPER, AS_HELP_STRING([--enable-PY_WRAPPER], [wrap the SU2 code with Python (default = no)]), [build_PY_WRAPPER="yes"], [build_PY_WRAPPER="no"]) @@ -332,7 +329,6 @@ AC_OUTPUT(Makefile \ SU2_DEF/obj/Makefile \ SU2_SOL/obj/Makefile \ SU2_GEO/obj/Makefile \ - SU2_INTERP/obj/Makefile \ SU2_PY/Makefile \ SU2_PY/pySU2/Makefile) @@ -411,7 +407,6 @@ Build Configuration Summary: Build SU2_DEF: $build_DEF Build SU2_SOL: $build_SOL Build SU2_GEO: $build_GEO - Build SU2_INTERP: $build_INTERP Build Py Wrapper: $build_PY_WRAPPER Please be sure to add the [\$]SU2_HOME and [\$]SU2_RUN environment variables, diff --git a/meson.build b/meson.build index f086926031a..969e42b21a7 100644 --- a/meson.build +++ b/meson.build @@ -185,8 +185,6 @@ subdir('SU2_DEF/src') subdir('SU2_GEO/src') # compile SU2_SOL executable subdir('SU2_SOL/src') -# compile SU2_INTERP executable -subdir('SU2_INTERP/src') # install python scripts subdir('SU2_PY') # unit tests From 67ed3c2e6de29a21c4d26666c0588b9f0934b561 Mon Sep 17 00:00:00 2001 From: fmpmorgado Date: Wed, 20 Jan 2021 14:25:12 +0000 Subject: [PATCH 14/23] Adressed problems in regression tests - Residuals were affected if BC_Sym was called after the strong BC routine --- SU2_CFD/src/integration/CIntegration.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/SU2_CFD/src/integration/CIntegration.cpp b/SU2_CFD/src/integration/CIntegration.cpp index 0d906d4f2ce..7ca291510b0 100644 --- a/SU2_CFD/src/integration/CIntegration.cpp +++ b/SU2_CFD/src/integration/CIntegration.cpp @@ -143,6 +143,10 @@ void CIntegration::Space_Integration(CGeometry *geometry, case DIELEC_BOUNDARY: solver_container[MainSolver]->BC_Dielec(geometry, solver_container, conv_bound_numerics, config, iMarker); break; + case SYMMETRY_PLANE: + if (!config->GetNEMOProblem()) + solver_container[MainSolver]->BC_Sym_Plane(geometry, solver_container, conv_bound_numerics, visc_bound_numerics, config, iMarker); + break; } } @@ -186,7 +190,7 @@ void CIntegration::Space_Integration(CGeometry *geometry, for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { KindBC = config->GetMarker_All_KindBC(iMarker); - if (KindBC == SYMMETRY_PLANE) solver_container[MainSolver]->BC_Sym_Plane(geometry, solver_container, conv_bound_numerics, visc_bound_numerics, config, iMarker); + if (KindBC == SYMMETRY_PLANE && config->GetNEMOProblem()) solver_container[MainSolver]->BC_Sym_Plane(geometry, solver_container, conv_bound_numerics, visc_bound_numerics, config, iMarker); } } From 734a874cee419b3312ff4cd1922e5c07f5b443cd Mon Sep 17 00:00:00 2001 From: fmpmorgado Date: Wed, 20 Jan 2021 15:14:41 +0000 Subject: [PATCH 15/23] Update on thermalbath regression test --- TestCases/parallel_regression.py | 4 ++-- TestCases/serial_regression.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/TestCases/parallel_regression.py b/TestCases/parallel_regression.py index 75fe71655c9..9e606fdf204 100644 --- a/TestCases/parallel_regression.py +++ b/TestCases/parallel_regression.py @@ -47,7 +47,7 @@ def main(): thermalbath.cfg_dir = "nonequilibrium/thermalbath/finitechemistry" thermalbath.cfg_file = "thermalbath.cfg" thermalbath.test_iter = 10 - thermalbath.test_vals = [2.473627, 2.473627, -11.989166, -11.879331, -32.000000, 10.804939] + thermalbath.test_vals = [2.598566, 2.598566, -12.082623, -12.170310, -32.000000, 10.929878] thermalbath.su2_exec = "mpirun -n 2 SU2_CFD" thermalbath.timeout = 1600 thermalbath.new_output = True @@ -59,7 +59,7 @@ def main(): thermalbath_frozen.cfg_dir = "nonequilibrium/thermalbath/frozen" thermalbath_frozen.cfg_file = "thermalbath_frozen.cfg" thermalbath_frozen.test_iter = 10 - thermalbath_frozen.test_vals = [ -32.000000, -32.000000, -11.92359, -11.962329, -32.000000, 10.813864] + thermalbath_frozen.test_vals = [ -32.000000, -32.000000, -11.988565, -12.042617, -32.000000, 10.938802] thermalbath_frozen.su2_exec = "mpirun -n 2 SU2_CFD" thermalbath_frozen.timeout = 1600 thermalbath_frozen.new_output = True diff --git a/TestCases/serial_regression.py b/TestCases/serial_regression.py index 4cb0e85f6f8..abfcfce0001 100644 --- a/TestCases/serial_regression.py +++ b/TestCases/serial_regression.py @@ -45,7 +45,7 @@ def main(): thermalbath.cfg_dir = "nonequilibrium/thermalbath/finitechemistry" thermalbath.cfg_file = "thermalbath.cfg" thermalbath.test_iter = 10 - thermalbath.test_vals = [2.473627, 2.473627, -12.033039, -11.945257, -32.000000, 10.804939] #last 4 columns + thermalbath.test_vals = [2.598566, 2.598566, -12.154360, -12.217291, -32.000000, 10.929878] #last 4 columns thermalbath.su2_exec = "SU2_CFD" thermalbath.timeout = 1600 thermalbath.new_output = True @@ -57,7 +57,7 @@ def main(): thermalbath_frozen.cfg_dir = "nonequilibrium/thermalbath/frozen" thermalbath_frozen.cfg_file = "thermalbath_frozen.cfg" thermalbath_frozen.test_iter = 10 - thermalbath_frozen.test_vals = [-32.000000, -32.000000, -11.953727, -12.066776, -32.000000, 10.813864] #last 4 columns + thermalbath_frozen.test_vals = [-32.000000, -32.000000, -12.030273, -12.066776, -32.000000, 10.938802] #last 4 columns thermalbath_frozen.su2_exec = "SU2_CFD" thermalbath_frozen.timeout = 1600 thermalbath_frozen.new_output = True From a67e6458bebc7ee6611a2e3eb57f4f9f44e10877 Mon Sep 17 00:00:00 2001 From: fmpmorgado Date: Wed, 20 Jan 2021 18:49:38 +0000 Subject: [PATCH 16/23] Changed vector name and simplified code to not manipulate Volume --- SU2_CFD/src/solvers/CNEMOEulerSolver.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp b/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp index a1adc827a9a..2f124a3f431 100644 --- a/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp +++ b/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp @@ -1345,7 +1345,6 @@ void CNEMOEulerSolver::ExplicitEuler_Iteration(CGeometry *geometry, CSolver **so Vol = (geometry->nodes->GetVolume(iPoint) + geometry->nodes->GetPeriodicVolume(iPoint)); - if (nodes->GetSymmetry(iPoint) > 0) Vol*=2*nodes->GetSymmetry(iPoint); Delta = nodes->GetDelta_Time(iPoint) / Vol; local_Res_TruncError = nodes->GetResTruncError(iPoint); @@ -1904,6 +1903,10 @@ void CNEMOEulerSolver::BC_Sym_Plane(CGeometry *geometry, CSolver **solver_contai unsigned short iDim, iVar; su2double Area, Normal[3], UnitNormal[3], Normal_Product; const su2double* Residual_Old; + su2double *Residual = new su2double[nVar]; + + for(iVar = 0; iVar < nVar; iVar++) + Residual[iVar]=0.0; /*--- Loop over all the vertices on this boundary marker ---*/ for(iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { @@ -1919,20 +1922,22 @@ void CNEMOEulerSolver::BC_Sym_Plane(CGeometry *geometry, CSolver **solver_contai Residual_Old = LinSysRes.GetBlock(iPoint); - for(iVar = 0; iVar < nVar; iVar++) - Res_Conv[iVar] = Residual_Old[iVar]; + for(iDim = 0; iDim < nDim; iDim++) + Residual[nSpecies+iDim] = Residual_Old[nSpecies+iDim]; Normal_Product = 0.0; for(iDim = 0; iDim < nDim; iDim++) - Normal_Product+= Res_Conv[nSpecies+iDim]*UnitNormal[iDim]; + Normal_Product+= Residual[nSpecies+iDim]*UnitNormal[iDim]; + /* --- Removes momentum residual normal to the Vertex in symmetry Plane ---*/ for(iDim = 0; iDim < nDim; iDim++) - Res_Conv[nSpecies+iDim]-=2*Normal_Product*UnitNormal[iDim]; + Residual[nSpecies+iDim]=(Residual[nSpecies+iDim]-2*Normal_Product*UnitNormal[iDim])*abs(UnitNormal[iDim]); - LinSysRes.AddBlock(iPoint, Res_Conv); + LinSysRes.AddBlock(iPoint, Residual); } + delete [] Residual; } void CNEMOEulerSolver::BC_Far_Field(CGeometry *geometry, CSolver **solver_container, From 992589d1cf04048b71c84d81178e26a18baea13f Mon Sep 17 00:00:00 2001 From: fmpmorgado Date: Wed, 20 Jan 2021 23:19:25 +0000 Subject: [PATCH 17/23] Changing thermalbath regressin value again --- TestCases/parallel_regression.py | 4 ++-- TestCases/serial_regression.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/TestCases/parallel_regression.py b/TestCases/parallel_regression.py index 02a528a9bd7..848fd715746 100644 --- a/TestCases/parallel_regression.py +++ b/TestCases/parallel_regression.py @@ -47,7 +47,7 @@ def main(): thermalbath.cfg_dir = "nonequilibrium/thermalbath/finitechemistry" thermalbath.cfg_file = "thermalbath.cfg" thermalbath.test_iter = 10 - thermalbath.test_vals = [2.598566, 2.598566, -12.082623, -12.170310, -32.000000, 10.929878] + thermalbath.test_vals = [2.473627, 2.473627, -12.082623, -12.170310, -32.000000, 10.804939] thermalbath.su2_exec = "mpirun -n 2 SU2_CFD" thermalbath.timeout = 1600 thermalbath.new_output = True @@ -59,7 +59,7 @@ def main(): thermalbath_frozen.cfg_dir = "nonequilibrium/thermalbath/frozen" thermalbath_frozen.cfg_file = "thermalbath_frozen.cfg" thermalbath_frozen.test_iter = 10 - thermalbath_frozen.test_vals = [ -32.000000, -32.000000, -11.988565, -12.042617, -32.000000, 10.938802] + thermalbath_frozen.test_vals = [-32.000000, -32.000000, -11.988565, -12.042617, -32.000000, 10.813864] thermalbath_frozen.su2_exec = "mpirun -n 2 SU2_CFD" thermalbath_frozen.timeout = 1600 thermalbath_frozen.new_output = True diff --git a/TestCases/serial_regression.py b/TestCases/serial_regression.py index fe579debcca..0354a304746 100644 --- a/TestCases/serial_regression.py +++ b/TestCases/serial_regression.py @@ -45,7 +45,7 @@ def main(): thermalbath.cfg_dir = "nonequilibrium/thermalbath/finitechemistry" thermalbath.cfg_file = "thermalbath.cfg" thermalbath.test_iter = 10 - thermalbath.test_vals = [2.598566, 2.598566, -12.154360, -12.217291, -32.000000, 10.929878] #last 4 columns + thermalbath.test_vals = [2.473627, 2.473627, -12.154360, -12.217291, -32.000000, 10.804939] #last 4 columns thermalbath.su2_exec = "SU2_CFD" thermalbath.timeout = 1600 thermalbath.new_output = True @@ -57,7 +57,7 @@ def main(): thermalbath_frozen.cfg_dir = "nonequilibrium/thermalbath/frozen" thermalbath_frozen.cfg_file = "thermalbath_frozen.cfg" thermalbath_frozen.test_iter = 10 - thermalbath_frozen.test_vals = [-32.000000, -32.000000, -12.030273, -12.066776, -32.000000, 10.938802] #last 4 columns + thermalbath_frozen.test_vals = [-32.000000, -32.000000, -12.030273, -12.066776, -32.000000, 10.813864] #last 4 columns thermalbath_frozen.su2_exec = "SU2_CFD" thermalbath_frozen.timeout = 1600 thermalbath_frozen.new_output = True From 0708c1e11695f6b8b1d07bbef37faa5ca6f6a2af Mon Sep 17 00:00:00 2001 From: fmpmorgado Date: Thu, 21 Jan 2021 20:09:20 +0000 Subject: [PATCH 18/23] Removing code complexity --- SU2_CFD/src/solvers/CNEMOEulerSolver.cpp | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp b/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp index d994083ba03..a54de8ed1af 100644 --- a/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp +++ b/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp @@ -1924,18 +1924,9 @@ void CNEMOEulerSolver::BC_Sym_Plane(CGeometry *geometry, CSolver **solver_contai Residual_Old = LinSysRes.GetBlock(iPoint); for(iDim = 0; iDim < nDim; iDim++) - Residual[nSpecies+iDim] = Residual_Old[nSpecies+iDim]; + Residual[nSpecies+iDim] = Residual_Old[nSpecies+iDim]*abs(UnitNormal[iDim]); - Normal_Product = 0.0; - - for(iDim = 0; iDim < nDim; iDim++) - Normal_Product+= Residual[nSpecies+iDim]*UnitNormal[iDim]; - - /* --- Removes momentum residual normal to the Vertex in symmetry Plane ---*/ - for(iDim = 0; iDim < nDim; iDim++) - Residual[nSpecies+iDim]=(Residual[nSpecies+iDim]-2*Normal_Product*UnitNormal[iDim])*abs(UnitNormal[iDim]); - - LinSysRes.AddBlock(iPoint, Residual); + LinSysRes.SubtractBlock(iPoint, Residual); } delete [] Residual; From 77cabde864630dad9f8900645706cb45e4678c2d Mon Sep 17 00:00:00 2001 From: fmpmorgado Date: Thu, 21 Jan 2021 20:15:39 +0000 Subject: [PATCH 19/23] Not used Variable --- SU2_CFD/src/solvers/CNEMOEulerSolver.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp b/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp index a54de8ed1af..c741a9e15a1 100644 --- a/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp +++ b/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp @@ -1902,7 +1902,7 @@ void CNEMOEulerSolver::BC_Sym_Plane(CGeometry *geometry, CSolver **solver_contai CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { unsigned long iPoint, iVertex; unsigned short iDim, iVar; - su2double Area, Normal[3], UnitNormal[3], Normal_Product; + su2double Area, Normal[3], UnitNormal[3]; const su2double* Residual_Old; su2double *Residual = new su2double[nVar]; From de4714842be1f1249c0e199ad19b1b6b4fd7a620 Mon Sep 17 00:00:00 2001 From: fmpmorgado Date: Thu, 21 Jan 2021 21:53:48 +0000 Subject: [PATCH 20/23] Modified Euler_wall_bc to be the same as in CEulerSolver --- SU2_CFD/src/solvers/CNEMOEulerSolver.cpp | 336 +++++++++++++++++------ 1 file changed, 251 insertions(+), 85 deletions(-) diff --git a/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp b/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp index c741a9e15a1..1311b8c350a 100644 --- a/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp +++ b/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp @@ -1906,6 +1906,8 @@ void CNEMOEulerSolver::BC_Sym_Plane(CGeometry *geometry, CSolver **solver_contai const su2double* Residual_Old; su2double *Residual = new su2double[nVar]; + BC_Euler_Wall(geometry, solver_container, conv_numerics, visc_numerics, config, val_marker); + for(iVar = 0; iVar < nVar; iVar++) Residual[iVar]=0.0; @@ -2846,125 +2848,289 @@ void CNEMOEulerSolver::BC_Supersonic_Outlet(CGeometry *geometry, CSolver **solut void CNEMOEulerSolver::BC_Euler_Wall(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { - unsigned short iDim, jDim, iSpecies, iVar, jVar; - unsigned long iPoint, iVertex; + unsigned short iDim, iVar; + unsigned long iVertex, iPoint; - su2double *Normal = nullptr, Area, UnitNormal[3], *NormalArea, - **Jacobian_b, **DubDu, - rho, cs, P, rhoE, rhoEve, conc, *u, *dPdU; + bool implicit = (config->GetKind_TimeIntScheme() == EULER_IMPLICIT); + bool viscous = config->GetViscous(); + bool preprocessed = false; - bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); + unsigned short VEL_INDEX = nodes->GetVelIndex(); - /*--- Allocate arrays ---*/ - Normal = new su2double[nDim]; - NormalArea = new su2double[nDim]; - Jacobian_b = new su2double*[nVar]; - DubDu = new su2double*[nVar]; - u = new su2double[nDim]; + /*--- Allocation of variables necessary for convective fluxes. ---*/ + su2double Area, ProjVelocity_i, *V_reflected, *V_domain, Normal[MAXNDIM] = {0.0}, UnitNormal[MAXNDIM] = {0.0}; - for (iVar = 0; iVar < nVar; iVar++) { - Jacobian_b[iVar] = new su2double[nVar]; - DubDu[iVar] = new su2double[nVar]; - } + /*--- Allocation of variables necessary for viscous fluxes. ---*/ + su2double ProjGradient, ProjNormVelGrad, ProjTangVelGrad, TangentialNorm, + Tangential[MAXNDIM] = {0.0}, GradNormVel[MAXNDIM] = {0.0}, GradTangVel[MAXNDIM] = {0.0}; - /*--- Get species molar mass ---*/ - auto& Ms = FluidModel->GetSpeciesMolarMass(); + /*--- Allocation of primitive gradient arrays for viscous fluxes. ---*/ + su2double** Grad_Reflected = new su2double*[nPrimVarGrad]; + for (iVar = 0; iVar < nPrimVarGrad; iVar++) Grad_Reflected[iVar] = new su2double[nDim]; - /*--- Loop over all the vertices on this boundary (val_marker) ---*/ + /*--- Loop over all the vertices on this boundary marker. ---*/ + + SU2_OMP_FOR_DYN(OMP_MIN_SIZE) for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { + if (!preprocessed || geometry->bound_is_straight[val_marker] != true) { + /*----------------------------------------------------------------------------------------------*/ + /*--- Preprocessing: ---*/ + /*--- Compute the unit normal and (in case of viscous flow) a corresponding unit tangential ---*/ + /*--- to that normal. On a straight(2D)/plane(3D) boundary these two vectors are constant. ---*/ + /*--- This circumstance is checked in gemoetry->ComputeSurf_Straightness(...) and stored ---*/ + /*--- such that the recomputation does not occur for each node. On true symmetry planes, the ---*/ + /*--- normal is constant but this routines is used for Symmetry, Euler-Wall in inviscid flow ---*/ + /*--- and Euler Wall in viscous flow as well. In the latter curvy boundaries are likely to ---*/ + /*--- happen. In doubt, the conditional above which checks straightness can be thrown out ---*/ + /*--- such that the recomputation is done for each node (which comes with a tiny performance ---*/ + /*--- penalty). ---*/ + /*----------------------------------------------------------------------------------------------*/ + + preprocessed = true; + + /*--- Normal vector for a random vertex (zero) on this marker (negate for outward convention). ---*/ + geometry->vertex[val_marker][iVertex]->GetNormal(Normal); + for (iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim]; + + /*--- Compute unit normal, to be used for unit tangential, projected velocity and velocity + component gradients. ---*/ + Area = GeometryToolbox::Norm(nDim, Normal); + + for (iDim = 0; iDim < nDim; iDim++) UnitNormal[iDim] = -Normal[iDim] / Area; + + /*--- Preprocessing: Compute unit tangential, the direction is arbitrary as long as + t*n=0 && |t|_2 = 1 ---*/ + if (viscous) { + switch (nDim) { + case 2: { + Tangential[0] = -UnitNormal[1]; + Tangential[1] = UnitNormal[0]; + break; + } + case 3: { + /*--- n = ai + bj + ck, if |b| > |c| ---*/ + if (abs(UnitNormal[1]) > abs(UnitNormal[2])) { + /*--- t = bi + (c-a)j - bk ---*/ + Tangential[0] = UnitNormal[1]; + Tangential[1] = UnitNormal[2] - UnitNormal[0]; + Tangential[2] = -UnitNormal[1]; + } else { + /*--- t = ci - cj + (b-a)k ---*/ + Tangential[0] = UnitNormal[2]; + Tangential[1] = -UnitNormal[2]; + Tangential[2] = UnitNormal[1] - UnitNormal[0]; + } + /*--- Make it a unit vector. ---*/ + TangentialNorm = sqrt(pow(Tangential[0], 2) + pow(Tangential[1], 2) + pow(Tangential[2], 2)); + Tangential[0] = Tangential[0] / TangentialNorm; + Tangential[1] = Tangential[1] / TangentialNorm; + Tangential[2] = Tangential[2] / TangentialNorm; + break; + } + } // switch + } // if viscous + } // if bound_is_straight + iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); - /*--- Check if the node belongs to the domain (i.e, not a halo node) ---*/ + /*--- Check if the node belongs to the domain (i.e., not a halo node) ---*/ if (geometry->nodes->GetDomain(iPoint)) { + /*-------------------------------------------------------------------------------*/ + /*--- Step 1: For the convective fluxes, create a reflected state of the ---*/ + /*--- Primitive variables by copying all interior values to the ---*/ + /*--- reflected. Only the velocity is mirrored along the symmetry ---*/ + /*--- axis. Based on the Upwind_Residual routine. ---*/ + /*-------------------------------------------------------------------------------*/ - /*--- Normal vector for this vertex (negative for outward convention) ---*/ + /*--- Allocate the reflected state at the symmetry boundary. ---*/ + V_reflected = GetCharacPrimVar(val_marker, iVertex); + + /*--- Grid movement ---*/ + if (dynamic_grid) + conv_numerics->SetGridVel(geometry->nodes->GetGridVel(iPoint), geometry->nodes->GetGridVel(iPoint)); + + /*--- Normal vector for this vertex (negate for outward convention). ---*/ geometry->vertex[val_marker][iVertex]->GetNormal(Normal); + for (iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim]; + conv_numerics->SetNormal(Normal); - /*--- Calculate parameters from the geometry ---*/ - Area = GeometryToolbox::Norm(nDim, Normal); + /*--- Get current solution at this boundary node ---*/ + V_domain = nodes->GetPrimitive(iPoint); - for (iDim = 0; iDim < nDim; iDim++){ - NormalArea[iDim] = -Normal[iDim]; - UnitNormal[iDim] = -Normal[iDim]/Area; - } + /*--- Set the reflected state based on the boundary node. Scalars are copied and + the velocity is mirrored along the symmetry boundary, i.e. the velocity in + normal direction is substracted twice. ---*/ + for (iVar = 0; iVar < nPrimVar; iVar++) V_reflected[iVar] = nodes->GetPrimitive(iPoint, iVar); - /*--- Retrieve the pressure on the vertex ---*/ - P = nodes->GetPressure(iPoint); + /*--- Compute velocity in normal direction (ProjVelcity_i=(v*n)) und substract twice from + velocity in normal direction: v_r = v - 2 (v*n)n ---*/ + ProjVelocity_i = nodes->GetProjVel(iPoint, UnitNormal); - /*--- Apply the flow-tangency b.c. to the convective flux ---*/ - for (iSpecies = 0; iSpecies < nSpecies; iSpecies++) - Residual[iSpecies] = 0.0; - for (iDim = 0; iDim < nDim; iDim++){ - Residual[nSpecies+iDim] = P * UnitNormal[iDim] * Area; + /*--- Adjustment to v.n due to grid movement. ---*/ + if (dynamic_grid) { + ProjVelocity_i -= GeometryToolbox::DotProduct(nDim, geometry->nodes->GetGridVel(iPoint), UnitNormal); } - Residual[nSpecies+nDim] = 0.0; - Residual[nSpecies+nDim+1] = 0.0; - /*--- Add value to the residual ---*/ - LinSysRes.AddBlock(iPoint, Residual); + for (iDim = 0; iDim < nDim; iDim++) + V_reflected[VEL_INDEX + iDim] = nodes->GetVelocity(iPoint, iDim) - 2.0 * ProjVelocity_i * UnitNormal[iDim]; + + /*--- Set Primitive and Secondary for numerics class. ---*/ + conv_numerics->SetPrimitive(V_domain, V_reflected); + conv_numerics->SetConservative(nodes->GetSolution(iPoint),nodes->GetSolution(iPoint)); + + conv_numerics->SetdPdU (nodes->GetdPdU(iPoint), nodes->GetdPdU(iPoint)); + conv_numerics->SetdTdU (nodes->GetdTdU(iPoint), nodes->GetdTdU(iPoint)); + conv_numerics->SetdTvedU(nodes->GetdTvedU(iPoint), nodes->GetdTvedU(iPoint)); + conv_numerics->SetEve (nodes->GetEve(iPoint), nodes->GetEve(iPoint)); + conv_numerics->SetCvve (nodes->GetCvve(iPoint), nodes->GetCvve(iPoint)); + conv_numerics->SetGamma (nodes->GetGamma(iPoint), nodes->GetGamma(iPoint)); + + /*--- Compute the residual using an upwind scheme. ---*/ + auto residual = conv_numerics->ComputeResidual(config); + + /*--- Update residual value ---*/ + LinSysRes.AddBlock(iPoint, residual); - /*--- If using implicit time-stepping, calculate b.c. contribution to Jacobian ---*/ + /*--- Jacobian contribution for implicit integration. ---*/ if (implicit) { + Jacobian.AddBlock2Diag(iPoint, residual.jacobian_i); + } - /*--- Initialize Jacobian ---*/ - for (iVar = 0; iVar < nVar; iVar++) - for (jVar = 0; jVar < nVar; jVar++) - Jacobian_i[iVar][jVar] = 0.0; - - /*--- Calculate state i ---*/ - rho = nodes->GetDensity(iPoint); - rhoE = nodes->GetSolution(iPoint,nSpecies+nDim); - rhoEve = nodes->GetSolution(iPoint,nSpecies+nDim+1); - dPdU = nodes->GetdPdU(iPoint); - for (iDim = 0; iDim < nDim; iDim++) - u[iDim] = nodes->GetVelocity(iPoint,iDim); + if (viscous) { + /*-------------------------------------------------------------------------------*/ + /*--- Step 2: The viscous fluxes of the Navier-Stokes equations depend on the ---*/ + /*--- Primitive variables and their gradients. The viscous numerics ---*/ + /*--- container is filled just as the convective numerics container, ---*/ + /*--- but the primitive gradients of the reflected state have to be ---*/ + /*--- determined additionally such that symmetry at the boundary is ---*/ + /*--- enforced. Based on the Viscous_Residual routine. ---*/ + /*-------------------------------------------------------------------------------*/ + + /*--- Set the normal vector and the coordinates. ---*/ + visc_numerics->SetCoord(geometry->nodes->GetCoord(iPoint), geometry->nodes->GetCoord(iPoint)); + visc_numerics->SetNormal(Normal); + + /*--- Primitive variables, and gradient ---*/ + visc_numerics->SetPrimitive(V_domain, V_reflected); + + visc_numerics->SetConservative(nodes->GetSolution(iPoint), nodes->GetSolution(iPoint)); + + /*--- Also need to correct Gradient for Conservative Quantities ?? ---*/ + // visc_numerics->SetConsVarGradient(nodes->GetGradient(iPoint), nodes->GetGradient(iPoint) ); - conc = 0.0; - for (iSpecies = 0; iSpecies < nSpecies; iSpecies++) { - cs = nodes->GetMassFraction(iPoint,iSpecies); - conc += cs * rho/Ms[iSpecies]; + /*--- Pass supplementary information to CNumerics ---*/ + visc_numerics->SetdPdU (nodes->GetdPdU(iPoint), nodes->GetdPdU(iPoint)); + visc_numerics->SetdTdU (nodes->GetdTdU(iPoint), nodes->GetdTdU(iPoint)); + visc_numerics->SetdTvedU(nodes->GetdTvedU(iPoint), nodes->GetdTvedU(iPoint)); + visc_numerics->SetEve (nodes->GetEve(iPoint), nodes->GetEve(iPoint)); + visc_numerics->SetCvve (nodes->GetCvve(iPoint), nodes->GetCvve(iPoint)); - /////// NEW ////// - for (iDim = 0; iDim < nDim; iDim++) { - Jacobian_i[nSpecies+iDim][iSpecies] = dPdU[iSpecies] * UnitNormal[iDim]; - Jacobian_i[iSpecies][nSpecies+iDim] = cs * UnitNormal[iDim]; + /*--- Species diffusion coefficients ---*/ + visc_numerics->SetDiffusionCoeff(nodes->GetDiffusionCoeff(iPoint), + nodes->GetDiffusionCoeff(iPoint)); + + /*--- Laminar viscosity ---*/ + visc_numerics->SetLaminarViscosity(nodes->GetLaminarViscosity(iPoint), + nodes->GetLaminarViscosity(iPoint)); + + /*--- Eddy viscosity ---*/ + visc_numerics->SetEddyViscosity(nodes->GetEddyViscosity(iPoint), + nodes->GetEddyViscosity(iPoint)); + + /*--- Thermal conductivity ---*/ + visc_numerics->SetThermalConductivity(nodes->GetThermalConductivity(iPoint), + nodes->GetThermalConductivity(iPoint)); + + /*--- Vib-el. thermal conductivity ---*/ + visc_numerics->SetThermalConductivity_ve(nodes->GetThermalConductivity_ve(iPoint), + nodes->GetThermalConductivity_ve(iPoint)); + + /*--- For viscous Fluxes also the gradients of the primitives need to be determined. + 1. The gradients of scalars are mirrored along the sym plane just as velocity for the primitives + 2. The gradients of the velocity components need more attention, i.e. the gradient of the + normal velocity in tangential direction is mirrored and the gradient of the tangential velocity in + normal direction is mirrored. ---*/ + + /*--- Get gradients of primitives of boundary cell ---*/ + for (iVar = 0; iVar < nPrimVarGrad; iVar++) + for (iDim = 0; iDim < nDim; iDim++) + Grad_Reflected[iVar][iDim] = nodes->GetGradient_Primitive(iPoint, iVar, iDim); + + /*--- Reflect the gradients for all scalars including the velocity components. + The gradients of the velocity components are set later with the + correct values: grad(V)_r = grad(V) - 2 [grad(V)*n]n, V beeing any primitive ---*/ + for (iVar = 0; iVar < nPrimVarGrad; iVar++) { + if (iVar == 0 || iVar > nDim) { // Exclude velocity component gradients + + /*--- Compute projected part of the gradient in a dot product ---*/ + ProjGradient = 0.0; + for (iDim = 0; iDim < nDim; iDim++) ProjGradient += Grad_Reflected[iVar][iDim] * UnitNormal[iDim]; + + for (iDim = 0; iDim < nDim; iDim++) + Grad_Reflected[iVar][iDim] = Grad_Reflected[iVar][iDim] - 2.0 * ProjGradient * UnitNormal[iDim]; } } - for (iDim = 0; iDim < nDim; iDim++) { - for (jDim = 0; jDim < nDim; jDim++) { - Jacobian_i[nSpecies+iDim][nSpecies+jDim] = u[iDim]*UnitNormal[jDim] - + dPdU[nSpecies+jDim]*UnitNormal[iDim]; + /*--- Compute gradients of normal and tangential velocity: + grad(v*n) = grad(v_x) n_x + grad(v_y) n_y (+ grad(v_z) n_z) + grad(v*t) = grad(v_x) t_x + grad(v_y) t_y (+ grad(v_z) t_z) ---*/ + for (iVar = 0; iVar < nDim; iVar++) { // counts gradient components + GradNormVel[iVar] = 0.0; + GradTangVel[iVar] = 0.0; + for (iDim = 0; iDim < nDim; iDim++) { // counts sum with unit normal/tangential + GradNormVel[iVar] += Grad_Reflected[VEL_INDEX + iDim][iVar] * UnitNormal[iDim]; + GradTangVel[iVar] += Grad_Reflected[VEL_INDEX + iDim][iVar] * Tangential[iDim]; } - Jacobian_i[nSpecies+iDim][nSpecies+nDim] = dPdU[nSpecies+nDim] *UnitNormal[iDim]; - Jacobian_i[nSpecies+iDim][nSpecies+nDim+1] = dPdU[nSpecies+nDim+1]*UnitNormal[iDim]; + } - Jacobian_i[nSpecies+nDim][nSpecies+iDim] = (rhoE+P)/rho * UnitNormal[iDim]; - Jacobian_i[nSpecies+nDim+1][nSpecies+iDim] = rhoEve/rho * UnitNormal[iDim]; + /*--- Refelect gradients in tangential and normal direction by substracting the normal/tangential + component twice, just as done with velocity above. + grad(v*n)_r = grad(v*n) - 2 {grad([v*n])*t}t + grad(v*t)_r = grad(v*t) - 2 {grad([v*t])*n}n ---*/ + ProjNormVelGrad = 0.0; + ProjTangVelGrad = 0.0; + for (iDim = 0; iDim < nDim; iDim++) { + ProjNormVelGrad += GradNormVel[iDim] * Tangential[iDim]; // grad([v*n])*t + ProjTangVelGrad += GradTangVel[iDim] * UnitNormal[iDim]; // grad([v*t])*n } - /*--- Integrate over the dual-grid area ---*/ - for (iVar = 0; iVar < nVar; iVar++) - for (jVar = 0; jVar < nVar; jVar++) - Jacobian_i[iVar][jVar] = Jacobian_i[iVar][jVar] * Area; + for (iDim = 0; iDim < nDim; iDim++) { + GradNormVel[iDim] = GradNormVel[iDim] - 2.0 * ProjNormVelGrad * Tangential[iDim]; + GradTangVel[iDim] = GradTangVel[iDim] - 2.0 * ProjTangVelGrad * UnitNormal[iDim]; + } - /*--- Apply the contribution to the system ---*/ - Jacobian.AddBlock(iPoint,iPoint,Jacobian_i); + /*--- Transfer reflected gradients back into the Cartesian Coordinate system: + grad(v_x)_r = grad(v*n)_r n_x + grad(v*t)_r t_x + grad(v_y)_r = grad(v*n)_r n_y + grad(v*t)_r t_y + ( grad(v_z)_r = grad(v*n)_r n_z + grad(v*t)_r t_z ) ---*/ + for (iVar = 0; iVar < nDim; iVar++) // loops over the velocity component gradients + for (iDim = 0; iDim < nDim; iDim++) // loops over the entries of the above + Grad_Reflected[VEL_INDEX + iDim][iDim] = + GradNormVel[iDim] * UnitNormal[iVar] + GradTangVel[iDim] * Tangential[iVar]; + + /*--- Set the primitive gradients of the boundary and reflected state. ---*/ + visc_numerics->SetPrimVarGradient(nodes->GetGradient_Primitive(iPoint), Grad_Reflected); + + /*--- Turbulent kinetic energy. ---*/ + if ((config->GetKind_Turb_Model() == SST) || (config->GetKind_Turb_Model() == SST_SUST)) + visc_numerics->SetTurbKineticEnergy(solver_container[TURB_SOL]->GetNodes()->GetSolution(iPoint, 0), + solver_container[TURB_SOL]->GetNodes()->GetSolution(iPoint, 0)); + + /*--- Compute and update residual. Note that the viscous shear stress tensor is computed in the + following routine based upon the velocity-component gradients. ---*/ + auto residual = visc_numerics->ComputeResidual(config); - } - } - } - delete [] Normal; - delete [] NormalArea; - delete [] u; + LinSysRes.SubtractBlock(iPoint, residual); - for (iVar = 0; iVar < nVar; iVar++) { - delete [] Jacobian_b[iVar]; - delete [] DubDu[iVar]; - } + /*--- Jacobian contribution for implicit integration. ---*/ + if (implicit) Jacobian.SubtractBlock2Diag(iPoint, residual.jacobian_i); + } // if viscous + } // if GetDomain + } // for iVertex - delete [] Jacobian_b; - delete [] DubDu; + /*--- Free locally allocated memory ---*/ + for (iVar = 0; iVar < nPrimVarGrad; iVar++) delete[] Grad_Reflected[iVar]; + delete[] Grad_Reflected; } From bd1301054fe8c05b31c3c6040bd635a7670b8a84 Mon Sep 17 00:00:00 2001 From: fmpmorgado Date: Thu, 21 Jan 2021 22:02:14 +0000 Subject: [PATCH 21/23] Fixing CIntegration --- SU2_CFD/src/integration/CIntegration.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/SU2_CFD/src/integration/CIntegration.cpp b/SU2_CFD/src/integration/CIntegration.cpp index 86b7b89befe..5099f881603 100644 --- a/SU2_CFD/src/integration/CIntegration.cpp +++ b/SU2_CFD/src/integration/CIntegration.cpp @@ -137,16 +137,16 @@ void CIntegration::Space_Integration(CGeometry *geometry, case FAR_FIELD: solver_container[MainSolver]->BC_Far_Field(geometry, solver_container, conv_bound_numerics, visc_bound_numerics, config, iMarker); break; + case SYMMETRY_PLANE: + if (!config->GetNEMOProblem()) + solver_container[MainSolver]->BC_Sym_Plane(geometry, solver_container, conv_bound_numerics, visc_bound_numerics, config, iMarker); + break; case ELECTRODE_BOUNDARY: solver_container[MainSolver]->BC_Electrode(geometry, solver_container, conv_bound_numerics, config, iMarker); break; case DIELEC_BOUNDARY: solver_container[MainSolver]->BC_Dielec(geometry, solver_container, conv_bound_numerics, config, iMarker); break; - case SYMMETRY_PLANE: - if (!config->GetNEMOProblem()) - solver_container[MainSolver]->BC_Sym_Plane(geometry, solver_container, conv_bound_numerics, visc_bound_numerics, config, iMarker); - break; } } From 3d964088ded90b10d5c0102c71daccd07bd2a9e5 Mon Sep 17 00:00:00 2001 From: fmpmorgado Date: Fri, 22 Jan 2021 13:18:45 +0000 Subject: [PATCH 22/23] Created routine to fix Edge Normals at Symmetry Planes and removed Euler call at symmetry BC --- SU2_CFD/src/solvers/CNEMOEulerSolver.cpp | 72 +++++++++++++++++++++--- 1 file changed, 64 insertions(+), 8 deletions(-) diff --git a/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp b/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp index 1311b8c350a..186107af00d 100644 --- a/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp +++ b/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp @@ -46,7 +46,7 @@ CNEMOEulerSolver::CNEMOEulerSolver(CGeometry *geometry, CConfig *config, description = "Euler"; } - unsigned long iPoint, counter_local, counter_global = 0; + unsigned long iPoint, jPoint, iEdge, counter_local, counter_global = 0; unsigned short iDim, iMarker, iSpecies, nLineLets; unsigned short nZone = geometry->GetnZone(); su2double *Mvec_Inf, Alpha, Beta, Soundspeed_Inf, sqvel; @@ -58,6 +58,8 @@ CNEMOEulerSolver::CNEMOEulerSolver(CGeometry *geometry, CConfig *config, bool time_stepping = config->GetTime_Marching() == TIME_STEPPING; bool adjoint = config->GetDiscrete_Adjoint(); string filename_ = "flow"; + su2double Normal[3], Tangent[3], Normal_Sym[3], UnitNormal_Sym[3], Product, Area; + su2double tol = 1e-16; bool nonPhys; @@ -262,6 +264,58 @@ CNEMOEulerSolver::CNEMOEulerSolver(CGeometry *geometry, CConfig *config, } } + + /*--- Correct normal directions of edges ---*/ + for (unsigned long iMarker = 0; iMarker < geometry->GetnMarker(); iMarker++) { + if (config->GetMarker_All_KindBC(iMarker) == SYMMETRY_PLANE){ + for (unsigned long iVertex = 0; iVertex < geometry->GetnVertex(iMarker); iVertex++) { + + unsigned long iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + + geometry->vertex[iMarker][iVertex]->GetNormal(Normal_Sym); + + Area = GeometryToolbox::Norm(nDim, Normal_Sym); + + for(iDim = 0; iDimnodes->GetnPoint(iPoint); ++iNeigh){ + Product = 0.0; + + jPoint = geometry->nodes->GetPoint(iPoint,iNeigh); + + /*---Check if neighbour point is on the same plane as the Symmetry_Plane + by computing the internal product and of the Normal Vertex vector and + the vector connecting iPoint and jPoint. If the product is lower than + estabilished tolerance (to account for Numerical errors) both points are + in the same plane as SYMMETRY_PLANE---*/ + + for(iDim = 0; iDimnodes->GetCoord(jPoint,iDim) - geometry->nodes->GetCoord(iPoint,iDim); + Product += Tangent[iDim] * Normal_Sym[iDim]; + } + + if (abs(Product) < tol) { + Product = 0.0; + + iEdge = geometry->nodes->GetEdge(iPoint,iNeigh); + + geometry->edges->GetNormal(iEdge,Normal); + + for(iDim = 0; iDimedges->SetNormal(iEdge,Normal); + } + } + } + } + } + /*--- Warning message about non-physical points ---*/ if (config->GetComm_Level() == COMM_FULL) { @@ -1902,31 +1956,33 @@ void CNEMOEulerSolver::BC_Sym_Plane(CGeometry *geometry, CSolver **solver_contai CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { unsigned long iPoint, iVertex; unsigned short iDim, iVar; - su2double Area, Normal[3], UnitNormal[3]; + su2double Area, Normal[3], UnitNormal[3], Normal_Product; const su2double* Residual_Old; su2double *Residual = new su2double[nVar]; - BC_Euler_Wall(geometry, solver_container, conv_numerics, visc_numerics, config, val_marker); - for(iVar = 0; iVar < nVar; iVar++) Residual[iVar]=0.0; /*--- Loop over all the vertices on this boundary marker ---*/ for(iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { + Normal_Product = 0.0; + geometry->vertex[val_marker][iVertex]->GetNormal(Normal); Area = GeometryToolbox::Norm(nDim, Normal); - for(iDim = 0; iDim < nDim; iDim++) - UnitNormal[iDim] = Normal[iDim]/Area; - iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); Residual_Old = LinSysRes.GetBlock(iPoint); + for(iDim = 0; iDim < nDim; iDim++) { + UnitNormal[iDim] = Normal[iDim]/Area; + Normal_Product += Residual_Old[nSpecies+iDim]*UnitNormal[iDim]; + } + for(iDim = 0; iDim < nDim; iDim++) - Residual[nSpecies+iDim] = Residual_Old[nSpecies+iDim]*abs(UnitNormal[iDim]); + Residual[nSpecies+iDim] = Normal_Product*UnitNormal[iDim]; LinSysRes.SubtractBlock(iPoint, Residual); } From f8426e51b0e8c02e34649e2060f439fec61f1a65 Mon Sep 17 00:00:00 2001 From: fmpmorgado Date: Fri, 22 Jan 2021 14:56:14 +0000 Subject: [PATCH 23/23] Addressing PR requested changes and Remove viscous part in Euler wall BC --- SU2_CFD/src/output/CNEMOCompOutput.cpp | 2 +- SU2_CFD/src/solvers/CNEMOEulerSolver.cpp | 212 ++--------------------- configure.ac | 4 +- 3 files changed, 14 insertions(+), 204 deletions(-) diff --git a/SU2_CFD/src/output/CNEMOCompOutput.cpp b/SU2_CFD/src/output/CNEMOCompOutput.cpp index 982d9359522..9fbeb1fd84c 100644 --- a/SU2_CFD/src/output/CNEMOCompOutput.cpp +++ b/SU2_CFD/src/output/CNEMOCompOutput.cpp @@ -559,7 +559,7 @@ void CNEMOCompOutput::LoadVolumeData(CConfig *config, CGeometry *geometry, CSolv void CNEMOCompOutput::LoadSurfaceData(CConfig *config, CGeometry *geometry, CSolver **solver, unsigned long iPoint, unsigned short iMarker, unsigned long iVertex){ - if ((config->GetKind_Solver() == NEMO_NAVIER_STOKES && config->GetMarker_All_KindBC(iMarker) != EULER && config->GetMarker_All_KindBC(iMarker) != SYMMETRY_PLANE)) { + if (config->GetKind_Solver() == NEMO_NAVIER_STOKES && config->GetViscous_Wall(iMarker)) { SetVolumeOutputValue("SKIN_FRICTION-X", iPoint, solver[FLOW_SOL]->GetCSkinFriction(iMarker, iVertex, 0)); SetVolumeOutputValue("SKIN_FRICTION-Y", iPoint, solver[FLOW_SOL]->GetCSkinFriction(iMarker, iVertex, 1)); if (nDim == 3) diff --git a/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp b/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp index 186107af00d..45c36d41af5 100644 --- a/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp +++ b/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp @@ -58,8 +58,9 @@ CNEMOEulerSolver::CNEMOEulerSolver(CGeometry *geometry, CConfig *config, bool time_stepping = config->GetTime_Marching() == TIME_STEPPING; bool adjoint = config->GetDiscrete_Adjoint(); string filename_ = "flow"; - su2double Normal[3], Tangent[3], Normal_Sym[3], UnitNormal_Sym[3], Product, Area; - su2double tol = 1e-16; + su2double Normal[MAXNDIM] = {0.0}, Tangent[MAXNDIM] = {0.0}; + su2double Normal_Sym[MAXNDIM] = {0.0}, UnitNormal_Sym[MAXNDIM] = {0.0}; + su2double Product, Area, tol = 1e-16; bool nonPhys; @@ -234,7 +235,7 @@ CNEMOEulerSolver::CNEMOEulerSolver(CGeometry *geometry, CConfig *config, sqvel = 0.0; for (iDim = 0; iDim < nDim; iDim++){ sqvel += Mvec_Inf[iDim]*Soundspeed_Inf * Mvec_Inf[iDim]*Soundspeed_Inf; - } + } const auto& Energies_Inf = FluidModel->ComputeMixtureEnergies(); /*--- Initialize Solution & Solution_Old vectors ---*/ @@ -250,9 +251,8 @@ CNEMOEulerSolver::CNEMOEulerSolver(CGeometry *geometry, CConfig *config, nodes->SetSolution_Old(iPoint,Solution); if(nonPhys) - counter_local++; + counter_local++; } - /*--- Count number of symmetry planes where each Vertex is inserted ---*/ for (unsigned long iMarker = 0; iMarker < geometry->GetnMarker(); iMarker++) { @@ -264,7 +264,6 @@ CNEMOEulerSolver::CNEMOEulerSolver(CGeometry *geometry, CConfig *config, } } - /*--- Correct normal directions of edges ---*/ for (unsigned long iMarker = 0; iMarker < geometry->GetnMarker(); iMarker++) { if (config->GetMarker_All_KindBC(iMarker) == SYMMETRY_PLANE){ @@ -285,7 +284,7 @@ CNEMOEulerSolver::CNEMOEulerSolver(CGeometry *geometry, CConfig *config, jPoint = geometry->nodes->GetPoint(iPoint,iNeigh); - /*---Check if neighbour point is on the same plane as the Symmetry_Plane + /*---Check if neighbour point is on the same plane as the Symmetry_Plane by computing the internal product and of the Normal Vertex vector and the vector connecting iPoint and jPoint. If the product is lower than estabilished tolerance (to account for Numerical errors) both points are @@ -314,7 +313,7 @@ CNEMOEulerSolver::CNEMOEulerSolver(CGeometry *geometry, CConfig *config, } } } - } + } /*--- Warning message about non-physical points ---*/ if (config->GetComm_Level() == COMM_FULL) { @@ -587,32 +586,24 @@ void CNEMOEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_contai if(nodes->GetSymmetry(iPoint) == 1 && nodes->GetSymmetry(jPoint) == 0) nodes->AddMax_Lambda_Visc(iPoint, Lambda/2.0); else if (nodes->GetSymmetry(iPoint) == 2 && nodes->GetSymmetry(jPoint) == 1) nodes->AddMax_Lambda_Visc(iPoint, Lambda/2.0); else nodes->AddMax_Lambda_Visc(iPoint, Lambda); - } - } /*--- Loop boundary edges ---*/ for (iMarker = 0; iMarker < geometry->GetnMarker(); iMarker++) { if ((config->GetMarker_All_KindBC(iMarker) != INTERNAL_BOUNDARY) && (config->GetMarker_All_KindBC(iMarker) != PERIODIC_BOUNDARY)) { - + SU2_OMP_FOR_STAT(OMP_MIN_SIZE) for (iVertex = 0; iVertex < geometry->GetnVertex(iMarker); iVertex++) { /*--- Point identification, Normal vector and area ---*/ iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); - if (!geometry->nodes->GetDomain(iPoint)) continue; + if (!geometry->nodes->GetDomain(iPoint) || config->GetMarker_All_KindBC(iMarker) == SYMMETRY_PLANE) continue; geometry->vertex[iMarker][iVertex]->GetNormal(Normal); - /*--- Set Normal to zero if node is in the Symmetry Plane marker ---*/ - if(config->GetMarker_All_KindBC(iMarker) == SYMMETRY_PLANE) { - for(iDim = 0; iDim < nDim; iDim++) - Normal[iDim]=0; - } - Area = GeometryToolbox::Norm(nDim, Normal); /*--- Mean Values ---*/ Mean_ProjVel = nodes->GetProjVel(iPoint,Normal); @@ -648,8 +639,7 @@ void CNEMOEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_contai Lambda_2 = (Mean_ThermalCond+Mean_ThermalCond_ve)/cv; Lambda = (Lambda_1 + Lambda_2)*Area*Area/Mean_Density; - if(nodes->GetSymmetry(iPoint) > 0 && config->GetMarker_All_KindBC(iMarker) == SYMMETRY_PLANE) nodes->AddMax_Lambda_Visc(iPoint, Lambda/2.0); - else nodes->AddMax_Lambda_Visc(iPoint, Lambda); + nodes->AddMax_Lambda_Visc(iPoint, Lambda); } } @@ -1956,12 +1946,9 @@ void CNEMOEulerSolver::BC_Sym_Plane(CGeometry *geometry, CSolver **solver_contai CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { unsigned long iPoint, iVertex; unsigned short iDim, iVar; - su2double Area, Normal[3], UnitNormal[3], Normal_Product; + su2double Area, Normal[MAXNDIM], UnitNormal[MAXNDIM], Normal_Product; const su2double* Residual_Old; - su2double *Residual = new su2double[nVar]; - - for(iVar = 0; iVar < nVar; iVar++) - Residual[iVar]=0.0; + su2double Residual[MAXNVAR] = {0.0}; /*--- Loop over all the vertices on this boundary marker ---*/ for(iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { @@ -1986,8 +1973,6 @@ void CNEMOEulerSolver::BC_Sym_Plane(CGeometry *geometry, CSolver **solver_contai LinSysRes.SubtractBlock(iPoint, Residual); } - - delete [] Residual; } void CNEMOEulerSolver::BC_Far_Field(CGeometry *geometry, CSolver **solver_container, @@ -2908,7 +2893,6 @@ void CNEMOEulerSolver::BC_Euler_Wall(CGeometry *geometry, CSolver **solver_conta unsigned long iVertex, iPoint; bool implicit = (config->GetKind_TimeIntScheme() == EULER_IMPLICIT); - bool viscous = config->GetViscous(); bool preprocessed = false; unsigned short VEL_INDEX = nodes->GetVelIndex(); @@ -2916,14 +2900,6 @@ void CNEMOEulerSolver::BC_Euler_Wall(CGeometry *geometry, CSolver **solver_conta /*--- Allocation of variables necessary for convective fluxes. ---*/ su2double Area, ProjVelocity_i, *V_reflected, *V_domain, Normal[MAXNDIM] = {0.0}, UnitNormal[MAXNDIM] = {0.0}; - /*--- Allocation of variables necessary for viscous fluxes. ---*/ - su2double ProjGradient, ProjNormVelGrad, ProjTangVelGrad, TangentialNorm, - Tangential[MAXNDIM] = {0.0}, GradNormVel[MAXNDIM] = {0.0}, GradTangVel[MAXNDIM] = {0.0}; - - /*--- Allocation of primitive gradient arrays for viscous fluxes. ---*/ - su2double** Grad_Reflected = new su2double*[nPrimVarGrad]; - for (iVar = 0; iVar < nPrimVarGrad; iVar++) Grad_Reflected[iVar] = new su2double[nDim]; - /*--- Loop over all the vertices on this boundary marker. ---*/ SU2_OMP_FOR_DYN(OMP_MIN_SIZE) @@ -2956,35 +2932,6 @@ void CNEMOEulerSolver::BC_Euler_Wall(CGeometry *geometry, CSolver **solver_conta /*--- Preprocessing: Compute unit tangential, the direction is arbitrary as long as t*n=0 && |t|_2 = 1 ---*/ - if (viscous) { - switch (nDim) { - case 2: { - Tangential[0] = -UnitNormal[1]; - Tangential[1] = UnitNormal[0]; - break; - } - case 3: { - /*--- n = ai + bj + ck, if |b| > |c| ---*/ - if (abs(UnitNormal[1]) > abs(UnitNormal[2])) { - /*--- t = bi + (c-a)j - bk ---*/ - Tangential[0] = UnitNormal[1]; - Tangential[1] = UnitNormal[2] - UnitNormal[0]; - Tangential[2] = -UnitNormal[1]; - } else { - /*--- t = ci - cj + (b-a)k ---*/ - Tangential[0] = UnitNormal[2]; - Tangential[1] = -UnitNormal[2]; - Tangential[2] = UnitNormal[1] - UnitNormal[0]; - } - /*--- Make it a unit vector. ---*/ - TangentialNorm = sqrt(pow(Tangential[0], 2) + pow(Tangential[1], 2) + pow(Tangential[2], 2)); - Tangential[0] = Tangential[0] / TangentialNorm; - Tangential[1] = Tangential[1] / TangentialNorm; - Tangential[2] = Tangential[2] / TangentialNorm; - break; - } - } // switch - } // if viscous } // if bound_is_straight iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); @@ -3051,143 +2998,8 @@ void CNEMOEulerSolver::BC_Euler_Wall(CGeometry *geometry, CSolver **solver_conta if (implicit) { Jacobian.AddBlock2Diag(iPoint, residual.jacobian_i); } - - if (viscous) { - /*-------------------------------------------------------------------------------*/ - /*--- Step 2: The viscous fluxes of the Navier-Stokes equations depend on the ---*/ - /*--- Primitive variables and their gradients. The viscous numerics ---*/ - /*--- container is filled just as the convective numerics container, ---*/ - /*--- but the primitive gradients of the reflected state have to be ---*/ - /*--- determined additionally such that symmetry at the boundary is ---*/ - /*--- enforced. Based on the Viscous_Residual routine. ---*/ - /*-------------------------------------------------------------------------------*/ - - /*--- Set the normal vector and the coordinates. ---*/ - visc_numerics->SetCoord(geometry->nodes->GetCoord(iPoint), geometry->nodes->GetCoord(iPoint)); - visc_numerics->SetNormal(Normal); - - /*--- Primitive variables, and gradient ---*/ - visc_numerics->SetPrimitive(V_domain, V_reflected); - - visc_numerics->SetConservative(nodes->GetSolution(iPoint), nodes->GetSolution(iPoint)); - - /*--- Also need to correct Gradient for Conservative Quantities ?? ---*/ - // visc_numerics->SetConsVarGradient(nodes->GetGradient(iPoint), nodes->GetGradient(iPoint) ); - - /*--- Pass supplementary information to CNumerics ---*/ - visc_numerics->SetdPdU (nodes->GetdPdU(iPoint), nodes->GetdPdU(iPoint)); - visc_numerics->SetdTdU (nodes->GetdTdU(iPoint), nodes->GetdTdU(iPoint)); - visc_numerics->SetdTvedU(nodes->GetdTvedU(iPoint), nodes->GetdTvedU(iPoint)); - visc_numerics->SetEve (nodes->GetEve(iPoint), nodes->GetEve(iPoint)); - visc_numerics->SetCvve (nodes->GetCvve(iPoint), nodes->GetCvve(iPoint)); - - /*--- Species diffusion coefficients ---*/ - visc_numerics->SetDiffusionCoeff(nodes->GetDiffusionCoeff(iPoint), - nodes->GetDiffusionCoeff(iPoint)); - - /*--- Laminar viscosity ---*/ - visc_numerics->SetLaminarViscosity(nodes->GetLaminarViscosity(iPoint), - nodes->GetLaminarViscosity(iPoint)); - - /*--- Eddy viscosity ---*/ - visc_numerics->SetEddyViscosity(nodes->GetEddyViscosity(iPoint), - nodes->GetEddyViscosity(iPoint)); - - /*--- Thermal conductivity ---*/ - visc_numerics->SetThermalConductivity(nodes->GetThermalConductivity(iPoint), - nodes->GetThermalConductivity(iPoint)); - - /*--- Vib-el. thermal conductivity ---*/ - visc_numerics->SetThermalConductivity_ve(nodes->GetThermalConductivity_ve(iPoint), - nodes->GetThermalConductivity_ve(iPoint)); - - /*--- For viscous Fluxes also the gradients of the primitives need to be determined. - 1. The gradients of scalars are mirrored along the sym plane just as velocity for the primitives - 2. The gradients of the velocity components need more attention, i.e. the gradient of the - normal velocity in tangential direction is mirrored and the gradient of the tangential velocity in - normal direction is mirrored. ---*/ - - /*--- Get gradients of primitives of boundary cell ---*/ - for (iVar = 0; iVar < nPrimVarGrad; iVar++) - for (iDim = 0; iDim < nDim; iDim++) - Grad_Reflected[iVar][iDim] = nodes->GetGradient_Primitive(iPoint, iVar, iDim); - - /*--- Reflect the gradients for all scalars including the velocity components. - The gradients of the velocity components are set later with the - correct values: grad(V)_r = grad(V) - 2 [grad(V)*n]n, V beeing any primitive ---*/ - for (iVar = 0; iVar < nPrimVarGrad; iVar++) { - if (iVar == 0 || iVar > nDim) { // Exclude velocity component gradients - - /*--- Compute projected part of the gradient in a dot product ---*/ - ProjGradient = 0.0; - for (iDim = 0; iDim < nDim; iDim++) ProjGradient += Grad_Reflected[iVar][iDim] * UnitNormal[iDim]; - - for (iDim = 0; iDim < nDim; iDim++) - Grad_Reflected[iVar][iDim] = Grad_Reflected[iVar][iDim] - 2.0 * ProjGradient * UnitNormal[iDim]; - } - } - - /*--- Compute gradients of normal and tangential velocity: - grad(v*n) = grad(v_x) n_x + grad(v_y) n_y (+ grad(v_z) n_z) - grad(v*t) = grad(v_x) t_x + grad(v_y) t_y (+ grad(v_z) t_z) ---*/ - for (iVar = 0; iVar < nDim; iVar++) { // counts gradient components - GradNormVel[iVar] = 0.0; - GradTangVel[iVar] = 0.0; - for (iDim = 0; iDim < nDim; iDim++) { // counts sum with unit normal/tangential - GradNormVel[iVar] += Grad_Reflected[VEL_INDEX + iDim][iVar] * UnitNormal[iDim]; - GradTangVel[iVar] += Grad_Reflected[VEL_INDEX + iDim][iVar] * Tangential[iDim]; - } - } - - /*--- Refelect gradients in tangential and normal direction by substracting the normal/tangential - component twice, just as done with velocity above. - grad(v*n)_r = grad(v*n) - 2 {grad([v*n])*t}t - grad(v*t)_r = grad(v*t) - 2 {grad([v*t])*n}n ---*/ - ProjNormVelGrad = 0.0; - ProjTangVelGrad = 0.0; - for (iDim = 0; iDim < nDim; iDim++) { - ProjNormVelGrad += GradNormVel[iDim] * Tangential[iDim]; // grad([v*n])*t - ProjTangVelGrad += GradTangVel[iDim] * UnitNormal[iDim]; // grad([v*t])*n - } - - for (iDim = 0; iDim < nDim; iDim++) { - GradNormVel[iDim] = GradNormVel[iDim] - 2.0 * ProjNormVelGrad * Tangential[iDim]; - GradTangVel[iDim] = GradTangVel[iDim] - 2.0 * ProjTangVelGrad * UnitNormal[iDim]; - } - - /*--- Transfer reflected gradients back into the Cartesian Coordinate system: - grad(v_x)_r = grad(v*n)_r n_x + grad(v*t)_r t_x - grad(v_y)_r = grad(v*n)_r n_y + grad(v*t)_r t_y - ( grad(v_z)_r = grad(v*n)_r n_z + grad(v*t)_r t_z ) ---*/ - for (iVar = 0; iVar < nDim; iVar++) // loops over the velocity component gradients - for (iDim = 0; iDim < nDim; iDim++) // loops over the entries of the above - Grad_Reflected[VEL_INDEX + iDim][iDim] = - GradNormVel[iDim] * UnitNormal[iVar] + GradTangVel[iDim] * Tangential[iVar]; - - /*--- Set the primitive gradients of the boundary and reflected state. ---*/ - visc_numerics->SetPrimVarGradient(nodes->GetGradient_Primitive(iPoint), Grad_Reflected); - - /*--- Turbulent kinetic energy. ---*/ - if ((config->GetKind_Turb_Model() == SST) || (config->GetKind_Turb_Model() == SST_SUST)) - visc_numerics->SetTurbKineticEnergy(solver_container[TURB_SOL]->GetNodes()->GetSolution(iPoint, 0), - solver_container[TURB_SOL]->GetNodes()->GetSolution(iPoint, 0)); - - /*--- Compute and update residual. Note that the viscous shear stress tensor is computed in the - following routine based upon the velocity-component gradients. ---*/ - auto residual = visc_numerics->ComputeResidual(config); - - LinSysRes.SubtractBlock(iPoint, residual); - - /*--- Jacobian contribution for implicit integration. ---*/ - if (implicit) Jacobian.SubtractBlock2Diag(iPoint, residual.jacobian_i); - } // if viscous } // if GetDomain } // for iVertex - - /*--- Free locally allocated memory ---*/ - for (iVar = 0; iVar < nPrimVarGrad; iVar++) delete[] Grad_Reflected[iVar]; - delete[] Grad_Reflected; - } void CNEMOEulerSolver::SetResidual_DualTime(CGeometry *geometry, diff --git a/configure.ac b/configure.ac index 99c52bbafec..3415d019da9 100644 --- a/configure.ac +++ b/configure.ac @@ -110,7 +110,7 @@ AC_ARG_ENABLE(SOL, [build_SOL=$enableval], [build_SOL="yes"]) AC_ARG_ENABLE(GEO, AS_HELP_STRING([--disable-GEO], [build the SU2_GEO executable (default = yes)]), - [build_GEO=$enableval], [build_GEO="yes"]) + [build_GEO=$enableval], [build_GEO="yes"]) AC_ARG_ENABLE(PY_WRAPPER, AS_HELP_STRING([--enable-PY_WRAPPER], [wrap the SU2 code with Python (default = no)]), [build_PY_WRAPPER="yes"], [build_PY_WRAPPER="no"]) @@ -295,7 +295,6 @@ then build_DEF=no build_SOL=no build_GEO=no - build_INTERP=no build_PY=no fi @@ -315,7 +314,6 @@ AM_CONDITIONAL([BUILD_DOT],[test $build_DOT != "no"]) AM_CONDITIONAL([BUILD_DEF],[test $build_DEF != "no"]) AM_CONDITIONAL([BUILD_SOL],[test $build_SOL != "no"]) AM_CONDITIONAL([BUILD_GEO],[test $build_GEO != "no"]) -AM_CONDITIONAL([BUILD_INTERP],[test $build_INTERP != "no"]) AM_CONDITIONAL([BUILD_PY],[test $build_PY != "no"]) AM_CONDITIONAL([BUILD_PY_WRAPPER], [test $build_PY_WRAPPER != "no"])