[SCM] Gerris Flow Solver branch, upstream, updated. b3aa46814a06c9cb2912790b23916ffb44f1f203
Stephane Popinet
s.popinet at niwa.co.nz
Fri May 15 02:52:15 UTC 2009
The following commit has been merged in the upstream branch:
commit 37506ef1c11ce881abd891af636a8cb632df88e8
Author: Stephane Popinet <s.popinet at niwa.co.nz>
Date: Thu Jul 7 10:17:27 2005 +1000
Fix for floating-point bug in calculation of 2D center of mass
Also added checks for consistency of the center of mass and center of
area positions.
darcs-hash:20050707001727-fbd8f-2a97d5d499484e4e772581b1022fd2fbf21976d6.gz
diff --git a/src/solid.c b/src/solid.c
index 181adcb..aedd215 100644
--- a/src/solid.c
+++ b/src/solid.c
@@ -110,6 +110,7 @@ static void face_fractions (CellFace * f, GfsSolidVector * solid, FttVector * h)
gboolean ins;
guint o = 0;
GtsPoint r[2];
+ gdouble a;
solid->a = 0.;
solid->cm.x = solid->cm.y = solid->cm.z = 0.;
@@ -161,9 +162,47 @@ static void face_fractions (CellFace * f, GfsSolidVector * solid, FttVector * h)
else
solid->s[etod[i]] = 0.;
}
- solid->cm.x /= 3.*solid->a;
- solid->cm.y /= 3.*solid->a;
- solid->a /= 2.*h->x*h->y;
+
+ a = solid->a/(2.*h->x*h->y);
+ if (a > 1e-4) {
+ solid->cm.x /= 3.*solid->a;
+ solid->cm.y /= 3.*solid->a;
+ }
+ else {
+ guint n = 0;
+
+ solid->cm.x = solid->cm.y = 0.;
+ for (m = 0; m < 4 && f->n[m] == 0; m++);
+ ins = f->inside[m] < 0;
+ for (k = m; k < m + 4; k++) {
+ guint i = k % 4, i1 = (i + 1) % 4;
+ gdouble x1 = f->p[i].x, y1 = f->p[i].y, x2 = f->p[i1].x, y2 = f->p[i1].y;
+ if (f->n[i] > 0) {
+ gdouble x = (1. - f->x[i])*x1 + f->x[i]*x2;
+ gdouble y = (1. - f->x[i])*y1 + f->x[i]*y2;
+
+ g_assert (ins == (f->inside[i] < 0));
+ solid->cm.x += x;
+ solid->cm.y += y;
+ n++;
+ if (ins) {
+ solid->cm.x += x1;
+ solid->cm.y += y1;
+ n++;
+ }
+ ins = !ins;
+ }
+ else if (ins) {
+ solid->cm.x += x1;
+ solid->cm.y += y1;
+ n++;
+ }
+ }
+ g_assert (n > 0);
+ solid->cm.x /= n;
+ solid->cm.y /= n;
+ }
+ solid->a = a;
}
#if FTT_2D
@@ -700,6 +739,22 @@ void gfs_domain_init_solid_fractions (GfsDomain * domain,
gts_object_destroy (GTS_OBJECT (p.status));
}
+static gboolean pos_is_inside (FttVector * p, const FttCell * cell)
+{
+ FttVector p1, p2;
+ gdouble h = ftt_cell_size (cell)/2.;
+
+ ftt_cell_pos (cell, &p1);
+ p2.x = (p->x - p1.x)/h;
+ p2.y = (p->y - p1.y)/h;
+ p2.z = (p->z - p1.z)/h;
+ if (fabs (p2.x) > 1. || fabs (p2.y) > 1. || fabs (p2.z) > 1.) {
+ g_warning ("cell: (%g,%g,%g) p2: (%g,%g,%g)", p1.x, p1.y, p1.z, p2.x, p2.y, p2.z);
+ return FALSE;
+ }
+ return TRUE;
+}
+
static gboolean check_area_fractions (const FttCell * root)
{
guint i, level;
@@ -711,6 +766,21 @@ static gboolean check_area_fractions (const FttCell * root)
ftt_cell_neighbors (root, &neighbor);
solid = GFS_STATE (root)->solid;
+ if (solid) {
+ if (!pos_is_inside (&solid->cm, root)) {
+ g_warning ("file %s: line %d (%s): cm is not inside cell",
+ __FILE__, __LINE__, G_GNUC_PRETTY_FUNCTION);
+ ret = FALSE;
+ g_assert_not_reached ();
+ }
+ if (!pos_is_inside (&solid->ca, root)) {
+ g_warning ("file %s: line %d (%s): ca is not inside cell",
+ __FILE__, __LINE__, G_GNUC_PRETTY_FUNCTION);
+ ret = FALSE;
+ g_assert_not_reached ();
+ }
+ }
+
for (i = 0; i < FTT_NEIGHBORS; i++)
if (neighbor.c[i]) {
GfsSolidVector * nsolid = GFS_STATE (neighbor.c[i])->solid;
@@ -811,7 +881,7 @@ static void check_solid_fractions (FttCell * cell, gboolean * ret)
}
a /= FTT_CELLS;
if (fabs (GFS_STATE (cell)->solid->a - a) >= 1e-10) {
- g_warning ("file %s: line %d (%s): children->a: %g parent->a: %g\n",
+ g_warning ("file %s: line %d (%s): children->a: %g parent->a: %g",
__FILE__, __LINE__, G_GNUC_PRETTY_FUNCTION,
a, GFS_STATE (cell)->solid->a);
*ret = FALSE;
--
Gerris Flow Solver
More information about the debian-science-commits
mailing list