|
SNOWPACK 20251207.15ac3588
Physically based, energy balance snow cover model
|
This module contains the solver for the diffusion-advection equation for the transport of salinity.
#include <SalinityTransport.h>
Public Types | |
| enum | SalinityTransportSolvers { EXPLICIT , IMPLICIT , IMPLICIT2 } |
Public Member Functions | |
| SalinityTransport (size_t nE) | |
| Class for solving diffusion-advection equation for salinity using the Crank-Nicolson implicit method Solve Richards Equation . | |
| bool | VerifyCFL (const double dt) |
| Check for CFL criterion . | |
| bool | VerifyImplicitDt (const double dt) |
| Check for Implicit criterion . | |
| bool | SolveSalinityTransportEquationImplicit (const double dt, std::vector< double > &DeltaSal, const double f, const bool DonorCell=true) |
| Solve diffusion-advection equation using the Crank-Nicolson implicit, or fully implicit method . | |
| bool | SolveSalinityTransportEquationExplicit (const double dt, std::vector< double > &DeltaSal) |
| Solve diffusion-advection equation using the upwind explicit method . | |
Public Attributes | |
| std::vector< double > | flux_up |
| std::vector< double > | flux_down |
| std::vector< double > | flux_up_2 |
| std::vector< double > | flux_down_2 |
| std::vector< double > | dz_ |
| std::vector< double > | dz_up |
| std::vector< double > | dz_down |
| std::vector< double > | theta1 |
| std::vector< double > | theta2 |
| std::vector< double > | BrineSal |
| std::vector< double > | D |
| std::vector< double > | sb |
| double | BottomSalinity |
| double | TopSalinity |
| double | BottomSalFlux |
| double | TopSalFlux |
| SalinityTransport::SalinityTransport | ( | size_t | nE | ) |
Class for solving diffusion-advection equation for salinity using the Crank-Nicolson implicit method
Solve Richards Equation
.
| nE | Domain size (number of elements) |
| bool SalinityTransport::SolveSalinityTransportEquationExplicit | ( | const double | dt, |
| std::vector< double > & | DeltaSal | ||
| ) |
Solve diffusion-advection equation using the upwind explicit method
.
| dt | Time step (s) |
| DeltaSal | Result vector (change in salinity over time step) |
| bool SalinityTransport::SolveSalinityTransportEquationImplicit | ( | const double | dt, |
| std::vector< double > & | DeltaSal, | ||
| const double | f, | ||
| const bool | DonorCell = true |
||
| ) |
Solve diffusion-advection equation using the Crank-Nicolson implicit, or fully implicit method
.
This function solves the following equation (n and i denoting time and spatial level, respectively):
\[ \begin{multlined} \frac{ \left ( \theta^{n+1}_i S_{\mathrm{b}, i}^{n+1} - \theta^{n}_i S_{\mathrm{b}, i}^{n} \right ) } { \Delta t } \\ - f \left [ \left ( \frac{ 2 D_{i+1}^{n} \theta^{n+1}_{i+1} S_{\mathrm{b}, i+1}^{n+1} }{ \Delta z_{\mathrm{up}} \left ( \Delta z_{\mathrm{up}} + \Delta z_{\mathrm{down}} \right ) } - \frac{ 2 D_{i}^{n} \theta^{n+1}_{i} S_{\mathrm{b}, i}^{n+1} }{\left ( \Delta z_{\mathrm{up}} \Delta z_{\mathrm{down}} \right ) } + \frac{ D_{i-1}^{n} \theta^{n+1}_{i-1} S_{\mathrm{b}, i-1}^{n+1} }{ \Delta z_{\mathrm{down}} \left ( \Delta z_{\mathrm{up}} + \Delta z_{\mathrm{down}} \right ) } \right ) \right ] \\ - \left ( 1-f \right ) \left [ \left ( \frac{ 2 D_{i+1}^{n} \theta^{n}_{i+1} S_{\mathrm{b}, i+1}^{n} }{ \Delta z_{\mathrm{up}} \left ( \Delta z_{\mathrm{up}} + \Delta z_{\mathrm{down}} \right ) } - \frac{ 2 D_{i}^{n} \theta^{n}_{i} S_{\mathrm{b}, i}^{n} }{\left ( \Delta z_{\mathrm{up}} \Delta z_{\mathrm{down}} \right ) } + \frac{ D_{i-1}^{n} \theta^{n}_{i-1} S_{\mathrm{b}, i-1}^{n} }{ \Delta z_{\mathrm{down}} \left ( \Delta z_{\mathrm{up}} + \Delta z_{\mathrm{down}} \right ) } \right ) \right ] \\ - f \left [ \left ( \frac{q^{n}_{i+1} S_{\mathrm{b},i+1}^{n+1} - q^{n}_{i-1} S_{\mathrm{b},i-1}^{n+1}}{\left ( \Delta z_{\mathrm{up}} + \Delta z_{\mathrm{down}} \right ) } \right ) \right ] - \left ( 1-f \right ) \left [ \left ( \frac{q^{n}_{i+1} S_{\mathrm{b},i+1}^{n} - q^{n}_{i-1} S_{\mathrm{b},i-1}^{n}}{\left ( \Delta z_{\mathrm{up}} + \Delta z_{\mathrm{down}} \right ) } \right ) \right ] - s_{\mathrm{sb}} = 0 \end{multlined} \]
Here, \(f=1\) results in the fully implicit scheme, whereas \(f=0.5\) corresponds to the Crank-Nicolson scheme. The implicit scheme is first order accurate, whereas the Crank-Nicolson scheme is second order accurate. Furthermore, both are unconditionally stable and suffer only minimal numerical diffusion for the advection part. As with many other common schemes, the advection part is not perfectly conserving sharp transitions. Futhermore, the reason to not use the fully implicit or the Crank Nicolson scheme is the occurrence of spurious oscillations in the solution, which negatively impact the accuracy of the simulations more than the negative effect on computational efficiency imposed by the CFL criterion required for the explicit method (see SalinityTransport::SolveSalinityTransportEquationExcplicit).
| dt | Time step (s) |
| DeltaSal | Result vector (change in salinity over time step) |
| f | Set to 0.5 for Crank-Nicolson, or to 1.0 for fully implicit |
| DonorCell | If true, use mass-conserving donor-cell scheme (upwind). If false, use default implicit discretization |
| bool SalinityTransport::VerifyCFL | ( | const double | dt | ) |
Check for CFL criterion
.
| dt | Time step (s) |
| bool SalinityTransport::VerifyImplicitDt | ( | const double | dt | ) |
Check for Implicit criterion
.
| dt | Time step (s) |
| double SalinityTransport::BottomSalFlux |
| double SalinityTransport::BottomSalinity |
| std::vector<double> SalinityTransport::BrineSal |
| std::vector<double> SalinityTransport::D |
| std::vector<double> SalinityTransport::dz_ |
| std::vector<double> SalinityTransport::dz_down |
| std::vector<double> SalinityTransport::dz_up |
| std::vector<double> SalinityTransport::flux_down |
| std::vector<double> SalinityTransport::flux_down_2 |
| std::vector<double> SalinityTransport::flux_up |
| std::vector<double> SalinityTransport::flux_up_2 |
| std::vector<double> SalinityTransport::sb |
| std::vector<double> SalinityTransport::theta1 |
| std::vector<double> SalinityTransport::theta2 |
| double SalinityTransport::TopSalFlux |
| double SalinityTransport::TopSalinity |