22 #include "pism/energy/enthSystem.hh"
23 #include "pism/util/ConfigInterface.hh"
24 #include "pism/util/EnthalpyConverter.hh"
26 #include "pism/util/error_handling.hh"
32 const std::string &prefix,
33 double dx,
double dy,
double dt,
43 m_strain_heating3(strain_heating3),
69 size_t Mz =
m_z.size();
83 ratio = config.
get_number(prefix +
".temperate_ice_thermal_conductivity_ratio"),
91 if (config.
get_flag(
"energy.temperature_dependent_thermal_conductivity")) {
104 return 9.828 * exp(-0.0057 * T);
125 for (
unsigned int k = 0;
k <
m_w.size(); ++
k) {
153 for (
unsigned int k = 0;
k <=
m_ks;
k++) {
156 p =
m_EC->pressure(depth);
172 const double epsilon = 1e-6 / 3.15569259747e7;
174 for (
unsigned int k = 0;
k <=
m_ks;
k++) {
190 "initAllColumns() in enthSystemCtx");
199 static inline double upwind(
double u,
double E_m,
double E,
double E_p,
double delta_inverse) {
200 return u * delta_inverse * (u < 0 ? (E_p - E) : (E - E_m));
223 const bool include_horizontal_advection =
236 m_L_ks = -Rminus - Rplus + 2.0 * mu_w * A_l;
238 m_D_ks = 1.0 + Rminus + Rplus + 2.0 * mu_w * A_d;
247 double upwind_u = 0.0;
248 double upwind_v = 0.0;
249 if (include_horizontal_advection) {
254 if (include_strain_heating) {
264 "not ready to solve: need initAllColumns() in enthSystemCtx");
268 "not ready to solve: need setSchemeParamsThisColumn() in enthSystemCtx");
279 #if (Pism_DEBUG == 1)
281 if (not std::isnan(
m_D0) || not std::isnan(
m_U0) || not std::isnan(
m_B0)) {
283 "setting basal boundary conditions twice in enthSystemCtx");
349 Rplus = 0.5 * (
m_R[0] +
m_R[1]),
357 m_D0 = 1.0 + Rminus + Rplus + 2.0 * mu_w * A_d;
359 m_U0 = - Rminus - Rplus + 2.0 * mu_w * A_u;
364 double upwind_u = 0.0;
365 double upwind_v = 0.0;
366 if (include_horizontal_advection) {
371 if (include_strain_heating) {
396 for (
unsigned int k = 1;
k <=
m_ks;
k++) {
404 for (
unsigned int k = 1;
k <=
m_ks;
k++) {
409 m_EC->pressure(depth));
431 for (
unsigned int k =
m_ks + 1;
k <
m_R.size(); ++
k) {
486 if (std::isnan(
m_D0) || std::isnan(
m_U0) || std::isnan(
m_B0)) {
488 "solveThisColumn() should only be called after\n"
489 " setting basal boundary condition in enthSystemCtx");
508 for (
unsigned int k = 1;
k <
m_ks;
k++) {
519 S.L(
k) = - Rminus + nu_w * A_l;
520 S.D(
k) = 1.0 + Rminus + Rplus + nu_w * A_d;
521 S.U(
k) = - Rplus + nu_w * A_u;
524 double upwind_u = 0.0;
525 double upwind_v = 0.0;
526 if (include_horizontal_advection) {
531 if (include_strain_heating) {
535 S.RHS(
k) =
m_Enth[
k] +
m_dt * (one_over_rho * Sigma - upwind_u - upwind_v);
551 S.solve(
m_ks + 1, result);
554 e.
add_context(
"solving the tri-diagonal system (enthSystemCtx) at (%d,%d)\n"
555 "saving system to m-file... ",
m_i,
m_j);
561 for (
unsigned int k =
m_ks+1;
k < result.size();
k++) {
double get_number(const std::string &name, UseFlag flag=REMEMBER_THIS_USE) const
bool get_flag(const std::string &name, UseFlag flag=REMEMBER_THIS_USE) const
A class for storing and accessing PISM configuration flags and parameters.
std::shared_ptr< EnthalpyConverter > Ptr
void add_context(const std::string &message)
Add a message providing some context. This way we can (sort of) get a stack trace even though C++ exc...
void save_system(std::ostream &output, unsigned int system_size) const
View the tridiagonal system A x = b to an output stream, both A as a full matrix and b as a vector.
std::string prefix() const
static void save_vector(std::ostream &output, const std::vector< double > &v, unsigned int system_size, const std::string &variable)
Utility for simple ascii view of a vector (one-dimensional column) quantity.
Virtual base class. Abstracts a tridiagonal system to solve in a column of ice and/or bedrock.
A virtual class collecting methods common to ice and bedrock 3D fields.
const array::Array3D & m_w3
void coarse_to_fine(const array::Array3D &coarse, int i, int j, double *fine) const
void reportColumnZeroPivotErrorMFile(unsigned int M)
Write system matrix and right-hand-side into an Python script. The file name contains ZERO_PIVOT_ERRO...
std::vector< double > m_z
levels of the fine vertical grid
unsigned int m_ks
current system size; corresponds to the highest vertical level within the ice
std::vector< double > m_u
u-component of the ice velocity
const array::Array3D & m_u3
pointers to 3D velocity components
void init_column(int i, int j, double ice_thickness)
const array::Array3D & m_v3
int m_i
current column indexes
TridiagonalSystem * m_solver
std::vector< double > m_w
w-component of the ice velocity
std::vector< double > m_v
v-component of the ice velocity
Base class for tridiagonal systems in the ice.
void assemble_R()
Assemble the R array. The R value switches at the CTS.
std::vector< double > m_Enth_s
bool m_margin_exclude_vertical_advection
const array::Array3D & m_Enth3
std::vector< double > m_E_n
std::vector< double > m_E_w
std::vector< double > m_R
values of
const array::Array3D & m_strain_heating3
std::vector< double > m_Enth
void set_surface_neumann_bc(double dE)
Set enthalpy flux at the surface.
void compute_enthalpy_CTS()
Compute the CTS value of enthalpy in an ice column.
EnthalpyConverter::Ptr m_EC
void set_surface_heat_flux(double heat_flux)
Set the top surface heat flux into the ice.
enthSystemCtx(const std::vector< double > &storage_grid, const std::string &prefix, double dx, double dy, double dt, const Config &config, const array::Array3D &Enth3, const array::Array3D &u3, const array::Array3D &v3, const array::Array3D &w3, const array::Array3D &strain_heating3, EnthalpyConverter::Ptr EC)
void init(int i, int j, bool ismarginal, double ice_thickness)
void set_basal_neumann_bc(double dE)
Set enthalpy flux at the base.
bool m_margin_exclude_horizontal_advection
std::vector< double > m_E_e
double k_from_T(double T) const
std::vector< double > m_strain_heating
strain heating in the ice column
bool m_margin_exclude_strain_heat
virtual void save_system(std::ostream &output, unsigned int M) const
void set_basal_heat_flux(double heat_flux)
Set coefficients in discrete equation for Neumann condition at base of ice.
double m_D0
implicit FD method parameter
std::vector< double > m_E_s
void solve(std::vector< double > &result)
Solve the tridiagonal system, in a single column, which determines the new values of the ice enthalpy...
void checkReadyToSolve() const
double compute_lambda()
Compute the lambda for BOMBPROOF.
void set_basal_dirichlet_bc(double E_basal)
Set coefficients in discrete equation for at base of ice.
void set_surface_dirichlet_bc(double E_surface)
#define PISM_ERROR_LOCATION
double min(const array::Scalar &input)
Finds minimum over all the values in an array::Scalar object. Ignores ghosts.
bool marginal(const array::Scalar1 &thickness, int i, int j, double threshold)
static double upwind(double u, double E_m, double E, double E_p, double delta_inverse)
static double K(double psi_x, double psi_y, double speed, double epsilon)
static double S(unsigned n)