84 auto grid = result.
grid();
87 eps = std::numeric_limits<double>::epsilon(),
95 return (Q.e - Q.w) / dx + (Q.n - Q.s) / dy;
98 int limiter_count = 0;
100 for (
auto p = grid->points(); p; p.next()) {
101 const int i = p.i(), j = p.j();
103 auto Q = flux.
star(i, j);
104 auto Q_n = flux.
star(i, j + 1);
105 auto Q_e = flux.
star(i + 1, j);
112 if ((div_Q <= 0.0 or x(i, j) - dt * div_Q >= eps) and
113 (div_Q_e <= 0.0 or x(i + 1, j) - dt * div_Q_e >= eps) and
114 (div_Q_n <= 0.0 or x(i, j + 1) - dt * div_Q_n >= eps)) {
120 result(i, j, 0) = Q.e;
121 result(i, j, 1) = Q.n;
134 double F_out = flux_out(Q, dx, dy, dt);
135 double F_out_n = flux_out(Q_n, dx, dy, dt);
136 double F_out_e = flux_out(Q_e, dx, dy, dt);
139 double F_e = Q.e * dt / dx;
140 double F_n = Q.n * dt / dy;
153 double X_ij = pp(x(i, j) - eps);
154 double X_e = pp(x(i + 1, j) - eps);
155 double X_n = pp(x(i, j + 1) - eps);
158 double F_e_limited = std::max(std::min(F_e, (pp(F_e) / F_out) * X_ij),
159 (-np(F_e) / F_out_e) * X_e);
161 assert(x(i, j) - F_e_limited >= 0);
162 assert(x(i + 1, j) + F_e_limited >= 0);
164 double F_n_limited = std::max(std::min(F_n, (pp(F_n) / F_out) * X_ij),
165 (-np(F_n) / F_out_n) * X_n);
167 assert(x(i, j) - F_n_limited >= 0);
168 assert(x(i, j + 1) + F_n_limited >= 0);
171 result(i, j, 0) = F_e_limited * dx / dt;
172 result(i, j, 1) = F_n_limited * dy / dt;
175 limiter_count =
GlobalSum(grid->com, limiter_count);
176 if (limiter_count > 0) {
177 auto log = grid->ctx()->log();
178 log->message(2,
"limited ice flux at %d locations\n", limiter_count);