Implementing variable density for unsteady incompressible flow#2641
Implementing variable density for unsteady incompressible flow#2641tkiymaz wants to merge 83 commits into
Conversation
|
@Cristopher-Morales can you review this pr please? |
Removed commented-out code for setting density at local point.
Updated the comment for density retrieval to reflect changes for transient density handling.
Removed unnecessary blank lines in CIncEulerVariable.hpp
Removed unnecessary blank lines in CVariable.hpp
Removed unnecessary blank lines to improve code readability.
Hi @pcarruscag ! Yes, I can help reviewing this PR. Please let me know if you need something else from my side |
Removed commented-out code and updated density calculation.
|
@Cristopher-Morales I guess the changes to the preconditioner can be removed from this PR since we now have your implementation |
Removed unnecessary blank lines in SetPrimVar function.
Removed unnecessary blank lines in CVariable.cpp.
Removed debug print statement from SetPrimVar function.
|
|
||
| inline void Set_Density_time_n(unsigned long iPoint, su2double val) { | ||
| Density_time_n[iPoint] = val; | ||
| } |
There was a problem hiding this comment.
Documentation must be added, similar to the function above SetDensity, Same for the two functions below Set_Density_unsteady and GetDensity_time_n
|
@pcarruscag can you have a quick look at this PR? The primal works as expected, the adjoint unsteady will be finalized in another PR. |
Co-authored-by: Pedro Gomes <38071223+pcarruscag@users.noreply.github.com>
Co-authored-by: Pedro Gomes <38071223+pcarruscag@users.noreply.github.com>
| if (incompressible) { | ||
| /*--- This is temporary and only valid for constant-density problems: | ||
| density could also be temperature dependent, but as it is not a part | ||
| of the solution vector it's neither stored for previous time steps | ||
| nor updated with the solution at the end of each iteration. */ | ||
| Density_nM1 = flowNodes->GetDensity(iPoint); | ||
| Density_n = flowNodes->GetDensity(iPoint); | ||
| Density_nP1 = flowNodes->GetDensity(iPoint); | ||
| Density_nM1 = incFlowNodes->GetDensity_time_n1(iPoint); | ||
| Density_n = incFlowNodes->GetDensity_time_n(iPoint); | ||
| Density_nP1 = incFlowNodes->GetDensity(iPoint); | ||
| } else { | ||
| Density_nM1 = flowNodes->GetSolution_time_n1(iPoint)[0]; | ||
| Density_n = flowNodes->GetSolution_time_n(iPoint, 0); | ||
| Density_nP1 = flowNodes->GetSolution(iPoint, 0); | ||
| } |
There was a problem hiding this comment.
We should use CFlowVariable to abstract this away.
Declare the GetDensity_time_n functions in CFlowVariable as virtual, the default implementation grabs density from the solution containers, whereas CIncEulerVariable overrides and uses its own containers for density.
Then the scalar solver does not need to carry logic about whether the flow is compressible or incompressible.
| /*! | ||
| * \brief Register the density at time n as an AD input (no-op for non-incompressible nodes). | ||
| */ | ||
| inline virtual void RegisterDensity_time_n() {} | ||
|
|
||
| /*! | ||
| * \brief Register the density at time n-1 as an AD input (no-op for non-incompressible nodes). | ||
| */ | ||
| inline virtual void RegisterDensity_time_n1() {} |
There was a problem hiding this comment.
Can't this be part of registering the time_n solutions?
| SetVolumeOutputValue("PRESSURE_COEFF", iPoint, (Node_Flow->GetPressure(iPoint) - solver[FLOW_SOL]->GetPressure_Inf())/factor); | ||
| SetVolumeOutputValue("DENSITY", iPoint, Node_Flow->GetDensity(iPoint)); | ||
|
|
||
| // Load density at previous timesteps for restart (unsteady with non-constant density) | ||
| if (config->GetTime_Domain() && config->GetKind_FluidModel() != CONSTANT_DENSITY) { | ||
| SetVolumeOutputValue("DENSITY_TIME_N", iPoint, Node_Flow_Inc->GetDensity_time_n(iPoint)); | ||
| if (config->GetTime_Marching() == TIME_MARCHING::DT_STEPPING_2ND) { | ||
| SetVolumeOutputValue("DENSITY_TIME_N1", iPoint, Node_Flow_Inc->GetDensity_time_n1(iPoint)); | ||
| } | ||
| } |
There was a problem hiding this comment.
We have density in the restart file, we load more than one restart file for transient to get the previous solutions.
Why do we need each of the multiple files we write and load to also carry old information? This way we are storing and loading repeated information.
| direct_solver->GetNodes()->RegisterSolution_time_n(); | ||
| /*--- Density is stored separately from the solution vector for incompressible flows. ---*/ | ||
| if (config->GetKind_Regime() == ENUM_REGIME::INCOMPRESSIBLE) | ||
| direct_solver->GetNodes()->RegisterDensity_time_n(); | ||
| } |
There was a problem hiding this comment.
So make RegisterSolution_time_n virtual and specialize it for the incompressible variable.
The purpose of abstractions like CSolver, CVariable, etc. is to keep physics/regime specific aspects contained in the "leaf classes" to allow the bigger ones like iteration, driver, etc. to deal with more general orchestration aspects
Proposed Changes
Implements variable density treatment for unsteady incompressible flow simulations. Currently, SU2 uses constant density in transient simulations, which is inaccurate for combustion cases where density varies significantly due to heat release and species composition changes. This contribution enables proper density updates during time-stepping for flamelet-based combustion modeling. For now, only 1st order time marching is implemented
Related Work
Related to incompressible flow solver and flamelet combustion modeling. No specific issue linked yet.
PR Checklist
pre-commit run --allto format old commits.