sandbox/Antoonvh/frac-dist.h
Distance to a fraction field
We use a slightly modified distance()
function to
find the distance field to a surface that is represented by volume
fractions.
#include "fractions.h"
#include "distance2.h"
Therefore, we need triangles; Using Alexis Berny’s method for triangularization of a fraction field.
struct cff {
scalar c;
face vector f; // optional
};
* coords_from_fractions (struct cff input) {
coord * p;
coord scalar c = input.c;
if (!input.f.x.i)
.f.x.i = -1;
input//We first count how many triangles there will be:
long int nr_tri = 0, nr_p = 0;
foreach(reduction(+:nr_tri)) {
if (c[] > 1e-6 && c[] < 1. - 1e-6) {
= facet_normal (point, c, input.f);
coord n double alpha = plane_alpha (c[], n);
[12];
coord v+= facets (n, alpha, v, 1.) - 2;
nr_tri }
}
//Each triangle has 3 coordinates and we need a `nodata` coordinate:
= (coord*) malloc ((nr_tri*3 + 1)*sizeof(coord));
p // Fill `p` with triplets
foreach(){
if (c[] > 1e-6 && c[] < 1. - 1e-6) {
= facet_normal (point, c, input.f);
coord n double alpha = plane_alpha (c[], n);
[12];
coord vint m = facets (n, alpha, v, 1.); //m is the number of coordinates
for (int j = 0; j < m - 2; j++) {
= {x + v[0].x*Delta , y + v[0].y*Delta , z + v[0].z*Delta};
coord temp1 = {x + v[j+1].x*Delta, y + v[j+1].y*Delta, z + v[j+1].z*Delta};
coord temp2 = {x + v[j+2].x*Delta, y + v[j+2].y*Delta, z + v[j+2].z*Delta};
coord temp3 [nr_p++] = temp1;
p[nr_p++] = temp2;
p[nr_p++] = temp3;
p}
}
}
= {nodata, nodata, nodata};
coord w [nr_p] = w;
preturn p;
}
distance to surface
The user interface is provided via
distance_to_surface()
struct dts {
scalar c; // Volume fraction field
face vector f; // Optional face fraction field
scalar d; // Optional output: centered distance field
vertex scalar phi; // Optional output: distance at vertices
};
void distance_to_surface (struct dts dff) {
assert (dimension == 3); //fixme: there should be a 2D analog
struct cff nja = (struct cff){dff.c, dff.f};
* p = coords_from_fractions (nja);
coord
scalar d = automatic(dff.d);
distance (d, p);
if (dff.phi.i) { //Distance at vertices
vertex scalar phi = dff.phi;
boundary ({d});
foreach_vertex()
[] = (d[] + d[-1] + d[0,-1] + d[-1,-1] +
phi[0,0,-1] + d[-1,0,-1] + d[0,-1,-1] + d[-1,-1,-1])/8.;
dboundary ({phi});
}
}