Skip to content
Snippets Groups Projects
Commit 9165d74e authored by Célestin Marot's avatar Célestin Marot
Browse files

I need to investigate

I apparently create some points outside of the circumsphere of their "parent" tetrahedron.
I need to investigate if this is new or if it already did this in the old version
parent 08db7b6b
No related branches found
No related tags found
No related merge requests found
...@@ -1237,11 +1237,17 @@ static HXTStatus insertion(HXT2Sync* shared2sync, ...@@ -1237,11 +1237,17 @@ static HXTStatus insertion(HXT2Sync* shared2sync,
HXT_CHECK( walking2Cavity(mesh, &local->partition, curTet, vta) ); HXT_CHECK( walking2Cavity(mesh, &local->partition, curTet, vta) );
const uint16_t color = mesh->tetrahedra.colors[*curTet];
/* if color==UINT16_MAX, the inserted point is not in any defined volume.
* other than in a perfectDelaunay context, I don't see why anybody would
* want such insertion. */
HXT_ASSERT(perfectlyDelaunay || color!=UINT16_MAX);
if(nodalSizes!=NULL && filterTet(mesh, nodalSizes, *curTet, vta)){ if(nodalSizes!=NULL && filterTet(mesh, nodalSizes, *curTet, vta)){
return HXT_STATUS_FALSE; return HXT_STATUS_FALSE;
} }
const uint16_t color = mesh->tetrahedra.colors[*curTet];
int edgeConstraint = 0; int edgeConstraint = 0;
HXTStatus status = diggingACavity(mesh, local, *curTet, vta, &edgeConstraint); HXTStatus status = diggingACavity(mesh, local, *curTet, vta, &edgeConstraint);
......
...@@ -206,6 +206,11 @@ static void getBestCenter(double p[4][4], double nodalSize[4], double center[3], ...@@ -206,6 +206,11 @@ static void getBestCenter(double p[4][4], double nodalSize[4], double center[3],
double yc = p[3][1] - p[0][1]; double yc = p[3][1] - p[0][1];
double zc = p[3][2] - p[0][2]; double zc = p[3][2] - p[0][2];
/* Squares of lengths of the edges incident to `p[0]'. */
double alength = xa * xa + ya * ya + za * za;
double blength = xb * xb + yb * yb + zb * zb;
double clength = xc * xc + yc * yc + zc * zc;
/* Cross products of these edges. */ /* Cross products of these edges. */
double xcrossbc = yb * zc - yc * zb; double xcrossbc = yb * zc - yc * zb;
double ycrossbc = zb * xc - zc * xb; double ycrossbc = zb * xc - zc * xb;
...@@ -217,11 +222,65 @@ static void getBestCenter(double p[4][4], double nodalSize[4], double center[3], ...@@ -217,11 +222,65 @@ static void getBestCenter(double p[4][4], double nodalSize[4], double center[3],
double ycrossab = za * xb - zb * xa; double ycrossab = za * xb - zb * xa;
double zcrossab = xa * yb - xb * ya; double zcrossab = xa * yb - xb * ya;
/* get the cross product corresponding to the last face: (c-a)x(a-b) */ /* calculate the denominator of the formulae. */
/* the sum of the cross product of the faces of a tetrahedron = 0 */ /* Use orient3d() from http://www.cs.cmu.edu/~quake/robust.html */
double xsumcros = xcrossab + xcrossbc + xcrossca; /* to ensure a correctly signed (and reasonably accurate) result, */
double ysumcros = ycrossab + ycrossbc + ycrossca; /* avoiding any possibility of division by zero. */
double zsumcros = zcrossab + zcrossbc + zcrossca; double xxx = xa * xcrossbc + ya * ycrossbc + za * zcrossbc;
int sureSign = (xxx > o3dstaticfilter) - (xxx < -o3dstaticfilter);
if(sureSign==0)
xxx = orient3d(p[1], p[2], p[3], p[0]);
double denominator = 0.5 / xxx;
/* Calculate offset (from `p[0]') of circumcenter. */
double xcirca = (alength * xcrossbc + blength * xcrossca + clength * xcrossab) *
denominator;
double ycirca = (alength * ycrossbc + blength * ycrossca + clength * ycrossab) *
denominator;
double zcirca = (alength * zcrossbc + blength * zcrossca + clength * zcrossab) *
denominator;
// center[0] = xcirca + p[0][0];
// center[1] = ycirca + p[0][1];
// center[2] = zcirca + p[0][2];
// /* To interpolate a linear function at the circumcenter, define a */
// /* coordinate system with a bary0-axis directed from `p[0]' to `p[1]', */
// /* an bary1-axis directed from `p[0]' to `p[2]', and a bary2-axis directed */
// /* from `p[0]' to `p[3]'. The values for bary0, bary1, and bary2 are computed */
// /* by Cramer's Rule for solving systems of linear equations. */
bary[0] = (xcirca * xcrossbc + ycirca * ycrossbc + zcirca * zcrossbc) *
(2.0 * denominator);
bary[1] = (xcirca * xcrossca + ycirca * ycrossca + zcirca * zcrossca) *
(2.0 * denominator);
bary[2] = (xcirca * xcrossab + ycirca * ycrossab + zcirca * zcrossab) *
(2.0 * denominator);
bary[3] = 1.0 - bary[0] - bary[1] - bary[2];
// if we are outside the tet, we get back inside...
if(bary[0]<0.0 || bary[1]<0.0 || bary[2]<0.0 || bary[3]<0.0) {
/* get the cross product corresponding to the last face: (c-a)x(a-b) */
/* the sum of the cross product of the faces of a tetrahedron = 0 */
double xsumcros = xcrossab + xcrossbc + xcrossca;
double ysumcros = ycrossab + ycrossbc + ycrossca;
double zsumcros = zcrossab + zcrossbc + zcrossca;
double invA0x2 = 1.0/sqrt(xsumcros*xsumcros + ysumcros*ysumcros + zsumcros*zsumcros); /* (2 x area of the facet opposite to p0)^-1 */
double invA1x2 = 1.0/sqrt(xcrossbc*xcrossbc + ycrossbc*ycrossbc + zcrossbc*zcrossbc); /* (2 x area of the facet opposite to p1)^-1 */
double invA2x2 = 1.0/sqrt(xcrossca*xcrossca + ycrossca*ycrossca + zcrossca*zcrossca); /* (2 x area of the facet opposite to p2)^-1 */
double invA3x2 = 1.0/sqrt(xcrossab*xcrossab + ycrossab*ycrossab + zcrossab*zcrossab); /* (2 x area of the facet opposite to p3)^-1 */
double x75_den = invA0x2 + invA1x2 + invA2x2 + invA3x2;
const double alpha = 0.5;
bary[0] = (1.0 - alpha)*0.25 + alpha*invA0x2/x75_den;
bary[1] = (1.0 - alpha)*0.25 + alpha*invA1x2/x75_den;
bary[2] = (1.0 - alpha)*0.25 + alpha*invA2x2/x75_den;
bary[3] = (1.0 - alpha)*0.25 + alpha*invA3x2/x75_den;
}
// we would like to ponderate points something proportional to the inverse of its nodalsize // we would like to ponderate points something proportional to the inverse of its nodalsize
double avg = 0.0; double avg = 0.0;
...@@ -247,17 +306,14 @@ static void getBestCenter(double p[4][4], double nodalSize[4], double center[3], ...@@ -247,17 +306,14 @@ static void getBestCenter(double p[4][4], double nodalSize[4], double center[3],
double s2 = nodalSize[2]==DBL_MAX ? avg : nodalSize[2]; double s2 = nodalSize[2]==DBL_MAX ? avg : nodalSize[2];
double s3 = nodalSize[3]==DBL_MAX ? avg : nodalSize[3]; double s3 = nodalSize[3]==DBL_MAX ? avg : nodalSize[3];
double invA0x2 = 1.0/sqrt(xsumcros*xsumcros + ysumcros*ysumcros + zsumcros*zsumcros); /* (2 x area of the facet opposite to p0)^-1 */ // we don't entirely ponderate by the mesh size, only a factor alpha of the coordinates
double invA1x2 = 1.0/sqrt(xcrossbc*xcrossbc + ycrossbc*ycrossbc + zcrossbc*zcrossbc); /* (2 x area of the facet opposite to p1)^-1 */ // are ponderated by the mesh size.
double invA2x2 = 1.0/sqrt(xcrossca*xcrossca + ycrossca*ycrossca + zcrossca*zcrossca); /* (2 x area of the facet opposite to p2)^-1 */ const double alpha = 0.5;
double invA3x2 = 1.0/sqrt(xcrossab*xcrossab + ycrossab*ycrossab + zcrossab*zcrossab); /* (2 x area of the facet opposite to p3)^-1 */
double x75_den = invA0x2 + invA1x2 + invA2x2 + invA3x2; bary[0] = (1.0 - alpha)*bary[0] + alpha * bary[0]/s0;
bary[1] = (1.0 - alpha)*bary[1] + alpha * bary[1]/s1;
bary[0] = (0.25 + invA0x2 / x75_den) / s0; bary[2] = (1.0 - alpha)*bary[2] + alpha * bary[2]/s2;
bary[1] = (0.25 + invA1x2 / x75_den) / s1; bary[3] = (1.0 - alpha)*bary[3] + alpha * bary[3]/s3;
bary[2] = (0.25 + invA2x2 / x75_den) / s2;
bary[3] = (0.25 + invA3x2 / x75_den) / s3;
double baryDenom = bary[0] + bary[1] + bary[2] + bary[3]; double baryDenom = bary[0] + bary[1] + bary[2] + bary[3];
bary[0] /= baryDenom; bary[0] /= baryDenom;
...@@ -413,7 +469,6 @@ static HXTStatus refineBalanceWork(HXTMesh* mesh, uint32_t* startPt, size_t* sta ...@@ -413,7 +469,6 @@ static HXTStatus refineBalanceWork(HXTMesh* mesh, uint32_t* startPt, size_t* sta
} }
startPt[maxThreads] = sum; startPt[maxThreads] = sum;
HXT_INFO("%u points created in %lu tet", sum, mesh->tetrahedra.num);
ptPerThreadGoal = sum/maxThreads + 1; ptPerThreadGoal = sum/maxThreads + 1;
} }
...@@ -486,18 +541,15 @@ HXTStatus hxtRefineTetrahedra(HXTMesh* mesh, HXTDelaunayOptions* delOptions, ...@@ -486,18 +541,15 @@ HXTStatus hxtRefineTetrahedra(HXTMesh* mesh, HXTDelaunayOptions* delOptions,
double s[4]; double s[4];
getTetCoordAndNodalSize(mesh, delOptions->nodalSizes, i, p, s); getTetCoordAndNodalSize(mesh, delOptions->nodalSizes, i, p, s);
// TODO: do a SIMD getBestCenter function... // TODO: do a SIMD getBestCenter function if it gets slow
double bary[4]; double bary[4];
getBestCenter(p, s, &newVertices[4*ptIndex], bary); getBestCenter(p, s, &newVertices[4*ptIndex], bary);
// // the center should be inside the tet // #ifdef DEBUG
// double ori0 = orient3d(p[0], p[1], p[2], &newVertices[4*ptIndex]); if(insphere(p[0], p[1], p[2], p[3], &newVertices[4*ptIndex])>=0.0)
// double ori1 = orient3d(p[0], p[1], &newVertices[4*ptIndex], p[3]); HXT_WARNING("the added point is not even in the circumsphere %.12g", orient3d(p[0], p[1], p[2], p[3]));
// double ori2 = orient3d(p[0], &newVertices[4*ptIndex], p[2], p[3]); // #endif
// double ori3 = orient3d(&newVertices[4*ptIndex], p[1], p[2], p[3]);
// if(ori0 > 0.0 || ori1 > 0.0 || ori2 > 0.0 || ori3 > 0.0) // the point is created outside the tet.
// continue;
ptToTet[ptIndex] = i; ptToTet[ptIndex] = i;
if(meshSizeFun==NULL) /* we could compute it anyway. TODO: vectorize */ if(meshSizeFun==NULL) /* we could compute it anyway. TODO: vectorize */
...@@ -526,6 +578,10 @@ HXTStatus hxtRefineTetrahedra(HXTMesh* mesh, HXTDelaunayOptions* delOptions, ...@@ -526,6 +578,10 @@ HXTStatus hxtRefineTetrahedra(HXTMesh* mesh, HXTDelaunayOptions* delOptions,
#pragma omp for schedule(static) #pragma omp for schedule(static)
for(size_t i=0; i<totNewPts; i++) { for(size_t i=0; i<totNewPts; i++) {
uint64_t tetID = ptToTet[i]; uint64_t tetID = ptToTet[i];
// if(tetID==HXT_NO_ADJACENT) {
// newVertices[4*i + 3] = -DBL_MAX;
// continue;
// }
double p[4][4]; double p[4][4];
double s[4]; double s[4];
getTetCoordAndNodalSize(mesh, delOptions->nodalSizes, tetID, p, s); getTetCoordAndNodalSize(mesh, delOptions->nodalSizes, tetID, p, s);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment