165 &
D, &D_new, &geometry.
cell_type, &bc_mask, &A, &A_new,
173 double soft_residual =
m_config->get_number(
"fracture_density.softening_lower_limit");
198 double gamma =
m_config->get_number(
"fracture_density.gamma");
199 double initThreshold =
m_config->get_number(
"fracture_density.initiation_threshold");
200 double gammaheal =
m_config->get_number(
"fracture_density.gamma_h");
201 double healThreshold =
m_config->get_number(
"fracture_density.healing_threshold");
203 m_log->message(3,
"PISM-PIK INFO: fracture density is found with parameters:\n"
204 " gamma=%.2f, sigma_cr=%.2f, gammah=%.2f, healing_cr=%.1e and soft_res=%f \n",
205 gamma, initThreshold, gammaheal, healThreshold, soft_residual);
207 bool do_fracground =
m_config->get_flag(
"fracture_density.include_grounded_ice");
209 double fdBoundaryValue =
m_config->get_number(
"fracture_density.phi0");
211 bool constant_healing =
m_config->get_flag(
"fracture_density.constant_healing");
213 bool fracture_weighted_healing =
m_config->get_flag(
"fracture_density.fracture_weighted_healing");
215 bool max_shear_stress =
m_config->get_flag(
"fracture_density.max_shear_stress");
217 bool lefm =
m_config->get_flag(
"fracture_density.lefm");
219 bool constant_fd =
m_config->get_flag(
"fracture_density.constant_fd");
221 bool fd2d_scheme =
m_config->get_flag(
"fracture_density.fd2d_scheme");
223 double glen_exponent =
m_flow_law->exponent();
225 bool borstad_limit =
m_config->get_flag(
"fracture_density.borstad_limit");
227 double minH =
m_config->get_number(
"stress_balance.ice_free_thickness_standard");
229 for (
auto p :
m_grid->points()) {
230 const int i = p.i(), j = p.j();
238 if (u >= dx * v / dy and v >= 0.0) {
239 tempFD = u * (
D(i, j) -
D(i - 1, j)) / dx + v * (
D(i - 1, j) -
D(i - 1, j - 1)) / dy;
240 }
else if (u <= dx * v / dy and u >= 0.0) {
241 tempFD = u * (
D(i, j - 1) -
D(i - 1, j - 1)) / dx + v * (
D(i, j) -
D(i, j - 1)) / dy;
242 }
else if (u >= -dx * v / dy and u <= 0.0) {
243 tempFD = -u * (
D(i, j - 1) -
D(i + 1, j - 1)) / dx + v * (
D(i, j) -
D(i, j - 1)) / dy;
244 }
else if (u <= -dx * v / dy and v >= 0.0) {
245 tempFD = -u * (
D(i, j) -
D(i + 1, j)) / dx + v * (
D(i + 1, j) -
D(i + 1, j - 1)) / dy;
246 }
else if (u <= dx * v / dy and v <= 0.0) {
247 tempFD = -u * (
D(i, j) -
D(i + 1, j)) / dx - v * (
D(i + 1, j) -
D(i + 1, j + 1)) / dy;
248 }
else if (u >= dx * v / dy and u <= 0.0) {
249 tempFD = -u * (
D(i, j + 1) -
D(i + 1, j + 1)) / dx - v * (
D(i, j) -
D(i, j + 1)) / dy;
250 }
else if (u <= -dx * v / dy and u >= 0.0) {
251 tempFD = u * (
D(i, j + 1) -
D(i - 1, j + 1)) / dx - v * (
D(i, j) -
D(i, j + 1)) / dy;
252 }
else if (u >= -dx * v / dy and v <= 0.0) {
253 tempFD = u * (
D(i, j) -
D(i - 1, j)) / dx - v * (
D(i - 1, j) -
D(i - 1, j + 1)) / dy;
255 m_log->message(3,
"######### missing case of angle %f of %f and %f at %d, %d \n",
256 atan(v / u) / M_PI * 180., u * 3e7, v * 3e7, i, j);
259 tempFD += u * (u < 0 ?
D(i + 1, j) -
D(i, j) :
D(i, j) -
D(i - 1, j)) / dx;
260 tempFD += v * (v < 0 ?
D(i, j + 1) -
D(i, j) :
D(i, j) -
D(i, j - 1)) / dy;
263 D_new(i, j) -= tempFD * dt;
272 T1 = 0.5 * (txx + tyy) + sqrt(0.25 * pow(txx - tyy, 2) + pow(txy, 2)),
273 T2 = 0.5 * (txx + tyy) - sqrt(0.25 * pow(txx - tyy, 2) + pow(txy, 2)),
274 sigmat = sqrt(pow(T1, 2) + pow(T2, 2) - T1 * T2);
278 if (max_shear_stress) {
279 double maxshear = fabs(T1);
280 maxshear = std::max(maxshear, fabs(T2));
281 maxshear = std::max(maxshear, fabs(T1 - T2));
288 double sigmamu = 0.1;
290 double sigmac = 0.64 / M_PI;
292 double sigmabetatest, sigmanor, sigmatau, Kone, Ktwo, KSI, KSImax = 0.0, sigmatetanull;
294 for (
int l = 46; l <= 90; ++l) {
295 sigmabetatest = l * M_PI / 180.0;
298 sigmanor = 0.5 * (T1 + T2) - (T1 - T2) * cos(2 * sigmabetatest);
299 sigmatau = 0.5 * (T1 - T2) * sin(2 * sigmabetatest);
301 if (sigmamu * sigmanor < 0.0) {
302 if (fabs(sigmatau) <= fabs(sigmamu * sigmanor)) {
306 sigmatau += (sigmamu * sigmanor);
308 sigmatau -= (sigmamu * sigmanor);
314 Kone = sigmanor * sqrt(M_PI * sigmac);
315 Ktwo = sigmatau * sqrt(M_PI * sigmac);
320 sigmatetanull = -2.0 * atan((sqrt(pow(Kone, 2) + 8.0 * pow(Ktwo, 2)) - Kone) / (4.0 * Ktwo));
323 KSI = cos(0.5 * sigmatetanull) *
324 (Kone * cos(0.5 * sigmatetanull) * cos(0.5 * sigmatetanull) - 0.5 * 3.0 * Ktwo * sin(sigmatetanull));
327 KSImax = std::max(KSI, KSImax);
339 double t0 = initThreshold;
345 double ee = sqrt(pow(e1, 2.0) + pow(e2, 2.0) - e1 * e2);
348 double e0 = pow((t0 / hardness(i, j)), glen_exponent);
351 double ex = exp((e0 - ee) / (e0 * (kappa - 1)));
357 double ts = hardness(i, j) * pow(ee, 1.0 / glen_exponent) * (1 - D_new(i, j));
360 if (ts > te and ee > e0) {
362 fdnew = 1.0 - (ex * pow((ee / e0), -1 / glen_exponent));
367 fdnew = gamma * (
m_strain_rates(i, j).eigen1 - 0.0) * (1 - D_new(i, j));
368 if (sigmat > initThreshold) {
369 D_new(i, j) += fdnew * dt;
374 double fdheal = gammaheal * std::min(0.0, (
m_strain_rates(i, j).eigen1 - healThreshold));
376 if (constant_healing) {
377 fdheal = gammaheal * (-healThreshold);
378 if (fracture_weighted_healing) {
379 D_new(i, j) += fdheal * dt * (1 -
D(i, j));
381 D_new(i, j) += fdheal * dt;
384 if (fracture_weighted_healing) {
385 D_new(i, j) += fdheal * dt * (1 -
D(i, j));
387 D_new(i, j) += fdheal * dt;
393 D_new(i, j) =
pism::clip(D_new(i, j), 0.0, 1.0);
400 if (sigmat > initThreshold) {
409 if (constant_healing or (
m_strain_rates(i, j).eigen1 < healThreshold)) {
410 if (fracture_weighted_healing) {
422 auto a = A.
star(i, j);
423 A_new(i, j) -= dt * u * (u < 0 ? a.e - a.c : a.c - a.w) / dx;
424 A_new(i, j) -= dt * v * (v < 0 ? a.n - a.c : a.c - a.s) / dy;
426 if (sigmat > initThreshold) {
432 double softening = pow((1.0 - (1.0 - soft_residual) * D_new(i, j)), -glen_exponent);
443 if (bc_mask(i, j) > 0.5) {
444 D_new(i, j) = fdBoundaryValue;
457 if (geometry.
cell_type.
ice_free(i, j) or i == 0 or j == 0 or i == Mx - 1 or j == My - 1) {
471 D_new(i, j) =
D(i, j);