23 #include "pism/geometry/grounded_cell_fraction.hh"
25 #include "pism/util/error_handling.hh"
26 #include "pism/util/pism_utilities.hh"
27 #include "pism/util/array/Scalar.hh"
65 return 0.5 * std::fabs((a.
x - c.
x) * (b.
y - a.
y) - (a.
x - b.
x) * (c.
y - a.
y));
73 return {a / (a - b), 0.0};
83 return {c / (c - b), b / (b - c)};
93 return {0.0, a / (a - c)};
110 return (p.
x < 0.0 or p.
x > 1.0 or p.
y < 0.0 or p.
y > 1.0);
117 const double threshold = 1e-12;
118 return std::fabs(a.
x - b.
x) < threshold and std::fabs(a.
y - b.
y) < threshold;
134 assert(std::isfinite(a));
135 assert(std::isfinite(b));
136 assert(std::isfinite(c));
138 if (a > 0.0 and b > 0.0 and c > 0.0) {
142 if (a <= 0.0 and b <= 0.0 and c <= 0.0) {
147 const double total_area = 0.5;
157 double ratio =
triangle_area({0.0, 0.0}, ab, ac) / total_area;
158 assert((ratio >= 0.0) and (ratio <= 1.0));
169 double ratio =
triangle_area({1.0, 0.0}, bc, ab) / total_area;
170 assert((ratio >= 0.0) and (ratio <= 1.0));
181 double ratio =
triangle_area({0.0, 1.0}, ac, bc) / total_area;
182 assert((ratio >= 0.0) and (ratio <= 1.0));
194 double ratio =
triangle_area({1.0, 0.0}, bc, ab) / total_area;
195 assert((ratio >= 0.0) and (ratio <= 1.0));
205 double ratio =
triangle_area({0.0, 0.0}, ab, ac) / total_area;
206 assert((ratio >= 0.0) and (ratio <= 1.0));
219 "the logic in grounded_area_fraction failed! Please submit a bug report.");
225 static double F(
double SL,
double B,
double H,
double alpha) {
227 water_depth = SL - B,
228 shelf_depth = H * alpha;
229 return shelf_depth - water_depth;
238 return {
F(SL.
c, B.
c, H.
c, alpha),
239 F(SL.
n, B.
n, H.
n, alpha),
241 F(SL.
w, B.
w, H.
w, alpha),
243 F(SL.
s, B.
s, H.
s, alpha),
245 F(SL.
e, B.
e, H.
e, alpha),
258 double ocean_density,
263 auto grid = result.
grid();
264 double alpha = ice_density / ocean_density;
270 for (
auto p = grid->points(); p; p.next()) {
271 const int i = p.i(), j = p.j();
292 auto S = sea_level.
box(i, j);
293 auto H = ice_thickness.
box(i, j);
294 auto B = bed_topography.
box(i, j);
296 auto x =
F(
S, B, H, alpha);
299 f.
sw = 0.25 * (x.sw + x.s + x.c + x.w);
300 f.
se = 0.25 * (x.s + x.se + x.e + x.c);
301 f.
ne = 0.25 * (x.c + x.e + x.ne + x.n);
302 f.
nw = 0.25 * (x.w + x.c + x.n + x.nw);
304 f.
s = 0.5 * (x.c + x.s);
305 f.
e = 0.5 * (x.c + x.e);
306 f.
n = 0.5 * (x.c + x.n);
307 f.
w = 0.5 * (x.c + x.w);
321 result(i, j) =
clip(fraction, 0.0, 1.0);
void failed()
Indicates a failure of a parallel section.
static RuntimeError formatted(const ErrorLocation &location, const char format[],...) __attribute__((format(printf
build a RuntimeError with a formatted message
Makes sure that we call begin_access() and end_access() for all accessed array::Arrays.
stencils::Box< T > box(int i, int j) const
std::shared_ptr< const Grid > grid() const
#define PISM_ERROR_LOCATION
static double F(double SL, double B, double H, double alpha)
Point intersect_bc(double b, double c)
double grounded_area_fraction(double a, double b, double c)
static bool same(const Point &a, const Point &b)
Point intersect_ac(double a, double c)
void compute_grounded_cell_fraction(double ice_density, double ocean_density, const array::Scalar1 &sea_level, const array::Scalar1 &ice_thickness, const array::Scalar1 &bed_topography, array::Scalar &result)
stencils::Box< double > Box
bool invalid(const Point &p)
static double triangle_area(const Point &a, const Point &b, const Point &c)
Point intersect_ab(double a, double b)
static double S(unsigned n)