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));
326 KSImax = std::max(KSI, KSImax);
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;
373 double fdheal = gammaheal * std::min(0.0, (
m_strain_rates(i, j).eigen1 - healThreshold));
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);