Skip to content

[ConvectionDiffusionApplication] Adding crosswind stabilization to Eulerian Convection–Diffusion element#14272

Open
Marco1410 wants to merge 9 commits intomasterfrom
marco/convection_diffusion
Open

[ConvectionDiffusionApplication] Adding crosswind stabilization to Eulerian Convection–Diffusion element#14272
Marco1410 wants to merge 9 commits intomasterfrom
marco/convection_diffusion

Conversation

@Marco1410
Copy link
Copy Markdown
Contributor

📝 Description
This pull request introduces a crosswind stabilization term in the EulerianConvectionDiffusionElement of Kratos.

The implementation follows the discontinuity-capturing approach proposed in A discontinuity‑capturing crosswind‑dissipation for the finite element solution of the convection‑diffusion equation by Ramon Codina. The method adds a nonlinear diffusion in the direction orthogonal to the flow in order to reduce the spurious oscillations that may still appear when using streamline-based stabilization techniques.

The stabilization term can be activated through the element settings.
By default CROSS_WIND_STABILIZATION_FACTOR is zero.

 "transient_parameters" : {
        "dynamic_tau" : 1.0,
        "theta"       : 0.5,
        "cross_wind_stabilization_factor" : 0.0
   }

Additionally, a unit test has been included to verify the correct behaviour of the implementation.

To illustrate the effect of the stabilization, two example simulations are shown below:

  • Without crosswind stabilization:
    Spurious oscillations appear near steep gradients.
    Without CrossWind

  • With crosswind stabilization:
    The oscillations are significantly reduced.
    WithCrossWind

🆕 Changelog

  • eulerian_conv_diff.cpp
  • convection_diffusion_transient_solver.py
  • test_eulerian_conv_diff.cpp

@Marco1410 Marco1410 changed the title [CONVECTION DIFFUSION] Adding crosswind stabilization to Eulerian Convection–Diffusion element [ConvectionDiffusionApplication] Adding crosswind stabilization to Eulerian Convection–Diffusion element Mar 11, 2026
Copy link
Copy Markdown
Member

@rubenzorrilla rubenzorrilla left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not fully convinced about the elemental cross wind factor calculation. Aside of this, the others are minors.

const double disc_capturing_coeff = 0.5*C*h*fabs(res/norm_grad);
BoundedMatrix<double,TDim,TDim> D = disc_capturing_coeff*( IdentityMatrix(TDim));
const double norm_vel_squared = norm_vel*norm_vel;
D += (std::max( disc_capturing_coeff - tau*norm_vel_squared , 0.0) - disc_capturing_coeff)/(norm_vel_squared) * outer_prod(vel_gauss,vel_gauss);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure about this? Shouldn't it involve the viscosity besides the tau?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rubenzorrilla, I use tau because I want to remove the contribution in the streamline direction.

The problem with the projected Péclet is that when the velocity and the gradient are aligned, the crosswind contribution disappears, even if oscillations are still present.

This is likely why the original formulation is implemented in this way. For this reason, I think it is better to keep the current approach, since it is more appropriate and robust.

@Marco1410 Marco1410 requested a review from rubenzorrilla April 9, 2026 13:16
const double res = dphi_dt + conv;

// Projected velocity
u_proj = (conv/norm_grad) * (grad_phi_halfstep/norm_grad);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
u_proj = (conv/norm_grad) * (grad_phi_halfstep/norm_grad);
u_proj = (conv/std::pow(norm_grad,2)) * grad_phi_halfstep;

Easier to follow

double density;
double beta;
double div_v;
double C;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd use a more self-descriptive variable name

// Residual
const double res = dphi_dt + conv;

// Projected velocity
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Projected velocity
// Velocity projected in the direction of the solution gradient

// Projected velocity
u_proj = (conv/norm_grad) * (grad_phi_halfstep/norm_grad);

// Projected Peclet
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Projected Peclet
// Peclet number projected in the direction of the solution gradient

Comment on lines +165 to +166
// Residual
const double res = dphi_dt + conv;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this include the source term and diffusion?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also the beta term in case we use a compressible flux.

Copy link
Copy Markdown
Member

@rubenzorrilla rubenzorrilla left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minors. As a summary of our discussion, lets add the complete residual for the crosswind calculation and see what happens when avoiding the "custom" limiter stuff.

Copy link
Copy Markdown
Member

@rubenzorrilla rubenzorrilla left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Finally, we agree on having alpha_c = Variables.C as default, but we leave commented current option with the projected Peclet number and limiter. Lets put some comments explaining our discussion.

@Marco1410 Marco1410 requested a review from rubenzorrilla April 14, 2026 20:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants