23 #include "pism/fracturedensity/FractureDensity.hh"
24 #include "pism/geometry/Geometry.hh"
25 #include "pism/stressbalance/StressBalance.hh"
26 #include "pism/util/pism_utilities.hh"
31 std::shared_ptr<const rheology::FlowLaw> flow_law)
33 m_density(grid,
"fracture_density"),
34 m_density_new(grid,
"new_fracture_density"),
35 m_growth_rate(grid,
"fracture_growth_rate"),
36 m_healing_rate(grid,
"fracture_healing_rate"),
37 m_flow_enhancement(grid,
"fracture_flow_enhancement"),
38 m_age(grid,
"fracture_age"),
39 m_age_new(grid,
"new_fracture_age"),
40 m_toughness(grid,
"fracture_toughness"),
43 m_velocity(grid,
"ghosted_velocity"),
44 m_flow_law(flow_law) {
60 .
long_name(
"fracture-induced flow enhancement");
72 .long_name(
"major principal component of horizontal strain-rate")
77 .long_name(
"minor principal component of horizontal strain-rate")
91 m_log->message(2,
"* Restarting the fracture density model from %s...\n",
102 m_log->message(2,
"* Bootstrapping the fracture density model from %s...\n",
164 &
D, &D_new, &geometry.
cell_type, &bc_mask, &A, &A_new,
172 double soft_residual =
m_config->get_number(
"fracture_density.softening_lower_limit");
197 double gamma =
m_config->get_number(
"fracture_density.gamma");
198 double initThreshold =
m_config->get_number(
"fracture_density.initiation_threshold");
199 double gammaheal =
m_config->get_number(
"fracture_density.gamma_h");
200 double healThreshold =
m_config->get_number(
"fracture_density.healing_threshold");
202 m_log->message(3,
"PISM-PIK INFO: fracture density is found with parameters:\n"
203 " gamma=%.2f, sigma_cr=%.2f, gammah=%.2f, healing_cr=%.1e and soft_res=%f \n",
204 gamma, initThreshold, gammaheal, healThreshold, soft_residual);
206 bool do_fracground =
m_config->get_flag(
"fracture_density.include_grounded_ice");
208 double fdBoundaryValue =
m_config->get_number(
"fracture_density.phi0");
210 bool constant_healing =
m_config->get_flag(
"fracture_density.constant_healing");
212 bool fracture_weighted_healing =
m_config->get_flag(
"fracture_density.fracture_weighted_healing");
214 bool max_shear_stress =
m_config->get_flag(
"fracture_density.max_shear_stress");
216 bool lefm =
m_config->get_flag(
"fracture_density.lefm");
218 bool constant_fd =
m_config->get_flag(
"fracture_density.constant_fd");
220 bool fd2d_scheme =
m_config->get_flag(
"fracture_density.fd2d_scheme");
222 double glen_exponent =
m_flow_law->exponent();
224 bool borstad_limit =
m_config->get_flag(
"fracture_density.borstad_limit");
226 double minH =
m_config->get_number(
"stress_balance.ice_free_thickness_standard");
228 for (
auto p =
m_grid->points(); p; p.next()) {
229 const int i = p.i(), j = p.j();
237 if (u >= dx * v / dy and v >= 0.0) {
238 tempFD = u * (
D(i, j) -
D(i - 1, j)) / dx + v * (
D(i - 1, j) -
D(i - 1, j - 1)) / dy;
239 }
else if (u <= dx * v / dy and u >= 0.0) {
240 tempFD = u * (
D(i, j - 1) -
D(i - 1, j - 1)) / dx + v * (
D(i, j) -
D(i, j - 1)) / dy;
241 }
else if (u >= -dx * v / dy and u <= 0.0) {
242 tempFD = -u * (
D(i, j - 1) -
D(i + 1, j - 1)) / dx + v * (
D(i, j) -
D(i, j - 1)) / dy;
243 }
else if (u <= -dx * v / dy and v >= 0.0) {
244 tempFD = -u * (
D(i, j) -
D(i + 1, j)) / dx + v * (
D(i + 1, j) -
D(i + 1, j - 1)) / dy;
245 }
else if (u <= dx * v / dy and v <= 0.0) {
246 tempFD = -u * (
D(i, j) -
D(i + 1, j)) / dx - v * (
D(i + 1, j) -
D(i + 1, j + 1)) / dy;
247 }
else if (u >= dx * v / dy and u <= 0.0) {
248 tempFD = -u * (
D(i, j + 1) -
D(i + 1, j + 1)) / dx - v * (
D(i, j) -
D(i, j + 1)) / dy;
249 }
else if (u <= -dx * v / dy and u >= 0.0) {
250 tempFD = u * (
D(i, j + 1) -
D(i - 1, j + 1)) / dx - v * (
D(i, j) -
D(i, j + 1)) / dy;
251 }
else if (u >= -dx * v / dy and v <= 0.0) {
252 tempFD = u * (
D(i, j) -
D(i - 1, j)) / dx - v * (
D(i - 1, j) -
D(i - 1, j + 1)) / dy;
254 m_log->message(3,
"######### missing case of angle %f of %f and %f at %d, %d \n",
255 atan(v / u) / M_PI * 180., u * 3e7, v * 3e7, i, j);
258 tempFD += u * (u < 0 ?
D(i + 1, j) -
D(i, j) :
D(i, j) -
D(i - 1, j)) / dx;
259 tempFD += v * (v < 0 ?
D(i, j + 1) -
D(i, j) :
D(i, j) -
D(i, j - 1)) / dy;
262 D_new(i, j) -= tempFD * dt;
271 T1 = 0.5 * (txx + tyy) + sqrt(0.25 * pow(txx - tyy, 2) + pow(txy, 2)),
272 T2 = 0.5 * (txx + tyy) - sqrt(0.25 * pow(txx - tyy, 2) + pow(txy, 2)),
273 sigmat = sqrt(pow(T1, 2) + pow(T2, 2) - T1 * T2);
277 if (max_shear_stress) {
278 double maxshear = fabs(T1);
279 maxshear =
std::max(maxshear, fabs(T2));
280 maxshear =
std::max(maxshear, fabs(T1 - T2));
287 double sigmamu = 0.1;
289 double sigmac = 0.64 / M_PI;
291 double sigmabetatest, sigmanor, sigmatau, Kone, Ktwo, KSI, KSImax = 0.0, sigmatetanull;
293 for (
int l = 46; l <= 90; ++l) {
294 sigmabetatest = l * M_PI / 180.0;
297 sigmanor = 0.5 * (T1 + T2) - (T1 - T2) * cos(2 * sigmabetatest);
298 sigmatau = 0.5 * (T1 - T2) * sin(2 * sigmabetatest);
300 if (sigmamu * sigmanor < 0.0) {
301 if (fabs(sigmatau) <= fabs(sigmamu * sigmanor)) {
305 sigmatau += (sigmamu * sigmanor);
307 sigmatau -= (sigmamu * sigmanor);
313 Kone = sigmanor * sqrt(M_PI * sigmac);
314 Ktwo = sigmatau * sqrt(M_PI * sigmac);
319 sigmatetanull = -2.0 * atan((sqrt(pow(Kone, 2) + 8.0 * pow(Ktwo, 2)) - Kone) / (4.0 * Ktwo));
322 KSI = cos(0.5 * sigmatetanull) *
323 (Kone * cos(0.5 * sigmatetanull) * cos(0.5 * sigmatetanull) - 0.5 * 3.0 * Ktwo * sin(sigmatetanull));
338 double t0 = initThreshold;
344 double ee = sqrt(pow(e1, 2.0) + pow(e2, 2.0) - e1 * e2);
347 double e0 = pow((t0 / hardness(i, j)), glen_exponent);
350 double ex = exp((e0 - ee) / (e0 * (kappa - 1)));
356 double ts = hardness(i, j) * pow(ee, 1.0 / glen_exponent) * (1 - D_new(i, j));
359 if (ts > te and ee > e0) {
361 fdnew = 1.0 - (ex * pow((ee / e0), -1 / glen_exponent));
366 fdnew = gamma * (
m_strain_rates(i, j).eigen1 - 0.0) * (1 - D_new(i, j));
367 if (sigmat > initThreshold) {
368 D_new(i, j) += fdnew * dt;
375 if (constant_healing) {
376 fdheal = gammaheal * (-healThreshold);
377 if (fracture_weighted_healing) {
378 D_new(i, j) += fdheal * dt * (1 -
D(i, j));
380 D_new(i, j) += fdheal * dt;
383 if (fracture_weighted_healing) {
384 D_new(i, j) += fdheal * dt * (1 -
D(i, j));
386 D_new(i, j) += fdheal * dt;
392 D_new(i, j) =
pism::clip(D_new(i, j), 0.0, 1.0);
399 if (sigmat > initThreshold) {
408 if (constant_healing or (
m_strain_rates(i, j).eigen1 < healThreshold)) {
409 if (fracture_weighted_healing) {
421 auto a = A.
star(i, j);
422 A_new(i, j) -= dt * u * (u < 0 ? a.e - a.c : a.c - a.w) / dx;
423 A_new(i, j) -= dt * v * (v < 0 ? a.n - a.c : a.c - a.s) / dy;
425 if (sigmat > initThreshold) {
431 double softening = pow((1.0 - (1.0 - soft_residual) * D_new(i, j)), -glen_exponent);
442 if (bc_mask(i, j) > 0.5) {
443 D_new(i, j) = fdBoundaryValue;
456 if (geometry.
cell_type.
ice_free(i, j) or i == 0 or j == 0 or i == Mx - 1 or j == My - 1) {
470 D_new(i, j) =
D(i, j);
const Config::ConstPtr m_config
configuration database used by this component
const Logger::ConstPtr m_log
logger (for easy access)
@ REGRID_WITHOUT_REGRID_VARS
const std::shared_ptr< const Grid > m_grid
grid used by this component
void regrid(const std::string &module_name, array::Array &variable, RegriddingFlag flag=NO_REGRID_WITHOUT_REGRID_VARS)
A class defining a common interface for most PISM sub-models.
static Ptr wrap(const T &input)
std::string filename() const
High-level PISM I/O class.
void define_model_state_impl(const File &output) const
The default (empty implementation).
void restart(const File &input_file, int record)
void update(double dt, const Geometry &geometry, const array::Vector &velocity, const array::Scalar &hardness, const array::Scalar &inflow_boundary_mask)
FractureDensity(std::shared_ptr< const Grid > grid, std::shared_ptr< const rheology::FlowLaw > flow_law)
array::Array2D< stressbalance::DeviatoricStresses > m_deviatoric_stresses
components of horizontal stress tensor along axes and shear stress (temporary storage)
array::Scalar m_density_new
const array::Scalar & toughness() const
const array::Scalar & growth_rate() const
array::Array2D< stressbalance::PrincipalStrainRates > m_strain_rates
major and minor principal components of horizontal strain-rate tensor (temporary storage)
const array::Scalar & age() const
array::Scalar m_healing_rate
void bootstrap(const File &input_file)
void write_model_state_impl(const File &output) const
The default (empty implementation).
std::shared_ptr< const rheology::FlowLaw > m_flow_law
array::Scalar m_growth_rate
const array::Scalar & healing_rate() const
const array::Scalar & flow_enhancement() const
DiagnosticList diagnostics_impl() const
array::Scalar m_toughness
array::Scalar m_flow_enhancement
const array::Scalar & density() const
array::Vector1 m_velocity
Ghosted copy of the ice velocity.
array::CellType2 cell_type
array::Scalar2 ice_thickness
Makes sure that we call begin_access() and end_access() for all accessed array::Arrays.
void copy_from(const Array2D< T > &source)
stencils::Star< T > star(int i, int j) const
void read(const std::string &filename, unsigned int time)
void define(const File &file, io::Type default_type) const
Define variables corresponding to an Array in a file opened using file.
void write(const std::string &filename) const
void set(double c)
Result: v[j] <- c for all j.
void regrid(const std::string &filename, io::Default default_value)
SpatialVariableMetadata & metadata(unsigned int N=0)
Returns a reference to the SpatialVariableMetadata object containing metadata for the compoment N.
bool ice_free(int i, int j) const
bool grounded(int i, int j) const
bool icy(int i, int j) const
double max(const array::Scalar &input)
Finds maximum over all the values in an array::Scalar object. Ignores ghosts.
double min(const array::Scalar &input)
Finds minimum over all the values in an array::Scalar object. Ignores ghosts.
void compute_2D_principal_strain_rates(const array::Vector1 &V, const array::CellType1 &mask, array::Array2D< PrincipalStrainRates > &result)
Compute eigenvalues of the horizontal, vertically-integrated strain rate tensor.
void compute_2D_stresses(const rheology::FlowLaw &flow_law, const array::Vector1 &velocity, const array::Scalar &hardness, const array::CellType1 &cell_type, array::Array2D< DeviatoricStresses > &result)
Compute 2D deviatoric stresses.
std::map< std::string, Diagnostic::Ptr > DiagnosticList