CC Gradients in the volVars: non local elementsolution?
Kilian wrote about this back in !1248 (closed). Since that MR, most of the non-implicit parts of RANS have been changed or updated to allow for a fully implicit solve (this is especially done in !2930, but the wall distance and new spatial params developments have helped too).
Now, only one aspect of the non-implicit model issue remains. For a few of the RANS models (in particular the SST model, which is in high demand) there are "limiter" functions for the determination of the effective viscosity (a volume variables parameter. These limiter functions depend on the gradient of cell centered primary variables (\nabla k, \, \nabla \omega, \, \nabla \epsilon
).
Dependencies on the cell centered gradients also occur in the source terms, and parameters in the flux evaluation (in particular for the SST model) are weighted on functions dependent on these gradients. Within the fluxvars
or localResidual
headers, these gradients can be calculated on the fly as the entire elementVolumeVariables
is already available.
During the update within the volume variables, the effective viscosity is updated for use in the full momentum balance. Here lies the issue. As these limiters are dependent on the cell centered gradient, the cell centered gradient would need to be available in the volume variables. In the past, this gradient was stored in the problem, and updated once every time step (not fully implicit). To make this fully implicit, the gradients would need to be available for these limiters within the volume variables.
The volumeVars update function recieves the elementSolution, where the current solution for this element is stored. The element solution is a vector of primary variables, but for cell centered models, this includes only one set of primary variables (only one dof per element). This is done here (abbreviated):
class CCElementSolution
{
template<class ElementVolumeVariables>
CCElementSolution(const Element& element,
const ElementVolumeVariables& elemVolVars,
const FVElementGeometry& fvGeometry)
{
for (const auto& scv : scvs(fvGeometry))
priVars_ = elemVolVars[scv].priVars();
}
... more stuff ...
}
If, for the rans models, this elementSolution
recieved all of the solutions from the neighboring elements (already in the stencil), the gradient could be calculated and stored in the volumeVars
, and be available for use in the fluxVars
, the localResiduals
, and (most importantly) the limiter functions. This would mean that the elementSolution
built in the gridVariables
would have more entries, and look something like this (psuedocode):
class CCFullStencilElementSolution
{
template<class ElementVolumeVariables>
CCFullStencilElementSolution(const Element& element,
const ElementVolumeVariables& elemVolVars,
const FVElementGeometry& fvGeometry)
{
for (const auto& scv : scvs(fvGeometry))
passedVector_.push_back(elemVolVars[scv].priVars());
for (const auto& scvf : scvfs(fvGeometry))
passedVector_.push_back(elemVolVars[scvf.outside()].priVars()); //todo: real syntax
}
... more stuff ...
}
The CCElementSolution
class is discretization specific, but this extension would only be needed for the rans models, not all cc*pfa models (physics specific), bad. I would propose to introduce a second CCElementSolution
class in the cctpfa folder (could be called CCFullStencilElementSolution
or something like that). Then in the gridVariables update, where this elementSolution
is created, the type of ElementSolution
can be collected (CCElementSolution
or CCFullStencilElementSolution
), built, and passed to the volVars update function. As a default, the current CCElementSolution
class will continue to be used, and the rans models will define the ElementSolution
type to be the CCFullStencilElementSolution
type such that the gradients can be calculated.
I would appriciate your input on this @timok, @heck, @martins, @bernd (i've discussed this briefly with some of you). I understand that a cell centered gradient isn't necessarily an cell volume specific variable, but this is needed in the volume variables. I would think passing the information via an elementSolution
would be the least intrusive method. Otherwise there would have to be some other type of storage cache somewhere that the volvars would need to be given access to.
If you think this is would at least be an option, I will implement this and we can discuss the content in an MR.