diff --git a/README.md b/README.md
index f47dab4..6955631 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,10 @@
## `JIGSAW: An unstructured mesh generator`
-
-  
-  
-  
-
+
+
+
+
+
`JIGSAW` is an unstructured mesh generator and tessellation library; designed to generate high-quality triangulations and polyhedral decompositions of general planar, surface and volumetric domains. `JIGSAW` includes refinement-based algorithms for the construction of new meshes, optimisation-driven techniques for the improvement of existing grids, as well as routines to assemble (restricted) Delaunay tessellations, Voronoi complexes and Power diagrams.
diff --git a/bisect.m b/bisect.m
index 64862d6..264789e 100644
--- a/bisect.m
+++ b/bisect.m
@@ -5,7 +5,7 @@
% Darren Engwirda
% github.com/dengwirda/jigsaw-matlab
% 08-Aug-2019
-% darren.engwirda@columbia.edu
+% d.engwirda@gmail.com
%-----------------------------------------------------------
%
diff --git a/certify.m b/certify.m
index 2933e12..616f285 100644
--- a/certify.m
+++ b/certify.m
@@ -4,8 +4,8 @@
%-----------------------------------------------------------
% Darren Engwirda
% github.com/dengwirda/jigsaw-matlab
-% 07-Aug-2019
-% darren.engwirda@columbia.edu
+% 30-May-2020
+% d.engwirda@gmail.com
%-----------------------------------------------------------
%
@@ -576,6 +576,50 @@
end
end
+ if (inspect(mesh,'seeds'))
+ if (~isempty (mesh.seeds.coord))
+ if ( isnumeric(mesh.seeds.coord))
+%----------------------------------------- check SEEDS array
+ ns = size(mesh.seeds.coord,1) ;
+
+ if (ndims(mesh.seeds.coord) ~= 2)
+ error('certify:incorrectDimensions', ...
+ 'Invalid SEEDS.COORD dimensions.') ;
+ end
+ if ( size(mesh.seeds.coord,2)< 3)
+ error('certify:incorrectDimensions', ...
+ 'Invalid SEEDS.COORD dimensions.') ;
+ end
+
+ if (any(isinf(mesh.seeds.coord)))
+ error('certify:invalidMeshPosition', ...
+ 'Invalid SEEDS.COORD values.') ;
+ end
+ if (any(isnan(mesh.seeds.coord)))
+ error('certify:invalidMeshPosition', ...
+ 'Invalid SEEDS.COORD values.') ;
+ end
+
+ if (isfield(mesh,'mshID'))
+ if (strcmpi(mesh.mshID,'euclidean-grid'))
+ error('certify:incompatiblemshID', ...
+ 'Incompatible msh-ID flag.') ;
+ end
+ if (strcmpi(mesh.mshID,'ellipsoid-grid'))
+ error('certify:incompatiblemshID', ...
+ 'Incompatible msh-ID flag.') ;
+ end
+ end
+
+ else
+%----------------------------------------- wrong SEEDS class
+ error('certify:incorrectInputClass', ...
+ 'Invalid SEEDS.COORD type.') ;
+
+ end
+ end
+ end
+
%----------------------------------------- ok if we get here
flag = +1 ;
diff --git a/compile.m b/compile.m
index 40effaa..81bc6e5 100644
--- a/compile.m
+++ b/compile.m
@@ -17,7 +17,7 @@
% Darren Engwirda
% github.com/dengwirda/jigsaw-matlab
% 26-Jul-2019
-% darren.engwirda@columbia.edu
+% d.engwirda@gmail.com
%-----------------------------------------------------------
%
diff --git a/details.m b/details.m
index 4c2eaa8..e13c595 100644
--- a/details.m
+++ b/details.m
@@ -66,6 +66,6 @@
% Darren Engwirda
% github.com/dengwirda/jigsaw-matlab
% 26-Jul-2019
-% darren.engwirda@columbia.edu
+% d.engwirda@gmail.com
%-----------------------------------------------------------
%
diff --git a/example.m b/example.m
index 8233a41..208bcf1 100644
--- a/example.m
+++ b/example.m
@@ -46,7 +46,7 @@ function example(varargin)
% Darren Engwirda
% github.com/dengwirda/jigsaw-matlab
% 07-Aug-2019
-% darren.engwirda@columbia.edu
+% d.engwirda@gmail.com
%-----------------------------------------------------------
%
@@ -1122,6 +1122,8 @@ function example(varargin)
opts.hfun_hmax = +inf ;
opts.hfun_hmin = +0.0 ;
+ %opts.optm_kern = 'cvt+dqdx';
+
mesh = jigsaw (opts) ;
figure ; drawmesh(mesh) ;
diff --git a/external/jigsaw/README.md b/external/jigsaw/README.md
index ce2b43c..9a02711 100644
--- a/external/jigsaw/README.md
+++ b/external/jigsaw/README.md
@@ -1,10 +1,10 @@
## `JIGSAW: An unstructured mesh generator`
-
-  
-  
-  
-
+
+
+
+
+
`JIGSAW` is an unstructured mesh generator and tessellation library; designed to generate high-quality triangulations and polyhedral decompositions of general planar, surface and volumetric domains. `JIGSAW` includes refinement-based algorithms for the construction of new meshes, optimisation-driven techniques for the improvement of existing grids, as well as routines to assemble (restricted) Delaunay tessellations, Voronoi complexes and Power diagrams.
diff --git a/external/jigsaw/inc/jigsaw_const.h b/external/jigsaw/inc/jigsaw_const.h
index 39f7f8e..1ad031f 100644
--- a/external/jigsaw/inc/jigsaw_const.h
+++ b/external/jigsaw/inc/jigsaw_const.h
@@ -31,11 +31,11 @@
*
--------------------------------------------------------
*
- * Last updated: 27 November, 2019
+ * Last updated: 16 July, 2020
*
- * Copyright 2013-2019
+ * Copyright 2013-2020
* Darren Engwirda
- * darren.engwirda@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda
*
--------------------------------------------------------
@@ -55,6 +55,9 @@
# define JIGSAW_FILE_NOT_CREATED +3
# define JIGSAW_INVALID_ARGUMENT +4
+# define JIGSAW_INVALID_INDEXING +5
+# define JIGSAW_INVALID_USEROPTS +6
+# define JIGSAW_INVALID_ARRAYDIM +7
/*
--------------------------------------------------------
@@ -93,6 +96,7 @@
# define JIGSAW_KERN_ODT_DQDX +404
# define JIGSAW_KERN_CVT_DQDX +405
+# define JIGSAW_KERN_H95_DQDX +406
diff --git a/external/jigsaw/inc/jigsaw_jig_t.h b/external/jigsaw/inc/jigsaw_jig_t.h
index b911745..2e64066 100644
--- a/external/jigsaw/inc/jigsaw_jig_t.h
+++ b/external/jigsaw/inc/jigsaw_jig_t.h
@@ -35,7 +35,7 @@
*
* Copyright 2013-2019
* Darren Engwirda
- * darren.engwirda@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda
*
--------------------------------------------------------
diff --git a/external/jigsaw/inc/jigsaw_msh_t.h b/external/jigsaw/inc/jigsaw_msh_t.h
index 8b76ea6..7823e10 100644
--- a/external/jigsaw/inc/jigsaw_msh_t.h
+++ b/external/jigsaw/inc/jigsaw_msh_t.h
@@ -31,11 +31,11 @@
*
--------------------------------------------------------
*
- * Last updated: 27 June, 2019
+ * Last updated: 30 May, 2020
*
- * Copyright 2013-2019
+ * Copyright 2013-2020
* Darren Engwirda
- * darren.engwirda@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda
*
--------------------------------------------------------
@@ -209,6 +209,9 @@
jigsaw_BOUND_array_t _bound;
+ jigsaw_VERT2_array_t _seed2;
+ jigsaw_VERT3_array_t _seed3;
+
/* if (_flags == ELLIPSOID_MESH) */
jigsaw_REALS_array_t _radii;
diff --git a/external/jigsaw/inc/lib_jigsaw.h b/external/jigsaw/inc/lib_jigsaw.h
index 1e2f94b..d84ff3f 100644
--- a/external/jigsaw/inc/lib_jigsaw.h
+++ b/external/jigsaw/inc/lib_jigsaw.h
@@ -18,7 +18,7 @@
*
* Copyright 2013 -- 2019
* Darren Engwirda
- * darren.engwirda@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda
*
--------------------------------------------------------
diff --git a/external/jigsaw/src/CMakeLists.txt b/external/jigsaw/src/CMakeLists.txt
index eda1ba6..358d3c8 100644
--- a/external/jigsaw/src/CMakeLists.txt
+++ b/external/jigsaw/src/CMakeLists.txt
@@ -2,7 +2,7 @@ function (cfg_compile_options OPT CFG)
add_compile_options ("$<$:${OPT}>")
endfunction ()
-set (CMAKE_CXX_STANDARD 11)
+set (CMAKE_CXX_STANDARD 17)
set (CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR
diff --git a/external/jigsaw/src/geo_load.hpp b/external/jigsaw/src/geo_load.hpp
index b8b2c04..c751960 100644
--- a/external/jigsaw/src/geo_load.hpp
+++ b/external/jigsaw/src/geo_load.hpp
@@ -31,11 +31,11 @@
*
--------------------------------------------------------
*
- * Last updated: 22 July, 2019
+ * Last updated: 30 May, 2020
*
- * Copyright 2013-2019
+ * Copyright 2013-2020
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
--------------------------------------------------------
@@ -167,6 +167,67 @@
_mesh.push_node(_ndat, false) ;
}
}
+ /*---------------------------------- parse SEEDS data */
+ __normal_call void_type push_seeds (
+ std:: size_t _ipos ,
+ double *_pval ,
+ std::int32_t _itag
+ )
+ {
+ __unreferenced(_ipos) ;
+
+ if (this->_ndim == +2 &&
+ this->_kind ==
+ jmsh_kind::euclidean_mesh)
+ {
+ typename
+ geom_data::euclidean_mesh_2d
+ ::seed_type _sdat ;
+ _sdat.mark () = + 0 ;
+ _sdat.self () = + 1 ;
+ _sdat.pval(0) = _pval[0];
+ _sdat.pval(1) = _pval[1];
+ _sdat.itag () = _itag ;
+
+ this->_geom->_euclidean_mesh_2d.
+ _seed.push_tail(_sdat) ;
+ }
+ else
+ if (this->_ndim == +3 &&
+ this->_kind ==
+ jmsh_kind::euclidean_mesh)
+ {
+ typename
+ geom_data::euclidean_mesh_3d
+ ::seed_type _sdat ;
+ _sdat.mark () = + 0 ;
+ _sdat.self () = + 1 ;
+ _sdat.pval(0) = _pval[0];
+ _sdat.pval(1) = _pval[1];
+ _sdat.pval(2) = _pval[2];
+ _sdat.itag () = _itag ;
+
+ this->_geom->_euclidean_mesh_3d.
+ _seed.push_tail(_sdat) ;
+ }
+ else
+ if (this->_kind ==
+ jmsh_kind::ellipsoid_mesh)
+ {
+ typename
+ geom_data::ellipsoid_mesh_3d
+ ::seed_type _sdat ;
+ _sdat.mark () = + 0 ;
+ _sdat.self () = + 1 ;
+ _sdat.pval(0) = _pval[0];
+ _sdat.pval(1) = _pval[1];
+ _sdat.pval(2) = + 0.0 ;
+ _sdat.itag () = _itag ;
+
+ this->_geom->_ellipsoid_mesh_3d.
+ _seed.push_tail(_sdat) ;
+ }
+ }
/*---------------------------------- parse EDGE2 data */
__normal_call void_type push_edge2 (
std:: size_t _ipos ,
@@ -282,9 +343,8 @@
_pdat.indx () = _inum ;
_pdat.kind () = _KIND ;
- this->_geom->
- _euclidean_mesh_2d.
- _part.push(_pdat) ;
+ this->_geom->_euclidean_mesh_2d.
+ _part.push (_pdat) ;
}
else
if (this->_ndim == +3 &&
@@ -298,9 +358,8 @@
_pdat.indx () = _inum ;
_pdat.kind () = _KIND ;
- this->_geom->
- _euclidean_mesh_3d.
- _part.push(_pdat) ;
+ this->_geom->_euclidean_mesh_3d.
+ _part.push (_pdat) ;
}
else
if (this->_kind ==
@@ -343,6 +402,8 @@
{
_jlog.push(
"**parse error: " + * _iter + "\n" ) ;
+
+ _errv = __invalid_argument ;
}
}
catch (...)
@@ -405,6 +466,27 @@
_tria.push_node(_ndat , false) ;
}
+ for (auto _ipos = (size_t) +0 ;
+ _ipos != _gmsh._seed2._size ;
+ ++_ipos )
+ {
+ typename
+ geom_data::euclidean_mesh_2d
+ ::seed_type _sdat ;
+ _sdat.pval(0) = _gmsh.
+ _seed2._data[_ipos]._ppos[0];
+ _sdat.pval(1) = _gmsh.
+ _seed2._data[_ipos]._ppos[1];
+ _sdat.itag () = _gmsh.
+ _seed2._data[_ipos]._itag ;
+
+ _sdat.mark () = + 0 ;
+ _sdat.self () = + 1 ;
+
+ _geom._euclidean_mesh_2d.
+ _seed.push_tail(_sdat);
+ }
+
for (auto _ipos = (size_t) +0 ;
_ipos != _gmsh._edge2._size ;
++_ipos )
@@ -470,6 +552,29 @@
_tria.push_node(_ndat , false) ;
}
+ for (auto _ipos = (size_t) +0 ;
+ _ipos != _gmsh._seed3._size ;
+ ++_ipos )
+ {
+ typename
+ geom_data::euclidean_mesh_3d
+ ::seed_type _sdat ;
+ _sdat.pval(0) = _gmsh.
+ _seed3._data[_ipos]._ppos[0];
+ _sdat.pval(1) = _gmsh.
+ _seed3._data[_ipos]._ppos[1];
+ _sdat.pval(2) = _gmsh.
+ _seed3._data[_ipos]._ppos[2];
+ _sdat.itag () = _gmsh.
+ _seed3._data[_ipos]._itag ;
+
+ _sdat.mark () = + 0 ;
+ _sdat.self () = + 1 ;
+
+ _geom._euclidean_mesh_3d.
+ _seed.push_tail(_sdat);
+ }
+
for (auto _ipos = (size_t) +0 ;
_ipos != _gmsh._edge2._size ;
++_ipos )
@@ -558,24 +663,46 @@
}
for (auto _ipos = (size_t) +0 ;
- _ipos != _gmsh._vert3._size ;
+ _ipos != _gmsh._vert2._size ;
++_ipos )
{
typename
geom_data::ellipsoid_mesh_3d
::node_type _ndat ;
_ndat.pval(0) = _gmsh.
- _vert3._data[_ipos]._ppos[0];
+ _vert2._data[_ipos]._ppos[0];
_ndat.pval(1) = _gmsh.
- _vert3._data[_ipos]._ppos[1];
+ _vert2._data[_ipos]._ppos[1];
_ndat.pval(2) = + 0.0 ;
_ndat.itag () = _gmsh.
- _vert3._data[_ipos]._itag ;
+ _vert2._data[_ipos]._itag ;
_geom._ellipsoid_mesh_3d.
_mesh.push_node(_ndat , false) ;
}
+ for (auto _ipos = (size_t) +0 ;
+ _ipos != _gmsh._seed2._size ;
+ ++_ipos )
+ {
+ typename
+ geom_data::ellipsoid_mesh_3d
+ ::seed_type _sdat ;
+ _sdat.pval(0) = _gmsh.
+ _seed2._data[_ipos]._ppos[0];
+ _sdat.pval(1) = _gmsh.
+ _seed2._data[_ipos]._ppos[1];
+ _sdat.pval(2) = + 0.0 ;
+ _sdat.itag () = _gmsh.
+ _seed2._data[_ipos]._itag ;
+
+ _sdat.mark () = + 0 ;
+ _sdat.self () = + 1 ;
+
+ _geom._ellipsoid_mesh_3d.
+ _seed.push_tail(_sdat);
+ }
+
for (auto _ipos = (size_t) +0 ;
_ipos != _gmsh._edge2._size ;
++_ipos )
@@ -668,17 +795,17 @@
{
/*--------------------------------- euclidean-mesh-2d */
iptr_type _imin =
- std::numeric_limits::max() ;
+ std::numeric_limits::max () ;
iptr_type _imax =
- std::numeric_limits::min() ;
+ std::numeric_limits::min () ;
iptr_type _nnPT = +0 ;
iptr_type _nnE2 = +0 ;
for (auto _iter = _geom.
- _euclidean_mesh_2d._tria._set1.head() ;
+ _euclidean_mesh_2d._tria.node().head() ;
_iter != _geom.
- _euclidean_mesh_2d._tria._set1.tend() ;
+ _euclidean_mesh_2d._tria.node().tend() ;
++_iter )
{
if (_iter->mark() < 0) continue;
@@ -687,9 +814,9 @@
}
for (auto _iter = _geom.
- _euclidean_mesh_2d._tria._set2.head() ;
+ _euclidean_mesh_2d._tria.edge().head() ;
_iter != _geom.
- _euclidean_mesh_2d._tria._set2.tend() ;
+ _euclidean_mesh_2d._tria.edge().tend() ;
++_iter )
{
if (_iter->mark() < 0) continue;
@@ -708,7 +835,7 @@
if (_imin < +0 ||
_imax >= _nnPT)
{
- _errv = __invalid_argument ;
+ _errv = __invalid_indexing ;
}
}
@@ -740,12 +867,12 @@
_pptr->_data.indx() >= _nnE2
)
{
- _errv = __invalid_argument ;
+ _errv = __invalid_indexing ;
}
}
else
{
- _errv = __invalid_argument ;
+ _errv = __invalid_indexing ;
}
}
@@ -766,32 +893,32 @@
{
/*--------------------------------- euclidean-mesh-3d */
iptr_type _imin =
- std::numeric_limits::max() ;
+ std::numeric_limits::max () ;
iptr_type _imax =
- std::numeric_limits::min() ;
+ std::numeric_limits::min () ;
iptr_type _nnPT = +0 ;
iptr_type _nnE2 = +0 ;
iptr_type _nnT3 = +0 ;
for (auto _iter = _geom.
- _euclidean_mesh_3d._tria._set1.head() ;
+ _euclidean_mesh_3d._tria.node().head() ;
_iter != _geom.
- _euclidean_mesh_3d._tria._set1.tend() ;
+ _euclidean_mesh_3d._tria.node().tend() ;
++_iter )
{
- if (_iter->mark() < 0) continue ;
+ if (_iter->mark() < 0) continue;
_nnPT += +1 ;
}
for (auto _iter = _geom.
- _euclidean_mesh_3d._tria._set2.head() ;
+ _euclidean_mesh_3d._tria.edge().head() ;
_iter != _geom.
- _euclidean_mesh_3d._tria._set2.tend() ;
+ _euclidean_mesh_3d._tria.edge().tend() ;
++_iter )
{
- if (_iter->mark() < 0) continue ;
+ if (_iter->mark() < 0) continue;
_imin = std::min(
_imin, _iter->node(0)) ;
@@ -807,7 +934,7 @@
if (_imin < +0 ||
_imax >= _nnPT)
{
- _errv = __invalid_argument ;
+ _errv = __invalid_indexing ;
}
}
@@ -820,12 +947,12 @@
}
for (auto _iter = _geom.
- _euclidean_mesh_3d._tria._set3.head() ;
+ _euclidean_mesh_3d._tria.tri3().head() ;
_iter != _geom.
- _euclidean_mesh_3d._tria._set3.tend() ;
+ _euclidean_mesh_3d._tria.tri3().tend() ;
++_iter )
{
- if (_iter->mark() < 0) continue ;
+ if (_iter->mark() < 0) continue;
_imin = std::min(
_imin, _iter->node(0)) ;
@@ -845,7 +972,7 @@
if (_imin < +0 ||
_imax >= _nnPT)
{
- _errv = __invalid_argument ;
+ _errv = __invalid_indexing ;
}
}
@@ -877,12 +1004,12 @@
_pptr->_data.indx() >= _nnT3
)
{
- _errv = __invalid_argument ;
+ _errv = __invalid_indexing ;
}
}
else
{
- _errv = __invalid_argument ;
+ _errv = __invalid_indexing ;
}
}
@@ -936,17 +1063,17 @@
real_type _ymax = _YMIN;
iptr_type _imin =
- std::numeric_limits::max() ;
+ std::numeric_limits::max () ;
iptr_type _imax =
- std::numeric_limits::min() ;
+ std::numeric_limits::min () ;
iptr_type _nnPT = +0 ;
iptr_type _nnE2 = +0 ;
for (auto _iter = _geom.
- _ellipsoid_mesh_3d._mesh._set1.head() ;
+ _ellipsoid_mesh_3d._mesh.node().head() ;
_iter != _geom.
- _ellipsoid_mesh_3d._mesh._set1.tend() ;
+ _ellipsoid_mesh_3d._mesh.node().tend() ;
++_iter )
{
if (_iter->mark() < 0) continue;
@@ -983,9 +1110,9 @@
}
for (auto _iter = _geom.
- _ellipsoid_mesh_3d._mesh._set2.head() ;
+ _ellipsoid_mesh_3d._mesh.edge().head() ;
_iter != _geom.
- _ellipsoid_mesh_3d._mesh._set2.tend() ;
+ _ellipsoid_mesh_3d._mesh.edge().tend() ;
++_iter )
{
if (_iter->mark() < 0) continue;
@@ -1004,7 +1131,7 @@
if (_imin < +0 ||
_imax >= _nnPT)
{
- _errv = __invalid_argument ;
+ _errv = __invalid_indexing ;
}
}
@@ -1076,26 +1203,41 @@
iptr_type _nnE2 = +0 ;
for (auto _iter = _geom.
- _euclidean_mesh_2d._tria._set1.head() ;
+ _euclidean_mesh_2d._tria.node().head() ;
_iter != _geom.
- _euclidean_mesh_2d._tria._set1.tend() ;
+ _euclidean_mesh_2d._tria.node().tend() ;
++_iter )
{
- if (_iter->mark()>=+0) _nnPT += +1 ;
+ if (_iter->mark()>=0 ) _nnPT += +1 ;
}
__dumpINTS("|COORD.|", _nnPT)
for (auto _iter = _geom.
- _euclidean_mesh_2d._tria._set2.head() ;
+ _euclidean_mesh_2d._tria.edge().head() ;
_iter != _geom.
- _euclidean_mesh_2d._tria._set2.tend() ;
+ _euclidean_mesh_2d._tria.edge().tend() ;
++_iter )
{
- if (_iter->mark()>=+0) _nnE2 += +1 ;
+ if (_iter->mark()>=0 ) _nnE2 += +1 ;
}
__dumpINTS("|EDGE-2|", _nnE2)
+
+ _jlog.push("\n") ;
+
+ iptr_type _nnSD = +0 ;
+
+ for (auto _iter = _geom.
+ _euclidean_mesh_2d._seed.head() ;
+ _iter != _geom.
+ _euclidean_mesh_2d._seed.tend() ;
+ ++_iter )
+ {
+ if (_iter->mark()>=0 ) _nnSD += +1 ;
+ }
+
+ __dumpINTS("|SEEDS.|", _nnSD)
}
else
if (_geom._ndim == +3 &&
@@ -1115,37 +1257,52 @@
iptr_type _nnT3 = +0 ;
for (auto _iter = _geom.
- _euclidean_mesh_3d._tria._set1.head() ;
+ _euclidean_mesh_3d._tria.node().head() ;
_iter != _geom.
- _euclidean_mesh_3d._tria._set1.tend() ;
+ _euclidean_mesh_3d._tria.node().tend() ;
++_iter )
{
- if (_iter->mark()>=+0) _nnPT += +1 ;
+ if (_iter->mark()>=0 ) _nnPT += +1 ;
}
__dumpINTS("|COORD.|", _nnPT)
for (auto _iter = _geom.
- _euclidean_mesh_3d._tria._set2.head() ;
+ _euclidean_mesh_3d._tria.edge().head() ;
_iter != _geom.
- _euclidean_mesh_3d._tria._set2.tend() ;
+ _euclidean_mesh_3d._tria.edge().tend() ;
++_iter )
{
- if (_iter->mark()>=+0) _nnE2 += +1 ;
+ if (_iter->mark()>=0 ) _nnE2 += +1 ;
}
__dumpINTS("|EDGE-2|", _nnE2)
for (auto _iter = _geom.
- _euclidean_mesh_3d._tria._set3.head() ;
+ _euclidean_mesh_3d._tria.tri3().head() ;
_iter != _geom.
- _euclidean_mesh_3d._tria._set3.tend() ;
+ _euclidean_mesh_3d._tria.tri3().tend() ;
++_iter )
{
- if (_iter->mark()>=+0) _nnT3 += +1 ;
+ if (_iter->mark()>=0 ) _nnT3 += +1 ;
}
__dumpINTS("|TRIA-3|", _nnT3)
+
+ _jlog.push("\n") ;
+
+ iptr_type _nnSD = +0 ;
+
+ for (auto _iter = _geom.
+ _euclidean_mesh_3d._seed.head() ;
+ _iter != _geom.
+ _euclidean_mesh_3d._seed.tend() ;
+ ++_iter )
+ {
+ if (_iter->mark()>=0 ) _nnSD += +1 ;
+ }
+
+ __dumpINTS("|SEEDS.|", _nnSD)
}
else
if (_geom._kind ==
@@ -1174,26 +1331,41 @@
iptr_type _nnE2 = +0 ;
for (auto _iter = _geom.
- _ellipsoid_mesh_3d._mesh._set1.head() ;
+ _ellipsoid_mesh_3d._mesh.node().head() ;
_iter != _geom.
- _ellipsoid_mesh_3d._mesh._set1.tend() ;
+ _ellipsoid_mesh_3d._mesh.node().tend() ;
++_iter )
{
- if (_iter->mark()>=+0) _nnPT += +1 ;
+ if (_iter->mark()>=0 ) _nnPT += +1 ;
}
__dumpINTS("|COORD.|", _nnPT)
for (auto _iter = _geom.
- _ellipsoid_mesh_3d._mesh._set2.head() ;
+ _ellipsoid_mesh_3d._mesh.edge().head() ;
_iter != _geom.
- _ellipsoid_mesh_3d._mesh._set2.tend() ;
+ _ellipsoid_mesh_3d._mesh.edge().tend() ;
++_iter )
{
- if (_iter->mark()>=+0) _nnE2 += +1 ;
+ if (_iter->mark()>=0 ) _nnE2 += +1 ;
}
__dumpINTS("|EDGE-2|", _nnE2)
+
+ _jlog.push("\n") ;
+
+ iptr_type _nnSD = +0 ;
+
+ for (auto _iter = _geom.
+ _ellipsoid_mesh_3d._seed.head() ;
+ _iter != _geom.
+ _ellipsoid_mesh_3d._seed.tend() ;
+ ++_iter )
+ {
+ if (_iter->mark()>=0 ) _nnSD += +1 ;
+ }
+
+ __dumpINTS("|SEEDS.|", _nnSD)
}
_jlog.push("\n") ;
diff --git a/external/jigsaw/src/hfn_init.hpp b/external/jigsaw/src/hfn_init.hpp
index 4c51fde..78aeb43 100644
--- a/external/jigsaw/src/hfn_init.hpp
+++ b/external/jigsaw/src/hfn_init.hpp
@@ -35,7 +35,7 @@
*
* Copyright 2013-2019
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
--------------------------------------------------------
diff --git a/external/jigsaw/src/hfn_load.hpp b/external/jigsaw/src/hfn_load.hpp
index 7a0ede8..230a1d1 100644
--- a/external/jigsaw/src/hfn_load.hpp
+++ b/external/jigsaw/src/hfn_load.hpp
@@ -31,11 +31,11 @@
*
--------------------------------------------------------
*
- * Last updated: 22 July, 2019
+ * Last updated: 26 April, 2020
*
- * Copyright 2013-2019
+ * Copyright 2013-2020
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
--------------------------------------------------------
@@ -583,6 +583,8 @@
{
_jlog.push(
"**parse error: " + * _iter + "\n" ) ;
+
+ _errv = __invalid_argument ;
}
}
catch (...)
@@ -1170,9 +1172,9 @@
}
for (auto _iter = _hfun.
- _euclidean_mesh_2d._mesh._set1.head() ;
+ _euclidean_mesh_2d._mesh.node().head();
_iter != _hfun.
- _euclidean_mesh_2d._mesh._set1.tend() ;
+ _euclidean_mesh_2d._mesh.node().tend();
++_iter )
{
if (_iter->mark() < 0) continue ;
@@ -1181,9 +1183,9 @@
}
for (auto _iter = _hfun.
- _euclidean_mesh_2d._mesh._set3.head() ;
+ _euclidean_mesh_2d._mesh.tri3().head();
_iter != _hfun.
- _euclidean_mesh_2d._mesh._set3.tend() ;
+ _euclidean_mesh_2d._mesh.tri3().tend();
++_iter )
{
if (_iter->mark() < 0) continue ;
@@ -1216,7 +1218,7 @@
_jlog.push (
"**input error: DHDX. matrix incorrect dimensions.\n") ;
- _errv = __invalid_argument ;
+ _errv = __invalid_arraydim ;
}
if (_hmin <= (real_type) +0.)
@@ -1240,7 +1242,7 @@
_jlog.push (
"**input error: HFUN. tria. indexing is incorrect.\n") ;
- _errv = __invalid_argument ;
+ _errv = __invalid_indexing ;
}
}
else
@@ -1317,7 +1319,7 @@
_jlog.push (
"**input error: HFUN. matrix incorrect dimensions.\n") ;
- _errv = __invalid_argument ;
+ _errv = __invalid_arraydim ;
}
if (_gnum > +0 &&
@@ -1327,7 +1329,7 @@
_jlog.push (
"**input error: DHDX. matrix incorrect dimensions.\n") ;
- _errv = __invalid_argument ;
+ _errv = __invalid_arraydim ;
}
if (_hmin <= (real_type) +0.)
@@ -1391,9 +1393,9 @@
}
for (auto _iter = _hfun.
- _euclidean_mesh_3d._mesh._set1.head() ;
+ _euclidean_mesh_3d._mesh.node().head();
_iter != _hfun.
- _euclidean_mesh_3d._mesh._set1.tend() ;
+ _euclidean_mesh_3d._mesh.node().tend();
++_iter )
{
if (_iter->mark() < 0) continue ;
@@ -1402,9 +1404,9 @@
}
for (auto _iter = _hfun.
- _euclidean_mesh_3d._mesh._set4.head() ;
+ _euclidean_mesh_3d._mesh.tri4().head();
_iter != _hfun.
- _euclidean_mesh_3d._mesh._set4.tend() ;
+ _euclidean_mesh_3d._mesh.tri4().tend();
++_iter )
{
if (_iter->mark() < 0) continue ;
@@ -1441,7 +1443,7 @@
_jlog.push (
"**input error: DHDX. matrix incorrect dimensions.\n") ;
- _errv = __invalid_argument ;
+ _errv = __invalid_arraydim ;
}
if (_hmin <= (real_type) +0.)
@@ -1465,7 +1467,7 @@
_jlog.push (
"**input error: HFUN. tria. indexing is incorrect.\n") ;
- _errv = __invalid_argument ;
+ _errv = __invalid_indexing ;
}
}
else
@@ -1558,7 +1560,7 @@
_jlog.push (
"**input error: HFUN. matrix incorrect dimensions.\n") ;
- _errv = __invalid_argument ;
+ _errv = __invalid_arraydim ;
}
if (_gnum > +0 &&
@@ -1568,7 +1570,7 @@
_jlog.push (
"**input error: DHDX. matrix incorrect dimensions.\n") ;
- _errv = __invalid_argument ;
+ _errv = __invalid_arraydim ;
}
if (_hmin <= (real_type) +0.)
@@ -1622,6 +1624,7 @@
(real_type)std::atan(+1.0) * 4. ;
// careful with the way PI truncations onto float
+
// expanded range so that we don't throw warnings
// due to rounding issues...
@@ -1665,9 +1668,9 @@
}
for (auto _iter = _hfun.
- _ellipsoid_mesh_3d._mesh._set1.head() ;
+ _ellipsoid_mesh_3d._mesh.node().head();
_iter != _hfun.
- _ellipsoid_mesh_3d._mesh._set1.tend() ;
+ _ellipsoid_mesh_3d._mesh.node().tend();
++_iter )
{
if (_iter->mark() < 0) continue ;
@@ -1686,9 +1689,9 @@
}
for (auto _iter = _hfun.
- _ellipsoid_mesh_3d._mesh._set3.head() ;
+ _ellipsoid_mesh_3d._mesh.tri3().head();
_iter != _hfun.
- _ellipsoid_mesh_3d._mesh._set3.tend() ;
+ _ellipsoid_mesh_3d._mesh.tri3().tend();
++_iter )
{
if (_iter->mark() < 0) continue ;
@@ -1739,7 +1742,7 @@
_jlog.push (
"**input error: DHDX. matrix incorrect dimensions.\n") ;
- _errv = __invalid_argument ;
+ _errv = __invalid_arraydim ;
}
if (_hmin <= (real_type) +0.)
@@ -1763,7 +1766,7 @@
_jlog.push (
"**input error: HFUN. tria. indexing is incorrect.\n") ;
- _errv = __invalid_argument ;
+ _errv = __invalid_indexing ;
}
}
else
@@ -1901,7 +1904,7 @@
_jlog.push (
"**input error: HFUN. matrix incorrect dimensions.\n") ;
- _errv = __invalid_argument ;
+ _errv = __invalid_arraydim ;
}
if (_gnum > +0 &&
@@ -1911,7 +1914,7 @@
_jlog.push (
"**input error: DHDX. matrix incorrect dimensions.\n") ;
- _errv = __invalid_argument ;
+ _errv = __invalid_arraydim ;
}
if (_hmin <= (real_type) +0.)
@@ -2032,22 +2035,25 @@
_jlog.push(" \n") ;
- for (auto _iter = _hfun.
- _euclidean_mesh_2d._mesh._set1.head() ;
- _iter != _hfun.
- _euclidean_mesh_2d._mesh._set1.tend() ;
- ++_iter )
+ auto _mptr =
+ &_hfun._euclidean_mesh_2d._mesh;
+
+ for (auto _iter =
+ _mptr->node().head();
+ _iter !=
+ _mptr->node().tend();
+ ++_iter )
{
if (_iter->mark()>=+0) _num1 += +1 ;
}
__dumpINTS("|COORD.|", _num1)
- for (auto _iter = _hfun.
- _euclidean_mesh_2d._mesh._set3.head() ;
- _iter != _hfun.
- _euclidean_mesh_2d._mesh._set3.tend() ;
- ++_iter )
+ for (auto _iter =
+ _mptr->tri3().head();
+ _iter !=
+ _mptr->tri3().tend();
+ ++_iter )
{
if (_iter->mark()>=+0) _num3 += +1 ;
}
@@ -2128,22 +2134,25 @@
_jlog.push(" \n") ;
- for (auto _iter = _hfun.
- _euclidean_mesh_3d._mesh._set1.head() ;
- _iter != _hfun.
- _euclidean_mesh_3d._mesh._set1.tend() ;
- ++_iter )
+ auto _mptr =
+ &_hfun._euclidean_mesh_3d._mesh;
+
+ for (auto _iter =
+ _mptr->node().head();
+ _iter !=
+ _mptr->node().tend();
+ ++_iter )
{
if (_iter->mark()>=+0) _num1 += +1 ;
}
__dumpINTS("|COORD.|", _num1)
- for (auto _iter = _hfun.
- _euclidean_mesh_3d._mesh._set4.head() ;
- _iter != _hfun.
- _euclidean_mesh_3d._mesh._set4.tend() ;
- ++_iter )
+ for (auto _iter =
+ _mptr->tri4().head();
+ _iter !=
+ _mptr->tri4().tend();
+ ++_iter )
{
if (_iter->mark()>=+0) _num4 += +1 ;
}
@@ -2223,22 +2232,25 @@
_jlog.push(" \n") ;
- for (auto _iter = _hfun.
- _ellipsoid_mesh_3d._mesh._set1.head() ;
- _iter != _hfun.
- _ellipsoid_mesh_3d._mesh._set1.tend() ;
- ++_iter )
+ auto _mptr =
+ &_hfun._ellipsoid_mesh_3d._mesh;
+
+ for (auto _iter =
+ _mptr->node().head();
+ _iter !=
+ _mptr->node().tend();
+ ++_iter )
{
if (_iter->mark()>=+0) _num1 += +1 ;
}
__dumpINTS("|COORD.|", _num1)
- for (auto _iter = _hfun.
- _ellipsoid_mesh_3d._mesh._set3.head() ;
- _iter != _hfun.
- _ellipsoid_mesh_3d._mesh._set3.tend() ;
- ++_iter )
+ for (auto _iter =
+ _mptr->tri3().head();
+ _iter !=
+ _mptr->tri3().tend();
+ ++_iter )
{
if (_iter->mark()>=+0) _num3 += +1 ;
}
@@ -2283,7 +2295,7 @@
_jlog.push(" \n") ;
if (_hfun._ellipsoid_grid_3d._wrap)
- _jlog.push("PERIODIC = TRUE") ;
+ _jlog.push(" PERIODIC = TRUE") ;
}
diff --git a/external/jigsaw/src/ini_load.hpp b/external/jigsaw/src/ini_load.hpp
index aa60503..c02125d 100644
--- a/external/jigsaw/src/ini_load.hpp
+++ b/external/jigsaw/src/ini_load.hpp
@@ -31,11 +31,11 @@
*
--------------------------------------------------------
*
- * Last updated: 09 April, 2019
+ * Last updated: 04 March, 2020
*
- * Copyright 2013-2019
+ * Copyright 2013-2020
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
--------------------------------------------------------
@@ -221,7 +221,7 @@
{
typename
mesh_data::euclidean_mesh_2d
- ::tria_type _tdat ;
+ ::tri3_type _tdat ;
_tdat.node(0) = _node[0];
_tdat.node(1) = _node[1];
_tdat.node(2) = _node[2];
@@ -238,7 +238,7 @@
{
typename
mesh_data::euclidean_mesh_3d
- ::face_type _tdat ;
+ ::tri3_type _tdat ;
_tdat.node(0) = _node[0];
_tdat.node(1) = _node[1];
_tdat.node(2) = _node[2];
@@ -249,6 +249,52 @@
_mesh.push_tri3(_tdat, false) ;
}
}
+ /*---------------------------------- parse QUAD4 data */
+ __normal_call void_type push_quad4 (
+ std:: size_t _ipos ,
+ std::int32_t *_node ,
+ std::int32_t _itag
+ )
+ {
+ __unreferenced(_ipos) ;
+ __unreferenced(_itag) ;
+
+ if (this->_ndim == +2 &&
+ this->_kind ==
+ jmsh_kind::euclidean_mesh)
+ {
+ typename
+ mesh_data::euclidean_mesh_2d
+ ::quad_type _qdat ;
+ _qdat.node(0) = _node[0];
+ _qdat.node(1) = _node[1];
+ _qdat.node(2) = _node[2];
+ _qdat.node(3) = _node[3];
+ _qdat.itag () = _itag ;
+
+ this->_init->
+ _euclidean_mesh_2d.
+ _mesh.push_quad(_qdat, false) ;
+ }
+ else
+ if (this->_ndim == +3 &&
+ this->_kind ==
+ jmsh_kind::euclidean_mesh)
+ {
+ typename
+ mesh_data::euclidean_mesh_3d
+ ::quad_type _qdat ;
+ _qdat.node(0) = _node[0];
+ _qdat.node(1) = _node[1];
+ _qdat.node(2) = _node[2];
+ _qdat.node(3) = _node[3];
+ _qdat.itag () = _itag ;
+
+ this->_init->
+ _euclidean_mesh_3d.
+ _mesh.push_quad(_qdat, false) ;
+ }
+ }
/*---------------------------------- parse TRIA4 data */
__normal_call void_type push_tria4 (
std:: size_t _ipos ,
@@ -272,7 +318,7 @@
{
typename
mesh_data::euclidean_mesh_3d
- ::tria_type _tdat ;
+ ::tri4_type _tdat ;
_tdat.node(0) = _node[0];
_tdat.node(1) = _node[1];
_tdat.node(2) = _node[2];
@@ -318,6 +364,8 @@
{
_jlog.push(
"**parse error: " + * _iter + "\n" ) ;
+
+ _errv = __invalid_argument ;
}
}
catch (...)
@@ -416,7 +464,7 @@
{
typename
mesh_data::euclidean_mesh_2d
- ::tria_type _tdat ;
+ ::tri3_type _tdat ;
_tdat.node(0) = _imsh.
_tria3._data[_ipos]._node[0];
_tdat.node(1) = _imsh.
@@ -430,6 +478,28 @@
_mesh.push_tri3(_tdat,false);
}
+ for (auto _ipos = (size_t) +0 ;
+ _ipos != _imsh._quad4._size ;
+ ++_ipos )
+ {
+ typename
+ mesh_data::euclidean_mesh_2d
+ ::quad_type _qdat ;
+ _qdat.node(0) = _imsh.
+ _quad4._data[_ipos]._node[0];
+ _qdat.node(1) = _imsh.
+ _quad4._data[_ipos]._node[1];
+ _qdat.node(2) = _imsh.
+ _quad4._data[_ipos]._node[2];
+ _qdat.node(3) = _imsh.
+ _quad4._data[_ipos]._node[3];
+ _qdat.itag () = _imsh.
+ _quad4._data[_ipos]._itag ;
+
+ _init._euclidean_mesh_2d.
+ _mesh.push_quad(_qdat,false);
+ }
+
}
else
if (_imsh._vert3._size > 0)
@@ -495,7 +565,7 @@
{
typename
mesh_data::euclidean_mesh_3d
- ::face_type _tdat ;
+ ::tri3_type _tdat ;
_tdat.node(0) = _imsh.
_tria3._data[_ipos]._node[0];
_tdat.node(1) = _imsh.
@@ -509,13 +579,35 @@
_mesh.push_tri3(_tdat,false);
}
+ for (auto _ipos = (size_t) +0 ;
+ _ipos != _imsh._quad4._size ;
+ ++_ipos )
+ {
+ typename
+ mesh_data::euclidean_mesh_3d
+ ::quad_type _qdat ;
+ _qdat.node(0) = _imsh.
+ _quad4._data[_ipos]._node[0];
+ _qdat.node(1) = _imsh.
+ _quad4._data[_ipos]._node[1];
+ _qdat.node(2) = _imsh.
+ _quad4._data[_ipos]._node[2];
+ _qdat.node(3) = _imsh.
+ _quad4._data[_ipos]._node[3];
+ _qdat.itag () = _imsh.
+ _quad4._data[_ipos]._itag ;
+
+ _init._euclidean_mesh_3d.
+ _mesh.push_quad(_qdat,false);
+ }
+
for (auto _ipos = (size_t) +0 ;
_ipos != _imsh._tria4._size ;
++_ipos )
{
typename
mesh_data::euclidean_mesh_3d
- ::tria_type _tdat ;
+ ::tri4_type _tdat ;
_tdat.node(0) = _imsh.
_tria4._data[_ipos]._node[0];
_tdat.node(1) = _imsh.
@@ -628,9 +720,9 @@
iptr_type _nmax = +0 ;
for (auto _iter = _init.
- _euclidean_mesh_2d._mesh._set1.head() ;
+ _euclidean_mesh_2d._mesh.node().head();
_iter != _init.
- _euclidean_mesh_2d._mesh._set1.tend() ;
+ _euclidean_mesh_2d._mesh.node().tend();
++_iter )
{
if (_iter->mark() < 0) continue ;
@@ -639,9 +731,27 @@
}
for (auto _iter = _init.
- _euclidean_mesh_2d._mesh._set2.head() ;
+ _euclidean_mesh_2d._mesh.edge().head();
+ _iter != _init.
+ _euclidean_mesh_2d._mesh.edge().tend();
+ ++_iter )
+ {
+ if (_iter->mark() < 0) continue ;
+
+ _imin = std::min(
+ _imin, _iter->node(0)) ;
+ _imin = std::min(
+ _imin, _iter->node(1)) ;
+ _imax = std::max(
+ _imax, _iter->node(0)) ;
+ _imax = std::max(
+ _imax, _iter->node(1)) ;
+ }
+
+ for (auto _iter = _init.
+ _euclidean_mesh_2d._mesh.tri3().head();
_iter != _init.
- _euclidean_mesh_2d._mesh._set2.tend() ;
+ _euclidean_mesh_2d._mesh.tri3().tend();
++_iter )
{
if (_iter->mark() < 0) continue ;
@@ -650,16 +760,20 @@
_imin, _iter->node(0)) ;
_imin = std::min(
_imin, _iter->node(1)) ;
+ _imin = std::min(
+ _imin, _iter->node(2)) ;
_imax = std::max(
_imax, _iter->node(0)) ;
_imax = std::max(
_imax, _iter->node(1)) ;
+ _imax = std::max(
+ _imax, _iter->node(2)) ;
}
for (auto _iter = _init.
- _euclidean_mesh_2d._mesh._set3.head() ;
+ _euclidean_mesh_2d._mesh.quad().head();
_iter != _init.
- _euclidean_mesh_2d._mesh._set3.tend() ;
+ _euclidean_mesh_2d._mesh.quad().tend();
++_iter )
{
if (_iter->mark() < 0) continue ;
@@ -670,20 +784,24 @@
_imin, _iter->node(1)) ;
_imin = std::min(
_imin, _iter->node(2)) ;
+ _imin = std::min(
+ _imin, _iter->node(3)) ;
_imax = std::max(
_imax, _iter->node(0)) ;
_imax = std::max(
_imax, _iter->node(1)) ;
_imax = std::max(
_imax, _iter->node(2)) ;
+ _imax = std::max(
+ _imax, _iter->node(3)) ;
}
if (_imin < +0 || _imax>=_nmax)
{
_jlog.push (
- "**input error: GEOM. tria. indexing is incorrect.\n") ;
+ "**input error: INIT. cell. indexing is incorrect.\n") ;
- _errv = __invalid_argument ;
+ _errv = __invalid_indexing ;
}
}
else
@@ -700,9 +818,9 @@
iptr_type _nmax = +0 ;
for (auto _iter = _init.
- _euclidean_mesh_3d._mesh._set1.head() ;
+ _euclidean_mesh_3d._mesh.node().head();
_iter != _init.
- _euclidean_mesh_3d._mesh._set1.tend() ;
+ _euclidean_mesh_3d._mesh.node().tend();
++_iter )
{
if (_iter->mark() < 0) continue ;
@@ -711,9 +829,9 @@
}
for (auto _iter = _init.
- _euclidean_mesh_3d._mesh._set2.head() ;
+ _euclidean_mesh_3d._mesh.edge().head();
_iter != _init.
- _euclidean_mesh_3d._mesh._set2.tend() ;
+ _euclidean_mesh_3d._mesh.edge().tend();
++_iter )
{
if (_iter->mark() < 0) continue ;
@@ -729,9 +847,9 @@
}
for (auto _iter = _init.
- _euclidean_mesh_3d._mesh._set3.head() ;
+ _euclidean_mesh_3d._mesh.tri3().head();
_iter != _init.
- _euclidean_mesh_3d._mesh._set3.tend() ;
+ _euclidean_mesh_3d._mesh.tri3().tend();
++_iter )
{
if (_iter->mark() < 0) continue ;
@@ -751,9 +869,35 @@
}
for (auto _iter = _init.
- _euclidean_mesh_3d._mesh._set4.head() ;
+ _euclidean_mesh_3d._mesh.quad().head();
_iter != _init.
- _euclidean_mesh_3d._mesh._set4.tend() ;
+ _euclidean_mesh_3d._mesh.quad().tend();
+ ++_iter )
+ {
+ if (_iter->mark() < 0) continue ;
+
+ _imin = std::min(
+ _imin, _iter->node(0)) ;
+ _imin = std::min(
+ _imin, _iter->node(1)) ;
+ _imin = std::min(
+ _imin, _iter->node(2)) ;
+ _imin = std::min(
+ _imin, _iter->node(3)) ;
+ _imax = std::max(
+ _imax, _iter->node(0)) ;
+ _imax = std::max(
+ _imax, _iter->node(1)) ;
+ _imax = std::max(
+ _imax, _iter->node(2)) ;
+ _imax = std::max(
+ _imax, _iter->node(3)) ;
+ }
+
+ for (auto _iter = _init.
+ _euclidean_mesh_3d._mesh.tri4().head();
+ _iter != _init.
+ _euclidean_mesh_3d._mesh.tri4().tend();
++_iter )
{
if (_iter->mark() < 0) continue ;
@@ -779,9 +923,9 @@
if (_imin < +0 || _imax>=_nmax)
{
_jlog.push (
- "**input error: GEOM. tria. indexing is incorrect.\n") ;
+ "**input error: INIT. cell. indexing is incorrect.\n") ;
- _errv = __invalid_argument ;
+ _errv = __invalid_indexing ;
}
}
@@ -840,42 +984,53 @@
_jlog.push("\n") ;
- iptr_type _num1 = +0 ;
- iptr_type _num2 = +0 ;
- iptr_type _num3 = +0 ;
+ iptr_type _nnN1 = +0 ;
+ iptr_type _nnE2 = +0 ;
+ iptr_type _nnT3 = +0 , _nnQ4 = +0 ;
for (auto _iter = _init.
- _euclidean_mesh_2d._mesh._set1.head() ;
+ _euclidean_mesh_2d._mesh.node().head();
_iter != _init.
- _euclidean_mesh_2d._mesh._set1.tend() ;
+ _euclidean_mesh_2d._mesh.node().tend();
++_iter )
{
- if (_iter->mark()>=+0) _num1 += +1 ;
+ if (_iter->mark()>=+0) _nnN1 += +1 ;
}
- __dumpINTS("|COORD.|", _num1)
+ __dumpINTS("|COORD.|", _nnN1)
for (auto _iter = _init.
- _euclidean_mesh_2d._mesh._set2.head() ;
+ _euclidean_mesh_2d._mesh.edge().head();
_iter != _init.
- _euclidean_mesh_2d._mesh._set2.tend() ;
+ _euclidean_mesh_2d._mesh.edge().tend();
++_iter )
{
- if (_iter->mark()>=+0) _num2 += +1 ;
+ if (_iter->mark()>=+0) _nnE2 += +1 ;
}
- __dumpINTS("|EDGE-2|", _num2)
+ __dumpINTS("|EDGE-2|", _nnE2)
for (auto _iter = _init.
- _euclidean_mesh_2d._mesh._set3.head() ;
+ _euclidean_mesh_2d._mesh.tri3().head();
_iter != _init.
- _euclidean_mesh_2d._mesh._set3.tend() ;
+ _euclidean_mesh_2d._mesh.tri3().tend();
++_iter )
{
- if (_iter->mark()>=+0) _num3 += +1 ;
+ if (_iter->mark()>=+0) _nnT3 += +1 ;
}
- __dumpINTS("|TRIA-3|", _num3)
+ __dumpINTS("|TRIA-3|", _nnT3)
+
+ for (auto _iter = _init.
+ _euclidean_mesh_2d._mesh.quad().head();
+ _iter != _init.
+ _euclidean_mesh_2d._mesh.quad().tend();
+ ++_iter )
+ {
+ if (_iter->mark()>=+0) _nnQ4 += +1 ;
+ }
+
+ __dumpINTS("|QUAD-4|", _nnQ4)
}
else
if (_init._ndim == +3 &&
@@ -890,54 +1045,65 @@
_jlog.push("\n") ;
- iptr_type _num1 = +0 ;
- iptr_type _num2 = +0 ;
- iptr_type _num3 = +0 ;
- iptr_type _num4 = +0 ;
+ iptr_type _nnN1 = +0 ;
+ iptr_type _nnE2 = +0 ;
+ iptr_type _nnT3 = +0 , _nnQ4 = +0 ;
+ iptr_type _nnT4 = +0 ;
+
+ for (auto _iter = _init.
+ _euclidean_mesh_3d._mesh.node().head();
+ _iter != _init.
+ _euclidean_mesh_3d._mesh.node().tend();
+ ++_iter )
+ {
+ if (_iter->mark()>=+0) _nnN1 += +1 ;
+ }
+
+ __dumpINTS("|COORD.|", _nnN1)
for (auto _iter = _init.
- _euclidean_mesh_3d._mesh._set1.head() ;
+ _euclidean_mesh_3d._mesh.edge().head();
_iter != _init.
- _euclidean_mesh_3d._mesh._set1.tend() ;
+ _euclidean_mesh_3d._mesh.edge().tend();
++_iter )
{
- if (_iter->mark()>=+0) _num1 += +1 ;
+ if (_iter->mark()>=+0) _nnE2 += +1 ;
}
- __dumpINTS("|COORD.|", _num1)
+ __dumpINTS("|EDGE-2|", _nnE2)
for (auto _iter = _init.
- _euclidean_mesh_3d._mesh._set2.head() ;
+ _euclidean_mesh_3d._mesh.tri3().head();
_iter != _init.
- _euclidean_mesh_3d._mesh._set2.tend() ;
+ _euclidean_mesh_3d._mesh.tri3().tend();
++_iter )
{
- if (_iter->mark()>=+0) _num2 += +1 ;
+ if (_iter->mark()>=+0) _nnT3 += +1 ;
}
- __dumpINTS("|EDGE-2|", _num2)
+ __dumpINTS("|TRIA-3|", _nnT3)
for (auto _iter = _init.
- _euclidean_mesh_3d._mesh._set3.head() ;
+ _euclidean_mesh_3d._mesh.quad().head();
_iter != _init.
- _euclidean_mesh_3d._mesh._set3.tend() ;
+ _euclidean_mesh_3d._mesh.quad().tend();
++_iter )
{
- if (_iter->mark()>=+0) _num3 += +1 ;
+ if (_iter->mark()>=+0) _nnQ4 += +1 ;
}
- __dumpINTS("|TRIA-3|", _num3)
+ __dumpINTS("|QUAD-4|", _nnQ4)
for (auto _iter = _init.
- _euclidean_mesh_3d._mesh._set4.head() ;
+ _euclidean_mesh_3d._mesh.tri4().head();
_iter != _init.
- _euclidean_mesh_3d._mesh._set4.tend() ;
+ _euclidean_mesh_3d._mesh.tri4().tend();
++_iter )
{
- if (_iter->mark()>=+0) _num4 += +1 ;
+ if (_iter->mark()>=+0) _nnT4 += +1 ;
}
- __dumpINTS("|TRIA-4|", _num4)
+ __dumpINTS("|TRIA-4|", _nnT4)
}
_jlog.push("\n") ;
diff --git a/external/jigsaw/src/jig_load.hpp b/external/jigsaw/src/jig_load.hpp
index 37a31f2..0415bcd 100644
--- a/external/jigsaw/src/jig_load.hpp
+++ b/external/jigsaw/src/jig_load.hpp
@@ -31,11 +31,11 @@
*
--------------------------------------------------------
*
- * Last updated: 29 October, 2019
+ * Last updated: 16 July, 2020
*
- * Copyright 2013-2019
+ * Copyright 2013-2020
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
--------------------------------------------------------
@@ -439,6 +439,8 @@
{
_jlog.push(
"**parse error: " + * _iter + "\n" ) ;
+
+ _errv = __invalid_useropts ;
}
}
catch (...)
@@ -488,6 +490,8 @@
JIGSAW_BNDS_DUALCELL)
_jcfg._bnds_pred =
jcfg_data::bnds_pred::bnd_dual ;
+ else
+ _errv = __invalid_useropts ;
/*------------------------------------- GEOM keywords */
_jcfg._mesh_opts.
@@ -513,6 +517,8 @@
JIGSAW_HFUN_ABSOLUTE)
_jcfg._hfun_scal =
jcfg_data::hfun_scal::absolute ;
+ else
+ _errv = __invalid_useropts ;
_jcfg.
_hfun_hmax = _jjig._hfun_hmax ;
@@ -534,6 +540,8 @@
JIGSAW_KERN_BISECTOR)
_jcfg._mesh_pred =
jcfg_data::mesh_pred::bisector ;
+ else
+ _errv = __invalid_useropts ;
_jcfg._mesh_opts.
dims() = _jjig._mesh_dims ;
@@ -576,6 +584,13 @@
JIGSAW_KERN_CVT_DQDX)
_jcfg._iter_pred =
jcfg_data::iter_pred::cvt_dqdx ;
+ else
+ if (_jjig._optm_kern ==
+ JIGSAW_KERN_H95_DQDX)
+ _jcfg._iter_pred =
+ jcfg_data::iter_pred::h95_dqdx ;
+ else
+ _errv = __invalid_useropts ;
_jcfg._iter_opts.
iter() = _jjig._optm_iter ;
@@ -624,7 +639,7 @@
if ( (__var < __vlo) || \
(__var > __vhi) ) \
{ \
- _errv = __invalid_argument ; \
+ _errv = __invalid_useropts ; \
_sstr.str(""); \
_sstr.clear(); \
_sstr << \
@@ -640,7 +655,7 @@
if ( (__var < __vlo) || \
(__var > __vhi) ) \
{ \
- _errv = __invalid_argument ; \
+ _errv = __invalid_useropts ; \
_sstr.str(""); \
_sstr.clear(); \
_sstr << \
@@ -1012,6 +1027,11 @@
jcfg_data::iter_pred::cvt_dqdx)
_jlog.push (
" OPTM-KERN = CVT+DQDX \n") ;
+ else
+ if(_jcfg._iter_pred ==
+ jcfg_data::iter_pred::h95_dqdx)
+ _jlog.push (
+ " OPTM-KERN = H95+DQDX \n") ;
__dumpINTS("OPTM-ITER",
_jcfg._iter_opts.iter())
diff --git a/external/jigsaw/src/jig_read.hpp b/external/jigsaw/src/jig_read.hpp
index 5956cf9..3983429 100644
--- a/external/jigsaw/src/jig_read.hpp
+++ b/external/jigsaw/src/jig_read.hpp
@@ -31,11 +31,11 @@
*
--------------------------------------------------------
*
- * Last updated: 29 October, 2019
+ * Last updated: 16 July, 2020
*
- * Copyright 2013-2019
+ * Copyright 2013-2020
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
--------------------------------------------------------
@@ -234,8 +234,7 @@
/*---------------------------------- read "file" data */
#define __putFILE(__fun, __tok) \
if (__tok.count() == +2) \
- _dest.__fun( \
- trim(__tok[ 1])) ; \
+ _dest.__fun(trim(__tok[ 1])) ; \
else \
_errs.push_tail(_line) ;
@@ -247,14 +246,17 @@
if (__str[1].find("DELAUNAY")!= \
std::string::npos ) \
_dest.__fun ( \
- jcfg_data \
- ::mesh_pred::delaunay) ; \
+ jcfg_data::mesh_pred::delaunay) ; \
else \
if (__str[1].find("DELFRONT")!= \
std::string::npos ) \
_dest.__fun ( \
- jcfg_data \
- ::mesh_pred::delfront) ; \
+ jcfg_data::mesh_pred::delfront) ; \
+ else \
+ if (__str[1].find("BISECTOR")!= \
+ std::string::npos ) \
+ _dest.__fun ( \
+ jcfg_data::mesh_pred::bisector) ; \
else \
_errs.push_tail(_line) ; \
} \
@@ -269,14 +271,17 @@
if (__str[1].find("ODT+DQDX")!= \
std::string::npos ) \
_dest.__fun ( \
- jcfg_data \
- ::iter_pred::odt_dqdx) ; \
+ jcfg_data::iter_pred::odt_dqdx) ; \
else \
if (__str[1].find("CVT+DQDX")!= \
std::string::npos ) \
_dest.__fun ( \
- jcfg_data \
- ::iter_pred::cvt_dqdx) ; \
+ jcfg_data::iter_pred::cvt_dqdx) ; \
+ else \
+ if (__str[1].find("H95+DQDX")!= \
+ std::string::npos ) \
+ _dest.__fun ( \
+ jcfg_data::iter_pred::h95_dqdx) ; \
else \
_errs.push_tail(_line) ; \
} \
@@ -291,14 +296,12 @@
if (__str[1].find("BND-TRIA")!= \
std::string::npos ) \
_dest.__fun ( \
- jcfg_data \
- ::bnds_pred::bnd_tria) ; \
+ jcfg_data::bnds_pred::bnd_tria) ; \
else \
if (__str[1].find("BND-DUAL")!= \
std::string::npos ) \
_dest.__fun ( \
- jcfg_data \
- ::bnds_pred::bnd_dual) ; \
+ jcfg_data::bnds_pred::bnd_dual) ; \
else \
_errs.push_tail(_line) ; \
} \
@@ -313,14 +316,12 @@
if (__str[1].find("ABSOLUTE")!= \
std::string::npos ) \
_dest.__fun ( \
- jcfg_data \
- ::hfun_scal::absolute) ; \
+ jcfg_data::hfun_scal::absolute) ; \
else \
if (__str[1].find("RELATIVE")!= \
std::string::npos ) \
_dest.__fun ( \
- jcfg_data \
- ::hfun_scal::relative) ; \
+ jcfg_data::hfun_scal::relative) ; \
else \
_errs.push_tail(_line) ; \
} \
diff --git a/external/jigsaw/src/jigsaw.cpp b/external/jigsaw/src/jigsaw.cpp
index 46eae57..333e417 100644
--- a/external/jigsaw/src/jigsaw.cpp
+++ b/external/jigsaw/src/jigsaw.cpp
@@ -2,22 +2,25 @@
//
// for cmd-jigsaw:
//
- // g++ -std=c++11 -pedantic -Wall -Wextra -O3 -flto
- // -DNDEBUG -D__cmd_jigsaw jigsaw.cpp -o../bin/jigsaw
+ // g++ -std=c++17 -pedantic -Wall -Wextra -O3 -flto
+ // -DNDEBUG -DCMD_JIGSAW jigsaw.cpp -o../bin/jigsaw
//
- // g++ -std=c++11 -pedantic -Wall -Wextra -O3 -flto
- // -DNDEBUG -D__cmd_tripod jigsaw.cpp -o../bin/tripod
- //
- // g++ -std=c++11 -pedantic -Wall -Wextra -O3 -flto
- // -DNDEBUG -D__cmd_marche jigsaw.cpp -o../bin/marche
+ // g++ -std=c++17 -pedantic -Wall -Wextra -O3 -flto
+ // -DNDEBUG -DCMD_TRIPOD jigsaw.cpp -o../bin/tripod
//
+ // g++ -std=c++17 -pedantic -Wall -Wextra -O3 -flto
+ // -DNDEBUG -DCMD_MARCHE jigsaw.cpp -o../bin/marche
//
// for lib-jigsaw:
//
- // g++ -std=c++11 -pedantic -Wall -Wextra -O3 -flto
- // -fPIC -DNDEBUG -D__lib_jigsaw jigsaw.cpp -shared
+ // g++ -std=c++17 -pedantic -Wall -Wextra -O3 -flto
+ // -fPIC -DNDEBUG -DLIB_JIGSAW jigsaw.cpp -shared
// -o../lib/libjigsaw.so
//
+ // more option(s):
+ //
+ // -DUSE_NETCDF
+ // -DUSE_TIMERS
//
// -Wfloat-conversion -Wsign-conversion -Wshadow
//
@@ -37,12 +40,12 @@
* JIGSAW: an unstructured mesh generation library.
--------------------------------------------------------
*
- * JIGSAW release 0.9.12.x
- * Last updated: 25 November, 2019
+ * JIGSAW release 0.9.13.x
+ * Last updated: 27 July, 2020
*
- * Copyright 2013 -- 2019
+ * Copyright 2013 -- 2020
* Darren Engwirda
- * darren.engwirda@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda
*
--------------------------------------------------------
@@ -184,27 +187,43 @@
--------------------------------------------------------
*/
+# define __JGSWVSTR "JIGSAW VERSION 0.9.13"
-# define __jloglndv \
-"#------------------------------------------------------------\n"
+# if defined( USE_NETCDF)
+# define __use_netcdf
+# endif
+# if defined( USE_TIMERS)
+# define __use_timers
+# endif
-// define __cmd_jigsaw // the cmd-ln exe's
-// define __cmd_tripod
-// define __cmd_marche
+ // define __cmd_jigsaw // the cmd-ln exe's
+ // define __cmd_tripod
+ // define __cmd_marche
+ // define __lib_jigsaw // a shared library
-// define __lib_jigsaw // a shared library
+# if defined( CMD_JIGSAW)
+# define __cmd_jigsaw
+# endif
+# if defined( CMD_TRIPOD)
+# define __cmd_tripod
+# endif
+# if defined( CMD_MARCHE)
+# define __cmd_marche
+# endif
+# if defined( LIB_JIGSAW)
+# define __lib_jigsaw
+# endif
# if !defined(__cmd_jigsaw) && \
!defined(__cmd_tripod) && \
!defined(__cmd_marche) && \
!defined(__lib_jigsaw)
-
/*---------------------------------- build by default */
# define __cmd_jigsaw
-
# endif
-# define __JGSWVSTR "JIGSAW VERSION 0.9.12"
+# define __jloglndv \
+"#------------------------------------------------------------\n"
/*---------------------------------- for i/o on files */
@@ -229,11 +248,19 @@
# include
# endif//__use_timers
- /*---------------------------------- JIGSAW's backend */
+ /*---------------------------------- to do netcdf i/o */
+ extern "C"
+ {
+# ifdef __use_netcdf
+# include "netcdf/lib_netcdf.h"
+# endif//__use_netcdf
+ }
+
+ /*---------------------------------- JIGSAW's backend */
-# include "libcpp/libbasic.hpp"
-# include "libcpp/libparse.hpp"
+# include "libcpp/basebase.hpp"
+# include "libcpp/textutil.hpp"
# include "libcpp/useropts.hpp"
@@ -278,6 +305,12 @@
iptr_type static constexpr
__invalid_argument = +4 ;
+ iptr_type static constexpr
+ __invalid_indexing = +5 ;
+ iptr_type static constexpr
+ __invalid_useropts = +6 ;
+ iptr_type static constexpr
+ __invalid_arraydim = +7 ;
/*
@@ -332,7 +365,8 @@
enum enum_data {
nullkern ,
odt_dqdx = JIGSAW_KERN_ODT_DQDX,
- cvt_dqdx = JIGSAW_KERN_CVT_DQDX
+ cvt_dqdx = JIGSAW_KERN_CVT_DQDX,
+ h95_dqdx = JIGSAW_KERN_H95_DQDX
} ;
} ;
@@ -380,7 +414,6 @@
class geom_data // holds the GEOM obj.
{
public :
-
typedef mesh ::geom_mesh_euclidean_2d <
real_type,
iptr_type> euclidean_mesh_2d ;
@@ -405,9 +438,7 @@
ellipsoid_mesh_3d _ellipsoid_mesh_3d ;
public :
-
/*------------------------- helper: init. everything! */
-
__normal_call void_type init_geom (
jcfg_data &_jcfg
)
@@ -439,7 +470,6 @@
class hfun_data // holds the HFUN obj.
{
public :
-
typedef mesh ::hfun_constant_value_kd <
iptr_type,
real_type> constant_value_kd ;
@@ -487,9 +517,7 @@
ellipsoid_grid_3d _ellipsoid_grid_3d ;
public :
-
/*------------------------- helper: init. everything! */
-
__normal_call void_type init_hfun (
jcfg_data &_jcfg,
bool_type _link = false
@@ -526,7 +554,6 @@
}
/*------------------------- helper: limit everything! */
-
__normal_call void_type clip_hfun (
jcfg_data &_jcfg
)
@@ -555,14 +582,13 @@
/*
--------------------------------------------------------
- * aggregated RDEL data containers.
+ * aggregated MESH data containers.
--------------------------------------------------------
*/
- class rdel_data // holds the restrict-del obj.
+ class mesh_data // holds the mesh-complex obj.
{
public :
-
typedef mesh::rdel_complex_2d <
real_type ,
iptr_type > euclidean_rdel_2d ;
@@ -571,29 +597,15 @@
real_type ,
iptr_type > euclidean_rdel_3d ;
- std::size_t _ndim = +0;
-
- jmsh_kind ::
- enum_data _kind =
- jmsh_kind::null_mesh_kind ;
-
- euclidean_rdel_2d _euclidean_rdel_2d ;
- euclidean_rdel_3d _euclidean_rdel_3d ;
-
- euclidean_rdel_2d _euclidean_rvor_2d ;
- euclidean_rdel_3d _euclidean_rvor_3d ;
-
- } ;
-
- /*
- --------------------------------------------------------
- * aggregated MESH data containers.
- --------------------------------------------------------
- */
+ /*
+ typedef mesh::tree_complex_2d <
+ real_type ,
+ iptr_type > euclidean_tree_2d ;
- class mesh_data // holds the tria-complex obj.
- {
- public :
+ typedef mesh::tree_complex_3d <
+ real_type ,
+ iptr_type > euclidean_tree_3d ;
+ */
typedef mesh::iter_mesh_euclidean_2d <
real_type ,
@@ -609,6 +621,12 @@
enum_data _kind =
jmsh_kind::null_mesh_kind ;
+ euclidean_rdel_2d _euclidean_rdel_2d ;
+ euclidean_rdel_3d _euclidean_rdel_3d ;
+
+ euclidean_rdel_2d _euclidean_rvor_2d ;
+ euclidean_rdel_3d _euclidean_rvor_3d ;
+
euclidean_mesh_2d _euclidean_mesh_2d ;
euclidean_mesh_3d _euclidean_mesh_3d ;
@@ -747,7 +765,7 @@
/*
--------------------------------------------------------
- * COPY-MESH: copy r-DT to tri-complex.
+ * COPY-MESH: copy rDT to mesh-complex.
--------------------------------------------------------
*/
diff --git a/external/jigsaw/src/jigsaw.hpp b/external/jigsaw/src/jigsaw.hpp
index 5e769ac..8af1def 100644
--- a/external/jigsaw/src/jigsaw.hpp
+++ b/external/jigsaw/src/jigsaw.hpp
@@ -14,11 +14,11 @@
* JIGSAW: an unstructured mesh generation library.
--------------------------------------------------------
*
- * Last updated: 25 November, 2019
+ * Last updated: 16 July, 2020
*
- * Copyright 2013 -- 2019
+ * Copyright 2013 -- 2020
* Darren Engwirda
- * darren.engwirda@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda
*
--------------------------------------------------------
@@ -308,13 +308,13 @@
template <
typename jlog_data
>
- __normal_call iptr_type mesh_impl (
+ __normal_call iptr_type mesh_core (
jcfg_data &_args,
jlog_data &_jlog,
geom_data &_geom,
mesh_data &_init,
hfun_data &_hfun,
- rdel_data &_rdel
+ mesh_data &_mesh
)
{
iptr_type _errv = __no_error ;
@@ -330,16 +330,16 @@
if (_hfun._ndim == +0 )
{
/*--------------- with constant-value HFUN kernel */
- _rdel._kind =
+ _mesh._kind =
jmsh_kind::euclidean_mesh;
- _rdel._ndim = +2 ;
+ _mesh._ndim = +2 ;
mesh_euclidean_2d (
_geom._euclidean_mesh_2d,
_init._euclidean_mesh_2d,
_hfun._constant_value_kd,
- _rdel._euclidean_rdel_2d,
+ _mesh._euclidean_rdel_2d,
_args, _jlog) ;
}
else
@@ -348,16 +348,16 @@
jmsh_kind::euclidean_mesh)
{
/*--------------- with euclidean-mesh HFUN kernel */
- _rdel._kind =
+ _mesh._kind =
jmsh_kind::euclidean_mesh;
- _rdel._ndim = +2 ;
+ _mesh._ndim = +2 ;
mesh_euclidean_2d (
_geom._euclidean_mesh_2d,
_init._euclidean_mesh_2d,
_hfun._euclidean_mesh_2d,
- _rdel._euclidean_rdel_2d,
+ _mesh._euclidean_rdel_2d,
_args, _jlog) ;
}
else
@@ -366,16 +366,16 @@
jmsh_kind::euclidean_grid)
{
/*--------------- with euclidean-grid HFUN kernel */
- _rdel._kind =
+ _mesh._kind =
jmsh_kind::euclidean_mesh;
- _rdel._ndim = +2 ;
+ _mesh._ndim = +2 ;
mesh_euclidean_2d (
_geom._euclidean_mesh_2d,
_init._euclidean_mesh_2d,
_hfun._euclidean_grid_2d,
- _rdel._euclidean_rdel_2d,
+ _mesh._euclidean_rdel_2d,
_args, _jlog) ;
}
@@ -390,16 +390,16 @@
if (_hfun._ndim == +0 )
{
/*--------------- with constant-value HFUN kernel */
- _rdel._kind =
+ _mesh._kind =
jmsh_kind::euclidean_mesh;
- _rdel._ndim = +3 ;
+ _mesh._ndim = +3 ;
mesh_euclidean_3d (
_geom._euclidean_mesh_3d,
_init._euclidean_mesh_3d,
_hfun._constant_value_kd,
- _rdel._euclidean_rdel_3d,
+ _mesh._euclidean_rdel_3d,
_args, _jlog) ;
}
else
@@ -408,16 +408,16 @@
jmsh_kind::euclidean_mesh)
{
/*--------------- with euclidean-mesh HFUN kernel */
- _rdel._kind =
+ _mesh._kind =
jmsh_kind::euclidean_mesh;
- _rdel._ndim = +3 ;
+ _mesh._ndim = +3 ;
mesh_euclidean_3d (
_geom._euclidean_mesh_3d,
_init._euclidean_mesh_3d,
_hfun._euclidean_mesh_3d,
- _rdel._euclidean_rdel_3d,
+ _mesh._euclidean_rdel_3d,
_args, _jlog) ;
}
else
@@ -426,16 +426,16 @@
jmsh_kind::euclidean_grid)
{
/*--------------- with euclidean-grid HFUN kernel */
- _rdel._kind =
+ _mesh._kind =
jmsh_kind::euclidean_mesh;
- _rdel._ndim = +3 ;
+ _mesh._ndim = +3 ;
mesh_euclidean_3d (
_geom._euclidean_mesh_3d,
_init._euclidean_mesh_3d,
_hfun._euclidean_grid_3d,
- _rdel._euclidean_rdel_3d,
+ _mesh._euclidean_rdel_3d,
_args, _jlog) ;
}
@@ -449,16 +449,16 @@
if (_hfun._ndim == +0 )
{
/*--------------- with constant-value HFUN kernel */
- _rdel._kind =
+ _mesh._kind =
jmsh_kind::euclidean_mesh;
- _rdel._ndim = +3 ;
+ _mesh._ndim = +3 ;
mesh_euclidean_3d (
_geom._ellipsoid_mesh_3d,
_init._euclidean_mesh_3d,
_hfun._constant_value_kd,
- _rdel._euclidean_rdel_3d,
+ _mesh._euclidean_rdel_3d,
_args, _jlog) ;
}
else
@@ -466,16 +466,16 @@
jmsh_kind::ellipsoid_grid)
{
/*--------------- with ellipsoid-grid HFUN kernel */
- _rdel._kind =
+ _mesh._kind =
jmsh_kind::euclidean_mesh;
- _rdel._ndim = +3 ;
+ _mesh._ndim = +3 ;
mesh_euclidean_3d (
_geom._ellipsoid_mesh_3d,
_init._euclidean_mesh_3d,
_hfun._ellipsoid_grid_3d,
- _rdel._euclidean_rdel_3d,
+ _mesh._euclidean_rdel_3d,
_args, _jlog) ;
}
else
@@ -483,16 +483,16 @@
jmsh_kind::ellipsoid_mesh)
{
/*--------------- with ellipsoid-mesh HFUN kernel */
- _rdel._kind =
+ _mesh._kind =
jmsh_kind::euclidean_mesh;
- _rdel._ndim = +3 ;
+ _mesh._ndim = +3 ;
mesh_euclidean_3d (
_geom._ellipsoid_mesh_3d,
_init._euclidean_mesh_3d,
_hfun._ellipsoid_mesh_3d,
- _rdel._euclidean_rdel_3d,
+ _mesh._euclidean_rdel_3d,
_args, _jlog) ;
}
else
@@ -501,16 +501,16 @@
jmsh_kind::euclidean_mesh)
{
/*--------------- with euclidean-mesh HFUN kernel */
- _rdel._kind =
+ _mesh._kind =
jmsh_kind::euclidean_mesh;
- _rdel._ndim = +3 ;
+ _mesh._ndim = +3 ;
mesh_euclidean_3d (
_geom._ellipsoid_mesh_3d,
_init._euclidean_mesh_3d,
_hfun._euclidean_mesh_3d,
- _rdel._euclidean_rdel_3d,
+ _mesh._euclidean_rdel_3d,
_args, _jlog) ;
}
else
@@ -519,16 +519,16 @@
jmsh_kind::euclidean_grid)
{
/*--------------- with euclidean-grid HFUN kernel */
- _rdel._kind =
+ _mesh._kind =
jmsh_kind::euclidean_mesh;
- _rdel._ndim = +3 ;
+ _mesh._ndim = +3 ;
mesh_euclidean_3d (
_geom._ellipsoid_mesh_3d,
_init._euclidean_mesh_3d,
_hfun._euclidean_grid_3d,
- _rdel._euclidean_rdel_3d,
+ _mesh._euclidean_rdel_3d,
_args, _jlog) ;
}
@@ -568,8 +568,10 @@
/*-------------------------- call ODT-ITER kernel */
typedef mesh::
iter_pred_euclidean_2d <
- real_type ,
- iptr_type > pred_type ;
+ geom_type ,
+ typename
+ mesh_type::
+ mesh_type > pred_type ;
typedef mesh::iter_mesh_2 <
geom_type ,
@@ -585,12 +587,10 @@
iter_opts *_opts =
&_args._iter_opts ;
- pred_type _pred ;
iter_func::iter_mesh (
_geom, _hfun ,
_mesh. _mesh ,
iter_func::_odt_kern ,
- _pred,
*_opts, _jlog ) ;
}
else
@@ -600,8 +600,10 @@
/*-------------------------- call CVT-ITER kernel */
typedef mesh::
iter_pred_euclidean_2d <
- real_type ,
- iptr_type > pred_type ;
+ geom_type ,
+ typename
+ mesh_type::
+ mesh_type > pred_type ;
typedef mesh::iter_mesh_2 <
geom_type ,
@@ -617,12 +619,42 @@
iter_opts *_opts =
&_args._iter_opts ;
- pred_type _pred ;
iter_func::iter_mesh (
_geom, _hfun ,
_mesh. _mesh ,
iter_func::_cvt_kern ,
- _pred,
+ *_opts, _jlog ) ;
+ }
+ else
+ if (_args._iter_pred ==
+ jcfg_data::iter_pred::h95_dqdx)
+ {
+ /*-------------------------- call H95-ITER kernel */
+ typedef mesh::
+ iter_pred_euclidean_2d <
+ geom_type ,
+ typename
+ mesh_type::
+ mesh_type > pred_type ;
+
+ typedef mesh::iter_mesh_2 <
+ geom_type ,
+ typename
+ mesh_type::
+ mesh_type ,
+ hfun_type ,
+ pred_type > iter_func ;
+
+ typedef
+ jcfg_data::iter_opts iter_opts ;
+
+ iter_opts *_opts =
+ &_args._iter_opts ;
+
+ iter_func::iter_mesh (
+ _geom, _hfun ,
+ _mesh. _mesh ,
+ iter_func::_h95_kern ,
*_opts, _jlog ) ;
}
}
@@ -647,8 +679,10 @@
/*-------------------------- call ODT-ITER kernel */
typedef mesh::
iter_pred_ellipsoid_3d <
- real_type ,
- iptr_type > pred_type ;
+ geom_type ,
+ typename
+ mesh_type::
+ mesh_type > pred_type ;
typedef mesh::iter_mesh_2 <
geom_type ,
@@ -664,12 +698,10 @@
iter_opts *_opts =
&_args._iter_opts ;
- pred_type _pred ;
iter_func::iter_mesh (
_geom, _hfun ,
_mesh. _mesh ,
iter_func::_odt_kern ,
- _pred,
*_opts, _jlog ) ;
}
else
@@ -679,8 +711,10 @@
/*-------------------------- call CVT-ITER kernel */
typedef mesh::
iter_pred_ellipsoid_3d <
- real_type ,
- iptr_type > pred_type ;
+ geom_type ,
+ typename
+ mesh_type::
+ mesh_type > pred_type ;
typedef mesh::iter_mesh_2 <
geom_type ,
@@ -696,12 +730,42 @@
iter_opts *_opts =
&_args._iter_opts ;
- pred_type _pred ;
iter_func::iter_mesh (
_geom, _hfun ,
_mesh. _mesh ,
iter_func::_cvt_kern ,
- _pred,
+ *_opts, _jlog ) ;
+ }
+ else
+ if (_args._iter_pred ==
+ jcfg_data::iter_pred::h95_dqdx)
+ {
+ /*-------------------------- call H95-ITER kernel */
+ typedef mesh::
+ iter_pred_ellipsoid_3d <
+ geom_type ,
+ typename
+ mesh_type::
+ mesh_type > pred_type ;
+
+ typedef mesh::iter_mesh_2 <
+ geom_type ,
+ typename
+ mesh_type::
+ mesh_type ,
+ hfun_type ,
+ pred_type > iter_func ;
+
+ typedef
+ jcfg_data::iter_opts iter_opts ;
+
+ iter_opts *_opts =
+ &_args._iter_opts ;
+
+ iter_func::iter_mesh (
+ _geom, _hfun ,
+ _mesh. _mesh ,
+ iter_func::_h95_kern ,
*_opts, _jlog ) ;
}
}
@@ -738,7 +802,7 @@
template <
typename jlog_data
>
- __normal_call iptr_type iter_impl (
+ __normal_call iptr_type iter_core (
jcfg_data &_args,
jlog_data &_jlog,
geom_data &_geom,
@@ -990,7 +1054,6 @@
hfun_data _hfun ; // HFUN data
geom_data _geom ; // GEOM data
- rdel_data _rdel ; // TRIA data
mesh_data _mesh ; // MESH data
jcfg_data _jcfg ;
@@ -1007,6 +1070,9 @@
__unreferenced(_time) ;
# endif//__use_timers
+ /*--------------------------------- init. geo. kernel */
+ mp_float::exactinit() ;
+
/*--------------------------------- init. output data */
jigsaw_init_msh_t(_mmsh) ;
@@ -1155,7 +1221,7 @@
if (_imsh != nullptr )
{
- /*--------------------------------- assemble init-con */
+ /*--------------------------------- initialise i.c.'s */
_jlog.push ( __jloglndv "\n" ) ;
_jlog.push (
" Forming INIT data...\n\n" ) ;
@@ -1276,10 +1342,10 @@
# endif//__use_timers
if ((_retv =
- JIGSAW ::mesh_impl (
+ JIGSAW ::mesh_core (
_jcfg, _jlog ,
_geom, _mesh ,
- _hfun, _rdel)) != __no_error)
+ _hfun, _mesh)) != __no_error)
{
return _retv ;
}
@@ -1294,29 +1360,49 @@
if (_gmsh != nullptr )
{
/*--------------------------------- call copy routine */
- if(_jcfg._mesh_opts.iter() != +0 &&
- _jcfg._iter_opts.iter() != +0 )
- {
_jlog.push ( __jloglndv "\n" ) ;
_jlog.push (
- " Pushing MESH data...\n\n" ) ;
+ " Forming MESH data...\n\n" ) ;
# ifdef __use_timers
_ttic = _time.now();
# endif//__use_timers
+ if(_jcfg._mesh_opts.iter() != +0 &&
+ _jcfg._iter_opts.iter() != +0 )
+ {
+
if ((_retv = copy_mesh (
+ _jcfg,
+ _jlog, _mesh)) != __no_error)
+ {
+ return _retv ;
+ }
+
+ if ((_retv = init_mesh (
_jcfg, _jlog ,
- _rdel, _mesh)) != __no_error)
+ _geom, _mesh)) != __no_error)
{
return _retv ;
}
+ }
+ else
+ {
+
+ if ((_retv = init_mesh (
+ _jcfg, _jlog ,
+ _geom, _mesh)) != __no_error)
+ {
+ return _retv ;
+ }
+
+ }
+
# ifdef __use_timers
_ttoc = _time.now();
_jlog.push(dump_time(_ttic, _ttoc));
# endif//__use_timers
- }
}
if (_gmsh != nullptr )
@@ -1332,15 +1418,8 @@
_ttic = _time.now();
# endif//__use_timers
- if ((_retv = init_mesh (
- _jcfg,
- _jlog, _mesh)) != __no_error)
- {
- return _retv ;
- }
-
if ((_retv =
- JIGSAW ::iter_impl (
+ JIGSAW ::iter_core (
_jcfg, _jlog ,
_geom,
_hfun, _mesh)) != __no_error)
@@ -1372,7 +1451,7 @@
if ((_retv = save_rdel (
_jcfg, _jlog ,
- _rdel,*_mmsh)) != __no_error)
+ _mesh,*_mmsh)) != __no_error)
{
return _retv ;
}
@@ -1412,7 +1491,6 @@
{
hfun_data _hfun ; // HFUN data
geom_data _geom ; // GEOM data
- rdel_data _rdel ; // TRIA data
mesh_data _mesh ; // MESH data
# ifdef __use_timers
@@ -1428,6 +1506,9 @@
__unreferenced(_time) ;
# endif//__use_timers
+ /*--------------------------------- init. geo. kernel */
+ mp_float::exactinit() ;
+
/*-------------------------- find *.JFCG file in args */
iptr_type _retv = -1 ;
jcfg_data _jcfg ;
@@ -1462,9 +1543,7 @@
break ;
}
- std::string _path ;
- std::string _name ;
- std::string _fext ;
+ std::string _path , _name , _fext ;
file_part ( _ssrc ,
_path , _name , _fext ) ;
@@ -1622,7 +1701,7 @@
if(!_jcfg._init_file.empty())
{
- /*--------------------------------- assemble init-con */
+ /*--------------------------------- initialise i.c.'s */
_jlog.push ( __jloglndv "\n" ) ;
_jlog.push (
" Forming INIT data...\n\n" ) ;
@@ -1743,10 +1822,10 @@
# endif//__use_timers
if ((_retv =
- JIGSAW ::mesh_impl (
+ JIGSAW ::mesh_core (
_jcfg, _jlog ,
_geom, _mesh ,
- _hfun, _rdel)) != __no_error)
+ _hfun, _mesh)) != __no_error)
{
return _retv ;
}
@@ -1772,7 +1851,7 @@
if ((_retv = save_tria (
_jcfg,
- _jlog, _rdel)) != __no_error)
+ _jlog, _mesh)) != __no_error)
{
return _retv ;
}
@@ -1785,30 +1864,50 @@
if(!_jcfg._geom_file.empty())
{
- if(_jcfg._mesh_opts.iter() != +0 &&
- _jcfg._iter_opts.iter() != +0 )
- {
/*--------------------------------- call copy routine */
_jlog.push ( __jloglndv "\n" ) ;
_jlog.push (
- " Pushing MESH data...\n\n" ) ;
+ " Forming MESH data...\n\n" ) ;
# ifdef __use_timers
_ttic = _time.now();
# endif//__use_timers
+ if(_jcfg._mesh_opts.iter() != +0 &&
+ _jcfg._iter_opts.iter() != +0 )
+ {
+
if ((_retv = copy_mesh (
+ _jcfg,
+ _jlog, _mesh)) != __no_error)
+ {
+ return _retv ;
+ }
+
+ if ((_retv = init_mesh (
_jcfg, _jlog ,
- _rdel, _mesh)) != __no_error)
+ _geom, _mesh)) != __no_error)
{
return _retv ;
}
+ }
+ else
+ {
+
+ if ((_retv = init_mesh (
+ _jcfg, _jlog ,
+ _geom, _mesh)) != __no_error)
+ {
+ return _retv ;
+ }
+
+ }
+
# ifdef __use_timers
_ttoc = _time.now();
_jlog.push(dump_time(_ttic, _ttoc));
# endif//__use_timers
- }
}
if(!_jcfg._geom_file.empty())
@@ -1824,15 +1923,8 @@
_ttic = _time.now();
# endif//__use_timers
- if ((_retv = init_mesh (
- _jcfg,
- _jlog, _mesh)) != __no_error)
- {
- return _retv ;
- }
-
if ((_retv =
- JIGSAW ::iter_impl (
+ JIGSAW ::iter_core (
_jcfg, _jlog ,
_geom,
_hfun, _mesh)) != __no_error)
@@ -1865,7 +1957,7 @@
if ((_retv = save_rdel (
_jcfg,
- _jlog, _rdel)) != __no_error)
+ _jlog, _mesh)) != __no_error)
{
return _retv ;
}
diff --git a/external/jigsaw/src/libcpp/aabb_tree/aabb_mesh_k.hpp b/external/jigsaw/src/libcpp/aabb_tree/aabb_mesh_k.hpp
index c1f7d5d..08b1f1d 100644
--- a/external/jigsaw/src/libcpp/aabb_tree/aabb_mesh_k.hpp
+++ b/external/jigsaw/src/libcpp/aabb_tree/aabb_mesh_k.hpp
@@ -35,7 +35,7 @@
*
* Copyright 2013-2017
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
------------------------------------------------------------
diff --git a/external/jigsaw/src/libcpp/aabb_tree/aabb_pred_k.hpp b/external/jigsaw/src/libcpp/aabb_tree/aabb_pred_k.hpp
index 56e57a0..729795c 100644
--- a/external/jigsaw/src/libcpp/aabb_tree/aabb_pred_k.hpp
+++ b/external/jigsaw/src/libcpp/aabb_tree/aabb_pred_k.hpp
@@ -35,7 +35,7 @@
*
* Copyright 2013-2019
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
------------------------------------------------------------
diff --git a/external/jigsaw/src/libcpp/aabb_tree/aabb_tree_k.hpp b/external/jigsaw/src/libcpp/aabb_tree/aabb_tree_k.hpp
index 3a393ee..62db444 100644
--- a/external/jigsaw/src/libcpp/aabb_tree/aabb_tree_k.hpp
+++ b/external/jigsaw/src/libcpp/aabb_tree/aabb_tree_k.hpp
@@ -31,11 +31,11 @@
*
------------------------------------------------------------
*
- * Last updated: 10 July, 2019
+ * Last updated: 02 April, 2020
*
- * Copyright 2013-2019
+ * Copyright 2013-2020
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
------------------------------------------------------------
@@ -68,7 +68,7 @@
typedef typename
item_type::iptr_type iptr_type ;
- iptr_type static constexpr _dims = K * +1 ;
+ iptr_type static constexpr _dims = K ;
typedef geom_tree::aabb_tree <
item_type ,
@@ -509,19 +509,19 @@
}
/*---------- split pos. - mean of non-long aabb's */
- real_type _spos = (real_type)+0.;
-
+ double _SPOS = +0. ;
for(item_data *_iptr = _cptr ;
_iptr != nullptr ;
_iptr = _next )
{
_next = _iptr->_next ;
- _spos +=_iptr->
+ _SPOS +=_iptr->
_data.pmid (_bdim);
}
- _spos = _spos / _cnum ;
+ real_type _spos =
+ (real_type)(_SPOS / _cnum);
/*---------- partition list - split on left|right */
for(item_data *_iptr = _cptr ;
@@ -567,11 +567,11 @@
/*------------------ push new children onto stack */
if (_cnum < this->_imax)
{
- real_type _volp, _voll, _volr ;
+ double _volp, _voll, _volr ;
- _volp = (real_type) +1. ;
- _voll = (real_type) +1. ;
- _volr = (real_type) +1. ;
+ _volp = +1. ;
+ _voll = +1. ;
+ _volr = +1. ;
for (auto _idim = _dims; _idim-- != +0; )
{
@@ -655,19 +655,19 @@
if (_hash % 2 == +0 )
{
- this->_work.push_tail (
- _node->lower( 0)) ;
+ this->_work.push_tail (
+ _node->lower( 0)) ;
- this->_work.push_tail (
- _node->lower( 1)) ;
+ this->_work.push_tail (
+ _node->lower( 1)) ;
}
else
{
- this->_work.push_tail (
- _node->lower( 1)) ;
+ this->_work.push_tail (
+ _node->lower( 1)) ;
- this->_work.push_tail (
- _node->lower( 0)) ;
+ this->_work.push_tail (
+ _node->lower( 0)) ;
}
}
}
@@ -774,15 +774,15 @@
_node->lower(0)->_pmin ,
_node->lower(0)->_pmax )
)
- this->_work.push_tail (
- _node->lower(0)) ;
+ this->_work.push_tail (
+ _node->lower(0)) ;
if (_pred(
_node->lower(1)->_pmin ,
_node->lower(1)->_pmax )
)
- this->_work.push_tail (
- _node->lower(1)) ;
+ this->_work.push_tail (
+ _node->lower(1)) ;
}
}
@@ -820,14 +820,7 @@
}
} ;
- bool_type _find = false;
-
- if (this->_root
- == nullptr) return _find;
-
- real_type _dsqr =
- +std::numeric_limits
- ::infinity() ;
+ if (this->_root == nullptr) return false ;
/*----------------- maintain stack of unvisited nodes */
containers::priorityset<
@@ -845,6 +838,12 @@
_nnpq.push (_ndat);
/*----------------- traverse tree while len. reducing */
+ bool_type _find = false ;
+
+ real_type _dsqr =
+ +std::numeric_limits
+ ::infinity() ;
+
for ( ; !_nnpq.empty() ; )
{
/*------------------------ test next closest node */
diff --git a/external/jigsaw/src/libcpp/aabb_tree/aabb_type_k.hpp b/external/jigsaw/src/libcpp/aabb_tree/aabb_type_k.hpp
index 0c857d1..dd8cd43 100644
--- a/external/jigsaw/src/libcpp/aabb_tree/aabb_type_k.hpp
+++ b/external/jigsaw/src/libcpp/aabb_tree/aabb_type_k.hpp
@@ -35,7 +35,7 @@
*
* Copyright 2013-2017
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
------------------------------------------------------------
diff --git a/external/jigsaw/src/libcpp/aabbtree.hpp b/external/jigsaw/src/libcpp/aabbtree.hpp
index deac021..52deac5 100644
--- a/external/jigsaw/src/libcpp/aabbtree.hpp
+++ b/external/jigsaw/src/libcpp/aabbtree.hpp
@@ -35,7 +35,7 @@
*
* Copyright 2013-2018
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
------------------------------------------------------------
diff --git a/external/jigsaw/src/libcpp/algorithms.hpp b/external/jigsaw/src/libcpp/algorithms.hpp
index def461d..330e328 100644
--- a/external/jigsaw/src/libcpp/algorithms.hpp
+++ b/external/jigsaw/src/libcpp/algorithms.hpp
@@ -35,7 +35,7 @@
*
* Copyright 2013-2017
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
------------------------------------------------------------
@@ -46,7 +46,7 @@
# ifndef __ALGORITHMS__
# define __ALGORITHMS__
-# include "libbasic.hpp"
+# include "basebase.hpp"
# include "algorithms/sort.hpp"
# include "algorithms/find.hpp"
diff --git a/external/jigsaw/src/libcpp/algorithms/find.hpp b/external/jigsaw/src/libcpp/algorithms/find.hpp
index 7686978..3564454 100644
--- a/external/jigsaw/src/libcpp/algorithms/find.hpp
+++ b/external/jigsaw/src/libcpp/algorithms/find.hpp
@@ -35,7 +35,7 @@
*
* Copyright 2013-2017
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
--------------------------------------------------------
diff --git a/external/jigsaw/src/libcpp/algorithms/sort.hpp b/external/jigsaw/src/libcpp/algorithms/sort.hpp
index f59d4c9..f161c7e 100644
--- a/external/jigsaw/src/libcpp/algorithms/sort.hpp
+++ b/external/jigsaw/src/libcpp/algorithms/sort.hpp
@@ -35,7 +35,7 @@
*
* Copyright 2013-2019
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
--------------------------------------------------------
diff --git a/external/jigsaw/src/libcpp/allocators.hpp b/external/jigsaw/src/libcpp/allocators.hpp
index 55a5298..7f7e57a 100644
--- a/external/jigsaw/src/libcpp/allocators.hpp
+++ b/external/jigsaw/src/libcpp/allocators.hpp
@@ -35,7 +35,7 @@
*
* Copyright 2013-2017
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
------------------------------------------------------------
@@ -46,7 +46,7 @@
# ifndef __ALLOCATORS__
# define __ALLOCATORS__
-# include "libbasic.hpp"
+# include "basebase.hpp"
# include "allocators/alloc_base.hpp"
# include "allocators/alloc_pool.hpp"
diff --git a/external/jigsaw/src/libcpp/allocators/alloc_base.hpp b/external/jigsaw/src/libcpp/allocators/alloc_base.hpp
index 52eb264..75f3d5c 100644
--- a/external/jigsaw/src/libcpp/allocators/alloc_base.hpp
+++ b/external/jigsaw/src/libcpp/allocators/alloc_base.hpp
@@ -42,7 +42,7 @@
*
* Copyright 2013-2017
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
--------------------------------------------------------
diff --git a/external/jigsaw/src/libcpp/allocators/alloc_item.hpp b/external/jigsaw/src/libcpp/allocators/alloc_item.hpp
index 1ff2744..b9c1727 100644
--- a/external/jigsaw/src/libcpp/allocators/alloc_item.hpp
+++ b/external/jigsaw/src/libcpp/allocators/alloc_item.hpp
@@ -42,7 +42,7 @@
*
* Copyright 2013-2018
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
--------------------------------------------------------
diff --git a/external/jigsaw/src/libcpp/allocators/alloc_pool.hpp b/external/jigsaw/src/libcpp/allocators/alloc_pool.hpp
index 7708ffd..68c839d 100644
--- a/external/jigsaw/src/libcpp/allocators/alloc_pool.hpp
+++ b/external/jigsaw/src/libcpp/allocators/alloc_pool.hpp
@@ -45,7 +45,7 @@
*
* Copyright 2013-2017
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
--------------------------------------------------------
diff --git a/external/jigsaw/src/libcpp/allocators/alloc_wrap.hpp b/external/jigsaw/src/libcpp/allocators/alloc_wrap.hpp
index 4aede0f..5eb8404 100644
--- a/external/jigsaw/src/libcpp/allocators/alloc_wrap.hpp
+++ b/external/jigsaw/src/libcpp/allocators/alloc_wrap.hpp
@@ -43,7 +43,7 @@
*
* Copyright 2013-2017
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
--------------------------------------------------------
diff --git a/external/jigsaw/src/libcpp/libbasic.hpp b/external/jigsaw/src/libcpp/basebase.hpp
similarity index 78%
rename from external/jigsaw/src/libcpp/libbasic.hpp
rename to external/jigsaw/src/libcpp/basebase.hpp
index 84769ef..d62e11b 100644
--- a/external/jigsaw/src/libcpp/libbasic.hpp
+++ b/external/jigsaw/src/libcpp/basebase.hpp
@@ -31,11 +31,11 @@
*
------------------------------------------------------------
*
- * Last updated: 20 February, 2019
+ * Last updated: 02 March, 2020
*
- * Copyright 2013-2019
+ * Copyright 2013-2020
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
------------------------------------------------------------
@@ -43,11 +43,12 @@
# pragma once
-# ifndef __LIBBASIC__
-# define __LIBBASIC__
+# ifndef __BASEBASE__
+# define __BASEBASE__
# include
# include
+# include
/*
------------------------------------------------------------
@@ -65,44 +66,17 @@
# endif
-/*
-------------------------------------------------------------
- * global data type alias
-------------------------------------------------------------
- */
-
- typedef void void_type ;
- typedef bool bool_type ;
- typedef char char_type ;
+# define __assert assert
/*
------------------------------------------------------------
- * breakpoint-able assert!
+ * global data type alias
------------------------------------------------------------
*/
-# ifdef NDEBUG
-# define __assert(__expr) ((void) 0)
-# else
- std::size_t volatile __assert_holder;
- inline void __assert_breakp(
- )
- /*------------------------------ put breakpoint here! */
- { __assert_holder = +0;
- }
-
-# include
-
-# define __assert(__expr) \
- do { \
- if(!(__expr)) \
- { \
- /*------------------------------ stop for breakpoint! */ \
- __assert_breakp (); \
- assert((__expr)); \
- } \
- } while ( false ) ;
-# endif
+ typedef void void_type ;
+ typedef bool bool_type ;
+ typedef char char_type ;
/*
------------------------------------------------------------
@@ -173,7 +147,7 @@
# define __chkbit(x,b) (!!((x)&(1ULL<<(b))) )
-# endif //__LIBBASIC__
+# endif//__BASEBASE__
diff --git a/external/jigsaw/src/libcpp/containers.hpp b/external/jigsaw/src/libcpp/containers.hpp
index d14b627..31e6b6f 100644
--- a/external/jigsaw/src/libcpp/containers.hpp
+++ b/external/jigsaw/src/libcpp/containers.hpp
@@ -35,7 +35,7 @@
*
* Copyright 2013-2018
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
------------------------------------------------------------
@@ -68,6 +68,7 @@
# include "containers/arraylist.hpp"
# include "containers/hashtable.hpp"
+# include "containers/hashtwice.hpp"
# include "containers/priorityset.hpp"
# include "containers/prioritymap.hpp"
diff --git a/external/jigsaw/src/libcpp/containers/array.hpp b/external/jigsaw/src/libcpp/containers/array.hpp
index 6ea55a1..5b89fe7 100644
--- a/external/jigsaw/src/libcpp/containers/array.hpp
+++ b/external/jigsaw/src/libcpp/containers/array.hpp
@@ -41,11 +41,11 @@
*
------------------------------------------------------------
*
- * Last updated: 21 August, 2018
+ * Last updated: 27 April, 2020
*
- * Copyright 2013-2018
+ * Copyright 2013-2020
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
------------------------------------------------------------
@@ -117,11 +117,11 @@
}
__normal_call void_type ctor_iter (
_write_it _head,
- _write_it _tail,
+ _write_it _tend,
data_type const& _data
)
{ /* copy construct sequence */
- for ( ; _head != _tail ; ++_head)
+ for ( ; _head != _tend ; ++_head)
{
self_type::construct(&*_head,
_data) ;
@@ -132,10 +132,10 @@
__normal_call void_type dtor_iter (
_write_it _head,
- _write_it _tail
+ _write_it _tend
)
{
- for ( ; _head != _tail ; ++_head)
+ for ( ; _head != _tend ; ++_head)
{
self_type::_destruct(&*_head) ;
}
@@ -201,11 +201,11 @@
>
__normal_call void_type copy_iter (
iter_type _head,
- iter_type _tail,
+ iter_type _tend,
__cont::base_iterator_kind
)
{ /* copy range onto object */
- for(;_head!=_tail;++_head) push_tail(*_head) ;
+ for(;_head!=_tend;++_head) push_tail(*_head) ;
}
public :
@@ -241,7 +241,7 @@
>
__inline_call array (
iter_type _head,
- iter_type _tail,
+ iter_type _tend,
allocator const&_asrc = allocator()
) : obj_alloc( _asrc )
{
@@ -249,7 +249,7 @@
this->_ptrs[_tptr] = nullptr;
this->_ptrs[_lptr] = nullptr;
- copy_iter(_head,_tail,
+ copy_iter(_head,_tend,
__cont::iter_kind(_head)) ;
}
@@ -272,10 +272,10 @@
/*------------------------------------- alloc storage */
set_alloc(_src.count());
/*------------------------------------- copy sequence */
- _const_it _head, _tail ;
+ _const_it _head, _tend ;
_head = _src.head();
- _tail = _src.tend();
- copy_iter(_head,_tail,
+ _tend = _src.tend();
+ copy_iter(_head,_tend,
__cont::iter_kind(_head)) ;
}
@@ -348,6 +348,17 @@
return ( *this ) ;
}
+/*-------------------------------------- fill const. data */
+ __inline_call void_type fill (
+ data_type const& _data
+ )
+ {
+ for (auto _iter = this->head();
+ _iter!= this->tend();
+ ++_iter )
+ *_iter = __copy(data_type, _data) ;
+ }
+
/*-------------------------------------- push array alloc */
__normal_call void_type set_alloc (
size_type _new_alloc
@@ -761,6 +772,14 @@
_destruct(--this->_ptrs[_tptr] ) ;
}
+/*------------------------------------ is index in bounds */
+ __inline_call bool_type bounds (
+ size_type _pos
+ ) const
+ {
+ return _pos >= +0 && _pos < count() ;
+ }
+
/*------------------------------------ operator[] (write) */
__inline_call data_type &operator[] (
size_type _pos
diff --git a/external/jigsaw/src/libcpp/containers/array_iter.hpp b/external/jigsaw/src/libcpp/containers/array_iter.hpp
index f899577..cf0cb97 100644
--- a/external/jigsaw/src/libcpp/containers/array_iter.hpp
+++ b/external/jigsaw/src/libcpp/containers/array_iter.hpp
@@ -45,7 +45,7 @@
*
* Copyright 2013-2017
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
------------------------------------------------------------
diff --git a/external/jigsaw/src/libcpp/containers/arraylist.hpp b/external/jigsaw/src/libcpp/containers/arraylist.hpp
index 6e26d0b..5bf8f9d 100644
--- a/external/jigsaw/src/libcpp/containers/arraylist.hpp
+++ b/external/jigsaw/src/libcpp/containers/arraylist.hpp
@@ -41,7 +41,7 @@
*
* Copyright 2013-2018
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
------------------------------------------------------------
@@ -53,6 +53,7 @@
# define __ARRAY_LIST__
# include "single_list.hpp"
+# include "array.hpp"
# include "block_array.hpp"
namespace containers {
diff --git a/external/jigsaw/src/libcpp/containers/basic_stack.hpp b/external/jigsaw/src/libcpp/containers/basic_stack.hpp
index 64ece32..2153dfa 100644
--- a/external/jigsaw/src/libcpp/containers/basic_stack.hpp
+++ b/external/jigsaw/src/libcpp/containers/basic_stack.hpp
@@ -43,7 +43,7 @@
*
* Copyright 2013-2018
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
------------------------------------------------------------
diff --git a/external/jigsaw/src/libcpp/containers/block_array.hpp b/external/jigsaw/src/libcpp/containers/block_array.hpp
index d97e0bf..35f853e 100644
--- a/external/jigsaw/src/libcpp/containers/block_array.hpp
+++ b/external/jigsaw/src/libcpp/containers/block_array.hpp
@@ -43,11 +43,11 @@
*
------------------------------------------------------------
*
- * Last updated: 03 July, 2019
+ * Last updated: 27 April, 2020
*
- * Copyright 2013-2019
+ * Copyright 2013-2020
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
------------------------------------------------------------
@@ -260,6 +260,17 @@
return ( *this ) ;
}
+/*-------------------------------------- fill const. data */
+ __inline_call void_type fill (
+ data_type const& _data
+ )
+ {
+ for (auto _iter = this->head();
+ _iter!= this->tend();
+ ++_iter )
+ *_iter = __copy(data_type, _data) ;
+ }
+
/*
--------------------------------------------------------
* SET-ALLOC: push new array alloc.
@@ -803,6 +814,13 @@
--------------------------------------------------------
*/
+ __inline_call bool_type bounds ( // index in bnds
+ size_type _pos
+ ) const
+ {
+ return _pos >= +0 && _pos < count() ;
+ }
+
__inline_call data_type &operator[] ( // write
size_type _pos
)
diff --git a/external/jigsaw/src/libcpp/containers/block_iter.hpp b/external/jigsaw/src/libcpp/containers/block_iter.hpp
index 216c845..d658e4a 100644
--- a/external/jigsaw/src/libcpp/containers/block_iter.hpp
+++ b/external/jigsaw/src/libcpp/containers/block_iter.hpp
@@ -47,7 +47,7 @@
*
* Copyright 2013-2019
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
------------------------------------------------------------
diff --git a/external/jigsaw/src/libcpp/containers/double_list.hpp b/external/jigsaw/src/libcpp/containers/double_list.hpp
index 8114fa9..56bf71f 100644
--- a/external/jigsaw/src/libcpp/containers/double_list.hpp
+++ b/external/jigsaw/src/libcpp/containers/double_list.hpp
@@ -43,7 +43,7 @@
*
* Copyright 2013-2017
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
------------------------------------------------------------
diff --git a/external/jigsaw/src/libcpp/containers/doubleiter.hpp b/external/jigsaw/src/libcpp/containers/doubleiter.hpp
index 1aebc32..7e3e5c8 100644
--- a/external/jigsaw/src/libcpp/containers/doubleiter.hpp
+++ b/external/jigsaw/src/libcpp/containers/doubleiter.hpp
@@ -43,7 +43,7 @@
*
* Copyright 2013-2017
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
------------------------------------------------------------
diff --git a/external/jigsaw/src/libcpp/containers/fixed_array.hpp b/external/jigsaw/src/libcpp/containers/fixed_array.hpp
index 2aac51d..9240f71 100644
--- a/external/jigsaw/src/libcpp/containers/fixed_array.hpp
+++ b/external/jigsaw/src/libcpp/containers/fixed_array.hpp
@@ -41,7 +41,7 @@
*
* Copyright 2013-2017
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
------------------------------------------------------------
@@ -97,35 +97,38 @@
for (auto _item = head() ;
_SIZE != +0 ;
--_SIZE, ++_item )
- {
- *_item = _dsrc ;
- }
+ *_item = __copy(data_type, _dsrc) ;
}
-/*-------------------------------- helper - copy sequence */
template <
typename iter_type
>
- __normal_call void_type copy_iter (
+ __normal_call void_type copy_data (
iter_type _head,
- iter_type _tail,
- __cont::base_iterator_kind
+ iter_type _tend
)
{
for (auto _item = head() ;
- _head != _tail;
+ _head != _tend;
++_item, ++_head )
- {
- *_item = *_head ;
- }
+ *_item = __copy(data_type,*_head) ;
}
+
+/*-------------------------------- helper - copy sequence */
+ template <
+ typename iter_type
+ >
+ __normal_call void_type copy_iter (
+ iter_type _head,
+ iter_type _tend,
+ __cont::base_iterator_kind
+ ) { copy_data(_head, _tend) ; }
+
__inline_call void_type copy_iter (
size_type _SIZE,
data_type const& _dsrc ,
__cont::null_iterator_kind
- )
- { copy_data(_SIZE, _dsrc);
- }
+ ) { copy_data(_SIZE, _dsrc) ; }
public :
@@ -143,7 +146,7 @@
/*--------------------------- default c'tor - initialisor */
template <
- typename iter_type
+ typename iter_type
>
__inline_call fixed_array (
iter_type _head,
@@ -151,7 +154,7 @@
)
{
copy_iter(_head,_tail ,
- __cont::iter_kind(_head)) ;
+ __cont::iter_kind(_head)) ;
}
/*--------------------------- default d'tor/copy/move ops */
diff --git a/external/jigsaw/src/libcpp/containers/hashtable.hpp b/external/jigsaw/src/libcpp/containers/hashtable.hpp
index 37792f4..77af72b 100644
--- a/external/jigsaw/src/libcpp/containers/hashtable.hpp
+++ b/external/jigsaw/src/libcpp/containers/hashtable.hpp
@@ -37,11 +37,11 @@
*
------------------------------------------------------------
*
- * Last updated: 05 July, 2019
+ * Last updated: 28 April, 2020
*
- * Copyright 2013-2019
+ * Copyright 2013-2020
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
------------------------------------------------------------
@@ -519,6 +519,8 @@
__normal_call void_type _get_info (
size_type &_min_count,
size_type &_max_count,
+ double &_nil_ratio,
+ double &_bad_ratio,
double &_ave_count
)
{
@@ -527,6 +529,11 @@
_max_count =
std::numeric_limits::min();
+ size_type _bad_limit =
+ (size_type) (+3 * this->_load);
+
+ _nil_ratio = (double)+.0;
+ _bad_ratio = (double)+.0;
_ave_count = (double)+.0;
/*-------------------------- iter. all lists in table */
typename lptr_list::_write_it
@@ -548,9 +555,17 @@
if (_max_count < _lsiz)
_max_count = _lsiz;
+ if (_lsiz == (size_type) +0)
+ _nil_ratio += +1. ;
+
+ if (_bad_limit < _lsiz)
+ _bad_ratio += +1. ;
+
_ave_count += (double)_lsiz;
}
+ _nil_ratio /= this->_lptr.count() ;
+ _bad_ratio /= this->_lptr.count() ;
_ave_count /= this->_lptr.count() ;
}
diff --git a/external/jigsaw/src/libcpp/containers/hashtwice.hpp b/external/jigsaw/src/libcpp/containers/hashtwice.hpp
new file mode 100644
index 0000000..d82d64d
--- /dev/null
+++ b/external/jigsaw/src/libcpp/containers/hashtwice.hpp
@@ -0,0 +1,773 @@
+
+/*
+------------------------------------------------------------
+ * a "2-choice" chained hash-table.
+------------------------------------------------------------
+ *
+ * HASH-TABLE is a dynamically-sized, chained hashtable
+ * implementation, essentially a linear array of singly-
+ * linked hash buckets. Here, the so-called "2-choice"
+ * variant is implemented, in which each operation uses
+ * a pair of hash functions. Obj. are inserted into the
+ * slot with the lower collision count.
+ *
+------------------------------------------------------------
+ *
+ * This program may be freely redistributed under the
+ * condition that the copyright notices (including this
+ * entire header) are not removed, and no compensation
+ * is received through use of the software. Private,
+ * research, and institutional use is free. You may
+ * distribute modified versions of this code UNDER THE
+ * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE
+ * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE
+ * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE
+ * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR
+ * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution
+ * of this code as part of a commercial system is
+ * permissible ONLY BY DIRECT ARRANGEMENT WITH THE
+ * AUTHOR. (If you are not directly supplying this
+ * code to a customer, and you are instead telling them
+ * how they can obtain it for free, then you are not
+ * required to make any arrangement with me.)
+ *
+ * Disclaimer: Neither I nor: Columbia University, The
+ * Massachusetts Institute of Technology, The
+ * University of Sydney, nor The National Aeronautics
+ * and Space Administration warrant this code in any
+ * way whatsoever. This code is provided "as-is" to be
+ * used at your own risk.
+ *
+------------------------------------------------------------
+ *
+ * Last updated: 28 April, 2020
+ *
+ * Copyright 2013-2020
+ * Darren Engwirda
+ * d.engwirda@gmail.com
+ * https://github.com/dengwirda/
+ *
+------------------------------------------------------------
+ */
+
+# pragma once
+
+# ifndef __HASH_TWICE__
+# define __HASH_TWICE__
+
+# include "arraylist.hpp"
+
+ namespace containers {
+
+# define __cont containers
+
+ template <
+ typename D ,
+ typename H ,
+ typename P ,
+ typename A = allocators::basic_alloc
+ >
+ class hash_twice :
+ public containers::array_list
+ {
+/*------------------------- a dynamic, chained hash-table */
+ public :
+
+ typedef D data_type ;
+ typedef H hash_type ;
+ typedef P pred_type ;
+ typedef A allocator ;
+
+ typedef containers::array_list <
+ data_type ,
+ allocator > base_type ;
+
+ typedef typename
+ base_type::size_type size_type ;
+ typedef typename
+ base_type::diff_type diff_type ;
+ typedef typename
+ base_type::item_type item_type ;
+ typedef typename
+ base_type::lptr_list lptr_list ;
+
+ typedef typename
+ base_type::_write_it _write_it ;
+ typedef typename
+ base_type::_const_it _const_it ;
+
+ typedef containers::array <
+ size_type ,
+ allocator > size_list ;
+
+ typedef containers::hash_twice <
+ data_type ,
+ hash_type ,
+ pred_type ,
+ allocator > self_type ;
+
+ size_type static constexpr _mini_count = +8 ;
+
+ public :
+
+ hash_type const _hfun;
+ pred_type const _pred;
+
+ size_list _lsiz;
+
+ double _load;
+
+ public :
+
+/*------------------------ update table count and re-hash */
+ __inline_call size_type hash_mask (
+ ) const
+ { return this->_lptr.count() - 1 ;
+ }
+
+ __static_call
+ __inline_call bool_type is_pwr2 (
+ size_type _xval
+ )
+ { return (_xval & (_xval-1)) == 0 ;
+ }
+
+ __static_call
+ __inline_call size_type next_pwr2 (
+ size_type _xval
+ )
+ {
+ if (_xval<= 1) return 1 ;
+ int _pwr2 = 2;
+ _xval--;
+ while (_xval >>= 1) _pwr2 <<= 1 ;
+ return _pwr2 ;
+ }
+
+ __static_call
+ __inline_call size_type prev_pwr2 (
+ size_type _xval
+ )
+ {
+ int _pwr2 = 1;
+ while (_xval >>= 1) _pwr2 <<= 1 ;
+ return _pwr2 ;
+ }
+
+ __normal_call void_type set_slots (
+ size_type _slots,
+ __cont::alloc_types _alloc =
+ __cont::loose_alloc
+ )
+ {
+ /*------------------------------- round to next 2^pwr */
+ _slots = next_pwr2 (_slots);
+
+ /*------------------------------- inc/dec. table size */
+ if (_slots <
+ this->_mini_count )
+ this->_lptr.set_count (
+ this->_mini_count ,
+ _alloc , nullptr) ;
+ else
+ this->_lptr.set_count (
+ _slots, _alloc , nullptr) ;
+
+ /*------------------------------- re-hash all objects */
+ redo_hash() ;
+ }
+
+ __normal_call void_type grow_hash (
+ )
+ {
+ /*------------------------------- increase table size */
+ if (this->_lptr.count() <
+ this->_mini_count )
+ this->_lptr.set_count (
+ this->_mini_count ,
+ containers::tight_alloc, nullptr) ;
+ else
+ this->_lptr.set_count (
+ this->_lptr.count()*+2,
+ containers::tight_alloc, nullptr) ;
+
+ /*------------------------------- re-hash all objects */
+ redo_hash() ;
+ }
+
+ __normal_call void_type redo_hash (
+ )
+ {
+ this->_lsiz.set_count(
+ this->_lptr.count(), containers::tight_alloc, 0);
+
+ typename size_list::_write_it
+ _ITER = this->_lsiz.head(),
+ _TEND = this->_lsiz.tend();
+ for( ; _ITER != _TEND; ++_ITER)
+ {
+ *_ITER = (size_type)+0;
+ }
+
+ if (this->_size == +0) return ;
+
+ __assert (
+ is_pwr2(this->_lptr.count() ) &&
+ "hashtable: count must be 2^n!" ) ;
+
+ item_type*_head = nullptr ;
+ item_type*_tail = nullptr ;
+ item_type*_next = nullptr ;
+ /*--------------- splice together a list of all items */
+ typename lptr_list::_write_it
+ _iter = this->_lptr.head(),
+ _tend = this->_lptr.tend();
+ for( ; _iter != _tend; ++_iter)
+ {
+ /*--------------------- find first non-empty list */
+ if (*_iter != nullptr)
+ {
+ _head = *_iter;
+ _tail = *_iter;
+ *_iter = nullptr;
+ _iter++; break;
+ }
+ }
+ for( ; _iter != _tend; ++_iter)
+ {
+ /*--------------- splice remaining lists together */
+ if (*_iter != nullptr)
+ {
+ _tail = *_iter;
+ for(; nullptr != _tail->_next; )
+ {
+ _tail=_tail->_next ;
+ }
+ /*------ re-attach at _tail and jump to _head */
+ _tail->
+ _next = _head;
+ _head = *_iter;
+ *_iter = nullptr ;
+ }
+ }
+ /*------------------ re-hash all items onto new table */
+ for ( ; _head != nullptr; _head = _next)
+ {
+ _next = _head->_next;
+ /*--------------------------- calc new hash value */
+ uint32_t _hash[2] ;
+ this->_hfun(
+ _head->_data, _hash[0], _hash[1]) ;
+
+ _hash[0] &= this->hash_mask();
+ _hash[1] &= this->hash_mask();
+
+ /*--------------------------- push onto new table */
+ if (this->_lsiz[_hash[0]] <=
+ this->_lsiz[_hash[1]] )
+ {
+ base_type::push_item(
+ this->_lptr[_hash[0]], _head) ;
+
+ this->_lsiz[_hash[0]] += 1 ;
+ }
+ else
+ {
+ base_type::push_item(
+ this->_lptr[_hash[1]], _head) ;
+
+ this->_lsiz[_hash[1]] += 1 ;
+ }
+ }
+ }
+
+ public :
+
+/*--------------------------- default c'tor - do nothing! */
+ __inline_call hash_twice (
+ hash_type const&_hsrc = hash_type(),
+ pred_type const&_psrc = pred_type(),
+ double const&_lsrc = double(+.8),
+ allocator const&_asrc = allocator(),
+ size_type const&_nsrc = size_t(+ 0)
+ /*----------------------------- c'tor alloc from obj. */
+ ) : base_type( _asrc),
+ /*----------------------------- c'tor other from obj. */
+ _hfun(_hsrc), _pred(_psrc),
+ _lsiz(_asrc), _load(_lsrc)
+ {
+ set_slots(_nsrc,
+ containers::tight_alloc) ;
+ }
+
+/*--------------------------- default d'tor/copy/move ops */
+ __inline_call~hash_twice () = default ;
+
+ __inline_call hash_twice (
+ self_type const& _src
+ ) = default ;
+ __inline_call hash_twice (
+ self_type && _src
+ ) = default ;
+
+ __inline_call self_type& operator = (
+ self_type const& _src
+ ) = default ;
+ __inline_call self_type& operator = (
+ self_type && _src
+ ) = default ;
+
+/*------------------------------- calc. table load-factor */
+ __inline_call double load_fact (
+ size_type _iinc = +0
+ )
+ { return (double) (this->_size +_iinc) /
+ (double) this->_lptr.count() ;
+ }
+
+/*----------------------------- push data onto hash table */
+ __inline_call _write_it push ( // copy construct
+ data_type const&_data
+ )
+ {
+ /*------------- re-size table if load factor exceeded */
+ if (load_fact(1)> this->_load)
+ grow_hash() ;
+ /*------------------------------- evaluate hash value */
+ uint32_t _hash[2] ;
+ this->_hfun(_data, _hash[0], _hash[1]) ;
+
+ _hash[0] &= this->hash_mask();
+ _hash[1] &= this->hash_mask();
+
+ /*------------------------------- push data onto list */
+ if (this->_lsiz[_hash[0]] <= +1 ||
+ this->_lsiz[_hash[0]] <=
+ this->_lsiz[_hash[1]] )
+ {
+ this->_lsiz[_hash[0]] += +1 ;
+ return base_type::push(_data,_hash[0]) ;
+ }
+ else
+ {
+ this->_lsiz[_hash[1]] += +1 ;
+ return base_type::push(_data,_hash[1]) ;
+ }
+ }
+
+/*----------------------------- push data onto hash table */
+ __inline_call _write_it push ( // move construct
+ data_type && _data
+ )
+ {
+ /*------------- re-size table if load factor exceeded */
+ if (load_fact(1)> this->_load)
+ grow_hash() ;
+ /*------------------------------- evaluate hash value */
+ uint32_t _hash[2] ;
+ this->_hfun(_data, _hash[0], _hash[1]) ;
+
+ _hash[0] &= this->hash_mask();
+ _hash[1] &= this->hash_mask();
+
+ /*------------------------------- push data onto list */
+ if (this->_lsiz[_hash[0]] <= +1 ||
+ this->_lsiz[_hash[0]] <=
+ this->_lsiz[_hash[1]] )
+ {
+ this->_lsiz[_hash[0]] += +1 ;
+ return base_type::push(_data,_hash[0]) ;
+ }
+ else
+ {
+ this->_lsiz[_hash[1]] += +1 ;
+ return base_type::push(_data,_hash[1]) ;
+ }
+ }
+
+/*-------------------------- scan table for exact matches */
+ __normal_call bool_type find (
+ data_type const&_data,
+ item_type *&_same
+ )
+ {
+ if (this->_lptr.empty()) return false;
+
+ /*------------------------------- evaluate hash value */
+ uint32_t _hash[2] ;
+ this->_hfun(_data, _hash[0], _hash[1]) ;
+
+ _hash[0] &= this->hash_mask();
+ _hash[1] &= this->hash_mask();
+
+ /*------------------------------- scan list from head */
+ _same = this->_lptr[_hash[0]];
+ /*------------------------------- check exact matches */
+ for( ; _same != nullptr;
+ _same = _same->_next)
+ {
+ if (this->_pred(_same->_data,_data))
+ {
+ return true ;
+ }
+ }
+
+ /*------------------------------- scan list from head */
+ _same = this->_lptr[_hash[1]];
+ /*------------------------------- check exact matches */
+ for( ; _same != nullptr;
+ _same = _same->_next)
+ {
+ if (this->_pred(_same->_data,_data))
+ {
+ return true ;
+ }
+ }
+
+ /*---------------------------------- no matches found */
+ return false ;
+ }
+
+ __normal_call bool_type find (
+ data_type const&_data,
+ _write_it &_same
+ )
+ {
+ if (this->_lptr.empty()) return false;
+
+ /*------------------------------- evaluate hash value */
+ uint32_t _hash[2] ;
+ this->_hfun(_data, _hash[0], _hash[1]) ;
+
+ _hash[0] &= this->hash_mask();
+ _hash[1] &= this->hash_mask();
+
+ /*------------------------------- scan list from head */
+ item_type *_spos ;
+ _spos = this->_lptr[_hash[0]];
+ /*------------------------------- check exact matches */
+ for( ; _spos != nullptr;
+ _spos = _spos->_next)
+ {
+ if (this->_pred(_spos->_data,_data))
+ {
+ _same = _write_it (_spos,
+ (base_type*)this) ;
+
+ return true ;
+ }
+ }
+
+ /*------------------------------- scan list from head */
+ _spos = this->_lptr[_hash[1]];
+ /*------------------------------- check exact matches */
+ for( ; _spos != nullptr;
+ _spos = _spos->_next)
+ {
+ if (this->_pred(_spos->_data,_data))
+ {
+ _same = _write_it (_spos,
+ (base_type*)this) ;
+
+ return true ;
+ }
+ }
+
+ /*---------------------------------- no matches found */
+ return false ;
+ }
+
+/*-------------------------- scan table for exact matches */
+ template <
+ typename list_type
+ >
+ __normal_call bool_type find (
+ data_type const&_data,
+ list_type &_list
+ )
+ {
+ if (this->_lptr.empty()) return false;
+
+ /*------------------------------- evaluate hash value */
+ uint32_t _hash[2] ;
+ this->_hfun(_data, _hash[0], _hash[1]) ;
+
+ _hash[0] &= this->hash_mask();
+ _hash[1] &= this->hash_mask();
+
+ /*------------------------------- scan list from head */
+ item_type *_same;
+ _same = this->_lptr[_hash[0]] ;
+ /*------------------------------- check exact matches */
+ for( ; _same != nullptr;
+ _same = _same->_next)
+ {
+ if (this->_pred(_same->_data,_data))
+ {
+ _list.push_tail(_same);
+ }
+ }
+
+ /*------------------------------- scan list from head */
+ _same = this->_lptr[_hash[1]] ;
+ /*------------------------------- check exact matches */
+ for( ; _same != nullptr;
+ _same = _same->_next)
+ {
+ if (this->_pred(_same->_data,_data))
+ {
+ _list.push_tail(_same);
+ }
+ }
+
+ /*---------------------------------- no matches found */
+ return ( !_list.empty() );
+ }
+
+/*--------------------- _pop any exact matches from table */
+ __normal_call bool_type _pop (
+ data_type const&_data,
+ data_type &_same
+ )
+ {
+ if (this->_lptr.empty()) return false;
+
+ /*------------------------------- evaluate hash value */
+ uint32_t _hash[2] ;
+ this->_hfun(_data, _hash[0], _hash[1]) ;
+
+ _hash[0] &= this->hash_mask();
+ _hash[1] &= this->hash_mask();
+
+ /*------------------------------- scan list from head */
+ item_type *_prev , *_item;
+ _prev = nullptr;
+ _item = this->_lptr[_hash[0]];
+ /*------------------------------- check exact matches */
+ for( ; _item != nullptr;
+ _prev = _item, _item = _item->_next)
+ {
+ if (this->_pred(_item->_data,_data))
+ {
+ this->_lsiz[_hash[0]] -= 1 ;
+ /*-------------------- steal data before _pop */
+ _same = std::move(_item->_data);
+ /*------------------- _pop and _destruct item */
+ base_type::_pop(
+ _write_it(_prev, this) ,
+ _write_it(_item, this) ,
+ _hash[0]) ;
+ /*------------------------- exact match found */
+ return true ;
+ }
+ }
+
+ /*------------------------------- scan list from head */
+ _prev = nullptr;
+ _item = this->_lptr[_hash[1]];
+ /*------------------------------- check exact matches */
+ for( ; _item != nullptr;
+ _prev = _item, _item = _item->_next)
+ {
+ if (this->_pred(_item->_data,_data))
+ {
+ this->_lsiz[_hash[1]] -= 1 ;
+ /*-------------------- steal data before _pop */
+ _same = std::move(_item->_data);
+ /*------------------- _pop and _destruct item */
+ base_type::_pop(
+ _write_it(_prev, this) ,
+ _write_it(_item, this) ,
+ _hash[1]) ;
+ /*------------------------- exact match found */
+ return true ;
+ }
+ }
+
+ /*--------------------------------- couldnt find data */
+ return false ;
+ }
+
+/*--------------------- _pop any exact matches from table */
+ __normal_call bool_type _pop (
+ data_type const&_data
+ )
+ {
+ if (this->_lptr.empty()) return false;
+
+ /*------------------------------- evaluate hash value */
+ uint32_t _hash[2] ;
+ this->_hfun(_data, _hash[0], _hash[1]) ;
+
+ _hash[0] &= this->hash_mask();
+ _hash[1] &= this->hash_mask();
+
+ /*------------------------------- scan list from head */
+ item_type *_prev , *_item;
+ _prev = nullptr;
+ _item = this->_lptr[_hash[0]];
+ /*------------------------------- check exact matches */
+ for( ; _item != nullptr;
+ _prev = _item, _item = _item->_next)
+ {
+ if (this->_pred(_item->_data,_data))
+ {
+ this->_lsiz[_hash[0]] -= 1 ;
+ /*------------------- _pop and _destruct item */
+ base_type::_pop(
+ _write_it(_prev, this) ,
+ _write_it(_item, this) ,
+ _hash[0]) ;
+ /*------------------------- exact match found */
+ return true ;
+ }
+ }
+
+ /*------------------------------- scan list from head */
+ _prev = nullptr;
+ _item = this->_lptr[_hash[1]];
+ /*------------------------------- check exact matches */
+ for( ; _item != nullptr;
+ _prev = _item, _item = _item->_next)
+ {
+ if (this->_pred(_item->_data,_data))
+ {
+ this->_lsiz[_hash[1]] -= 1 ;
+ /*------------------- _pop and _destruct item */
+ base_type::_pop(
+ _write_it(_prev, this) ,
+ _write_it(_item, this) ,
+ _hash[1]) ;
+ /*------------------------- exact match found */
+ return true ;
+ }
+ }
+
+ /*--------------------------------- couldnt find data */
+ return false ;
+ }
+
+/*------------------- _pop any pointer matches from table */
+ __normal_call bool_type _pop (
+ item_type *_iptr
+ )
+ {
+ if (this->_lptr.empty()) return false;
+
+ /*------------------------------- evaluate hash value */
+ uint32_t _hash[2] ;
+ this->_hfun(_iptr->_data, _hash[0], _hash[1]);
+
+ _hash[0] &= this->hash_mask();
+ _hash[1] &= this->hash_mask();
+
+ /*------------------------------- scan list from head */
+ item_type *_prev , *_item;
+ _prev = nullptr;
+ _item = this->_lptr[_hash[0]];
+ /*------------------------------- check exact matches */
+ for( ; _item != nullptr;
+ _prev = _item, _item = _item->_next)
+ {
+ if(_iptr == _item)
+ {
+ this->_lsiz[_hash[0]] -= 1 ;
+ /*------------------- _pop and _destruct item */
+ base_type::_pop(
+ _write_it(_prev, this) ,
+ _write_it(_item, this) ,
+ _hash[0]) ;
+ /*------------------------- exact match found */
+ return true ;
+ }
+ }
+
+ /*------------------------------- scan list from head */
+ _prev = nullptr;
+ _item = this->_lptr[_hash[1]];
+ /*------------------------------- check exact matches */
+ for( ; _item != nullptr;
+ _prev = _item, _item = _item->_next)
+ {
+ if(_iptr == _item)
+ {
+ this->_lsiz[_hash[1]] -= 1 ;
+ /*------------------- _pop and _destruct item */
+ base_type::_pop(
+ _write_it(_prev, this) ,
+ _write_it(_item, this) ,
+ _hash[1]) ;
+ /*------------------------- exact match found */
+ return true ;
+ }
+ }
+
+ /*--------------------------------- couldnt find data */
+ return false ;
+ }
+
+/*---------------------- scan table and report statistics */
+ __normal_call void_type _get_info (
+ size_type &_min_count,
+ size_type &_max_count,
+ double &_nil_ratio,
+ double &_bad_ratio,
+ double &_ave_count
+ )
+ {
+ _min_count =
+ std::numeric_limits::max();
+ _max_count =
+ std::numeric_limits::min();
+
+ size_type _bad_limit =
+ (size_type) (+3 * this->_load);
+
+ _nil_ratio = (double)+.0;
+ _bad_ratio = (double)+.0;
+ _ave_count = (double)+.0;
+ /*-------------------------- iter. all lists in table */
+ typename lptr_list::_write_it
+ _iter = this->_lptr.head(),
+ _tend = this->_lptr.tend();
+ for( ; _iter != _tend; ++_iter)
+ {
+ /*---------------------- count items in each list */
+ item_type*_next =*_iter;
+ size_type _lnum = +0;
+ for( ; _next != nullptr;
+ _next = _next->_next)
+ {
+ _lnum += +1 ;
+ }
+ /*----------------------------- update statistics */
+ if (_min_count > _lnum)
+ _min_count = _lnum;
+ if (_max_count < _lnum)
+ _max_count = _lnum;
+
+ if (_lnum == (size_type) +0)
+ _nil_ratio += +1. ;
+
+ if (_bad_limit < _lnum)
+ _bad_ratio += +1. ;
+
+ _ave_count += (double)_lnum;
+ }
+
+ _nil_ratio /= this->_lptr.count() ;
+ _bad_ratio /= this->_lptr.count() ;
+ _ave_count /= this->_lptr.count() ;
+ }
+
+ } ;
+
+# undef __cont
+
+
+ }
+
+# endif //__HASH_TWICE__
+
+
+
diff --git a/external/jigsaw/src/libcpp/containers/iter_base.hpp b/external/jigsaw/src/libcpp/containers/iter_base.hpp
index 188677d..6b5f32f 100644
--- a/external/jigsaw/src/libcpp/containers/iter_base.hpp
+++ b/external/jigsaw/src/libcpp/containers/iter_base.hpp
@@ -35,7 +35,7 @@
*
* Copyright 2013-2017
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
--------------------------------------------------------
diff --git a/external/jigsaw/src/libcpp/containers/prioritymap.hpp b/external/jigsaw/src/libcpp/containers/prioritymap.hpp
index 48245fb..f54c507 100644
--- a/external/jigsaw/src/libcpp/containers/prioritymap.hpp
+++ b/external/jigsaw/src/libcpp/containers/prioritymap.hpp
@@ -39,11 +39,11 @@
*
------------------------------------------------------------
*
- * Last updated: 17 August, 2018
+ * Last updated: 25 April, 2020
*
- * Copyright 2013-2017
+ * Copyright 2013-2020
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
------------------------------------------------------------
@@ -123,7 +123,7 @@
size_type ,
allocator > free_list ;
- size_type static const _nfan = +4 ; // fan out
+ size_type static constexpr _nfan = +4 ; // fan out
public :
@@ -565,14 +565,15 @@
--------------------------------------------------------
*/
- __normal_call void_type update ( // copy
+ __inline_call void_type update ( // copy
kptr_type _kptr,
data_type const&_data
)
{/*------------------ move "hole" to updated position */
size_type _hpos =
this->_keys[_kptr];
- _write_it _ipos ;
+ _write_it _ipos =
+ this->_heap.tend();
if (this->_pred(_data ,
this->_heap[_hpos]. _data))
/*-------------------- push "hole" to upper level */
@@ -598,14 +599,15 @@
_ipos - this->_heap.head() ;
}
- __normal_call void_type update ( // move
+ __inline_call void_type update ( // move
kptr_type _kptr,
data_type &&_data
)
{/*------------------ move "hole" to updated position */
size_type _hpos =
this->_keys[_kptr];
- _write_it _ipos ;
+ _write_it _ipos =
+ this->_heap.tend();
if (this->_pred(_data ,
this->_heap[_hpos]. _data))
/*-------------------- push "hole" to upper level */
@@ -631,6 +633,56 @@
_ipos - this->_heap.head() ;
}
+ /*
+ --------------------------------------------------------
+ * REDUCE: update data in heap ("lower" priority)
+ --------------------------------------------------------
+ */
+
+ __inline_call void_type reduce ( // copy
+ kptr_type _kptr,
+ data_type const&_data
+ )
+ {/*------------------ move "hole" to updated position */
+ size_type _hpos =
+ this->_keys[_kptr];
+ _write_it _ipos = push_upper (
+ this->_heap.head(),
+ this->_heap.head()+_hpos ,
+ __copy(data_type,_data)) ;
+
+ /*------------------------ copy this data into "hole" */
+ _ipos->_kptr = _kptr ;
+ _ipos->_data =
+ __copy(data_type,_data) ;
+
+ /*------------------------ copy position into mapping */
+ this->_keys[_kptr] =
+ _ipos - this->_heap.head() ;
+ }
+
+ __inline_call void_type reduce ( // move
+ kptr_type _kptr,
+ data_type &&_data
+ )
+ {/*------------------ move "hole" to updated position */
+ size_type _hpos =
+ this->_keys[_kptr];
+ _write_it _ipos = push_upper (
+ this->_heap.head(),
+ this->_heap.head()+_hpos ,
+ __copy(data_type,_data)) ;
+
+ /*------------------------ copy this data into "hole" */
+ _ipos->_kptr = _kptr ;
+ _ipos->_data =
+ __move(data_type,_data) ;
+
+ /*------------------------ copy position into mapping */
+ this->_keys[_kptr] =
+ _ipos - this->_heap.head() ;
+ }
+
/*
--------------------------------------------------------
* test heap validity (debug only!)
diff --git a/external/jigsaw/src/libcpp/containers/priorityset.hpp b/external/jigsaw/src/libcpp/containers/priorityset.hpp
index f959c7d..54d9cf1 100644
--- a/external/jigsaw/src/libcpp/containers/priorityset.hpp
+++ b/external/jigsaw/src/libcpp/containers/priorityset.hpp
@@ -43,7 +43,7 @@
*
* Copyright 2013-2017
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
------------------------------------------------------------
@@ -90,7 +90,7 @@
typedef typename
container::_const_it _const_it ;
- size_type static const _nfan = +4; // fan out
+ size_type static constexpr _nfan = +4; // fan out
public :
diff --git a/external/jigsaw/src/libcpp/containers/single_list.hpp b/external/jigsaw/src/libcpp/containers/single_list.hpp
index 7a05208..0e58672 100644
--- a/external/jigsaw/src/libcpp/containers/single_list.hpp
+++ b/external/jigsaw/src/libcpp/containers/single_list.hpp
@@ -45,7 +45,7 @@
*
* Copyright 2013-2018
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
------------------------------------------------------------
diff --git a/external/jigsaw/src/libcpp/containers/singleiter.hpp b/external/jigsaw/src/libcpp/containers/singleiter.hpp
index 5919ed9..3a681de 100644
--- a/external/jigsaw/src/libcpp/containers/singleiter.hpp
+++ b/external/jigsaw/src/libcpp/containers/singleiter.hpp
@@ -45,7 +45,7 @@
*
* Copyright 2013-2017
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
------------------------------------------------------------
diff --git a/external/jigsaw/src/libcpp/expansion/dd_float.hpp b/external/jigsaw/src/libcpp/expansion/dd_float.hpp
new file mode 100644
index 0000000..d53e547
--- /dev/null
+++ b/external/jigsaw/src/libcpp/expansion/dd_float.hpp
@@ -0,0 +1,550 @@
+
+/*
+ --------------------------------------------------------
+ * MPFLOAT: multi-precision floating-point arithmetic.
+ --------------------------------------------------------
+ *
+ * "double-double" arithmetic. Here mp-expansion size
+ * is capped at 2, with subsequent bits truncated:
+ *
+ * M. Joldes, J-M. Muller, V. Popescu (2017): Tight &
+ * rigourous error bounds for basic building blocks of
+ * double-word arithmetic. ACM Transactions on
+ * Mathematical Software, ACM, 44 (2), pp. 1-27.
+ *
+ * Y. Hida, X. Li, and D. Bailey (2000): Quad-double
+ * arithmetic: Algorithms, implementation, and
+ * application. In the 15th IEEE Symposium on Computer
+ * Arithmetic, pp. 155-162.
+ *
+ --------------------------------------------------------
+ *
+ * This program may be freely redistributed under the
+ * condition that the copyright notices (including this
+ * entire header) are not removed, and no compensation
+ * is received through use of the software. Private,
+ * research, and institutional use is free. You may
+ * distribute modified versions of this code UNDER THE
+ * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE
+ * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE
+ * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE
+ * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR
+ * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution
+ * of this code as part of a commercial system is
+ * permissible ONLY BY DIRECT ARRANGEMENT WITH THE
+ * AUTHOR. (If you are not directly supplying this
+ * code to a customer, and you are instead telling them
+ * how they can obtain it for free, then you are not
+ * required to make any arrangement with me.)
+ *
+ * Disclaimer: Neither I nor: Columbia University, The
+ * Massachusetts Institute of Technology, The
+ * University of Sydney, nor The National Aeronautics
+ * and Space Administration warrant this code in any
+ * way whatsoever. This code is provided "as-is" to be
+ * used at your own risk.
+ *
+ --------------------------------------------------------
+ *
+ * Last updated: 16 April, 2020
+ *
+ * Copyright 2020--
+ * Darren Engwirda
+ * d.engwirda@gmail.com
+ * https://github.com/dengwirda/
+ *
+ --------------------------------------------------------
+ */
+
+# pragma once
+
+# ifndef __DD_FLOAT__
+# define __DD_FLOAT__
+
+# include "mp_basic.hpp"
+
+// namespace mp_float { // hmmm no...
+
+ /*
+ --------------------------------------------------------
+ * DD_FLT: (double-double) precision numbers
+ --------------------------------------------------------
+ */
+
+# define REAL_TYPE mp_float::real_type
+# define INDX_TYPE mp_float::indx_type
+
+ class dd_flt;
+
+ __inline_call dd_flt operator + ( // fwd. dec's
+ dd_flt const&,
+ REAL_TYPE ) ;
+ __inline_call dd_flt operator + (
+ REAL_TYPE ,
+ dd_flt const&) ;
+ __inline_call dd_flt operator + (
+ dd_flt const&,
+ dd_flt const&) ;
+
+ __inline_call dd_flt operator - (
+ dd_flt const&,
+ REAL_TYPE ) ;
+ __inline_call dd_flt operator - (
+ REAL_TYPE ,
+ dd_flt const&) ;
+ __inline_call dd_flt operator - (
+ dd_flt const&,
+ dd_flt const&) ;
+
+ __inline_call dd_flt operator * (
+ dd_flt const&,
+ REAL_TYPE ) ;
+ __inline_call dd_flt operator * (
+ REAL_TYPE ,
+ dd_flt const&) ;
+ __inline_call dd_flt operator * (
+ dd_flt const&,
+ dd_flt const&) ;
+
+ __inline_call dd_flt operator / (
+ dd_flt const&,
+ REAL_TYPE ) ;
+ __inline_call dd_flt operator / (
+ REAL_TYPE ,
+ dd_flt const&) ;
+ __inline_call dd_flt operator / (
+ dd_flt const&,
+ dd_flt const&) ;
+
+ class dd_flt
+ {
+/*------------------------------ doubledouble number type */
+ public :
+ typedef REAL_TYPE real_type;
+ typedef INDX_TYPE indx_type;
+
+ indx_type static constexpr _size = 2 ;
+ indx_type static constexpr _xlen = 2 ;
+
+ real_type _xdat [ 2 ] ;
+
+ public :
+/*------------------------------ access to expansion bits */
+ __inline_call real_type& hi (
+ )
+ { return this->_xdat[1] ;
+ }
+ __inline_call real_type& lo (
+ )
+ { return this->_xdat[0] ;
+ }
+
+ __inline_call real_type const&hi (
+ ) const
+ { return this->_xdat[1] ;
+ }
+ __inline_call real_type const&lo (
+ ) const
+ { return this->_xdat[0] ;
+ }
+
+/*------------------------------ initialising constructor */
+ __inline_call dd_flt (
+ real_type _hi = real_type(+0.) ,
+ real_type _lo = real_type(+0.)
+ )
+ { this->_xdat[0] = _lo ;
+ this->_xdat[1] = _hi ;
+ }
+
+ __inline_call dd_flt ( // copy c'tor
+ dd_flt const& _aa
+ )
+ {
+ this->_xdat[0] = _aa.lo();
+ this->_xdat[1] = _aa.hi();
+ }
+
+ __inline_call dd_flt& operator = ( // assignment
+ dd_flt const& _aa
+ )
+ {
+ this->_xdat[0] = _aa.lo();
+ this->_xdat[1] = _aa.hi();
+
+ return ( *this ) ;
+ }
+ __inline_call dd_flt& operator = ( // assignment
+ real_type _aa
+ )
+ {
+ this->_xdat[0] = +0. ;
+ this->_xdat[1] = (real_type)_aa;
+
+ return ( *this ) ;
+ }
+
+/*---------------------------------------- cast operators */
+ __inline_call operator real_type (
+ ) const
+ { return (real_type)(hi()+lo());
+ }
+
+ __inline_call operator indx_type (
+ ) const
+ { return (indx_type)(hi()+lo());
+ }
+
+/*---------------------------------------- math operators */
+ __inline_call dd_flt operator + (
+ ) const
+ { return dd_flt(+hi(), +lo());
+ }
+
+ __inline_call dd_flt operator - (
+ ) const
+ { return dd_flt(-hi(), -lo());
+ }
+
+/*------------------------------ helper: init. from a + b */
+ __inline_call void from_add (
+ real_type _aa, real_type _bb
+ )
+ {
+ mp_float::one_one_add_full(_aa, _bb,
+ this->_xdat[1],
+ this->_xdat[0]) ;
+ }
+
+/*------------------------------ helper: init. from a - b */
+ __inline_call void from_sub (
+ real_type _aa, real_type _bb
+ )
+ {
+ mp_float::one_one_sub_full(_aa, _bb,
+ this->_xdat[1],
+ this->_xdat[0]) ;
+ }
+
+/*------------------------------ helper: init. from a * a */
+ __inline_call void from_sqr (
+ real_type _aa
+ )
+ {
+ mp_float::one_one_sqr_full(_aa,
+ this->_xdat[1],
+ this->_xdat[0]) ;
+ }
+
+/*------------------------------ helper: init. from a * b */
+ __inline_call void from_mul (
+ real_type _aa, real_type _bb
+ )
+ {
+ mp_float::one_one_mul_full(_aa, _bb,
+ this->_xdat[1],
+ this->_xdat[0]) ;
+ }
+
+ __inline_call dd_flt& operator+= ( // via double
+ real_type _aa
+ )
+ {
+ dd_flt _tt = *this + _aa ;
+
+ hi() = _tt.hi();
+ lo() = _tt.lo();
+
+ return ( *this ) ;
+ }
+ __inline_call dd_flt& operator-= (
+ real_type _aa
+ )
+ {
+ dd_flt _tt = *this - _aa ;
+
+ hi() = _tt.hi();
+ lo() = _tt.lo();
+
+ return ( *this ) ;
+ }
+ __inline_call dd_flt& operator*= (
+ real_type _aa
+ )
+ {
+ dd_flt _tt = *this * _aa ;
+
+ hi() = _tt.hi();
+ lo() = _tt.lo();
+
+ return ( *this ) ;
+ }
+ __inline_call dd_flt& operator/= (
+ real_type _aa
+ )
+ {
+ dd_flt _tt = *this / _aa ;
+
+ hi() = _tt.hi();
+ lo() = _tt.lo();
+
+ return ( *this ) ;
+ }
+
+ __inline_call dd_flt& operator+= ( // via dd_flt
+ dd_flt const& _aa
+ )
+ {
+ dd_flt _tt = *this + _aa ;
+
+ hi() = _tt.hi();
+ lo() = _tt.lo();
+
+ return ( *this ) ;
+ }
+ __inline_call dd_flt& operator-= (
+ dd_flt const& _aa
+ )
+ {
+ dd_flt _tt = *this - _aa ;
+
+ hi() = _tt.hi();
+ lo() = _tt.lo();
+
+ return ( *this ) ;
+ }
+ __inline_call dd_flt& operator*= (
+ dd_flt const& _aa
+ )
+ {
+ dd_flt _tt = *this * _aa ;
+
+ hi() = _tt.hi();
+ lo() = _tt.lo();
+
+ return ( *this ) ;
+ }
+ __inline_call dd_flt& operator/= (
+ dd_flt const& _aa
+ )
+ {
+ dd_flt _tt = *this / _aa ;
+
+ hi() = _tt.hi();
+ lo() = _tt.lo();
+
+ return ( *this ) ;
+ }
+
+ } ;
+
+ /*
+ --------------------------------------------------------
+ * double-double a + b operators
+ --------------------------------------------------------
+ */
+
+ __inline_call dd_flt operator + (
+ dd_flt const& _aa,
+ REAL_TYPE _bb
+ )
+ {
+ REAL_TYPE _x0, _x1;
+ mp_float::two_one_add_clip(
+ _aa.hi(), _aa.lo(), _bb, _x1, _x0
+ ) ;
+
+ return ( dd_flt(_x1, _x0) ) ;
+ }
+
+ __inline_call dd_flt operator + (
+ REAL_TYPE _aa,
+ dd_flt const& _bb
+ )
+ { return ( +(_bb + _aa) ) ;
+ }
+
+ __inline_call dd_flt operator + (
+ dd_flt const& _aa,
+ dd_flt const& _bb
+ )
+ {
+ REAL_TYPE _x0, _x1;
+ mp_float::two_two_add_clip(
+ _aa.hi(), _aa.lo(),
+ _bb.hi(), _bb.lo(), _x1, _x0
+ ) ;
+
+ return ( dd_flt(_x1, _x0) ) ;
+ }
+
+ /*
+ --------------------------------------------------------
+ * double-double a - b operators
+ --------------------------------------------------------
+ */
+
+ __inline_call dd_flt operator - (
+ dd_flt const& _aa,
+ REAL_TYPE _bb
+ )
+ {
+ REAL_TYPE _x0, _x1;
+ mp_float::two_one_sub_clip(
+ _aa.hi(), _aa.lo(), _bb, _x1, _x0
+ ) ;
+
+ return ( dd_flt(_x1, _x0) ) ;
+ }
+
+ __inline_call dd_flt operator - (
+ REAL_TYPE _aa,
+ dd_flt const& _bb
+ )
+ { return ( -(_bb - _aa) ) ;
+ }
+
+ __inline_call dd_flt operator - (
+ dd_flt const& _aa,
+ dd_flt const& _bb
+ )
+ {
+ REAL_TYPE _x0, _x1;
+ mp_float::two_two_sub_clip(
+ _aa.hi(), _aa.lo(),
+ _bb.hi(), _bb.lo(), _x1, _x0
+ ) ;
+
+ return ( dd_flt(_x1, _x0) ) ;
+ }
+
+ /*
+ --------------------------------------------------------
+ * double-double a * b operators
+ --------------------------------------------------------
+ */
+
+ __inline_call dd_flt operator * (
+ dd_flt const& _aa,
+ REAL_TYPE _bb
+ )
+ {
+ REAL_TYPE _x0, _x1;
+ mp_float::two_one_mul_clip(
+ _aa.hi(), _aa.lo(), _bb, _x1, _x0
+ ) ;
+
+ return ( dd_flt(_x1, _x0) ) ;
+ }
+
+ __inline_call dd_flt operator * (
+ REAL_TYPE _aa,
+ dd_flt const& _bb
+ )
+ { return ( _bb * _aa ) ;
+ }
+
+ __inline_call dd_flt operator * (
+ dd_flt const& _aa,
+ dd_flt const& _bb
+ )
+ {
+ REAL_TYPE _x0, _x1;
+ mp_float::two_two_mul_clip(
+ _aa.hi(), _aa.lo(),
+ _bb.hi(), _bb.lo(), _x1, _x0
+ ) ;
+
+ return ( dd_flt(_x1, _x0) ) ;
+ }
+
+ /*
+ --------------------------------------------------------
+ * double-double a / b operators
+ --------------------------------------------------------
+ */
+
+ __inline_call dd_flt operator / (
+ dd_flt const& _aa,
+ REAL_TYPE _bb
+ )
+ {
+ REAL_TYPE _x0, _x1;
+ mp_float::two_one_div_clip(
+ _aa.hi(), _aa.lo(), _bb, _x1, _x0
+ ) ;
+
+ return ( dd_flt(_x1, _x0) ) ;
+ }
+
+ __inline_call dd_flt operator / (
+ REAL_TYPE _aa,
+ dd_flt const& _bb
+ )
+ { return ( dd_flt(_aa) / _bb ) ;
+ }
+
+ __inline_call dd_flt operator / (
+ dd_flt const& _aa,
+ dd_flt const& _bb
+ )
+ {
+ REAL_TYPE _x0, _x1;
+ mp_float::two_two_div_clip(
+ _aa.hi(), _aa.lo(),
+ _bb.hi(), _bb.lo(), _x1, _x0
+ ) ;
+
+ return ( dd_flt(_x1, _x0) ) ;
+ }
+
+ /*
+ --------------------------------------------------------
+ * double-double equal operators
+ --------------------------------------------------------
+ */
+
+ __inline_call bool operator == (
+ dd_flt const& _aa,
+ dd_flt const& _bb
+ )
+ { return _aa.hi() == _bb.hi() &&
+ _aa.lo() == _bb.lo() ;
+ }
+
+ __inline_call bool operator != (
+ dd_flt const& _aa,
+ dd_flt const& _bb
+ )
+ { return _aa.hi() != _bb.hi() ||
+ _aa.lo() != _bb.lo() ;
+ }
+
+ __inline_call bool operator < (
+ dd_flt const& _aa,
+ dd_flt const& _bb
+ )
+ { return _aa.hi() != _bb.hi() ?
+ _aa.hi() < _bb.hi() :
+ _aa.lo() < _bb.lo() ;
+ }
+
+ __inline_call bool operator > (
+ dd_flt const& _aa,
+ dd_flt const& _bb
+ )
+ { return _aa.hi() != _bb.hi() ?
+ _aa.hi() > _bb.hi() :
+ _aa.lo() > _bb.lo() ;
+ }
+
+# undef REAL_TYPE
+# undef INDX_TYPE
+
+
+// }
+
+# endif//__DD_FLOAT__
+
+
+
diff --git a/external/jigsaw/src/libcpp/expansion/ia_float.hpp b/external/jigsaw/src/libcpp/expansion/ia_float.hpp
new file mode 100644
index 0000000..341b6a5
--- /dev/null
+++ b/external/jigsaw/src/libcpp/expansion/ia_float.hpp
@@ -0,0 +1,671 @@
+
+/*
+ --------------------------------------------------------
+ * MPFLOAT: multi-precision floating-point arithmetic.
+ --------------------------------------------------------
+ *
+ * This program may be freely redistributed under the
+ * condition that the copyright notices (including this
+ * entire header) are not removed, and no compensation
+ * is received through use of the software. Private,
+ * research, and institutional use is free. You may
+ * distribute modified versions of this code UNDER THE
+ * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE
+ * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE
+ * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE
+ * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR
+ * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution
+ * of this code as part of a commercial system is
+ * permissible ONLY BY DIRECT ARRANGEMENT WITH THE
+ * AUTHOR. (If you are not directly supplying this
+ * code to a customer, and you are instead telling them
+ * how they can obtain it for free, then you are not
+ * required to make any arrangement with me.)
+ *
+ * Disclaimer: Neither I nor: Columbia University, The
+ * Massachusetts Institute of Technology, The
+ * University of Sydney, nor The National Aeronautics
+ * and Space Administration warrant this code in any
+ * way whatsoever. This code is provided "as-is" to be
+ * used at your own risk.
+ *
+ --------------------------------------------------------
+ *
+ * Last updated: 10 April, 2020
+ *
+ * Copyright 2020--
+ * Darren Engwirda
+ * d.engwirda@gmail.com
+ * https://github.com/dengwirda/
+ *
+ --------------------------------------------------------
+ */
+
+// very simple, light-weight interval arithmetic for the
+// construction of "filtered" numerical predicates. Only
+// OP = {+, -, *,} implemented...
+
+
+# pragma once
+
+# ifndef __IA_FLOAT__
+# define __IA_FLOAT__
+
+# include "mp_basic.hpp"
+
+// namespace mp_float { // hmmm no...
+
+ /*
+ --------------------------------------------------------
+ * IA-FLT: interval arithmetic
+ --------------------------------------------------------
+ */
+
+# define REAL_TYPE mp_float::real_type
+# define INDX_TYPE mp_float::indx_type
+
+// silliness with "volatile" to try to stop the compiler
+// from spuriously(!) optimising floating-point op's and
+// breaking rounding-mode behaviour...
+
+// really, proper compiler support is needed instead and
+// it's unclear whether this is actually reliable or not
+
+ __normal_call REAL_TYPE add_up ( // for rnd up
+ REAL_TYPE _aa, REAL_TYPE _bb
+ )
+ { REAL_TYPE volatile _cc = (+_aa) + (+_bb) ;
+ return +_cc ;
+ }
+
+ __normal_call REAL_TYPE add_dn (
+ REAL_TYPE _aa, REAL_TYPE _bb
+ )
+ { REAL_TYPE volatile _cc = (-_aa) + (-_bb) ;
+ return -_cc ;
+ }
+
+ __normal_call REAL_TYPE sub_up (
+ REAL_TYPE _aa, REAL_TYPE _bb
+ )
+ { REAL_TYPE volatile _cc = (+_aa) - (+_bb) ;
+ return +_cc ;
+ }
+
+ __normal_call REAL_TYPE sub_dn (
+ REAL_TYPE _aa, REAL_TYPE _bb
+ )
+ { REAL_TYPE volatile _cc = (+_bb) - (+_aa) ;
+ return -_cc ;
+ }
+
+ __normal_call REAL_TYPE mul_up (
+ REAL_TYPE _aa, REAL_TYPE _bb
+ )
+ { REAL_TYPE volatile _cc = (+_aa) * (+_bb) ;
+ return +_cc ;
+ }
+
+ __normal_call REAL_TYPE mul_dn (
+ REAL_TYPE _aa, REAL_TYPE _bb
+ )
+ { REAL_TYPE volatile _cc = (+_aa) * (-_bb) ;
+ return -_cc ;
+ }
+
+ class ia_flt;
+
+ __inline_call ia_flt operator + ( // fwd. dec's
+ ia_flt const&,
+ REAL_TYPE ) ;
+ __inline_call ia_flt operator + (
+ REAL_TYPE ,
+ ia_flt const&) ;
+ __inline_call ia_flt operator + (
+ ia_flt const&,
+ ia_flt const&) ;
+
+ __inline_call ia_flt operator - (
+ ia_flt const&,
+ REAL_TYPE ) ;
+ __inline_call ia_flt operator - (
+ REAL_TYPE ,
+ ia_flt const&) ;
+ __inline_call ia_flt operator - (
+ ia_flt const&,
+ ia_flt const&) ;
+
+ __inline_call ia_flt operator * (
+ ia_flt const&,
+ REAL_TYPE ) ;
+ __inline_call ia_flt operator * (
+ REAL_TYPE ,
+ ia_flt const&) ;
+ __inline_call ia_flt operator * (
+ ia_flt const&,
+ ia_flt const&) ;
+
+ class ia_rnd
+ {
+/*---------------------------------- interval FP-rnd type */
+ public :
+ int volatile _rndstate = 0;
+
+ public :
+/*---------------------------------- floating pt rounding */
+ __normal_call ia_rnd (
+ )
+ {
+ _rndstate=fegetround();
+
+ fesetround (FE_UPWARD);
+ }
+ __normal_call ~ia_rnd (
+ )
+ {
+ fesetround (_rndstate);
+ }
+ } ;
+
+ class ia_flt
+ {
+/*---------------------------------- interval number type */
+ public :
+ typedef REAL_TYPE real_type;
+ typedef INDX_TYPE indx_type;
+
+ indx_type static constexpr _size = 2 ;
+ indx_type static constexpr _xlen = 2 ;
+
+ real_type _xdat [ 2 ] ;
+
+ public :
+/*------------------------------ access to expansion bits */
+ __inline_call real_type& up (
+ )
+ { return this->_xdat[1] ;
+ }
+ __inline_call real_type& lo (
+ )
+ { return this->_xdat[0] ;
+ }
+
+ __inline_call real_type const&up (
+ ) const
+ { return this->_xdat[1] ;
+ }
+ __inline_call real_type const&lo (
+ ) const
+ { return this->_xdat[0] ;
+ }
+
+/*------------------------------ initialising constructor */
+ __inline_call ia_flt (
+ real_type _lo = real_type(+0.) ,
+ real_type _up = real_type(+0.)
+ )
+ { this->_xdat[0] = _lo ;
+ this->_xdat[1] = _up ;
+ }
+
+ __inline_call ia_flt ( // copy c'tor
+ ia_flt const& _aa
+ )
+ {
+ this->_xdat[0] = _aa.lo();
+ this->_xdat[1] = _aa.up();
+ }
+
+ __inline_call ia_flt& operator = ( // assignment
+ ia_flt const& _aa
+ )
+ {
+ this->_xdat[0] = _aa.lo();
+ this->_xdat[1] = _aa.up();
+
+ return ( *this ) ;
+ }
+ __inline_call ia_flt& operator = ( // assignment
+ real_type _aa
+ )
+ {
+ this->_xdat[0] = (real_type)_aa;
+ this->_xdat[1] = (real_type)_aa;
+
+ return ( *this ) ;
+ }
+
+/*---------------------------------------- set from float */
+ __inline_call void_type from_add (
+ real_type _aa,
+ real_type _bb
+ )
+ {
+ lo() = add_dn(_aa, _bb) ;
+ up() = add_up(_aa, _bb) ;
+ }
+
+ __inline_call void_type from_sub (
+ real_type _aa,
+ real_type _bb
+ )
+ {
+ lo() = sub_dn(_aa, _bb) ;
+ up() = sub_up(_aa, _bb) ;
+ }
+
+ __inline_call void_type from_mul (
+ real_type _aa,
+ real_type _bb
+ )
+ {
+ lo() = mul_dn(_aa, _bb) ;
+ up() = mul_up(_aa, _bb) ;
+ }
+
+/*---------------------------------------- math operators */
+ __inline_call ia_flt operator + (
+ ) const
+ { return ia_flt(+lo(), +up());
+ }
+
+ __inline_call ia_flt operator - (
+ ) const
+ { return ia_flt(-lo(), -up());
+ }
+
+ __inline_call ia_flt& operator+= ( // via double
+ real_type _aa
+ )
+ {
+ ia_flt _tt = *this + _aa ;
+
+ up() = _tt.up();
+ lo() = _tt.lo();
+
+ return ( *this ) ;
+ }
+ __inline_call ia_flt& operator-= (
+ real_type _aa
+ )
+ {
+ ia_flt _tt = *this - _aa ;
+
+ up() = _tt.up();
+ lo() = _tt.lo();
+
+ return ( *this ) ;
+ }
+ __inline_call ia_flt& operator*= (
+ real_type _aa
+ )
+ {
+ ia_flt _tt = *this * _aa ;
+
+ up() = _tt.up();
+ lo() = _tt.lo();
+
+ return ( *this ) ;
+ }
+
+ __inline_call ia_flt& operator+= ( // via ia_flt
+ ia_flt const& _aa
+ )
+ {
+ ia_flt _tt = *this + _aa ;
+
+ up() = _tt.up();
+ lo() = _tt.lo();
+
+ return ( *this ) ;
+ }
+ __inline_call ia_flt& operator-= (
+ ia_flt const& _aa
+ )
+ {
+ ia_flt _tt = *this - _aa ;
+
+ up() = _tt.up();
+ lo() = _tt.lo();
+
+ return ( *this ) ;
+ }
+ __inline_call ia_flt& operator*= (
+ ia_flt const& _aa
+ )
+ {
+ ia_flt _tt = *this * _aa ;
+
+ up() = _tt.up();
+ lo() = _tt.lo();
+
+ return ( *this ) ;
+ }
+
+/*---------------------------------------- mid-rad. forms */
+ __inline_call real_type mid (
+ ) const
+ {
+ real_type _mm = lo() + up() ;
+
+ if (!std::isfinite(_mm))
+ {
+ _mm =
+ (lo() / (real_type)+2.)+
+ (up() / (real_type)+2.);
+ }
+ else
+ {
+ _mm /= (real_type)+2. ;
+ }
+
+ return _mm ;
+ }
+
+ __inline_call real_type rad (
+ ) const
+ {
+ real_type _r1 = up() - mid() ;
+ real_type _r2 = mid() - lo() ;
+
+ return std::max(_r1, _r2) ;
+ }
+
+ } ;
+
+ /*
+ --------------------------------------------------------
+ * interval-float a + b operators
+ --------------------------------------------------------
+ */
+
+ __inline_call ia_flt operator + (
+ ia_flt const& _aa,
+ REAL_TYPE _bb
+ )
+ {
+ REAL_TYPE _lo, _up;
+
+ _lo = add_dn(_aa.lo(), _bb) ;
+ _up = add_up(_aa.up(), _bb) ;
+
+ return ( ia_flt(_lo, _up) ) ;
+ }
+
+ __inline_call ia_flt operator + (
+ REAL_TYPE _aa,
+ ia_flt const& _bb
+ )
+ {
+ REAL_TYPE _lo, _up;
+
+ _lo = add_dn(_aa, _bb.lo()) ;
+ _up = add_up(_aa, _bb.up()) ;
+
+ return ( ia_flt(_lo, _up) ) ;
+ }
+
+ __inline_call ia_flt operator + (
+ ia_flt const& _aa,
+ ia_flt const& _bb
+ )
+ {
+ REAL_TYPE _lo, _up;
+
+ _lo = add_dn(_aa.lo(), _bb.lo()) ;
+ _up = add_up(_aa.up(), _bb.up()) ;
+
+ return ( ia_flt(_lo, _up) ) ;
+ }
+
+ /*
+ --------------------------------------------------------
+ * interval-float a - b operators
+ --------------------------------------------------------
+ */
+
+ __inline_call ia_flt operator - (
+ ia_flt const& _aa,
+ REAL_TYPE _bb
+ )
+ {
+ REAL_TYPE _lo, _up;
+
+ _lo = sub_dn(_aa.lo(), _bb) ;
+ _up = sub_up(_aa.up(), _bb) ;
+
+ return ( ia_flt(_lo, _up) ) ;
+ }
+
+ __inline_call ia_flt operator - (
+ REAL_TYPE _aa,
+ ia_flt const& _bb
+ )
+ {
+ REAL_TYPE _lo, _up;
+
+ _lo = sub_dn(_aa, _bb.up()) ;
+ _up = sub_up(_aa, _bb.lo()) ;
+
+ return ( ia_flt(_lo, _up) ) ;
+ }
+
+ __inline_call ia_flt operator - (
+ ia_flt const& _aa,
+ ia_flt const& _bb
+ )
+ {
+ REAL_TYPE _lo, _up;
+
+ _lo = sub_dn(_aa.lo(), _bb.up()) ;
+ _up = sub_up(_aa.up(), _bb.lo()) ;
+
+ return ( ia_flt(_lo, _up) ) ;
+ }
+
+ /*
+ --------------------------------------------------------
+ * interval-float a * b operators
+ --------------------------------------------------------
+ */
+
+ __inline_call ia_flt operator * (
+ ia_flt const& _aa,
+ REAL_TYPE _bb
+ )
+ {
+ REAL_TYPE _lo, _up;
+
+ if (_bb > (REAL_TYPE) +0.)
+ {
+ _lo = mul_dn(_aa.lo(), _bb) ;
+ _up = mul_up(_aa.up(), _bb) ;
+ }
+ else
+ if (_bb < (REAL_TYPE)+0.)
+ {
+ _lo = mul_dn(_aa.up(), _bb) ;
+ _up = mul_up(_aa.lo(), _bb) ;
+ }
+ else
+ {
+ _lo = (REAL_TYPE)+0. ;
+ _up = (REAL_TYPE)+0. ;
+ }
+
+ return ( ia_flt(_lo, _up) ) ;
+ }
+
+ __inline_call ia_flt operator * (
+ REAL_TYPE _aa,
+ ia_flt const& _bb
+ )
+ { return ( _bb * _aa ) ;
+ }
+
+ __normal_call ia_flt operator * (
+ ia_flt const& _aa,
+ ia_flt const& _bb
+ )
+ {
+ REAL_TYPE _lo, _up;
+
+ if (_aa.lo() < (REAL_TYPE)+0.)
+ {
+ if (_aa.up() > (REAL_TYPE)+0.)
+ {
+ if (_bb.lo() < (REAL_TYPE)+0.)
+ {
+ if (_bb.up() > (REAL_TYPE)+0.) // mix * mix
+ {
+ REAL_TYPE _l1, _l2;
+ _l1 = mul_dn(_aa.lo(), _bb.up());
+ _l2 = mul_dn(_aa.up(), _bb.lo());
+ _lo = std::min(_l1, _l2);
+
+ REAL_TYPE _u1, _u2;
+ _u1 = mul_up(_aa.lo(), _bb.lo());
+ _u2 = mul_up(_aa.up(), _bb.up());
+ _up = std::min(_u1, _u2);
+ }
+ else // mix * -ve
+ {
+ _lo = mul_dn(_aa.up(), _bb.lo());
+ _up = mul_up(_aa.lo(), _bb.lo());
+ }
+ }
+ else
+ {
+ if (_bb.up() > (REAL_TYPE)+0.) // mix * +ve
+ {
+ _lo = mul_dn(_aa.lo(), _bb.up());
+ _up = mul_up(_aa.up(), _bb.up());
+ }
+ else // mix * +0.
+ {
+ _lo = (REAL_TYPE)+0. ;
+ _up = (REAL_TYPE)+0. ;
+ }
+ }
+ }
+ else
+ {
+ if (_bb.lo() < (REAL_TYPE)+0.)
+ {
+ if (_bb.up() > (REAL_TYPE)+0.) // -ve * mix
+ {
+ _lo = mul_dn(_aa.lo(), _bb.up());
+ _up = mul_up(_aa.lo(), _bb.lo());
+ }
+ else // -ve * -ve
+ {
+ _lo = mul_dn(_aa.up(), _bb.up());
+ _up = mul_up(_aa.lo(), _bb.lo());
+ }
+ }
+ else
+ {
+ if (_bb.up() > (REAL_TYPE)+0.) // -ve * +ve
+ {
+ _lo = mul_dn(_aa.lo(), _bb.up());
+ _up = mul_up(_aa.up(), _bb.lo());
+ }
+ else // -ve * +0.
+ {
+ _lo = (REAL_TYPE)+0. ;
+ _up = (REAL_TYPE)+0. ;
+ }
+ }
+ }
+ }
+ else
+ {
+ if (_aa.up() > (REAL_TYPE)+0.)
+ {
+ if (_bb.lo() < (REAL_TYPE)+0.)
+ {
+ if (_bb.up() > (REAL_TYPE)+0.) // +ve * mix
+ {
+ _lo = mul_dn(_aa.up(), _bb.lo());
+ _up = mul_up(_aa.up(), _bb.up());
+ }
+ else // +ve * -ve
+ {
+ _lo = mul_dn(_aa.up(), _bb.lo());
+ _up = mul_up(_aa.lo(), _bb.up());
+ }
+ }
+ else
+ {
+ if (_bb.up() > (REAL_TYPE)+0.) // +ve * +ve
+ {
+ _lo = mul_dn(_aa.lo(), _bb.lo());
+ _up = mul_up(_aa.up(), _bb.up());
+ }
+ else // +ve * +0.
+ {
+ _lo = (REAL_TYPE)+0. ;
+ _up = (REAL_TYPE)+0. ;
+ }
+ }
+ }
+ else // -ve * ???
+ {
+ _lo = (REAL_TYPE)+0. ;
+ _up = (REAL_TYPE)+0. ;
+ }
+ }
+
+ return ( ia_flt(_lo, _up) ) ;
+ }
+
+ /*
+ --------------------------------------------------------
+ * interval-float a ^ 2 operators
+ --------------------------------------------------------
+ */
+
+ __normal_call ia_flt sqr (
+ ia_flt const& _aa
+ )
+ {
+ REAL_TYPE _lo, _up;
+
+ if (_aa.up() < (REAL_TYPE)+0.)
+ {
+ _lo = mul_dn(_aa.up(), _aa.up());
+ _up = mul_up(_aa.lo(), _aa.lo());
+ }
+ else
+ if (_aa.lo() > (REAL_TYPE)+0.)
+ {
+ _lo = mul_dn(_aa.lo(), _aa.lo());
+ _up = mul_up(_aa.up(), _aa.up());
+ }
+ else
+ {
+ if (-_aa.lo() > +_aa.up())
+ {
+ _lo = (REAL_TYPE)+0.;
+ _up = mul_up(_aa.lo(), _aa.lo());
+ }
+ else
+ {
+ _lo = (REAL_TYPE)+0.;
+ _up = mul_up(_aa.up(), _aa.up());
+ }
+ }
+
+ return ( ia_flt(_lo, _up) ) ;
+ }
+
+# undef REAL_TYPE
+# undef INDX_TYPE
+
+
+// }
+
+# endif//__IA_FLOAT__
+
+
+
diff --git a/external/jigsaw/src/libcpp/expansion/mp_basic.hpp b/external/jigsaw/src/libcpp/expansion/mp_basic.hpp
new file mode 100644
index 0000000..684d3cb
--- /dev/null
+++ b/external/jigsaw/src/libcpp/expansion/mp_basic.hpp
@@ -0,0 +1,660 @@
+
+ /*
+ --------------------------------------------------------
+ * MPFLOAT: multi-precision floating-point arithmetic.
+ --------------------------------------------------------
+ *
+ * These are the low-level multi-precision kernels ---
+ * computing elementary operations on "expansions" of
+ * floating-point numbers such that rounding error is
+ * eliminated. See Shewchuk for more detail:
+ *
+ * J. R. Shewchuk (1997): Adaptive Precision Floating-
+ * Point Arithmetic & Fast Robust Geometric Predicates
+ * Discrete & Computational Geometry, 18, pp. 305-363.
+ *
+ * This header is adapted from Shewchuk's original C89
+ * source (predicates.c).
+ *
+ * Related "clipped" operations for "double-double"
+ * arithmetic are also included. Here expansion length
+ * is capped at 2, with subsequent bits truncated:
+ *
+ * M. Joldes, J-M. Muller, V. Popescu (2017): Tight &
+ * rigourous error bounds for basic building blocks of
+ * double-word arithmetic. ACM Transactions on
+ * Mathematical Software, ACM, 44 (2), pp. 1-27.
+ *
+ * Y. Hida, X. Li, and D. Bailey (2000): Quad-double
+ * arithmetic: Algorithms, implementation, and
+ * application. In the 15th IEEE Symposium on Computer
+ * Arithmetic, pp. 155-162.
+ *
+ --------------------------------------------------------
+ *
+ * This program may be freely redistributed under the
+ * condition that the copyright notices (including this
+ * entire header) are not removed, and no compensation
+ * is received through use of the software. Private,
+ * research, and institutional use is free. You may
+ * distribute modified versions of this code UNDER THE
+ * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE
+ * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE
+ * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE
+ * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR
+ * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution
+ * of this code as part of a commercial system is
+ * permissible ONLY BY DIRECT ARRANGEMENT WITH THE
+ * AUTHOR. (If you are not directly supplying this
+ * code to a customer, and you are instead telling them
+ * how they can obtain it for free, then you are not
+ * required to make any arrangement with me.)
+ *
+ * Disclaimer: Neither I nor: Columbia University, The
+ * Massachusetts Institute of Technology, The
+ * University of Sydney, nor The National Aeronautics
+ * and Space Administration warrant this code in any
+ * way whatsoever. This code is provided "as-is" to be
+ * used at your own risk.
+ *
+ --------------------------------------------------------
+ *
+ * Last updated: 16 April, 2020
+ *
+ * Copyright 2020--
+ * Darren Engwirda
+ * d.engwirda@gmail.com
+ * https://github.com/dengwirda/
+ *
+ --------------------------------------------------------
+ */
+
+# pragma once
+
+# ifndef __MP_BASIC__
+# define __MP_BASIC__
+
+ namespace mp_float {
+
+# define REAL_TYPE mp_float::real_type
+# define INDX_TYPE mp_float::indx_type
+
+ /*------------------------ have hardware FMA support? */
+
+# if defined(FP_FAST_FMA)
+ bool constexpr _has_fma =
+ std::is_same::value;
+# elif defined(FP_FAST_FMAF)
+ bool constexpr _has_fma =
+ std::is_same::value;
+# else
+ bool constexpr _has_fma = false;
+# endif
+
+ /*
+ --------------------------------------------------------
+ * multi-precision initialisation, a'la shewchuk
+ --------------------------------------------------------
+ */
+
+ REAL_TYPE _splitter;
+ REAL_TYPE _epsilon ;
+
+ __normal_call void exactinit (
+ )
+ {
+ /*-------------- find machine eps, etc, a'la shewchuk */
+ INDX_TYPE _alternate = +1 ;
+ REAL_TYPE _lastcheck ;
+ REAL_TYPE _halve = +0.5;
+ REAL_TYPE _check = +1.0;
+
+ /*-------------- find eps: bisect until 1. + eps ~ 1. */
+
+ _epsilon = _splitter = +1.00 ;
+
+ do {
+ _lastcheck = _check;
+ _epsilon *= _halve;
+
+ if (_alternate)
+ _splitter *= +2.00 ;
+
+ _alternate = !_alternate ;
+
+ _check = 1.00 + _epsilon ;
+ }
+ while (_check != +1.00 &&
+ _check != _lastcheck) ;
+
+ _splitter += 1.00 ;
+ }
+
+ /*
+ --------------------------------------------------------
+ * multi-precision "add" routines, a'la shewchuk
+ --------------------------------------------------------
+ */
+
+ __inline_call void one_one_add_fast (
+ REAL_TYPE _aa, REAL_TYPE _bb,
+ REAL_TYPE &_x1, REAL_TYPE &_x0
+ )
+ {
+ REAL_TYPE _bvirt;
+ _x1 = _aa + _bb;
+ _bvirt = _x1 - _aa;
+ _x0 = _bb - _bvirt;
+ }
+
+ __inline_call void one_one_add_full (
+ REAL_TYPE _aa, REAL_TYPE _bb,
+ REAL_TYPE &_x1, REAL_TYPE &_x0
+ )
+ {
+ REAL_TYPE _bvirt, _avirt;
+ _x1 = _aa + _bb;
+ _bvirt = _x1 - _aa;
+ _avirt = _x1 - _bvirt;
+
+ REAL_TYPE _bround, _around;
+ _bround = _bb - _bvirt;
+ _around = _aa - _avirt;
+ _x0 = _around + _bround;
+ }
+
+ __inline_call void two_one_add_full (
+ REAL_TYPE _a1, REAL_TYPE _a0,
+ REAL_TYPE _bb,
+ REAL_TYPE &_x2, REAL_TYPE &_x1,
+ REAL_TYPE &_x0
+ )
+ {
+ REAL_TYPE _tt;
+ one_one_add_full(_a0, _bb, _tt, _x0
+ ) ;
+ one_one_add_full(_a1, _tt, _x2, _x1
+ ) ;
+ }
+
+ __inline_call void two_one_add_clip ( // dd_flt
+ REAL_TYPE _a1, REAL_TYPE _a0,
+ REAL_TYPE _bb,
+ REAL_TYPE &_x1, REAL_TYPE &_x0
+ )
+ {
+ REAL_TYPE _t0, _t1 ;
+ one_one_add_full(_a1, _bb, _t1, _t0
+ ) ;
+
+ _t0 = _t0 + _a0 ;
+
+ one_one_add_fast(_t1, _t0, _x1, _x0
+ ) ;
+ }
+
+ __inline_call void two_two_add_full (
+ REAL_TYPE _a1, REAL_TYPE _a0,
+ REAL_TYPE _b1, REAL_TYPE _b0,
+ REAL_TYPE &_x3, REAL_TYPE &_x2,
+ REAL_TYPE &_x1, REAL_TYPE &_x0
+ )
+ {
+ REAL_TYPE _t1, _t0 ;
+ two_one_add_full(_a1, _a0, _b0, _t1,
+ _t0, _x0
+ ) ;
+ two_one_add_full(_t1, _t0, _b1, _x3,
+ _x2, _x1
+ ) ;
+ }
+
+ __inline_call void two_two_add_clip ( // dd_flt
+ REAL_TYPE _a1, REAL_TYPE _a0,
+ REAL_TYPE _b1, REAL_TYPE _b0,
+ REAL_TYPE &_x1, REAL_TYPE &_x0
+ )
+ {
+ REAL_TYPE _t1, _t0 ;
+ REAL_TYPE _s1, _s0 ;
+ REAL_TYPE _w1, _w0 ;
+ one_one_add_full(_a1, _b1, _s1, _s0
+ ) ;
+ one_one_add_full(_a0, _b0, _t1, _t0
+ ) ;
+
+ _s0 = _s0 + _t1 ;
+
+ one_one_add_fast(_s1, _s0, _w1, _w0
+ ) ;
+
+ _w0 = _w0 + _t0 ;
+
+ one_one_add_fast(_w1, _w0, _x1, _x0
+ ) ;
+ }
+
+ /*
+ --------------------------------------------------------
+ * multi-precision "sub" routines, a'la shewchuk
+ --------------------------------------------------------
+ */
+
+ __inline_call void one_one_sub_fast (
+ REAL_TYPE _aa, REAL_TYPE _bb,
+ REAL_TYPE &_x1, REAL_TYPE &_x0
+ )
+ {
+ REAL_TYPE _bvirt;
+ _x1 = _aa - _bb;
+ _bvirt = _aa - _x1;
+ _x0 = _bvirt - _bb;
+ }
+
+ __inline_call void one_one_sub_full (
+ REAL_TYPE _aa, REAL_TYPE _bb,
+ REAL_TYPE &_x1, REAL_TYPE &_x0
+ )
+ {
+ REAL_TYPE _bvirt, _avirt;
+ _x1 = _aa - _bb;
+ _bvirt = _aa - _x1;
+ _avirt = _x1 + _bvirt;
+
+ REAL_TYPE _bround, _around;
+ _bround = _bvirt - _bb;
+ _around = _aa - _avirt;
+ _x0 = _around + _bround;
+ }
+
+ __inline_call void two_one_sub_full (
+ REAL_TYPE _a1, REAL_TYPE _a0,
+ REAL_TYPE _bb,
+ REAL_TYPE &_x2, REAL_TYPE &_x1,
+ REAL_TYPE &_x0
+ )
+ {
+ REAL_TYPE _tt;
+ one_one_sub_full(_a0, _bb, _tt, _x0
+ ) ;
+ one_one_add_full(_a1, _tt, _x2, _x1
+ ) ;
+ }
+
+ __inline_call void two_one_sub_clip ( // dd_flt
+ REAL_TYPE _a1, REAL_TYPE _a0,
+ REAL_TYPE _bb,
+ REAL_TYPE &_x1, REAL_TYPE &_x0
+ )
+ {
+ REAL_TYPE _t0, _t1 ;
+ one_one_sub_full(_a1, _bb, _t1, _t0
+ ) ;
+
+ _t0 = _t0 + _a0 ;
+
+ one_one_add_fast(_t1, _t0, _x1, _x0
+ ) ;
+ }
+
+ __inline_call void two_two_sub_full (
+ REAL_TYPE _a1, REAL_TYPE _a0,
+ REAL_TYPE _b1, REAL_TYPE _b0,
+ REAL_TYPE &_x3, REAL_TYPE &_x2,
+ REAL_TYPE &_x1, REAL_TYPE &_x0
+ )
+ {
+ REAL_TYPE _t1, _t0 ;
+ two_one_sub_full(_a1, _a0, _b0, _t1,
+ _t0, _x0
+ ) ;
+ two_one_sub_full(_t1, _t0, _b1, _x3,
+ _x2, _x1
+ ) ;
+ }
+
+ __inline_call void two_two_sub_clip ( // dd_flt
+ REAL_TYPE _a1, REAL_TYPE _a0,
+ REAL_TYPE _b1, REAL_TYPE _b0,
+ REAL_TYPE &_x1, REAL_TYPE &_x0
+ )
+ {
+ REAL_TYPE _s0, _s1 ;
+ REAL_TYPE _t0, _t1 ;
+ REAL_TYPE _w0, _w1 ;
+ one_one_sub_full(_a1, _b1, _s1, _s0
+ ) ;
+ one_one_sub_full(_a0, _b0, _t1, _t0
+ ) ;
+
+ _s0 = _s0 + _t1 ;
+
+ one_one_add_fast(_s1, _s0, _w1, _w0
+ ) ;
+
+ _w0 = _w0 + _t0 ;
+
+ one_one_add_fast(_w1, _w0, _x1, _x0
+ ) ;
+ }
+
+ /*
+ --------------------------------------------------------
+ * multi-precision "mul" routines, a'la shewchuk
+ --------------------------------------------------------
+ */
+
+ __inline_call void one_split (
+ REAL_TYPE _aa,
+ REAL_TYPE &_x1, REAL_TYPE &_x0
+ )
+ {
+ REAL_TYPE _cc, _ab ;
+ _cc = _aa * _splitter;
+ _ab = _cc - _aa;
+ _x1 = _cc - _ab;
+ _x0 = _aa - _x1;
+ }
+
+ __inline_call void one_one_mul_full (
+ REAL_TYPE _aa, REAL_TYPE _bb,
+ REAL_TYPE &_x1, REAL_TYPE &_x0
+ )
+ {
+ if constexpr (_has_fma)
+ {
+ _x1 = _aa * _bb;
+ _x0 = fma(_aa, _bb, -_x1);
+ }
+ else // use fpu
+ {
+ REAL_TYPE _ah, _al, _bh, _bl;
+ _x1 = _aa * _bb;
+ one_split (_aa, _ah, _al);
+ one_split (_bb, _bh, _bl);
+
+ REAL_TYPE _err1, _err2, _err3;
+ _err1 = _x1 - (_ah * _bh);
+ _err2 = _err1 - (_al * _bh);
+ _err3 = _err2 - (_ah * _bl);
+ _x0 = (_al * _bl) - _err3;
+ }
+ }
+
+ __inline_call void one_one_mul_full (
+ REAL_TYPE _aa,
+ REAL_TYPE _bb, REAL_TYPE _bh,
+ REAL_TYPE _bl,
+ REAL_TYPE &_x1, REAL_TYPE &_x0
+ )
+ {
+ if constexpr (_has_fma)
+ {
+ _x1 = _aa * _bb;
+ _x0 = fma(_aa, _bb, -_x1);
+ }
+ else // use fpu
+ {
+ REAL_TYPE _ah, _al;
+ _x1 = _aa * _bb;
+ one_split (_aa, _ah, _al);
+
+ REAL_TYPE _err1, _err2, _err3;
+ _err1 = _x1 - (_ah * _bh);
+ _err2 = _err1 - (_al * _bh);
+ _err3 = _err2 - (_ah * _bl);
+ _x0 = (_al * _bl) - _err3;
+ }
+ }
+
+ __inline_call void one_one_mul_full (
+ REAL_TYPE _aa, REAL_TYPE _ah,
+ REAL_TYPE _al,
+ REAL_TYPE _bb, REAL_TYPE _bh,
+ REAL_TYPE _bl,
+ REAL_TYPE &_x1, REAL_TYPE &_x0
+ )
+ {
+ if constexpr (_has_fma)
+ {
+ _x1 = _aa * _bb;
+ _x0 = fma(_aa, _bb, -_x1);
+ }
+ else // use fpu
+ {
+ _x1 = _aa * _bb;
+
+ REAL_TYPE _err1, _err2, _err3;
+ _err1 = _x1 - (_ah * _bh);
+ _err2 = _err1 - (_al * _bh);
+ _err3 = _err2 - (_ah * _bl);
+ _x0 = (_al * _bl) - _err3;
+ }
+ }
+
+ __inline_call void one_one_sqr_full (
+ REAL_TYPE _aa,
+ REAL_TYPE &_x1, REAL_TYPE &_x0
+ )
+ {
+ if constexpr (_has_fma)
+ {
+ _x1 = _aa * _aa;
+ _x0 = fma(_aa, _aa, -_x1);
+ }
+ else // use fpu
+ {
+ REAL_TYPE _ah, _al;
+ _x1 = _aa * _aa;
+ one_split (_aa, _ah, _al);
+
+ REAL_TYPE _err1, _err3;
+ _err1 = _x1 - (_ah * _ah);
+ _err3 = _err1 - ((_ah + _ah) * _al);
+ _x0 = (_al * _al) - _err3;
+ }
+ }
+
+ __inline_call void one_one_sqr_full (
+ REAL_TYPE _aa, REAL_TYPE _ah,
+ REAL_TYPE _al,
+ REAL_TYPE &_x1, REAL_TYPE &_x0
+ )
+ {
+ if constexpr (_has_fma)
+ {
+ _x1 = _aa * _aa;
+ _x0 = fma(_aa, _aa, -_x1);
+ }
+ else // use fpu
+ {
+ _x1 = _aa * _aa;
+
+ REAL_TYPE _err1, _err3;
+ _err1 = _x1 - (_ah * _ah);
+ _err3 = _err1 - ((_ah + _ah) * _al);
+ _x0 = (_al * _al) - _err3;
+ }
+ }
+
+ __inline_call void two_one_mul_full (
+ REAL_TYPE _a1, REAL_TYPE _a0,
+ REAL_TYPE _bb,
+ REAL_TYPE &_x3, REAL_TYPE &_x2,
+ REAL_TYPE &_x1, REAL_TYPE &_x0
+ )
+ {
+ if constexpr (_has_fma)
+ {
+ REAL_TYPE _t0, _t1, _t2, _t3 ;
+ one_one_mul_full(_a0, _bb, _t2, _x0
+ ) ;
+ one_one_mul_full(_a1, _bb, _t1, _t0
+ ) ;
+
+ one_one_add_full(_t2, _t0, _t3, _x1
+ ) ;
+ one_one_add_fast(_t1, _t3, _x3, _x2
+ ) ;
+ }
+ else // use fpu
+ {
+ REAL_TYPE _bh, _bl;
+ REAL_TYPE _t0, _t1, _t2, _t3 ;
+ one_split(_bb, _bh, _bl) ;
+
+ one_one_mul_full(_a0, _bb, _bh, _bl,
+ _t2, _x0
+ ) ;
+ one_one_mul_full(_a1, _bb, _bh, _bl,
+ _t1, _t0
+ ) ;
+
+ one_one_add_full(_t2, _t0, _t3, _x1
+ ) ;
+ one_one_add_fast(_t1, _t3, _x3, _x2
+ ) ;
+ }
+ }
+
+ __inline_call void two_one_mul_clip ( // dd_flt
+ REAL_TYPE _a1, REAL_TYPE _a0,
+ REAL_TYPE _bb,
+ REAL_TYPE &_x1, REAL_TYPE &_x0
+ )
+ {
+ if constexpr (_has_fma)
+ {
+ REAL_TYPE _t0, _t1;
+ one_one_mul_full(_a1, _bb, _t1, _t0
+ ) ;
+
+ _t0 = fma(_a0, _bb, _t0);
+
+ one_one_add_fast(_t1, _t0, _x1, _x0
+ ) ;
+ }
+ else // use fpu
+ {
+ REAL_TYPE _t0, _t1, _ss ;
+ one_one_mul_full(_a1, _bb, _t1, _t0
+ ) ;
+
+ _ss = _a0 * _bb ;
+ _t0 = _t0 + _ss ;
+
+ one_one_add_fast(_t1, _t0, _x1, _x0
+ ) ;
+ }
+ }
+
+ __inline_call void two_two_mul_clip ( // dd_flt
+ REAL_TYPE _a1, REAL_TYPE _a0,
+ REAL_TYPE _b1, REAL_TYPE _b0,
+ REAL_TYPE &_x1, REAL_TYPE &_x0
+ )
+ {
+ if constexpr (_has_fma)
+ {
+ REAL_TYPE _t0, _t1, _ss;
+ one_one_mul_full(_a1, _b1, _t1, _t0
+ ) ;
+
+ _ss = _a0 * _b0 ;
+ _ss = fma(_a1, _b0, _ss);
+ _ss = fma(_a0, _b0, _ss);
+
+ _t0 = _t0 + _ss ;
+
+ one_one_add_fast(_t1, _t0, _x1, _x0
+ ) ;
+ }
+ else
+ {
+ REAL_TYPE _t0, _t1;
+ REAL_TYPE _ss, _s1, _s2, _s3;
+ one_one_mul_full(_a1, _b1, _t1, _t0
+ ) ;
+
+ _s1 = _a0 * _b0 ;
+ _s2 = _a1 * _b0 ;
+ _s3 = _a0 * _b1 ;
+ _ss = _s1 + _s2 + _s3 ;
+
+ _t0 = _t0 + _ss ;
+
+ one_one_add_fast(_t1, _t0, _x1, _x0
+ ) ;
+ }
+ }
+
+ __inline_call void two_one_div_clip ( // dd_flt
+ REAL_TYPE _a1, REAL_TYPE _a0,
+ REAL_TYPE _bb,
+ REAL_TYPE &_x1, REAL_TYPE &_x0
+ )
+ {
+ REAL_TYPE _t0, _t1, _p1, _p0, _dd;
+ _t1 = _a1 / _bb;
+
+ one_one_mul_full(_t1, _bb, _p1, _p0
+ ) ;
+
+ _dd = _a1 - _p1;
+ _dd = _dd - _p0;
+ _dd = _dd + _a0;
+
+ _t0 = _dd / _bb;
+
+ one_one_add_fast(_t1, _t0, _x1, _x0
+ ) ;
+ }
+
+ __inline_call void two_two_div_clip ( // dd_flt
+ REAL_TYPE _a1, REAL_TYPE _a0,
+ REAL_TYPE _b1, REAL_TYPE _b0,
+ REAL_TYPE &_x1, REAL_TYPE &_x0
+ )
+ {
+ REAL_TYPE _t0, _t1, _ee;
+ _t1 = _a1 / _b1 ;
+
+ REAL_TYPE _r0, _r1 ;
+ REAL_TYPE _w0, _w1 ;
+ two_one_mul_clip(_b1, _b0, _t1,
+ _r1, _r0 // rr = bb * t1
+ ) ;
+ two_two_sub_clip(_a1, _a0, _r1, _r0,
+ _w1, _w0 // ww = aa - rr
+ ) ;
+
+ _t0 = _w1 / _b1 ;
+
+ REAL_TYPE _u0, _u1 ;
+ two_one_mul_clip(_b1, _b0, _t0,
+ _r1, _r0 // rr = bb * t0
+ ) ;
+ two_two_sub_clip(_w1, _w0, _r1, _r0,
+ _u1, _u0 // uu = ww - rr
+ ) ;
+
+ _ee = _u1 / _b1 ;
+
+ REAL_TYPE _q0, _q1 ; // t1 + t0 + ee
+ one_one_add_fast(_t1, _t0, _q1, _q0
+ ) ;
+ two_one_add_clip(_q1, _q0, _ee,
+ _x1, _x0
+ ) ;
+ }
+
+# undef REAL_TYPE
+# undef INDX_TYPE
+
+
+ }
+
+# endif//__MP_BASIC__
+
+
+
diff --git a/external/jigsaw/src/libcpp/expansion/mp_float.hpp b/external/jigsaw/src/libcpp/expansion/mp_float.hpp
new file mode 100644
index 0000000..e04fb98
--- /dev/null
+++ b/external/jigsaw/src/libcpp/expansion/mp_float.hpp
@@ -0,0 +1,1023 @@
+
+ /*
+ --------------------------------------------------------
+ * MPFLOAT: multi-precision floating-point arithmetic.
+ --------------------------------------------------------
+ *
+ * These are the high-level multi-precision objects ---
+ * computing elementary operations on "expansions" of
+ * floating-point numbers such that rounding error is
+ * eliminated. See Shewchuk for more detail:
+ *
+ * J. R. Shewchuk (1997), Adaptive Precision Floating-
+ * Point Arithmetic & Fast Robust Geometric Predicates
+ * Discrete & Computational Geometry, 18, pp. 305-363.
+ *
+ * This header provides a stack allocated, compile-time
+ * "expansion" object that wraps Shewchuk's operators,
+ * inspired by similar run-time constructs, e.g. Lévy:
+ *
+ * B. Lévy (2016), Robustness and efficiency of
+ * geometric programs: The Predicate Construction Kit
+ * (PCK). Computer-Aided Design, 72, pp. 03-12.
+ *
+ * Here, various compile-time techniques and template
+ * patterns are used to build a "zero-overhead"
+ * framework that doesn't require run-time stack/heap
+ * manipulation or pointer indirection.
+ *
+ --------------------------------------------------------
+ *
+ * This program may be freely redistributed under the
+ * condition that the copyright notices (including this
+ * entire header) are not removed, and no compensation
+ * is received through use of the software. Private,
+ * research, and institutional use is free. You may
+ * distribute modified versions of this code UNDER THE
+ * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE
+ * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE
+ * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE
+ * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR
+ * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution
+ * of this code as part of a commercial system is
+ * permissible ONLY BY DIRECT ARRANGEMENT WITH THE
+ * AUTHOR. (If you are not directly supplying this
+ * code to a customer, and you are instead telling them
+ * how they can obtain it for free, then you are not
+ * required to make any arrangement with me.)
+ *
+ * Disclaimer: Neither I nor: Columbia University, The
+ * Massachusetts Institute of Technology, The
+ * University of Sydney, nor The National Aeronautics
+ * and Space Administration warrant this code in any
+ * way whatsoever. This code is provided "as-is" to be
+ * used at your own risk.
+ *
+ --------------------------------------------------------
+ *
+ * Last updated: 30 April, 2020
+ *
+ * Copyright 2020--
+ * Darren Engwirda
+ * d.engwirda@gmail.com
+ * https://github.com/dengwirda/
+ *
+ --------------------------------------------------------
+ */
+
+# pragma once
+
+# ifndef __MP_FLOAT__
+# define __MP_FLOAT__
+
+# include "mp_basic.hpp"
+
+ namespace mp_float {
+
+ /*
+ --------------------------------------------------------
+ * EXPANSION: multi-precision floating-point numbers.
+ --------------------------------------------------------
+ */
+
+# define REAL_TYPE mp_float::real_type
+# define INDX_TYPE mp_float::indx_type
+
+ template <
+ size_t N = +1 // max. floats in expansion
+ >
+ class expansion
+ {
+/*-------------- a compile-time multi-precision expansion */
+ public :
+ typedef REAL_TYPE real_type;
+ typedef INDX_TYPE indx_type;
+
+ indx_type static constexpr _size = N ;
+
+ real_type _xdat [ N ] ;
+ indx_type _xlen = 0 ;
+
+ public :
+/*------------------------------ initialising constructor */
+ __inline_call expansion ()
+ { // just default...
+ }
+ __inline_call expansion (
+ REAL_TYPE _xx
+ )
+ { this->push(_xx) ;
+ }
+
+/*------------------------------ append bits to expansion */
+ __inline_call void push (
+ real_type _xx
+ )
+ { this->_xdat[this->_xlen++] = _xx ;
+ }
+
+/*------------------------------ query the expansion size */
+ __inline_call indx_type count (
+ ) const
+ { return this->_xlen ;
+ }
+ __inline_call indx_type alloc (
+ ) const
+ { return this->_size ;
+ }
+ __inline_call bool empty (
+ ) const
+ { return this->_xlen == +0 ;
+ }
+
+/*------------------------------ access to expansion bits */
+ __inline_call real_type & operator[] (
+ indx_type _ii
+ )
+ {
+ assert ( _ii < this->_size &&
+ "expansion: index out of bounds") ;
+
+ return ( this->_xdat[_ii] ) ;
+ }
+
+ __inline_call real_type const& operator[] (
+ indx_type _ii
+ ) const
+ {
+ assert ( _ii<= this->_size &&
+ "expansion: index out of bounds") ;
+
+ return ( this->_xdat[_ii] ) ;
+ }
+
+ public :
+/*------------------------------ helper: init. from a + b */
+ __inline_call void from_add (
+ real_type _aa, real_type _bb
+ )
+ {
+ static_assert( _size >= 2,
+ "from-add: insufficient alloc.!") ;
+
+ this->_xlen = +2 ;
+
+ one_one_add_full(_aa, _bb,
+ this->_xdat[1],
+ this->_xdat[0]) ;
+ }
+
+/*------------------------------ helper: init. from a - b */
+ __inline_call void from_sub (
+ real_type _aa, real_type _bb
+ )
+ {
+ static_assert( _size >= 2,
+ "from-sub: insufficient alloc.!") ;
+
+ this->_xlen = +2 ;
+
+ one_one_sub_full(_aa, _bb,
+ this->_xdat[1],
+ this->_xdat[0]) ;
+ }
+
+/*------------------------------ helper: init. from a * a */
+ __inline_call void from_sqr (
+ real_type _aa
+ )
+ {
+ static_assert( _size >= 2,
+ "from-sqr: insufficient alloc.!") ;
+
+ this->_xlen = +2 ;
+
+ one_one_sqr_full(_aa,
+ this->_xdat[1],
+ this->_xdat[0]) ;
+ }
+
+/*------------------------------ helper: init. from a * b */
+ __inline_call void from_mul (
+ real_type _aa, real_type _bb
+ )
+ {
+ static_assert( _size >= 2,
+ "from-mul: insufficient alloc.!") ;
+
+ this->_xlen = +2 ;
+
+ one_one_mul_full(_aa, _bb,
+ this->_xdat[1],
+ this->_xdat[0]) ;
+ }
+
+ } ;
+
+ /*
+ --------------------------------------------------------
+ * shortcut utilities to construct basic expansions
+ --------------------------------------------------------
+ */
+
+ __inline_call
+ expansion<2> expansion_from_add (
+ REAL_TYPE _aa, REAL_TYPE _bb
+ )
+ {
+ expansion<2> _ex; _ex.from_add(_aa, _bb) ;
+ return _ex;
+ }
+
+ __inline_call
+ expansion<2> expansion_from_sub (
+ REAL_TYPE _aa, REAL_TYPE _bb
+ )
+ {
+ expansion<2> _ex; _ex.from_sub(_aa, _bb) ;
+ return _ex;
+ }
+
+ __inline_call
+ expansion<2> expansion_from_sqr (
+ REAL_TYPE _aa
+ )
+ {
+ expansion<2> _ex; _ex.from_sqr(_aa) ;
+ return _ex;
+ }
+
+ __inline_call
+ expansion<2> expansion_from_mul (
+ REAL_TYPE _aa, REAL_TYPE _bb
+ )
+ {
+ expansion<2> _ex; _ex.from_mul(_aa, _bb) ;
+ return _ex;
+ }
+
+ /*
+ --------------------------------------------------------
+ * alloc. requirements for operations on expansions
+ --------------------------------------------------------
+ */
+
+ __inline_call INDX_TYPE constexpr add_alloc (
+ INDX_TYPE _na,
+ INDX_TYPE _nb
+ )
+ { return _na + _nb ;
+ }
+
+ __inline_call INDX_TYPE constexpr sub_alloc (
+ INDX_TYPE _na,
+ INDX_TYPE _nb
+ )
+ { return _na + _nb ;
+ }
+
+ __inline_call INDX_TYPE constexpr mul_alloc (
+ INDX_TYPE _na,
+ INDX_TYPE _nb
+ )
+ { return _na * _nb * +2 ;
+ }
+
+ /*
+ --------------------------------------------------------
+ * add two multi-precision expansion, a'la shewchuk
+ --------------------------------------------------------
+ */
+
+ template <
+ size_t NE, size_t NF, size_t NH
+ >
+ __normal_call void fast_expansion_add_zeroelim (
+ expansion const& _ee ,
+ expansion const& _ff ,
+ expansion & _hh
+ ) // adapted from: fast_expansion_sum_zeroelim
+ {
+ REAL_TYPE _qq, _qn, _hx;
+ REAL_TYPE _ex = _ee [0];
+ REAL_TYPE _fx = _ff [0];
+ INDX_TYPE _ei = +0, _fi = +0 ;
+
+ _hh._xlen = 0;
+
+ if((_fx > _ex) == (_fx > -_ex))
+ {
+ _qq = _ex;
+ _ex = _ee[++_ei];
+ }
+ else
+ {
+ _qq = _fx;
+ _fx = _ff[++_fi];
+ }
+
+ if((_ei < _ee._xlen) && (_fi < _ff._xlen))
+ {
+ if((_fx > _ex) == (_fx > -_ex))
+ {
+ one_one_add_fast(
+ _ex, _qq, _qn, _hx);
+ _qq = _qn;
+ _ex = _ee[++_ei];
+ }
+ else
+ {
+ one_one_add_fast(
+ _fx, _qq, _qn, _hx);
+ _qq = _qn;
+ _fx = _ff[++_fi];
+ }
+ if (_hx != +0.0) _hh.push (_hx) ;
+
+ while ((_ei < _ee._xlen) &&
+ (_fi < _ff._xlen) )
+ {
+ if((_fx > _ex) == (_fx > -_ex))
+ {
+ one_one_add_full(
+ _qq, _ex, _qn, _hx);
+ _qq = _qn;
+ _ex = _ee[++_ei] ;
+ }
+ else
+ {
+ one_one_add_full(
+ _qq, _fx, _qn, _hx);
+ _qq = _qn;
+ _fx = _ff[++_fi] ;
+ }
+ if (_hx != +0.0) _hh.push (_hx) ;
+ }
+ }
+
+ while (_ei < _ee._xlen)
+ {
+ one_one_add_full(_qq, _ex, _qn, _hx);
+ _qq = _qn;
+ _ex = _ee[++_ei];
+ if (_hx != +0.0) _hh.push (_hx) ;
+ }
+
+ while (_fi < _ff._xlen)
+ {
+ one_one_add_full(_qq, _fx, _qn, _hx);
+ _qq = _qn;
+ _fx = _ff[++_fi];
+ if (_hx != +0.0) _hh.push (_hx) ;
+ }
+
+ if((_qq != +0.0) || (_hh._xlen == +0))
+ {
+ _hh.push(_qq) ;
+ }
+ }
+
+ template <
+ size_t NA, size_t NB, size_t NC
+ >
+ __inline_call void expansion_add (
+ expansion const& _aa ,
+ expansion const& _bb ,
+ expansion & _cc
+ ) // adapted from: fast_expansion_sum_zeroelim
+ {
+ static_assert ( NC >= NA + NB ,
+ "expansion-add: insufficient alloc.!");
+
+ if (_aa._xlen == +1 && // 1-to-1 unrolling
+ _bb._xlen == +1)
+ {
+ REAL_TYPE _t1, _t0;
+
+ _cc._xlen = +0 ;
+
+ one_one_add_full(
+ _aa[0], _bb[0], _t1, _t0);
+
+ if (_t0 != +0.0) _cc.push (_t0) ;
+ if (_t1 != +0.0) _cc.push (_t1) ;
+ if (_cc.empty()) _cc.push (+0.) ;
+ }
+ else
+ if (_aa._xlen == +2 && // 2-to-1 unrolling
+ _bb._xlen == +1)
+ {
+ REAL_TYPE _t2, _t1, _t0;
+
+ _cc._xlen = +0 ;
+
+ two_one_add_full(
+ _aa[1], _aa[0], _bb[0], _t2, _t1, _t0);
+
+ if (_t0 != +0.0) _cc.push (_t0) ;
+ if (_t1 != +0.0) _cc.push (_t1) ;
+ if (_t2 != +0.0) _cc.push (_t2) ;
+ if (_cc.empty()) _cc.push (+0.) ;
+ }
+ else
+ if (_aa._xlen == +1 && // 1-to-2 unrolling
+ _bb._xlen == +2)
+ {
+ REAL_TYPE _t2, _t1, _t0;
+
+ _cc._xlen = +0 ;
+
+ two_one_add_full(
+ _bb[1], _bb[0], _aa[0], _t2, _t1, _t0);
+
+ if (_t0 != +0.0) _cc.push (_t0) ;
+ if (_t1 != +0.0) _cc.push (_t1) ;
+ if (_t2 != +0.0) _cc.push (_t2) ;
+ if (_cc.empty()) _cc.push (+0.) ;
+ }
+ else
+ if (_aa._xlen == +2 && // 2-to-2 unrolling
+ _bb._xlen == +2)
+ {
+ REAL_TYPE _t3, _t2, _t1, _t0;
+
+ _cc._xlen = +0 ;
+
+ two_two_add_full(
+ _aa[1], _aa[0],
+ _bb[1], _bb[0], _t3, _t2, _t1, _t0);
+
+ if (_t0 != +0.0) _cc.push (_t0) ;
+ if (_t1 != +0.0) _cc.push (_t1) ;
+ if (_t2 != +0.0) _cc.push (_t2) ;
+ if (_t3 != +0.0) _cc.push (_t3) ;
+ if (_cc.empty()) _cc.push (+0.) ;
+ }
+ else // the n-to-m loops
+ {
+ fast_expansion_add_zeroelim(_aa, _bb, _cc);
+ }
+ }
+
+ /*
+ --------------------------------------------------------
+ * sub two multi-precision expansion, a'la shewchuk
+ --------------------------------------------------------
+ */
+
+ template <
+ size_t NE, size_t NF, size_t NH
+ >
+ __normal_call void fast_expansion_sub_zeroelim (
+ expansion const& _ee ,
+ expansion const& _ff ,
+ expansion & _hh
+ ) // adapted from: fast_expansion_diff_zeroelim
+ {
+ REAL_TYPE _qq, _qn, _hx;
+ REAL_TYPE _ex = _ee [0];
+ REAL_TYPE _fx =-_ff [0];
+ INDX_TYPE _ei = +0, _fi = +0 ;
+
+ _hh._xlen = 0;
+
+ if((_fx > _ex) == (_fx > -_ex))
+ {
+ _qq = _ex;
+ _ex = _ee[++_ei];
+ }
+ else
+ {
+ _qq = _fx;
+ _fx =-_ff[++_fi];
+ }
+
+ if((_ei < _ee._xlen) && (_fi < _ff._xlen))
+ {
+ if((_fx > _ex) == (_fx > -_ex))
+ {
+ one_one_add_fast(
+ _ex, _qq, _qn, _hx);
+ _qq = _qn;
+ _ex = _ee[++_ei];
+ }
+ else
+ {
+ one_one_add_fast(
+ _fx, _qq, _qn, _hx);
+ _qq = _qn;
+ _fx =-_ff[++_fi];
+ }
+ if (_hx != +0.0) _hh.push (_hx) ;
+
+ while ((_ei < _ee._xlen) &&
+ (_fi < _ff._xlen) )
+ {
+ if((_fx > _ex) == (_fx > -_ex))
+ {
+ one_one_add_full(
+ _qq, _ex, _qn, _hx);
+ _qq = _qn;
+ _ex = _ee[++_ei] ;
+ }
+ else
+ {
+ one_one_add_full(
+ _qq, _fx, _qn, _hx);
+ _qq = _qn;
+ _fx =-_ff[++_fi] ;
+ }
+ if (_hx != +0.0) _hh.push (_hx) ;
+ }
+ }
+
+ while (_ei < _ee._xlen)
+ {
+ one_one_add_full(_qq, _ex, _qn, _hx);
+ _qq = _qn;
+ _ex = _ee[++_ei];
+ if (_hx != +0.0) _hh.push (_hx) ;
+ }
+
+ while (_fi < _ff._xlen)
+ {
+ one_one_add_full(_qq, _fx, _qn, _hx);
+ _qq = _qn;
+ _fx =-_ff[++_fi];
+ if (_hx != +0.0) _hh.push (_hx) ;
+ }
+
+ if((_qq != +0.0) || (_hh._xlen == +0))
+ {
+ _hh.push(_qq) ;
+ }
+ }
+
+ template <
+ size_t NA, size_t NB, size_t NC
+ >
+ __inline_call void expansion_sub (
+ expansion const& _aa ,
+ expansion const& _bb ,
+ expansion & _cc
+ ) // adapted from: fast_expansion_diff_zeroelim
+ {
+ static_assert ( NC >= NA + NB ,
+ "expansion-sub: insufficient alloc.!");
+
+ if (_aa._xlen == +1 && // 1-to-1 unrolling
+ _bb._xlen == +1)
+ {
+ REAL_TYPE _t1, _t0;
+
+ _cc._xlen = +0 ;
+
+ one_one_sub_full(
+ _aa[0], _bb[0], _t1, _t0);
+
+ if (_t0 != +0.0) _cc.push (_t0) ;
+ if (_t1 != +0.0) _cc.push (_t1) ;
+ if (_cc.empty()) _cc.push (+0.) ;
+ }
+ else
+ if (_aa._xlen == +2 && // 2-to-1 unrolling
+ _bb._xlen == +1)
+ {
+ REAL_TYPE _t2, _t1, _t0;
+
+ _cc._xlen = +0 ;
+
+ two_one_sub_full(
+ _aa[1], _aa[0], _bb[0], _t2, _t1, _t0);
+
+ if (_t0 != +0.0) _cc.push (_t0) ;
+ if (_t1 != +0.0) _cc.push (_t1) ;
+ if (_t2 != +0.0) _cc.push (_t2) ;
+ if (_cc.empty()) _cc.push (+0.) ;
+ }
+ else
+ if (_aa._xlen == +2 && // 2-to-2 unrolling
+ _bb._xlen == +2)
+ {
+ REAL_TYPE _t3, _t2, _t1, _t0;
+
+ _cc._xlen = +0 ;
+
+ two_two_sub_full(
+ _aa[1], _aa[0],
+ _bb[1], _bb[0], _t3, _t2, _t1, _t0);
+
+ if (_t0 != +0.0) _cc.push (_t0) ;
+ if (_t1 != +0.0) _cc.push (_t1) ;
+ if (_t2 != +0.0) _cc.push (_t2) ;
+ if (_t3 != +0.0) _cc.push (_t3) ;
+ if (_cc.empty()) _cc.push (+0.) ;
+ }
+ else // the n-to-m loops
+ {
+ fast_expansion_sub_zeroelim(_aa, _bb, _cc);
+ }
+ }
+
+ /*
+ --------------------------------------------------------
+ * add/sub multi-precision expansion utilities
+ --------------------------------------------------------
+ */
+
+ template <
+ size_t NA, size_t NC
+ >
+ __inline_call void expansion_add (
+ expansion const& _aa ,
+ REAL_TYPE _bb ,
+ expansion & _cc
+ ) // add --- from-one
+ {
+ expansion_add(
+ _aa, expansion<1>(_bb), _cc ) ;
+ }
+
+ template <
+ size_t NA, size_t NC
+ >
+ __inline_call void expansion_sub (
+ expansion const& _aa ,
+ REAL_TYPE _bb ,
+ expansion & _cc
+ ) // sub --- from-one
+ {
+ expansion_sub(
+ _aa, expansion<1>(_bb), _cc ) ;
+ }
+
+ template <
+ size_t NA, size_t NB, size_t NC,
+ size_t ND
+ >
+ __inline_call void expansion_add (
+ expansion const& _aa,
+ expansion const& _bb,
+ expansion const& _cc,
+ expansion & _dd
+ ) // 3-way add kernel
+ {
+ expansion _ab ;
+ expansion_add(_aa, _bb, _ab);
+
+ expansion_add(_ab, _cc, _dd);
+ }
+
+ template <
+ size_t NA, size_t NB, size_t NC,
+ size_t ND, size_t NE
+ >
+ __inline_call void expansion_add (
+ expansion const& _aa,
+ expansion const& _bb,
+ expansion const& _cc,
+ expansion const& _dd,
+ expansion & _ee
+ ) // 4-way add kernel
+ {
+ expansion _ab ;
+ expansion_add(_aa, _bb, _ab);
+
+ expansion _cd ;
+ expansion_add(_cc, _dd, _cd);
+
+ expansion_add(_ab, _cd, _ee);
+ }
+
+ /*
+ --------------------------------------------------------
+ * scale a multi-precision expansion, a'la shewchuk
+ --------------------------------------------------------
+ */
+
+ template <
+ size_t NE, size_t NH
+ >
+ __normal_call void scale_expansion_zeroelim (
+ expansion const& _ee,
+ REAL_TYPE _bb,
+ expansion & _hh
+ ) // adapted from: scale_expansion_zeroelim
+ {
+ REAL_TYPE _bh, _bl, _t1, _t0 , _ss, _hx, _qq;
+ one_split(_bb, _bh, _bl) ;
+
+ _hh._xlen = +0 ;
+
+ one_one_mul_full(
+ _ee[ 0 ], _bb, _bh, _bl, _qq, _hx) ;
+
+ if (_hx != +0.0) _hh.push (_hx) ;
+
+ INDX_TYPE _ei;
+ for (_ei = +1; _ei < _ee._xlen; ++_ei)
+ {
+ one_one_mul_full(_ee[_ei], _bb, _bh, _bl,
+ _t1, _t0) ;
+
+ one_one_add_full(
+ _qq, _t0, _ss, _hx);
+
+ if (_hx != +0.0) _hh.push (_hx) ;
+
+ one_one_add_fast(
+ _t1, _ss, _qq, _hx);
+
+ if (_hx != +0.0) _hh.push (_hx) ;
+ }
+ if((_qq != +0.0) || (_hh._xlen == +0))
+ {
+ _hh.push(_qq) ;
+ }
+ }
+
+ template <
+ size_t NA, size_t NC
+ >
+ __inline_call void expansion_mul (
+ expansion const& _aa ,
+ REAL_TYPE _bb,
+ expansion & _cc
+ ) // adapted from: scale_expansion_zeroelim
+ {
+ static_assert ( NC >= NA * +2 ,
+ "expansion-mul: insufficient alloc.!");
+
+ if (_aa._xlen == +1) // 1-to-1 unrolling
+ {
+ REAL_TYPE _t1, _t0;
+
+ _cc._xlen = +0 ;
+
+ one_one_mul_full(
+ _aa[0], _bb, _t1, _t0);
+
+ if (_t0 != +0.0) _cc.push (_t0) ;
+ if (_t1 != +0.0) _cc.push (_t1) ;
+ if (_cc.empty()) _cc.push (+0.) ;
+ }
+ else
+ if (_aa._xlen == +2) // 2-to-1 unrolling
+ {
+ REAL_TYPE _t3, _t2, _t1, _t0;
+
+ _cc._xlen = +0 ;
+
+ two_one_mul_full(
+ _aa[1], _aa[0], _bb, _t3, _t2, _t1, _t0);
+
+ if (_t0 != +0.0) _cc.push (_t0) ;
+ if (_t1 != +0.0) _cc.push (_t1) ;
+ if (_t2 != +0.0) _cc.push (_t2) ;
+ if (_t3 != +0.0) _cc.push (_t3) ;
+ if (_cc.empty()) _cc.push (+0.) ;
+ }
+ else // the n-to-1 loops
+ {
+ scale_expansion_zeroelim (_aa, _bb, _cc);
+ }
+ }
+
+ /*
+ --------------------------------------------------------
+ * multi-precision expansion product, a'la shewchuk
+ --------------------------------------------------------
+ */
+
+ template <
+ size_t NA, size_t NB, size_t NC,
+ size_t NR
+ >
+ __normal_call void expansion_mul (
+ expansion const& _aa ,
+ expansion const& _bb ,
+ INDX_TYPE _i1, INDX_TYPE _i2 ,
+ expansion & _cc
+ ) // see shewchuk: block-wise "distillation"
+ {
+ INDX_TYPE _nr = _i2 - _i1 + 1;
+ if (_nr >= +3) // recursive splits
+ {
+ if constexpr ( NR >= +3 )
+ {
+ INDX_TYPE _im = _i1 + _nr / 2 ;
+
+ INDX_TYPE constexpr R1 = NR / 2 ;
+ INDX_TYPE constexpr R2 = NR - R1;
+
+ INDX_TYPE constexpr
+ N1 = mul_alloc (R1, NA) ;
+ INDX_TYPE constexpr
+ N2 = mul_alloc (R2, NA) ;
+
+ expansion _c1;
+ expansion_mul(
+ _aa, _bb, _i1, _im - 1, _c1);
+
+ expansion _c2;
+ expansion_mul(
+ _aa, _bb, _im + 0, _i2, _c2);
+
+ expansion_add(_c1, _c2, _cc) ;
+ }
+ else
+ {
+ assert( false &&
+ "expansion-mul: distill fail");
+ }
+ }
+ else
+ if (_nr == +2)
+ {
+ if constexpr ( NR >= +2 )
+ {
+ expansion _c1 ;
+ expansion _c2 ;
+ expansion_mul(
+ _aa, _bb [_i1 + 0], _c1) ;
+ expansion_mul(
+ _aa, _bb [_i1 + 1], _c2) ;
+
+ expansion_add(_c1, _c2, _cc) ;
+ }
+ else
+ {
+ assert( false &&
+ "expansion-mul: distill fail");
+ }
+ }
+ else
+ if (_nr == +1) // do 1-by-n direct
+ {
+ expansion_mul(_aa, _bb [_i1], _cc);
+ }
+ }
+
+ template <
+ size_t NA, size_t NB, size_t NC
+ >
+ __inline_call void expansion_mul (
+ expansion const& _aa ,
+ expansion const& _bb ,
+ expansion & _cc
+ ) // see shewchuk: block-wise "distillation"
+ {
+ if (_aa._xlen < _bb._xlen)
+ {
+ expansion_mul (
+ _bb, _aa, 0, _aa._xlen-1, _cc);
+ }
+ else
+ {
+ expansion_mul (
+ _aa, _bb, 0, _bb._xlen-1, _cc);
+ }
+ }
+
+ /*
+ --------------------------------------------------------
+ * -ve for multi-precision expansion, a'la shewchuk
+ --------------------------------------------------------
+ */
+
+ template <
+ size_t NN
+ >
+ __normal_call void expansion_neg (
+ expansion & _aa
+ )
+ {
+ INDX_TYPE _ii;
+ for (_ii = +0; _ii < _aa._xlen; ++_ii)
+ {
+ _aa[_ii] *= -1 ;
+ }
+ }
+
+ /*
+ --------------------------------------------------------
+ * est. of multi-precision expansion, a'la shewchuk
+ --------------------------------------------------------
+ */
+
+ template <
+ size_t NN
+ >
+ __normal_call REAL_TYPE expansion_est (
+ expansion const& _aa
+ )
+ {
+ REAL_TYPE _rr = +0.;
+ INDX_TYPE _ii;
+ for (_ii = +0; _ii < _aa._xlen; ++_ii)
+ {
+ _rr += _aa[_ii];
+ }
+
+ return _rr ;
+ }
+
+ /*
+ --------------------------------------------------------
+ * form dot-products for multi-precision expansions
+ --------------------------------------------------------
+ */
+
+ template <
+ size_t AX, size_t BX, size_t AY,
+ size_t BY,
+ size_t NP
+ >
+ __inline_call void expansion_dot (
+ expansion const& _xa,
+ expansion const& _xb,
+ expansion const& _ya,
+ expansion const& _yb,
+ expansion & _dp
+ ) // 2-dim dotproduct
+ {
+ expansion _xp ;
+ expansion_mul(_xa, _xb, _xp);
+
+ expansion _yp ;
+ expansion_mul(_ya, _yb, _yp);
+
+ expansion_add(_xp, _yp, _dp);
+ }
+
+ template <
+ size_t AX, size_t BX, size_t AY,
+ size_t BY, size_t AZ, size_t BZ,
+ size_t NP
+ >
+ __inline_call void expansion_dot (
+ expansion const& _xa,
+ expansion const& _xb,
+ expansion const& _ya,
+ expansion const& _yb,
+ expansion const& _za,
+ expansion const& _zb,
+ expansion & _dp
+ ) // 3-dim dotproduct
+ {
+ expansion _xp ;
+ expansion_mul(_xa, _xb, _xp);
+
+ expansion _yp ;
+ expansion_mul(_ya, _yb, _yp);
+
+ expansion _zp ;
+ expansion_mul(_za, _zb, _zp);
+
+ expansion_add(_xp, _yp, _zp, _dp);
+ }
+
+ template <
+ size_t AX, size_t BX, size_t AY,
+ size_t BY, size_t AZ, size_t BZ,
+ size_t AQ, size_t BQ,
+ size_t NP
+ >
+ __inline_call void expansion_dot (
+ expansion const& _xa,
+ expansion const& _xb,
+ expansion const& _ya,
+ expansion const& _yb,
+ expansion const& _za,
+ expansion const& _zb,
+ expansion const& _qa,
+ expansion const& _qb,
+ expansion & _dp
+ ) // 4-dim dotproduct
+ {
+ expansion _xp ;
+ expansion_mul(_xa, _xb, _xp);
+
+ expansion _yp ;
+ expansion_mul(_ya, _yb, _yp);
+
+ expansion _zp ;
+ expansion_mul(_za, _zb, _zp);
+
+ expansion _qp ;
+ expansion_mul(_qa, _qb, _qp);
+
+ expansion_add(
+ _xp, _yp, _zp, _qp, _dp);
+ }
+
+# undef REAL_TYPE
+# undef INDX_TYPE
+
+
+ }
+
+# endif//__MP_FLOAT__
+
+
+
diff --git a/external/jigsaw/src/libcpp/expansion/mp_utils.hpp b/external/jigsaw/src/libcpp/expansion/mp_utils.hpp
new file mode 100644
index 0000000..36f3b0c
--- /dev/null
+++ b/external/jigsaw/src/libcpp/expansion/mp_utils.hpp
@@ -0,0 +1,448 @@
+
+ /*
+ --------------------------------------------------------
+ * MPFLOAT: multi-precision floating-point arithmetic.
+ --------------------------------------------------------
+ *
+ * This program may be freely redistributed under the
+ * condition that the copyright notices (including this
+ * entire header) are not removed, and no compensation
+ * is received through use of the software. Private,
+ * research, and institutional use is free. You may
+ * distribute modified versions of this code UNDER THE
+ * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE
+ * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE
+ * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE
+ * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR
+ * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution
+ * of this code as part of a commercial system is
+ * permissible ONLY BY DIRECT ARRANGEMENT WITH THE
+ * AUTHOR. (If you are not directly supplying this
+ * code to a customer, and you are instead telling them
+ * how they can obtain it for free, then you are not
+ * required to make any arrangement with me.)
+ *
+ * Disclaimer: Neither I nor: Columbia University, The
+ * Massachusetts Institute of Technology, The
+ * University of Sydney, nor The National Aeronautics
+ * and Space Administration warrant this code in any
+ * way whatsoever. This code is provided "as-is" to be
+ * used at your own risk.
+ *
+ --------------------------------------------------------
+ *
+ * Last updated: 03 March, 2020
+ *
+ * Copyright 2020--
+ * Darren Engwirda
+ * d.engwirda@gmail.com
+ * https://github.com/dengwirda/
+ *
+ --------------------------------------------------------
+ */
+
+# pragma once
+
+# ifndef __MP_UTILS__
+# define __MP_UTILS__
+
+ namespace mp_float {
+
+# define REAL_TYPE mp_float::real_type
+# define INDX_TYPE mp_float::indx_type
+
+ /*---------------- compute an exact 2 x 2 determinant */
+
+ template <
+ size_t NN
+ >
+ __inline_call void compute_det_2x2 (
+ REAL_TYPE _aa, REAL_TYPE _bb ,
+ REAL_TYPE _cc, REAL_TYPE _dd ,
+ expansion & _final
+ )
+ {
+ expansion< 2 >_mulad, _mulbc ;
+ _mulad.from_mul (_aa, _dd);
+ _mulbc.from_mul (_bb, _cc);
+
+ expansion_sub(_mulad, _mulbc, _final);
+ }
+
+ /*
+ --------------------------------------------------------
+ *
+ * Compute an exact 3 x 3 determinant.
+ *
+ * | a1 a2 v1 |
+ * | b1 b2 v2 |
+ * | c1 c2 v3 |
+ *
+ * as the product of 2 x 2 minors about a pivot column
+ * P, shown here for P = 3. The entry V1 is associated
+ * with the minor
+ *
+ * | b1 b2 | = D1
+ * | c1 c2 |
+ *
+ * and so on for (V2,D2), (V3,D3) etc.
+ *
+ --------------------------------------------------------
+ */
+
+ template <
+ size_t NA, size_t NB, size_t NC,
+ size_t ND, size_t NE, size_t NF,
+ size_t NG
+ >
+ __inline_call void compute_det_3x3 (
+ expansion const& _det1p ,
+ expansion const& _val1p ,
+ expansion const& _det2p ,
+ expansion const& _val2p ,
+ expansion const& _det3p ,
+ expansion const& _val3p ,
+ expansion & _final ,
+ INDX_TYPE _pivot
+ )
+ {
+ /*---------------------------------- products Vi * Di */
+ INDX_TYPE
+ constexpr N1 = mul_alloc (NA, NB) ;
+ expansion _mul1p;
+ expansion_mul(_det1p, _val1p, _mul1p);
+
+ INDX_TYPE
+ constexpr N2 = mul_alloc (NC, ND) ;
+ expansion _mul2p;
+ expansion_mul(_det2p, _val2p, _mul2p);
+
+ INDX_TYPE
+ constexpr N3 = mul_alloc (NE, NF) ;
+ expansion _mul3p;
+ expansion_mul(_det3p, _val3p, _mul3p);
+
+ /*---------------------------------- sum (-1)^P * VDi */
+ INDX_TYPE
+ constexpr MM = sub_alloc (N1, N2) ;
+ expansion _sum_1;
+
+ if (_pivot % 2 == +0)
+ {
+ expansion_sub(_mul2p, _mul1p, _sum_1);
+ expansion_sub(_sum_1, _mul3p, _final);
+ }
+ else
+ {
+ expansion_sub(_mul1p, _mul2p, _sum_1);
+ expansion_add(_sum_1, _mul3p, _final);
+ }
+ }
+
+ /*--------------------- "unitary" case, with Vi = +1. */
+
+ template <
+ size_t NA, size_t NB, size_t NC,
+ size_t ND
+ >
+ __inline_call void unitary_det_3x3 (
+ expansion const& _det1p ,
+ expansion const& _det2p ,
+ expansion const& _det3p ,
+ expansion & _final ,
+ INDX_TYPE _pivot
+ )
+ {
+ INDX_TYPE
+ constexpr MM = sub_alloc (NA, NB) ;
+ expansion _sum_1;
+
+ if (_pivot % 2 == +0)
+ {
+ expansion_sub(_det2p, _det1p, _sum_1);
+ expansion_sub(_sum_1, _det3p, _final);
+ }
+ else
+ {
+ expansion_sub(_det1p, _det2p, _sum_1);
+ expansion_add(_sum_1, _det3p, _final);
+ }
+ }
+
+ /*
+ --------------------------------------------------------
+ *
+ * Compute an exact 4 x 4 determinant.
+ *
+ * | a1 a2 a3 v1 |
+ * | b1 b2 b2 v2 |
+ * | c1 c2 c3 v3 |
+ * | d1 d2 d3 v4 |
+ *
+ * as the product of 3 x 3 minors about a pivot column
+ * P, shown here for P = 4. The entry V1 is associated
+ * with the minor
+ *
+ * | b1 b2 b3 |
+ * | c1 c2 c3 | = D1
+ * | d1 d2 d3 |
+ *
+ * and so on for (V2,D2), (V3,D3) etc.
+ *
+ --------------------------------------------------------
+ */
+
+ template <
+ size_t NA, size_t NB, size_t NC,
+ size_t ND, size_t NE, size_t NF,
+ size_t NG, size_t NH, size_t NI
+ >
+ __inline_call void compute_det_4x4 (
+ expansion const& _det1p ,
+ expansion const& _val1p ,
+ expansion const& _det2p ,
+ expansion const& _val2p ,
+ expansion const& _det3p ,
+ expansion const& _val3p ,
+ expansion const& _det4p ,
+ expansion const& _val4p ,
+ expansion & _final ,
+ INDX_TYPE _pivot
+ )
+ {
+ /*---------------------------------- products Vi * Di */
+ INDX_TYPE
+ constexpr N1 = mul_alloc (NA, NB) ;
+ expansion _mul1p;
+ expansion_mul(_det1p, _val1p, _mul1p);
+
+ INDX_TYPE
+ constexpr N2 = mul_alloc (NC, ND) ;
+ expansion _mul2p;
+ expansion_mul(_det2p, _val2p, _mul2p);
+
+ INDX_TYPE
+ constexpr N3 = mul_alloc (NE, NF) ;
+ expansion _mul3p;
+ expansion_mul(_det3p, _val3p, _mul3p);
+
+ INDX_TYPE
+ constexpr N4 = mul_alloc (NG, NH) ;
+ expansion _mul4p;
+ expansion_mul(_det4p, _val4p, _mul4p);
+
+ /*---------------------------------- sum (-1)^P * VDi */
+ INDX_TYPE
+ constexpr M1 = sub_alloc (N1, N2) ;
+ expansion _sum_1;
+
+ INDX_TYPE
+ constexpr M2 = sub_alloc (N3, N4) ;
+ expansion _sum_2;
+
+ if (_pivot % 2 == +0)
+ {
+ expansion_sub(_mul2p, _mul1p, _sum_1);
+ expansion_sub(_mul4p, _mul3p, _sum_2);
+ }
+ else
+ {
+ expansion_sub(_mul1p, _mul2p, _sum_1);
+ expansion_sub(_mul3p, _mul4p, _sum_2);
+ }
+
+ expansion_add(_sum_1, _sum_2, _final);
+ }
+
+ /*--------------------- "unitary" case, with Vi = +1. */
+
+ template <
+ size_t NA, size_t NB, size_t NC,
+ size_t ND, size_t NE
+ >
+ __inline_call void unitary_det_4x4 (
+ expansion const& _det1p ,
+ expansion const& _det2p ,
+ expansion const& _det3p ,
+ expansion const& _det4p ,
+ expansion & _final ,
+ INDX_TYPE _pivot
+ )
+ {
+ INDX_TYPE
+ constexpr M1 = sub_alloc (NA, NB) ;
+ expansion _sum_1;
+
+ INDX_TYPE
+ constexpr M2 = sub_alloc (NC, ND) ;
+ expansion _sum_2;
+
+ if (_pivot % 2 == +0)
+ {
+ expansion_sub(_det2p, _det1p, _sum_1);
+ expansion_sub(_det4p, _det3p, _sum_2);
+ }
+ else
+ {
+ expansion_sub(_det2p, _det1p, _sum_1);
+ expansion_sub(_det4p, _det3p, _sum_2);
+ }
+
+ expansion_add(_sum_1, _sum_2, _final);
+ }
+
+ /*
+ --------------------------------------------------------
+ *
+ * Compute an exact 5 x 5 determinant.
+ *
+ * | a1 a2 a3 a4 v1 |
+ * | b1 b2 b3 b4 v2 |
+ * | c1 c2 c3 c4 v3 |
+ * | d1 d2 d3 d4 v4 |
+ * | e1 e2 e3 e4 v5 |
+ *
+ * as the product of 4 x 4 minors about a pivot column
+ * P, shown here for P = 5. The entry V1 is associated
+ * with the minor
+ *
+ * | b1 b2 b3 b4 |
+ * | c1 c2 c3 c4 | = D1
+ * | d1 d2 d3 d4 |
+ * | e1 e2 e3 e4 |
+ *
+ * and so on for (V2,D2), (V3,D3) etc.
+ *
+ --------------------------------------------------------
+ */
+
+ template <
+ size_t NA, size_t NB, size_t NC,
+ size_t ND, size_t NE, size_t NF,
+ size_t NG, size_t NH, size_t NI,
+ size_t NJ, size_t NK
+ >
+ __inline_call void compute_det_5x5 (
+ expansion const& _det1p ,
+ expansion const& _val1p ,
+ expansion const& _det2p ,
+ expansion const& _val2p ,
+ expansion const& _det3p ,
+ expansion const& _val3p ,
+ expansion const& _det4p ,
+ expansion const& _val4p ,
+ expansion const& _det5p ,
+ expansion const& _val5p ,
+ expansion & _final ,
+ INDX_TYPE _pivot
+ )
+ {
+ /*---------------------------------- products Vi * Di */
+ INDX_TYPE
+ constexpr N1 = mul_alloc (NA, NB) ;
+ expansion _mul1p;
+ expansion_mul(_det1p, _val1p, _mul1p);
+
+ INDX_TYPE
+ constexpr N2 = mul_alloc (NC, ND) ;
+ expansion _mul2p;
+ expansion_mul(_det2p, _val2p, _mul2p);
+
+ INDX_TYPE
+ constexpr N3 = mul_alloc (NE, NF) ;
+ expansion _mul3p;
+ expansion_mul(_det3p, _val3p, _mul3p);
+
+ INDX_TYPE
+ constexpr N4 = mul_alloc (NG, NH) ;
+ expansion _mul4p;
+ expansion_mul(_det4p, _val4p, _mul4p);
+
+ INDX_TYPE
+ constexpr N5 = mul_alloc (NI, NJ) ;
+ expansion _mul5p;
+ expansion_mul(_det5p, _val5p, _mul5p);
+
+ /*---------------------------------- sum (-1)^P * VDi */
+ INDX_TYPE
+ constexpr M1 = sub_alloc (N1, N2) ;
+ expansion _sum_1;
+
+ INDX_TYPE
+ constexpr M2 = sub_alloc (N3, N4) ;
+ expansion _sum_2;
+
+ INDX_TYPE
+ constexpr M3 = sub_alloc (M1, N5) ;
+ expansion _sum_3;
+
+ if (_pivot % 2 == +0)
+ {
+ expansion_sub(_mul2p, _mul1p, _sum_1);
+ expansion_sub(_mul4p, _mul3p, _sum_2);
+ expansion_sub(_sum_1, _mul5p, _sum_3);
+ }
+ else
+ {
+ expansion_sub(_mul1p, _mul2p, _sum_1);
+ expansion_sub(_mul3p, _mul4p, _sum_2);
+ expansion_add(_sum_1, _mul5p, _sum_3);
+ }
+
+ expansion_add(_sum_3, _sum_2, _final);
+ }
+
+ /*--------------------- "unitary" case, with Vi = +1. */
+
+ template <
+ size_t NA, size_t NB, size_t NC,
+ size_t ND, size_t NE, size_t NF
+ >
+ __inline_call void unitary_det_5x5 (
+ expansion const& _det1p ,
+ expansion const& _det2p ,
+ expansion const& _det3p ,
+ expansion const& _det4p ,
+ expansion const& _det5p ,
+ expansion & _final ,
+ INDX_TYPE _pivot
+ )
+ {
+ INDX_TYPE
+ constexpr N1 = sub_alloc (NA, NB) ;
+ expansion _sum_1;
+
+ INDX_TYPE
+ constexpr N2 = sub_alloc (NC, ND) ;
+ expansion _sum_2;
+
+ INDX_TYPE
+ constexpr N3 = sub_alloc (N1, NE) ;
+ expansion _sum_3;
+
+ if (_pivot % 2 == +0)
+ {
+ expansion_sub(_det2p, _det1p, _sum_1);
+ expansion_sub(_det4p, _det3p, _sum_2);
+ expansion_sub(_sum_1, _det5p, _sum_3);
+ }
+ else
+ {
+ expansion_sub(_det1p, _det2p, _sum_1);
+ expansion_sub(_det3p, _det4p, _sum_2);
+ expansion_add(_sum_1, _det5p, _sum_3);
+ }
+
+ expansion_add(_sum_3, _sum_2, _final);
+ }
+
+# undef REAL_TYPE
+# undef INDX_TYPE
+
+
+ }
+
+# endif//__MP_UTILS__
+
+
+
diff --git a/external/jigsaw/src/libcpp/geom_base/tria_ball_k.hpp b/external/jigsaw/src/libcpp/geom_base/cell_ball_k.hpp
similarity index 89%
rename from external/jigsaw/src/libcpp/geom_base/tria_ball_k.hpp
rename to external/jigsaw/src/libcpp/geom_base/cell_ball_k.hpp
index 3ba816b..d54da66 100644
--- a/external/jigsaw/src/libcpp/geom_base/tria_ball_k.hpp
+++ b/external/jigsaw/src/libcpp/geom_base/cell_ball_k.hpp
@@ -1,7 +1,7 @@
/*
--------------------------------------------------------
- * TRIA-BALL-K: various circumscribing ball calc.'s.
+ * CELL-BALL-K: various circumscribing ball calc.'s.
--------------------------------------------------------
*
* This program may be freely redistributed under the
@@ -31,11 +31,11 @@
*
--------------------------------------------------------
*
- * Last updated: 10 July, 2019
+ * Last updated: 26 July, 2020
*
- * Copyright 2013-2019
+ * Copyright 2013-2020
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
--------------------------------------------------------
@@ -43,8 +43,8 @@
# pragma once
-# ifndef __TRIA_BALL_K__
-# define __TRIA_BALL_K__
+# ifndef __CELL_BALL_K__
+# define __CELL_BALL_K__
namespace geometry {
@@ -245,16 +245,14 @@
real_type _xr[2*1] ;
_xr[0] = (real_type)+.5 * (
- _xm[__ij(0,0,2)] *
- _xm[__ij(0,0,2)] +
- _xm[__ij(0,1,2)] *
- _xm[__ij(0,1,2)] ) ;
+ std::pow(_xm[__ij(0,0,2)], +2) +
+ std::pow(_xm[__ij(0,1,2)], +2)
+ ) ;
_xr[1] = (real_type)+.5 * (
- _xm[__ij(1,0,2)] *
- _xm[__ij(1,0,2)] +
- _xm[__ij(1,1,2)] *
- _xm[__ij(1,1,2)] ) ;
+ std::pow(_xm[__ij(1,0,2)], +2) +
+ std::pow(_xm[__ij(1,1,2)], +2)
+ ) ;
real_type _dd ;
math::inv_2x2 (
@@ -349,20 +347,16 @@
real_type _xr[3*1] ;
_xr[0] = (real_type)+.5 * (
- _xm[__ij(0,0,3)] *
- _xm[__ij(0,0,3)] +
- _xm[__ij(0,1,3)] *
- _xm[__ij(0,1,3)] +
- _xm[__ij(0,2,3)] *
- _xm[__ij(0,2,3)] ) ;
+ std::pow(_xm[__ij(0,0,3)], +2) +
+ std::pow(_xm[__ij(0,1,3)], +2) +
+ std::pow(_xm[__ij(0,2,3)], +2)
+ ) ;
_xr[1] = (real_type)+.5 * (
- _xm[__ij(1,0,3)] *
- _xm[__ij(1,0,3)] +
- _xm[__ij(1,1,3)] *
- _xm[__ij(1,1,3)] +
- _xm[__ij(1,2,3)] *
- _xm[__ij(1,2,3)] ) ;
+ std::pow(_xm[__ij(1,0,3)], +2) +
+ std::pow(_xm[__ij(1,1,3)], +2) +
+ std::pow(_xm[__ij(1,2,3)], +2)
+ ) ;
_xr[2] = (real_type)+.0 ;
@@ -441,6 +435,80 @@
__circface13( _bb, _p3, _p1, _p2);
}
+ template <
+ typename real_type
+ >
+ __inline_call void_type quad_ball_2d (
+ __write_ptr (real_type) _bb ,
+ __const_ptr (real_type) _p1 ,
+ __const_ptr (real_type) _p2 ,
+ __const_ptr (real_type) _p3 ,
+ __const_ptr (real_type) _p4 ,
+ bool_type _in
+ )
+ {
+ __unreferenced(_in);
+
+ real_type _b1[3];
+ circ_ball_2d(
+ _b1, _p1, _p2, _p3, false) ;
+ real_type _b2[3];
+ circ_ball_2d(
+ _b2, _p1, _p3, _p4, false) ;
+ real_type _b3[3];
+ circ_ball_2d(
+ _b3, _p1, _p2, _p4, false) ;
+ real_type _b4[3];
+ circ_ball_2d(
+ _b4, _p2, _p3, _p4, false) ;
+
+ _bb[0] =
+ (_b1[0]+_b2[0]+_b3[0]+_b4[0]) / +4. ;
+ _bb[1] =
+ (_b1[1]+_b2[1]+_b3[1]+_b4[1]) / +4. ;
+
+ _bb[2] = std::pow(
+ _b1[2]*_b2[2]*_b3[2]*_b4[2], 1./4.) ;
+ }
+
+ template <
+ typename real_type
+ >
+ __inline_call void_type quad_ball_3d (
+ __write_ptr (real_type) _bb ,
+ __const_ptr (real_type) _p1 ,
+ __const_ptr (real_type) _p2 ,
+ __const_ptr (real_type) _p3 ,
+ __const_ptr (real_type) _p4 ,
+ bool_type _in
+ )
+ {
+ __unreferenced(_in);
+
+ real_type _b1[4];
+ circ_ball_3d(
+ _b1, _p1, _p2, _p3, false) ;
+ real_type _b2[4];
+ circ_ball_3d(
+ _b2, _p1, _p3, _p4, false) ;
+ real_type _b3[4];
+ circ_ball_3d(
+ _b3, _p1, _p2, _p4, false) ;
+ real_type _b4[4];
+ circ_ball_3d(
+ _b4, _p2, _p3, _p4, false) ;
+
+ _bb[0] =
+ (_b1[0]+_b2[0]+_b3[0]+_b4[0]) / +4. ;
+ _bb[1] =
+ (_b1[1]+_b2[1]+_b3[1]+_b4[1]) / +4. ;
+ _bb[2] =
+ (_b1[2]+_b2[2]+_b3[2]+_b4[2]) / +4. ;
+
+ _bb[3] = std::pow(
+ _b1[3]*_b2[3]*_b3[3]*_b4[3], 1./4.) ;
+ }
+
template <
typename real_type
>
@@ -469,28 +537,22 @@
real_type _xr[3*1] ;
_xr[0] = (real_type)+.5 * (
- _xm[__ij(0,0,3)] *
- _xm[__ij(0,0,3)] +
- _xm[__ij(0,1,3)] *
- _xm[__ij(0,1,3)] +
- _xm[__ij(0,2,3)] *
- _xm[__ij(0,2,3)] ) ;
+ std::pow(_xm[__ij(0,0,3)], +2) +
+ std::pow(_xm[__ij(0,1,3)], +2) +
+ std::pow(_xm[__ij(0,2,3)], +2)
+ ) ;
_xr[1] = (real_type)+.5 * (
- _xm[__ij(1,0,3)] *
- _xm[__ij(1,0,3)] +
- _xm[__ij(1,1,3)] *
- _xm[__ij(1,1,3)] +
- _xm[__ij(1,2,3)] *
- _xm[__ij(1,2,3)] ) ;
+ std::pow(_xm[__ij(1,0,3)], +2) +
+ std::pow(_xm[__ij(1,1,3)], +2) +
+ std::pow(_xm[__ij(1,2,3)], +2)
+ ) ;
_xr[2] = (real_type)+.5 * (
- _xm[__ij(2,0,3)] *
- _xm[__ij(2,0,3)] +
- _xm[__ij(2,1,3)] *
- _xm[__ij(2,1,3)] +
- _xm[__ij(2,2,3)] *
- _xm[__ij(2,2,3)] ) ;
+ std::pow(_xm[__ij(2,0,3)], +2) +
+ std::pow(_xm[__ij(2,1,3)], +2) +
+ std::pow(_xm[__ij(2,2,3)], +2)
+ ) ;
real_type _dd ;
math::inv_3x3 (
@@ -826,16 +888,14 @@
real_type _xr[2*1] ;
_xr[0] = (real_type)+.5 * (
- _xm[__ij(0,0,2)] *
- _xm[__ij(0,0,2)] +
- _xm[__ij(0,1,2)] *
- _xm[__ij(0,1,2)] ) ;
+ std::pow(_xm[__ij(0,0,2)], +2) +
+ std::pow(_xm[__ij(0,1,2)], +2)
+ ) ;
_xr[1] = (real_type)+.5 * (
- _xm[__ij(1,0,2)] *
- _xm[__ij(1,0,2)] +
- _xm[__ij(1,1,2)] *
- _xm[__ij(1,1,2)] ) ;
+ std::pow(_xm[__ij(1,0,2)], +2) +
+ std::pow(_xm[__ij(1,1,2)], +2)
+ ) ;
real_type _w21 = _p2[2]-_p1[2] ;
real_type _w31 = _p3[2]-_p1[2] ;
@@ -948,20 +1008,16 @@
real_type _xr[3*1] ;
_xr[0] = (real_type)+.5 * (
- _xm[__ij(0,0,3)] *
- _xm[__ij(0,0,3)] +
- _xm[__ij(0,1,3)] *
- _xm[__ij(0,1,3)] +
- _xm[__ij(0,2,3)] *
- _xm[__ij(0,2,3)] ) ;
+ std::pow(_xm[__ij(0,0,3)], +2) +
+ std::pow(_xm[__ij(0,1,3)], +2) +
+ std::pow(_xm[__ij(0,2,3)], +2)
+ ) ;
_xr[1] = (real_type)+.5 * (
- _xm[__ij(1,0,3)] *
- _xm[__ij(1,0,3)] +
- _xm[__ij(1,1,3)] *
- _xm[__ij(1,1,3)] +
- _xm[__ij(1,2,3)] *
- _xm[__ij(1,2,3)] ) ;
+ std::pow(_xm[__ij(1,0,3)], +2) +
+ std::pow(_xm[__ij(1,1,3)], +2) +
+ std::pow(_xm[__ij(1,2,3)], +2)
+ ) ;
real_type _w21 = _p2[3]-_p1[3] ;
real_type _w31 = _p3[3]-_p1[3] ;
@@ -1086,28 +1142,30 @@
real_type _xr[3*1] ;
_xr[0] = (real_type)+.5 * (
- _xm[__ij(0,0,3)] *
- _xm[__ij(0,0,3)] +
- _xm[__ij(0,1,3)] *
- _xm[__ij(0,1,3)] +
- _xm[__ij(0,2,3)] *
- _xm[__ij(0,2,3)] ) ;
+ std::pow(_xm[__ij(0,0,3)], +2) +
+ std::pow(_xm[__ij(0,1,3)], +2) +
+ std::pow(_xm[__ij(0,2,3)], +2)
+ ) ;
_xr[1] = (real_type)+.5 * (
- _xm[__ij(1,0,3)] *
- _xm[__ij(1,0,3)] +
- _xm[__ij(1,1,3)] *
- _xm[__ij(1,1,3)] +
- _xm[__ij(1,2,3)] *
- _xm[__ij(1,2,3)] ) ;
+ std::pow(_xm[__ij(1,0,3)], +2) +
+ std::pow(_xm[__ij(1,1,3)], +2) +
+ std::pow(_xm[__ij(1,2,3)], +2)
+ ) ;
_xr[2] = (real_type)+.5 * (
- _xm[__ij(2,0,3)] *
- _xm[__ij(2,0,3)] +
- _xm[__ij(2,1,3)] *
- _xm[__ij(2,1,3)] +
- _xm[__ij(2,2,3)] *
- _xm[__ij(2,2,3)] ) ;
+ std::pow(_xm[__ij(2,0,3)], +2) +
+ std::pow(_xm[__ij(2,1,3)], +2) +
+ std::pow(_xm[__ij(2,2,3)], +2)
+ ) ;
+
+ real_type _w21 = _p2[3]-_p1[3] ;
+ real_type _w31 = _p3[3]-_p1[3] ;
+ real_type _w41 = _p4[3]-_p1[3] ;
+
+ _xr[0]-= (real_type)+.5 * _w21 ;
+ _xr[1]-= (real_type)+.5 * _w31 ;
+ _xr[2]-= (real_type)+.5 * _w41 ;
real_type _dd ;
math::inv_3x3 (
@@ -1400,7 +1458,7 @@
}
-# endif //__TRIA_BALL_K__
+# endif //__CELL_BALL_K__
diff --git a/external/jigsaw/src/libcpp/geom_base/tria_elem_k.hpp b/external/jigsaw/src/libcpp/geom_base/cell_base_k.hpp
similarity index 51%
rename from external/jigsaw/src/libcpp/geom_base/tria_elem_k.hpp
rename to external/jigsaw/src/libcpp/geom_base/cell_base_k.hpp
index 9f02dce..1ba51ed 100644
--- a/external/jigsaw/src/libcpp/geom_base/tria_elem_k.hpp
+++ b/external/jigsaw/src/libcpp/geom_base/cell_base_k.hpp
@@ -1,7 +1,7 @@
/*
--------------------------------------------------------
- * TRIA-ELEM-K: operations on simplexes in R^k.
+ * CELL-BASE-K: operations on linear cells in R^k.
--------------------------------------------------------
*
* This program may be freely redistributed under the
@@ -31,11 +31,11 @@
*
--------------------------------------------------------
*
- * Last updated: 30 Aug, 2019
+ * Last updated: 26 July, 2020
*
- * Copyright 2013-2019
+ * Copyright 2013-2020
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
--------------------------------------------------------
@@ -43,8 +43,8 @@
# pragma once
-# ifndef __TRIA_ELEM_K__
-# define __TRIA_ELEM_K__
+# ifndef __CELL_BASE_K__
+# define __CELL_BASE_K__
namespace geometry {
@@ -57,7 +57,7 @@
template <
typename data_type
>
- __normal_call data_type tria_area_2d (
+ __inline_call data_type tria_area_2d (
__const_ptr (data_type) _p1,
__const_ptr (data_type) _p2,
__const_ptr (data_type) _p3
@@ -81,7 +81,7 @@
template <
typename data_type
>
- __normal_call data_type tria_area_3d (
+ __inline_call data_type tria_area_3d (
__const_ptr (data_type) _p1,
__const_ptr (data_type) _p2,
__const_ptr (data_type) _p3
@@ -107,6 +107,155 @@
return (data_type)+.5 * _aval ;
}
+ template <
+ typename data_type
+ >
+ __inline_call void_type quad_axes_2d (
+ __const_ptr (data_type) _p1,
+ __const_ptr (data_type) _p2,
+ __const_ptr (data_type) _p3,
+ __const_ptr (data_type) _p4,
+ __write_ptr (data_type) _x1,
+ __write_ptr (data_type) _x2
+ ) // see VERDICT ref. manual
+ {
+ _x1[0] = (_p2[0] - _p1[0])
+ + (_p4[0] - _p3[0]);
+ _x1[1] = (_p2[1] - _p1[1])
+ + (_p4[1] - _p3[1]);
+
+ _x2[0] = (_p3[0] - _p2[0])
+ + (_p4[0] - _p1[0]);
+ _x2[1] = (_p3[1] - _p2[1])
+ + (_p4[1] - _p1[1]);
+ }
+
+ template <
+ typename data_type
+ >
+ __inline_call void_type quad_axes_3d (
+ __const_ptr (data_type) _p1,
+ __const_ptr (data_type) _p2,
+ __const_ptr (data_type) _p3,
+ __const_ptr (data_type) _p4,
+ __write_ptr (data_type) _x1,
+ __write_ptr (data_type) _x2
+ ) // see VERDICT ref. manual
+ {
+ _x1[0] = (_p2[0] - _p1[0])
+ + (_p4[0] - _p3[0]);
+ _x1[1] = (_p2[1] - _p1[1])
+ + (_p4[1] - _p3[1]);
+ _x1[2] = (_p2[2] - _p1[2])
+ + (_p4[2] - _p3[2]);
+
+ _x2[0] = (_p3[0] - _p2[0])
+ + (_p4[0] - _p1[0]);
+ _x2[1] = (_p3[1] - _p2[1])
+ + (_p4[1] - _p1[1]);
+ _x2[2] = (_p3[2] - _p2[2])
+ + (_p4[2] - _p1[2]);
+ }
+
+ template <
+ typename data_type
+ >
+ __inline_call data_type quad_area_2d (
+ __const_ptr (data_type) _p1,
+ __const_ptr (data_type) _p2,
+ __const_ptr (data_type) _p3,
+ __const_ptr (data_type) _p4
+ ) // see VERDICT ref. manual
+ {
+ data_type _a1 =
+ tria_area_2d(_p1, _p2, _p3);
+ data_type _a2 =
+ tria_area_2d(_p1, _p3, _p4);
+ data_type _a3 =
+ tria_area_2d(_p1, _p2, _p4);
+ data_type _a4 =
+ tria_area_2d(_p2, _p3, _p4);
+
+ return ((_a1+_a2) + (_a3+_a4)) / +2.;
+
+ /*
+ // data_type _x1[2], _x2[2], _nc;
+ // quad_axes_2d(_p1, _p2, _p3, _p4, _x1, _x2);
+
+ data_type _v1[2], _a1;
+ data_type _v2[2], _a2;
+ data_type _v3[2], _a3;
+ data_type _v4[2], _a4;
+ vector_2d(_p1, _p2, _v1);
+ vector_2d(_p2, _p3, _v2);
+ vector_2d(_p3, _p4, _v3);
+ vector_2d(_p4, _p1, _v4);
+
+ cross_2d (_v4, _v1, _a1);
+ cross_2d (_v1, _v2, _a2);
+ cross_2d (_v2, _v3, _a3);
+ cross_2d (_v3, _v4, _a4);
+
+ return (_a1 + _a2 + _a3 + _a4);
+ */
+ }
+
+ template <
+ typename data_type
+ >
+ __inline_call data_type quad_area_3d (
+ __const_ptr (data_type) _p1,
+ __const_ptr (data_type) _p2,
+ __const_ptr (data_type) _p3,
+ __const_ptr (data_type) _p4
+ ) // see VERDICT ref. manual
+ {
+ data_type _a1 =
+ tria_area_3d(_p1, _p2, _p3);
+ data_type _a2 =
+ tria_area_3d(_p1, _p3, _p4);
+ data_type _a3 =
+ tria_area_3d(_p1, _p2, _p4);
+ data_type _a4 =
+ tria_area_3d(_p2, _p3, _p4);
+
+ return ((_a1+_a2) + (_a3+_a4)) / +2.;
+
+ /*
+ data_type _x1[3], _x2[3], _nc[3];
+ quad_axes_3d(_p1, _p2, _p3, _p4, _x1, _x2);
+
+ data_type _v1[3], _n1[3];
+ data_type _v2[3], _n2[3];
+ data_type _v3[3], _n3[3];
+ data_type _v4[3], _n4[3];
+ vector_3d(_p1, _p2, _v1);
+ vector_3d(_p2, _p3, _v2);
+ vector_3d(_p3, _p4, _v3);
+ vector_3d(_p4, _p1, _v4);
+
+ cross_3d (_v4, _v1, _n1);
+ cross_3d (_v1, _v2, _n2);
+ cross_3d (_v2, _v3, _n3);
+ cross_3d (_v3, _v4, _n4);
+
+ cross_3d (_x1, _x2, _nc);
+
+ data_type _lc = length_3d(_nc);
+
+ data_type _a1 =
+ dot_3d(_nc, _n1) / _lc;
+ data_type _a2 =
+ dot_3d(_nc, _n2) / _lc;
+ data_type _a3 =
+ dot_3d(_nc, _n3) / _lc;
+ data_type _a4 =
+ dot_3d(_nc, _n4) / _lc;
+
+ return (_a1 + _a2 + _a3 + _a4);
+ */
+ }
+
template <
typename data_type
>
@@ -142,6 +291,29 @@
_ev12[1] * _ev13[0] ;
}
+ template <
+ typename data_type
+ >
+ __inline_call void_type quad_norm_3d (
+ __const_ptr (data_type) _p1,
+ __const_ptr (data_type) _p2,
+ __const_ptr (data_type) _p3,
+ __const_ptr (data_type) _p4,
+ __write_ptr (data_type) _nv
+ )
+ {
+ data_type _xx11[3], _xx22[3] ;
+ quad_axes_3d(
+ _p1, _p2, _p3, _p4, _xx11, _xx22);
+
+ _nv[0] = _xx11[1] * _xx22[2] -
+ _xx11[2] * _xx22[1] ;
+ _nv[1] = _xx11[2] * _xx22[0] -
+ _xx11[0] * _xx22[2] ;
+ _nv[2] = _xx11[0] * _xx22[1] -
+ _xx11[1] * _xx22[0] ;
+ }
+
template <
typename data_type
>
@@ -171,33 +343,25 @@
/*
--------------------------------------------------------
- * tria. "quality" scores.
+ * cell "quality" scores.
--------------------------------------------------------
*/
template <
typename data_type
>
- __normal_call
+ __inline_call
data_type tria_quality_2d (
__const_ptr (data_type) _p1,
__const_ptr (data_type) _p2,
__const_ptr (data_type) _p3
)
- {
- // mean of condition no. + gradient-error metrics
- // see Shewchuk
+ { // "volume-length" metric, see Shewchuk
- // 4. * std::sqrt(3.)
- data_type static
- constexpr _mulA =
+ data_type static // +4. * std::sqrt(3.)
+ constexpr _mul =
(data_type)+6.928203230275509 ;
- // 4. / std::sqrt(3.)
- data_type static
- constexpr _mulB =
- (data_type)+2.309401076758503 ;
-
data_type _len1 =
lensqr_2d(_p1, _p2) ;
data_type _len2 =
@@ -205,52 +369,30 @@
data_type _len3 =
lensqr_2d(_p3, _p1) ;
- data_type _barA =
+ data_type _lbar =
_len1+_len2+_len3 ;
- data_type _barB =
- _len1*_len2*_len3 ;
-
- _barB = std::pow(
- _barB, (data_type)+1./3.);
-
data_type _area =
- tria_area_2d(_p1, _p2, _p3);
-
- data_type _scrA =
- _mulA * _area / _barA ;
-
- data_type _scrB =
- _mulB * _area / _barB ;
+ tria_area_2d(_p1, _p2, _p3) ;
- return
- ((data_type)+1.0-.33)*_scrA +
- ((data_type)+0.0+.33)*_scrB ;
+ return _mul * _area / _lbar ;
}
template <
typename data_type
>
- __normal_call
+ __inline_call
data_type tria_quality_3d (
__const_ptr (data_type) _p1,
__const_ptr (data_type) _p2,
__const_ptr (data_type) _p3
)
- {
- // mean of condition no. + gradient-error metrics
- // see Shewchuk
+ { // "volume-length" metric, see Shewchuk
- // 4. * std::sqrt(3.)
- data_type static
- constexpr _mulA =
+ data_type static // +4. * std::sqrt(3.)
+ constexpr _mul =
(data_type)+6.928203230275509 ;
- // 4. / std::sqrt(3.)
- data_type static
- constexpr _mulB =
- (data_type)+2.309401076758503 ;
-
data_type _len1 =
lensqr_3d(_p1, _p2) ;
data_type _len2 =
@@ -258,42 +400,28 @@
data_type _len3 =
lensqr_3d(_p3, _p1) ;
- data_type _barA =
+ data_type _lbar =
_len1+_len2+_len3 ;
- data_type _barB =
- _len1*_len2*_len3 ;
-
- _barB = std::pow(
- _barB, (data_type)+1./3.);
-
data_type _area =
- tria_area_3d(_p1, _p2, _p3);
+ tria_area_3d(_p1, _p2, _p3) ;
- data_type _scrA =
- _mulA * _area / _barA ;
-
- data_type _scrB =
- _mulB * _area / _barB ;
-
- return
- ((data_type)+1.0-.33)*_scrA +
- ((data_type)+0.0+.33)*_scrB ;
+ return _mul * _area / _lbar ;
}
template <
typename data_type
>
- __normal_call
+ __inline_call
data_type tria_quality_3d (
__const_ptr (data_type) _p1,
__const_ptr (data_type) _p2,
__const_ptr (data_type) _p3,
__const_ptr (data_type) _p4
)
- {
- // 6. * std::sqrt(2.)
- data_type static
+ { // "volume-length" metric, see Shewchuk
+
+ data_type static // +6. * std::sqrt(2.)
constexpr _scal =
(data_type)+8.485281374238571 ;
@@ -315,9 +443,93 @@
return _scal * _tvol / _lrms ;
}
+ template <
+ typename data_type
+ >
+ __inline_call
+ data_type quad_quality_2d (
+ __const_ptr (data_type) _p1,
+ __const_ptr (data_type) _p2,
+ __const_ptr (data_type) _p3,
+ __const_ptr (data_type) _p4
+ )
+ { // mean sub-tria "volume-length" metrics
+
+ data_type static // +2. / std::sqrt(+3.)
+ constexpr _scal =
+ (data_type)+1.154700538379252 ;
+
+ data_type _val1 =
+ tria_quality_2d(_p1, _p2, _p3) ;
+
+ data_type _val2 =
+ tria_quality_2d(_p1, _p3, _p4) ;
+
+ data_type _val3 =
+ tria_quality_2d(_p1, _p2, _p4) ;
+
+ data_type _val4 =
+ tria_quality_2d(_p2, _p3, _p4) ;
+
+ data_type _vmin =
+ std::min(std::min(_val1, _val2),
+ std::min(_val3, _val4)) ;
+
+ data_type _prod =
+ _val1*_val2*_val3*_val4 ;
+
+ data_type _mean = _scal *
+ std::pow(std::abs(_prod), 1./4.) ;
+
+ return
+ (_vmin > 0.) ? +_mean : -_mean ;
+ }
+
+ template <
+ typename data_type
+ >
+ __inline_call
+ data_type quad_quality_3d (
+ __const_ptr (data_type) _p1,
+ __const_ptr (data_type) _p2,
+ __const_ptr (data_type) _p3,
+ __const_ptr (data_type) _p4
+ )
+ { // mean sub-tria "volume-length" metrics
+
+ data_type static // +2. / std::sqrt(+3.)
+ constexpr _scal =
+ (data_type)+1.154700538379252 ;
+
+ data_type _val1 =
+ tria_quality_3d(_p1, _p2, _p3) ;
+
+ data_type _val2 =
+ tria_quality_3d(_p1, _p3, _p4) ;
+
+ data_type _val3 =
+ tria_quality_3d(_p1, _p2, _p4) ;
+
+ data_type _val4 =
+ tria_quality_3d(_p2, _p3, _p4) ;
+
+ data_type _vmin =
+ std::min(std::min(_val1, _val2),
+ std::min(_val3, _val4)) ;
+
+ data_type _prod =
+ _val1*_val2*_val3*_val4 ;
+
+ data_type _mean = _scal *
+ std::pow(std::abs(_prod), 1./4.) ;
+
+ return
+ (_vmin > 0.) ? +_mean : -_mean ;
+ }
+
/*
--------------------------------------------------------
- * voro. "quality" scores.
+ * dual "quality" scores.
--------------------------------------------------------
*/
@@ -325,39 +537,27 @@
typename data_type
>
__normal_call
- data_type dual_quality_2d (
+ data_type tria_duality_2d (
__const_ptr (data_type) _p1,
__const_ptr (data_type) _p2,
__const_ptr (data_type) _p3
)
{
- data_type _ob[ +3] ;
- geometry::perp_ball_2d(_ob,
- _p1 , _p2, _p3);
-
- data_type _o1[ +3] ;
- geometry::perp_ball_2d(_o1,
- _p1 , _p2) ;
- data_type _o2[ +3] ;
- geometry::perp_ball_2d(_o2,
- _p2 , _p3) ;
- data_type _o3[ +3] ;
- geometry::perp_ball_2d(_o3,
- _p3 , _p1) ;
-
- data_type _mb[ +3] ;
- geometry::mass_ball_2d(_mb,
- _p1 , _p2, _p3);
-
- data_type _m1[ +3] ;
- geometry::mass_ball_2d(_m1,
- _p1 , _p2) ;
- data_type _m2[ +3] ;
- geometry::mass_ball_2d(_m2,
- _p2 , _p3) ;
- data_type _m3[ +3] ;
- geometry::mass_ball_2d(_m3,
- _p3 , _p1) ;
+ data_type _ob[3];
+ perp_ball_2d(_ob, _p1, _p2, _p3);
+
+ data_type _o1[3], _o2[3], _o3[3];
+ perp_ball_2d(_o1, _p1, _p2) ;
+ perp_ball_2d(_o2, _p2, _p3) ;
+ perp_ball_2d(_o3, _p3, _p1) ;
+
+ data_type _mb[3];
+ mass_ball_2d(_mb, _p1, _p2, _p3);
+
+ data_type _m1[3], _m2[3], _m3[3];
+ mass_ball_2d(_m1, _p1, _p2) ;
+ mass_ball_2d(_m2, _p2, _p3) ;
+ mass_ball_2d(_m3, _p3, _p1) ;
data_type _lb =
geometry::lensqr_2d(_ob, _mb) ;
@@ -389,48 +589,34 @@
((data_type)+1.-.33) * _qb +
((data_type)+0.+.33) * _qe ;
- _qq = (data_type)1.- _qq ;
-
- return _qq ;
+ return (data_type)1.-_qq ;
}
template <
typename data_type
>
__normal_call
- data_type dual_quality_3d (
+ data_type tria_duality_3d (
__const_ptr (data_type) _p1,
__const_ptr (data_type) _p2,
__const_ptr (data_type) _p3
)
{
- data_type _ob[ +4] ;
- geometry::perp_ball_3d(_ob,
- _p1 , _p2, _p3);
-
- data_type _o1[ +4] ;
- geometry::perp_ball_3d(_o1,
- _p1 , _p2) ;
- data_type _o2[ +4] ;
- geometry::perp_ball_3d(_o2,
- _p2 , _p3) ;
- data_type _o3[ +4] ;
- geometry::perp_ball_3d(_o3,
- _p3 , _p1) ;
-
- data_type _mb[ +4] ;
- geometry::mass_ball_3d(_mb,
- _p1 , _p2, _p3);
-
- data_type _m1[ +4] ;
- geometry::mass_ball_3d(_m1,
- _p1 , _p2) ;
- data_type _m2[ +4] ;
- geometry::mass_ball_3d(_m2,
- _p2 , _p3) ;
- data_type _m3[ +4] ;
- geometry::mass_ball_3d(_m3,
- _p3 , _p1) ;
+ data_type _ob[4];
+ perp_ball_3d(_ob, _p1, _p2, _p3);
+
+ data_type _o1[4], _o2[4], _o3[4];
+ perp_ball_3d(_o1, _p1, _p2) ;
+ perp_ball_3d(_o2, _p2, _p3) ;
+ perp_ball_3d(_o3, _p3, _p1) ;
+
+ data_type _mb[4];
+ mass_ball_3d(_mb, _p1, _p2, _p3);
+
+ data_type _m1[4], _m2[4], _m3[4];
+ mass_ball_3d(_m1, _p1, _p2) ;
+ mass_ball_3d(_m2, _p2, _p3) ;
+ mass_ball_3d(_m3, _p3, _p1) ;
data_type _lb =
geometry::lensqr_3d(_ob, _mb) ;
@@ -462,9 +648,7 @@
((data_type)+1.-.33) * _qb +
((data_type)+0.+.33) * _qe ;
- _qq = (data_type)1.- _qq ;
-
- return _qq ;
+ return (data_type)1.-_qq ;
}
/*
@@ -472,7 +656,7 @@
typename data_type
>
__normal_call
- data_type dual_quality_3d (
+ data_type tria_duality_3d (
__const_ptr (data_type) _p1,
__const_ptr (data_type) _p2,
__const_ptr (data_type) _p3,
@@ -487,6 +671,6 @@
}
-# endif//__TRIA_ELEM_K__
+# endif//__CELL_BASE_K__
diff --git a/external/jigsaw/src/libcpp/geom_base/intersect_k.hpp b/external/jigsaw/src/libcpp/geom_base/intersect_k.hpp
index b1e2238..0d74eee 100644
--- a/external/jigsaw/src/libcpp/geom_base/intersect_k.hpp
+++ b/external/jigsaw/src/libcpp/geom_base/intersect_k.hpp
@@ -35,7 +35,7 @@
*
* Copyright 2013-2019
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
--------------------------------------------------------
@@ -875,7 +875,7 @@
_qq[0] = _qt[0] ; \
_qq[1] = _qt[1] ; \
\
- _dm = _dd; \
+ _dm = _dd ; \
} \
}
@@ -981,7 +981,7 @@
_qq[1] = _qt[1] ; \
_qq[2] = _qt[2] ; \
\
- _dm = _dd; \
+ _dm = _dd ; \
} \
}
@@ -1163,7 +1163,7 @@
_qq[1] = _qt[1] ; \
_qq[2] = _qt[2] ; \
\
- _dm = _dd; \
+ _dm = _dd ; \
} \
}
diff --git a/external/jigsaw/src/libcpp/geom_base/predicate_k.hpp b/external/jigsaw/src/libcpp/geom_base/predicate_k.hpp
deleted file mode 100644
index 3423723..0000000
--- a/external/jigsaw/src/libcpp/geom_base/predicate_k.hpp
+++ /dev/null
@@ -1,3818 +0,0 @@
-/*****************************************************************************/
-/* */
-/* Routines for Arbitrary Precision Floating-point Arithmetic */
-/* and Fast Robust Geometric Predicates */
-/* (predicates.c) */
-/* */
-/* May 18, 1996 */
-/* */
-/* Placed in the public domain by */
-/* Jonathan Richard Shewchuk */
-/* School of Computer Science */
-/* Carnegie Mellon University */
-/* 5000 Forbes Avenue */
-/* Pittsburgh, Pennsylvania 15213-3891 */
-/* jrs@cs.cmu.edu */
-/* */
-/* This file contains C implementation of algorithms for exact addition */
-/* and multiplication of floating-point numbers, and predicates for */
-/* robustly performing the orientation and incircle tests used in */
-/* computational geometry. The algorithms and underlying theory are */
-/* described in Jonathan Richard Shewchuk. "Adaptive Precision Floating- */
-/* Point Arithmetic and Fast Robust Geometric Predicates." Technical */
-/* Report CMU-CS-96-140, School of Computer Science, Carnegie Mellon */
-/* University, Pittsburgh, Pennsylvania, May 1996. (Submitted to */
-/* Discrete & Computational Geometry.) */
-/* */
-/* This file, the paper listed above, and other information are available */
-/* from the Web page http://www.cs.cmu.edu/~quake/robust.html . */
-/* */
-/*****************************************************************************/
-
-/*****************************************************************************/
-/* */
-/* Using this code: */
-/* */
-/* First, read the short or long version of the paper (from the Web page */
-/* above). */
-/* */
-/* Be sure to call exactinit() once, before calling any of the arithmetic */
-/* functions or geometric predicates. Also be sure to turn on the */
-/* optimizer when compiling this file. */
-/* */
-/* */
-/* Several geometric predicates are defined. Their parameters are all */
-/* points. Each point is an array of two, three or four floating-point */
-/* numbers. The geometric predicates, described in the papers, are */
-/* */
-/* orient2d(pa, pb, pc) */
-/* orient3d(pa, pb, pc, pd) */
-/* orient4d(pa, pb, pc, pd, pe) */
-/* incircle(pa, pb, pc, pd) */
-/* insphere(pa, pb, pc, pd, pe) */
-/* regular2(pa, pb, pc, pd) */
-/* regular3(pa, pb, pc, pd, pe) */
-/* */
-/* */
-/* An expansion is represented by an array of floating-point numbers, */
-/* sorted from smallest to largest magnitude (possibly with interspersed */
-/* zeros). The length of each expansion is stored as a separate integer, */
-/* and each arithmetic function returns an integer which is the length */
-/* of the expansion it created. */
-/* */
-/* Several arithmetic functions are defined. Their parameters are */
-/* */
-/* e, f Input expansions */
-/* elen, flen Lengths of input expansions (must be >= 1) */
-/* h Output expansion */
-/* b Input scalar */
-/* */
-/* The arithmetic functions are */
-/* */
-/* grow_expansion(elen, e, b, h) */
-/* grow_expansion_zeroelim(elen, e, b, h) */
-/* expansion_sum(elen, e, flen, f, h) */
-/* expansion_sum_zeroelim1(elen, e, flen, f, h) */
-/* expansion_sum_zeroelim2(elen, e, flen, f, h) */
-/* fast_expansion_sum(elen, e, flen, f, h) */
-/* fast_expansion_sum_zeroelim(elen, e, flen, f, h) */
-/* linear_expansion_sum(elen, e, flen, f, h) */
-/* linear_expansion_sum_zeroelim(elen, e, flen, f, h) */
-/* scale_expansion(elen, e, b, h) */
-/* scale_expansion_zeroelim(elen, e, b, h) */
-/* compress(elen, e, h) */
-/* */
-/* All of these are described in the long version of the paper; some are */
-/* described in the short version. All return an integer that is the */
-/* length of h. Those with suffix _zeroelim perform zero elimination, */
-/* and are recommended over their counterparts. The procedure */
-/* fast_expansion_sum_zeroelim() (or linear_expansion_sum_zeroelim() on */
-/* processors that do not use the round-to-even tiebreaking rule) is */
-/* recommended over expansion_sum_zeroelim(). Each procedure has a */
-/* little note next to it (in the code below) that tells you whether or */
-/* not the output expansion may be the same array as one of the input */
-/* expansions. */
-/* */
-/* */
-/* If you look around below, you'll also find macros for a bunch of */
-/* simple unrolled arithmetic operations, and procedures for printing */
-/* expansions (commented out because they don't work with all C */
-/* compilers) and for generating random floating-point numbers whose */
-/* significand bits are all random. Most of the macros have undocumented */
-/* requirements that certain of their parameters should not be the same */
-/* variable; for safety, better to make sure all the parameters are */
-/* distinct variables. Feel free to send email to jrs@cs.cmu.edu if you */
-/* have questions. */
-/* */
-/*****************************************************************************/
-
-#pragma once
-
-#ifndef __GEOMPRED__
-#define __GEOMPRED__
-
-#include
-#include
-#include
-
-namespace geompred
-{
-
-#define REAL double /* float or double */
-
-/* Which of the following two methods of finding the absolute values is */
-/* fastest is compiler-dependent. A few compilers can inline and optimize */
-/* the fabs() call; but most will incur the overhead of a function call, */
-/* which is disastrously slow. A faster way on IEEE machines might be to */
-/* mask the appropriate bit, but that's difficult to do in C. */
-
-#define Absolute(a) ((a) >= 0.0 ? (a) : -(a))
-
-/* Many of the operations are broken up into two pieces, a main part that */
-/* performs an approximate operation, and a "tail" that computes the */
-/* roundoff error of that operation. */
-/* */
-/* The operations Fast_Two_Sum(), Fast_Two_Diff(), Two_Sum(), Two_Diff(), */
-/* Split(), and Two_Product() are all implemented as described in the */
-/* reference. Each of these macros requires certain variables to be */
-/* defined in the calling routine. The variables `bvirt', `c', `abig', */
-/* `_i', `_j', `_k', `_l', `_m', and `_n' are declared `INEXACT' because */
-/* they store the result of an operation that may incur roundoff error. */
-/* The input parameter `x' (or the highest numbered `x_' parameter) must */
-/* also be declared `INEXACT'. */
-
-#define Fast_Two_Sum_Tail(a, b, x, y) \
- bvirt = x - a; \
- y = b - bvirt
-
-#define Fast_Two_Sum(a, b, x, y) \
- x = (REAL) (a + b); \
- Fast_Two_Sum_Tail(a, b, x, y)
-
-#define Fast_Two_Diff_Tail(a, b, x, y) \
- bvirt = a - x; \
- y = bvirt - b
-
-#define Fast_Two_Diff(a, b, x, y) \
- x = (REAL) (a - b); \
- Fast_Two_Diff_Tail(a, b, x, y)
-
-#define Two_Sum_Tail(a, b, x, y) \
- bvirt = (REAL) (x - a); \
- avirt = x - bvirt; \
- bround = b - bvirt; \
- around = a - avirt; \
- y = around + bround
-
-#define Two_Sum(a, b, x, y) \
- x = (REAL) (a + b); \
- Two_Sum_Tail(a, b, x, y)
-
-#define Two_Diff_Tail(a, b, x, y) \
- bvirt = (REAL) (a - x); \
- avirt = x + bvirt; \
- bround = bvirt - b; \
- around = a - avirt; \
- y = around + bround
-
-#define Two_Diff(a, b, x, y) \
- x = (REAL) (a - b); \
- Two_Diff_Tail(a, b, x, y)
-
-#define Split(a, ahi, alo) \
- c = (REAL) (splitter * a); \
- abig = (REAL) (c - a); \
- ahi = c - abig; \
- alo = a - ahi
-
-#define Two_Product_Tail(a, b, x, y) \
- Split(a, ahi, alo); \
- Split(b, bhi, blo); \
- err1 = x - (ahi * bhi); \
- err2 = err1 - (alo * bhi); \
- err3 = err2 - (ahi * blo); \
- y = (alo * blo) - err3
-
-#define Two_Product(a, b, x, y) \
- x = (REAL) (a * b); \
- Two_Product_Tail(a, b, x, y)
-
-/* Two_Product_Presplit() is Two_Product() where one of the inputs has */
-/* already been split. Avoids redundant splitting. */
-
-#define Two_Product_Presplit(a, b, bhi, blo, x, y) \
- x = (REAL) (a * b); \
- Split(a, ahi, alo); \
- err1 = x - (ahi * bhi); \
- err2 = err1 - (alo * bhi); \
- err3 = err2 - (ahi * blo); \
- y = (alo * blo) - err3
-
-/* Two_Product_2Presplit() is Two_Product() where both of the inputs have */
-/* already been split. Avoids redundant splitting. */
-
-#define Two_Product_2Presplit(a, ahi, alo, b, bhi, blo, x, y) \
- x = (REAL) (a * b); \
- err1 = x - (ahi * bhi); \
- err2 = err1 - (alo * bhi); \
- err3 = err2 - (ahi * blo); \
- y = (alo * blo) - err3
-
-/* Square() can be done more quickly than Two_Product(). */
-
-#define Square_Tail(a, x, y) \
- Split(a, ahi, alo); \
- err1 = x - (ahi * ahi); \
- err3 = err1 - ((ahi + ahi) * alo); \
- y = (alo * alo) - err3
-
-#define Square(a, x, y) \
- x = (REAL) (a * a); \
- Square_Tail(a, x, y)
-
-/* Macros for summing expansions of various fixed lengths. These are all */
-/* unrolled versions of Expansion_Sum(). */
-
-#define Two_One_Sum(a1, a0, b, x2, x1, x0) \
- Two_Sum(a0, b , _i, x0); \
- Two_Sum(a1, _i, x2, x1)
-
-#define Two_One_Diff(a1, a0, b, x2, x1, x0) \
- Two_Diff(a0, b , _i, x0); \
- Two_Sum( a1, _i, x2, x1)
-
-#define Two_Two_Sum(a1, a0, b1, b0, x3, x2, x1, x0) \
- Two_One_Sum(a1, a0, b0, _j, _0, x0); \
- Two_One_Sum(_j, _0, b1, x3, x2, x1)
-
-#define Two_Two_Diff(a1, a0, b1, b0, x3, x2, x1, x0) \
- Two_One_Diff(a1, a0, b0, _j, _0, x0); \
- Two_One_Diff(_j, _0, b1, x3, x2, x1)
-
-#define Four_One_Sum(a3, a2, a1, a0, b, x4, x3, x2, x1, x0) \
- Two_One_Sum(a1, a0, b , _j, x1, x0); \
- Two_One_Sum(a3, a2, _j, x4, x3, x2)
-
-#define Four_Two_Sum(a3, a2, a1, a0, b1, b0, x5, x4, x3, x2, x1, x0) \
- Four_One_Sum(a3, a2, a1, a0, b0, _k, _2, _1, _0, x0); \
- Four_One_Sum(_k, _2, _1, _0, b1, x5, x4, x3, x2, x1)
-
-#define Four_Four_Sum(a3, a2, a1, a0, b4, b3, b1, b0, x7, x6, x5, x4, x3, x2, \
- x1, x0) \
- Four_Two_Sum(a3, a2, a1, a0, b1, b0, _l, _2, _1, _0, x1, x0); \
- Four_Two_Sum(_l, _2, _1, _0, b4, b3, x7, x6, x5, x4, x3, x2)
-
-#define Eight_One_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b, x8, x7, x6, x5, x4, \
- x3, x2, x1, x0) \
- Four_One_Sum(a3, a2, a1, a0, b , _j, x3, x2, x1, x0); \
- Four_One_Sum(a7, a6, a5, a4, _j, x8, x7, x6, x5, x4)
-
-#define Eight_Two_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b1, b0, x9, x8, x7, \
- x6, x5, x4, x3, x2, x1, x0) \
- Eight_One_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b0, _k, _6, _5, _4, _3, _2, \
- _1, _0, x0); \
- Eight_One_Sum(_k, _6, _5, _4, _3, _2, _1, _0, b1, x9, x8, x7, x6, x5, x4, \
- x3, x2, x1)
-
-#define Eight_Four_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b4, b3, b1, b0, x11, \
- x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, x0) \
- Eight_Two_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b1, b0, _l, _6, _5, _4, _3, \
- _2, _1, _0, x1, x0); \
- Eight_Two_Sum(_l, _6, _5, _4, _3, _2, _1, _0, b4, b3, x11, x10, x9, x8, \
- x7, x6, x5, x4, x3, x2)
-
-/* Macros for multiplying expansions of various fixed lengths. */
-
-#define Two_One_Product(a1, a0, b, x3, x2, x1, x0) \
- Split(b, bhi, blo); \
- Two_Product_Presplit(a0, b, bhi, blo, _i, x0); \
- Two_Product_Presplit(a1, b, bhi, blo, _j, _0); \
- Two_Sum(_i, _0, _k, x1); \
- Fast_Two_Sum(_j, _k, x3, x2)
-
-#define Four_One_Product(a3, a2, a1, a0, b, x7, x6, x5, x4, x3, x2, x1, x0) \
- Split(b, bhi, blo); \
- Two_Product_Presplit(a0, b, bhi, blo, _i, x0); \
- Two_Product_Presplit(a1, b, bhi, blo, _j, _0); \
- Two_Sum(_i, _0, _k, x1); \
- Fast_Two_Sum(_j, _k, _i, x2); \
- Two_Product_Presplit(a2, b, bhi, blo, _j, _0); \
- Two_Sum(_i, _0, _k, x3); \
- Fast_Two_Sum(_j, _k, _i, x4); \
- Two_Product_Presplit(a3, b, bhi, blo, _j, _0); \
- Two_Sum(_i, _0, _k, x5); \
- Fast_Two_Sum(_j, _k, x7, x6)
-
-#define Two_Two_Product(a1, a0, b1, b0, x7, x6, x5, x4, x3, x2, x1, x0) \
- Split(a0, a0hi, a0lo); \
- Split(b0, bhi, blo); \
- Two_Product_2Presplit(a0, a0hi, a0lo, b0, bhi, blo, _i, x0); \
- Split(a1, a1hi, a1lo); \
- Two_Product_2Presplit(a1, a1hi, a1lo, b0, bhi, blo, _j, _0); \
- Two_Sum(_i, _0, _k, _1); \
- Fast_Two_Sum(_j, _k, _l, _2); \
- Split(b1, bhi, blo); \
- Two_Product_2Presplit(a0, a0hi, a0lo, b1, bhi, blo, _i, _0); \
- Two_Sum(_1, _0, _k, x1); \
- Two_Sum(_2, _k, _j, _1); \
- Two_Sum(_l, _j, _m, _2); \
- Two_Product_2Presplit(a1, a1hi, a1lo, b1, bhi, blo, _j, _0); \
- Two_Sum(_i, _0, _n, _0); \
- Two_Sum(_1, _0, _i, x2); \
- Two_Sum(_2, _i, _k, _1); \
- Two_Sum(_m, _k, _l, _2); \
- Two_Sum(_j, _n, _k, _0); \
- Two_Sum(_1, _0, _j, x3); \
- Two_Sum(_2, _j, _i, _1); \
- Two_Sum(_l, _i, _m, _2); \
- Two_Sum(_1, _k, _i, x4); \
- Two_Sum(_2, _i, _k, x5); \
- Two_Sum(_m, _k, x7, x6)
-
-/* An expansion of length two can be squared more quickly than finding the */
-/* product of two different expansions of length two, and the result is */
-/* guaranteed to have no more than six (rather than eight) components. */
-
-#define Two_Square(a1, a0, x5, x4, x3, x2, x1, x0) \
- Square(a0, _j, x0); \
- _0 = a0 + a0; \
- Two_Product(a1, _0, _k, _1); \
- Two_One_Sum(_k, _1, _j, _l, _2, x1); \
- Square(a1, _j, _1); \
- Two_Two_Sum(_j, _1, _l, _2, x5, x4, x3, x2)
-
-REAL splitter; /* = 2^ceiling(p / 2) + 1. Used to split floats in half. */
-REAL epsilon; /* = 2^(-p). Used to estimate roundoff errors. */
-/* A set of coefficients used to calculate maximum roundoff errors. */
-REAL resulterrbound;
-REAL o2derrboundA, o2derrboundB, o2derrboundC;
-REAL o3derrboundA, o3derrboundB, o3derrboundC;
-REAL iccerrboundA, iccerrboundB, iccerrboundC;
-REAL isperrboundA, isperrboundB, isperrboundC;
-
-/*****************************************************************************/
-/* */
-/* exactinit() Initialize the variables used for exact arithmetic. */
-/* */
-/* `epsilon' is the largest power of two such that 1.0 + epsilon = 1.0 in */
-/* floating-point arithmetic. `epsilon' bounds the relative roundoff */
-/* error. It is used for floating-point error analysis. */
-/* */
-/* `splitter' is used to split floating-point numbers into two half- */
-/* length significands for exact multiplication. */
-/* */
-/* I imagine that a highly optimizing compiler might be too smart for its */
-/* own good, and somehow cause this routine to fail, if it pretends that */
-/* floating-point arithmetic is too much like real arithmetic. */
-/* */
-/* Don't change this routine unless you fully understand it. */
-/* */
-/*****************************************************************************/
-
-void exactinit()
-{
- REAL half;
- REAL check, lastcheck;
- int every_other;
-#ifdef LINUX
- int cword;
-#endif /* LINUX */
-
-#ifdef CPU86
-#ifdef SINGLE
- _control87(_PC_24, _MCW_PC); /* Set FPU control word for single precision. */
-#else /* not SINGLE */
- _control87(_PC_53, _MCW_PC); /* Set FPU control word for double precision. */
-#endif /* not SINGLE */
-#endif /* CPU86 */
-#ifdef LINUX
-#ifdef SINGLE
- /* cword = 4223; */
- cword = 4210; /* set FPU control word for single precision */
-#else /* not SINGLE */
- /* cword = 4735; */
- cword = 4722; /* set FPU control word for double precision */
-#endif /* not SINGLE */
- _FPU_SETCW(cword);
-#endif /* LINUX */
-
- every_other = 1;
- half = 0.5;
- epsilon = 1.0;
- splitter = 1.0;
- check = 1.0;
-
- /* Repeatedly divide `epsilon' by two until it is too small to add to */
- /* one without causing roundoff. (Also check if the sum is equal to */
- /* the previous sum, for machines that round up instead of using exact */
- /* rounding. Not that these routines will work on such machines.) */
- do {
- lastcheck = check;
- epsilon *= half;
- if (every_other) {
- splitter *= 2.0;
- }
- every_other = !every_other;
- check = 1.0 + epsilon;
- } while ((check != 1.0) && (check != lastcheck));
- splitter += 1.0;
-
- /* Error bounds for orientation and insphere tests. */
- resulterrbound = (3.0 + 8.0 * epsilon) * epsilon;
- o2derrboundA = (3.0 + 16.0 * epsilon) * epsilon;
- o2derrboundB = (2.0 + 12.0 * epsilon) * epsilon;
- o2derrboundC = (9.0 + 64.0 * epsilon) * epsilon * epsilon;
- o3derrboundA = (7.0 + 56.0 * epsilon) * epsilon;
- o3derrboundB = (3.0 + 28.0 * epsilon) * epsilon;
- o3derrboundC = (26.0 + 288.0 * epsilon) * epsilon * epsilon;
- isperrboundA = (16.0 + 224.0 * epsilon) * epsilon;
- isperrboundB = (5.0 + 72.0 * epsilon) * epsilon;
- isperrboundC = (71.0 + 1408.0 * epsilon) * epsilon * epsilon;
-}
-
-/*****************************************************************************/
-/* */
-/* grow_expansion() Add a scalar to an expansion. */
-/* */
-/* Sets h = e + b. See the long version of my paper for details. */
-/* */
-/* Maintains the nonoverlapping property. If round-to-even is used (as */
-/* with IEEE 754), maintains the strongly nonoverlapping and nonadjacent */
-/* properties as well. (That is, if e has one of these properties, so */
-/* will h.) */
-/* */
-/*****************************************************************************/
-
-int grow_expansion (
- int elen,
- __const_ptr(REAL) e ,
- REAL b ,
- __write_ptr(REAL) h ) /* e and h can be the same. */
-{
- REAL Q, Qnew;
- int eindex;
- REAL enow;
- REAL bvirt, avirt, bround, around;
-
- Q = b;
- for (eindex = 0; eindex < elen; eindex++) {
- enow = e[eindex];
- Two_Sum(Q, enow, Qnew, h[eindex]);
- Q = Qnew;
- }
- h[eindex] = Q;
- return eindex + 1;
-}
-
-/*****************************************************************************/
-/* */
-/* grow_expansion_zeroelim() Add a scalar to an expansion, eliminating */
-/* zero components from the output expansion. */
-/* */
-/* Sets h = e + b. See the long version of my paper for details. */
-/* */
-/* Maintains the nonoverlapping property. If round-to-even is used (as */
-/* with IEEE 754), maintains the strongly nonoverlapping and nonadjacent */
-/* properties as well. (That is, if e has one of these properties, so */
-/* will h.) */
-/* */
-/*****************************************************************************/
-
-int grow_expansion_zeroelim (
- int elen,
- __const_ptr(REAL) e ,
- REAL b ,
- __write_ptr(REAL) h ) /* e and h can be the same. */
-{
- REAL Q, hh, Qnew;
- int eindex, hindex;
- REAL enow;
- REAL bvirt, avirt, bround, around;
-
- hindex = 0;
- Q = b;
- for (eindex = 0; eindex < elen; eindex++) {
- enow = e[eindex];
- Two_Sum(Q, enow, Qnew, hh);
- Q = Qnew;
- if (hh != 0.0) {
- h[hindex++] = hh;
- }
- }
- if ((Q != 0.0) || (hindex == 0)) {
- h[hindex++] = Q;
- }
- return hindex;
-}
-
-/*****************************************************************************/
-/* */
-/* expansion_sum() Sum two expansions. */
-/* */
-/* Sets h = e + f. See the long version of my paper for details. */
-/* */
-/* Maintains the nonoverlapping property. If round-to-even is used (as */
-/* with IEEE 754), maintains the nonadjacent property as well. (That is, */
-/* if e has one of these properties, so will h.) Does NOT maintain the */
-/* strongly nonoverlapping property. */
-/* */
-/*****************************************************************************/
-
-int expansion_sum (
- int elen,
- __const_ptr(REAL) e ,
- int flen,
- __const_ptr(REAL) f ,
- __write_ptr(REAL) h )
-/* e and h can be the same, but f and h cannot. */
-{
- REAL Q, Qnew;
- int findex, hindex, hlast;
- REAL hnow;
- REAL bvirt, avirt, bround, around;
-
- Q = f[0];
- for (hindex = 0; hindex < elen; hindex++) {
- hnow = e[hindex];
- Two_Sum(Q, hnow, Qnew, h[hindex]);
- Q = Qnew;
- }
- h[hindex] = Q;
- hlast = hindex;
- for (findex = 1; findex < flen; findex++) {
- Q = f[findex];
- for (hindex = findex; hindex <= hlast; hindex++) {
- hnow = h[hindex];
- Two_Sum(Q, hnow, Qnew, h[hindex]);
- Q = Qnew;
- }
- h[++hlast] = Q;
- }
- return hlast + 1;
-}
-
-/*****************************************************************************/
-/* */
-/* expansion_sum_zeroelim1() Sum two expansions, eliminating zero */
-/* components from the output expansion. */
-/* */
-/* Sets h = e + f. See the long version of my paper for details. */
-/* */
-/* Maintains the nonoverlapping property. If round-to-even is used (as */
-/* with IEEE 754), maintains the nonadjacent property as well. (That is, */
-/* if e has one of these properties, so will h.) Does NOT maintain the */
-/* strongly nonoverlapping property. */
-/* */
-/*****************************************************************************/
-
-int expansion_sum_zeroelim1 (
- int elen,
- __const_ptr(REAL) e ,
- int flen,
- __const_ptr(REAL) f ,
- __write_ptr(REAL) h )
-/* e and h can be the same, but f and h cannot. */
-{
- REAL Q, Qnew;
- int index, findex, hindex, hlast;
- REAL hnow;
- REAL bvirt, avirt, bround, around;
-
- Q = f[0];
- for (hindex = 0; hindex < elen; hindex++) {
- hnow = e[hindex];
- Two_Sum(Q, hnow, Qnew, h[hindex]);
- Q = Qnew;
- }
- h[hindex] = Q;
- hlast = hindex;
- for (findex = 1; findex < flen; findex++) {
- Q = f[findex];
- for (hindex = findex; hindex <= hlast; hindex++) {
- hnow = h[hindex];
- Two_Sum(Q, hnow, Qnew, h[hindex]);
- Q = Qnew;
- }
- h[++hlast] = Q;
- }
- hindex = -1;
- for (index = 0; index <= hlast; index++) {
- hnow = h[index];
- if (hnow != 0.0) {
- h[++hindex] = hnow;
- }
- }
- if (hindex == -1) {
- return 1;
- } else {
- return hindex + 1;
- }
-}
-
-/*****************************************************************************/
-/* */
-/* expansion_sum_zeroelim2() Sum two expansions, eliminating zero */
-/* components from the output expansion. */
-/* */
-/* Sets h = e + f. See the long version of my paper for details. */
-/* */
-/* Maintains the nonoverlapping property. If round-to-even is used (as */
-/* with IEEE 754), maintains the nonadjacent property as well. (That is, */
-/* if e has one of these properties, so will h.) Does NOT maintain the */
-/* strongly nonoverlapping property. */
-/* */
-/*****************************************************************************/
-
-int expansion_sum_zeroelim2 (
- int elen,
- __const_ptr(REAL) e ,
- int flen,
- __const_ptr(REAL) f ,
- __write_ptr(REAL) h )
-/* e and h can be the same, but f and h cannot. */
-{
- REAL Q, hh, Qnew;
- int eindex, findex, hindex, hlast;
- REAL enow;
- REAL bvirt, avirt, bround, around;
-
- hindex = 0;
- Q = f[0];
- for (eindex = 0; eindex < elen; eindex++) {
- enow = e[eindex];
- Two_Sum(Q, enow, Qnew, hh);
- Q = Qnew;
- if (hh != 0.0) {
- h[hindex++] = hh;
- }
- }
- h[hindex] = Q;
- hlast = hindex;
- for (findex = 1; findex < flen; findex++) {
- hindex = 0;
- Q = f[findex];
- for (eindex = 0; eindex <= hlast; eindex++) {
- enow = h[eindex];
- Two_Sum(Q, enow, Qnew, hh);
- Q = Qnew;
- if (hh != 0) {
- h[hindex++] = hh;
- }
- }
- h[hindex] = Q;
- hlast = hindex;
- }
- return hlast + 1;
-}
-
-/*****************************************************************************/
-/* */
-/* fast_expansion_sum() Sum two expansions. */
-/* */
-/* Sets h = e + f. See the long version of my paper for details. */
-/* */
-/* If round-to-even is used (as with IEEE 754), maintains the strongly */
-/* nonoverlapping property. (That is, if e is strongly nonoverlapping, h */
-/* will be also.) Does NOT maintain the nonoverlapping or nonadjacent */
-/* properties. */
-/* */
-/*****************************************************************************/
-
-int fast_expansion_sum (
- int elen,
- __const_ptr(REAL) e ,
- int flen,
- __const_ptr(REAL) f ,
- __write_ptr(REAL) h ) /* h cannot be e or f. */
-{
- REAL Q, Qnew;
- REAL bvirt, avirt, bround, around;
- int eindex, findex, hindex;
- REAL enow, fnow;
-
- enow = e[0];
- fnow = f[0];
- eindex = findex = 0;
- if ((fnow > enow) == (fnow > -enow)) {
- Q = enow;
- enow = e[++eindex];
- } else {
- Q = fnow;
- fnow = f[++findex];
- }
- hindex = 0;
- if ((eindex < elen) && (findex < flen)) {
- if ((fnow > enow) == (fnow > -enow)) {
- Fast_Two_Sum(enow, Q, Qnew, h[0]);
- enow = e[++eindex];
- } else {
- Fast_Two_Sum(fnow, Q, Qnew, h[0]);
- fnow = f[++findex];
- }
- Q = Qnew;
- hindex = 1;
- while ((eindex < elen) && (findex < flen)) {
- if ((fnow > enow) == (fnow > -enow)) {
- Two_Sum(Q, enow, Qnew, h[hindex]);
- enow = e[++eindex];
- } else {
- Two_Sum(Q, fnow, Qnew, h[hindex]);
- fnow = f[++findex];
- }
- Q = Qnew;
- hindex++;
- }
- }
- while (eindex < elen) {
- Two_Sum(Q, enow, Qnew, h[hindex]);
- enow = e[++eindex];
- Q = Qnew;
- hindex++;
- }
- while (findex < flen) {
- Two_Sum(Q, fnow, Qnew, h[hindex]);
- fnow = f[++findex];
- Q = Qnew;
- hindex++;
- }
- h[hindex] = Q;
- return hindex + 1;
-}
-
-/*****************************************************************************/
-/* */
-/* fast_expansion_sum_zeroelim() Sum two expansions, eliminating zero */
-/* components from the output expansion. */
-/* */
-/* Sets h = e + f. See the long version of my paper for details. */
-/* */
-/* If round-to-even is used (as with IEEE 754), maintains the strongly */
-/* nonoverlapping property. (That is, if e is strongly nonoverlapping, h */
-/* will be also.) Does NOT maintain the nonoverlapping or nonadjacent */
-/* properties. */
-/* */
-/*****************************************************************************/
-
-int fast_expansion_sum_zeroelim (
- int elen,
- __const_ptr(REAL) e ,
- int flen,
- __const_ptr(REAL) f ,
- __write_ptr(REAL) h ) /* h cannot be e or f. */
-{
- REAL Q, Qnew, hh;
- REAL bvirt, avirt, bround, around;
- int eindex, findex, hindex;
- REAL enow, fnow;
-
- enow = e[0];
- fnow = f[0];
- eindex = findex = 0;
- if ((fnow > enow) == (fnow > -enow)) {
- Q = enow;
- enow = e[++eindex];
- } else {
- Q = fnow;
- fnow = f[++findex];
- }
- hindex = 0;
- if ((eindex < elen) && (findex < flen)) {
- if ((fnow > enow) == (fnow > -enow)) {
- Fast_Two_Sum(enow, Q, Qnew, hh);
- enow = e[++eindex];
- } else {
- Fast_Two_Sum(fnow, Q, Qnew, hh);
- fnow = f[++findex];
- }
- Q = Qnew;
- if (hh != 0.0) {
- h[hindex++] = hh;
- }
- while ((eindex < elen) && (findex < flen)) {
- if ((fnow > enow) == (fnow > -enow)) {
- Two_Sum(Q, enow, Qnew, hh);
- enow = e[++eindex];
- } else {
- Two_Sum(Q, fnow, Qnew, hh);
- fnow = f[++findex];
- }
- Q = Qnew;
- if (hh != 0.0) {
- h[hindex++] = hh;
- }
- }
- }
- while (eindex < elen) {
- Two_Sum(Q, enow, Qnew, hh);
- enow = e[++eindex];
- Q = Qnew;
- if (hh != 0.0) {
- h[hindex++] = hh;
- }
- }
- while (findex < flen) {
- Two_Sum(Q, fnow, Qnew, hh);
- fnow = f[++findex];
- Q = Qnew;
- if (hh != 0.0) {
- h[hindex++] = hh;
- }
- }
- if ((Q != 0.0) || (hindex == 0)) {
- h[hindex++] = Q;
- }
- return hindex;
-}
-
-/*****************************************************************************/
-/* */
-/* linear_expansion_sum() Sum two expansions. */
-/* */
-/* Sets h = e + f. See either version of my paper for details. */
-/* */
-/* Maintains the nonoverlapping property. (That is, if e is */
-/* nonoverlapping, h will be also.) */
-/* */
-/*****************************************************************************/
-
-int linear_expansion_sum (
- int elen,
- __const_ptr(REAL) e ,
- int flen,
- __const_ptr(REAL) f ,
- __write_ptr(REAL) h ) /* h cannot be e or f. */
-{
- REAL Q, q, Qnew, R;
- REAL bvirt, avirt, bround, around;
- int eindex, findex, hindex;
- REAL enow, fnow, g0;
-
- enow = e[0];
- fnow = f[0];
- eindex = findex = 0;
- if ((fnow > enow) == (fnow > -enow)) {
- g0 = enow;
- enow = e[++eindex];
- } else {
- g0 = fnow;
- fnow = f[++findex];
- }
- if ((eindex < elen) && ((findex >= flen)
- || ((fnow > enow) == (fnow > -enow)))) {
- Fast_Two_Sum(enow, g0, Qnew, q);
- enow = e[++eindex];
- } else {
- Fast_Two_Sum(fnow, g0, Qnew, q);
- fnow = f[++findex];
- }
- Q = Qnew;
- for (hindex = 0; hindex < elen + flen - 2; hindex++) {
- if ((eindex < elen) && ((findex >= flen)
- || ((fnow > enow) == (fnow > -enow)))) {
- Fast_Two_Sum(enow, q, R, h[hindex]);
- enow = e[++eindex];
- } else {
- Fast_Two_Sum(fnow, q, R, h[hindex]);
- fnow = f[++findex];
- }
- Two_Sum(Q, R, Qnew, q);
- Q = Qnew;
- }
- h[hindex] = q;
- h[hindex + 1] = Q;
- return hindex + 2;
-}
-
-/*****************************************************************************/
-/* */
-/* linear_expansion_sum_zeroelim() Sum two expansions, eliminating zero */
-/* components from the output expansion. */
-/* */
-/* Sets h = e + f. See either version of my paper for details. */
-/* */
-/* Maintains the nonoverlapping property. (That is, if e is */
-/* nonoverlapping, h will be also.) */
-/* */
-/*****************************************************************************/
-
-int linear_expansion_sum_zeroelim (
- int elen,
- __const_ptr(REAL) e ,
- int flen,
- __const_ptr(REAL) f ,
- __write_ptr(REAL) h ) /* h cannot be e or f. */
-{
- REAL Q, q, hh, Qnew, R;
- REAL bvirt, avirt, bround, around;
- int eindex, findex, hindex;
- int count;
- REAL enow, fnow, g0;
-
- enow = e[0];
- fnow = f[0];
- eindex = findex = 0;
- hindex = 0;
- if ((fnow > enow) == (fnow > -enow)) {
- g0 = enow;
- enow = e[++eindex];
- } else {
- g0 = fnow;
- fnow = f[++findex];
- }
- if ((eindex < elen) && ((findex >= flen)
- || ((fnow > enow) == (fnow > -enow)))) {
- Fast_Two_Sum(enow, g0, Qnew, q);
- enow = e[++eindex];
- } else {
- Fast_Two_Sum(fnow, g0, Qnew, q);
- fnow = f[++findex];
- }
- Q = Qnew;
- for (count = 2; count < elen + flen; count++) {
- if ((eindex < elen) && ((findex >= flen)
- || ((fnow > enow) == (fnow > -enow)))) {
- Fast_Two_Sum(enow, q, R, hh);
- enow = e[++eindex];
- } else {
- Fast_Two_Sum(fnow, q, R, hh);
- fnow = f[++findex];
- }
- Two_Sum(Q, R, Qnew, q);
- Q = Qnew;
- if (hh != 0) {
- h[hindex++] = hh;
- }
- }
- if (q != 0) {
- h[hindex++] = q;
- }
- if ((Q != 0.0) || (hindex == 0)) {
- h[hindex++] = Q;
- }
- return hindex;
-}
-
-/*****************************************************************************/
-/* */
-/* scale_expansion() Multiply an expansion by a scalar. */
-/* */
-/* Sets h = be. See either version of my paper for details. */
-/* */
-/* Maintains the nonoverlapping property. If round-to-even is used (as */
-/* with IEEE 754), maintains the strongly nonoverlapping and nonadjacent */
-/* properties as well. (That is, if e has one of these properties, so */
-/* will h.) */
-/* */
-/*****************************************************************************/
-
-int scale_expansion (
- int elen,
- __const_ptr(REAL) e ,
- REAL b ,
- __write_ptr(REAL) h ) /* e and h cannot be the same. */
-{
- REAL Q, sum, product1, product0;
- int eindex, hindex;
- REAL enow;
- REAL bvirt, avirt, bround, around;
- REAL c, abig, ahi, alo, bhi, blo;
- REAL err1, err2, err3;
-
- Split(b, bhi, blo);
- Two_Product_Presplit(e[0], b, bhi, blo, Q, h[0]);
- hindex = 1;
- for (eindex = 1; eindex < elen; eindex++) {
- enow = e[eindex];
- Two_Product_Presplit(enow, b, bhi, blo, product1, product0);
- Two_Sum(Q, product0, sum, h[hindex]);
- hindex++;
- Two_Sum(product1, sum, Q, h[hindex]);
- hindex++;
- }
- h[hindex] = Q;
- return elen + elen;
-}
-
-/*****************************************************************************/
-/* */
-/* scale_expansion_zeroelim() Multiply an expansion by a scalar, */
-/* eliminating zero components from the */
-/* output expansion. */
-/* */
-/* Sets h = be. See either version of my paper for details. */
-/* */
-/* Maintains the nonoverlapping property. If round-to-even is used (as */
-/* with IEEE 754), maintains the strongly nonoverlapping and nonadjacent */
-/* properties as well. (That is, if e has one of these properties, so */
-/* will h.) */
-/* */
-/*****************************************************************************/
-
-int scale_expansion_zeroelim (
- int elen,
- __const_ptr(REAL) e ,
- REAL b ,
- __write_ptr(REAL) h ) /* e and h cannot be the same. */
-{
- REAL Q, sum, hh;
- REAL product1, product0;
- int eindex, hindex;
- REAL enow;
- REAL bvirt, avirt, bround, around;
- REAL c, abig, ahi, alo, bhi, blo;
- REAL err1, err2, err3;
-
- Split(b, bhi, blo);
- Two_Product_Presplit(e[0], b, bhi, blo, Q, hh);
- hindex = 0;
- if (hh != 0) {
- h[hindex++] = hh;
- }
- for (eindex = 1; eindex < elen; eindex++) {
- enow = e[eindex];
- Two_Product_Presplit(enow, b, bhi, blo, product1, product0);
- Two_Sum(Q, product0, sum, hh);
- if (hh != 0) {
- h[hindex++] = hh;
- }
- Fast_Two_Sum(product1, sum, Q, hh);
- if (hh != 0) {
- h[hindex++] = hh;
- }
- }
- if ((Q != 0.0) || (hindex == 0)) {
- h[hindex++] = Q;
- }
- return hindex;
-}
-
-/*****************************************************************************/
-/* */
-/* compress() Compress an expansion. */
-/* */
-/* See the long version of my paper for details. */
-/* */
-/* Maintains the nonoverlapping property. If round-to-even is used (as */
-/* with IEEE 754), then any nonoverlapping expansion is converted to a */
-/* nonadjacent expansion. */
-/* */
-/*****************************************************************************/
-
-int compress (
- int elen,
- __const_ptr(REAL) e ,
- __write_ptr(REAL) h ) /* e and h may be the same. */
-{
- REAL Q, q, Qnew;
- int eindex, hindex;
- REAL bvirt;
- REAL enow, hnow;
- int top, bottom;
-
- bottom = elen - 1;
- Q = e[bottom];
- for (eindex = elen - 2; eindex >= 0; eindex--) {
- enow = e[eindex];
- Fast_Two_Sum(Q, enow, Qnew, q);
- if (q != 0) {
- h[bottom--] = Qnew;
- Q = q;
- } else {
- Q = Qnew;
- }
- }
- top = 0;
- for (hindex = bottom + 1; hindex < elen; hindex++) {
- hnow = h[hindex];
- Fast_Two_Sum(hnow, Q, Qnew, q);
- if (q != 0) {
- h[top++] = q;
- }
- Q = Qnew;
- }
- h[top] = Q;
- return top + 1;
-}
-
-/*****************************************************************************/
-/* */
-/* estimate() Produce a one-word estimate of an expansion's value. */
-/* */
-/* See either version of my paper for details. */
-/* */
-/*****************************************************************************/
-
-REAL estimate (
- int elen,
- __const_ptr(REAL) e )
-{
- REAL Q;
- int eindex;
-
- Q = e[0];
- for (eindex = 1; eindex < elen; eindex++) {
- Q += e[eindex];
- }
- return Q;
-}
-
-/*****************************************************************************/
-/* */
-/* orient2d() Adaptive exact 2D orientation test. Robust. */
-/* */
-/* Return a positive value if the points pa, pb, and pc occur */
-/* in counterclockwise order; a negative value if they occur */
-/* in clockwise order; and zero if they are collinear. The */
-/* result is also a rough approximation of twice the signed */
-/* area of the triangle defined by the three points. */
-/* */
-/* The last three use exact arithmetic to ensure a correct answer. The */
-/* result returned is the determinant of a matrix. In orient2d() only, */
-/* this determinant is computed adaptively, in the sense that exact */
-/* arithmetic is used only to the degree it is needed to ensure that the */
-/* returned value has the correct sign. Hence, orient2d() is usually quite */
-/* fast, but will run more slowly when the input points are collinear or */
-/* nearly so. */
-/* */
-/*****************************************************************************/
-
-REAL orient2dexact (
- __const_ptr(REAL) pa,
- __const_ptr(REAL) pb,
- __const_ptr(REAL) pc)
-{
- REAL axby1, axcy1, bxcy1, bxay1, cxay1, cxby1;
- REAL axby0, axcy0, bxcy0, bxay0, cxay0, cxby0;
- REAL aterms[4], bterms[4], cterms[4];
- REAL aterms3, bterms3, cterms3;
- REAL v[8], w[12];
- int vlength=0, wlength=0;
-
- REAL bvirt, avirt, bround, around;
- REAL c, abig, ahi, alo, bhi, blo;
- REAL err1, err2, err3;
- REAL _i, _j, _0;
-
- Two_Product(pa[0], pb[1], axby1, axby0);
- Two_Product(pa[0], pc[1], axcy1, axcy0);
- Two_Two_Diff(axby1, axby0, axcy1, axcy0,
- aterms3, aterms[2], aterms[1], aterms[0]);
- aterms[3] = aterms3;
-
- Two_Product(pb[0], pc[1], bxcy1, bxcy0);
- Two_Product(pb[0], pa[1], bxay1, bxay0);
- Two_Two_Diff(bxcy1, bxcy0, bxay1, bxay0,
- bterms3, bterms[2], bterms[1], bterms[0]);
- bterms[3] = bterms3;
-
- Two_Product(pc[0], pa[1], cxay1, cxay0);
- Two_Product(pc[0], pb[1], cxby1, cxby0);
- Two_Two_Diff(cxay1, cxay0, cxby1, cxby0,
- cterms3, cterms[2], cterms[1], cterms[0]);
- cterms[3] = cterms3;
-
- vlength = fast_expansion_sum_zeroelim(4, aterms, 4, bterms, v);
- wlength = fast_expansion_sum_zeroelim(vlength, v, 4, cterms, w);
-
- return w[wlength - 1];
-}
-
-REAL orient2dadapt (
- __const_ptr(REAL) pa,
- __const_ptr(REAL) pb,
- __const_ptr(REAL) pc,
- REAL detsum)
-{
- REAL acx, acy, bcx, bcy;
- REAL acxtail, acytail, bcxtail, bcytail;
- REAL detleft, detright;
- REAL detlefttail, detrighttail;
- REAL det, errbound;
- REAL B[4], C1[8], C2[12], D[16];
- REAL B3;
- int C1length=0, C2length=0, Dlength=0;
- REAL u[4];
- REAL u3, s1, t1, s0, t0;
-
- REAL bvirt, avirt, bround, around;
- REAL c, abig, ahi, alo, bhi, blo;
- REAL err1, err2, err3;
- REAL _i, _j, _0;
-
- acx = (REAL) (pa[0] - pc[0]);
- bcx = (REAL) (pb[0] - pc[0]);
- acy = (REAL) (pa[1] - pc[1]);
- bcy = (REAL) (pb[1] - pc[1]);
-
- Two_Product(acx, bcy, detleft, detlefttail);
- Two_Product(acy, bcx, detright, detrighttail);
-
- Two_Two_Diff(detleft, detlefttail, detright, detrighttail,
- B3, B[2], B[1], B[0]);
- B[3] = B3;
-
- det = estimate(4, B);
- errbound = o2derrboundB * detsum;
- if ((det >= errbound) || (-det >= errbound)) {
- return det;
- }
-
- Two_Diff_Tail(pa[0], pc[0], acx, acxtail);
- Two_Diff_Tail(pb[0], pc[0], bcx, bcxtail);
- Two_Diff_Tail(pa[1], pc[1], acy, acytail);
- Two_Diff_Tail(pb[1], pc[1], bcy, bcytail);
-
- if ((acxtail == 0.0) && (acytail == 0.0)
- && (bcxtail == 0.0) && (bcytail == 0.0)) {
- return det;
- }
-
- errbound = o2derrboundC * detsum + resulterrbound * Absolute(det);
- det += (acx * bcytail + bcy * acxtail)
- - (acy * bcxtail + bcx * acytail);
- if ((det >= errbound) || (-det >= errbound)) {
- return det;
- }
-
- Two_Product(acxtail, bcy, s1, s0);
- Two_Product(acytail, bcx, t1, t0);
- Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]);
- u[3] = u3;
- C1length = fast_expansion_sum_zeroelim(4, B, 4, u, C1);
-
- Two_Product(acx, bcytail, s1, s0);
- Two_Product(acy, bcxtail, t1, t0);
- Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]);
- u[3] = u3;
- C2length = fast_expansion_sum_zeroelim(C1length, C1, 4, u, C2);
-
- Two_Product(acxtail, bcytail, s1, s0);
- Two_Product(acytail, bcxtail, t1, t0);
- Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]);
- u[3] = u3;
- Dlength = fast_expansion_sum_zeroelim(C2length, C2, 4, u, D);
-
- return(D[Dlength - 1]);
-}
-
-REAL orient2d (
- __const_ptr(REAL) pa,
- __const_ptr(REAL) pb,
- __const_ptr(REAL) pc)
-{
- REAL detleft, detright, det;
- REAL detsum, errbound;
-
- detleft = (pa[0] - pc[0]) * (pb[1] - pc[1]);
- detright = (pa[1] - pc[1]) * (pb[0] - pc[0]);
- det = detleft - detright;
-
- if (detleft > 0.0) {
- if (detright <= 0.0) {
- return det;
- } else {
- detsum = detleft + detright;
- }
- } else if (detleft < 0.0) {
- if (detright >= 0.0) {
- return det;
- } else {
- detsum = -detleft - detright;
- }
- } else {
- return det;
- }
-
- errbound = o2derrboundA * detsum;
- if ((det >= errbound) || (-det >= errbound)) {
- return det;
- }
-
- return orient2dadapt(pa, pb, pc, detsum);
-}
-
-/*****************************************************************************/
-/* */
-/* orient3d() Adaptive exact 3D orientation test. Robust. */
-/* */
-/* Return a positive value if the point pd lies below the */
-/* plane passing through pa, pb, and pc; "below" is defined so */
-/* that pa, pb, and pc appear in counterclockwise order when */
-/* viewed from above the plane. Returns a negative value if */
-/* pd lies above the plane. Returns zero if the points are */
-/* coplanar. The result is also a rough approximation of six */
-/* times the signed volume of the tetrahedron defined by the */
-/* four points. */
-/* */
-/* The last three use exact arithmetic to ensure a correct answer. The */
-/* result returned is the determinant of a matrix. In orient3d() only, */
-/* this determinant is computed adaptively, in the sense that exact */
-/* arithmetic is used only to the degree it is needed to ensure that the */
-/* returned value has the correct sign. Hence, orient3d() is usually quite */
-/* fast, but will run more slowly when the input points are coplanar or */
-/* nearly so. */
-/* */
-/*****************************************************************************/
-
-REAL orient3dexact (
- __const_ptr(REAL) pa,
- __const_ptr(REAL) pb,
- __const_ptr(REAL) pc,
- __const_ptr(REAL) pd)
-{
- REAL axby1, bxcy1, cxdy1, dxay1, axcy1, bxdy1;
- REAL bxay1, cxby1, dxcy1, axdy1, cxay1, dxby1;
- REAL axby0, bxcy0, cxdy0, dxay0, axcy0, bxdy0;
- REAL bxay0, cxby0, dxcy0, axdy0, cxay0, dxby0;
- REAL ab[4], bc[4], cd[4], da[4], ac[4], bd[4];
- REAL temp8[8];
- int templen=0;
- REAL abc[12], bcd[12], cda[12], dab[12];
- int abclen=0, bcdlen=0, cdalen=0, dablen=0;
- REAL adet[24], bdet[24], cdet[24], ddet[24];
- int alen=0, blen=0, clen=0, dlen=0;
- REAL abdet[48], cddet[48];
- int ablen=0, cdlen=0;
- REAL deter[96];
- int deterlen=0;
- int i;
-
- REAL bvirt, avirt, bround, around;
- REAL c, abig, ahi, alo, bhi, blo;
- REAL err1, err2, err3;
- REAL _i, _j, _0;
-
- Two_Product(pa[0], pb[1], axby1, axby0);
- Two_Product(pb[0], pa[1], bxay1, bxay0);
- Two_Two_Diff(axby1, axby0, bxay1, bxay0, ab[3], ab[2], ab[1], ab[0]);
-
- Two_Product(pb[0], pc[1], bxcy1, bxcy0);
- Two_Product(pc[0], pb[1], cxby1, cxby0);
- Two_Two_Diff(bxcy1, bxcy0, cxby1, cxby0, bc[3], bc[2], bc[1], bc[0]);
-
- Two_Product(pc[0], pd[1], cxdy1, cxdy0);
- Two_Product(pd[0], pc[1], dxcy1, dxcy0);
- Two_Two_Diff(cxdy1, cxdy0, dxcy1, dxcy0, cd[3], cd[2], cd[1], cd[0]);
-
- Two_Product(pd[0], pa[1], dxay1, dxay0);
- Two_Product(pa[0], pd[1], axdy1, axdy0);
- Two_Two_Diff(dxay1, dxay0, axdy1, axdy0, da[3], da[2], da[1], da[0]);
-
- Two_Product(pa[0], pc[1], axcy1, axcy0);
- Two_Product(pc[0], pa[1], cxay1, cxay0);
- Two_Two_Diff(axcy1, axcy0, cxay1, cxay0, ac[3], ac[2], ac[1], ac[0]);
-
- Two_Product(pb[0], pd[1], bxdy1, bxdy0);
- Two_Product(pd[0], pb[1], dxby1, dxby0);
- Two_Two_Diff(bxdy1, bxdy0, dxby1, dxby0, bd[3], bd[2], bd[1], bd[0]);
-
- templen = fast_expansion_sum_zeroelim(4, cd, 4, da, temp8);
- cdalen = fast_expansion_sum_zeroelim(templen, temp8, 4, ac, cda);
- templen = fast_expansion_sum_zeroelim(4, da, 4, ab, temp8);
- dablen = fast_expansion_sum_zeroelim(templen, temp8, 4, bd, dab);
- for (i = 0; i < 4; i++) {
- bd[i] = -bd[i];
- ac[i] = -ac[i];
- }
- templen = fast_expansion_sum_zeroelim(4, ab, 4, bc, temp8);
- abclen = fast_expansion_sum_zeroelim(templen, temp8, 4, ac, abc);
- templen = fast_expansion_sum_zeroelim(4, bc, 4, cd, temp8);
- bcdlen = fast_expansion_sum_zeroelim(templen, temp8, 4, bd, bcd);
-
- alen = scale_expansion_zeroelim(bcdlen, bcd, pa[2], adet);
- blen = scale_expansion_zeroelim(cdalen, cda, -pb[2], bdet);
- clen = scale_expansion_zeroelim(dablen, dab, pc[2], cdet);
- dlen = scale_expansion_zeroelim(abclen, abc, -pd[2], ddet);
-
- ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet);
- cdlen = fast_expansion_sum_zeroelim(clen, cdet, dlen, ddet, cddet);
- deterlen = fast_expansion_sum_zeroelim(ablen, abdet, cdlen, cddet, deter);
-
- return deter[deterlen - 1];
-}
-
-REAL orient3dadapt (
- __const_ptr(REAL) pa,
- __const_ptr(REAL) pb,
- __const_ptr(REAL) pc,
- __const_ptr(REAL) pd,
- REAL permanent)
-{
- REAL adx, bdx, cdx, ady, bdy, cdy, adz, bdz, cdz;
- REAL det, errbound;
-
- REAL bdxcdy1, cdxbdy1, cdxady1, adxcdy1, adxbdy1, bdxady1;
- REAL bdxcdy0, cdxbdy0, cdxady0, adxcdy0, adxbdy0, bdxady0;
- REAL bc[4], ca[4], ab[4];
- REAL bc3, ca3, ab3;
- REAL adet[8], bdet[8], cdet[8];
- int alen=0, blen=0, clen=0;
- REAL abdet[16];
- int ablen=0;
- REAL *finnow, *finother, *finswap;
- REAL fin1[192], fin2[192];
- int finlength=0;
-
- REAL adxtail, bdxtail, cdxtail;
- REAL adytail, bdytail, cdytail;
- REAL adztail, bdztail, cdztail;
- REAL at_blarge, at_clarge;
- REAL bt_clarge, bt_alarge;
- REAL ct_alarge, ct_blarge;
- REAL at_b[4], at_c[4], bt_c[4], bt_a[4], ct_a[4], ct_b[4];
- int at_blen=0, at_clen=0, bt_clen=0;
- int bt_alen=0, ct_alen=0, ct_blen=0;
- REAL bdxt_cdy1, cdxt_bdy1, cdxt_ady1;
- REAL adxt_cdy1, adxt_bdy1, bdxt_ady1;
- REAL bdxt_cdy0, cdxt_bdy0, cdxt_ady0;
- REAL adxt_cdy0, adxt_bdy0, bdxt_ady0;
- REAL bdyt_cdx1, cdyt_bdx1, cdyt_adx1;
- REAL adyt_cdx1, adyt_bdx1, bdyt_adx1;
- REAL bdyt_cdx0, cdyt_bdx0, cdyt_adx0;
- REAL adyt_cdx0, adyt_bdx0, bdyt_adx0;
- REAL bct[8], cat[8], abt[8];
- int bctlen=0, catlen=0, abtlen=0;
- REAL bdxt_cdyt1, cdxt_bdyt1, cdxt_adyt1;
- REAL adxt_cdyt1, adxt_bdyt1, bdxt_adyt1;
- REAL bdxt_cdyt0, cdxt_bdyt0, cdxt_adyt0;
- REAL adxt_cdyt0, adxt_bdyt0, bdxt_adyt0;
- REAL u[4], v[12], w[16];
- REAL u3;
- int vlength=0, wlength=0;
- REAL negate;
-
- REAL bvirt, avirt, bround, around;
- REAL c, abig, ahi, alo, bhi, blo;
- REAL err1, err2, err3;
- REAL _i, _j, _k, _0;
-
- adx = (REAL) (pa[0] - pd[0]);
- bdx = (REAL) (pb[0] - pd[0]);
- cdx = (REAL) (pc[0] - pd[0]);
- ady = (REAL) (pa[1] - pd[1]);
- bdy = (REAL) (pb[1] - pd[1]);
- cdy = (REAL) (pc[1] - pd[1]);
- adz = (REAL) (pa[2] - pd[2]);
- bdz = (REAL) (pb[2] - pd[2]);
- cdz = (REAL) (pc[2] - pd[2]);
-
- Two_Product(bdx, cdy, bdxcdy1, bdxcdy0);
- Two_Product(cdx, bdy, cdxbdy1, cdxbdy0);
- Two_Two_Diff(bdxcdy1, bdxcdy0, cdxbdy1, cdxbdy0, bc3, bc[2], bc[1], bc[0]);
- bc[3] = bc3;
- alen = scale_expansion_zeroelim(4, bc, adz, adet);
-
- Two_Product(cdx, ady, cdxady1, cdxady0);
- Two_Product(adx, cdy, adxcdy1, adxcdy0);
- Two_Two_Diff(cdxady1, cdxady0, adxcdy1, adxcdy0, ca3, ca[2], ca[1], ca[0]);
- ca[3] = ca3;
- blen = scale_expansion_zeroelim(4, ca, bdz, bdet);
-
- Two_Product(adx, bdy, adxbdy1, adxbdy0);
- Two_Product(bdx, ady, bdxady1, bdxady0);
- Two_Two_Diff(adxbdy1, adxbdy0, bdxady1, bdxady0, ab3, ab[2], ab[1], ab[0]);
- ab[3] = ab3;
- clen = scale_expansion_zeroelim(4, ab, cdz, cdet);
-
- ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet);
- finlength = fast_expansion_sum_zeroelim(ablen, abdet, clen, cdet, fin1);
-
- det = estimate(finlength, fin1);
- errbound = o3derrboundB * permanent;
- if ((det >= errbound) || (-det >= errbound)) {
- return det;
- }
-
- Two_Diff_Tail(pa[0], pd[0], adx, adxtail);
- Two_Diff_Tail(pb[0], pd[0], bdx, bdxtail);
- Two_Diff_Tail(pc[0], pd[0], cdx, cdxtail);
- Two_Diff_Tail(pa[1], pd[1], ady, adytail);
- Two_Diff_Tail(pb[1], pd[1], bdy, bdytail);
- Two_Diff_Tail(pc[1], pd[1], cdy, cdytail);
- Two_Diff_Tail(pa[2], pd[2], adz, adztail);
- Two_Diff_Tail(pb[2], pd[2], bdz, bdztail);
- Two_Diff_Tail(pc[2], pd[2], cdz, cdztail);
-
- if ((adxtail == 0.0) && (bdxtail == 0.0) && (cdxtail == 0.0)
- && (adytail == 0.0) && (bdytail == 0.0) && (cdytail == 0.0)
- && (adztail == 0.0) && (bdztail == 0.0) && (cdztail == 0.0)) {
- return det;
- }
-
- errbound = o3derrboundC * permanent + resulterrbound * Absolute(det);
- det += (adz * ((bdx * cdytail + cdy * bdxtail)
- - (bdy * cdxtail + cdx * bdytail))
- + adztail * (bdx * cdy - bdy * cdx))
- + (bdz * ((cdx * adytail + ady * cdxtail)
- - (cdy * adxtail + adx * cdytail))
- + bdztail * (cdx * ady - cdy * adx))
- + (cdz * ((adx * bdytail + bdy * adxtail)
- - (ady * bdxtail + bdx * adytail))
- + cdztail * (adx * bdy - ady * bdx));
- if ((det >= errbound) || (-det >= errbound)) {
- return det;
- }
-
- finnow = fin1;
- finother = fin2;
-
- if (adxtail == 0.0) {
- if (adytail == 0.0) {
- at_b[0] = 0.0;
- at_blen = 1;
- at_c[0] = 0.0;
- at_clen = 1;
- } else {
- negate = -adytail;
- Two_Product(negate, bdx, at_blarge, at_b[0]);
- at_b[1] = at_blarge;
- at_blen = 2;
- Two_Product(adytail, cdx, at_clarge, at_c[0]);
- at_c[1] = at_clarge;
- at_clen = 2;
- }
- } else {
- if (adytail == 0.0) {
- Two_Product(adxtail, bdy, at_blarge, at_b[0]);
- at_b[1] = at_blarge;
- at_blen = 2;
- negate = -adxtail;
- Two_Product(negate, cdy, at_clarge, at_c[0]);
- at_c[1] = at_clarge;
- at_clen = 2;
- } else {
- Two_Product(adxtail, bdy, adxt_bdy1, adxt_bdy0);
- Two_Product(adytail, bdx, adyt_bdx1, adyt_bdx0);
- Two_Two_Diff(adxt_bdy1, adxt_bdy0, adyt_bdx1, adyt_bdx0,
- at_blarge, at_b[2], at_b[1], at_b[0]);
- at_b[3] = at_blarge;
- at_blen = 4;
- Two_Product(adytail, cdx, adyt_cdx1, adyt_cdx0);
- Two_Product(adxtail, cdy, adxt_cdy1, adxt_cdy0);
- Two_Two_Diff(adyt_cdx1, adyt_cdx0, adxt_cdy1, adxt_cdy0,
- at_clarge, at_c[2], at_c[1], at_c[0]);
- at_c[3] = at_clarge;
- at_clen = 4;
- }
- }
- if (bdxtail == 0.0) {
- if (bdytail == 0.0) {
- bt_c[0] = 0.0;
- bt_clen = 1;
- bt_a[0] = 0.0;
- bt_alen = 1;
- } else {
- negate = -bdytail;
- Two_Product(negate, cdx, bt_clarge, bt_c[0]);
- bt_c[1] = bt_clarge;
- bt_clen = 2;
- Two_Product(bdytail, adx, bt_alarge, bt_a[0]);
- bt_a[1] = bt_alarge;
- bt_alen = 2;
- }
- } else {
- if (bdytail == 0.0) {
- Two_Product(bdxtail, cdy, bt_clarge, bt_c[0]);
- bt_c[1] = bt_clarge;
- bt_clen = 2;
- negate = -bdxtail;
- Two_Product(negate, ady, bt_alarge, bt_a[0]);
- bt_a[1] = bt_alarge;
- bt_alen = 2;
- } else {
- Two_Product(bdxtail, cdy, bdxt_cdy1, bdxt_cdy0);
- Two_Product(bdytail, cdx, bdyt_cdx1, bdyt_cdx0);
- Two_Two_Diff(bdxt_cdy1, bdxt_cdy0, bdyt_cdx1, bdyt_cdx0,
- bt_clarge, bt_c[2], bt_c[1], bt_c[0]);
- bt_c[3] = bt_clarge;
- bt_clen = 4;
- Two_Product(bdytail, adx, bdyt_adx1, bdyt_adx0);
- Two_Product(bdxtail, ady, bdxt_ady1, bdxt_ady0);
- Two_Two_Diff(bdyt_adx1, bdyt_adx0, bdxt_ady1, bdxt_ady0,
- bt_alarge, bt_a[2], bt_a[1], bt_a[0]);
- bt_a[3] = bt_alarge;
- bt_alen = 4;
- }
- }
- if (cdxtail == 0.0) {
- if (cdytail == 0.0) {
- ct_a[0] = 0.0;
- ct_alen = 1;
- ct_b[0] = 0.0;
- ct_blen = 1;
- } else {
- negate = -cdytail;
- Two_Product(negate, adx, ct_alarge, ct_a[0]);
- ct_a[1] = ct_alarge;
- ct_alen = 2;
- Two_Product(cdytail, bdx, ct_blarge, ct_b[0]);
- ct_b[1] = ct_blarge;
- ct_blen = 2;
- }
- } else {
- if (cdytail == 0.0) {
- Two_Product(cdxtail, ady, ct_alarge, ct_a[0]);
- ct_a[1] = ct_alarge;
- ct_alen = 2;
- negate = -cdxtail;
- Two_Product(negate, bdy, ct_blarge, ct_b[0]);
- ct_b[1] = ct_blarge;
- ct_blen = 2;
- } else {
- Two_Product(cdxtail, ady, cdxt_ady1, cdxt_ady0);
- Two_Product(cdytail, adx, cdyt_adx1, cdyt_adx0);
- Two_Two_Diff(cdxt_ady1, cdxt_ady0, cdyt_adx1, cdyt_adx0,
- ct_alarge, ct_a[2], ct_a[1], ct_a[0]);
- ct_a[3] = ct_alarge;
- ct_alen = 4;
- Two_Product(cdytail, bdx, cdyt_bdx1, cdyt_bdx0);
- Two_Product(cdxtail, bdy, cdxt_bdy1, cdxt_bdy0);
- Two_Two_Diff(cdyt_bdx1, cdyt_bdx0, cdxt_bdy1, cdxt_bdy0,
- ct_blarge, ct_b[2], ct_b[1], ct_b[0]);
- ct_b[3] = ct_blarge;
- ct_blen = 4;
- }
- }
-
- bctlen = fast_expansion_sum_zeroelim(bt_clen, bt_c, ct_blen, ct_b, bct);
- wlength = scale_expansion_zeroelim(bctlen, bct, adz, w);
- finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w,
- finother);
- finswap = finnow; finnow = finother; finother = finswap;
-
- catlen = fast_expansion_sum_zeroelim(ct_alen, ct_a, at_clen, at_c, cat);
- wlength = scale_expansion_zeroelim(catlen, cat, bdz, w);
- finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w,
- finother);
- finswap = finnow; finnow = finother; finother = finswap;
-
- abtlen = fast_expansion_sum_zeroelim(at_blen, at_b, bt_alen, bt_a, abt);
- wlength = scale_expansion_zeroelim(abtlen, abt, cdz, w);
- finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w,
- finother);
- finswap = finnow; finnow = finother; finother = finswap;
-
- if (adztail != 0.0) {
- vlength = scale_expansion_zeroelim(4, bc, adztail, v);
- finlength = fast_expansion_sum_zeroelim(finlength, finnow, vlength, v,
- finother);
- finswap = finnow; finnow = finother; finother = finswap;
- }
- if (bdztail != 0.0) {
- vlength = scale_expansion_zeroelim(4, ca, bdztail, v);
- finlength = fast_expansion_sum_zeroelim(finlength, finnow, vlength, v,
- finother);
- finswap = finnow; finnow = finother; finother = finswap;
- }
- if (cdztail != 0.0) {
- vlength = scale_expansion_zeroelim(4, ab, cdztail, v);
- finlength = fast_expansion_sum_zeroelim(finlength, finnow, vlength, v,
- finother);
- finswap = finnow; finnow = finother; finother = finswap;
- }
-
- if (adxtail != 0.0) {
- if (bdytail != 0.0) {
- Two_Product(adxtail, bdytail, adxt_bdyt1, adxt_bdyt0);
- Two_One_Product(adxt_bdyt1, adxt_bdyt0, cdz, u3, u[2], u[1], u[0]);
- u[3] = u3;
- finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
- finother);
- finswap = finnow; finnow = finother; finother = finswap;
- if (cdztail != 0.0) {
- Two_One_Product(adxt_bdyt1, adxt_bdyt0, cdztail, u3, u[2], u[1], u[0]);
- u[3] = u3;
- finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
- finother);
- finswap = finnow; finnow = finother; finother = finswap;
- }
- }
- if (cdytail != 0.0) {
- negate = -adxtail;
- Two_Product(negate, cdytail, adxt_cdyt1, adxt_cdyt0);
- Two_One_Product(adxt_cdyt1, adxt_cdyt0, bdz, u3, u[2], u[1], u[0]);
- u[3] = u3;
- finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
- finother);
- finswap = finnow; finnow = finother; finother = finswap;
- if (bdztail != 0.0) {
- Two_One_Product(adxt_cdyt1, adxt_cdyt0, bdztail, u3, u[2], u[1], u[0]);
- u[3] = u3;
- finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
- finother);
- finswap = finnow; finnow = finother; finother = finswap;
- }
- }
- }
- if (bdxtail != 0.0) {
- if (cdytail != 0.0) {
- Two_Product(bdxtail, cdytail, bdxt_cdyt1, bdxt_cdyt0);
- Two_One_Product(bdxt_cdyt1, bdxt_cdyt0, adz, u3, u[2], u[1], u[0]);
- u[3] = u3;
- finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
- finother);
- finswap = finnow; finnow = finother; finother = finswap;
- if (adztail != 0.0) {
- Two_One_Product(bdxt_cdyt1, bdxt_cdyt0, adztail, u3, u[2], u[1], u[0]);
- u[3] = u3;
- finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
- finother);
- finswap = finnow; finnow = finother; finother = finswap;
- }
- }
- if (adytail != 0.0) {
- negate = -bdxtail;
- Two_Product(negate, adytail, bdxt_adyt1, bdxt_adyt0);
- Two_One_Product(bdxt_adyt1, bdxt_adyt0, cdz, u3, u[2], u[1], u[0]);
- u[3] = u3;
- finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
- finother);
- finswap = finnow; finnow = finother; finother = finswap;
- if (cdztail != 0.0) {
- Two_One_Product(bdxt_adyt1, bdxt_adyt0, cdztail, u3, u[2], u[1], u[0]);
- u[3] = u3;
- finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
- finother);
- finswap = finnow; finnow = finother; finother = finswap;
- }
- }
- }
- if (cdxtail != 0.0) {
- if (adytail != 0.0) {
- Two_Product(cdxtail, adytail, cdxt_adyt1, cdxt_adyt0);
- Two_One_Product(cdxt_adyt1, cdxt_adyt0, bdz, u3, u[2], u[1], u[0]);
- u[3] = u3;
- finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
- finother);
- finswap = finnow; finnow = finother; finother = finswap;
- if (bdztail != 0.0) {
- Two_One_Product(cdxt_adyt1, cdxt_adyt0, bdztail, u3, u[2], u[1], u[0]);
- u[3] = u3;
- finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
- finother);
- finswap = finnow; finnow = finother; finother = finswap;
- }
- }
- if (bdytail != 0.0) {
- negate = -cdxtail;
- Two_Product(negate, bdytail, cdxt_bdyt1, cdxt_bdyt0);
- Two_One_Product(cdxt_bdyt1, cdxt_bdyt0, adz, u3, u[2], u[1], u[0]);
- u[3] = u3;
- finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
- finother);
- finswap = finnow; finnow = finother; finother = finswap;
- if (adztail != 0.0) {
- Two_One_Product(cdxt_bdyt1, cdxt_bdyt0, adztail, u3, u[2], u[1], u[0]);
- u[3] = u3;
- finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
- finother);
- finswap = finnow; finnow = finother; finother = finswap;
- }
- }
- }
-
- if (adztail != 0.0) {
- wlength = scale_expansion_zeroelim(bctlen, bct, adztail, w);
- finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w,
- finother);
- finswap = finnow; finnow = finother; finother = finswap;
- }
- if (bdztail != 0.0) {
- wlength = scale_expansion_zeroelim(catlen, cat, bdztail, w);
- finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w,
- finother);
- finswap = finnow; finnow = finother; finother = finswap;
- }
- if (cdztail != 0.0) {
- wlength = scale_expansion_zeroelim(abtlen, abt, cdztail, w);
- finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w,
- finother);
- finswap = finnow; finnow = finother; finother = finswap;
- }
-
- return finnow[finlength - 1];
-}
-
-REAL orient3d (
- __const_ptr(REAL) pa,
- __const_ptr(REAL) pb,
- __const_ptr(REAL) pc,
- __const_ptr(REAL) pd)
-{
- REAL adx, bdx, cdx, ady, bdy, cdy, adz, bdz, cdz;
- REAL bdxcdy, cdxbdy, cdxady, adxcdy, adxbdy, bdxady;
- REAL det;
- REAL permanent, errbound;
-
- adx = pa[0] - pd[0];
- bdx = pb[0] - pd[0];
- cdx = pc[0] - pd[0];
- ady = pa[1] - pd[1];
- bdy = pb[1] - pd[1];
- cdy = pc[1] - pd[1];
- adz = pa[2] - pd[2];
- bdz = pb[2] - pd[2];
- cdz = pc[2] - pd[2];
-
- bdxcdy = bdx * cdy;
- cdxbdy = cdx * bdy;
-
- cdxady = cdx * ady;
- adxcdy = adx * cdy;
-
- adxbdy = adx * bdy;
- bdxady = bdx * ady;
-
- det = adz * (bdxcdy - cdxbdy)
- + bdz * (cdxady - adxcdy)
- + cdz * (adxbdy - bdxady);
-
- permanent = (Absolute(bdxcdy) + Absolute(cdxbdy)) * Absolute(adz)
- + (Absolute(cdxady) + Absolute(adxcdy)) * Absolute(bdz)
- + (Absolute(adxbdy) + Absolute(bdxady)) * Absolute(cdz);
- errbound = o3derrboundA * permanent;
- if ((det > errbound) || (-det > errbound)) {
- return det;
- }
-
- return orient3dadapt(pa, pb, pc, pd, permanent);
-}
-
-/*****************************************************************************/
-/* */
-/* incircle() Adaptive exact 2D incircle test. Robust. */
-/* */
-/* Return a positive value if the point pd lies inside the */
-/* circle passing through pa, pb, and pc; a negative value if */
-/* it lies outside; and zero if the four points are cocircular.*/
-/* The points pa, pb, and pc must be in counterclockwise */
-/* order, or the sign of the result will be reversed. */
-/* */
-/* The last three use exact arithmetic to ensure a correct answer. The */
-/* result returned is the determinant of a matrix. In incircle() only, */
-/* this determinant is computed adaptively, in the sense that exact */
-/* arithmetic is used only to the degree it is needed to ensure that the */
-/* returned value has the correct sign. Hence, incircle() is usually quite */
-/* fast, but will run more slowly when the input points are cocircular or */
-/* nearly so. */
-/* */
-/*****************************************************************************/
-
-REAL incircleexact (
- __const_ptr(REAL) pa,
- __const_ptr(REAL) pb,
- __const_ptr(REAL) pc,
- __const_ptr(REAL) pd)
-{
- REAL axby1, bxcy1, cxdy1, dxay1, axcy1, bxdy1;
- REAL bxay1, cxby1, dxcy1, axdy1, cxay1, dxby1;
- REAL axby0, bxcy0, cxdy0, dxay0, axcy0, bxdy0;
- REAL bxay0, cxby0, dxcy0, axdy0, cxay0, dxby0;
- REAL ab[4], bc[4], cd[4], da[4], ac[4], bd[4];
- REAL temp8[8];
- int templen=0;
- REAL abc[12], bcd[12], cda[12], dab[12];
- int abclen=0, bcdlen=0, cdalen=0, dablen=0;
- REAL det24x[24], det24y[24], det48x[48], det48y[48];
- int xlen=0, ylen=0;
- REAL adet[96], bdet[96], cdet[96], ddet[96];
- int alen=0, blen=0, clen=0, dlen=0;
- REAL abdet[192], cddet[192];
- int ablen=0, cdlen=0;
- REAL deter[384];
- int deterlen=0;
- int i;
-
- REAL bvirt, avirt, bround, around;
- REAL c, abig, ahi, alo, bhi, blo;
- REAL err1, err2, err3;
- REAL _i, _j, _0;
-
- Two_Product(pa[0], pb[1], axby1, axby0);
- Two_Product(pb[0], pa[1], bxay1, bxay0);
- Two_Two_Diff(axby1, axby0, bxay1, bxay0, ab[3], ab[2], ab[1], ab[0]);
-
- Two_Product(pb[0], pc[1], bxcy1, bxcy0);
- Two_Product(pc[0], pb[1], cxby1, cxby0);
- Two_Two_Diff(bxcy1, bxcy0, cxby1, cxby0, bc[3], bc[2], bc[1], bc[0]);
-
- Two_Product(pc[0], pd[1], cxdy1, cxdy0);
- Two_Product(pd[0], pc[1], dxcy1, dxcy0);
- Two_Two_Diff(cxdy1, cxdy0, dxcy1, dxcy0, cd[3], cd[2], cd[1], cd[0]);
-
- Two_Product(pd[0], pa[1], dxay1, dxay0);
- Two_Product(pa[0], pd[1], axdy1, axdy0);
- Two_Two_Diff(dxay1, dxay0, axdy1, axdy0, da[3], da[2], da[1], da[0]);
-
- Two_Product(pa[0], pc[1], axcy1, axcy0);
- Two_Product(pc[0], pa[1], cxay1, cxay0);
- Two_Two_Diff(axcy1, axcy0, cxay1, cxay0, ac[3], ac[2], ac[1], ac[0]);
-
- Two_Product(pb[0], pd[1], bxdy1, bxdy0);
- Two_Product(pd[0], pb[1], dxby1, dxby0);
- Two_Two_Diff(bxdy1, bxdy0, dxby1, dxby0, bd[3], bd[2], bd[1], bd[0]);
-
- templen = fast_expansion_sum_zeroelim(4, cd, 4, da, temp8);
- cdalen = fast_expansion_sum_zeroelim(templen, temp8, 4, ac, cda);
- templen = fast_expansion_sum_zeroelim(4, da, 4, ab, temp8);
- dablen = fast_expansion_sum_zeroelim(templen, temp8, 4, bd, dab);
- for (i = 0; i < 4; i++) {
- bd[i] = -bd[i];
- ac[i] = -ac[i];
- }
- templen = fast_expansion_sum_zeroelim(4, ab, 4, bc, temp8);
- abclen = fast_expansion_sum_zeroelim(templen, temp8, 4, ac, abc);
- templen = fast_expansion_sum_zeroelim(4, bc, 4, cd, temp8);
- bcdlen = fast_expansion_sum_zeroelim(templen, temp8, 4, bd, bcd);
-
- xlen = scale_expansion_zeroelim(bcdlen, bcd, pa[0], det24x);
- xlen = scale_expansion_zeroelim(xlen, det24x, pa[0], det48x);
- ylen = scale_expansion_zeroelim(bcdlen, bcd, pa[1], det24y);
- ylen = scale_expansion_zeroelim(ylen, det24y, pa[1], det48y);
- alen = fast_expansion_sum_zeroelim(xlen, det48x, ylen, det48y, adet);
-
- xlen = scale_expansion_zeroelim(cdalen, cda, pb[0], det24x);
- xlen = scale_expansion_zeroelim(xlen, det24x, -pb[0], det48x);
- ylen = scale_expansion_zeroelim(cdalen, cda, pb[1], det24y);
- ylen = scale_expansion_zeroelim(ylen, det24y, -pb[1], det48y);
- blen = fast_expansion_sum_zeroelim(xlen, det48x, ylen, det48y, bdet);
-
- xlen = scale_expansion_zeroelim(dablen, dab, pc[0], det24x);
- xlen = scale_expansion_zeroelim(xlen, det24x, pc[0], det48x);
- ylen = scale_expansion_zeroelim(dablen, dab, pc[1], det24y);
- ylen = scale_expansion_zeroelim(ylen, det24y, pc[1], det48y);
- clen = fast_expansion_sum_zeroelim(xlen, det48x, ylen, det48y, cdet);
-
- xlen = scale_expansion_zeroelim(abclen, abc, pd[0], det24x);
- xlen = scale_expansion_zeroelim(xlen, det24x, -pd[0], det48x);
- ylen = scale_expansion_zeroelim(abclen, abc, pd[1], det24y);
- ylen = scale_expansion_zeroelim(ylen, det24y, -pd[1], det48y);
- dlen = fast_expansion_sum_zeroelim(xlen, det48x, ylen, det48y, ddet);
-
- ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet);
- cdlen = fast_expansion_sum_zeroelim(clen, cdet, dlen, ddet, cddet);
- deterlen = fast_expansion_sum_zeroelim(ablen, abdet, cdlen, cddet, deter);
-
- return deter[deterlen - 1];
-}
-
-REAL incircleadapt (
- __const_ptr(REAL) pa,
- __const_ptr(REAL) pb,
- __const_ptr(REAL) pc,
- __const_ptr(REAL) pd,
- REAL permanent)
-{
- REAL adx, bdx, cdx, ady, bdy, cdy;
- REAL det, errbound;
-
- REAL bdxcdy1, cdxbdy1, cdxady1, adxcdy1, adxbdy1, bdxady1;
- REAL bdxcdy0, cdxbdy0, cdxady0, adxcdy0, adxbdy0, bdxady0;
- REAL bc[4], ca[4], ab[4];
- REAL bc3, ca3, ab3;
- REAL axbc[8], axxbc[16], aybc[8], ayybc[16], adet[32];
- int axbclen=0, axxbclen=0, aybclen=0, ayybclen=0, alen=0;
- REAL bxca[8], bxxca[16], byca[8], byyca[16], bdet[32];
- int bxcalen=0, bxxcalen=0, bycalen=0, byycalen=0, blen=0;
- REAL cxab[8], cxxab[16], cyab[8], cyyab[16], cdet[32];
- int cxablen=0, cxxablen=0, cyablen=0, cyyablen=0, clen=0;
- REAL abdet[64];
- int ablen=0;
- REAL fin1[1152], fin2[1152];
- REAL *finnow, *finother, *finswap;
- int finlength=0;
-
- REAL adxtail, bdxtail, cdxtail, adytail, bdytail, cdytail;
- REAL adxadx1, adyady1, bdxbdx1, bdybdy1, cdxcdx1, cdycdy1;
- REAL adxadx0, adyady0, bdxbdx0, bdybdy0, cdxcdx0, cdycdy0;
- REAL aa[4], bb[4], cc[4];
- REAL aa3, bb3, cc3;
- REAL ti1, tj1;
- REAL ti0, tj0;
- REAL u[4], v[4];
- REAL u3, v3;
- REAL temp8[8], temp16a[16], temp16b[16], temp16c[16];
- REAL temp32a[32], temp32b[32], temp48[48], temp64[64];
- int temp8len=0, temp16alen=0, temp16blen=0, temp16clen=0;
- int temp32alen=0, temp32blen=0, temp48len=0, temp64len=0;
- REAL axtbb[8], axtcc[8], aytbb[8], aytcc[8];
- int axtbblen=0, axtcclen=0, aytbblen=0, aytcclen=0;
- REAL bxtaa[8], bxtcc[8], bytaa[8], bytcc[8];
- int bxtaalen=0, bxtcclen=0, bytaalen=0, bytcclen=0;
- REAL cxtaa[8], cxtbb[8], cytaa[8], cytbb[8];
- int cxtaalen=0, cxtbblen=0, cytaalen=0, cytbblen=0;
- REAL axtbc[8], aytbc[8], bxtca[8], bytca[8], cxtab[8], cytab[8];
- int axtbclen=0, aytbclen=0, bxtcalen=0, bytcalen=0, cxtablen=0, cytablen=0;
- REAL axtbct[16], aytbct[16], bxtcat[16], bytcat[16], cxtabt[16], cytabt[16];
- int axtbctlen=0, aytbctlen=0;
- int bxtcatlen=0, bytcatlen=0;
- int cxtabtlen=0, cytabtlen=0;
- REAL axtbctt[8], aytbctt[8], bxtcatt[8];
- REAL bytcatt[8], cxtabtt[8], cytabtt[8];
- int axtbcttlen=0, aytbcttlen=0;
- int bxtcattlen=0, bytcattlen=0;
- int cxtabttlen=0, cytabttlen=0;
- REAL abt[8], bct[8], cat[8];
- int abtlen=0, bctlen=0, catlen=0;
- REAL abtt[4], bctt[4], catt[4];
- int abttlen=0, bcttlen=0, cattlen=0;
- REAL abtt3, bctt3, catt3;
- REAL negate;
-
- REAL bvirt, avirt, bround, around;
- REAL c, abig, ahi, alo, bhi, blo;
- REAL err1, err2, err3;
- REAL _i, _j, _0;
-
- adx = (REAL) (pa[0] - pd[0]);
- bdx = (REAL) (pb[0] - pd[0]);
- cdx = (REAL) (pc[0] - pd[0]);
- ady = (REAL) (pa[1] - pd[1]);
- bdy = (REAL) (pb[1] - pd[1]);
- cdy = (REAL) (pc[1] - pd[1]);
-
- Two_Product(bdx, cdy, bdxcdy1, bdxcdy0);
- Two_Product(cdx, bdy, cdxbdy1, cdxbdy0);
- Two_Two_Diff(bdxcdy1, bdxcdy0, cdxbdy1, cdxbdy0, bc3, bc[2], bc[1], bc[0]);
- bc[3] = bc3;
- axbclen = scale_expansion_zeroelim(4, bc, adx, axbc);
- axxbclen = scale_expansion_zeroelim(axbclen, axbc, adx, axxbc);
- aybclen = scale_expansion_zeroelim(4, bc, ady, aybc);
- ayybclen = scale_expansion_zeroelim(aybclen, aybc, ady, ayybc);
- alen = fast_expansion_sum_zeroelim(axxbclen, axxbc, ayybclen, ayybc, adet);
-
- Two_Product(cdx, ady, cdxady1, cdxady0);
- Two_Product(adx, cdy, adxcdy1, adxcdy0);
- Two_Two_Diff(cdxady1, cdxady0, adxcdy1, adxcdy0, ca3, ca[2], ca[1], ca[0]);
- ca[3] = ca3;
- bxcalen = scale_expansion_zeroelim(4, ca, bdx, bxca);
- bxxcalen = scale_expansion_zeroelim(bxcalen, bxca, bdx, bxxca);
- bycalen = scale_expansion_zeroelim(4, ca, bdy, byca);
- byycalen = scale_expansion_zeroelim(bycalen, byca, bdy, byyca);
- blen = fast_expansion_sum_zeroelim(bxxcalen, bxxca, byycalen, byyca, bdet);
-
- Two_Product(adx, bdy, adxbdy1, adxbdy0);
- Two_Product(bdx, ady, bdxady1, bdxady0);
- Two_Two_Diff(adxbdy1, adxbdy0, bdxady1, bdxady0, ab3, ab[2], ab[1], ab[0]);
- ab[3] = ab3;
- cxablen = scale_expansion_zeroelim(4, ab, cdx, cxab);
- cxxablen = scale_expansion_zeroelim(cxablen, cxab, cdx, cxxab);
- cyablen = scale_expansion_zeroelim(4, ab, cdy, cyab);
- cyyablen = scale_expansion_zeroelim(cyablen, cyab, cdy, cyyab);
- clen = fast_expansion_sum_zeroelim(cxxablen, cxxab, cyyablen, cyyab, cdet);
-
- ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet);
- finlength = fast_expansion_sum_zeroelim(ablen, abdet, clen, cdet, fin1);
-
- det = estimate(finlength, fin1);
- errbound = iccerrboundB * permanent;
- if ((det >= errbound) || (-det >= errbound)) {
- return det;
- }
-
- Two_Diff_Tail(pa[0], pd[0], adx, adxtail);
- Two_Diff_Tail(pa[1], pd[1], ady, adytail);
- Two_Diff_Tail(pb[0], pd[0], bdx, bdxtail);
- Two_Diff_Tail(pb[1], pd[1], bdy, bdytail);
- Two_Diff_Tail(pc[0], pd[0], cdx, cdxtail);
- Two_Diff_Tail(pc[1], pd[1], cdy, cdytail);
- if ((adxtail == 0.0) && (bdxtail == 0.0) && (cdxtail == 0.0)
- && (adytail == 0.0) && (bdytail == 0.0) && (cdytail == 0.0)) {
- return det;
- }
-
- errbound = iccerrboundC * permanent + resulterrbound * Absolute(det);
- det += ((adx * adx + ady * ady) * ((bdx * cdytail + cdy * bdxtail)
- - (bdy * cdxtail + cdx * bdytail))
- + 2.0 * (adx * adxtail + ady * adytail) * (bdx * cdy - bdy * cdx))
- + ((bdx * bdx + bdy * bdy) * ((cdx * adytail + ady * cdxtail)
- - (cdy * adxtail + adx * cdytail))
- + 2.0 * (bdx * bdxtail + bdy * bdytail) * (cdx * ady - cdy * adx))
- + ((cdx * cdx + cdy * cdy) * ((adx * bdytail + bdy * adxtail)
- - (ady * bdxtail + bdx * adytail))
- + 2.0 * (cdx * cdxtail + cdy * cdytail) * (adx * bdy - ady * bdx));
- if ((det >= errbound) || (-det >= errbound)) {
- return det;
- }
-
- finnow = fin1;
- finother = fin2;
-
- if ((bdxtail != 0.0) || (bdytail != 0.0)
- || (cdxtail != 0.0) || (cdytail != 0.0)) {
- Square(adx, adxadx1, adxadx0);
- Square(ady, adyady1, adyady0);
- Two_Two_Sum(adxadx1, adxadx0, adyady1, adyady0, aa3, aa[2], aa[1], aa[0]);
- aa[3] = aa3;
- }
- if ((cdxtail != 0.0) || (cdytail != 0.0)
- || (adxtail != 0.0) || (adytail != 0.0)) {
- Square(bdx, bdxbdx1, bdxbdx0);
- Square(bdy, bdybdy1, bdybdy0);
- Two_Two_Sum(bdxbdx1, bdxbdx0, bdybdy1, bdybdy0, bb3, bb[2], bb[1], bb[0]);
- bb[3] = bb3;
- }
- if ((adxtail != 0.0) || (adytail != 0.0)
- || (bdxtail != 0.0) || (bdytail != 0.0)) {
- Square(cdx, cdxcdx1, cdxcdx0);
- Square(cdy, cdycdy1, cdycdy0);
- Two_Two_Sum(cdxcdx1, cdxcdx0, cdycdy1, cdycdy0, cc3, cc[2], cc[1], cc[0]);
- cc[3] = cc3;
- }
-
- if (adxtail != 0.0) {
- axtbclen = scale_expansion_zeroelim(4, bc, adxtail, axtbc);
- temp16alen = scale_expansion_zeroelim(axtbclen, axtbc, 2.0 * adx,
- temp16a);
-
- axtcclen = scale_expansion_zeroelim(4, cc, adxtail, axtcc);
- temp16blen = scale_expansion_zeroelim(axtcclen, axtcc, bdy, temp16b);
-
- axtbblen = scale_expansion_zeroelim(4, bb, adxtail, axtbb);
- temp16clen = scale_expansion_zeroelim(axtbblen, axtbb, -cdy, temp16c);
-
- temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
- temp16blen, temp16b, temp32a);
- temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c,
- temp32alen, temp32a, temp48);
- finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
- temp48, finother);
- finswap = finnow; finnow = finother; finother = finswap;
- }
- if (adytail != 0.0) {
- aytbclen = scale_expansion_zeroelim(4, bc, adytail, aytbc);
- temp16alen = scale_expansion_zeroelim(aytbclen, aytbc, 2.0 * ady,
- temp16a);
-
- aytbblen = scale_expansion_zeroelim(4, bb, adytail, aytbb);
- temp16blen = scale_expansion_zeroelim(aytbblen, aytbb, cdx, temp16b);
-
- aytcclen = scale_expansion_zeroelim(4, cc, adytail, aytcc);
- temp16clen = scale_expansion_zeroelim(aytcclen, aytcc, -bdx, temp16c);
-
- temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
- temp16blen, temp16b, temp32a);
- temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c,
- temp32alen, temp32a, temp48);
- finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
- temp48, finother);
- finswap = finnow; finnow = finother; finother = finswap;
- }
- if (bdxtail != 0.0) {
- bxtcalen = scale_expansion_zeroelim(4, ca, bdxtail, bxtca);
- temp16alen = scale_expansion_zeroelim(bxtcalen, bxtca, 2.0 * bdx,
- temp16a);
-
- bxtaalen = scale_expansion_zeroelim(4, aa, bdxtail, bxtaa);
- temp16blen = scale_expansion_zeroelim(bxtaalen, bxtaa, cdy, temp16b);
-
- bxtcclen = scale_expansion_zeroelim(4, cc, bdxtail, bxtcc);
- temp16clen = scale_expansion_zeroelim(bxtcclen, bxtcc, -ady, temp16c);
-
- temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
- temp16blen, temp16b, temp32a);
- temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c,
- temp32alen, temp32a, temp48);
- finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
- temp48, finother);
- finswap = finnow; finnow = finother; finother = finswap;
- }
- if (bdytail != 0.0) {
- bytcalen = scale_expansion_zeroelim(4, ca, bdytail, bytca);
- temp16alen = scale_expansion_zeroelim(bytcalen, bytca, 2.0 * bdy,
- temp16a);
-
- bytcclen = scale_expansion_zeroelim(4, cc, bdytail, bytcc);
- temp16blen = scale_expansion_zeroelim(bytcclen, bytcc, adx, temp16b);
-
- bytaalen = scale_expansion_zeroelim(4, aa, bdytail, bytaa);
- temp16clen = scale_expansion_zeroelim(bytaalen, bytaa, -cdx, temp16c);
-
- temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
- temp16blen, temp16b, temp32a);
- temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c,
- temp32alen, temp32a, temp48);
- finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
- temp48, finother);
- finswap = finnow; finnow = finother; finother = finswap;
- }
- if (cdxtail != 0.0) {
- cxtablen = scale_expansion_zeroelim(4, ab, cdxtail, cxtab);
- temp16alen = scale_expansion_zeroelim(cxtablen, cxtab, 2.0 * cdx,
- temp16a);
-
- cxtbblen = scale_expansion_zeroelim(4, bb, cdxtail, cxtbb);
- temp16blen = scale_expansion_zeroelim(cxtbblen, cxtbb, ady, temp16b);
-
- cxtaalen = scale_expansion_zeroelim(4, aa, cdxtail, cxtaa);
- temp16clen = scale_expansion_zeroelim(cxtaalen, cxtaa, -bdy, temp16c);
-
- temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
- temp16blen, temp16b, temp32a);
- temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c,
- temp32alen, temp32a, temp48);
- finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
- temp48, finother);
- finswap = finnow; finnow = finother; finother = finswap;
- }
- if (cdytail != 0.0) {
- cytablen = scale_expansion_zeroelim(4, ab, cdytail, cytab);
- temp16alen = scale_expansion_zeroelim(cytablen, cytab, 2.0 * cdy,
- temp16a);
-
- cytaalen = scale_expansion_zeroelim(4, aa, cdytail, cytaa);
- temp16blen = scale_expansion_zeroelim(cytaalen, cytaa, bdx, temp16b);
-
- cytbblen = scale_expansion_zeroelim(4, bb, cdytail, cytbb);
- temp16clen = scale_expansion_zeroelim(cytbblen, cytbb, -adx, temp16c);
-
- temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
- temp16blen, temp16b, temp32a);
- temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c,
- temp32alen, temp32a, temp48);
- finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
- temp48, finother);
- finswap = finnow; finnow = finother; finother = finswap;
- }
-
- if ((adxtail != 0.0) || (adytail != 0.0)) {
- if ((bdxtail != 0.0) || (bdytail != 0.0)
- || (cdxtail != 0.0) || (cdytail != 0.0)) {
- Two_Product(bdxtail, cdy, ti1, ti0);
- Two_Product(bdx, cdytail, tj1, tj0);
- Two_Two_Sum(ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0]);
- u[3] = u3;
- negate = -bdy;
- Two_Product(cdxtail, negate, ti1, ti0);
- negate = -bdytail;
- Two_Product(cdx, negate, tj1, tj0);
- Two_Two_Sum(ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0]);
- v[3] = v3;
- bctlen = fast_expansion_sum_zeroelim(4, u, 4, v, bct);
-
- Two_Product(bdxtail, cdytail, ti1, ti0);
- Two_Product(cdxtail, bdytail, tj1, tj0);
- Two_Two_Diff(ti1, ti0, tj1, tj0, bctt3, bctt[2], bctt[1], bctt[0]);
- bctt[3] = bctt3;
- bcttlen = 4;
- } else {
- bct[0] = 0.0;
- bctlen = 1;
- bctt[0] = 0.0;
- bcttlen = 1;
- }
-
- if (adxtail != 0.0) {
- temp16alen = scale_expansion_zeroelim(axtbclen, axtbc, adxtail, temp16a);
- axtbctlen = scale_expansion_zeroelim(bctlen, bct, adxtail, axtbct);
- temp32alen = scale_expansion_zeroelim(axtbctlen, axtbct, 2.0 * adx,
- temp32a);
- temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a,
- temp32alen, temp32a, temp48);
- finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
- temp48, finother);
- finswap = finnow; finnow = finother; finother = finswap;
- if (bdytail != 0.0) {
- temp8len = scale_expansion_zeroelim(4, cc, adxtail, temp8);
- temp16alen = scale_expansion_zeroelim(temp8len, temp8, bdytail,
- temp16a);
- finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen,
- temp16a, finother);
- finswap = finnow; finnow = finother; finother = finswap;
- }
- if (cdytail != 0.0) {
- temp8len = scale_expansion_zeroelim(4, bb, -adxtail, temp8);
- temp16alen = scale_expansion_zeroelim(temp8len, temp8, cdytail,
- temp16a);
- finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen,
- temp16a, finother);
- finswap = finnow; finnow = finother; finother = finswap;
- }
-
- temp32alen = scale_expansion_zeroelim(axtbctlen, axtbct, adxtail,
- temp32a);
- axtbcttlen = scale_expansion_zeroelim(bcttlen, bctt, adxtail, axtbctt);
- temp16alen = scale_expansion_zeroelim(axtbcttlen, axtbctt, 2.0 * adx,
- temp16a);
- temp16blen = scale_expansion_zeroelim(axtbcttlen, axtbctt, adxtail,
- temp16b);
- temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
- temp16blen, temp16b, temp32b);
- temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a,
- temp32blen, temp32b, temp64);
- finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len,
- temp64, finother);
- finswap = finnow; finnow = finother; finother = finswap;
- }
- if (adytail != 0.0) {
- temp16alen = scale_expansion_zeroelim(aytbclen, aytbc, adytail, temp16a);
- aytbctlen = scale_expansion_zeroelim(bctlen, bct, adytail, aytbct);
- temp32alen = scale_expansion_zeroelim(aytbctlen, aytbct, 2.0 * ady,
- temp32a);
- temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a,
- temp32alen, temp32a, temp48);
- finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
- temp48, finother);
- finswap = finnow; finnow = finother; finother = finswap;
-
-
- temp32alen = scale_expansion_zeroelim(aytbctlen, aytbct, adytail,
- temp32a);
- aytbcttlen = scale_expansion_zeroelim(bcttlen, bctt, adytail, aytbctt);
- temp16alen = scale_expansion_zeroelim(aytbcttlen, aytbctt, 2.0 * ady,
- temp16a);
- temp16blen = scale_expansion_zeroelim(aytbcttlen, aytbctt, adytail,
- temp16b);
- temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
- temp16blen, temp16b, temp32b);
- temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a,
- temp32blen, temp32b, temp64);
- finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len,
- temp64, finother);
- finswap = finnow; finnow = finother; finother = finswap;
- }
- }
- if ((bdxtail != 0.0) || (bdytail != 0.0)) {
- if ((cdxtail != 0.0) || (cdytail != 0.0)
- || (adxtail != 0.0) || (adytail != 0.0)) {
- Two_Product(cdxtail, ady, ti1, ti0);
- Two_Product(cdx, adytail, tj1, tj0);
- Two_Two_Sum(ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0]);
- u[3] = u3;
- negate = -cdy;
- Two_Product(adxtail, negate, ti1, ti0);
- negate = -cdytail;
- Two_Product(adx, negate, tj1, tj0);
- Two_Two_Sum(ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0]);
- v[3] = v3;
- catlen = fast_expansion_sum_zeroelim(4, u, 4, v, cat);
-
- Two_Product(cdxtail, adytail, ti1, ti0);
- Two_Product(adxtail, cdytail, tj1, tj0);
- Two_Two_Diff(ti1, ti0, tj1, tj0, catt3, catt[2], catt[1], catt[0]);
- catt[3] = catt3;
- cattlen = 4;
- } else {
- cat[0] = 0.0;
- catlen = 1;
- catt[0] = 0.0;
- cattlen = 1;
- }
-
- if (bdxtail != 0.0) {
- temp16alen = scale_expansion_zeroelim(bxtcalen, bxtca, bdxtail, temp16a);
- bxtcatlen = scale_expansion_zeroelim(catlen, cat, bdxtail, bxtcat);
- temp32alen = scale_expansion_zeroelim(bxtcatlen, bxtcat, 2.0 * bdx,
- temp32a);
- temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a,
- temp32alen, temp32a, temp48);
- finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
- temp48, finother);
- finswap = finnow; finnow = finother; finother = finswap;
- if (cdytail != 0.0) {
- temp8len = scale_expansion_zeroelim(4, aa, bdxtail, temp8);
- temp16alen = scale_expansion_zeroelim(temp8len, temp8, cdytail,
- temp16a);
- finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen,
- temp16a, finother);
- finswap = finnow; finnow = finother; finother = finswap;
- }
- if (adytail != 0.0) {
- temp8len = scale_expansion_zeroelim(4, cc, -bdxtail, temp8);
- temp16alen = scale_expansion_zeroelim(temp8len, temp8, adytail,
- temp16a);
- finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen,
- temp16a, finother);
- finswap = finnow; finnow = finother; finother = finswap;
- }
-
- temp32alen = scale_expansion_zeroelim(bxtcatlen, bxtcat, bdxtail,
- temp32a);
- bxtcattlen = scale_expansion_zeroelim(cattlen, catt, bdxtail, bxtcatt);
- temp16alen = scale_expansion_zeroelim(bxtcattlen, bxtcatt, 2.0 * bdx,
- temp16a);
- temp16blen = scale_expansion_zeroelim(bxtcattlen, bxtcatt, bdxtail,
- temp16b);
- temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
- temp16blen, temp16b, temp32b);
- temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a,
- temp32blen, temp32b, temp64);
- finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len,
- temp64, finother);
- finswap = finnow; finnow = finother; finother = finswap;
- }
- if (bdytail != 0.0) {
- temp16alen = scale_expansion_zeroelim(bytcalen, bytca, bdytail, temp16a);
- bytcatlen = scale_expansion_zeroelim(catlen, cat, bdytail, bytcat);
- temp32alen = scale_expansion_zeroelim(bytcatlen, bytcat, 2.0 * bdy,
- temp32a);
- temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a,
- temp32alen, temp32a, temp48);
- finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
- temp48, finother);
- finswap = finnow; finnow = finother; finother = finswap;
-
-
- temp32alen = scale_expansion_zeroelim(bytcatlen, bytcat, bdytail,
- temp32a);
- bytcattlen = scale_expansion_zeroelim(cattlen, catt, bdytail, bytcatt);
- temp16alen = scale_expansion_zeroelim(bytcattlen, bytcatt, 2.0 * bdy,
- temp16a);
- temp16blen = scale_expansion_zeroelim(bytcattlen, bytcatt, bdytail,
- temp16b);
- temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
- temp16blen, temp16b, temp32b);
- temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a,
- temp32blen, temp32b, temp64);
- finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len,
- temp64, finother);
- finswap = finnow; finnow = finother; finother = finswap;
- }
- }
- if ((cdxtail != 0.0) || (cdytail != 0.0)) {
- if ((adxtail != 0.0) || (adytail != 0.0)
- || (bdxtail != 0.0) || (bdytail != 0.0)) {
- Two_Product(adxtail, bdy, ti1, ti0);
- Two_Product(adx, bdytail, tj1, tj0);
- Two_Two_Sum(ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0]);
- u[3] = u3;
- negate = -ady;
- Two_Product(bdxtail, negate, ti1, ti0);
- negate = -adytail;
- Two_Product(bdx, negate, tj1, tj0);
- Two_Two_Sum(ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0]);
- v[3] = v3;
- abtlen = fast_expansion_sum_zeroelim(4, u, 4, v, abt);
-
- Two_Product(adxtail, bdytail, ti1, ti0);
- Two_Product(bdxtail, adytail, tj1, tj0);
- Two_Two_Diff(ti1, ti0, tj1, tj0, abtt3, abtt[2], abtt[1], abtt[0]);
- abtt[3] = abtt3;
- abttlen = 4;
- } else {
- abt[0] = 0.0;
- abtlen = 1;
- abtt[0] = 0.0;
- abttlen = 1;
- }
-
- if (cdxtail != 0.0) {
- temp16alen = scale_expansion_zeroelim(cxtablen, cxtab, cdxtail, temp16a);
- cxtabtlen = scale_expansion_zeroelim(abtlen, abt, cdxtail, cxtabt);
- temp32alen = scale_expansion_zeroelim(cxtabtlen, cxtabt, 2.0 * cdx,
- temp32a);
- temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a,
- temp32alen, temp32a, temp48);
- finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
- temp48, finother);
- finswap = finnow; finnow = finother; finother = finswap;
- if (adytail != 0.0) {
- temp8len = scale_expansion_zeroelim(4, bb, cdxtail, temp8);
- temp16alen = scale_expansion_zeroelim(temp8len, temp8, adytail,
- temp16a);
- finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen,
- temp16a, finother);
- finswap = finnow; finnow = finother; finother = finswap;
- }
- if (bdytail != 0.0) {
- temp8len = scale_expansion_zeroelim(4, aa, -cdxtail, temp8);
- temp16alen = scale_expansion_zeroelim(temp8len, temp8, bdytail,
- temp16a);
- finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen,
- temp16a, finother);
- finswap = finnow; finnow = finother; finother = finswap;
- }
-
- temp32alen = scale_expansion_zeroelim(cxtabtlen, cxtabt, cdxtail,
- temp32a);
- cxtabttlen = scale_expansion_zeroelim(abttlen, abtt, cdxtail, cxtabtt);
- temp16alen = scale_expansion_zeroelim(cxtabttlen, cxtabtt, 2.0 * cdx,
- temp16a);
- temp16blen = scale_expansion_zeroelim(cxtabttlen, cxtabtt, cdxtail,
- temp16b);
- temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
- temp16blen, temp16b, temp32b);
- temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a,
- temp32blen, temp32b, temp64);
- finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len,
- temp64, finother);
- finswap = finnow; finnow = finother; finother = finswap;
- }
- if (cdytail != 0.0) {
- temp16alen = scale_expansion_zeroelim(cytablen, cytab, cdytail, temp16a);
- cytabtlen = scale_expansion_zeroelim(abtlen, abt, cdytail, cytabt);
- temp32alen = scale_expansion_zeroelim(cytabtlen, cytabt, 2.0 * cdy,
- temp32a);
- temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a,
- temp32alen, temp32a, temp48);
- finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
- temp48, finother);
- finswap = finnow; finnow = finother; finother = finswap;
-
-
- temp32alen = scale_expansion_zeroelim(cytabtlen, cytabt, cdytail,
- temp32a);
- cytabttlen = scale_expansion_zeroelim(abttlen, abtt, cdytail, cytabtt);
- temp16alen = scale_expansion_zeroelim(cytabttlen, cytabtt, 2.0 * cdy,
- temp16a);
- temp16blen = scale_expansion_zeroelim(cytabttlen, cytabtt, cdytail,
- temp16b);
- temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
- temp16blen, temp16b, temp32b);
- temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a,
- temp32blen, temp32b, temp64);
- finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len,
- temp64, finother);
- finswap = finnow; finnow = finother; finother = finswap;
- }
- }
-
- return finnow[finlength - 1];
-}
-
-REAL incircle (
- __const_ptr(REAL) pa,
- __const_ptr(REAL) pb,
- __const_ptr(REAL) pc,
- __const_ptr(REAL) pd)
-{
- REAL adx, bdx, cdx, ady, bdy, cdy;
- REAL bdxcdy, cdxbdy, cdxady, adxcdy, adxbdy, bdxady;
- REAL alift, blift, clift;
- REAL det;
- REAL permanent, errbound;
-
- adx = pa[0] - pd[0];
- bdx = pb[0] - pd[0];
- cdx = pc[0] - pd[0];
- ady = pa[1] - pd[1];
- bdy = pb[1] - pd[1];
- cdy = pc[1] - pd[1];
-
- bdxcdy = bdx * cdy;
- cdxbdy = cdx * bdy;
- alift = adx * adx + ady * ady;
-
- cdxady = cdx * ady;
- adxcdy = adx * cdy;
- blift = bdx * bdx + bdy * bdy;
-
- adxbdy = adx * bdy;
- bdxady = bdx * ady;
- clift = cdx * cdx + cdy * cdy;
-
- det = alift * (bdxcdy - cdxbdy)
- + blift * (cdxady - adxcdy)
- + clift * (adxbdy - bdxady);
-
- permanent = (Absolute(bdxcdy) + Absolute(cdxbdy)) * alift
- + (Absolute(cdxady) + Absolute(adxcdy)) * blift
- + (Absolute(adxbdy) + Absolute(bdxady)) * clift;
- errbound = iccerrboundA * permanent;
- if ((det > errbound) || (-det > errbound)) {
- return det;
- }
-
- return incircleadapt(pa, pb, pc, pd, permanent);
-}
-
-/*****************************************************************************/
-/* */
-/* insphere() Adaptive exact 3D insphere test. Robust. */
-/* */
-/* Return a positive value if the point pe lies inside the */
-/* sphere passing through pa, pb, pc, and pd; a negative value */
-/* if it lies outside; and zero if the five points are */
-/* cospherical. The points pa, pb, pc, and pd must be ordered */
-/* so that they have a positive orientation (as defined by */
-/* orient3d()), or the sign of the result will be reversed. */
-/* */
-/* The last three use exact arithmetic to ensure a correct answer. The */
-/* result returned is the determinant of a matrix. In insphere() only, */
-/* this determinant is computed adaptively, in the sense that exact */
-/* arithmetic is used only to the degree it is needed to ensure that the */
-/* returned value has the correct sign. Hence, insphere() is usually quite */
-/* fast, but will run more slowly when the input points are cospherical or */
-/* nearly so. */
-/* */
-/*****************************************************************************/
-
-REAL insphereexact (
- __const_ptr(REAL) pa,
- __const_ptr(REAL) pb,
- __const_ptr(REAL) pc,
- __const_ptr(REAL) pd,
- __const_ptr(REAL) pe)
-{
- REAL axby1, bxcy1, cxdy1, dxey1, exay1;
- REAL bxay1, cxby1, dxcy1, exdy1, axey1;
- REAL axcy1, bxdy1, cxey1, dxay1, exby1;
- REAL cxay1, dxby1, excy1, axdy1, bxey1;
- REAL axby0, bxcy0, cxdy0, dxey0, exay0;
- REAL bxay0, cxby0, dxcy0, exdy0, axey0;
- REAL axcy0, bxdy0, cxey0, dxay0, exby0;
- REAL cxay0, dxby0, excy0, axdy0, bxey0;
- REAL ab[4], bc[4], cd[4], de[4], ea[4];
- REAL ac[4], bd[4], ce[4], da[4], eb[4];
- REAL temp8a[8], temp8b[8], temp16[16];
- int temp8alen=0, temp8blen=0, temp16len=0;
- REAL abc[24], bcd[24], cde[24], dea[24], eab[24];
- REAL abd[24], bce[24], cda[24], deb[24], eac[24];
- int abclen=0, bcdlen=0, cdelen=0, dealen=0, eablen=0;
- int abdlen=0, bcelen=0, cdalen=0, deblen=0, eaclen=0;
- REAL temp48a[48], temp48b[48];
- int temp48alen=0, temp48blen=0;
- REAL abcd[96], bcde[96], cdea[96], deab[96], eabc[96];
- int abcdlen=0, bcdelen=0, cdealen=0, deablen=0, eabclen=0;
- REAL temp192[192];
- REAL det384x[384], det384y[384], det384z[384];
- int xlen=0, ylen=0, zlen=0;
- REAL detxy[768];
- int xylen=0;
- REAL adet[1152], bdet[1152], cdet[1152], ddet[1152], edet[1152];
- int alen=0, blen=0, clen=0, dlen=0, elen=0;
- REAL abdet[2304], cddet[2304], cdedet[3456];
- int ablen=0, cdlen=0;
- REAL deter[5760];
- int deterlen=0;
- int i;
-
- REAL bvirt, avirt, bround, around;
- REAL c, abig, ahi, alo, bhi, blo;
- REAL err1, err2, err3;
- REAL _i, _j, _0;
-
- Two_Product(pa[0], pb[1], axby1, axby0);
- Two_Product(pb[0], pa[1], bxay1, bxay0);
- Two_Two_Diff(axby1, axby0, bxay1, bxay0, ab[3], ab[2], ab[1], ab[0]);
-
- Two_Product(pb[0], pc[1], bxcy1, bxcy0);
- Two_Product(pc[0], pb[1], cxby1, cxby0);
- Two_Two_Diff(bxcy1, bxcy0, cxby1, cxby0, bc[3], bc[2], bc[1], bc[0]);
-
- Two_Product(pc[0], pd[1], cxdy1, cxdy0);
- Two_Product(pd[0], pc[1], dxcy1, dxcy0);
- Two_Two_Diff(cxdy1, cxdy0, dxcy1, dxcy0, cd[3], cd[2], cd[1], cd[0]);
-
- Two_Product(pd[0], pe[1], dxey1, dxey0);
- Two_Product(pe[0], pd[1], exdy1, exdy0);
- Two_Two_Diff(dxey1, dxey0, exdy1, exdy0, de[3], de[2], de[1], de[0]);
-
- Two_Product(pe[0], pa[1], exay1, exay0);
- Two_Product(pa[0], pe[1], axey1, axey0);
- Two_Two_Diff(exay1, exay0, axey1, axey0, ea[3], ea[2], ea[1], ea[0]);
-
- Two_Product(pa[0], pc[1], axcy1, axcy0);
- Two_Product(pc[0], pa[1], cxay1, cxay0);
- Two_Two_Diff(axcy1, axcy0, cxay1, cxay0, ac[3], ac[2], ac[1], ac[0]);
-
- Two_Product(pb[0], pd[1], bxdy1, bxdy0);
- Two_Product(pd[0], pb[1], dxby1, dxby0);
- Two_Two_Diff(bxdy1, bxdy0, dxby1, dxby0, bd[3], bd[2], bd[1], bd[0]);
-
- Two_Product(pc[0], pe[1], cxey1, cxey0);
- Two_Product(pe[0], pc[1], excy1, excy0);
- Two_Two_Diff(cxey1, cxey0, excy1, excy0, ce[3], ce[2], ce[1], ce[0]);
-
- Two_Product(pd[0], pa[1], dxay1, dxay0);
- Two_Product(pa[0], pd[1], axdy1, axdy0);
- Two_Two_Diff(dxay1, dxay0, axdy1, axdy0, da[3], da[2], da[1], da[0]);
-
- Two_Product(pe[0], pb[1], exby1, exby0);
- Two_Product(pb[0], pe[1], bxey1, bxey0);
- Two_Two_Diff(exby1, exby0, bxey1, bxey0, eb[3], eb[2], eb[1], eb[0]);
-
- temp8alen = scale_expansion_zeroelim(4, bc, pa[2], temp8a);
- temp8blen = scale_expansion_zeroelim(4, ac, -pb[2], temp8b);
- temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b,
- temp16);
- temp8alen = scale_expansion_zeroelim(4, ab, pc[2], temp8a);
- abclen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16,
- abc);
-
- temp8alen = scale_expansion_zeroelim(4, cd, pb[2], temp8a);
- temp8blen = scale_expansion_zeroelim(4, bd, -pc[2], temp8b);
- temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b,
- temp16);
- temp8alen = scale_expansion_zeroelim(4, bc, pd[2], temp8a);
- bcdlen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16,
- bcd);
-
- temp8alen = scale_expansion_zeroelim(4, de, pc[2], temp8a);
- temp8blen = scale_expansion_zeroelim(4, ce, -pd[2], temp8b);
- temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b,
- temp16);
- temp8alen = scale_expansion_zeroelim(4, cd, pe[2], temp8a);
- cdelen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16,
- cde);
-
- temp8alen = scale_expansion_zeroelim(4, ea, pd[2], temp8a);
- temp8blen = scale_expansion_zeroelim(4, da, -pe[2], temp8b);
- temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b,
- temp16);
- temp8alen = scale_expansion_zeroelim(4, de, pa[2], temp8a);
- dealen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16,
- dea);
-
- temp8alen = scale_expansion_zeroelim(4, ab, pe[2], temp8a);
- temp8blen = scale_expansion_zeroelim(4, eb, -pa[2], temp8b);
- temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b,
- temp16);
- temp8alen = scale_expansion_zeroelim(4, ea, pb[2], temp8a);
- eablen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16,
- eab);
-
- temp8alen = scale_expansion_zeroelim(4, bd, pa[2], temp8a);
- temp8blen = scale_expansion_zeroelim(4, da, pb[2], temp8b);
- temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b,
- temp16);
- temp8alen = scale_expansion_zeroelim(4, ab, pd[2], temp8a);
- abdlen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16,
- abd);
-
- temp8alen = scale_expansion_zeroelim(4, ce, pb[2], temp8a);
- temp8blen = scale_expansion_zeroelim(4, eb, pc[2], temp8b);
- temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b,
- temp16);
- temp8alen = scale_expansion_zeroelim(4, bc, pe[2], temp8a);
- bcelen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16,
- bce);
-
- temp8alen = scale_expansion_zeroelim(4, da, pc[2], temp8a);
- temp8blen = scale_expansion_zeroelim(4, ac, pd[2], temp8b);
- temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b,
- temp16);
- temp8alen = scale_expansion_zeroelim(4, cd, pa[2], temp8a);
- cdalen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16,
- cda);
-
- temp8alen = scale_expansion_zeroelim(4, eb, pd[2], temp8a);
- temp8blen = scale_expansion_zeroelim(4, bd, pe[2], temp8b);
- temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b,
- temp16);
- temp8alen = scale_expansion_zeroelim(4, de, pb[2], temp8a);
- deblen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16,
- deb);
-
- temp8alen = scale_expansion_zeroelim(4, ac, pe[2], temp8a);
- temp8blen = scale_expansion_zeroelim(4, ce, pa[2], temp8b);
- temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b,
- temp16);
- temp8alen = scale_expansion_zeroelim(4, ea, pc[2], temp8a);
- eaclen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16,
- eac);
-
- temp48alen = fast_expansion_sum_zeroelim(cdelen, cde, bcelen, bce, temp48a);
- temp48blen = fast_expansion_sum_zeroelim(deblen, deb, bcdlen, bcd, temp48b);
- for (i = 0; i < temp48blen; i++) {
- temp48b[i] = -temp48b[i];
- }
- bcdelen = fast_expansion_sum_zeroelim(temp48alen, temp48a,
- temp48blen, temp48b, bcde);
- xlen = scale_expansion_zeroelim(bcdelen, bcde, pa[0], temp192);
- xlen = scale_expansion_zeroelim(xlen, temp192, pa[0], det384x);
- ylen = scale_expansion_zeroelim(bcdelen, bcde, pa[1], temp192);
- ylen = scale_expansion_zeroelim(ylen, temp192, pa[1], det384y);
- zlen = scale_expansion_zeroelim(bcdelen, bcde, pa[2], temp192);
- zlen = scale_expansion_zeroelim(zlen, temp192, pa[2], det384z);
- xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy);
- alen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, adet);
-
- temp48alen = fast_expansion_sum_zeroelim(dealen, dea, cdalen, cda, temp48a);
- temp48blen = fast_expansion_sum_zeroelim(eaclen, eac, cdelen, cde, temp48b);
- for (i = 0; i < temp48blen; i++) {
- temp48b[i] = -temp48b[i];
- }
- cdealen = fast_expansion_sum_zeroelim(temp48alen, temp48a,
- temp48blen, temp48b, cdea);
- xlen = scale_expansion_zeroelim(cdealen, cdea, pb[0], temp192);
- xlen = scale_expansion_zeroelim(xlen, temp192, pb[0], det384x);
- ylen = scale_expansion_zeroelim(cdealen, cdea, pb[1], temp192);
- ylen = scale_expansion_zeroelim(ylen, temp192, pb[1], det384y);
- zlen = scale_expansion_zeroelim(cdealen, cdea, pb[2], temp192);
- zlen = scale_expansion_zeroelim(zlen, temp192, pb[2], det384z);
- xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy);
- blen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, bdet);
-
- temp48alen = fast_expansion_sum_zeroelim(eablen, eab, deblen, deb, temp48a);
- temp48blen = fast_expansion_sum_zeroelim(abdlen, abd, dealen, dea, temp48b);
- for (i = 0; i < temp48blen; i++) {
- temp48b[i] = -temp48b[i];
- }
- deablen = fast_expansion_sum_zeroelim(temp48alen, temp48a,
- temp48blen, temp48b, deab);
- xlen = scale_expansion_zeroelim(deablen, deab, pc[0], temp192);
- xlen = scale_expansion_zeroelim(xlen, temp192, pc[0], det384x);
- ylen = scale_expansion_zeroelim(deablen, deab, pc[1], temp192);
- ylen = scale_expansion_zeroelim(ylen, temp192, pc[1], det384y);
- zlen = scale_expansion_zeroelim(deablen, deab, pc[2], temp192);
- zlen = scale_expansion_zeroelim(zlen, temp192, pc[2], det384z);
- xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy);
- clen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, cdet);
-
- temp48alen = fast_expansion_sum_zeroelim(abclen, abc, eaclen, eac, temp48a);
- temp48blen = fast_expansion_sum_zeroelim(bcelen, bce, eablen, eab, temp48b);
- for (i = 0; i < temp48blen; i++) {
- temp48b[i] = -temp48b[i];
- }
- eabclen = fast_expansion_sum_zeroelim(temp48alen, temp48a,
- temp48blen, temp48b, eabc);
- xlen = scale_expansion_zeroelim(eabclen, eabc, pd[0], temp192);
- xlen = scale_expansion_zeroelim(xlen, temp192, pd[0], det384x);
- ylen = scale_expansion_zeroelim(eabclen, eabc, pd[1], temp192);
- ylen = scale_expansion_zeroelim(ylen, temp192, pd[1], det384y);
- zlen = scale_expansion_zeroelim(eabclen, eabc, pd[2], temp192);
- zlen = scale_expansion_zeroelim(zlen, temp192, pd[2], det384z);
- xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy);
- dlen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, ddet);
-
- temp48alen = fast_expansion_sum_zeroelim(bcdlen, bcd, abdlen, abd, temp48a);
- temp48blen = fast_expansion_sum_zeroelim(cdalen, cda, abclen, abc, temp48b);
- for (i = 0; i < temp48blen; i++) {
- temp48b[i] = -temp48b[i];
- }
- abcdlen = fast_expansion_sum_zeroelim(temp48alen, temp48a,
- temp48blen, temp48b, abcd);
- xlen = scale_expansion_zeroelim(abcdlen, abcd, pe[0], temp192);
- xlen = scale_expansion_zeroelim(xlen, temp192, pe[0], det384x);
- ylen = scale_expansion_zeroelim(abcdlen, abcd, pe[1], temp192);
- ylen = scale_expansion_zeroelim(ylen, temp192, pe[1], det384y);
- zlen = scale_expansion_zeroelim(abcdlen, abcd, pe[2], temp192);
- zlen = scale_expansion_zeroelim(zlen, temp192, pe[2], det384z);
- xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy);
- elen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, edet);
-
- ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet);
- cdlen = fast_expansion_sum_zeroelim(clen, cdet, dlen, ddet, cddet);
- cdelen = fast_expansion_sum_zeroelim(cdlen, cddet, elen, edet, cdedet);
- deterlen = fast_expansion_sum_zeroelim(ablen, abdet, cdelen, cdedet, deter);
-
- return deter[deterlen - 1];
-}
-
-REAL insphereadapt (
- __const_ptr(REAL) pa,
- __const_ptr(REAL) pb,
- __const_ptr(REAL) pc,
- __const_ptr(REAL) pd,
- __const_ptr(REAL) pe,
- REAL permanent)
-{
- REAL aex, bex, cex, dex, aey, bey, cey, dey, aez, bez, cez, dez;
- REAL det, errbound;
-
- REAL aexbey1, bexaey1, bexcey1, cexbey1;
- REAL cexdey1, dexcey1, dexaey1, aexdey1;
- REAL aexcey1, cexaey1, bexdey1, dexbey1;
- REAL aexbey0, bexaey0, bexcey0, cexbey0;
- REAL cexdey0, dexcey0, dexaey0, aexdey0;
- REAL aexcey0, cexaey0, bexdey0, dexbey0;
- REAL ab[4], bc[4], cd[4], da[4], ac[4], bd[4];
- REAL ab3, bc3, cd3, da3, ac3, bd3;
- REAL abeps, bceps, cdeps, daeps, aceps, bdeps;
- REAL temp8a[8], temp8b[8], temp8c[8], temp16[16], temp24[24], temp48[48];
- int temp8alen=0, temp8blen=0, temp8clen=0;
- int temp16len=0, temp24len=0, temp48len=0;
- REAL xdet[96], ydet[96], zdet[96], xydet[192];
- int xlen=0, ylen=0, zlen=0, xylen=0;
- REAL adet[288], bdet[288], cdet[288], ddet[288];
- int alen=0, blen=0, clen=0, dlen=0;
- REAL abdet[576], cddet[576];
- int ablen=0, cdlen=0;
- REAL fin1[1152];
- int finlength=0;
-
- REAL aextail, bextail, cextail, dextail;
- REAL aeytail, beytail, ceytail, deytail;
- REAL aeztail, beztail, ceztail, deztail;
-
- REAL bvirt, avirt, bround, around;
- REAL c, abig, ahi, alo, bhi, blo;
- REAL err1, err2, err3;
- REAL _i, _j, _0;
-
- aex = (REAL) (pa[0] - pe[0]);
- bex = (REAL) (pb[0] - pe[0]);
- cex = (REAL) (pc[0] - pe[0]);
- dex = (REAL) (pd[0] - pe[0]);
- aey = (REAL) (pa[1] - pe[1]);
- bey = (REAL) (pb[1] - pe[1]);
- cey = (REAL) (pc[1] - pe[1]);
- dey = (REAL) (pd[1] - pe[1]);
- aez = (REAL) (pa[2] - pe[2]);
- bez = (REAL) (pb[2] - pe[2]);
- cez = (REAL) (pc[2] - pe[2]);
- dez = (REAL) (pd[2] - pe[2]);
-
- Two_Product(aex, bey, aexbey1, aexbey0);
- Two_Product(bex, aey, bexaey1, bexaey0);
- Two_Two_Diff(aexbey1, aexbey0, bexaey1, bexaey0, ab3, ab[2], ab[1], ab[0]);
- ab[3] = ab3;
-
- Two_Product(bex, cey, bexcey1, bexcey0);
- Two_Product(cex, bey, cexbey1, cexbey0);
- Two_Two_Diff(bexcey1, bexcey0, cexbey1, cexbey0, bc3, bc[2], bc[1], bc[0]);
- bc[3] = bc3;
-
- Two_Product(cex, dey, cexdey1, cexdey0);
- Two_Product(dex, cey, dexcey1, dexcey0);
- Two_Two_Diff(cexdey1, cexdey0, dexcey1, dexcey0, cd3, cd[2], cd[1], cd[0]);
- cd[3] = cd3;
-
- Two_Product(dex, aey, dexaey1, dexaey0);
- Two_Product(aex, dey, aexdey1, aexdey0);
- Two_Two_Diff(dexaey1, dexaey0, aexdey1, aexdey0, da3, da[2], da[1], da[0]);
- da[3] = da3;
-
- Two_Product(aex, cey, aexcey1, aexcey0);
- Two_Product(cex, aey, cexaey1, cexaey0);
- Two_Two_Diff(aexcey1, aexcey0, cexaey1, cexaey0, ac3, ac[2], ac[1], ac[0]);
- ac[3] = ac3;
-
- Two_Product(bex, dey, bexdey1, bexdey0);
- Two_Product(dex, bey, dexbey1, dexbey0);
- Two_Two_Diff(bexdey1, bexdey0, dexbey1, dexbey0, bd3, bd[2], bd[1], bd[0]);
- bd[3] = bd3;
-
- temp8alen = scale_expansion_zeroelim(4, cd, bez, temp8a);
- temp8blen = scale_expansion_zeroelim(4, bd, -cez, temp8b);
- temp8clen = scale_expansion_zeroelim(4, bc, dez, temp8c);
- temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a,
- temp8blen, temp8b, temp16);
- temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c,
- temp16len, temp16, temp24);
- temp48len = scale_expansion_zeroelim(temp24len, temp24, aex, temp48);
- xlen = scale_expansion_zeroelim(temp48len, temp48, -aex, xdet);
- temp48len = scale_expansion_zeroelim(temp24len, temp24, aey, temp48);
- ylen = scale_expansion_zeroelim(temp48len, temp48, -aey, ydet);
- temp48len = scale_expansion_zeroelim(temp24len, temp24, aez, temp48);
- zlen = scale_expansion_zeroelim(temp48len, temp48, -aez, zdet);
- xylen = fast_expansion_sum_zeroelim(xlen, xdet, ylen, ydet, xydet);
- alen = fast_expansion_sum_zeroelim(xylen, xydet, zlen, zdet, adet);
-
- temp8alen = scale_expansion_zeroelim(4, da, cez, temp8a);
- temp8blen = scale_expansion_zeroelim(4, ac, dez, temp8b);
- temp8clen = scale_expansion_zeroelim(4, cd, aez, temp8c);
- temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a,
- temp8blen, temp8b, temp16);
- temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c,
- temp16len, temp16, temp24);
- temp48len = scale_expansion_zeroelim(temp24len, temp24, bex, temp48);
- xlen = scale_expansion_zeroelim(temp48len, temp48, bex, xdet);
- temp48len = scale_expansion_zeroelim(temp24len, temp24, bey, temp48);
- ylen = scale_expansion_zeroelim(temp48len, temp48, bey, ydet);
- temp48len = scale_expansion_zeroelim(temp24len, temp24, bez, temp48);
- zlen = scale_expansion_zeroelim(temp48len, temp48, bez, zdet);
- xylen = fast_expansion_sum_zeroelim(xlen, xdet, ylen, ydet, xydet);
- blen = fast_expansion_sum_zeroelim(xylen, xydet, zlen, zdet, bdet);
-
- temp8alen = scale_expansion_zeroelim(4, ab, dez, temp8a);
- temp8blen = scale_expansion_zeroelim(4, bd, aez, temp8b);
- temp8clen = scale_expansion_zeroelim(4, da, bez, temp8c);
- temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a,
- temp8blen, temp8b, temp16);
- temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c,
- temp16len, temp16, temp24);
- temp48len = scale_expansion_zeroelim(temp24len, temp24, cex, temp48);
- xlen = scale_expansion_zeroelim(temp48len, temp48, -cex, xdet);
- temp48len = scale_expansion_zeroelim(temp24len, temp24, cey, temp48);
- ylen = scale_expansion_zeroelim(temp48len, temp48, -cey, ydet);
- temp48len = scale_expansion_zeroelim(temp24len, temp24, cez, temp48);
- zlen = scale_expansion_zeroelim(temp48len, temp48, -cez, zdet);
- xylen = fast_expansion_sum_zeroelim(xlen, xdet, ylen, ydet, xydet);
- clen = fast_expansion_sum_zeroelim(xylen, xydet, zlen, zdet, cdet);
-
- temp8alen = scale_expansion_zeroelim(4, bc, aez, temp8a);
- temp8blen = scale_expansion_zeroelim(4, ac, -bez, temp8b);
- temp8clen = scale_expansion_zeroelim(4, ab, cez, temp8c);
- temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a,
- temp8blen, temp8b, temp16);
- temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c,
- temp16len, temp16, temp24);
- temp48len = scale_expansion_zeroelim(temp24len, temp24, dex, temp48);
- xlen = scale_expansion_zeroelim(temp48len, temp48, dex, xdet);
- temp48len = scale_expansion_zeroelim(temp24len, temp24, dey, temp48);
- ylen = scale_expansion_zeroelim(temp48len, temp48, dey, ydet);
- temp48len = scale_expansion_zeroelim(temp24len, temp24, dez, temp48);
- zlen = scale_expansion_zeroelim(temp48len, temp48, dez, zdet);
- xylen = fast_expansion_sum_zeroelim(xlen, xdet, ylen, ydet, xydet);
- dlen = fast_expansion_sum_zeroelim(xylen, xydet, zlen, zdet, ddet);
-
- ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet);
- cdlen = fast_expansion_sum_zeroelim(clen, cdet, dlen, ddet, cddet);
- finlength = fast_expansion_sum_zeroelim(ablen, abdet, cdlen, cddet, fin1);
-
- det = estimate(finlength, fin1);
- errbound = isperrboundB * permanent;
- if ((det >= errbound) || (-det >= errbound)) {
- return det;
- }
-
- Two_Diff_Tail(pa[0], pe[0], aex, aextail);
- Two_Diff_Tail(pa[1], pe[1], aey, aeytail);
- Two_Diff_Tail(pa[2], pe[2], aez, aeztail);
- Two_Diff_Tail(pb[0], pe[0], bex, bextail);
- Two_Diff_Tail(pb[1], pe[1], bey, beytail);
- Two_Diff_Tail(pb[2], pe[2], bez, beztail);
- Two_Diff_Tail(pc[0], pe[0], cex, cextail);
- Two_Diff_Tail(pc[1], pe[1], cey, ceytail);
- Two_Diff_Tail(pc[2], pe[2], cez, ceztail);
- Two_Diff_Tail(pd[0], pe[0], dex, dextail);
- Two_Diff_Tail(pd[1], pe[1], dey, deytail);
- Two_Diff_Tail(pd[2], pe[2], dez, deztail);
- if ((aextail == 0.0) && (aeytail == 0.0) && (aeztail == 0.0)
- && (bextail == 0.0) && (beytail == 0.0) && (beztail == 0.0)
- && (cextail == 0.0) && (ceytail == 0.0) && (ceztail == 0.0)
- && (dextail == 0.0) && (deytail == 0.0) && (deztail == 0.0)) {
- return det;
- }
-
- errbound = isperrboundC * permanent + resulterrbound * Absolute(det);
- abeps = (aex * beytail + bey * aextail)
- - (aey * bextail + bex * aeytail);
- bceps = (bex * ceytail + cey * bextail)
- - (bey * cextail + cex * beytail);
- cdeps = (cex * deytail + dey * cextail)
- - (cey * dextail + dex * ceytail);
- daeps = (dex * aeytail + aey * dextail)
- - (dey * aextail + aex * deytail);
- aceps = (aex * ceytail + cey * aextail)
- - (aey * cextail + cex * aeytail);
- bdeps = (bex * deytail + dey * bextail)
- - (bey * dextail + dex * beytail);
- det += (((bex * bex + bey * bey + bez * bez)
- * ((cez * daeps + dez * aceps + aez * cdeps)
- + (ceztail * da3 + deztail * ac3 + aeztail * cd3))
- + (dex * dex + dey * dey + dez * dez)
- * ((aez * bceps - bez * aceps + cez * abeps)
- + (aeztail * bc3 - beztail * ac3 + ceztail * ab3)))
- - ((aex * aex + aey * aey + aez * aez)
- * ((bez * cdeps - cez * bdeps + dez * bceps)
- + (beztail * cd3 - ceztail * bd3 + deztail * bc3))
- + (cex * cex + cey * cey + cez * cez)
- * ((dez * abeps + aez * bdeps + bez * daeps)
- + (deztail * ab3 + aeztail * bd3 + beztail * da3))))
- + 2.0 * (((bex * bextail + bey * beytail + bez * beztail)
- * (cez * da3 + dez * ac3 + aez * cd3)
- + (dex * dextail + dey * deytail + dez * deztail)
- * (aez * bc3 - bez * ac3 + cez * ab3))
- - ((aex * aextail + aey * aeytail + aez * aeztail)
- * (bez * cd3 - cez * bd3 + dez * bc3)
- + (cex * cextail + cey * ceytail + cez * ceztail)
- * (dez * ab3 + aez * bd3 + bez * da3)));
- if ((det >= errbound) || (-det >= errbound)) {
- return det;
- }
-
- return insphereexact(pa, pb, pc, pd, pe);
-}
-
-REAL insphere (
- __const_ptr(REAL) pa,
- __const_ptr(REAL) pb,
- __const_ptr(REAL) pc,
- __const_ptr(REAL) pd,
- __const_ptr(REAL) pe)
-{
- REAL aex, bex, cex, dex;
- REAL aey, bey, cey, dey;
- REAL aez, bez, cez, dez;
- REAL aexbey, bexaey, bexcey, cexbey, cexdey, dexcey, dexaey, aexdey;
- REAL aexcey, cexaey, bexdey, dexbey;
- REAL alift, blift, clift, dlift;
- REAL ab, bc, cd, da, ac, bd;
- REAL abc, bcd, cda, dab;
- REAL aezplus, bezplus, cezplus, dezplus;
- REAL aexbeyplus, bexaeyplus, bexceyplus, cexbeyplus;
- REAL cexdeyplus, dexceyplus, dexaeyplus, aexdeyplus;
- REAL aexceyplus, cexaeyplus, bexdeyplus, dexbeyplus;
- REAL det;
- REAL permanent, errbound;
-
- aex = pa[0] - pe[0];
- bex = pb[0] - pe[0];
- cex = pc[0] - pe[0];
- dex = pd[0] - pe[0];
- aey = pa[1] - pe[1];
- bey = pb[1] - pe[1];
- cey = pc[1] - pe[1];
- dey = pd[1] - pe[1];
- aez = pa[2] - pe[2];
- bez = pb[2] - pe[2];
- cez = pc[2] - pe[2];
- dez = pd[2] - pe[2];
-
- aexbey = aex * bey;
- bexaey = bex * aey;
- ab = aexbey - bexaey;
- bexcey = bex * cey;
- cexbey = cex * bey;
- bc = bexcey - cexbey;
- cexdey = cex * dey;
- dexcey = dex * cey;
- cd = cexdey - dexcey;
- dexaey = dex * aey;
- aexdey = aex * dey;
- da = dexaey - aexdey;
-
- aexcey = aex * cey;
- cexaey = cex * aey;
- ac = aexcey - cexaey;
- bexdey = bex * dey;
- dexbey = dex * bey;
- bd = bexdey - dexbey;
-
- abc = aez * bc - bez * ac + cez * ab;
- bcd = bez * cd - cez * bd + dez * bc;
- cda = cez * da + dez * ac + aez * cd;
- dab = dez * ab + aez * bd + bez * da;
-
- alift = aex * aex + aey * aey + aez * aez;
- blift = bex * bex + bey * bey + bez * bez;
- clift = cex * cex + cey * cey + cez * cez;
- dlift = dex * dex + dey * dey + dez * dez;
-
- det = (dlift * abc - clift * dab) + (blift * cda - alift * bcd);
-
- aezplus = Absolute(aez);
- bezplus = Absolute(bez);
- cezplus = Absolute(cez);
- dezplus = Absolute(dez);
- aexbeyplus = Absolute(aexbey);
- bexaeyplus = Absolute(bexaey);
- bexceyplus = Absolute(bexcey);
- cexbeyplus = Absolute(cexbey);
- cexdeyplus = Absolute(cexdey);
- dexceyplus = Absolute(dexcey);
- dexaeyplus = Absolute(dexaey);
- aexdeyplus = Absolute(aexdey);
- aexceyplus = Absolute(aexcey);
- cexaeyplus = Absolute(cexaey);
- bexdeyplus = Absolute(bexdey);
- dexbeyplus = Absolute(dexbey);
- permanent = ((cexdeyplus + dexceyplus) * bezplus
- + (dexbeyplus + bexdeyplus) * cezplus
- + (bexceyplus + cexbeyplus) * dezplus)
- * alift
- + ((dexaeyplus + aexdeyplus) * cezplus
- + (aexceyplus + cexaeyplus) * dezplus
- + (cexdeyplus + dexceyplus) * aezplus)
- * blift
- + ((aexbeyplus + bexaeyplus) * dezplus
- + (bexdeyplus + dexbeyplus) * aezplus
- + (dexaeyplus + aexdeyplus) * bezplus)
- * clift
- + ((bexceyplus + cexbeyplus) * aezplus
- + (cexaeyplus + aexceyplus) * bezplus
- + (aexbeyplus + bexaeyplus) * cezplus)
- * dlift;
- errbound = isperrboundA * permanent;
- if ((det > errbound) || (-det > errbound)) {
- return det;
- }
-
- return insphereadapt(pa, pb, pc, pd, pe, permanent);
-}
-
-/*****************************************************************************/
-/* */
-/* orient4d() Return a positive value if the point pe lies above the */
-/* hyperplane passing through pa, pb, pc, and pd; "above" is */
-/* defined in a manner best found by trial-and-error. Returns */
-/* a negative value if pe lies below the hyperplane. Returns */
-/* zero if the points are co-hyperplanar (not affinely */
-/* independent). The result is also a rough approximation of */
-/* 24 times the signed volume of the 4-simplex defined by the */
-/* five points. */
-/* */
-/* Uses exact arithmetic if necessary to ensure a correct answer. The */
-/* result returned is the determinant of a matrix. This determinant is */
-/* computed adaptively, in the sense that exact arithmetic is used only to */
-/* the degree it is needed to ensure that the returned value has the */
-/* correct sign. Hence, orient4d() is usually quite fast, but will run */
-/* more slowly when the input points are hyper-coplanar or nearly so. */
-/* */
-/* See my Robust Predicates paper for details. */
-/* */
-/*****************************************************************************/
-
-REAL orient4dexact (
- __const_ptr(REAL) pa,
- __const_ptr(REAL) pb,
- __const_ptr(REAL) pc,
- __const_ptr(REAL) pd,
- __const_ptr(REAL) pe,
- REAL aheight,
- REAL bheight,
- REAL cheight,
- REAL dheight,
- REAL eheight)
-{
- REAL axby1, bxcy1, cxdy1, dxey1, exay1;
- REAL bxay1, cxby1, dxcy1, exdy1, axey1;
- REAL axcy1, bxdy1, cxey1, dxay1, exby1;
- REAL cxay1, dxby1, excy1, axdy1, bxey1;
- REAL axby0, bxcy0, cxdy0, dxey0, exay0;
- REAL bxay0, cxby0, dxcy0, exdy0, axey0;
- REAL axcy0, bxdy0, cxey0, dxay0, exby0;
- REAL cxay0, dxby0, excy0, axdy0, bxey0;
- REAL ab[4], bc[4], cd[4], de[4], ea[4];
- REAL ac[4], bd[4], ce[4], da[4], eb[4];
- REAL temp8a[8], temp8b[8], temp16[16];
- int temp8alen=0, temp8blen=0, temp16len=0;
- REAL abc[24], bcd[24], cde[24], dea[24], eab[24];
- REAL abd[24], bce[24], cda[24], deb[24], eac[24];
- int abclen=0, bcdlen=0, cdelen=0, dealen=0, eablen=0;
- int abdlen=0, bcelen=0, cdalen=0, deblen=0, eaclen=0;
- REAL temp48a[48], temp48b[48];
- int temp48alen=0, temp48blen=0;
- REAL abcd[96], bcde[96], cdea[96], deab[96], eabc[96];
- int abcdlen=0, bcdelen=0, cdealen=0, deablen=0, eabclen=0;
- REAL adet[192], bdet[192], cdet[192], ddet[192], edet[192];
- int alen, blen=0, clen=0, dlen=0, elen=0;
- REAL abdet[384], cddet[384], cdedet[576];
- int ablen=0, cdlen=0;
- REAL deter[960];
- int deterlen=0;
- int i;
-
- REAL bvirt, avirt, bround, around;
- REAL c, abig, ahi, alo, bhi, blo;
- REAL err1, err2, err3;
- REAL _i, _j, _0;
-
- Two_Product(pa[0], pb[1], axby1, axby0);
- Two_Product(pb[0], pa[1], bxay1, bxay0);
- Two_Two_Diff(axby1, axby0, bxay1, bxay0, ab[3], ab[2], ab[1], ab[0]);
-
- Two_Product(pb[0], pc[1], bxcy1, bxcy0);
- Two_Product(pc[0], pb[1], cxby1, cxby0);
- Two_Two_Diff(bxcy1, bxcy0, cxby1, cxby0, bc[3], bc[2], bc[1], bc[0]);
-
- Two_Product(pc[0], pd[1], cxdy1, cxdy0);
- Two_Product(pd[0], pc[1], dxcy1, dxcy0);
- Two_Two_Diff(cxdy1, cxdy0, dxcy1, dxcy0, cd[3], cd[2], cd[1], cd[0]);
-
- Two_Product(pd[0], pe[1], dxey1, dxey0);
- Two_Product(pe[0], pd[1], exdy1, exdy0);
- Two_Two_Diff(dxey1, dxey0, exdy1, exdy0, de[3], de[2], de[1], de[0]);
-
- Two_Product(pe[0], pa[1], exay1, exay0);
- Two_Product(pa[0], pe[1], axey1, axey0);
- Two_Two_Diff(exay1, exay0, axey1, axey0, ea[3], ea[2], ea[1], ea[0]);
-
- Two_Product(pa[0], pc[1], axcy1, axcy0);
- Two_Product(pc[0], pa[1], cxay1, cxay0);
- Two_Two_Diff(axcy1, axcy0, cxay1, cxay0, ac[3], ac[2], ac[1], ac[0]);
-
- Two_Product(pb[0], pd[1], bxdy1, bxdy0);
- Two_Product(pd[0], pb[1], dxby1, dxby0);
- Two_Two_Diff(bxdy1, bxdy0, dxby1, dxby0, bd[3], bd[2], bd[1], bd[0]);
-
- Two_Product(pc[0], pe[1], cxey1, cxey0);
- Two_Product(pe[0], pc[1], excy1, excy0);
- Two_Two_Diff(cxey1, cxey0, excy1, excy0, ce[3], ce[2], ce[1], ce[0]);
-
- Two_Product(pd[0], pa[1], dxay1, dxay0);
- Two_Product(pa[0], pd[1], axdy1, axdy0);
- Two_Two_Diff(dxay1, dxay0, axdy1, axdy0, da[3], da[2], da[1], da[0]);
-
- Two_Product(pe[0], pb[1], exby1, exby0);
- Two_Product(pb[0], pe[1], bxey1, bxey0);
- Two_Two_Diff(exby1, exby0, bxey1, bxey0, eb[3], eb[2], eb[1], eb[0]);
-
- temp8alen = scale_expansion_zeroelim(4, bc, pa[2], temp8a);
- temp8blen = scale_expansion_zeroelim(4, ac, -pb[2], temp8b);
- temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b,
- temp16);
- temp8alen = scale_expansion_zeroelim(4, ab, pc[2], temp8a);
- abclen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16,
- abc);
-
- temp8alen = scale_expansion_zeroelim(4, cd, pb[2], temp8a);
- temp8blen = scale_expansion_zeroelim(4, bd, -pc[2], temp8b);
- temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b,
- temp16);
- temp8alen = scale_expansion_zeroelim(4, bc, pd[2], temp8a);
- bcdlen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16,
- bcd);
-
- temp8alen = scale_expansion_zeroelim(4, de, pc[2], temp8a);
- temp8blen = scale_expansion_zeroelim(4, ce, -pd[2], temp8b);
- temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b,
- temp16);
- temp8alen = scale_expansion_zeroelim(4, cd, pe[2], temp8a);
- cdelen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16,
- cde);
-
- temp8alen = scale_expansion_zeroelim(4, ea, pd[2], temp8a);
- temp8blen = scale_expansion_zeroelim(4, da, -pe[2], temp8b);
- temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b,
- temp16);
- temp8alen = scale_expansion_zeroelim(4, de, pa[2], temp8a);
- dealen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16,
- dea);
-
- temp8alen = scale_expansion_zeroelim(4, ab, pe[2], temp8a);
- temp8blen = scale_expansion_zeroelim(4, eb, -pa[2], temp8b);
- temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b,
- temp16);
- temp8alen = scale_expansion_zeroelim(4, ea, pb[2], temp8a);
- eablen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16,
- eab);
-
- temp8alen = scale_expansion_zeroelim(4, bd, pa[2], temp8a);
- temp8blen = scale_expansion_zeroelim(4, da, pb[2], temp8b);
- temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b,
- temp16);
- temp8alen = scale_expansion_zeroelim(4, ab, pd[2], temp8a);
- abdlen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16,
- abd);
-
- temp8alen = scale_expansion_zeroelim(4, ce, pb[2], temp8a);
- temp8blen = scale_expansion_zeroelim(4, eb, pc[2], temp8b);
- temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b,
- temp16);
- temp8alen = scale_expansion_zeroelim(4, bc, pe[2], temp8a);
- bcelen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16,
- bce);
-
- temp8alen = scale_expansion_zeroelim(4, da, pc[2], temp8a);
- temp8blen = scale_expansion_zeroelim(4, ac, pd[2], temp8b);
- temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b,
- temp16);
- temp8alen = scale_expansion_zeroelim(4, cd, pa[2], temp8a);
- cdalen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16,
- cda);
-
- temp8alen = scale_expansion_zeroelim(4, eb, pd[2], temp8a);
- temp8blen = scale_expansion_zeroelim(4, bd, pe[2], temp8b);
- temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b,
- temp16);
- temp8alen = scale_expansion_zeroelim(4, de, pb[2], temp8a);
- deblen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16,
- deb);
-
- temp8alen = scale_expansion_zeroelim(4, ac, pe[2], temp8a);
- temp8blen = scale_expansion_zeroelim(4, ce, pa[2], temp8b);
- temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b,
- temp16);
- temp8alen = scale_expansion_zeroelim(4, ea, pc[2], temp8a);
- eaclen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16,
- eac);
-
- temp48alen = fast_expansion_sum_zeroelim(cdelen, cde, bcelen, bce, temp48a);
- temp48blen = fast_expansion_sum_zeroelim(deblen, deb, bcdlen, bcd, temp48b);
- for (i = 0; i < temp48blen; i++) {
- temp48b[i] = -temp48b[i];
- }
- bcdelen = fast_expansion_sum_zeroelim(temp48alen, temp48a,
- temp48blen, temp48b, bcde);
- alen = scale_expansion_zeroelim(bcdelen, bcde, aheight, adet);
-
- temp48alen = fast_expansion_sum_zeroelim(dealen, dea, cdalen, cda, temp48a);
- temp48blen = fast_expansion_sum_zeroelim(eaclen, eac, cdelen, cde, temp48b);
- for (i = 0; i < temp48blen; i++) {
- temp48b[i] = -temp48b[i];
- }
- cdealen = fast_expansion_sum_zeroelim(temp48alen, temp48a,
- temp48blen, temp48b, cdea);
- blen = scale_expansion_zeroelim(cdealen, cdea, bheight, bdet);
-
- temp48alen = fast_expansion_sum_zeroelim(eablen, eab, deblen, deb, temp48a);
- temp48blen = fast_expansion_sum_zeroelim(abdlen, abd, dealen, dea, temp48b);
- for (i = 0; i < temp48blen; i++) {
- temp48b[i] = -temp48b[i];
- }
- deablen = fast_expansion_sum_zeroelim(temp48alen, temp48a,
- temp48blen, temp48b, deab);
- clen = scale_expansion_zeroelim(deablen, deab, cheight, cdet);
-
- temp48alen = fast_expansion_sum_zeroelim(abclen, abc, eaclen, eac, temp48a);
- temp48blen = fast_expansion_sum_zeroelim(bcelen, bce, eablen, eab, temp48b);
- for (i = 0; i < temp48blen; i++) {
- temp48b[i] = -temp48b[i];
- }
- eabclen = fast_expansion_sum_zeroelim(temp48alen, temp48a,
- temp48blen, temp48b, eabc);
- dlen = scale_expansion_zeroelim(eabclen, eabc, dheight, ddet);
-
- temp48alen = fast_expansion_sum_zeroelim(bcdlen, bcd, abdlen, abd, temp48a);
- temp48blen = fast_expansion_sum_zeroelim(cdalen, cda, abclen, abc, temp48b);
- for (i = 0; i < temp48blen; i++) {
- temp48b[i] = -temp48b[i];
- }
- abcdlen = fast_expansion_sum_zeroelim(temp48alen, temp48a,
- temp48blen, temp48b, abcd);
- elen = scale_expansion_zeroelim(abcdlen, abcd, eheight, edet);
-
- ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet);
- cdlen = fast_expansion_sum_zeroelim(clen, cdet, dlen, ddet, cddet);
- cdelen = fast_expansion_sum_zeroelim(cdlen, cddet, elen, edet, cdedet);
- deterlen = fast_expansion_sum_zeroelim(ablen, abdet, cdelen, cdedet, deter);
-
- return deter[deterlen - 1];
-}
-
-REAL orient4dadapt (
- __const_ptr(REAL) pa,
- __const_ptr(REAL) pb,
- __const_ptr(REAL) pc,
- __const_ptr(REAL) pd,
- __const_ptr(REAL) pe,
- REAL aheight,
- REAL bheight,
- REAL cheight,
- REAL dheight,
- REAL eheight,
- REAL permanent)
-{
- REAL aex, bex, cex, dex, aey, bey, cey, dey, aez, bez, cez, dez;
- REAL aeheight, beheight, ceheight, deheight;
- REAL det, errbound;
-
- REAL aexbey1, bexaey1, bexcey1, cexbey1;
- REAL cexdey1, dexcey1, dexaey1, aexdey1;
- REAL aexcey1, cexaey1, bexdey1, dexbey1;
- REAL aexbey0, bexaey0, bexcey0, cexbey0;
- REAL cexdey0, dexcey0, dexaey0, aexdey0;
- REAL aexcey0, cexaey0, bexdey0, dexbey0;
- REAL ab[4], bc[4], cd[4], da[4], ac[4], bd[4];
- REAL ab3, bc3, cd3, da3, ac3, bd3;
- REAL abeps, bceps, cdeps, daeps, aceps, bdeps;
- REAL temp8a[8], temp8b[8], temp8c[8], temp16[16], temp24[24];
- int temp8alen=0, temp8blen=0, temp8clen=0;
- int temp16len=0, temp24len=0;
- REAL adet[48], bdet[48], cdet[48], ddet[48];
- int alen=0, blen=0, clen=0, dlen=0;
- REAL abdet[96], cddet[96];
- int ablen=0, cdlen=0;
- REAL fin1[192];
- int finlength=0;
-
- REAL aextail, bextail, cextail, dextail;
- REAL aeytail, beytail, ceytail, deytail;
- REAL aeztail, beztail, ceztail, deztail;
- REAL aeheighttail, beheighttail, ceheighttail, deheighttail;
-
- REAL bvirt, avirt, bround, around;
- REAL c, abig, ahi, alo, bhi, blo;
- REAL err1, err2, err3;
- REAL _i, _j, _0;
-
- aex = (REAL) (pa[0] - pe[0]);
- bex = (REAL) (pb[0] - pe[0]);
- cex = (REAL) (pc[0] - pe[0]);
- dex = (REAL) (pd[0] - pe[0]);
- aey = (REAL) (pa[1] - pe[1]);
- bey = (REAL) (pb[1] - pe[1]);
- cey = (REAL) (pc[1] - pe[1]);
- dey = (REAL) (pd[1] - pe[1]);
- aez = (REAL) (pa[2] - pe[2]);
- bez = (REAL) (pb[2] - pe[2]);
- cez = (REAL) (pc[2] - pe[2]);
- dez = (REAL) (pd[2] - pe[2]);
- aeheight = (REAL) (aheight - eheight);
- beheight = (REAL) (bheight - eheight);
- ceheight = (REAL) (cheight - eheight);
- deheight = (REAL) (dheight - eheight);
-
- Two_Product(aex, bey, aexbey1, aexbey0);
- Two_Product(bex, aey, bexaey1, bexaey0);
- Two_Two_Diff(aexbey1, aexbey0, bexaey1, bexaey0, ab3, ab[2], ab[1], ab[0]);
- ab[3] = ab3;
-
- Two_Product(bex, cey, bexcey1, bexcey0);
- Two_Product(cex, bey, cexbey1, cexbey0);
- Two_Two_Diff(bexcey1, bexcey0, cexbey1, cexbey0, bc3, bc[2], bc[1], bc[0]);
- bc[3] = bc3;
-
- Two_Product(cex, dey, cexdey1, cexdey0);
- Two_Product(dex, cey, dexcey1, dexcey0);
- Two_Two_Diff(cexdey1, cexdey0, dexcey1, dexcey0, cd3, cd[2], cd[1], cd[0]);
- cd[3] = cd3;
-
- Two_Product(dex, aey, dexaey1, dexaey0);
- Two_Product(aex, dey, aexdey1, aexdey0);
- Two_Two_Diff(dexaey1, dexaey0, aexdey1, aexdey0, da3, da[2], da[1], da[0]);
- da[3] = da3;
-
- Two_Product(aex, cey, aexcey1, aexcey0);
- Two_Product(cex, aey, cexaey1, cexaey0);
- Two_Two_Diff(aexcey1, aexcey0, cexaey1, cexaey0, ac3, ac[2], ac[1], ac[0]);
- ac[3] = ac3;
-
- Two_Product(bex, dey, bexdey1, bexdey0);
- Two_Product(dex, bey, dexbey1, dexbey0);
- Two_Two_Diff(bexdey1, bexdey0, dexbey1, dexbey0, bd3, bd[2], bd[1], bd[0]);
- bd[3] = bd3;
-
- temp8alen = scale_expansion_zeroelim(4, cd, bez, temp8a);
- temp8blen = scale_expansion_zeroelim(4, bd, -cez, temp8b);
- temp8clen = scale_expansion_zeroelim(4, bc, dez, temp8c);
- temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a,
- temp8blen, temp8b, temp16);
- temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c,
- temp16len, temp16, temp24);
- alen = scale_expansion_zeroelim(temp24len, temp24, -aeheight, adet);
-
- temp8alen = scale_expansion_zeroelim(4, da, cez, temp8a);
- temp8blen = scale_expansion_zeroelim(4, ac, dez, temp8b);
- temp8clen = scale_expansion_zeroelim(4, cd, aez, temp8c);
- temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a,
- temp8blen, temp8b, temp16);
- temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c,
- temp16len, temp16, temp24);
- blen = scale_expansion_zeroelim(temp24len, temp24, beheight, bdet);
-
- temp8alen = scale_expansion_zeroelim(4, ab, dez, temp8a);
- temp8blen = scale_expansion_zeroelim(4, bd, aez, temp8b);
- temp8clen = scale_expansion_zeroelim(4, da, bez, temp8c);
- temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a,
- temp8blen, temp8b, temp16);
- temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c,
- temp16len, temp16, temp24);
- clen = scale_expansion_zeroelim(temp24len, temp24, -ceheight, cdet);
-
- temp8alen = scale_expansion_zeroelim(4, bc, aez, temp8a);
- temp8blen = scale_expansion_zeroelim(4, ac, -bez, temp8b);
- temp8clen = scale_expansion_zeroelim(4, ab, cez, temp8c);
- temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a,
- temp8blen, temp8b, temp16);
- temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c,
- temp16len, temp16, temp24);
- dlen = scale_expansion_zeroelim(temp24len, temp24, deheight, ddet);
-
- ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet);
- cdlen = fast_expansion_sum_zeroelim(clen, cdet, dlen, ddet, cddet);
- finlength = fast_expansion_sum_zeroelim(ablen, abdet, cdlen, cddet, fin1);
-
- det = estimate(finlength, fin1);
- errbound = isperrboundB * permanent;
- if ((det >= errbound) || (-det >= errbound)) {
- return det;
- }
-
- Two_Diff_Tail(pa[0], pe[0], aex, aextail);
- Two_Diff_Tail(pa[1], pe[1], aey, aeytail);
- Two_Diff_Tail(pa[2], pe[2], aez, aeztail);
- Two_Diff_Tail(aheight, eheight, aeheight, aeheighttail);
- Two_Diff_Tail(pb[0], pe[0], bex, bextail);
- Two_Diff_Tail(pb[1], pe[1], bey, beytail);
- Two_Diff_Tail(pb[2], pe[2], bez, beztail);
- Two_Diff_Tail(bheight, eheight, beheight, beheighttail);
- Two_Diff_Tail(pc[0], pe[0], cex, cextail);
- Two_Diff_Tail(pc[1], pe[1], cey, ceytail);
- Two_Diff_Tail(pc[2], pe[2], cez, ceztail);
- Two_Diff_Tail(cheight, eheight, ceheight, ceheighttail);
- Two_Diff_Tail(pd[0], pe[0], dex, dextail);
- Two_Diff_Tail(pd[1], pe[1], dey, deytail);
- Two_Diff_Tail(pd[2], pe[2], dez, deztail);
- Two_Diff_Tail(dheight, eheight, deheight, deheighttail);
- if ((aextail == 0.0) && (aeytail == 0.0) && (aeztail == 0.0)
- && (bextail == 0.0) && (beytail == 0.0) && (beztail == 0.0)
- && (cextail == 0.0) && (ceytail == 0.0) && (ceztail == 0.0)
- && (dextail == 0.0) && (deytail == 0.0) && (deztail == 0.0)
- && (aeheighttail == 0.0) && (beheighttail == 0.0)
- && (ceheighttail == 0.0) && (deheighttail == 0.0)) {
- return det;
- }
-
- errbound = isperrboundC * permanent + resulterrbound * Absolute(det);
- abeps = (aex * beytail + bey * aextail)
- - (aey * bextail + bex * aeytail);
- bceps = (bex * ceytail + cey * bextail)
- - (bey * cextail + cex * beytail);
- cdeps = (cex * deytail + dey * cextail)
- - (cey * dextail + dex * ceytail);
- daeps = (dex * aeytail + aey * dextail)
- - (dey * aextail + aex * deytail);
- aceps = (aex * ceytail + cey * aextail)
- - (aey * cextail + cex * aeytail);
- bdeps = (bex * deytail + dey * bextail)
- - (bey * dextail + dex * beytail);
- det += ((beheight
- * ((cez * daeps + dez * aceps + aez * cdeps)
- + (ceztail * da3 + deztail * ac3 + aeztail * cd3))
- + deheight
- * ((aez * bceps - bez * aceps + cez * abeps)
- + (aeztail * bc3 - beztail * ac3 + ceztail * ab3)))
- - (aeheight
- * ((bez * cdeps - cez * bdeps + dez * bceps)
- + (beztail * cd3 - ceztail * bd3 + deztail * bc3))
- + ceheight
- * ((dez * abeps + aez * bdeps + bez * daeps)
- + (deztail * ab3 + aeztail * bd3 + beztail * da3))))
- + ((beheighttail * (cez * da3 + dez * ac3 + aez * cd3)
- + deheighttail * (aez * bc3 - bez * ac3 + cez * ab3))
- - (aeheighttail * (bez * cd3 - cez * bd3 + dez * bc3)
- + ceheighttail * (dez * ab3 + aez * bd3 + bez * da3)));
- if ((det >= errbound) || (-det >= errbound)) {
- return det;
- }
-
- return orient4dexact(pa, pb, pc, pd, pe,
- aheight, bheight, cheight, dheight, eheight);
-}
-
-REAL orient4d (
- __const_ptr(REAL) pa,
- __const_ptr(REAL) pb,
- __const_ptr(REAL) pc,
- __const_ptr(REAL) pd,
- __const_ptr(REAL) pe )
-{
- REAL aheight, bheight, cheight, dheight, eheight;
- REAL aex, bex, cex, dex;
- REAL aey, bey, cey, dey;
- REAL aez, bez, cez, dez;
- REAL aexbey, bexaey, bexcey, cexbey, cexdey, dexcey, dexaey, aexdey;
- REAL aexcey, cexaey, bexdey, dexbey;
- REAL aeheight, beheight, ceheight, deheight;
- REAL ab, bc, cd, da, ac, bd;
- REAL abc, bcd, cda, dab;
- REAL aezplus, bezplus, cezplus, dezplus;
- REAL aexbeyplus, bexaeyplus, bexceyplus, cexbeyplus;
- REAL cexdeyplus, dexceyplus, dexaeyplus, aexdeyplus;
- REAL aexceyplus, cexaeyplus, bexdeyplus, dexbeyplus;
- REAL det;
- REAL permanent, errbound;
-
- aheight = pa[3];
- bheight = pb[3];
- cheight = pc[3];
- dheight = pd[3];
- eheight = pe[3];
-
- aex = pa[0] - pe[0];
- bex = pb[0] - pe[0];
- cex = pc[0] - pe[0];
- dex = pd[0] - pe[0];
- aey = pa[1] - pe[1];
- bey = pb[1] - pe[1];
- cey = pc[1] - pe[1];
- dey = pd[1] - pe[1];
- aez = pa[2] - pe[2];
- bez = pb[2] - pe[2];
- cez = pc[2] - pe[2];
- dez = pd[2] - pe[2];
- aeheight = aheight - eheight;
- beheight = bheight - eheight;
- ceheight = cheight - eheight;
- deheight = dheight - eheight;
-
- aexbey = aex * bey;
- bexaey = bex * aey;
- ab = aexbey - bexaey;
- bexcey = bex * cey;
- cexbey = cex * bey;
- bc = bexcey - cexbey;
- cexdey = cex * dey;
- dexcey = dex * cey;
- cd = cexdey - dexcey;
- dexaey = dex * aey;
- aexdey = aex * dey;
- da = dexaey - aexdey;
-
- aexcey = aex * cey;
- cexaey = cex * aey;
- ac = aexcey - cexaey;
- bexdey = bex * dey;
- dexbey = dex * bey;
- bd = bexdey - dexbey;
-
- abc = aez * bc - bez * ac + cez * ab;
- bcd = bez * cd - cez * bd + dez * bc;
- cda = cez * da + dez * ac + aez * cd;
- dab = dez * ab + aez * bd + bez * da;
-
- det = (deheight * abc - ceheight * dab) + (beheight * cda - aeheight * bcd);
-
- aezplus = Absolute(aez);
- bezplus = Absolute(bez);
- cezplus = Absolute(cez);
- dezplus = Absolute(dez);
- aexbeyplus = Absolute(aexbey);
- bexaeyplus = Absolute(bexaey);
- bexceyplus = Absolute(bexcey);
- cexbeyplus = Absolute(cexbey);
- cexdeyplus = Absolute(cexdey);
- dexceyplus = Absolute(dexcey);
- dexaeyplus = Absolute(dexaey);
- aexdeyplus = Absolute(aexdey);
- aexceyplus = Absolute(aexcey);
- cexaeyplus = Absolute(cexaey);
- bexdeyplus = Absolute(bexdey);
- dexbeyplus = Absolute(dexbey);
- permanent = ((cexdeyplus + dexceyplus) * bezplus
- + (dexbeyplus + bexdeyplus) * cezplus
- + (bexceyplus + cexbeyplus) * dezplus)
- * aeheight
- + ((dexaeyplus + aexdeyplus) * cezplus
- + (aexceyplus + cexaeyplus) * dezplus
- + (cexdeyplus + dexceyplus) * aezplus)
- * beheight
- + ((aexbeyplus + bexaeyplus) * dezplus
- + (bexdeyplus + dexbeyplus) * aezplus
- + (dexaeyplus + aexdeyplus) * bezplus)
- * ceheight
- + ((bexceyplus + cexbeyplus) * aezplus
- + (cexaeyplus + aexceyplus) * bezplus
- + (aexbeyplus + bexaeyplus) * cezplus)
- * deheight;
- errbound = isperrboundA * permanent;
- if ((det > errbound) || (-det > errbound)) {
- return det;
- }
-
- return orient4dadapt(pa, pb, pc, pd, pe,
- aheight, bheight, cheight, dheight, eheight, permanent);
-}
-
-/*****************************************************************************/
-/* */
-/* regular_k() Return a positive value if the point pe is incompatible */
-/* with the sphere or hyperplane passing through pa, pb, pc, */
-/* and pd (meaning that pe is inside the sphere or below the */
-/* hyperplane); a negative value if it is compatible; and */
-/* zero if the five points are cospherical/cohyperplanar. */
-/* The points pa, pb, pc, and pd must be ordered so that */
-/* they have a positive orientation (as defined by */
-/* orient3d()), or the sign of the result will be reversed. */
-/* */
-/* Uses exact arithmetic if necessary to ensure a correct answer. The */
-/* result returned is the determinant of a matrix. This determinant is */
-/* computed adaptively, in the sense that exact arithmetic is used only to */
-/* the degree it is needed to ensure that the returned value has the */
-/* correct sign. Hence, orient4d() is usually quite fast, but will run */
-/* more slowly when the input points are hyper-coplanar or nearly so. */
-/* */
-/* See my Robust Predicates paper for details. */
-/* */
-/*****************************************************************************/
-
-REAL regular2 (
- __const_ptr(REAL) pa,
- __const_ptr(REAL) pb,
- __const_ptr(REAL) pc,
- __const_ptr(REAL) pd )
-{
- REAL PA[3], PB[3], PC[3], PD[3] ;
-
- PA[0] = pa[0] ; PA[1] = pa[1] ;
- PB[0] = pb[0] ; PB[1] = pb[1] ;
- PC[0] = pc[0] ; PC[1] = pc[1] ;
- PD[0] = pd[0] ; PD[1] = pd[1] ;
-
- PA[2] = pa[0] * pa[0]
- + pa[1] * pa[1] - pa[2] ;
- PB[2] = pb[0] * pb[0]
- + pb[1] * pb[1] - pb[2] ;
- PC[2] = pc[0] * pc[0]
- + pc[1] * pc[1] - pc[2] ;
- PD[2] = pd[0] * pd[0]
- + pd[1] * pd[1] - pd[2] ;
-
- return orient3d(PA, PB, PC, PD) ;
-}
-
-REAL regular3 (
- __const_ptr(REAL) pa,
- __const_ptr(REAL) pb,
- __const_ptr(REAL) pc,
- __const_ptr(REAL) pd,
- __const_ptr(REAL) pe )
-{
- REAL PA[4], PB[4], PC[4], PD[4], PE[4] ;
-
- PA[0] = pa[0] ; PA[1] = pa[1] ; PA[2] = pa[2] ;
- PB[0] = pb[0] ; PB[1] = pb[1] ; PB[2] = pb[2] ;
- PC[0] = pc[0] ; PC[1] = pc[1] ; PC[2] = pc[2] ;
- PD[0] = pd[0] ; PD[1] = pd[1] ; PD[2] = pd[2] ;
- PE[0] = pe[0] ; PE[1] = pe[1] ; PE[2] = pe[2] ;
-
- PA[3] = pa[0] * pa[0]
- + pa[1] * pa[1]
- + pa[2] * pa[2] - pa[3] ;
- PB[3] = pb[0] * pb[0]
- + pb[1] * pb[1]
- + pb[2] * pb[2] - pb[3] ;
- PC[3] = pc[0] * pc[0]
- + pc[1] * pc[1]
- + pc[2] * pc[2] - pc[3] ;
- PD[3] = pd[0] * pd[0]
- + pd[1] * pd[1]
- + pd[2] * pd[2] - pd[3] ;
- PE[3] = pe[0] * pe[0]
- + pe[1] * pe[1]
- + pe[2] * pe[2] - pe[3] ;
-
- return orient4d(PA, PB, PC, PD, PE) ;
-}
-
-}
-
-#endif // __GEOMPRED__
-
-
-
diff --git a/external/jigsaw/src/libcpp/geom_base/vect_base_k.hpp b/external/jigsaw/src/libcpp/geom_base/vect_base_k.hpp
index cf238be..cb979ba 100644
--- a/external/jigsaw/src/libcpp/geom_base/vect_base_k.hpp
+++ b/external/jigsaw/src/libcpp/geom_base/vect_base_k.hpp
@@ -31,11 +31,11 @@
*
--------------------------------------------------------
*
- * Last updated: 06 June, 2016
+ * Last updated: 30 April, 2020
*
- * Copyright 2013-2017
+ * Copyright 2013-2020
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
--------------------------------------------------------
@@ -76,6 +76,21 @@
_vv[2] = _p2[2] - _p1[2];
}
+ template <
+ typename data_type
+ >
+ __inline_call void_type vector_4d (
+ __const_ptr (data_type) _p1,
+ __const_ptr (data_type) _p2,
+ __write_ptr (data_type) _vv
+ )
+ {
+ _vv[0] = _p2[0] - _p1[0];
+ _vv[1] = _p2[1] - _p1[1];
+ _vv[2] = _p2[2] - _p1[2];
+ _vv[3] = _p2[3] - _p1[3];
+ }
+
/*-------------------------------- calc. (squared) length */
template <
typename data_type
@@ -98,6 +113,18 @@
_vv[2] * _vv[2] ;
}
+ template <
+ typename data_type
+ >
+ __inline_call data_type lensqr_4d (
+ __const_ptr (data_type) _vv
+ )
+ { return _vv[0] * _vv[0] +
+ _vv[1] * _vv[1] +
+ _vv[2] * _vv[2] +
+ _vv[3] * _vv[3] ;
+ }
+
template <
typename data_type
>
@@ -129,6 +156,23 @@
_vv[2] * _vv[2] ;
}
+ template <
+ typename data_type
+ >
+ __inline_call data_type lensqr_4d (
+ __const_ptr (data_type) _p1 ,
+ __const_ptr (data_type) _p2
+ )
+ {
+ data_type _vv[ +4];
+ vector_4d(_p1, _p2, _vv) ;
+
+ return _vv[0] * _vv[0] +
+ _vv[1] * _vv[1] +
+ _vv[2] * _vv[2] +
+ _vv[3] * _vv[3] ;
+ }
+
/*-------------------------------- calc. euclidean length */
template <
typename data_type
@@ -170,6 +214,72 @@
std::sqrt(lensqr_3d(_p1, _p2)) ;
}
+ template <
+ typename data_type
+ >
+ __inline_call data_type length_4d (
+ __const_ptr (data_type) _vv
+ )
+ { return std::sqrt(lensqr_4d(_vv)) ;
+ }
+
+ template <
+ typename data_type
+ >
+ __inline_call data_type length_4d (
+ __const_ptr (data_type) _p1 ,
+ __const_ptr (data_type) _p2
+ )
+ { return
+ std::sqrt(lensqr_4d(_p1, _p2)) ;
+ }
+
+/*-------------------------------- scale onto unit vector */
+ template <
+ typename data_type
+ >
+ __inline_call data_type normalise_2d (
+ __write_ptr (data_type) _vv
+ )
+ {
+ data_type _ll = length_2d(_vv) ;
+ _vv[0] /= _ll ;
+ _vv[1] /= _ll ;
+
+ return ( _ll ) ;
+ }
+
+ template <
+ typename data_type
+ >
+ __inline_call data_type normalise_3d (
+ __write_ptr (data_type) _vv
+ )
+ {
+ data_type _ll = length_3d(_vv) ;
+ _vv[0] /= _ll ;
+ _vv[1] /= _ll ;
+ _vv[2] /= _ll ;
+
+ return ( _ll ) ;
+ }
+
+ template <
+ typename data_type
+ >
+ __inline_call data_type normalise_4d (
+ __write_ptr (data_type) _vv
+ )
+ {
+ data_type _ll = length_4d(_vv) ;
+ _vv[0] /= _ll ;
+ _vv[1] /= _ll ;
+ _vv[2] /= _ll ;
+ _vv[3] /= _ll ;
+
+ return ( _ll ) ;
+ }
+
/*-------------------------------- vector "cross" product */
template <
typename data_type
@@ -226,6 +336,19 @@
_v1[2] * _v2[2] ;
}
+ template <
+ typename data_type
+ >
+ __inline_call data_type dot_4d (
+ __const_ptr (data_type) _v1 ,
+ __const_ptr (data_type) _v2
+ )
+ { return _v1[0] * _v2[0] +
+ _v1[1] * _v2[1] +
+ _v1[2] * _v2[2] +
+ _v1[3] * _v2[3] ;
+ }
+
/*-------------------------------- cosine between vectors */
template <
typename data_type
diff --git a/external/jigsaw/src/libcpp/geom_type/geom_base_2.hpp b/external/jigsaw/src/libcpp/geom_type/geom_base_2.hpp
index 31cbf64..886e29c 100644
--- a/external/jigsaw/src/libcpp/geom_type/geom_base_2.hpp
+++ b/external/jigsaw/src/libcpp/geom_type/geom_base_2.hpp
@@ -35,7 +35,7 @@
*
* Copyright 2013-2019
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
--------------------------------------------------------
diff --git a/external/jigsaw/src/libcpp/geom_type/geom_base_3.hpp b/external/jigsaw/src/libcpp/geom_type/geom_base_3.hpp
index cce2882..7adea5e 100644
--- a/external/jigsaw/src/libcpp/geom_type/geom_base_3.hpp
+++ b/external/jigsaw/src/libcpp/geom_type/geom_base_3.hpp
@@ -31,11 +31,11 @@
*
--------------------------------------------------------
*
- * Last updated: 09 August, 2019
+ * Last updated: 25 April, 2020
*
- * Copyright 2013-2019
+ * Copyright 2013-2020
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
--------------------------------------------------------
@@ -63,6 +63,9 @@
/*------------------------- types for intersect calls */
+ typedef
+ containers::array real_ptrs ;
+
struct line_type
{
real_type _ipos[3] ; // line endpoints
@@ -73,8 +76,7 @@
{
real_type _ppos[3] ; // point on flat
real_type _nvec[3] ; // norm. to flat
- real_type _rmin[3] ; // bounding-aabb
- real_type _rmax[3] ;
+ real_ptrs _bnds ; // dual vertices
} ;
struct disc_type
diff --git a/external/jigsaw/src/libcpp/geom_type/geom_mesh_ellipsoid_3.hpp b/external/jigsaw/src/libcpp/geom_type/geom_mesh_ellipsoid_3.hpp
index a69095d..5ef4ff0 100644
--- a/external/jigsaw/src/libcpp/geom_type/geom_mesh_ellipsoid_3.hpp
+++ b/external/jigsaw/src/libcpp/geom_type/geom_mesh_ellipsoid_3.hpp
@@ -31,11 +31,11 @@
*
--------------------------------------------------------
*
- * Last updated: 09 August, 2019
+ * Last updated: 30 April, 2020
*
- * Copyright 2013-2019
+ * Copyright 2013-2020
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
--------------------------------------------------------
@@ -131,6 +131,26 @@
} ;
+ class seed_type: public mesh_complex_node_3
+ {
+ /*------------------------------------ loc. node type */
+ public :
+ iptr_type _itag ;
+
+ public :
+ /*------------------------------------ "write" access */
+ __inline_call iptr_type& itag (
+ )
+ { return this->_itag ;
+ }
+ /*------------------------------------ "const" access */
+ __inline_call iptr_type const& itag (
+ ) const
+ { return this->_itag ;
+ }
+
+ } ;
+
class edge_type: public mesh_complex_edge_2
{
/*------------------------------------ loc. edge type */
@@ -175,6 +195,10 @@
edge_type,
allocator > mesh_type ;
+ typedef containers::array <
+ seed_type ,
+ allocator > seed_list ;
+
typedef geom_tree::aabb_node_base_k
tree_node ;
@@ -191,6 +215,8 @@
public :
+ seed_list _seed ;
+
containers::
fixed_array _bmin ;
containers::
@@ -249,6 +275,256 @@
_apos[1]= std::asin (_zrat);
}
+ /*
+ --------------------------------------------------------
+ * construct geometry from alloc. etc.
+ --------------------------------------------------------
+ */
+
+ __normal_call geom_mesh_ellipsoid_3d (
+ allocator const&
+ _asrc = allocator ()
+ ) : _seed( _asrc ) ,
+ _mesh( _asrc ) ,
+ _ebox( _asrc )
+ {
+ }
+
+ /*
+ --------------------------------------------------------
+ * NODE-FEAT: calc. node feature type.
+ --------------------------------------------------------
+ */
+
+ template <
+ typename list_type ,
+ typename geom_opts
+ >
+ __normal_call void_type node_feat (
+ iptr_type *_node ,
+ list_type &_aset ,
+ char_type &_feat ,
+ char_type &_topo ,
+ geom_opts &_opts
+ )
+ {
+ /*------------ "sharp" geometry//topology about node? */
+ real_type _DtoR =
+ (real_type)+3.141592653589793 / 180. ;
+
+ real_type _ZERO = -1. +
+ std::numeric_limits
+ ::epsilon();
+
+ real_type _phi1 =
+ (real_type)+180. - _opts.phi1();
+ real_type _eta1 =
+ (real_type)+ 0. + _opts.eta1();
+
+ real_type _hard =
+ std::cos( _phi1 * _DtoR) ;
+ real_type _soft =
+ std::cos( _eta1 * _DtoR) ;
+
+ __unreferenced(_node) ;
+
+ _feat = null_feat ;
+ _topo = (char_type)_aset.count () ;
+
+ for (auto _ipos = _aset.head() ;
+ _ipos != _aset.tend() ;
+ ++_ipos )
+ {
+ char_type _tbad = +1 ;
+ for (auto _jpos = _ipos+1 ;
+ _jpos != _aset.tend() ;
+ ++_jpos )
+ {
+ /*------------ find signed angle between edge vectors */
+ auto _iedg = _ipos->_cell ;
+ auto _jedg = _jpos->_cell ;
+
+ iptr_type _inod[2] = {
+ this->_mesh.edge(_iedg).node(0) ,
+ this->_mesh.edge(_iedg).node(1) ,
+ } ;
+
+ iptr_type _jnod[2] = {
+ this->_mesh.edge(_jedg).node(0) ,
+ this->_mesh.edge(_jedg).node(1) ,
+ } ;
+
+ real_type _ivec[3] ;
+ geometry::vector_3d(
+ & this->_mesh.
+ node(_inod[0]).pval(0) ,
+ & this->_mesh.
+ node(_inod[1]).pval(0) ,
+ _ivec) ;
+
+ real_type _jvec[3] ;
+ geometry::vector_3d(
+ & this->_mesh.
+ node(_jnod[0]).pval(0) ,
+ & this->_mesh.
+ node(_jnod[1]).pval(0) ,
+ _jvec) ;
+
+ real_type _acos = geometry::
+ cosine_3d(_ivec, _jvec) ;
+
+ if (_inod[0] == _jnod[1] ||
+ _inod[1] == _jnod[0] )
+ _acos *= (real_type)+1. ;
+ else
+ _acos *= (real_type)-1. ;
+
+ if (_acos >= _ZERO)
+ {
+ /*------------ tag as "feature" if angle sharp enough */
+ if (_acos <= _hard)
+ {
+ _feat =
+ std::max (_feat, hard_feat) ;
+ }
+ else
+ if (_acos <= _soft)
+ {
+ _feat =
+ std::max (_feat, soft_feat) ;
+ }
+ }
+ else
+ {
+ if (_tbad >= + 1 )
+ {
+ _topo -= _tbad-- ;
+ }
+ }
+ }
+ }
+ {
+ /*------------ tag as "feature" if topo. is irregular */
+ if (_topo != + 0 )
+ if (_topo != + 2 )
+ _feat =
+ std::max (_feat, soft_feat) ;
+ }
+ }
+
+ /*
+ --------------------------------------------------------
+ * FIND-FEAT: scan geometry and find features.
+ --------------------------------------------------------
+ */
+
+ template <
+ typename geom_opts
+ >
+ __normal_call void_type find_feat (
+ geom_opts &_opts
+ )
+ {
+ typename
+ mesh_type::connector _eadj ;
+
+ /*---------------------------------- init. geom feat. */
+ for (auto _iter =
+ this->_mesh.node().head() ;
+ _iter !=
+ this->_mesh.node().tend() ;
+ ++_iter )
+ {
+ if (_iter->mark() >= +0)
+ {
+ _iter->fdim () = +0 ;
+ _iter->feat () = null_feat ;
+ _iter->topo () = +2 ;
+ }
+ }
+
+ for (auto _iter =
+ this->_mesh.edge().head() ;
+ _iter !=
+ this->_mesh.edge().tend() ;
+ ++_iter )
+ {
+ if (_iter->mark() >= +0)
+ {
+ _iter->feat () = null_feat ;
+ _iter->topo () = +2 ;
+ }
+ }
+
+ /*---------------------------------- find sharp feat. */
+ for (auto _iter =
+ this->_mesh.node().head() ;
+ _iter !=
+ this->_mesh.node().tend() ;
+ ++_iter )
+ {
+ /*---------------------------------- find sharp 0-dim */
+ if (_iter->mark() >= +0 )
+ {
+ if (_iter->itag() <= -1 ||
+ _opts .feat() )
+ {
+ /*---------------------------------- set geo.-defined */
+ _eadj.set_count (0);
+
+ this->_mesh.connect_1(
+ &_iter->node (0), POINT_tag, _eadj) ;
+
+ node_feat (
+ &_iter->node (0),
+ _eadj ,
+ _iter->feat () ,
+ _iter->topo () ,
+ _opts ) ;
+
+ if (_iter->itag() <= -1)
+ {
+ /*---------------------------------- set user-defined */
+ _iter->feat () =
+ std::max(_iter->feat(), soft_feat) ;
+ }
+ }
+ }
+ }
+
+ for (auto _iter =
+ this->_mesh.edge().head() ;
+ _iter !=
+ this->_mesh.edge().tend() ;
+ ++_iter )
+ {
+ if (_iter->mark() >= +0)
+ {
+ /*----------------------------- assign nodes to edges */
+ this->_mesh.node()[
+ _iter->node(0)].fdim() = 1;
+ this->_mesh.node()[
+ _iter->node(1)].fdim() = 1;
+ }
+ }
+
+ for (auto _iter =
+ this->_mesh.node().head() ;
+ _iter !=
+ this->_mesh.node().tend() ;
+ ++_iter )
+ {
+ if (_iter->mark() >= +0)
+ {
+ if (_iter->feat() != null_feat)
+ {
+ /*----------------------------- assign nodes to feat. */
+ _iter->fdim() = +0;
+ }
+ }
+ }
+ }
+
/*
--------------------------------------------------------
* INIT-GEOM: init. geometry data structures.
@@ -275,13 +551,34 @@
/*--------------------------- convert to R^3 coord.'s */
for (auto _iter =
- this->_mesh._set1.head() ;
+ this->_mesh.node().head(); // POINT
+ _iter !=
+ this->_mesh.node().tend();
+ ++_iter )
+ {
+ if (_iter->mark() < 0) continue ;
+
+ real_type _apos[2];
+ real_type _ppos[3];
+
+ _apos[0] = _iter->pval(0) ;
+ _apos[1] = _iter->pval(1) ;
+
+ toR3(_apos, _ppos);
+
+ _iter->pval(0) = _ppos[0] ;
+ _iter->pval(1) = _ppos[1] ;
+ _iter->pval(2) = _ppos[2] ;
+ }
+
+ /*--------------------------- convert to R^3 coord.'s */
+ for (auto _iter =
+ this->_seed. head(); // SEEDS
_iter !=
- this->_mesh._set1.tend() ;
+ this->_seed. tend();
++_iter )
{
- if (_iter->mark() < 0)
- continue ;
+ if (_iter->mark() < 0) continue ;
real_type _apos[2];
real_type _ppos[3];
@@ -301,15 +598,17 @@
std::numeric_limits
::epsilon()) ;
- real_type _rBAR ;
- _rBAR = (real_type) +0. ;
+ real_type _rBAR = (real_type)0. ;
_rBAR += this->_radA ;
_rBAR += this->_radB ;
_rBAR += this->_radC ;
- _rBAR /= (real_type) +3. ;
+ _rBAR = _rBAR / (real_type)3. ;
this->_rEPS *= _rBAR ;
+ /*--------------------------- sharp feat. in geometry */
+ find_feat (_opts);
+
/*--------------------------- init. AABB for arc-seg. */
containers::
block_array _bbox;
@@ -317,13 +616,12 @@
iptr_type _inum = +0;
for (auto _iter =
- this->_mesh._set2.head() ;
+ this->_mesh.edge().head();
_iter !=
- this->_mesh._set2.tend() ;
+ this->_mesh.edge().tend();
++_iter, ++_inum )
{
- if (_iter->mark() < 0)
- continue ;
+ if (_iter->mark() < 0) continue ;
iptr_type _enod[ +2] ;
_enod[0] = _iter->node(0) ;
@@ -332,11 +630,11 @@
tree_item _tdat ;
_tdat.ipos() = _inum ;
- make_aabb (
- &this->_mesh.
- _set1[_enod[ 0 ]].pval(0) ,
- &this->_mesh.
- _set1[_enod[ 1 ]].pval(0) ,
+ make_aabb (*_iter ,
+ & this->_mesh.
+ node(_enod[ 0 ]).pval(0) ,
+ & this->_mesh.
+ node(_enod[ 1 ]).pval(0) ,
&_tdat .pmin( 0 ),
&_tdat .pmax( 0 )) ;
@@ -344,8 +642,8 @@
}
this->_ebox.load (
- _bbox.head(),
- _bbox.tend(),this->_nbox) ;
+ _bbox.head() ,
+ _bbox.tend() , this->_nbox) ;
}
/*
@@ -369,7 +667,7 @@
/*
--------------------------------------------------------
- * SEED-FEAT: init. "seed" vertex set on geom.
+ * SEED-FEAT: init. "seed" vertex set on feat.
--------------------------------------------------------
*/
@@ -384,38 +682,108 @@
{
__unreferenced(_opts) ;
- real_type _ppos[3] ;
+ /*------------------------- point at ellipsoid centre */
+ real_type _ppos[4] ;
iptr_type _inod;
- _ppos[0] = (real_type) +0.0E+0;
- _ppos[1] = (real_type) +0.0E+0;
- _ppos[2] = (real_type) +0.0E+0;
+ _ppos[0] = (real_type) +0.0E+0 ;
+ _ppos[1] = (real_type) +0.0E+0 ;
+ _ppos[2] = (real_type) +0.0E+0 ;
+ _ppos[3] = (real_type) +0.0E+0 ;
_rdel.
- _tria.push_node(_ppos, _inod) ;
+ _tria.push_node(_ppos, _inod);
_rdel.
- _tria.node(_inod)->fdim() = +4;
+ _tria.node(_inod)->fdim() = +4 ;
_rdel.
- _tria.node(_inod)->feat() = +0;
+ _tria.node(_inod)->feat() = +0 ;
_rdel.
- _tria.node(_inod)->topo() = +0;
+ _tria.node(_inod)->topo() = +0 ;
+
+ /*------------------------- push set of feature nodes */
+ for (auto _iter =
+ this->_mesh.node().head() ;
+ _iter !=
+ this->_mesh.node().tend() ;
+ ++_iter )
+ {
+ if (_iter->mark() >= +0 )
+ {
+ if (_iter->feat() != null_feat)
+ {
+ /*----------------------------- push any 'real' feat. */
+ _ppos[0] = _iter->pval(0) ;
+ _ppos[1] = _iter->pval(1) ;
+ _ppos[2] = _iter->pval(2) ;
+ _ppos[3] = (real_type)+0. ;
+
+ iptr_type _node = -1 ;
+ if (_rdel._tria.push_node (
+ &_ppos[ 0], _node))
+ {
+ _rdel._tria.node
+ (_node)->fdim()
+ = _iter->fdim() ;
+
+ _rdel._tria.node
+ (_node)->feat()
+ = _iter->feat() ;
+
+ _rdel._tria.node
+ (_node)->topo()
+ = _iter->topo() ;
+
+ _rdel._tria.node
+ (_node)->part()
+ = _iter->itag() ;
+ }
+ }
+ else
+ if (_iter->itag() <= -1 )
+ {
+ /*----------------------------- push any 'user' feat. */
+ _ppos[0] = _iter->pval(0) ;
+ _ppos[1] = _iter->pval(1) ;
+ _ppos[2] = _iter->pval(2) ;
+ _ppos[3] = (real_type)+0. ;
+
+ iptr_type _node = -1 ;
+ if (_rdel._tria.push_node (
+ &_ppos[ 0], _node))
+ {
+ _rdel._tria.node
+ (_node)->fdim()
+ = _iter->fdim() ;
+
+ _rdel._tria.node
+ (_node)->feat()
+ = _iter->feat() ;
+
+ _rdel._tria.node
+ (_node)->topo()
+ = _iter->topo() ;
+
+ _rdel._tria.node
+ (_node)->part()
+ = _iter->itag() ;
+ }
+ }
+ }
+ }
}
/*
--------------------------------------------------------
- * SEED-MESH: init. "seed" vertex set on geom.
+ * SEED-BASE: init. icosahedral "seed" vertex.
--------------------------------------------------------
*/
template <
- typename mesh_type ,
- typename geom_opts
+ typename mesh_type
>
- __normal_call void_type seed_mesh (
- mesh_type &_rdel ,
- geom_opts &_opts
+ __normal_call void_type seed_base (
+ mesh_type &_rdel
)
{
- __unreferenced(_opts) ;
-
+ /*--------------------------- init. reg.-icosahedron */
real_type _pi =
(real_type)std::atan(1.0) * 4. ;
@@ -424,11 +792,7 @@
real_type _lo = 2.*_pi / 10. ;
- if (_rdel._tria.
- _nset.count() <= +8 )
- {
- /*--------------------------- init. reg.-icosahedron */
- real_type _ppos[3] ;
+ real_type _ppos[4] ;
iptr_type _inod;
_ppos[0] = this->_radA *
std::cos(_pi*(real_type)+0.0) *
@@ -438,6 +802,7 @@
std::cos(_pi*(real_type)+0.5) ;
_ppos[2] = this->_radC *
std::sin(_pi*(real_type)+0.5) ;
+ _ppos[3] = (real_type)+0.0;
_rdel.
_tria.push_node(_ppos, _inod) ;
_rdel.
@@ -455,6 +820,7 @@
std::cos(_pi*(real_type)-0.5) ;
_ppos[2] = this->_radC *
std::sin(_pi*(real_type)-0.5) ;
+ _ppos[3] = (real_type)+0.0;
_rdel.
_tria.push_node(_ppos, _inod) ;
_rdel.
@@ -472,6 +838,7 @@
std::cos(_la*(real_type)+1.0) ;
_ppos[2] = this->_radC *
std::sin(_la*(real_type)+1.0) ;
+ _ppos[3] = (real_type)+0.0;
_rdel.
_tria.push_node(_ppos, _inod) ;
_rdel.
@@ -489,6 +856,7 @@
std::cos(_la*(real_type)-1.0) ;
_ppos[2] = this->_radC *
std::sin(_la*(real_type)-1.0) ;
+ _ppos[3] = (real_type)+0.0;
_rdel.
_tria.push_node(_ppos, _inod) ;
_rdel.
@@ -506,6 +874,7 @@
std::cos(_la*(real_type)+1.0) ;
_ppos[2] = this->_radC *
std::sin(_la*(real_type)+1.0) ;
+ _ppos[3] = (real_type)+0.0;
_rdel.
_tria.push_node(_ppos, _inod) ;
_rdel.
@@ -523,6 +892,7 @@
std::cos(_la*(real_type)-1.0) ;
_ppos[2] = this->_radC *
std::sin(_la*(real_type)-1.0) ;
+ _ppos[3] = (real_type)+0.0;
_rdel.
_tria.push_node(_ppos, _inod) ;
_rdel.
@@ -540,6 +910,7 @@
std::cos(_la*(real_type)+1.0) ;
_ppos[2] = this->_radC *
std::sin(_la*(real_type)+1.0) ;
+ _ppos[3] = (real_type)+0.0;
_rdel.
_tria.push_node(_ppos, _inod) ;
_rdel.
@@ -557,6 +928,7 @@
std::cos(_la*(real_type)-1.0) ;
_ppos[2] = this->_radC *
std::sin(_la*(real_type)-1.0) ;
+ _ppos[3] = (real_type)+0.0;
_rdel.
_tria.push_node(_ppos, _inod) ;
_rdel.
@@ -574,6 +946,7 @@
std::cos(_la*(real_type)+1.0) ;
_ppos[2] = this->_radC *
std::sin(_la*(real_type)+1.0) ;
+ _ppos[3] = (real_type)+0.0;
_rdel.
_tria.push_node(_ppos, _inod) ;
_rdel.
@@ -591,6 +964,7 @@
std::cos(_la*(real_type)-1.0) ;
_ppos[2] = this->_radC *
std::sin(_la*(real_type)-1.0) ;
+ _ppos[3] = (real_type)+0.0;
_rdel.
_tria.push_node(_ppos, _inod) ;
_rdel.
@@ -608,6 +982,7 @@
std::cos(_la*(real_type)+1.0) ;
_ppos[2] = this->_radC *
std::sin(_la*(real_type)+1.0) ;
+ _ppos[3] = (real_type)+0.0;
_rdel.
_tria.push_node(_ppos, _inod) ;
_rdel.
@@ -625,6 +1000,7 @@
std::cos(_la*(real_type)-1.0) ;
_ppos[2] = this->_radC *
std::sin(_la*(real_type)-1.0) ;
+ _ppos[3] = (real_type)+0.0;
_rdel.
_tria.push_node(_ppos, _inod) ;
_rdel.
@@ -633,9 +1009,100 @@
_tria.node(_inod)->feat() = +0;
_rdel.
_tria.node(_inod)->topo() = +2;
+ }
+ /*
+ --------------------------------------------------------
+ * SEED-MESH: init. "seed" vertex set on geom.
+ --------------------------------------------------------
+ */
+
+ template <
+ typename mesh_type ,
+ typename geom_opts
+ >
+ __normal_call void_type seed_mesh (
+ mesh_type &_rdel ,
+ geom_opts &_opts
+ )
+ {
+ /*------------------------- well-distributed sampling */
+ while (_rdel._tria._nset.count()
+ < (std::size_t)_opts.seed() + 5)
+ {
+ typename geom_type::
+ mesh_type::
+ node_list::_write_it _best ;
+
+ real_type _dmax = (real_type) +.0 ;
+ for (auto _ipos =
+ this->_mesh.node().head() ;
+ _ipos !=
+ this->_mesh.node().tend() ;
+ ++_ipos )
+ {
+ /*------------------------- get current furthest node */
+ if (_ipos->mark() >= 0)
+ {
+ real_type _dmin =
+ +std::numeric_limits
+ ::infinity();
+
+ for (auto _jpos =
+ _rdel._tria._nset.head() ;
+ _jpos !=
+ _rdel._tria._nset.tend() ;
+ ++_jpos )
+ {
+ real_type _dist =
+ geometry::lensqr_3d(
+ &_ipos->pval(+0),
+ &_jpos->pval(+0)) ;
+
+ _dmin = std::min(_dmin, _dist);
+ }
+
+ if (_dmax < _dmin)
+ {
+ _dmax = _dmin;
+ _best = _ipos;
+ }
+ }
+ }
+
+ if (_dmax > (real_type)0.)
+ {
+ /*------------------------- add current furthest node */
+ real_type _ppos[4] ;
+ _ppos[0] = _best->pval(0) ;
+ _ppos[1] = _best->pval(1) ;
+ _ppos[2] = _best->pval(2) ;
+ _ppos[3] = (real_type)+0. ;
+
+ iptr_type _node = -1;
+ if (_rdel._tria.push_node(
+ &_ppos[ 0], _node) )
+ {
+ _rdel._tria.node
+ (_node)->fdim()
+ = _best->fdim() ;
+
+ _rdel._tria.node
+ (_node)->feat()
+ = _best->feat() ;
+
+ _rdel._tria.node
+ (_node)->topo()
+ = _best->topo() ;
+ }
+ }
+ else break ;
}
+ if (_rdel._tria._nset.count() <= +8 )
+ {
+ seed_base(_rdel) ;
+ }
}
/*
@@ -645,6 +1112,7 @@
*/
__normal_call void_type make_aabb (
+ edge_type _edge,
real_type *_apos,
real_type *_bpos,
float *_rmin,
@@ -654,53 +1122,55 @@
/*- build an AABB that encloses a spheroidal arc-seg. */
real_type _rTOL = this->_rEPS ;
- _rmin[0] = (float)std::min(
- _apos[0], _bpos[0]) ;
- _rmin[1] = (float)std::min(
- _apos[1], _bpos[1]) ;
- _rmin[2] = (float)std::min(
- _apos[2], _bpos[2]) ;
-
- _rmax[0] = (float)std::max(
- _apos[0], _bpos[0]) ;
- _rmax[1] = (float)std::max(
- _apos[1], _bpos[1]) ;
- _rmax[2] = (float)std::max(
- _apos[2], _bpos[2]) ;
-
- float _rmid[3] = {
- (float) +.5 * _rmin[0] +
- (float) +.5 * _rmax[0] ,
- (float) +.5 * _rmin[1] +
- (float) +.5 * _rmax[1] ,
- (float) +.5 * _rmin[2] +
- (float) +.5 * _rmax[2] ,
- } ;
+ __unreferenced(_edge);
- float _rlen = +0. ;
- _rlen = std::max (
- _rlen , _rmax[0]-_rmin[0]);
- _rlen = std::max (
- _rlen , _rmax[1]-_rmin[1]);
- _rlen = std::max (
- _rlen , _rmax[2]-_rmin[2]);
+ _rmin[0] = std::min(
+ (float)_apos[0], (float)_bpos[0]) ;
+ _rmin[1] = std::min(
+ (float)_apos[1], (float)_bpos[1]) ;
+ _rmin[2] = std::min(
+ (float)_apos[2], (float)_bpos[2]) ;
- _rlen*= (float) +.5 ;
- _rlen+= (float) _rTOL ;
+ _rmax[0] = std::max(
+ (float)_apos[0], (float)_bpos[0]) ;
+ _rmax[1] = std::max(
+ (float)_apos[1], (float)_bpos[1]) ;
+ _rmax[2] = std::max(
+ (float)_apos[2], (float)_bpos[2]) ;
+
+ real_type _rlen =
+ geometry::length_3d(_apos, _bpos) ;
+
+ real_type _rmid[3] = {
+ _apos[0] * (real_type)+.5 +
+ _bpos[0] * (real_type)+.5 ,
+ _apos[1] * (real_type)+.5 +
+ _bpos[1] * (real_type)+.5 ,
+ _apos[2] * (real_type)+.5 +
+ _bpos[2] * (real_type)+.5 ,
+ } ;
_rmin[0] = std::min(
- _rmin[0], _rmid[0]-_rlen) ;
+ _rmin[0], (float)(_rmid[0]-_rlen));
_rmin[1] = std::min(
- _rmin[1], _rmid[1]-_rlen) ;
+ _rmin[1], (float)(_rmid[1]-_rlen));
_rmin[2] = std::min(
- _rmin[2], _rmid[2]-_rlen) ;
+ _rmin[2], (float)(_rmid[2]-_rlen));
_rmax[0] = std::max(
- _rmax[0], _rmid[0]+_rlen) ;
+ _rmax[0], (float)(_rmid[0]+_rlen));
_rmax[1] = std::max(
- _rmax[1], _rmid[1]+_rlen) ;
+ _rmax[1], (float)(_rmid[1]+_rlen));
_rmax[2] = std::max(
- _rmax[2], _rmid[2]+_rlen) ;
+ _rmax[2], (float)(_rmid[2]+_rlen));
+
+ _rmin[0] = _rmin[0]-(float)_rTOL;
+ _rmin[1] = _rmin[1]-(float)_rTOL;
+ _rmin[2] = _rmin[2]-(float)_rTOL;
+
+ _rmax[0] = _rmax[0]+(float)_rTOL;
+ _rmax[1] = _rmax[1]+(float)_rTOL;
+ _rmax[2] = _rmax[2]+(float)_rTOL;
}
/*
@@ -811,6 +1281,10 @@
_zero[1] = (real_type) +.0 ;
_zero[2] = (real_type) +.0 ;
+ _pprj[0] =_psrc[0] ;
+ _pprj[1] =_psrc[1] ;
+ _pprj[2] =_psrc[2] ;
+
real_type _ttaa, _ttbb ;
if (line_surf(
_zero, _psrc, _ttaa, _ttbb) )
@@ -832,7 +1306,7 @@
_zero[2] * (real_type) +.5
} ;
- if (_ttaa > (real_type)-1.)
+ if (_ttaa > (real_type) -1.)
{
_pprj[0] =
_pmid[0] + _ttaa*_pdel[0] ;
@@ -842,7 +1316,7 @@
_pmid[2] + _ttaa*_pdel[2] ;
}
else
- if (_ttbb > (real_type)-1.)
+ if (_ttbb > (real_type) -1.)
{
_pprj[0] =
_pmid[0] + _ttbb*_pdel[0] ;
@@ -993,94 +1467,95 @@
if (_inum >= (iptr_type) +1)
{
- if (_inum == (iptr_type) +1)
- {
+ if (_inum == (iptr_type) +1)
+ {
/*--------------------------- call hit output functor */
- real_type _pprj[3] ;
- proj_surf(_ppos, _pprj) ;
+ real_type _pprj[3] ;
+ proj_surf(_ppos, _pprj) ;
- real_type _plen =
- geometry::
- lensqr_3d(_ppos, _pprj) ;
+ real_type _plen =
+ geometry::
+ lensqr_3d(_ppos, _pprj) ;
- if (_plen < this->_rEPS *
- this->_rEPS )
- {
- _hfun(&_pprj[0], _htmp ,
- _edge.feat() ,
- _edge.topo() ,
- _edge.itag() ) ;
+ if (_plen < this->_rEPS *
+ this->_rEPS )
+ {
+ _hfun(&_pprj[0], _htmp ,
+ _edge.feat() ,
+ _edge.topo() ,
+ _edge.itag() ) ;
- _hnum += +1 ;
+ _hnum += +1 ;
- return true ;
- }
- }
- else
- if (_inum == (iptr_type) +2)
- {
+ return true ;
+ }
+
+ }
+ else
+ if (_inum == (iptr_type) +2)
+ {
/*--------------------------- call hit output functor */
- real_type _pprj[3] ;
- real_type _qprj[3] ;
- proj_surf(_ppos, _pprj) ;
- proj_surf(_qpos, _qprj) ;
+ real_type _pprj[3] ;
+ real_type _qprj[3] ;
+ proj_surf(_ppos, _pprj) ;
+ proj_surf(_qpos, _qprj) ;
- real_type _plen =
- geometry::
- lensqr_3d(_ppos, _pprj) ;
+ real_type _plen =
+ geometry::
+ lensqr_3d(_ppos, _pprj) ;
- real_type _qlen =
- geometry::
- lensqr_3d(_qpos, _qprj) ;
+ real_type _qlen =
+ geometry::
+ lensqr_3d(_qpos, _qprj) ;
- real_type _xlen =
- std::max (_plen, _qlen) ;
+ real_type _xlen =
+ std::max (_plen, _qlen) ;
- if (_xlen < this->_rEPS *
- this->_rEPS )
- {
- _hfun(&_pprj[0], _htmp ,
- _edge.feat() ,
- _edge.topo() ,
- _edge.itag() ) ;
+ if (_xlen < this->_rEPS *
+ this->_rEPS )
+ {
+ _hfun(&_pprj[0], _htmp ,
+ _edge.feat() ,
+ _edge.topo() ,
+ _edge.itag() ) ;
- _hfun(&_qprj[0], _htmp ,
- _edge.feat() ,
- _edge.topo() ,
- _edge.itag() ) ;
+ _hfun(&_qprj[0], _htmp ,
+ _edge.feat() ,
+ _edge.topo() ,
+ _edge.itag() ) ;
- _hnum += +2 ;
+ _hnum += +2 ;
- return true ;
- }
- }
+ return true ;
+ }
+ }
/*--------------------------- recursive arc bisection */
- bool_type _okay = false ;
+ bool_type _okay = false ;
+
+ real_type _cpos[3] = {
+ _apos[0] * (real_type) +.5 +
+ _bpos[0] * (real_type) +.5 ,
+ _apos[1] * (real_type) +.5 +
+ _bpos[1] * (real_type) +.5 ,
+ _apos[2] * (real_type) +.5 +
+ _bpos[2] * (real_type) +.5 ,
+ } ;
- real_type _cpos[3] = {
- _apos[0] * (real_type) +.5 +
- _bpos[0] * (real_type) +.5 ,
- _apos[1] * (real_type) +.5 +
- _bpos[1] * (real_type) +.5 ,
- _apos[2] * (real_type) +.5 +
- _bpos[2] * (real_type) +.5 ,
- } ;
+ real_type _cprj[3] ;
+ proj_surf(_cpos, _cprj) ;
- real_type _cprj[3] ;
- proj_surf(_cpos, _cprj) ;
+ _okay = _okay |
+ ball_kern( _ball, _edge,
+ _apos, _cprj, _call,
+ _hfun, _hnum) ;
- _okay = _okay |
- ball_kern( _ball, _edge,
- _apos, _cprj, _call,
- _hfun, _hnum) ;
+ _okay = _okay |
+ ball_kern( _ball, _edge,
+ _cprj, _bpos, _call,
+ _hfun, _hnum) ;
- _okay = _okay |
- ball_kern( _ball, _edge,
- _cprj, _bpos, _call,
- _hfun, _hnum) ;
-
- return _okay ;
+ return _okay ;
}
@@ -1115,144 +1590,64 @@
/*--------------------------- call linear intersector */
real_type _xpos[3] ;
if (geometry::line_flat_3d (
- _flat._ppos,
- _flat._nvec,
- _apos,_bpos,
- _xpos, true) )
+ _flat._ppos,
+ _flat._nvec,
+ _apos,_bpos,
+ _xpos, true) )
{
-
/*--------------------------- call hit output functor */
- real_type _xprj[3] ;
- proj_surf(_xpos, _xprj) ;
+ real_type _xprj[3] ;
+ proj_surf(_xpos, _xprj) ;
- real_type _xlen =
- geometry::
- lensqr_3d(_xpos, _xprj) ;
+ real_type _xtmp[3] ;
+ geometry::proj_flat_3d(
+ _xprj ,
+ _flat._ppos,
+ _flat._nvec, _xtmp) ;
- if (_xlen < this->_rEPS *
- this->_rEPS )
- {
- _hfun(&_xprj[0], _htmp ,
- _edge.feat() ,
- _edge.topo() ,
- _edge.itag() ) ;
-
- _hnum += +1 ;
-
- return true ;
- }
-
- /*--------------------------- recursive arc bisection */
- bool_type _okay = false ;
-
- real_type _cpos[3] = {
- _apos[0] * (real_type) +.5 +
- _bpos[0] * (real_type) +.5 ,
- _apos[1] * (real_type) +.5 +
- _bpos[1] * (real_type) +.5 ,
- _apos[2] * (real_type) +.5 +
- _bpos[2] * (real_type) +.5 ,
- } ;
-
- real_type _cprj[3] ;
- proj_surf(_cpos, _cprj) ;
-
- _okay = _okay |
- flat_kern( _flat, _edge,
- _apos, _cprj, _call,
- _hfun, _hnum) ;
-
- _okay = _okay |
- flat_kern( _flat, _edge,
- _cprj, _bpos, _call,
- _hfun, _hnum) ;
-
- return _okay ;
-
- }
-
- return false ;
- }
+ real_type _xlen =
+ geometry::
+ lensqr_3d(_xtmp, _xprj) ;
- /*
- --------------------------------------------------------
- * HELPERS: predicates for intersection tests.
- --------------------------------------------------------
- */
+ if (_xlen < this->_rEPS *
+ this->_rEPS )
+ {
+ _hfun(&_xprj[0], _htmp ,
+ _edge.feat() ,
+ _edge.topo() ,
+ _edge.itag() ) ;
- template <
- typename hits_func
- >
- __normal_call bool_type disc_kern (
- disc_type &_disc ,
- real_type *_apos ,
- real_type *_bpos ,
- iptr_type _call ,
- hits_func &_hfun
- )
- {
- /*- calc. intersection of a disc & spheroidal surface */
- if (is_inside(_apos) !=
- is_inside(_bpos) )
- {
- if (_call++ > +3 )
- {
- /*--------------------------- call linear intersector */
- line_type _ldat;
- _ldat._ipos[0] = _apos[0] ;
- _ldat._ipos[1] = _apos[1] ;
- _ldat._ipos[2] = _apos[2] ;
- _ldat._jpos[0] = _bpos[0] ;
- _ldat._jpos[1] = _bpos[1] ;
- _ldat._jpos[2] = _bpos[2] ;
+ _hnum += +1 ;
- return intersect(_ldat, _hfun);
+ return true ;
+ }
- }
- else
- {
/*--------------------------- recursive arc bisection */
- bool_type _okay = false ;
-
- real_type _cpos[4] = {
- (real_type) +.5 * _apos[0] +
- (real_type) +.5 * _bpos[0] ,
- (real_type) +.5 * _apos[1] +
- (real_type) +.5 * _bpos[1] ,
- (real_type) +.5 * _apos[2] +
- (real_type) +.5 * _bpos[2]
- } ;
-
- real_type _cdir[4] = {
- _cpos[0] - _disc._pmid[0] ,
- _cpos[1] - _disc._pmid[1] ,
- _cpos[2] - _disc._pmid[2] ,
- } ;
-
- _cdir[3] =
- geometry::length_3d(_cdir);
- _cdir[0]/= _cdir[3] ;
- _cdir[1]/= _cdir[3] ;
- _cdir[2]/= _cdir[3] ;
-
- _cpos[0] = _disc._pmid[0] +
- _cdir[0] * _disc._rrad ;
- _cpos[1] = _disc._pmid[1] +
- _cdir[1] * _disc._rrad ;
- _cpos[2] = _disc._pmid[2] +
- _cdir[2] * _disc._rrad ;
+ bool_type _okay = false ;
+
+ real_type _cpos[3] = {
+ _apos[0] * (real_type) +.5 +
+ _bpos[0] * (real_type) +.5 ,
+ _apos[1] * (real_type) +.5 +
+ _bpos[1] * (real_type) +.5 ,
+ _apos[2] * (real_type) +.5 +
+ _bpos[2] * (real_type) +.5 ,
+ } ;
- _okay = _okay |
- disc_kern( _disc,
- _apos , _cpos, _call, _hfun) ;
+ real_type _cprj[3] ;
+ proj_surf(_cpos, _cprj) ;
- _okay = _okay |
- disc_kern( _disc,
- _cpos , _bpos, _call, _hfun) ;
+ _okay = _okay |
+ flat_kern( _flat, _edge,
+ _apos, _cprj, _call,
+ _hfun, _hnum) ;
- return _okay ;
+ _okay = _okay |
+ flat_kern( _flat, _edge,
+ _cprj, _bpos, _call,
+ _hfun, _hnum) ;
- }
+ return _okay ;
}
return false ;
@@ -1313,27 +1708,27 @@
iptr_type _epos =
_iptr->_data.ipos() ;
- iptr_type _enod[2];
- _enod[0] =_geom.
- _mesh._set2[_epos].node(0) ;
- _enod[1] =_geom.
- _mesh._set2[_epos].node(1) ;
+ iptr_type _enod[2] ;
+ _enod[0] = _geom.
+ _mesh.edge(_epos).node(0) ;
+ _enod[1] = _geom.
+ _mesh.edge(_epos).node(1) ;
/*--------------- call output function on hit */
_geom .flat_kern (
this->_flat,
this->_geom.
- _mesh ._set2[_epos] ,
+ _mesh.edge(_epos) ,
&this->_geom.
- _mesh._set1[_enod[ 0]].pval(0) ,
+ _mesh.node(_enod[ 0]).pval(0) ,
&this->_geom.
- _mesh._set1[_enod[ 1]].pval(0) ,
+ _mesh.node(_enod[ 1]).pval(0) ,
+ 0 ,
this->_hfun,
this->_hnum) ;
this->_find =
- this->_find | (this->_hnum!=0) ;
+ this->_find | (this->_hnum != 0) ;
}
}
@@ -1401,26 +1796,26 @@
iptr_type _epos =
_iptr->_data.ipos() ;
- iptr_type _enod[2];
- _enod[0] =_geom.
- _mesh._set2[_epos].node(0) ;
- _enod[1] =_geom.
- _mesh._set2[_epos].node(1) ;
+ iptr_type _enod[2] ;
+ _enod[0] = _geom.
+ _mesh.edge(_epos).node(0) ;
+ _enod[1] = _geom.
+ _mesh.edge(_epos).node(1) ;
/*--------------- call output function on hit */
_geom. ball_test (
this->_ball,
this->_geom.
- _mesh ._set2[_epos] ,
+ _mesh.edge(_epos) ,
&this->_geom.
- _mesh._set1[_enod[ 0]].pval(0) ,
+ _mesh.node(_enod[ 0]).pval(0) ,
&this->_geom.
- _mesh._set1[_enod[ 1]].pval(0) ,
+ _mesh.node(_enod[ 1]).pval(0) ,
this->_hfun,
this->_hnum) ;
this->_find =
- this->_find | (this->_hnum!=0) ;
+ this->_find | (this->_hnum != 0) ;
}
}
@@ -1463,18 +1858,50 @@
(float) _flat. _nvec[2] ,
} ;
+ real_type _llen = +.5 *
+ geometry::length_3d(_flat._nvec) ;
+
float _RMIN[3] = {
- (float) _flat. _rmin[0] ,
- (float) _flat. _rmin[1] ,
- (float) _flat. _rmin[2] ,
+ (float)(_flat. _ppos[0] -
+ _llen) ,
+ (float)(_flat. _ppos[1] -
+ _llen) ,
+ (float)(_flat. _ppos[2] -
+ _llen) ,
} ;
float _RMAX[3] = {
- (float) _flat. _rmax[0] ,
- (float) _flat. _rmax[1] ,
- (float) _flat. _rmax[2] ,
+ (float)(_flat. _ppos[0] +
+ _llen) ,
+ (float)(_flat. _ppos[1] +
+ _llen) ,
+ (float)(_flat. _ppos[2] +
+ _llen) ,
} ;
+ for ( auto
+ _iter = _flat._bnds.head() ;
+ _iter != _flat._bnds.tend() ;
+ ++_iter )
+ {
+ real_type _xprj[3] ;
+ projector(*_iter, +2, _xprj) ;
+
+ _RMIN[0] = std::min(
+ _RMIN[0] , (float) _xprj[0]) ;
+ _RMIN[1] = std::min(
+ _RMIN[1] , (float) _xprj[1]) ;
+ _RMIN[2] = std::min(
+ _RMIN[2] , (float) _xprj[2]) ;
+
+ _RMAX[0] = std::max(
+ _RMAX[0] , (float) _xprj[0]) ;
+ _RMAX[1] = std::max(
+ _RMAX[1] , (float) _xprj[1]) ;
+ _RMAX[2] = std::max(
+ _RMAX[2] , (float) _xprj[2]) ;
+ }
+
/*------------------ call actual intersection testing */
tree_pred _pred(_PPOS, _NVEC,
_RMIN, _RMAX) ;
@@ -1560,6 +1987,7 @@
{
bool_type _find = false ;
+ /*------------------ compute line-ellipsoid intersect */
real_type _ipos[3] ;
_ipos[0] = _line._ipos[ 0];
_ipos[1] = _line._ipos[ 1];
@@ -1573,7 +2001,6 @@
real_type _ttaa, _ttbb;
if (line_surf(_ipos, _jpos, _ttaa, _ttbb))
{
-
real_type _pmid[3] = {
_jpos[0] * (real_type)+.5 +
_ipos[0] * (real_type)+.5 ,
@@ -1591,6 +2018,7 @@
_ipos[2] * (real_type)+.5
} ;
+ /*------------------ calc. XYZ pos. for intersections */
real_type _apos[3] = {
_pmid[0] + _ttaa * _pdel[0] ,
_pmid[1] + _ttaa * _pdel[1] ,
@@ -1603,8 +2031,9 @@
_pmid[2] + _ttbb * _pdel[2]
} ;
+ /*------------------ push surf.-proj. to output func. */
char_type _hits =
- geometry::null_hits ;
+ geometry::face_hits ;
char_type _feat = +2;
char_type _topo = +2;
iptr_type _itag = +0;
@@ -1613,18 +2042,16 @@
if (_ttaa <= (real_type)+1.)
{
_find = true ;
- _hfun ( _apos, _hits ,
- _feat, _topo ,
- _itag) ;
+ _hfun( _apos,
+ _hits, _feat, _topo, _itag) ;
}
if (_ttbb >= (real_type)-1.)
if (_ttbb <= (real_type)+1.)
{
_find = true ;
- _hfun ( _bpos, _hits ,
- _feat, _topo ,
- _itag) ;
+ _hfun( _bpos,
+ _hits, _feat, _topo, _itag) ;
}
}
@@ -1647,90 +2074,50 @@
hits_func &_hfun
)
{
- bool_type _find = false ;
+ /*------------------ calc. initial dir. to surf.-ball */
+ real_type _proj[3], _vdir[3] ;
+ proj_surf(_sbal, _proj) ;
- __unreferenced(_sbal) ;
-
- real_type _circ[3] = {
- (real_type) +0. ,
- (real_type) +0. ,
- (real_type) +0. } ;
-
- real_type _pdir[4] = {
- _disc._pmid[0] - _circ[0] ,
- _disc._pmid[1] - _circ[1] ,
- _disc._pmid[2] - _circ[2] ,
- (real_type) +0. } ;
-
- real_type _ddir[4] ;
- geometry::cross_3d(
- _pdir, _disc._nvec, _ddir) ;
-
- _pdir[3] =
- geometry::length_3d(_pdir) ;
- _pdir[0]/= _pdir[3] ;
- _pdir[1]/= _pdir[3] ;
- _pdir[2]/= _pdir[3] ;
-
- _ddir[3] =
- geometry::length_3d(_ddir) ;
- _ddir[0]/= _ddir[3] ;
- _ddir[1]/= _ddir[3] ;
- _ddir[2]/= _ddir[3] ;
-
- real_type _apos[3] = {
- _disc._pmid[0] -
- _disc._rrad *_pdir[0] ,
- _disc._pmid[1] -
- _disc._rrad *_pdir[1] ,
- _disc._pmid[2] -
- _disc._rrad *_pdir[2]
- } ;
+ iptr_type _iter;
+ for(_iter = 8; _iter-- != 0; )
+ {
+ /*------------------ iter. to improve dir.-to-surface */
+ geometry::vector_3d(
+ _disc._pmid, _proj, _vdir) ;
- real_type _bpos[3] = {
- _disc._pmid[0] +
- _disc._rrad *_ddir[0] ,
- _disc._pmid[1] +
- _disc._rrad *_ddir[1] ,
- _disc._pmid[2] +
- _disc._rrad *_ddir[2]
- } ;
+ geometry::normalise_3d( _vdir) ;
- real_type _cpos[3] = {
+ real_type _xpos[3] = {
_disc._pmid[0] +
- _disc._rrad *_pdir[0] ,
+ _disc._rrad *_vdir[0] ,
_disc._pmid[1] +
- _disc._rrad *_pdir[1] ,
+ _disc._rrad *_vdir[1] ,
_disc._pmid[2] +
- _disc._rrad *_pdir[2]
+ _disc._rrad *_vdir[2]
} ;
- real_type _dpos[3] = {
- _disc._pmid[0] -
- _disc._rrad *_ddir[0] ,
- _disc._pmid[1] -
- _disc._rrad *_ddir[1] ,
- _disc._pmid[2] -
- _disc._rrad *_ddir[2]
- } ;
+ proj_surf(_xpos, _proj) ;
- _find = _find |
- disc_kern(_disc,
- _apos , _bpos, +0, _hfun) ;
+ real_type _dsqr =
+ geometry::
+ lensqr_3d(_xpos, _proj) ;
- _find = _find |
- disc_kern(_disc,
- _bpos , _cpos, +0, _hfun) ;
+ if (_dsqr < this->_rEPS *
+ this->_rEPS )
+ break ;
+ }
- _find = _find |
- disc_kern(_disc,
- _cpos , _dpos, +0, _hfun) ;
+ /*------------------ push surf.-proj. to output func. */
+ char_type _hits =
+ geometry::face_hits ;
+ char_type _feat = +2;
+ char_type _topo = +2;
+ iptr_type _itag = +0;
- _find = _find |
- disc_kern(_disc,
- _dpos , _apos, +0, _hfun) ;
+ _hfun( _proj ,
+ _hits, _feat , _topo, _itag) ;
- return _find ;
+ return true ;
}
/*
@@ -1743,6 +2130,7 @@
real_type *_ppos
)
{
+ /*------------------ (x/a)^2 + (y/b)^2 + (z/c)^2 < 1? */
real_type _xx =
_ppos[0] / this->_radA ;
real_type _yy =
diff --git a/external/jigsaw/src/libcpp/geom_type/geom_mesh_euclidean_2.hpp b/external/jigsaw/src/libcpp/geom_type/geom_mesh_euclidean_2.hpp
index 223ae2f..b1da6f5 100644
--- a/external/jigsaw/src/libcpp/geom_type/geom_mesh_euclidean_2.hpp
+++ b/external/jigsaw/src/libcpp/geom_type/geom_mesh_euclidean_2.hpp
@@ -31,11 +31,11 @@
*
--------------------------------------------------------
*
- * Last updated: 08 December, 2019
+ * Last updated: 28 April, 2020
*
- * Copyright 2013-2019
+ * Copyright 2013-2020
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
--------------------------------------------------------
@@ -127,6 +127,26 @@
} ;
+ class seed_type: public mesh_complex_node_2
+ {
+ /*------------------------------------ loc. seed type */
+ public :
+ iptr_type _itag ;
+
+ public :
+ /*------------------------------------ "write" access */
+ __inline_call iptr_type& itag (
+ )
+ { return this->_itag ;
+ }
+ /*------------------------------------ "const" access */
+ __inline_call iptr_type const& itag (
+ ) const
+ { return this->_itag ;
+ }
+
+ } ;
+
class edge_type: public mesh_complex_edge_2
{
/*------------------------------------ loc. edge type */
@@ -261,6 +281,10 @@
iptr_type static constexpr
part_bytes = sizeof (part_item);
+ typedef containers::array <
+ seed_type ,
+ allocator > seed_list ;
+
typedef containers::array <
iptr_type ,
allocator > iptr_list ;
@@ -297,6 +321,8 @@
pool_base _pool ;
+ seed_list _seed ;
+
part_list _part ;
iptr_list _ptag ;
@@ -322,6 +348,7 @@
allocator const&
_asrc = allocator ()
) : _pool(part_bytes) ,
+ _seed( _asrc ) ,
_part(part_hash() ,
part_same() ,
.8, (pool_wrap(&_pool))) ,
@@ -367,8 +394,9 @@
geom_opts &_opts
)
{
+ /*------------ "sharp" geometry//topology about node? */
real_type _DtoR =
- (real_type) +3.1415926536 / 180. ;
+ (real_type)+3.141592653589793 / 180. ;
real_type _ZERO = -1. +
std::numeric_limits
@@ -387,7 +415,7 @@
__unreferenced(_node) ;
_feat = null_feat ;
- _topo = (char_type)_aset.count();
+ _topo = (char_type)_aset.count () ;
for (auto _ipos = _aset.head() ;
_ipos != _aset.tend() ;
@@ -398,75 +426,75 @@
_jpos != _aset.tend() ;
++_jpos )
{
- iptr_type _iedg = * _ipos ;
- iptr_type _jedg = * _jpos ;
+ /*------------ find signed angle between edge vectors */
+ auto _iedg = _ipos->_cell ;
+ auto _jedg = _jpos->_cell ;
- iptr_type _inod[2] ;
- _inod[0] = this->_tria.
- _set2[_iedg]. node(0) ;
- _inod[1] = this->_tria.
- _set2[_iedg]. node(1) ;
+ iptr_type _inod[2] = {
+ this->_tria.edge(_iedg).node(0) ,
+ this->_tria.edge(_iedg).node(1) ,
+ } ;
- iptr_type _jnod[2] ;
- _jnod[0] = this->_tria.
- _set2[_jedg]. node(0) ;
- _jnod[1] = this->_tria.
- _set2[_jedg]. node(1) ;
+ iptr_type _jnod[2] = {
+ this->_tria.edge(_jedg).node(0) ,
+ this->_tria.edge(_jedg).node(1) ,
+ } ;
real_type _ivec[2] ;
geometry::vector_2d(
- &this->_tria.
- _set1[ _inod[0]].pval(0) ,
- &this->_tria.
- _set1[ _inod[1]].pval(0) ,
- _ivec) ;
+ & this->_tria.
+ node(_inod[0]).pval(0) ,
+ & this->_tria.
+ node(_inod[1]).pval(0) ,
+ _ivec) ;
real_type _jvec[2] ;
geometry::vector_2d(
- &this->_tria.
- _set1[ _jnod[0]].pval(0) ,
- &this->_tria.
- _set1[ _jnod[1]].pval(0) ,
- _jvec) ;
+ & this->_tria.
+ node(_jnod[0]).pval(0) ,
+ & this->_tria.
+ node(_jnod[1]).pval(0) ,
+ _jvec) ;
- real_type _acos =
- geometry::cosine_2d(
- _ivec , _jvec) ;
+ real_type _acos = geometry::
+ cosine_2d(_ivec, _jvec) ;
if (_inod[0] == _jnod[1] ||
_inod[1] == _jnod[0] )
- _acos *= (real_type)+1.;
+ _acos *= (real_type)+1. ;
else
- _acos *= (real_type)-1.;
+ _acos *= (real_type)-1. ;
if (_acos >= _ZERO)
{
+ /*------------ tag as "feature" if angle sharp enough */
if (_acos <= _hard)
{
_feat =
- std::max(_feat, hard_feat) ;
+ std::max (_feat, hard_feat) ;
}
else
if (_acos <= _soft)
{
_feat =
- std::max(_feat, soft_feat) ;
+ std::max (_feat, soft_feat) ;
}
}
else
{
if (_tbad >= + 1 )
{
- _topo -= _tbad--;
+ _topo -= _tbad-- ;
}
}
}
}
{
+ /*------------ tag as "feature" if topo. is irregular */
if (_topo != + 0 )
if (_topo != + 2 )
_feat =
- std::max(_feat, soft_feat) ;
+ std::max (_feat, soft_feat) ;
}
}
@@ -483,13 +511,14 @@
geom_opts &_opts
)
{
- containers::array _eadj ;
+ typename
+ mesh_type::connector _eadj ;
/*---------------------------------- init. geom feat. */
for (auto _iter =
- this->_tria._set1.head() ;
+ this->_tria.node().head() ;
_iter !=
- this->_tria._set1.tend() ;
+ this->_tria.node().tend() ;
++_iter )
{
if (_iter->mark() >= +0)
@@ -501,9 +530,9 @@
}
for (auto _iter =
- this->_tria._set2.head() ;
+ this->_tria.edge().head() ;
_iter !=
- this->_tria._set2.tend() ;
+ this->_tria.edge().tend() ;
++_iter )
{
if (_iter->mark() >= +0)
@@ -515,9 +544,9 @@
/*---------------------------------- find sharp feat. */
for (auto _iter =
- this->_tria._set1.head() ;
+ this->_tria.node().head() ;
_iter !=
- this->_tria._set1.tend() ;
+ this->_tria.node().tend() ;
++_iter )
{
/*---------------------------------- find sharp 0-dim */
@@ -529,8 +558,8 @@
/*---------------------------------- set geo.-defined */
_eadj.set_count (0);
- this->_tria.node_edge (
- &_iter->node (0), _eadj) ;
+ this->_tria.connect_1(
+ &_iter->node (0), POINT_tag, _eadj) ;
node_feat (
&_iter->node (0),
@@ -543,39 +572,37 @@
{
/*---------------------------------- set user-defined */
_iter->feat () =
- std::max(_iter->feat () ,
- soft_feat) ;
+ std::max(_iter->feat(), soft_feat) ;
}
}
}
}
for (auto _iter =
- this->_tria._set2.head() ;
+ this->_tria.edge().head() ;
_iter !=
- this->_tria._set2.tend() ;
+ this->_tria.edge().tend() ;
++_iter )
{
if (_iter->mark() >= +0)
{
/*----------------------------- assign nodes to edges */
- this->_tria._set1[
- _iter->node(0)].fdim() = 1 ;
- this->_tria._set1[
- _iter->node(1)].fdim() = 1 ;
+ this->_tria.node()[
+ _iter->node(0)].fdim() = 1;
+ this->_tria.node()[
+ _iter->node(1)].fdim() = 1;
}
}
for (auto _iter =
- this->_tria._set1.head() ;
+ this->_tria.node().head() ;
_iter !=
- this->_tria._set1.tend() ;
+ this->_tria.node().tend() ;
++_iter )
{
if (_iter->mark() >= +0)
{
- if (_iter->feat() !=
- mesh::null_feat)
+ if (_iter->feat() != null_feat)
{
/*----------------------------- assign nodes to feat. */
_iter->fdim() = +0;
@@ -703,14 +730,14 @@
{
/*----------------------------- expand aabb via EDGE2 */
auto _inod = this->
- _tria._set2[_cell].node(0);
+ _tria.edge(_cell).node(0) ;
auto _jnod = this->
- _tria._set2[_cell].node(1);
+ _tria.edge(_cell).node(1) ;
- auto _iptr = &this->
- _tria._set1[_inod];
- auto _jptr = &this->
- _tria._set1[_jnod];
+ auto _iptr =
+ &this->_tria.node(_inod);
+ auto _jptr =
+ &this->_tria.node(_jnod);
real_type _xmin =
std::min (_iptr->pval(0) ,
@@ -791,9 +818,9 @@
/*----------------------------- calc. aabb for inputs */
for (auto _iter =
- this->_tria._set1.head() ;
+ this->_tria.node().head() ;
_iter !=
- this->_tria._set1.tend() ;
+ this->_tria.node().tend() ;
++_iter )
{
if (_iter->mark() >= +0 )
@@ -836,10 +863,10 @@
init_part (_opts);
/*-------------------- make aabb-tree and init. bbox. */
- aabb_mesh(this->_tria._set1,
- this->_tria._set2,
+ aabb_mesh(this->_tria.node(),
+ this->_tria.edge(),
this->_ebox,
- _BTOL,this->_nbox, edge_pred ()
+ _BTOL, this->_nbox, edge_pred()
) ;
}
@@ -862,9 +889,9 @@
/*------------------------- push set of feature nodes */
for (auto _iter =
- this->_tria._set1.head() ;
+ this->_tria.node().head() ;
_iter !=
- this->_tria._set1.tend() ;
+ this->_tria.node().tend() ;
++_iter )
{
if (_iter->mark() >= +0 )
@@ -872,9 +899,14 @@
if (_iter->feat() != null_feat)
{
/*----------------------------- push any 'real' feat. */
+ real_type _ppos[3] ;
+ _ppos[0] = _iter->pval(0) ;
+ _ppos[1] = _iter->pval(1) ;
+ _ppos[2] = (real_type)+0. ;
+
iptr_type _node = -1 ;
if (_mesh._tria.push_node (
- &_iter->pval(0), _node))
+ &_ppos[ 0], _node))
{
_mesh._tria.node
(_node)->fdim()
@@ -897,9 +929,14 @@
if (_iter->itag() <= -1 )
{
/*----------------------------- push any 'user' feat. */
+ real_type _ppos[3] ;
+ _ppos[0] = _iter->pval(0) ;
+ _ppos[1] = _iter->pval(1) ;
+ _ppos[2] = (real_type)+0. ;
+
iptr_type _node = -1 ;
if (_mesh._tria.push_node (
- &_iter->pval(0), _node))
+ &_ppos[ 0], _node))
{
_mesh._tria.node
(_node)->fdim()
@@ -951,16 +988,18 @@
for (_fdim = 1; _fdim != 3; ++_fdim)
{
for (auto _ipos =
- this->_tria._set1.head() ;
+ this->_tria.node().head() ;
_ipos !=
- this->_tria._set1.tend() ;
+ this->_tria.node().tend() ;
++_ipos )
{
+ /*------------------------- get current furthest node */
if (_ipos->mark() >= 0 &&
_ipos->fdim () == _fdim)
{
real_type _dmin =
- +std::numeric_limits::infinity() ;
+ +std::numeric_limits
+ ::infinity();
for (auto _jpos =
_mesh._tria._nset.head() ;
@@ -989,9 +1028,14 @@
if (_dmax > (real_type)0.)
{
/*------------------------- add current furthest node */
+ real_type _ppos[3] ;
+ _ppos[0] = _best->pval(0) ;
+ _ppos[1] = _best->pval(1) ;
+ _ppos[2] = (real_type)+0. ;
+
iptr_type _node = -1;
if (_mesh._tria.push_node(
- &_best->pval(0), _node) )
+ &_ppos[ 0], _node) )
{
_mesh._tria.node
(_node)->fdim()
@@ -1114,21 +1158,21 @@
&& !have_part(_epos) )
continue ;
- iptr_type _enod[2];
- _enod[0] =_geom.
- _tria._set2[_epos].node(0) ;
- _enod[1] =_geom.
- _tria._set2[_epos].node(1) ;
+ iptr_type _enod[2] ;
+ _enod[0] = _geom.
+ _tria.edge(_epos).node(0) ;
+ _enod[1] = _geom.
+ _tria.edge(_epos).node(1) ;
- real_type _xpos[2];
+ real_type _xpos[2] ;
_HITS =
geometry::line_line_2d (
& this->_ipos[0],
& this->_jpos[0],
&_geom ._tria.
- _set1 [_enod[0]].pval(0),
+ node( _enod[0] ).pval(0) ,
&_geom ._tria.
- _set1 [_enod[1]].pval(0),
+ node( _enod[1] ).pval(0) ,
_xpos, true, 2 ) ;
if(_HITS != geometry::null_hits)
@@ -1136,11 +1180,11 @@
/*--------------- call output function on hit */
this->_hfun (_xpos, _HITS ,
_geom._tria .
- _set2[_epos].feat() ,
+ edge(_epos).feat() ,
_geom._tria .
- _set2[_epos].topo() ,
+ edge(_epos).topo() ,
_geom._tria .
- _set2[_epos].itag() ) ;
+ edge(_epos).itag() ) ;
this->_hnum+= +1 ;
@@ -1220,22 +1264,22 @@
iptr_type _epos =
_iptr->_data.ipos() ;
- iptr_type _enod[2];
- _enod[0] =_geom.
- _tria._set2[_epos].node(0) ;
- _enod[1] =_geom.
- _tria._set2[_epos].node(1) ;
-
- real_type _ipos[2];
- real_type _jpos[2];
- size_t _nhit =
+ iptr_type _enod[2];
+ _enod[0] = _geom.
+ _tria.edge(_epos).node(0) ;
+ _enod[1] = _geom.
+ _tria.edge(_epos).node(1) ;
+
+ real_type _ipos[2];
+ real_type _jpos[2];
+ size_t _nhit =
geometry::ball_line_2d (
this->_ball,
this->_rsiz,
&_geom ._tria.
- _set1 [_enod[0]].pval(0) ,
+ node (_enod[0] ).pval(0) ,
&_geom ._tria.
- _set1 [_enod[1]].pval(0) ,
+ node (_enod[1] ).pval(0) ,
_ipos, _jpos ) ;
switch (_nhit)
@@ -1245,11 +1289,11 @@
/*--------------- call output function on hit */
this->_hfun (_jpos, _HITS ,
_geom._tria .
- _set2[_epos].feat() ,
+ edge(_epos).feat() ,
_geom._tria .
- _set2[_epos].topo() ,
+ edge(_epos).topo() ,
_geom._tria .
- _set2[_epos].itag() ) ;
+ edge(_epos).itag() ) ;
this->_hnum += +1;
} // falls through
@@ -1259,11 +1303,11 @@
/*--------------- call output function on hit */
this->_hfun (_ipos, _HITS ,
_geom._tria .
- _set2[_epos].feat() ,
+ edge(_epos).feat() ,
_geom._tria .
- _set2[_epos].topo() ,
+ edge(_epos).topo() ,
_geom._tria .
- _set2[_epos].itag() ) ;
+ edge(_epos).itag() ) ;
this->_hnum += +1;
@@ -1330,17 +1374,17 @@
iptr_type _enod[+2] = {
this->_mesh->
- _set2 [_EPOS ].node(0) ,
+ edge (_EPOS ).node(0) ,
this->_mesh->
- _set2 [_EPOS ].node(1) ,
+ edge (_EPOS ).node(1) ,
} ;
if (geometry::proj_line_2d (
_ppos,
&this->_mesh->
- _set1 [_enod[0]].pval(0) ,
+ node (_enod[0]).pval(0) ,
&this->_mesh->
- _set1 [_enod[1]].pval(0) ,
+ node (_enod[1]).pval(0) ,
_qtmp, _HITS) )
{
if (_HITS !=
diff --git a/external/jigsaw/src/libcpp/geom_type/geom_mesh_euclidean_3.hpp b/external/jigsaw/src/libcpp/geom_type/geom_mesh_euclidean_3.hpp
index c1d5095..5cf35db 100644
--- a/external/jigsaw/src/libcpp/geom_type/geom_mesh_euclidean_3.hpp
+++ b/external/jigsaw/src/libcpp/geom_type/geom_mesh_euclidean_3.hpp
@@ -31,11 +31,11 @@
*
--------------------------------------------------------
*
- * Last updated: 08 December, 2019
+ * Last updated: 28 April, 2020
*
- * Copyright 2013-2019
+ * Copyright 2013-2020
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
--------------------------------------------------------
@@ -129,6 +129,26 @@
} ;
+ class seed_type: public mesh_complex_node_3
+ {
+ /*------------------------------------ loc. node type */
+ public :
+ iptr_type _itag ;
+
+ public :
+ /*------------------------------------ "write" access */
+ __inline_call iptr_type& itag (
+ )
+ { return this->_itag ;
+ }
+ /*------------------------------------ "const" access */
+ __inline_call iptr_type const& itag (
+ ) const
+ { return this->_itag ;
+ }
+
+ } ;
+
class edge_type: public mesh_complex_edge_2
{
/*------------------------------------ loc. edge type */
@@ -302,6 +322,10 @@
iptr_type static constexpr
part_bytes = sizeof (part_item);
+ typedef containers::array <
+ seed_type ,
+ allocator > seed_list ;
+
typedef containers::array <
iptr_type ,
allocator > iptr_list ;
@@ -340,6 +364,8 @@
pool_base _pool ;
+ seed_list _seed ;
+
part_list _part ;
iptr_list _ptag ;
@@ -366,6 +392,7 @@
allocator const&
_asrc = allocator ()
) : _pool(part_bytes) ,
+ _seed( _asrc ) ,
_part(part_hash() ,
part_same() ,
.8, (pool_wrap(&_pool))) ,
@@ -399,33 +426,41 @@
/*
--------------------------------------------------------
- * NODE-FEAT: calc. node feature type.
+ * FEAT-LIST: extract feat. edge list.
--------------------------------------------------------
*/
- template <
- typename list_type
- >
__normal_call void_type feat_list (
- list_type &_lsrc ,
- list_type &_ldst
+ typename
+ mesh_type::connector &_lsrc ,
+ typename
+ mesh_type::connector &_ldst
)
{
for (auto _iter = _lsrc.head() ;
_iter != _lsrc.tend() ;
++_iter )
{
- auto _feat =
- this->
- _tria._set2[ *_iter].feat() ;
+ auto _feat = this->_tria.
+ edge(_iter->_cell).feat() ;
+
+ auto _self = this->_tria.
+ edge(_iter->_cell).self() ;
- if (_feat != null_feat)
+ if (_self >= +1 ||
+ _feat != mesh::null_feat)
{
- _ldst.push_tail(*_iter) ;
+ _ldst.push_tail( *_iter ) ;
}
}
}
+ /*
+ --------------------------------------------------------
+ * NODE-FEAT: calc. node feature type.
+ --------------------------------------------------------
+ */
+
template <
typename list_type ,
typename geom_opts
@@ -438,8 +473,9 @@
geom_opts &_opts
)
{
+ /*------------ "sharp" geometry//topology about node? */
real_type _DtoR =
- (real_type) +3.1415926536 / 180.0;
+ (real_type)+3.141592653589793 / 180. ;
real_type _ZERO = -1. +
std::numeric_limits
@@ -458,7 +494,7 @@
__unreferenced(_node) ;
_feat = null_feat ;
- _topo = (char_type)_aset.count();
+ _topo = (char_type)_aset.count () ;
for (auto _ipos = _aset.head() ;
_ipos != _aset.tend() ;
@@ -469,78 +505,84 @@
_jpos != _aset.tend() ;
++_jpos )
{
- iptr_type _iedg = * _ipos ;
- iptr_type _jedg = * _jpos ;
+ /*------------ find signed angle between edge vectors */
+ auto _iedg = _ipos->_cell ;
+ auto _jedg = _jpos->_cell ;
- iptr_type _inod[2] ;
- _inod[0] = this->_tria.
- _set2[_iedg]. node(0) ;
- _inod[1] = this->_tria.
- _set2[_iedg]. node(1) ;
+ iptr_type _inod[2] = {
+ this->_tria.edge(_iedg).node(0) ,
+ this->_tria.edge(_iedg).node(1) ,
+ } ;
- iptr_type _jnod[2] ;
- _jnod[0] = this->_tria.
- _set2[_jedg]. node(0) ;
- _jnod[1] = this->_tria.
- _set2[_jedg]. node(1) ;
+ iptr_type _jnod[2] = {
+ this->_tria.edge(_jedg).node(0) ,
+ this->_tria.edge(_jedg).node(1) ,
+ } ;
real_type _ivec[3] ;
geometry::vector_3d(
- &this->_tria.
- _set1[ _inod[0]].pval(0) ,
- &this->_tria.
- _set1[ _inod[1]].pval(0) ,
- _ivec) ;
+ & this->_tria.
+ node(_inod[0]).pval(0) ,
+ & this->_tria.
+ node(_inod[1]).pval(0) ,
+ _ivec) ;
real_type _jvec[3] ;
geometry::vector_3d(
- &this->_tria.
- _set1[ _jnod[0]].pval(0) ,
- &this->_tria.
- _set1[ _jnod[1]].pval(0) ,
- _jvec) ;
+ & this->_tria.
+ node(_jnod[0]).pval(0) ,
+ & this->_tria.
+ node(_jnod[1]).pval(0) ,
+ _jvec) ;
- real_type _acos =
- geometry::cosine_3d(
- _ivec , _jvec) ;
+ real_type _acos = geometry::
+ cosine_3d(_ivec, _jvec) ;
if (_inod[0] == _jnod[1] ||
_inod[1] == _jnod[0] )
- _acos *= (real_type)+1.;
+ _acos *= (real_type)+1. ;
else
- _acos *= (real_type)-1.;
+ _acos *= (real_type)-1. ;
if (_acos >= _ZERO)
{
+ /*------------ tag as "feature" if angle sharp enough */
if (_acos <= _hard)
{
_feat =
- std::max(_feat, hard_feat) ;
+ std::max (_feat, hard_feat) ;
}
else
if (_acos <= _soft)
{
_feat =
- std::max(_feat, soft_feat) ;
+ std::max (_feat, soft_feat) ;
}
}
else
{
if (_tbad >= + 1 )
{
- _topo -= _tbad--;
+ _topo -= _tbad-- ;
}
}
}
}
{
+ /*------------ tag as "feature" if topo. is irregular */
if (_topo != + 0 )
if (_topo != + 2 )
_feat =
- std::max(_feat, soft_feat) ;
+ std::max (_feat, soft_feat) ;
}
}
+ /*
+ --------------------------------------------------------
+ * NODE-FEAT: calc. node feature type.
+ --------------------------------------------------------
+ */
+
template <
typename list_type ,
typename geom_opts
@@ -552,10 +594,11 @@
geom_opts &_opts
)
{
+ /*------------ "sharp" geometry//topology about node? */
char_type _feat = null_feat ;
real_type _DtoR =
- (real_type) +3.1415926536 / 180.0;
+ (real_type)+3.141592653589793 / 180. ;
real_type _phi1 =
(real_type)+180. - _opts.phi1();
@@ -576,22 +619,23 @@
_fpos != _fadj.tend() ;
++_fpos )
{
- iptr_type _iedg = * _epos ;
- iptr_type _ifac = * _fpos ;
+ /*------------ find signed angle between cell vectors */
+ auto _iedg = _epos->_cell ;
+ auto _ifac = _fpos->_cell ;
iptr_type _enod[2] ;
_enod[0] = this->_tria.
- _set2[_iedg]. node(0) ;
+ edge(_iedg). node(0) ;
_enod[1] = this->_tria.
- _set2[_iedg]. node(1) ;
+ edge(_iedg). node(1) ;
iptr_type _fnod[3] ;
_fnod[0] = this->_tria.
- _fset[_ifac]. node(0) ;
+ tri3(_ifac). node(0) ;
_fnod[1] = this->_tria.
- _fset[_ifac]. node(1) ;
+ tri3(_ifac). node(1) ;
_fnod[2] = this->_tria.
- _fset[_ifac]. node(2) ;
+ tri3(_ifac). node(2) ;
iptr_type _same = +0 ;
if (_fnod[0] == _enod[0])
@@ -610,34 +654,32 @@
real_type _evec[3] ;
geometry::vector_3d(
- &this->_tria.
- _set1[ _enod[0]].pval(0) ,
- &this->_tria.
- _set1[ _enod[1]].pval(0) ,
- _evec) ;
+ & this->_tria.
+ node(_enod[0]).pval(0) ,
+ & this->_tria.
+ node(_enod[1]).pval(0) ,
+ _evec) ;
real_type _fvec[3] ;
-
//!! actually, need to project edge onto tria
+ real_type _acos = geometry::
+ cosine_3d(_evec, _fvec) ;
- real_type _acos =
- geometry::cosine_3d(
- _evec , _fvec) ;
-
- _acos =std::abs(_acos) ;
+ _acos = std::abs(_acos) ;
+ /*------------ tag as "feature" if angle sharp enough */
if (_acos <= _hard)
{
_feat =
- std::max(_feat, hard_feat) ;
+ std::max (_feat, hard_feat) ;
}
else
if (_acos <= _soft)
{
_feat =
- std::max(_feat, soft_feat) ;
+ std::max (_feat, soft_feat) ;
}
}
@@ -662,8 +704,9 @@
geom_opts &_opts
)
{
+ /*------------ "sharp" geometry//topology about edge? */
real_type _DtoR =
- (real_type) +3.1415926536 / 180.0;
+ (real_type)+3.141592653589793 / 180. ;
real_type _ZERO = -1. +
std::numeric_limits
@@ -680,7 +723,7 @@
std::cos( _eta2 * _DtoR) ;
_feat = null_feat ;
- _topo = (char_type)_aset.count();
+ _topo = (char_type)_aset.count () ;
for (auto _ipos = _aset.head() ;
_ipos != _aset.tend() ;
@@ -691,128 +734,121 @@
_jpos != _aset.tend() ;
++_jpos )
{
- iptr_type _itri = * _ipos ;
- iptr_type _jtri = * _jpos ;
-
- iptr_type _inod[3];
- iptr_type _jnod[3];
+ /*------------ find signed angle between cell normals */
+ auto _itri = _ipos->_cell ;
+ auto _jtri = _jpos->_cell ;
- iptr_type _iloc ;
+ iptr_type _inod[3], _iloc ;
for (_iloc = 3; _iloc-- != 0; )
{
- tri3_type::face_node (
- _inod, _iloc, 2, 1) ;
-
- _inod[0] = this->_tria.
- _set3[_itri].
- node(_inod[0]);
- _inod[1] = this->_tria.
- _set3[_itri].
- node(_inod[1]);
- _inod[2] = this->_tria.
- _set3[_itri].
- node(_inod[2]);
-
- iptr_type _same = +0 ;
- if (_inod[0]==_enod[0])
- _same += +1 ;
- if (_inod[0]==_enod[1])
- _same += +1 ;
- if (_inod[1]==_enod[0])
- _same += +1 ;
- if (_inod[1]==_enod[1])
- _same += +1 ;
-
- if (_same == +2 ) break ;
+ tri3_type::face_node (
+ _inod, _iloc, +2, +1) ;
+
+ _inod[0] = this->_tria.
+ tri3(_itri).node(_inod[0]) ;
+ _inod[1] = this->_tria.
+ tri3(_itri).node(_inod[1]) ;
+ _inod[2] = this->_tria.
+ tri3(_itri).node(_inod[2]) ;
+
+ iptr_type _same = +0 ;
+ if (_inod[0]==_enod[0])
+ _same += +1 ;
+ if (_inod[0]==_enod[1])
+ _same += +1 ;
+ if (_inod[1]==_enod[0])
+ _same += +1 ;
+ if (_inod[1]==_enod[1])
+ _same += +1 ;
+
+ if (_same == +2 ) break ;
}
- iptr_type _jloc ;
+ iptr_type _jnod[3], _jloc ;
for (_jloc = 3; _jloc-- != 0; )
{
- tri3_type::face_node (
- _jnod, _jloc, 2, 1) ;
-
- _jnod[0] = this->_tria.
- _set3[_jtri].
- node(_jnod[0]);
- _jnod[1] = this->_tria.
- _set3[_jtri].
- node(_jnod[1]);
- _jnod[2] = this->_tria.
- _set3[_jtri].
- node(_jnod[2]);
-
- iptr_type _same = +0 ;
- if (_jnod[0]==_enod[0])
- _same += +1 ;
- if (_jnod[0]==_enod[1])
- _same += +1 ;
- if (_jnod[1]==_enod[0])
- _same += +1 ;
- if (_jnod[1]==_enod[1])
- _same += +1 ;
-
- if (_same == +2 ) break ;
+ tri3_type::face_node (
+ _jnod, _jloc, +2, +1) ;
+
+ _jnod[0] = this->_tria.
+ tri3(_jtri).node(_jnod[0]) ;
+ _jnod[1] = this->_tria.
+ tri3(_jtri).node(_jnod[1]) ;
+ _jnod[2] = this->_tria.
+ tri3(_jtri).node(_jnod[2]) ;
+
+ iptr_type _same = +0 ;
+ if (_jnod[0]==_enod[0])
+ _same += +1 ;
+ if (_jnod[0]==_enod[1])
+ _same += +1 ;
+ if (_jnod[1]==_enod[0])
+ _same += +1 ;
+ if (_jnod[1]==_enod[1])
+ _same += +1 ;
+
+ if (_same == +2 ) break ;
}
real_type _ivec[3];
geometry::tria_norm_3d (
- &this->_tria.
- _set1 [_inod[0]].pval(0) ,
- &this->_tria.
- _set1 [_inod[1]].pval(0) ,
- &this->_tria.
- _set1 [_inod[2]].pval(0) ,
- _ivec) ;
+ & this->_tria.
+ node(_inod[0]).pval(0) ,
+ & this->_tria.
+ node(_inod[1]).pval(0) ,
+ & this->_tria.
+ node(_inod[2]).pval(0) ,
+ _ivec) ;
real_type _jvec[3];
geometry::tria_norm_3d (
- &this->_tria.
- _set1 [_jnod[0]].pval(0) ,
- &this->_tria.
- _set1 [_jnod[1]].pval(0) ,
- &this->_tria.
- _set1 [_jnod[2]].pval(0) ,
- _jvec) ;
-
- real_type _acos =
- geometry::cosine_3d(
- _ivec , _jvec) ;
+ & this->_tria.
+ node(_jnod[0]).pval(0) ,
+ & this->_tria.
+ node(_jnod[1]).pval(0) ,
+ & this->_tria.
+ node(_jnod[2]).pval(0) ,
+ _jvec) ;
+
+ real_type _acos = geometry::
+ cosine_3d(_ivec, _jvec) ;
if (_inod[0] == _jnod[1] &&
_inod[1] == _jnod[0] )
- _acos *= (real_type)+1.;
+ _acos *= (real_type)+1. ;
else
- _acos *= (real_type)-1.;
+ _acos *= (real_type)-1. ;
if (_acos >= _ZERO)
{
+ /*------------ tag as "feature" if angle sharp enough */
if (_acos <= _hard)
{
_feat =
- std::max(_feat, hard_feat) ;
+ std::max (_feat, hard_feat) ;
}
else
if (_acos <= _soft)
{
_feat =
- std::max(_feat, soft_feat) ;
+ std::max (_feat, soft_feat) ;
}
}
else
{
if (_tbad >= + 1 )
{
- _topo -= _tbad--;
+ _topo -= _tbad-- ;
}
}
}
}
{
+ /*------------ tag as "feature" if topo. is irregular */
if (_topo != + 0 )
if (_topo != + 2 )
_feat =
- std::max(_feat, soft_feat) ;
+ std::max (_feat, soft_feat) ;
}
}
@@ -829,23 +865,22 @@
geom_opts &_opts
)
{
- containers::
- array _eadj ;
- containers::
- array _fadj ;
- containers::
- array _ebnd ;
-
- containers::
- array _nmrk ;
- containers::
- array _emrk ;
+ containers::array _nmrk ;
+ containers::array _emrk ;
+
+ typename
+ mesh_type::connector _eadj ;
+ typename
+ mesh_type::connector _fadj ;
+
+ typename
+ mesh_type::connector _ebnd ;
/*---------------------------------- init. geom feat. */
for (auto _iter =
- this->_tria._set1.head() ;
+ this->_tria.node().head() ;
_iter !=
- this->_tria._set1.tend() ;
+ this->_tria.node().tend() ;
++_iter )
{
if (_iter->mark() >= +0)
@@ -856,9 +891,9 @@
}
}
for (auto _iter =
- this->_tria._set2.head() ;
+ this->_tria.edge().head() ;
_iter !=
- this->_tria._set2.tend() ;
+ this->_tria.edge().tend() ;
++_iter )
{
if (_iter->mark() >= +0)
@@ -868,9 +903,9 @@
}
}
for (auto _iter =
- this->_tria._set3.head() ;
+ this->_tria.tri3().head() ;
_iter !=
- this->_tria._set3.tend() ;
+ this->_tria.tri3().tend() ;
++_iter )
{
if (_iter->mark() >= +0)
@@ -882,20 +917,20 @@
/*---------------------------------- find sharp feat. */
_nmrk.set_count (
- this->_tria._set1.count() ,
+ this->_tria.node().count(),
containers::loose_alloc,-1) ;
_emrk.set_count (
- this->_tria._set2.count() ,
+ this->_tria.edge().count(),
containers::loose_alloc,-1) ;
iptr_type _nnum = +0 ;
iptr_type _enum = +0 ;
for (auto _epos =
- this->_tria._set2.head() ;
+ this->_tria.edge().head() ;
_epos !=
- this->_tria._set2.tend() ;
+ this->_tria.edge().tend() ;
++_epos, ++_enum)
{
/*---------------------------------- find sharp 1-dim */
@@ -908,8 +943,8 @@
/*---------------------------------- set geo.-defined */
_fadj.set_count (0);
- this->_tria.edge_tri3 (
- &_epos->node (0), _fadj) ;
+ this->_tria.connect_2(
+ &_epos->node (0), EDGE2_tag, _fadj) ;
edge_feat (
&_epos->node (0),
@@ -918,12 +953,21 @@
_epos->topo () ,
_opts ) ;
+ if (_epos->self() >= +1)
+ {
+ /*---------------------------------- set for isolated */
+ _epos->feat () =
+ std::max(_epos->feat(), soft_feat) ;
+
+ _nmrk[_epos->node(0)] = +1;
+ _nmrk[_epos->node(1)] = +1;
+ }
+
if (_epos->itag() <= -1)
{
/*---------------------------------- set user-defined */
_epos->feat () =
- std::max(_epos->feat () ,
- soft_feat) ;
+ std::max(_epos->feat(), soft_feat) ;
_nmrk[_epos->node(0)] = +1;
_nmrk[_epos->node(1)] = +1;
@@ -933,9 +977,9 @@
}
for (auto _npos =
- this->_tria._set1.head() ;
+ this->_tria.node().head() ;
_npos !=
- this->_tria._set1.tend() ;
+ this->_tria.node().tend() ;
++_npos, ++_nnum)
{
/*---------------------------------- find sharp 0-dim */
@@ -949,11 +993,11 @@
_eadj.set_count (0);
_fadj.set_count (0);
- this->_tria.node_edge (
- &_npos->node (0), _eadj) ;
+ this->_tria.connect_1(
+ &_npos->node (0), POINT_tag, _eadj) ;
- this->_tria.node_tri3 (
- &_npos->node (0), _fadj) ;
+ this->_tria.connect_2(
+ &_npos->node (0), POINT_tag, _fadj) ;
_ebnd.set_count (0);
@@ -970,35 +1014,34 @@
{
/*---------------------------------- set user-defined */
_npos->feat () =
- std::max(_npos->feat () ,
- soft_feat) ;
+ std::max(_npos->feat(), soft_feat) ;
}
}
}
}
for (auto _iter =
- this->_tria._set3.head() ;
+ this->_tria.tri3().head() ;
_iter !=
- this->_tria._set3.tend() ;
+ this->_tria.tri3().tend() ;
++_iter )
{
/*----------------------------- assign nodes to trias */
if (_iter->mark() >= +0)
{
- this->_tria._set1[
- _iter->node(0)].fdim() = 2;
- this->_tria._set1[
- _iter->node(1)].fdim() = 2;
- this->_tria._set1[
- _iter->node(2)].fdim() = 2;
+ this->_tria.node(
+ _iter->node(0)).fdim() = 2;
+ this->_tria.node(
+ _iter->node(1)).fdim() = 2;
+ this->_tria.node(
+ _iter->node(2)).fdim() = 2;
}
}
for (auto _iter =
- this->_tria._set2.head() ;
+ this->_tria.edge().head() ;
_iter !=
- this->_tria._set2.tend() ;
+ this->_tria.edge().tend() ;
++_iter )
{
/*----------------------------- assign nodes to edges */
@@ -1006,18 +1049,18 @@
{
if (_iter->feat() != null_feat)
{
- this->_tria._set1[
- _iter->node(0)].fdim() = 1;
- this->_tria._set1[
- _iter->node(1)].fdim() = 1;
+ this->_tria.node(
+ _iter->node(0)).fdim() = 1;
+ this->_tria.node(
+ _iter->node(1)).fdim() = 1;
}
}
}
for (auto _iter =
- this->_tria._set1.head() ;
+ this->_tria.node().head() ;
_iter !=
- this->_tria._set1.tend() ;
+ this->_tria.node().tend() ;
++_iter )
{
if (_iter->mark() >= +0)
@@ -1150,18 +1193,18 @@
{
/*----------------------------- expand aabb via TRIA3 */
auto _inod = this->
- _tria._set3[_cell].node(0);
+ _tria.tri3(_cell).node(0) ;
auto _jnod = this->
- _tria._set3[_cell].node(1);
+ _tria.tri3(_cell).node(1) ;
auto _knod = this->
- _tria._set3[_cell].node(2);
+ _tria.tri3(_cell).node(2) ;
- auto _iptr = &this->
- _tria._set1[_inod];
- auto _jptr = &this->
- _tria._set1[_jnod];
- auto _kptr = &this->
- _tria._set1[_knod];
+ auto _iptr =
+ &this->_tria.node(_inod);
+ auto _jptr =
+ &this->_tria.node(_jnod);
+ auto _kptr =
+ &this->_tria.node(_knod);
real_type _xmin =
std::min (_iptr->pval(0) ,
@@ -1275,9 +1318,9 @@
/*----------------------------- calc. aabb for inputs */
for (auto _iter =
- this->_tria._set1.head() ;
+ this->_tria.node().head() ;
_iter !=
- this->_tria._set1.tend() ;
+ this->_tria.node().tend() ;
++_iter )
{
if (_iter->mark() >= +0)
@@ -1330,16 +1373,16 @@
init_part (_opts);
/*-------------------- make aabb-tree and init. bbox. */
- aabb_mesh(this->_tria._set1,
- this->_tria._set2,
+ aabb_mesh(this->_tria.node(),
+ this->_tria.edge(),
this->_ebox,
- _BTOL,this->_nbox,edge_pred ()
+ _BTOL, this->_nbox, edge_pred()
) ;
- aabb_mesh(this->_tria._set1,
- this->_tria._set3,
+ aabb_mesh(this->_tria.node(),
+ this->_tria.tri3(),
this->_tbox,
- _BTOL,this->_nbox,tri3_pred ()
+ _BTOL, this->_nbox, tri3_pred()
) ;
}
@@ -1362,9 +1405,9 @@
/*------------------------- push set of feature nodes */
for (auto _iter =
- this->_tria._set1.head() ;
+ this->_tria.node().head() ;
_iter !=
- this->_tria._set1.tend() ;
+ this->_tria.node().tend() ;
++_iter )
{
if (_iter->mark() >= +0 )
@@ -1372,9 +1415,15 @@
if (_iter->feat() != null_feat)
{
/*----------------------------- push any 'real' feat. */
+ real_type _ppos[4] ;
+ _ppos[0] = _iter->pval(0) ;
+ _ppos[1] = _iter->pval(1) ;
+ _ppos[2] = _iter->pval(2) ;
+ _ppos[3] = (real_type)+0. ;
+
iptr_type _node = -1 ;
if (_mesh._tria.push_node (
- &_iter->pval(0), _node))
+ &_ppos[ 0], _node))
{
_mesh._tria.node
(_node)->fdim()
@@ -1397,9 +1446,15 @@
if (_iter->itag() <= -1 )
{
/*----------------------------- push any 'user' feat. */
+ real_type _ppos[4] ;
+ _ppos[0] = _iter->pval(0) ;
+ _ppos[1] = _iter->pval(1) ;
+ _ppos[2] = _iter->pval(2) ;
+ _ppos[3] = (real_type)+0. ;
+
iptr_type _node = -1 ;
if (_mesh._tria.push_node (
- &_iter->pval(0), _node))
+ &_ppos[ 0], _node))
{
_mesh._tria.node
(_node)->fdim()
@@ -1451,11 +1506,12 @@
for (_fdim = 1; _fdim != 4; ++_fdim)
{
for (auto _ipos =
- this->_tria._set1.head() ;
+ this->_tria.node().head() ;
_ipos !=
- this->_tria._set1.tend() ;
+ this->_tria.node().tend() ;
++_ipos )
{
+ /*------------------------- get current furthest node */
if (_ipos->mark() >= 0 &&
_ipos->fdim () == _fdim)
{
@@ -1490,9 +1546,15 @@
if (_dmax > (real_type)0.)
{
/*------------------------- add current furthest node */
+ real_type _ppos[4] ;
+ _ppos[0] = _best->pval(0) ;
+ _ppos[1] = _best->pval(1) ;
+ _ppos[2] = _best->pval(2) ;
+ _ppos[3] = (real_type)+0. ;
+
iptr_type _node = -1;
if (_mesh._tria.push_node(
- &_best->pval(0), _node) )
+ &_ppos[ 0], _node) )
{
_mesh._tria.node
(_node)->fdim()
@@ -1585,21 +1647,21 @@
iptr_type _epos =
_iptr->_data.ipos() ;
- iptr_type _enod[2];
- _enod[0] =_geom.
- _tria._set2[_epos].node(0) ;
- _enod[1] =_geom.
- _tria._set2[_epos].node(1) ;
+ iptr_type _enod[2] ;
+ _enod[0] = _geom.
+ _tria.edge(_epos).node(0) ;
+ _enod[1] = _geom.
+ _tria.edge(_epos).node(1) ;
- real_type _xpos[3];
- bool_type _okay =
+ real_type _xpos[3] ;
+ bool_type _okay =
geometry::line_flat_3d (
this->_pmid,
this->_nvec,
&this->_geom.
- _tria._set1[_enod[0]].pval(0) ,
+ _tria.node( _enod[0]).pval(0) ,
&this->_geom.
- _tria._set1[_enod[1]].pval(0) ,
+ _tria.node( _enod[1]).pval(0) ,
_xpos, true);
if (_okay)
@@ -1607,11 +1669,11 @@
/*--------------- call output function on hit */
this->_hfun (_xpos, _HITS ,
_geom._tria .
- _set2[_epos].feat() ,
+ edge(_epos).feat() ,
_geom._tria .
- _set2[_epos].topo() ,
+ edge(_epos).topo() ,
_geom._tria .
- _set2[_epos].itag() ) ;
+ edge(_epos).itag() ) ;
this->_hnum+= +1 ;
@@ -1724,23 +1786,23 @@
continue ;
iptr_type _tnod[3];
- _tnod[0] =_geom.
- _tria._set3[_tpos].node(0) ;
- _tnod[1] =_geom.
- _tria._set3[_tpos].node(1) ;
- _tnod[2] =_geom.
- _tria._set3[_tpos].node(2) ;
+ _tnod[0] = _geom.
+ _tria.tri3(_tpos).node(0) ;
+ _tnod[1] = _geom.
+ _tria.tri3(_tpos).node(1) ;
+ _tnod[2] = _geom.
+ _tria.tri3(_tpos).node(2) ;
real_type _xpos[3];
_HITS = geometry::line_tria_3d (
& this->_ipos[0],
& this->_jpos[0],
&_geom ._tria.
- _set1 [_tnod[0]].pval(0),
+ node( _tnod[0] ).pval(0) ,
&_geom ._tria.
- _set1 [_tnod[1]].pval(0),
+ node( _tnod[1] ).pval(0) ,
&_geom ._tria.
- _set1 [_tnod[2]].pval(0),
+ node( _tnod[2] ).pval(0) ,
_xpos, true, 2 );
if(_HITS != geometry::null_hits)
@@ -1748,11 +1810,11 @@
/*--------------- call output function on hit */
this->_hfun (_xpos, _HITS ,
_geom._tria .
- _set3[_tpos].feat() ,
+ tri3(_tpos).feat() ,
_geom._tria .
- _set3[_tpos].topo() ,
+ tri3(_tpos).topo() ,
_geom._tria .
- _set3[_tpos].itag() ) ;
+ tri3(_tpos).itag() ) ;
this->_hnum+= +1 ;
@@ -1833,23 +1895,23 @@
iptr_type _epos =
_iptr->_data.ipos() ;
- iptr_type _enod[2];
- _enod[0] =_geom.
- _tria._set2[_epos].node(0) ;
- _enod[1] =_geom.
- _tria._set2[_epos].node(1) ;
+ iptr_type _enod[2] ;
+ _enod[0] = _geom.
+ _tria.edge(_epos).node(0) ;
+ _enod[1] = _geom.
+ _tria.edge(_epos).node(1) ;
- real_type _ipos[3];
- real_type _jpos[3];
- size_t _nhit =
+ real_type _ipos[3] ;
+ real_type _jpos[3] ;
+ size_t _nhit =
geometry::ball_line_3d (
this->_ball,
this->_rsiz,
&_geom ._tria.
- _set1 [_enod[0]].pval(0) ,
+ node( _enod[0] ).pval(0) ,
&_geom ._tria.
- _set1 [_enod[1]].pval(0) ,
- _ipos, _jpos ) ;
+ node( _enod[1] ).pval(0) ,
+ _ipos, _jpos );
switch (_nhit)
{
@@ -1858,11 +1920,11 @@
/*--------------- call output function on hit */
this->_hfun (_jpos, _HITS ,
_geom._tria .
- _set2[_epos].feat() ,
+ edge(_epos).feat() ,
_geom._tria .
- _set2[_epos].topo() ,
+ edge(_epos).topo() ,
_geom._tria .
- _set2[_epos].itag() ) ;
+ edge(_epos).itag() ) ;
this->_hnum += +1;
} // falls through
@@ -1871,11 +1933,11 @@
/*--------------- call output function on hit */
this->_hfun (_ipos, _HITS ,
_geom._tria .
- _set2[_epos].feat() ,
+ edge(_epos).feat() ,
_geom._tria .
- _set2[_epos].topo() ,
+ edge(_epos).topo() ,
_geom._tria .
- _set2[_epos].itag() ) ;
+ edge(_epos).itag() ) ;
this->_hnum += +1;
@@ -1951,13 +2013,13 @@
iptr_type _tpos =
_iptr->_data.ipos() ;
- iptr_type _tnod[3];
- _tnod[0] =_geom.
- _tria._set3[_tpos].node(0) ;
- _tnod[1] =_geom.
- _tria._set3[_tpos].node(1) ;
- _tnod[2] =_geom.
- _tria._set3[_tpos].node(2) ;
+ iptr_type _tnod[3] ;
+ _tnod[0] = _geom.
+ _tria.tri3(_tpos).node(0) ;
+ _tnod[1] = _geom.
+ _tria.tri3(_tpos).node(1) ;
+ _tnod[2] = _geom.
+ _tria.tri3(_tpos).node(2) ;
real_type _apos[3] ;
real_type _bpos[3] ;
@@ -1968,18 +2030,18 @@
this->_cmid ,
this->_nvec ,
&_geom ._tria.
- _set1 [_tnod[0]].pval(0) ,
+ node( _tnod[0] ).pval(0) ,
&_geom ._tria.
- _set1 [_tnod[1]].pval(0) ,
+ node( _tnod[1] ).pval(0) ,
&_geom ._tria.
- _set1 [_tnod[2]].pval(0) ,
+ node( _tnod[2] ).pval(0) ,
_apos, _bpos))
/*--------------- circ-tria intersection test */
_nh=geometry::ball_line_3d (
this->_cmid ,
this->_rsiz ,
_apos, _bpos ,
- _ipos, _jpos ) ;
+ _ipos, _jpos ) ;
switch (_nh)
{
@@ -1988,22 +2050,22 @@
/*--------------- call output function on hit */
this->_hfun (_jpos, _HITS ,
_geom._tria .
- _set3[_tpos].feat() ,
+ tri3(_tpos).feat() ,
_geom._tria .
- _set3[_tpos].topo() ,
+ tri3(_tpos).topo() ,
_geom._tria .
- _set3[_tpos].itag() ) ;
+ tri3(_tpos).itag() ) ;
} // falls through
case +1 :
{
/*--------------- call output function on hit */
this->_hfun (_ipos, _HITS ,
_geom._tria .
- _set3[_tpos].feat() ,
+ tri3(_tpos).feat() ,
_geom._tria .
- _set3[_tpos].topo() ,
+ tri3(_tpos).topo() ,
_geom._tria .
- _set3[_tpos].itag() ) ;
+ tri3(_tpos).itag() ) ;
this->_find = true ;
} // falls through
@@ -2067,18 +2129,18 @@
iptr_type _enod[+2] = {
this->_mesh->
- _set2 [_EPOS ].node(0) ,
+ edge (_EPOS ).node(0) ,
this->_mesh->
- _set2 [_EPOS ].node(1) ,
+ edge (_EPOS ).node(1) ,
} ;
if (geometry::proj_line_3d (
_ppos,
&this->_mesh->
- _set1 [_enod[0]].pval(0) ,
+ node (_enod[0]).pval(0) ,
&this->_mesh->
- _set1 [_enod[1]].pval(0) ,
- _qtmp, _HITS) )
+ node (_enod[1]).pval(0) ,
+ _qtmp, _HITS) )
{
if (_HITS !=
geometry::null_hits)
@@ -2164,22 +2226,22 @@
iptr_type _tnod[+3] = {
this->_mesh->
- _set3 [_TPOS ].node(0) ,
+ tri3 (_TPOS ).node(0) ,
this->_mesh->
- _set3 [_TPOS ].node(1) ,
+ tri3 (_TPOS ).node(1) ,
this->_mesh->
- _set3 [_TPOS ].node(2) ,
+ tri3 (_TPOS ).node(2) ,
} ;
if (geometry::proj_tria_3d (
_ppos,
&this->_mesh->
- _set1 [_tnod[0]].pval(0) ,
+ node (_tnod[0]).pval(0) ,
&this->_mesh->
- _set1 [_tnod[1]].pval(0) ,
+ node (_tnod[1]).pval(0) ,
&this->_mesh->
- _set1 [_tnod[2]].pval(0) ,
- _qtmp, _HITS) )
+ node (_tnod[2]).pval(0) ,
+ _qtmp, _HITS) )
{
if (_HITS !=
geometry::null_hits)
@@ -2250,17 +2312,39 @@
} ;
float _RMIN[3] = {
- (float) _flat. _rmin[0] ,
- (float) _flat. _rmin[1] ,
- (float) _flat. _rmin[2] ,
+ (float) _flat. _ppos[0] ,
+ (float) _flat. _ppos[1] ,
+ (float) _flat. _ppos[2] ,
} ;
float _RMAX[3] = {
- (float) _flat. _rmax[0] ,
- (float) _flat. _rmax[1] ,
- (float) _flat. _rmax[2] ,
+ (float) _flat. _ppos[0] ,
+ (float) _flat. _ppos[1] ,
+ (float) _flat. _ppos[2] ,
} ;
+ for ( auto
+ _iter = _flat._bnds.head() ;
+ _iter != _flat._bnds.tend() ;
+ ++_iter )
+ {
+ auto _circ = *_iter;
+
+ _RMIN[0] = std::min(
+ _RMIN[0] , (float) _circ[0]) ;
+ _RMIN[1] = std::min(
+ _RMIN[1] , (float) _circ[1]) ;
+ _RMIN[2] = std::min(
+ _RMIN[2] , (float) _circ[2]) ;
+
+ _RMAX[0] = std::max(
+ _RMAX[0] , (float) _circ[0]) ;
+ _RMAX[1] = std::max(
+ _RMAX[1] , (float) _circ[1]) ;
+ _RMAX[2] = std::max(
+ _RMAX[2] , (float) _circ[2]) ;
+ }
+
/*------------------ call actual intersection testing */
tree_pred _pred(_PPOS, _NVEC,
_RMIN, _RMAX) ;
diff --git a/external/jigsaw/src/libcpp/geometry.hpp b/external/jigsaw/src/libcpp/geometry.hpp
index ccf9e75..56a2124 100644
--- a/external/jigsaw/src/libcpp/geometry.hpp
+++ b/external/jigsaw/src/libcpp/geometry.hpp
@@ -35,7 +35,7 @@
*
* Copyright 2013-2017
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
------------------------------------------------------------
@@ -46,21 +46,21 @@
# ifndef __GEOMETRY__
# define __GEOMETRY__
-# include "libbasic.hpp"
+# include "basebase.hpp"
+
# include "mpfloats.hpp"
+# include "geompred.hpp"
+
# include "mathutil.hpp"
# include "geom_base/vect_base_k.hpp"
-# include "geom_base/predicate_k.hpp"
-
# include "geom_base/intersect_k.hpp"
-# include "geom_base/tria_ball_k.hpp"
-# include "geom_base/tria_elem_k.hpp"
+# include "geom_base/cell_ball_k.hpp"
+# include "geom_base/cell_base_k.hpp"
-#
-# endif //__GEOMETRY__
+# endif//__GEOMETRY__
diff --git a/external/jigsaw/src/libcpp/geompred.hpp b/external/jigsaw/src/libcpp/geompred.hpp
new file mode 100644
index 0000000..d4965a6
--- /dev/null
+++ b/external/jigsaw/src/libcpp/geompred.hpp
@@ -0,0 +1,59 @@
+
+/*
+------------------------------------------------------------
+ * robust geometric predicates, a'la shewchuk
+------------------------------------------------------------
+ *
+ * This program may be freely redistributed under the
+ * condition that the copyright notices (including this
+ * entire header) are not removed, and no compensation
+ * is received through use of the software. Private,
+ * research, and institutional use is free. You may
+ * distribute modified versions of this code UNDER THE
+ * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE
+ * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE
+ * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE
+ * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR
+ * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution
+ * of this code as part of a commercial system is
+ * permissible ONLY BY DIRECT ARRANGEMENT WITH THE
+ * AUTHOR. (If you are not directly supplying this
+ * code to a customer, and you are instead telling them
+ * how they can obtain it for free, then you are not
+ * required to make any arrangement with me.)
+ *
+ * Disclaimer: Neither I nor: Columbia University, The
+ * Massachusetts Institute of Technology, The
+ * University of Sydney, nor The National Aeronautics
+ * and Space Administration warrant this code in any
+ * way whatsoever. This code is provided "as-is" to be
+ * used at your own risk.
+ *
+------------------------------------------------------------
+ *
+ * Last updated: 01 March, 2020
+ *
+ * Copyright 2020--
+ * Darren Engwirda
+ * d.engwirda@gmail.com
+ * https://github.com/dengwirda/
+ *
+------------------------------------------------------------
+ */
+
+# pragma once
+
+# ifndef __PREDICATES__
+# define __PREDICATES__
+
+# include "basebase.hpp"
+# include "mpfloats.hpp"
+
+# include
+
+# include "predicate/predicate_k.hpp"
+
+# endif//__PREDICATES__
+
+
+
diff --git a/external/jigsaw/src/libcpp/geomtype.hpp b/external/jigsaw/src/libcpp/geomtype.hpp
index 5448638..4722cef 100644
--- a/external/jigsaw/src/libcpp/geomtype.hpp
+++ b/external/jigsaw/src/libcpp/geomtype.hpp
@@ -31,11 +31,11 @@
*
------------------------------------------------------------
*
- * Last updated: 09 January, 2019
+ * Last updated: 20 February, 2020
*
- * Copyright 2013-2019
+ * Copyright 2013-2020
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
------------------------------------------------------------
@@ -49,10 +49,10 @@
namespace mesh
{
/*-------------------------- classification of mesh feat. */
- char_type null_feat = 0 ;
- char_type user_feat = 1 ;
- char_type soft_feat = 2 ;
- char_type hard_feat = 3 ;
+ char_type constexpr null_feat = 0 ;
+ char_type constexpr user_feat = 1 ;
+ char_type constexpr soft_feat = 2 ;
+ char_type constexpr hard_feat = 3 ;
}
# include "containers.hpp"
@@ -62,6 +62,8 @@
# include "aabbtree.hpp"
# include "meshtype.hpp"
+# include "rdel_mesh/rdel_filt_k.hpp"
+
# include "geom_type/geom_base_2.hpp"
# include "geom_type/geom_base_3.hpp"
diff --git a/external/jigsaw/src/libcpp/hashfunc.hpp b/external/jigsaw/src/libcpp/hashfunc.hpp
index d412de7..65b164a 100644
--- a/external/jigsaw/src/libcpp/hashfunc.hpp
+++ b/external/jigsaw/src/libcpp/hashfunc.hpp
@@ -40,7 +40,7 @@ on 1 byte), but shoehorning those bytes into integers efficiently is messy.
#ifndef __HASHFUNC__
#define __HASHFUNC__
-#include "libbasic.hpp"
+#include "basebase.hpp"
namespace hash {
diff --git a/external/jigsaw/src/libcpp/iter_mesh/iter_divs_2.inc b/external/jigsaw/src/libcpp/iter_mesh/iter_divs_2.inc
index bab7e56..ca684b7 100644
--- a/external/jigsaw/src/libcpp/iter_mesh/iter_divs_2.inc
+++ b/external/jigsaw/src/libcpp/iter_mesh/iter_divs_2.inc
@@ -31,11 +31,11 @@
*
--------------------------------------------------------
*
- * Last updated: 27 October, 2019
+ * Last updated: 12 Sept., 2020
*
- * Copyright 2013-2019
+ * Copyright 2013-2020
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
--------------------------------------------------------
@@ -54,72 +54,73 @@
__normal_call void_type _div_edge (
geom_type &_geom ,
mesh_type &_mesh ,
- size_type &_hfun ,
- pred_type &_pred ,
+ hfun_type &_hfun ,
real_list &_hval ,
iter_opts &_opts ,
+ iptr_type _iout ,
iptr_type _enum ,
char_type _kern ,
bool_type &_okay ,
iptr_type &_inew ,
- iptr_list &_tset ,
- iptr_list &_tnew ,
- real_list &_tsrc ,
- real_list &_tdst ,
- real_list &_ttmp ,
- real_type _TLIM ,
+ conn_list &_cset ,
+ conn_list &_cnew ,
+ conn_list &_iset ,
+ conn_list &_jset ,
+ real_list &_qsrc ,
+ real_list &_qdst ,
+ real_list &_qtmp ,
+ real_type _QLIM ,
real_type _lmin
= (real_type) +1.00E+00 ,
real_type _qinc
= (real_type) +1.00E-02
)
{
- __unreferenced(_pred) ; // for MSVC...
- __unreferenced(_opts) ;
+ iptr_type static constexpr
+ _last = pred_type::geom_dims+0 ;
+
+ // iptr_type static constexpr
+ // _DEG_TRIA3 = (iptr_type)+6 ;
+ // iptr_type static constexpr
+ // _DEG_QUAD4 = (iptr_type)+4 ;
/*--------------------------------- get edge indexing */
- auto _edge =
- _mesh._set2.head() + _enum ;
+ auto _eptr =
+ _mesh. edge().head()+_enum ;
iptr_type _enod[2] ;
- _enod[ 0] = _edge->node(0) ;
- _enod[ 1] = _edge->node(1) ;
+ _enod[ 0] = _eptr->node(0) ;
+ _enod[ 1] = _eptr->node(1) ;
auto _iptr = _mesh.
- _set1.head()+ _edge->node(0) ;
+ node().head() + _eptr->node(0);
auto _jptr = _mesh.
- _set1.head()+ _edge->node(1) ;
+ node().head() + _eptr->node(1);
- _tset.set_count(+0);
- _tnew.set_count(+0);
+ _cset.set_count(+0);
+ _cnew.set_count(+0);
+ _iset.set_count(+0);
+ _jset.set_count(+0);
- _mesh.edge_tri3(_enum,_tset) ;
+ _mesh.connect_2(
+ _enum, EDGE2_tag, _cset) ;
_okay = false ;
- if (_tset.count()!=2) return ;
+ if (_cset.count()<=1) return ;
/*--------------------------------- get edge h-sizing */
- real_type _ipos[_dims] ;
- real_type _jpos[_dims] ;
- iptr_type _idim = +0;
- for (_idim = _dims+0; _idim-- != 0; )
- {
- _ipos[_idim] =
- _iptr->pval(_idim) ;
- _jpos[_idim] =
- _jptr->pval(_idim) ;
- }
-
- real_type _isiz =
- _hfun.eval(_ipos, _iptr->hidx ()) ;
- real_type _jsiz =
- _hfun.eval(_jpos, _jptr->hidx ()) ;
+ real_type _isiz, _jsiz ;
+ _isiz = _hfun.eval(
+ &_iptr->pval(0), _iptr->hidx()) ;
+ _jsiz = _hfun.eval(
+ &_jptr->pval(0), _jptr->hidx()) ;
- real_type _lsqr =
- _pred.length_sq(_ipos, _jpos) ;
+ real_type _lsqr =
+ pred_type::length_sq (
+ &_iptr->pval(0),&_jptr->pval(0)) ;
- real_type _hbar =
+ real_type _hbar =
std::max(_isiz , _jsiz);
/*--------------------------------- exit if too small */
@@ -127,260 +128,276 @@
_hbar * _lmin )
return ;
- /*--------------------------------- get adjacent face */
- auto _itri =
- _mesh._set3.head()+_tset[0];
- auto _jtri =
- _mesh._set3.head()+_tset[1];
-
- _tsrc.set_count(+2) ;
-
- _tsrc[0] = _pred.cost_tria (
- &_mesh._set1[
- _itri->node(0)].pval(0),
- &_mesh._set1[
- _itri->node(1)].pval(0),
- &_mesh._set1[
- _itri->node(2)].pval(0)
- ) ;
-
- _tsrc[1] = _pred.cost_tria (
- &_mesh._set1[
- _jtri->node(0)].pval(0),
- &_mesh._set1[
- _jtri->node(1)].pval(0),
- &_mesh._set1[
- _jtri->node(2)].pval(0)
- ) ;
-
- if (_tsrc[1] < _tsrc[0])
- std::swap(_itri, _jtri ) ;
+ /*--------------------------------- split if too long */
+ real_type static constexpr
+ _lBIG = (real_type)+7./5. ;
- real_type _TMIN = std::min (
- _tsrc[0] , _tsrc[1]) ;
+ if (_lsqr >= _hbar * _lBIG *
+ _hbar * _lBIG )
+ {
+ // if more regular geom. is constructed via the edge
+ // div, make it easier to do so!
- /*--------------------------------- exit if too good! */
- real_type _TURN =
- std::pow(_TLIM, +1./4.) ;
+ _qinc -= (real_type)+1./2. ;
- if (_TMIN>_TURN ) return ;
+ _qinc /= std::cbrt (_iout) ; // no oscl. wrt. zip
- /*--------------------------------- get adjacent ball */
- real_type _ibal[_dims+1] ;
- for(_idim = _dims+0; _idim-- != 0; )
- {
- _ibal[_idim] =
- _mesh._set1[
- _itri->node(0)].pval(_idim) +
- _mesh._set1[
- _itri->node(1)].pval(_idim) +
- _mesh._set1[
- _itri->node(2)].pval(_idim) ;
-
- _ibal[_idim]/=
- (real_type) +3.0 ;
}
-
- real_type _jbal[_dims+1] ;
- for(_idim = _dims+0; _idim-- != 0; )
+ else
{
- _jbal[_idim] =
- _mesh._set1[
- _jtri->node(0)].pval(_idim) +
- _mesh._set1[
- _jtri->node(1)].pval(_idim) +
- _mesh._set1[
- _jtri->node(2)].pval(_idim) ;
-
- _jbal[_idim]/=
- (real_type) +3.0 ;
- }
+ /*--------------------------------- get adjacent face */
+ _mesh.connect_2(_eptr->node(+0),
+ POINT_tag, _iset) ;
+ _mesh.connect_2(_eptr->node(+1),
+ POINT_tag, _jset) ;
- /*--------------------------------- get adjacent apex */
- iptr_type _inod [3] ;
- iptr_type _jnod [3] ;
- for(auto _inum = 3; _inum-- != 0; )
- {
- mesh_type::tri3_type::
- face_node(
- _inod, _inum, 2, 1) ;
- _inod[0] =
- _itri->node(_inod[0]);
- _inod[1] =
- _itri->node(_inod[1]);
- _inod[2] =
- _itri->node(_inod[2]);
-
- if (_inod[2] != _enod[0])
- if (_inod[2] != _enod[1])
- break ;
- }
- for(auto _inum = 3; _inum-- != 0; )
- {
- mesh_type::tri3_type::
- face_node(
- _jnod, _inum, 2, 1) ;
- _jnod[0] =
- _jtri->node(_jnod[0]);
- _jnod[1] =
- _jtri->node(_jnod[1]);
- _jnod[2] =
- _jtri->node(_jnod[2]);
-
- if (_jnod[2] != _enod[0])
- if (_jnod[2] != _enod[1])
- break ;
- }
+ /*--------------------------------- calc. local topo. */
+ if (_iset.count() <= +7) return;
+ if (_jset.count() <= +7) return;
- /*--------------------------------- push node to mesh */
- typename mesh_type
- ::node_type _ndat ;
- typename mesh_type
- ::tri3_type _tdat ;
+ } // if (_lBIG)
- _ndat.fdim() = +2;
- _ndat.feat() =
- mesh::null_feat;
+ /*--------------------------------- get adjacent cost */
+ real_type _qmin = loop_cost(
+ _mesh, _cset, _qsrc, cell_kind()) ;
- for(_idim = _dims+0; _idim-- != 0; )
+ /*--------------------------------- get adjacent ball */
+ real_type _ball[_last + 1] ;
+ for (auto _idim =
+ pred_type::real_dims; _idim-- != 0; )
{
- _ndat.pval(_idim)
- = (real_type) +0.0 ;
- _ndat.pval(_idim) +=
- _ibal[_idim] ;
- _ndat.pval(_idim) +=
- _jbal[_idim] ;
-
- _ndat.pval(_idim)
- /= (real_type) +2.0 ;
- }
-
- _ndat.pval(_dims) = (real_type)0. ;
- _ndat.pval(_dims) +=
- _iptr->pval(_dims) ;
- _ndat.pval(_dims) +=
- _jptr->pval(_dims) ;
-
- _ndat.pval(_dims) /= (real_type)2. ;
-
- _ndat.hidx() =
- size_type::null_hint() ;
-
- iptr_type _nnew =
- _mesh.push_node(_ndat) ;
-
- _inew = _nnew ;
-
- auto _nptr =
- _mesh._set1.head() + _nnew ;
-
- _hval.set_count(std::max (
- _nnew + 1,
- (iptr_type)_hval.count())) ;
-
- _hval[_nnew] = (real_type)-1. ;
-
- /*--------------------------------- redo mesh indexes */
- _tdat.node(0) = _nnew;
- _tdat.node(1) = _inod[ 2] ;
- _tdat.node(2) = _inod[ 0] ;
+ _ball[_idim] = (real_type) +0. ;
+ _ball[_idim] +=
+ _iptr->pval(_idim) ;
+ _ball[_idim] +=
+ _jptr->pval(_idim) ;
- _tdat.itag () = _itri->itag() ;
+ _ball[_idim] /= (real_type) +2. ;
+ }
- _tnew.push_tail(
- _mesh.push_tri3(_tdat)) ;
+ pred_type::
+ proj_node(_geom, _ball, _ball);
- _tdat.node(0) = _nnew;
- _tdat.node(1) = _inod[ 1] ;
- _tdat.node(2) = _inod[ 2] ;
+ /*--------------------------------- try to split edge */
+ # define NULLFEAT null_feat
+ # define NULLHINT hfun_type::null_hint()
- _tdat.itag () = _itri->itag() ;
+ typename mesh_type::node_type _ndat ;
- _tnew.push_tail(
- _mesh.push_tri3(_tdat)) ;
+ typename mesh_type::tri3_type _tdat ;
+ typename mesh_type::quad_type _qdat ;
- _tdat.node(0) = _nnew;
- _tdat.node(1) = _jnod[ 1] ;
- _tdat.node(2) = _jnod[ 2] ;
+ for (auto _idim =
+ pred_type::real_dims; _idim-- != 0; )
+ {
+ _ndat.pval(_idim) = _ball[_idim];
+ }
- _tdat.itag () = _jtri->itag() ;
+ _ndat.fdim() = (iptr_type) +2 ;
+ _ndat.feat() = NULLFEAT ;
+ _ndat.hidx() = NULLHINT ;
+ _inew = _mesh.push_node(_ndat);
- _tnew.push_tail(
- _mesh.push_tri3(_tdat)) ;
+ auto _nptr =
+ _mesh. node().head () + _inew ;
- _tdat.node(0) = _nnew;
- _tdat.node(1) = _jnod[ 2] ;
- _tdat.node(2) = _jnod[ 0] ;
+ _hval.set_count( std::max(
+ _inew + 1, (iptr_type)_hval.count())) ;
- _tdat.itag () = _jtri->itag() ;
+ _hval[_inew] = (real_type)-1. ;
- _tnew.push_tail(
- _mesh.push_tri3(_tdat)) ;
+ /*--------------------------------- push a new cavity */
+ for (auto _cell = _cset.head();
+ _cell != _cset.tend();
+ ++_cell )
+ {
+ if (_cell->_kind == TRIA3_tag)
+ {
+ /*--------------------------------- sub-div adj. tria */
+ auto _tptr =
+ _mesh. tri3().head()+_cell->_cell ;
+
+ iptr_type _ENOD[ 3], _ENUM, _TNUM ;
+ for(_ENUM = 3; _ENUM-- != 0; )
+ {
+ mesh_type::tri3_type::
+ face_node(_ENOD, _ENUM, 2, 1) ;
+ _ENOD[0] =
+ _tptr->node(_ENOD[0]);
+ _ENOD[1] =
+ _tptr->node(_ENOD[1]);
+ _ENOD[2] =
+ _tptr->node(_ENOD[2]);
+
+ if (_ENOD[2] != _enod[0])
+ if (_ENOD[2] != _enod[1])
+ break ;
+ }
+
+ /*--------------------------------- div into 2 tria's */
+ _tdat.node(0) = _inew;
+ _tdat.node(1) = _ENOD[2] ;
+ _tdat.node(2) = _ENOD[0] ;
+ _tdat.itag () = _tptr->itag () ;
+
+ _TNUM = _mesh.push_tri3(_tdat) ;
+
+ _cnew.push_tail(typename
+ conn_list::data_type(_TNUM,TRIA3_tag));
+
+ _tdat.node(0) = _inew;
+ _tdat.node(1) = _ENOD[1] ;
+ _tdat.node(2) = _ENOD[2] ;
+ _tdat.itag () = _tptr->itag () ;
+
+ _TNUM = _mesh.push_tri3(_tdat) ;
+
+ _cnew.push_tail(typename
+ conn_list::data_type(_TNUM,TRIA3_tag));
+ }
+ else
+ if (_cell->_kind == QUAD4_tag)
+ {
+ /*--------------------------------- sub-div adj. quad */
+ auto _qptr =
+ _mesh. quad().head()+_cell->_cell ;
+
+ iptr_type _ENOD[ 4], _ENUM, _TNUM ;
+ for(_ENUM = 4; _ENUM-- != 0; )
+ {
+ mesh_type::quad_type::
+ face_node(_ENOD, _ENUM, 2, 1) ;
+ _ENOD[0] =
+ _qptr->node(_ENOD[0]);
+ _ENOD[1] =
+ _qptr->node(_ENOD[1]);
+ _ENOD[2] =
+ _qptr->node(_ENOD[2]);
+ _ENOD[3] =
+ _qptr->node(_ENOD[3]);
+
+ if (_ENOD[2] != _enod[0])
+ if (_ENOD[2] != _enod[1])
+ if (_ENOD[3] != _enod[0])
+ if (_ENOD[3] != _enod[1])
+ break ;
+ }
+
+ /*--------------------------------- div into 3 tria's */
+ _tdat.node(0) = _inew;
+ _tdat.node(1) = _ENOD[3] ;
+ _tdat.node(2) = _ENOD[0] ;
+ _tdat.itag () = _qptr->itag () ;
+
+ _TNUM = _mesh.push_tri3(_tdat) ;
+
+ _cnew.push_tail(typename
+ conn_list::data_type(_TNUM,TRIA3_tag));
+
+ _tdat.node(0) = _inew;
+ _tdat.node(1) = _ENOD[2] ;
+ _tdat.node(2) = _ENOD[3] ;
+ _tdat.itag () = _qptr->itag () ;
+
+ _TNUM = _mesh.push_tri3(_tdat) ;
+
+ _cnew.push_tail(typename
+ conn_list::data_type(_TNUM,TRIA3_tag));
+
+ _tdat.node(0) = _inew;
+ _tdat.node(1) = _ENOD[1] ;
+ _tdat.node(2) = _ENOD[2] ;
+ _tdat.itag () = _qptr->itag () ;
+
+ _TNUM = _mesh.push_tri3(_tdat) ;
+
+ _cnew.push_tail(typename
+ conn_list::data_type(_TNUM,TRIA3_tag));
+ }
+ }
/*--------------------------------- optim. node coord */
iptr_type static
- constexpr _INUM = (iptr_type) +4 ;
+ constexpr _INUM = (iptr_type) +4;
- for (auto _iloc = +0; _iloc != _INUM ;
+ iptr_type _move = -1;
+ for (auto _iloc = +0; _iloc != _INUM;
++_iloc )
{
- iptr_type _move = (iptr_type) -1 ;
-
- _ttmp.set_count(0) ;
+ _qtmp.set_count(0) ;
real_type _minC =
- loop_cost( _mesh, _pred ,
- _tnew,
- _ttmp,
- tria_kind() ) ;
+ loop_cost( _mesh,
+ _cset, _qtmp, cell_kind()
+ ) ;
- move_node( _geom, _mesh ,
- _hfun, _pred, _hval ,
+ move_node( _geom, _mesh,
+ _hfun, _hval ,
_opts, _nptr, _kern,
- _move, _tnew,
- _ttmp, _tdst,
- _minC, _TLIM ) ;
+ _move, _cnew,
+ _qtmp, _qdst,
+ _minC, _QLIM ) ;
- if (_move <= +0) break ;
+ if (_move <= +0) break ;
}
- /*--------------------------------- compare cost scr. */
- _tdst.set_count(0) ;
+ /*--------------------------------- is cost improved? */
+ _qdst.set_count(0);
- loop_cost(_mesh, _pred, _tnew,
- _tdst,
- tria_kind() ) ;
+ real_type _QMIN =
+ loop_cost( _mesh,
+ _cnew, _qdst, cell_kind ()
+ ) ;
- move_okay(_tdst, _tsrc, _okay,
- _TURN,
- _qinc) ;
+ move_okay( _qdst, _qsrc, _move,
+ +1.0 , _qinc) ;
- if (_okay)
+ if((_okay = _move > 0 &&
+ _QMIN >= _qmin+_qinc))
{
/*--------------------------------- delete old cavity */
- for (auto _tria = _tset.head() ;
- _tria != _tset.tend() ;
- ++_tria )
+ for (auto _cell = _cset.head();
+ _cell != _cset.tend();
+ ++_cell )
{
- _mesh.
- _pop_tri3(* _tria) ;
+ if (_cell->_kind == TRIA3_tag)
+ {
+ _mesh.
+ _pop_tri3(_cell->_cell);
+ }
+ else
+ if (_cell->_kind == QUAD4_tag)
+ {
+ _mesh.
+ _pop_quad(_cell->_cell);
+ }
}
}
else
{
/*--------------------------------- delete new cavity */
- for (auto _tria = _tnew.head() ;
- _tria != _tnew.tend() ;
- ++_tria )
+ for (auto _cell = _cnew.head();
+ _cell != _cnew.tend();
+ ++_cell )
{
- _mesh.
- _pop_tri3(* _tria) ;
+ if (_cell->_kind == TRIA3_tag)
+ {
+ _mesh.
+ _pop_tri3(_cell->_cell);
+ }
+ else
+ if (_cell->_kind == QUAD4_tag)
+ {
+ _mesh.
+ _pop_quad(_cell->_cell);
+ }
}
- _mesh.
- _pop_node(& _nnew) ;
+ _mesh._pop_node ( &_inew ) ;
}
+ # undef NULLHINT
+ # undef NULLFEAT
}
diff --git a/external/jigsaw/src/libcpp/iter_mesh/iter_divs_3.inc b/external/jigsaw/src/libcpp/iter_mesh/iter_divs_3.inc
index 7a417e1..5eba1ae 100644
--- a/external/jigsaw/src/libcpp/iter_mesh/iter_divs_3.inc
+++ b/external/jigsaw/src/libcpp/iter_mesh/iter_divs_3.inc
@@ -1,7 +1,7 @@
/*
--------------------------------------------------------
- * ITER-DIVS-2: optim. schemes to split edges.
+ * ITER-DIVS-3: optim. schemes to split edges.
--------------------------------------------------------
*
* This program may be freely redistributed under the
@@ -35,7 +35,7 @@
*
* Copyright 2013-2018
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
--------------------------------------------------------
@@ -50,81 +50,4 @@
--------------------------------------------------------
*/
- __static_call
- __normal_call void_type _div_edge_3 (
- geom_type &_geom ,
- mesh_type &_mesh ,
- size_type &_hfun ,
- pred_type &_pred ,
- real_list &_hval ,
- iter_opts &_opts ,
- iptr_type _enum ,
- bool_type &_okay ,
- iptr_list &_tset ,
- real_list &_csrc ,
- real_list &_cdst ,
- real_type _lmin
- = (real_type) +0.67E+00,
- real_type _good
- = (real_type) +9.25E-01,
- real_type _qinc
- = (real_type) +1.00E-08
- )
- {
- __unreferenced(_pred) ; // for MSVC...
- __unreferenced(_opts) ;
-
- /*--------------------------------- get edge indexing */
- auto _edge =
- _mesh._set2.head() + _enum ;
-
- iptr_type _enod[2] ;
- _enod[ 0] = _edge->node(0) ;
- _enod[ 1] = _edge->node(1) ;
-
- auto _iptr = _mesh.
- _set1.head()+ _edge->node(0) ;
- auto _jptr = _mesh.
- _set1.head()+ _edge->node(1) ;
-
- _tset.set_count(+0);
- _mesh.edge_tri4(_enum, _tset);
-
- _okay = false ;
-
- /*--------------------------------- get edge h-sizing */
- real_type _ipos[_dims] ;
- real_type _jpos[_dims] ;
- iptr_type _idim = +0;
- for (_idim = _dims+0; _idim-- != 0; )
- {
- _ipos[_idim] =
- _iptr->pval(_idim) ;
- _jpos[_idim] =
- _jptr->pval(_idim) ;
- }
-
- real_type _isiz =
- _hfun.eval(_ipos, _iptr->hidx ()) ;
- real_type _jsiz =
- _hfun.eval(_jpos, _jptr->hidx ()) ;
-
- real_type _lsqr =
- _pred.length_sq(_ipos, _jpos) ;
-
- real_type _hbar =
- std::min(_isiz , _jsiz);
-
- /*--------------------------------- exit if too small */
- if (_lsqr <= _hbar * _lmin *
- _hbar * _lmin )
- return ;
-
- /*--------------------------------- get adjacent face */
-
-
-
- }
-
-
diff --git a/external/jigsaw/src/libcpp/iter_mesh/iter_dual_2.inc b/external/jigsaw/src/libcpp/iter_mesh/iter_dual_2.inc
index 9b9d868..3c2b6d0 100644
--- a/external/jigsaw/src/libcpp/iter_mesh/iter_dual_2.inc
+++ b/external/jigsaw/src/libcpp/iter_mesh/iter_dual_2.inc
@@ -31,11 +31,11 @@
*
--------------------------------------------------------
*
- * Last updated: 27 October, 2019
+ * Last updated: 30 April, 2020
*
- * Copyright 2013-2019
+ * Copyright 2013-2020
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
--------------------------------------------------------
@@ -46,7 +46,7 @@
/*
--------------------------------------------------------
- * DQDW-MOVE: "local-ascent" weight movement vector.
+ * DQDW-TRI3: "local-ascent" node movement vector.
--------------------------------------------------------
*/
@@ -54,209 +54,359 @@
typename node_iter
>
__static_call
- __normal_call void_type dqdw_move_2 (
- geom_type &_geom ,
+ __normal_call void_type dqdw_tri3_k (
mesh_type &_mesh ,
- size_type &_hfun ,
- pred_type &_pred ,
- iptr_list &_tset ,
+ iptr_type _cell ,
node_iter _node ,
- real_list &_cost ,
- real_type &_step ,
- real_type &_wadj
+ real_type _COST ,
+ real_type _STEP ,
+ real_type _SAVE ,
+ real_type &_DQDW
)
{
+ iptr_type static constexpr
+ _last = pred_type::geom_dims + 0 ;
+
real_type static const _WINC =
std::pow(std::numeric_limits
- ::epsilon(), +.50) ;
+ ::epsilon(), .50) ;
real_type static const _RMIN =
std::pow(std::numeric_limits
- ::epsilon(), +.75) ;
+ ::epsilon(), .75) ;
real_type static const _RMAX =
std::pow(std::numeric_limits
- ::epsilon(), +.25) ;
+ ::epsilon(), .25) ;
- __unreferenced(_geom);
- __unreferenced(_hfun);
+ /*------------------------------------- cell indexing */
+ auto _ppos = &_node->pval(0);
- /*------------------ calc. local characteristic scale */
- real_type _qmin =
- +std::numeric_limits
- ::infinity();
+ auto _tptr =
+ _mesh. tri3().head() + _cell ;
+
+ /*------------------ local iter. on finite-diff. step */
+ real_type _wdel = _WINC * _STEP;
- iptr_type _tnum = +0 ;
+ real_type _wsum = (real_type)0.;
- _step = (real_type)0.;
- _wadj = (real_type)0.;
+ real_type _sdel = (real_type)0.;
+ real_type _sabs = (real_type)0.;
+ real_type _sbar = (real_type)0.;
- for (auto _tria = _tset.head(),
- _tend = _tset.tend();
- _tria != _tend;
- ++_tria, ++_tnum)
+ for (auto _iter = +0; _iter++ != +2; )
{
- auto _tptr =
- _mesh._set3.head()+*_tria;
+ /*------------------ centred finite-diff. for dQ / dw */
+ _ppos[_last] = _SAVE + _wdel;
+
+ _wsum = (real_type)+0. ;
+ _wsum += _ppos[_last] - _SAVE;
+
+ real_type _scr1 =
+ pred_type::tri3_cost (
+ &_mesh. node(
+ _tptr->node(0)).pval(0),
+ &_mesh. node(
+ _tptr->node(1)).pval(0),
+ &_mesh. node(
+ _tptr->node(2)).pval(0),
+ typename
+ pred_type::dual_kind ()
+ ) ;
+
+ _ppos[_last] = _SAVE - _wdel;
+
+ _wsum -= _ppos[_last] - _SAVE;
+
+ real_type _scr0 =
+ pred_type::tri3_cost (
+ &_mesh. node(
+ _tptr->node(0)).pval(0),
+ &_mesh. node(
+ _tptr->node(1)).pval(0),
+ &_mesh. node(
+ _tptr->node(2)).pval(0),
+ typename
+ pred_type::dual_kind ()
+ ) ;
+
+ _sdel = _scr1 - _scr0 ;
+
+ _sbar = std::abs(_COST) ;
+ _sabs = std::abs(_sdel) ;
+
+ /*------------------ try to adjust step on rel. diff. */
+ if (_sabs > (real_type)0.)
+ {
+ if (_sabs > _RMAX * _sbar)
+ {
+ _wdel/= (real_type) +10. ;
+ }
+ else
+ if (_sabs < _RMIN * _sbar)
+ {
+ _wdel*= (real_type) +10. ;
+ }
+ else { break ; }
+ }
+ else { break ; }
+ }
- iptr_type _tnod[3] ;
- _tnod[ 0] = _tptr->node( 0) ;
- _tnod[ 1] = _tptr->node( 1) ;
- _tnod[ 2] = _tptr->node( 2) ;
+ _ppos [_last] = _SAVE ;
- algorithms::isort(
- &_tnod[0], &_tnod[3],
- std::less()) ;
+ /*------------------ finalise gradient and accumulate */
- auto _inod =
- _mesh._set1.head()+_tnod[0] ;
- auto _jnod =
- _mesh._set1.head()+_tnod[1] ;
- auto _knod =
- _mesh._set1.head()+_tnod[2] ;
+ _DQDW += _sdel / _wsum ;
+ }
- _qmin = std::min(
- _qmin, _cost[_tnum]) ;
+ /*
+ --------------------------------------------------------
+ * DQDW-QUAD: "local-ascent" node movement vector.
+ --------------------------------------------------------
+ */
- real_type _ball[_dims+1] ;
- _pred.circ_ball(_ball,
- &_inod->pval(0),
- &_jnod->pval(0),
- &_knod->pval(0) ) ;
+ template <
+ typename node_iter
+ >
+ __static_call
+ __normal_call void_type dqdw_quad_k (
+ mesh_type &_mesh ,
+ iptr_type _cell ,
+ node_iter _node ,
+ real_type _COST ,
+ real_type _STEP ,
+ real_type _SAVE ,
+ real_type &_DQDW
+ )
+ {
+ iptr_type static constexpr
+ _last = pred_type::geom_dims + 0 ;
+
+ real_type static const _WINC =
+ std::pow(std::numeric_limits
+ ::epsilon(), .50) ;
+
+ real_type static const _RMIN =
+ std::pow(std::numeric_limits
+ ::epsilon(), .75) ;
- _wadj += _ball[_dims] ; // ball-rad.^2
+ real_type static const _RMAX =
+ std::pow(std::numeric_limits
+ ::epsilon(), .25) ;
+
+ /*------------------------------------- cell indexing */
+ auto _ppos = &_node->pval(0);
+
+ auto _qptr =
+ _mesh. quad().head() + _cell ;
+
+ /*------------------ local iter. on finite-diff. step */
+ real_type _wdel = _WINC * _STEP;
+
+ real_type _wsum = (real_type)0.;
+
+ real_type _sdel = (real_type)0.;
+ real_type _sabs = (real_type)0.;
+ real_type _sbar = (real_type)0.;
+
+ for (auto _iter = +0; _iter++ != +2; )
+ {
+ /*------------------ centred finite-diff. for dQ / dw */
+ _ppos[_last] = _SAVE + _wdel;
+
+ _wsum = (real_type)+0. ;
+ _wsum += _ppos[_last] - _SAVE;
+
+ real_type _scr1 =
+ pred_type::quad_cost (
+ &_mesh. node(
+ _qptr->node(0)).pval(0),
+ &_mesh. node(
+ _qptr->node(1)).pval(0),
+ &_mesh. node(
+ _qptr->node(2)).pval(0),
+ &_mesh. node(
+ _qptr->node(3)).pval(0),
+ typename
+ pred_type::dual_kind ()
+ ) ;
+
+ _ppos[_last] = _SAVE - _wdel;
+
+ _wsum -= _ppos[_last] - _SAVE;
+
+ real_type _scr0 =
+ pred_type::quad_cost (
+ &_mesh. node(
+ _qptr->node(0)).pval(0),
+ &_mesh. node(
+ _qptr->node(1)).pval(0),
+ &_mesh. node(
+ _qptr->node(2)).pval(0),
+ &_mesh. node(
+ _qptr->node(3)).pval(0),
+ typename
+ pred_type::dual_kind ()
+ ) ;
+
+ _sdel = _scr1 - _scr0 ;
+
+ _sbar = std::abs(_COST) ;
+ _sabs = std::abs(_sdel) ;
+
+ /*------------------ try to adjust step on rel. diff. */
+ if (_sabs > (real_type)0.)
+ {
+ if (_sabs > _RMAX * _sbar)
+ {
+ _wdel/= (real_type) +10. ;
+ }
+ else
+ if (_sabs < _RMIN * _sbar)
+ {
+ _wdel*= (real_type) +10. ;
+ }
+ else { break ; }
+ }
+ else { break ; }
}
- _wadj /= _tset.count () ;
+ _ppos [_last] = _SAVE ;
+
+ /*------------------ finalise gradient and accumulate */
- /*------------------ adj. gradients w.r.t. W: dQ / dw */
- real_type _qbar, _qlow, _dqdw;
- _qbar = (real_type) +1. ;
- _qlow = (real_type) +0. ;
- _dqdw = (real_type) +0. ;
+ _DQDW += _sdel / _wsum ;
+ }
- iptr_type _lnum = +0 ;
- iptr_type _hnum = +1 ;
+ /*
+ --------------------------------------------------------
+ * DQDW-MOVE: "local-ascent" node movement vector.
+ --------------------------------------------------------
+ */
- real_type _save =
- _node->pval (_dims);
+ // Shift weight via gradients of quality functions
- real_type _qlim = _qmin +
- (real_type) +1.0E-002 ;
+ // wnew <=== wold + beta * BEST[ d./dw Q(x,w)|_i ]
- _tnum = (iptr_type) +0 ;
- for (auto _tria = _tset.head(),
- _tend = _tset.tend();
- _tria != _tend;
- ++_tria, ++_tnum)
+ template <
+ typename node_iter
+ >
+ __static_call
+ __normal_call void_type dqdw_move_2 (
+ mesh_type &_mesh ,
+ conn_list &_conn ,
+ node_iter _node ,
+ real_list &_cost ,
+ real_type &_step ,
+ real_type &_wadj
+ )
+ {
+ iptr_type static constexpr
+ _last = pred_type::geom_dims + 0 ;
+
+ real_type static const _WINC =
+ std::pow(std::numeric_limits
+ ::epsilon(), .50) ;
+
+ _step = (real_type) 0. ;
+ _wadj = (real_type) 0. ;
+
+ /*------------------ calc. local characteristic scale */
+ real_type _qmin =
+ +std::numeric_limits::infinity();
+
+ real_type _bmin[_last] = {
+ +std::numeric_limits::infinity()
+ } ;
+ real_type _bmax[_last] = {
+ -std::numeric_limits::infinity()
+ } ;
+
+ iptr_type _cnum = + 0 ;
+ for (auto _next = _conn.head() ,
+ _tend = _conn.tend() ;
+ _next != _tend ;
+ ++_next, ++_cnum )
{
- auto _tptr =
- _mesh._set3.head()+*_tria ;
+ auto _cell = _next->_cell ;
+ auto _kind = _next->_kind ;
- real_type _qtri = _cost[_tnum] ;
- real_type _DQDW ;
+ _qmin = std::min(
+ _qmin, _cost [_cnum]) ;
- /*-------------- only do gradients for 'poor' set */
- if (_qtri <= _qlim)
+ if (_kind == TRIA3_tag)
+ {
+ halo_tri3_k(_mesh,
+ _cell , _node, _bmin, _bmax,
+ _wadj ) ;
+ }
+ else
+ if (_kind == QUAD4_tag)
{
- real_type _hsum = (real_type)0.;
+ halo_quad_k(_mesh,
+ _cell , _node, _bmin, _bmax,
+ _wadj ) ;
+ }
+ }
- real_type _wdel = _WINC*_wadj;
+ _wadj = _wadj / _cnum ;
- real_type _sdel = (real_type)0.;
- real_type _sabs = (real_type)0.;
- real_type _sbar = (real_type)0.;
+ /*------------------ adj. gradients wrt. pos: dQ / dx */
+ real_type _qlim = _qmin +
+ (real_type)+1.0E-002 ;
- /*---------- local iter. on finite-diff. step */
- for (auto _iter = +0; _iter++ != +2; )
- {
+ real_type _DQDW = (real_type) 0.;
- /*------ centred finite-diff. for dQ / dw */
- _node->pval(_dims) =
- _save + _wdel;
-
- _hsum = (real_type)+0.;
- _hsum += _node->
- pval(_dims) - _save;
-
- real_type _scr1 =
- _pred.cost_dual (
- &_mesh._set1[
- _tptr->node(0)].pval(0),
- &_mesh._set1[
- _tptr->node(1)].pval(0),
- &_mesh._set1[
- _tptr->node(2)].pval(0)) ;
-
- _node->pval(_dims) =
- _save - _wdel;
-
- _hsum -= _node->
- pval(_dims) - _save;
-
- real_type _scr0 =
- _pred.cost_dual (
- &_mesh._set1[
- _tptr->node(0)].pval(0),
- &_mesh._set1[
- _tptr->node(1)].pval(0),
- &_mesh._set1[
- _tptr->node(2)].pval(0)) ;
-
- _sbar = _cost[_tnum];
-
- _sdel = _scr1-_scr0 ;
-
- _sbar = std::abs(_sbar) ;
- _sabs = std::abs(_sdel) ;
-
- _node->pval(_dims) =
- _save;
-
- /*------ try to adjust step on rel. diff. */
- if (_sabs > (real_type)0.)
- {
- if (_sabs > _RMAX * _sbar)
- {
- _wdel *=
- (real_type) +.10 ;
- }
- else
- if (_sabs < _RMIN * _sbar)
- {
- _wdel *=
- (real_type) +10. ;
- }
- else { break ; }
- }
- else { break ; }
- }
+ real_type _SAVE =
+ _node->pval (_last) ;
+
+ real_type _qbar = (real_type) 1.;
+ real_type _qlow = (real_type) 0.;
- _node->pval(_dims) = _save ;
+ iptr_type _lnum = 0, _hnum = 1, _nnum = 0;
+ for (auto _next = _conn.head() ,
+ _tend = _conn.tend() ;
+ _next != _tend ;
+ ++_next, ++_nnum )
+ {
+ auto _cell = _next->_cell ;
+ auto _kind = _next->_kind ;
- /*---------- finalise gradient and accumulate */
- _DQDW = _sdel / _hsum ;
+ auto _COST = _cost [_nnum];
- _dqdw += _DQDW;
+ if (_COST <= _qlim)
+ {
+ if (_kind == TRIA3_tag)
+ {
+ dqdw_tri3_k(_mesh, _cell,
+ _node , _COST, _wadj, _SAVE,
+ _DQDW ) ;
+ }
+ else
+ if (_kind == QUAD4_tag)
+ {
+ dqdw_quad_k(_mesh, _cell,
+ _node , _COST, _wadj, _SAVE,
+ _DQDW ) ;
+ }
- _qlow += _qtri; _lnum += 1 ;
+ _qlow += _COST ; _lnum += +1 ;
}
else
{
- /*---------- accumulate metrics in 'good' set */
- _qbar += _qtri; _hnum += 1 ;
+ _qbar += _COST ; _hnum += +1 ;
}
}
- if (_tnum > +0)
+ if (_nnum > +0)
{
- _dqdw /= _lnum ;
+ _DQDW /= _lnum ;
_qlow /= _lnum ;
_qbar /= _hnum ;
}
/*------------------ 1st ord. Taylor-series step est. */
- real_type _scal = std::abs (_dqdw) ;
+ real_type _scal = std::abs (_DQDW) ;
if (_scal*_wadj <= _WINC)
{
@@ -264,9 +414,9 @@
}
else
{
- _step = (_qbar-_qlow) / _dqdw ;
+ _step = (_qbar-_qlow) / _DQDW ;
- _step*= (real_type)+.50 ;
+ _step/= (real_type) +2. ;
}
if (_step > (real_type) +0. )
diff --git a/external/jigsaw/src/libcpp/iter_mesh/iter_dual_3.inc b/external/jigsaw/src/libcpp/iter_mesh/iter_dual_3.inc
index bcd80a9..5d85728 100644
--- a/external/jigsaw/src/libcpp/iter_mesh/iter_dual_3.inc
+++ b/external/jigsaw/src/libcpp/iter_mesh/iter_dual_3.inc
@@ -35,7 +35,7 @@
*
* Copyright 2013-2018
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
--------------------------------------------------------
@@ -44,234 +44,4 @@
// from iter_mesh_k.hpp
- /*
- --------------------------------------------------------
- * GRAD-DUAL: "local-ascent" weight movement vector.
- --------------------------------------------------------
- */
-
- template <
- typename node_iter
- >
- __static_call
- __normal_call void_type grad_dual_3 (
- geom_type &_geom ,
- mesh_type &_mesh ,
- size_type &_hfun ,
- pred_type &_pred ,
- iptr_list &_tset ,
- node_iter _node ,
- real_list &_cost ,
- real_type &_line ,
- real_type &_ladj
- )
- {
- real_type static const _ZERO =
- std::pow(std::numeric_limits
- ::epsilon(), +.80) ;
-
- real_type static const _WINC =
- std::pow(std::numeric_limits
- ::epsilon(), +.50) ;
-
- real_type static const _RMIN =
- std::pow(std::numeric_limits
- ::epsilon(), +.75) ;
-
- real_type static const _RMAX =
- std::pow(std::numeric_limits
- ::epsilon(), +.25) ;
-
- real_type _qmin =
- +std::numeric_limits
- ::infinity() ;
-
- __unreferenced(_geom);
- __unreferenced(_hfun);
-
- real_type _dqdw = (real_type)0. ;
-
- iptr_type _tnum = +0 ;
-
- _ladj = (real_type)0.;
-
- real_type _save =
- _node->pval(_dims) ;
-
- for (auto _tria = _tset.head(),
- _tend = _tset.tend();
- _tria != _tend;
- ++_tria, ++_tnum)
- {
- auto _tptr =
- _mesh._set4.head()+*_tria ;
-
- auto _inod = _mesh.
- _set1 .head()+_tptr->node(0) ;
- auto _jnod = _mesh.
- _set1 .head()+_tptr->node(1) ;
- auto _knod = _mesh.
- _set1 .head()+_tptr->node(2) ;
- auto _lnod = _mesh.
- _set1 .head()+_tptr->node(3) ;
-
- _qmin = std::min(
- _qmin, _cost[_tnum]) ;
-
- real_type _ball[_dims+1] ;
- _pred.circ_ball(_ball,
- &_inod->pval(0),
- &_jnod->pval(0),
- &_knod->pval(0),
- &_lnod->pval(0)) ;
-
- _ladj += _ball[_dims]; // ball-rad.^2
- }
-
- real_type _qbar , _qlow ;
- _qbar = (real_type) +1. ;
- _qlow = (real_type) +0. ;
-
- iptr_type _lnum = +0 ;
- iptr_type _hnum = +1 ;
-
- real_type _qlim = _qmin +
- (real_type) +1.0E-004 ;
-
- _ladj /= _tset.count () ;
-
- _tnum = (iptr_type) +0 ;
- for (auto _tria = _tset.head(),
- _tend = _tset.tend();
- _tria != _tend;
- ++_tria, ++_tnum)
- {
- auto _tptr =
- _mesh._set4.head()+*_tria ;
-
- real_type _qtri = _cost[_tnum] ;
- real_type _DQDW ;
-
- if (_qtri <= _qlim)
- {
- real_type _hsum = (real_type)0.;
-
- real_type _wdel = _WINC*_ladj;
-
- real_type _sdel = (real_type)0.;
- real_type _sabs = (real_type)0.;
- real_type _sbar = (real_type)0.;
-
- for (auto _iter = +0; _iter++ != +8; )
- {
- _node->pval(_dims) =
- _save + _wdel;
-
- _hsum = (real_type)+0.;
- _hsum += _node->
- pval(_dims) - _save;
-
- real_type _scr1 =
- _pred.cost_dual (
- &_mesh._set1[
- _tptr->node(0)].pval(0),
- &_mesh._set1[
- _tptr->node(1)].pval(0),
- &_mesh._set1[
- _tptr->node(2)].pval(0),
- &_mesh._set1[
- _tptr->node(3)].pval(0)
- ) ;
-
- _node->pval(_dims) =
- _save - _wdel;
-
- _hsum -= _node->
- pval(_dims) - _save;
-
- real_type _scr0 =
- _pred.cost_dual (
- &_mesh._set1[
- _tptr->node(0)].pval(0),
- &_mesh._set1[
- _tptr->node(1)].pval(0),
- &_mesh._set1[
- _tptr->node(2)].pval(0),
- &_mesh._set1[
- _tptr->node(3)].pval(0)
- ) ;
-
- _sdel = _scr1 - _scr0 ;
- _sabs =
- std::abs(_sdel);
-
- _sbar = std::max(
- std::abs(_scr1),
- std::abs(_scr0)) ;
-
- _node->pval(_dims) =_save;
-
- if (_sabs > (real_type)0.)
- {
- if (_sabs > _RMAX * _sbar)
- {
- _wdel *=
- (real_type) +.10 ;
- }
- else
- if (_sabs < _RMIN * _sbar)
- {
- _wdel *=
- (real_type) +10. ;
- }
- else { break ; }
- }
- else { break ; }
- }
-
- _DQDW = _sdel / _hsum ;
-
- _node->pval(_dims) = _save ;
-
- _dqdw += _DQDW;
-
- _qlow += _qtri; _lnum += 1 ;
- }
- else
- {
- _qbar += _qtri; _hnum += 1 ;
- }
- }
-
- if (_tnum > +0)
- {
- _dqdw /= _lnum ;
- _qlow /= _lnum ;
- }
- if (_hnum > +0)
- {
- _qbar /= _hnum ;
- }
-
- real_type _scal = std::abs (_dqdw) ;
-
- if (_scal <= _ZERO * _ladj)
- {
- _line = (real_type) +0. ;
- }
- else
- {
- _line = _dqdw / _scal;
-
- _scal = (_qbar - _qlow)
- / (_line * _dqdw) ;
-
- _scal = std::min(_scal, _ladj) ;
-
- _line *= _scal ;
- }
-
- }
-
-
diff --git a/external/jigsaw/src/libcpp/iter_mesh/iter_flip_2.inc b/external/jigsaw/src/libcpp/iter_mesh/iter_flip_2.inc
index 8edc2cb..821c9b3 100644
--- a/external/jigsaw/src/libcpp/iter_mesh/iter_flip_2.inc
+++ b/external/jigsaw/src/libcpp/iter_mesh/iter_flip_2.inc
@@ -31,11 +31,11 @@
*
--------------------------------------------------------
*
- * Last updated: 19 December, 2018
+ * Last updated: 30 April, 2020
*
- * Copyright 2013-2018
+ * Copyright 2013-2020
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
--------------------------------------------------------
@@ -52,18 +52,19 @@
__static_call
__normal_call bool_type need_flip_delaunay (
- geom_type &_geom ,
- mesh_type &_mesh ,
- pred_type &_pred ,
- __const_ptr (iptr_type) _inod ,
- __const_ptr (iptr_type) _jnod
+ geom_type &_geom,
+ mesh_type &_mesh,
+ __const_ptr(iptr_type) _inod,
+ __const_ptr(iptr_type) _jnod
)
{
+ /*----------------------------- assess flip criterion */
+ iptr_type static constexpr
+ _last=pred_type::geom_dims+0 ;
+
real_type static const _LTOL =
std::pow(std::numeric_limits
- ::epsilon(), +.80) ;
-
- __unreferenced(_pred) ; // for MSVC...
+ ::epsilon(), +.8) ;
iptr_type _iloc[3] ;
_iloc[0] = _inod[0] ;
@@ -72,7 +73,7 @@
algorithms::isort(
&_iloc[0], &_iloc[3] ,
- std::less());
+ std::less ()) ;
iptr_type _jloc[3] ;
_jloc[0] = _jnod[0] ;
@@ -81,49 +82,49 @@
algorithms::isort(
&_jloc[0], &_jloc[3] ,
- std::less());
+ std::less ()) ;
- real_type _ibal[_dims+1] ;
- _pred.circ_ball(_ibal ,
- &_mesh._set1[_iloc[0]].pval(0),
- &_mesh._set1[_iloc[1]].pval(0),
- &_mesh._set1[_iloc[2]].pval(0)
+ real_type _ibal[_last + 1] ;
+ pred_type::tri3_ball(_ibal ,
+ &_mesh.node(_iloc[0]).pval(0) ,
+ &_mesh.node(_iloc[1]).pval(0) ,
+ &_mesh.node(_iloc[2]).pval(0)
) ;
- real_type _jbal[_dims+1] ;
- _pred.circ_ball(_jbal ,
- &_mesh._set1[_jloc[0]].pval(0),
- &_mesh._set1[_jloc[1]].pval(0),
- &_mesh._set1[_jloc[2]].pval(0)
+ real_type _jbal[_last + 1] ;
+ pred_type::tri3_ball(_jbal ,
+ &_mesh.node(_jloc[0]).pval(0) ,
+ &_mesh.node(_jloc[1]).pval(0) ,
+ &_mesh.node(_jloc[2]).pval(0)
) ;
- real_type _null[_dims] = {
- (real_type) +0. } ;
+ real_type _null[_last] = {
+ (real_type) +0.0 } ;
- _pred. proj_node (
+ pred_type::proj_node (
_geom, _null, _ibal) ;
- _pred. proj_node (
+ pred_type::proj_node (
_geom, _null, _jbal) ;
+ /*----------------------------- measure dual distance */
real_type _ilen =
- _pred.length_sq(_jbal,
- &_mesh._set1[_inod[2]].pval(0));
+ pred_type::length_sq(_jbal,
+ &_mesh.node(_inod[2]).pval(0));
real_type _jlen =
- _pred.length_sq(_ibal,
- &_mesh._set1[_jnod[2]].pval(0));
+ pred_type::length_sq(_ibal,
+ &_mesh.node(_jnod[2]).pval(0));
- real_type _btol = _LTOL *
- std::max(_ilen, _jlen) ;
+ real_type _btol =
+ (real_type)+.5 * _LTOL * (_ilen + _jlen) ;
- real_type _idel =
- _ilen - _jbal[_dims] ;
- real_type _jdel =
- _jlen - _ibal[_dims] ;
+ real_type _idel =
+ _ilen - _jbal [_last] ;
+ real_type _jdel =
+ _jlen - _ibal [_last] ;
- if (_idel >= - _btol ||
- _jdel >= - _btol )
+ if (_idel >= -_btol || _jdel >= -_btol)
{
return false ;
}
@@ -134,19 +135,20 @@
}
__static_call
- __normal_call bool_type need_flip_weighted (
- geom_type &_geom ,
- mesh_type &_mesh ,
- pred_type &_pred ,
- __const_ptr (iptr_type) _inod ,
- __const_ptr (iptr_type) _jnod
+ __normal_call bool_type need_flip_laguerre (
+ geom_type &_geom,
+ mesh_type &_mesh,
+ __const_ptr(iptr_type) _inod,
+ __const_ptr(iptr_type) _jnod
)
{
+ /*----------------------------- assess flip criterion */
+ iptr_type static constexpr
+ _last=pred_type::geom_dims+0 ;
+
real_type static const _LTOL =
std::pow(std::numeric_limits
- ::epsilon(), +.80) ;
-
- __unreferenced(_pred) ; // for MSVC...
+ ::epsilon(), +.8) ;
iptr_type _iloc[3] ;
_iloc[0] = _inod[0] ;
@@ -155,7 +157,7 @@
algorithms::isort(
&_iloc[0], &_iloc[3] ,
- std::less());
+ std::less ()) ;
iptr_type _jloc[3] ;
_jloc[0] = _jnod[0] ;
@@ -164,58 +166,58 @@
algorithms::isort(
&_jloc[0], &_jloc[3] ,
- std::less());
+ std::less ()) ;
- real_type _ibal[_dims+1] ;
- _pred.perp_ball(_ibal ,
- &_mesh._set1[_iloc[0]].pval(0),
- &_mesh._set1[_iloc[1]].pval(0),
- &_mesh._set1[_iloc[2]].pval(0)
+ real_type _ibal[_last + 1] ;
+ pred_type::tri3_ball(_ibal ,
+ &_mesh.node(_iloc[0]).pval(0) ,
+ &_mesh.node(_iloc[1]).pval(0) ,
+ &_mesh.node(_iloc[2]).pval(0)
) ;
- real_type _jbal[_dims+1] ;
- _pred.perp_ball(_jbal ,
- &_mesh._set1[_jloc[0]].pval(0),
- &_mesh._set1[_jloc[1]].pval(0),
- &_mesh._set1[_jloc[2]].pval(0)
+ real_type _jbal[_last + 1] ;
+ pred_type::tri3_ball(_jbal ,
+ &_mesh.node(_jloc[0]).pval(0) ,
+ &_mesh.node(_jloc[1]).pval(0) ,
+ &_mesh.node(_jloc[2]).pval(0)
) ;
- real_type _null[_dims] = {
- (real_type) +0. } ;
+ real_type _null[_last] = {
+ (real_type) +0.0 } ;
- _pred. proj_node (
+ pred_type::proj_node (
_geom, _null, _ibal) ;
- _pred. proj_node (
+ pred_type::proj_node (
_geom, _null, _jbal) ;
+ /*----------------------------- measure dual distance */
real_type _ilen =
- _pred.length_sq(_jbal,
- &_mesh._set1[_inod[2]].pval( +0));
-
- real_type _ipwr =
- _mesh._set1[_inod[2]].pval(_dims) ;
+ pred_type::length_sq(_jbal,
+ &_mesh.node(_inod[2]).pval(0));
real_type _jlen =
- _pred.length_sq(_ibal,
- &_mesh._set1[_jnod[2]].pval( +0));
+ pred_type::length_sq(_ibal,
+ &_mesh.node(_jnod[2]).pval(0));
+
+ real_type _ipwr =
+ _mesh.node(_inod[2]).pval (_last) ;
real_type _jpwr =
- _mesh._set1[_jnod[2]].pval(_dims) ;
+ _mesh.node(_jnod[2]).pval (_last) ;
_ilen -= _ipwr ;
_jlen -= _jpwr ;
- real_type _btol = _LTOL *
- std::max(_ilen, _jlen) ;
+ real_type _btol =
+ (real_type)+.5 * _LTOL * (_ilen + _jlen) ;
- real_type _idel =
- _ilen - _jbal[_dims] ;
- real_type _jdel =
- _jlen - _ibal[_dims] ;
+ real_type _idel =
+ _ilen - _jbal [_last] ;
+ real_type _jdel =
+ _jlen - _ibal [_last] ;
- if (_idel >= - _btol ||
- _jdel >= - _btol )
+ if (_idel >= -_btol || _jdel >= -_btol)
{
return false ;
}
@@ -225,69 +227,55 @@
}
}
-
/*
--------------------------------------------------------
* FLIP-T2T2: 2-simplex topological flip.
--------------------------------------------------------
*/
+ //__static_call
+ //__normal_call void_type flip_t1q1 (
+
+ //__static_call
+ //__normal_call void_type flip_q2q2 (
+
__static_call
__normal_call void_type flip_t2t2 (
geom_type &_geom ,
mesh_type &_mesh ,
- size_type &_hfun ,
- pred_type &_pred ,
- iptr_type _tria ,
- iptr_type _edge ,
- iptr_list &_told ,
- iptr_list &_tnew ,
+ iptr_type *_enod ,
+ conn_list &_conn ,
+ conn_list &_next ,
bool_type &_flip ,
real_list &_qold ,
real_list &_qnew
)
{
- __unreferenced( _hfun) ;
- __unreferenced( _qold) ;
- __unreferenced( _qnew) ;
-
- _flip = false ;
-
- _told.set_count(0) ;
- _tnew.set_count(0) ;
-
- iptr_type _enod[3] ;
- mesh_type::tri3_type::
- face_node(_enod, _edge, 2, 1) ;
- _enod[ 0] = _mesh.
- _set3[_tria].node(_enod[0]) ;
- _enod[ 1] = _mesh.
- _set3[_tria].node(_enod[1]) ;
-
- iptr_type _epos = -1 ;
+ iptr_type _epos = -1 ;
_mesh.find_edge(_enod, _epos) ;
- if (_epos==-1) return;
+ if (_epos==-1) return ;
auto _eptr =
- _mesh._set2.head() + _epos ;
-
- if (_eptr->self()>=+1) return ;
+ _mesh. edge().head() + _epos;
- _mesh.edge_tri3(_epos, _told) ;
+ if (_eptr->self() > 0) return ;
- if (_told.count()!=+2) return ;
-
- iptr_type _itri = _told[0] ;
- iptr_type _jtri = _told[1] ;
+ auto _itri = _conn[0]._cell;
+ auto _jtri = _conn[1]._cell;
auto _iptr =
- _mesh._set3.head() + _itri ;
+ _mesh. tri3().head() + _itri;
auto _jptr =
- _mesh._set3.head() + _jtri ;
+ _mesh. tri3().head() + _jtri;
+
+ if (_iptr->itag () !=
+ _jptr->itag () ) return ;
- if ( _iptr->itag() !=
- _jptr->itag() ) return ;
+ /*----------------------------- extract cell indexing */
+ __unreferenced( _geom ) ;
+ __unreferenced( _qold ) ;
+ __unreferenced( _qnew ) ;
iptr_type _inod [3] ;
iptr_type _jnod [3] ;
@@ -296,11 +284,11 @@
mesh_type::tri3_type::
face_node(_inod, _inum, 2, 1) ;
_inod[0] =
- _iptr->node(_inod[0]);
+ _iptr->node(_inod[0]) ;
_inod[1] =
- _iptr->node(_inod[1]);
+ _iptr->node(_inod[1]) ;
_inod[2] =
- _iptr->node(_inod[2]);
+ _iptr->node(_inod[2]) ;
if (_inod[2] != _enod[0])
if (_inod[2] != _enod[1])
@@ -311,24 +299,24 @@
mesh_type::tri3_type::
face_node(_jnod, _inum, 2, 1) ;
_jnod[0] =
- _jptr->node(_jnod[0]);
+ _jptr->node(_jnod[0]) ;
_jnod[1] =
- _jptr->node(_jnod[1]);
+ _jptr->node(_jnod[1]) ;
_jnod[2] =
- _jptr->node(_jnod[2]);
+ _jptr->node(_jnod[2]) ;
if (_jnod[2] != _enod[0])
if (_jnod[2] != _enod[1])
break ;
}
- __assert(_inod[0]==_jnod[1] &&
- _inod[1]==_jnod[0] &&
- "FLIP-T2T2: bad orientation!");
+ assert( _inod[0] == _jnod[1] &&
+ _inod[1] == _jnod[0] &&
+ "ITER.FLIP-T2T2: bad orientation!") ;
- if(!need_flip_weighted (
+ /*----------------------------- flip cells about edge */
+ if(!need_flip_laguerre (
_geom, _mesh ,
- _pred,
_inod, _jnod)) return ;
_mesh._pop_tri3(_itri) ;
@@ -336,16 +324,16 @@
_flip = true ;
- typename mesh_type
- ::tri3_type _tdat ;
+ typename mesh_type::tri3_type _tdat ;
_tdat.node(0) = _inod[0] ;
_tdat.node(1) = _jnod[2] ;
_tdat.node(2) = _inod[2] ;
_tdat.itag () = _iptr->itag() ;
- _tnew.push_tail(
- _mesh.push_tri3(_tdat)) ;
+ _next.push_tail(typename
+ conn_list::data_type(
+ _mesh.push_tri3(_tdat), TRIA3_tag)) ;
_tdat.node(0) = _jnod[0] ;
_tdat.node(1) = _inod[2] ;
@@ -353,8 +341,203 @@
_tdat.itag () = _jptr->itag() ;
- _tnew.push_tail(
- _mesh.push_tri3(_tdat)) ;
+ _next.push_tail(typename
+ conn_list::data_type(
+ _mesh.push_tri3(_tdat), TRIA3_tag)) ;
+ }
+
+ /*
+ --------------------------------------------------------
+ * FLIP-TRI3: "flip" mesh topology.
+ --------------------------------------------------------
+ */
+
+ __static_call
+ __inline_call void_type flip_tri3 (
+ geom_type &_geom ,
+ mesh_type &_mesh ,
+ iptr_type _cell ,
+ bool_type &_flip ,
+ conn_list &_conn ,
+ conn_list &_next ,
+ real_list &_qold ,
+ real_list &_qnew
+ )
+ {
+ auto _coin = (std::rand() % 3) + 1 ;
+ for (auto _enum = _coin; _enum-- > 0; )
+ {
+ _flip = false ;
+ /*----------------------------- flip cells about edge */
+ iptr_type _enod[3] ;
+ mesh_type::tri3_type::
+ face_node(_enod, _enum, +2, +1) ;
+ _enod[ 0] = _mesh.tri3(
+ _cell).node( _enod[ 0]) ;
+ _enod[ 1] = _mesh.tri3(
+ _cell).node( _enod[ 1]) ;
+
+ _conn.set_count(0) ;
+ _next.set_count(0) ;
+ _mesh.connect_2(
+ &_enod[0], EDGE2_tag, _conn) ;
+
+ if (_conn.count() != +2) continue ;
+
+ if (_conn[0]._kind==TRIA3_tag &&
+ _conn[1]._kind==TRIA3_tag )
+ {
+ flip_t2t2( _geom, _mesh, _enod,
+ _conn, _next, _flip,
+ _qold, _qnew) ;
+
+ if (_flip) return ;
+ }
+ else
+ {
+ // flip_t1q1( _geom, _mesh, _enod,
+ // _conn, _next, _flip,
+ // _qold, _qnew) ;
+
+ if (_flip) return ;
+ }
+ }
+
+ for (auto _enum = 3; _enum-- > _coin; )
+ {
+ _flip = false ;
+ /*----------------------------- flip cells about edge */
+ iptr_type _enod[3] ;
+ mesh_type::tri3_type::
+ face_node(_enod, _enum, +2, +1) ;
+ _enod[ 0] = _mesh.tri3(
+ _cell).node( _enod[ 0]) ;
+ _enod[ 1] = _mesh.tri3(
+ _cell).node( _enod[ 1]) ;
+
+ _conn.set_count(0) ;
+ _next.set_count(0) ;
+ _mesh.connect_2(
+ &_enod[0], EDGE2_tag, _conn) ;
+
+ if (_conn.count() != +2) continue ;
+
+ if (_conn[0]._kind==TRIA3_tag &&
+ _conn[1]._kind==TRIA3_tag )
+ {
+ flip_t2t2( _geom, _mesh, _enod,
+ _conn, _next, _flip,
+ _qold, _qnew) ;
+
+ if (_flip) return ;
+ }
+ else
+ {
+ // flip_t1q1( _geom, _mesh, _enod,
+ // _conn, _next, _flip,
+ // _qold, _qnew) ;
+
+ if (_flip) return ;
+ }
+ }
+
+ }
+
+ /*
+ --------------------------------------------------------
+ * FLIP-QUAD: "flip" mesh topology.
+ --------------------------------------------------------
+ */
+
+ __static_call
+ __inline_call void_type flip_quad (
+ geom_type &/*_geom*/ ,
+ mesh_type &_mesh ,
+ iptr_type _cell ,
+ bool_type &_flip ,
+ conn_list &_conn ,
+ conn_list &_next ,
+ real_list &/*_qold*/ ,
+ real_list &/*_qnew*/
+ )
+ {
+ auto _coin = (std::rand() % 4) + 1 ;
+ for (auto _enum = _coin; _enum-- > 0; )
+ {
+ _flip = false ;
+ /*----------------------------- flip cells about edge */
+ iptr_type _enod[4] ;
+ mesh_type::quad_type::
+ face_node(_enod, _enum, +2, +1) ;
+ _enod[ 0] = _mesh.quad(
+ _cell).node( _enod[ 0]) ;
+ _enod[ 1] = _mesh.quad(
+ _cell).node( _enod[ 1]) ;
+
+ _conn.set_count(0) ;
+ _next.set_count(0) ;
+ _mesh.connect_2(
+ &_enod[0], EDGE2_tag, _conn) ;
+
+ if (_conn.count() != +2) continue ;
+
+ if (_conn[0]._kind==QUAD4_tag &&
+ _conn[1]._kind==QUAD4_tag )
+ {
+ // flip_q2q2( _geom, _mesh, _enod,
+ // _conn, _next, _flip,
+ // _qold, _qnew) ;
+
+ if (_flip) return ;
+ }
+ else
+ {
+ // flip_t1q1( _geom, _mesh, _enod,
+ // _conn, _next, _flip,
+ // _qold, _qnew) ;
+
+ if (_flip) return ;
+ }
+ }
+
+ for (auto _enum = 4; _enum-- > _coin; )
+ {
+ _flip = false ;
+ /*----------------------------- flip cells about edge */
+ iptr_type _enod[4] ;
+ mesh_type::quad_type::
+ face_node(_enod, _enum, +2, +1) ;
+ _enod[ 0] = _mesh.quad(
+ _cell).node( _enod[ 0]) ;
+ _enod[ 1] = _mesh.quad(
+ _cell).node( _enod[ 1]) ;
+
+ _conn.set_count(0) ;
+ _next.set_count(0) ;
+ _mesh.connect_2(
+ &_enod[0], EDGE2_tag, _conn) ;
+
+ if (_conn.count() != +2) continue ;
+
+ if (_conn[0]._kind==QUAD4_tag &&
+ _conn[1]._kind==QUAD4_tag )
+ {
+ // flip_q2q2( _geom, _mesh, _enod,
+ // _conn, _next, _flip,
+ // _qold, _qnew) ;
+
+ if (_flip) return ;
+ }
+ else
+ {
+ // flip_t1q1( _geom, _mesh, _enod,
+ // _conn, _next, _flip,
+ // _qold, _qnew) ;
+
+ if (_flip) return ;
+ }
+ }
+
}
diff --git a/external/jigsaw/src/libcpp/iter_mesh/iter_flip_3.inc b/external/jigsaw/src/libcpp/iter_mesh/iter_flip_3.inc
index 2dbbc67..5fea529 100644
--- a/external/jigsaw/src/libcpp/iter_mesh/iter_flip_3.inc
+++ b/external/jigsaw/src/libcpp/iter_mesh/iter_flip_3.inc
@@ -35,7 +35,7 @@
*
* Copyright 2013-2018
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
--------------------------------------------------------
diff --git a/external/jigsaw/src/libcpp/iter_mesh/iter_mesh_2.hpp b/external/jigsaw/src/libcpp/iter_mesh/iter_mesh_2.hpp
index a44e3e9..aca69ec 100644
--- a/external/jigsaw/src/libcpp/iter_mesh/iter_mesh_2.hpp
+++ b/external/jigsaw/src/libcpp/iter_mesh/iter_mesh_2.hpp
@@ -31,11 +31,11 @@
*
--------------------------------------------------------
*
- * Last updated: 25 January, 2020
+ * Last updated: 12 Sept., 2020
*
* Copyright 2013-2020
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
--------------------------------------------------------
@@ -50,7 +50,7 @@
/*
--------------------------------------------------------
- * ITER-MESH-2: hill-climbing surf. iter.
+ * ITER-MESH-2: optimise mixed 2-complex meshes
--------------------------------------------------------
*/
@@ -65,7 +65,7 @@
public :
typedef M mesh_type ;
typedef G geom_type ;
- typedef H size_type ;
+ typedef H hfun_type ;
typedef P pred_type ;
typedef typename
@@ -73,17 +73,23 @@
typedef typename
mesh_type::iptr_type iptr_type ;
- iptr_type static
- constexpr _dims = pred_type::_dims ;
+ iptr_type static constexpr
+ topo_dims = pred_type::topo_dims ;
+ iptr_type static constexpr
+ geom_dims = pred_type::geom_dims ;
+ iptr_type static constexpr
+ real_dims = pred_type::real_dims ;
- char_type static
+ char_type static // optim. kern. selector
constexpr _odt_kern = +1 ;
char_type static
constexpr _cvt_kern = +2 ;
+ char_type static
+ constexpr _h95_kern = +3 ;
char_type static
constexpr dqdx_kern = +5 ;
- class tria_kind {} ; // dummy for overloads
+ class cell_kind {} ; // dummies for overload
class dual_kind {} ;
typedef mesh::iter_params <
@@ -99,144 +105,248 @@
typedef containers
::array< real_type > real_list ;
+ class mark_list // integer cell markers
+ {
+ public :
+ iptr_list _node;
+ iptr_list _edge;
+ iptr_list _tri3;
+ iptr_list _quad;
+ };
+
+ typedef typename
+ mesh_type::connector conn_list ;
+
public :
/*
--------------------------------------------------------
- * FLIP-SIGN: flip tria for +ve iter. cost fn.
+ * FLIP-SIGN: flip cells for +ve iter. cost fn.
--------------------------------------------------------
*/
__static_call
__normal_call void_type flip_next (
- mesh_type &_mesh ,
- iptr_type _tpos ,
- iptr_type _epos ,
- iptr_type &_tadj ,
- iptr_type &_eadj ,
- iptr_list &_tset
+ mesh_type &_mesh,
+ conn_list &_list,
+ iptr_type _icel,
+ iptr_type *_inod,
+ mark_list &_seen,
+ conn_list &_conn
)
{
- iptr_type _inod[3] ;
- iptr_type _jnod[3] ;
- mesh_type::tri3_type::
- face_node(_inod, _epos, 2, 1) ;
- _inod[ 0] = _mesh.
- _set3[_tpos].node(_inod[0]) ;
- _inod[ 1] = _mesh.
- _set3[_tpos].node(_inod[1]) ;
- _inod[ 2] = _mesh.
- _set3[_tpos].node(_inod[2]) ;
+ /*------------------------- flip to match cell "sign" */
+ _conn.set_count(0) ;
+ _mesh.connect_2(
+ _inod, EDGE2_tag, _conn);
- _tset.set_count(0) ;
+ if (_conn.count() != 2) return;
- _mesh.edge_tri3(_inod, _tset) ;
+ iptr_type _jcel, _jfac;
+ char_type _kind;
+ if ((iptr_type)
+ _conn[0]._cell == _icel)
+ {
+ _jcel = _conn[ 1]._cell ;
+ _kind = _conn[ 1]._kind ;
+ }
+ else
+ {
+ _jcel = _conn[ 0]._cell ;
+ _kind = _conn[ 0]._kind ;
+ }
- if (_tset.count()!=+2) return ;
+ /*------------------------- match indexing along edge */
+ if (_kind == TRIA3_tag)
+ {
+ if (_seen._tri3[_jcel] == +0)
+ {
+ _list.push_tail(typename
+ conn_list::data_type(_jcel, _kind)) ;
- if (_tset[0] == _tpos)
- _tadj = _tset[1] ;
- else
- _tadj = _tset[0] ;
+ _seen._tri3[_jcel] = +1;
+
+ iptr_type _jnod[3] ;
+ for(_jfac = 3 ; _jfac-- != 0; )
+ {
+ mesh_type::tri3_type::
+ face_node(_jnod, _jfac, 2, 1) ;
+ _jnod[ 0] = _mesh.
+ tri3(_jcel).node(_jnod[0]) ;
+ _jnod[ 1] = _mesh.
+ tri3(_jcel).node(_jnod[1]) ;
+ _jnod[ 2] = _mesh.
+ tri3(_jcel).node(_jnod[2]) ;
+
+ if (_jnod[ 2] != _inod[ 0])
+ if (_jnod[ 2] != _inod[ 1])
+ break ;
+ }
- for(_eadj = 3 ; _eadj-- != 0; )
+ if (_jnod[ 0] == _inod[ 0] &&
+ _jnod[ 1] == _inod[ 1])
+ {
+ std::swap (
+ _mesh.tri3(_jcel).node( 0),
+ _mesh.tri3(_jcel).node( 1)) ;
+ }
+ }
+ }
+ else
+ if (_kind == QUAD4_tag)
{
- mesh_type::tri3_type::
- face_node(_jnod, _eadj, 2, 1) ;
- _jnod[ 0] = _mesh.
- _set3[_tadj].node(_jnod[0]) ;
- _jnod[ 1] = _mesh.
- _set3[_tadj].node(_jnod[1]) ;
- _jnod[ 2] = _mesh.
- _set3[_tadj].node(_jnod[2]) ;
-
- if (_jnod[ 2] != _inod[ 0])
- if (_jnod[ 2] != _inod[ 1])
- break ;
+ if (_seen._quad[_jcel] == +0)
+ {
+ _list.push_tail(typename
+ conn_list::data_type(_jcel, _kind)) ;
+
+ _seen._quad[_jcel] = +1;
+
+ // TODO: reverse quad indexes
}
+ }
+ }
- if (_jnod[ 0] == _inod[ 0] &&
- _jnod[ 1] == _inod[ 1] )
+ __static_call
+ __normal_call void_type flip_bfs_ (
+ mesh_type &_mesh,
+ conn_list &_list,
+ mark_list &_seen
+ )
+ {
+ conn_list _conn;
+ for ( ; !_list.empty() ; )
{
- std::swap (
- _mesh._set3[_tadj].node(0),
- _mesh._set3[_tadj].node(1)) ;
+ /*------------------------- flip via BFS on cell adj. */
+ typename conn_list::data_type _cell ;
+ _list._pop_tail(_cell) ;
+
+ if (_cell._kind == TRIA3_tag)
+ {
+ for(auto _enum = +3; _enum-- != +0; )
+ {
+ auto _cpos = _cell._cell;
+
+ iptr_type _enod[3] ;
+ mesh_type::tri3_type::
+ face_node(_enod, _enum, +2, +1) ;
+ _enod[ 0] = _mesh.tri3(
+ _cpos).node( _enod[ 0]) ;
+ _enod[ 1] = _mesh.tri3(
+ _cpos).node( _enod[ 1]) ;
+
+ flip_next( _mesh, _list,
+ _cpos, _enod, _seen, _conn) ;
+ }
+ }
+ else
+ if (_cell._kind == QUAD4_tag)
+ {
+ for(auto _enum = +4; _enum-- != +0; )
+ {
+ auto _cpos = _cell._cell;
+
+ iptr_type _enod[4] ;
+ mesh_type::quad_type::
+ face_node(_enod, _enum, +2, +1) ;
+ _enod[ 0] = _mesh.quad(
+ _cpos).node( _enod[ 0]) ;
+ _enod[ 1] = _mesh.quad(
+ _cpos).node( _enod[ 1]) ;
+
+ flip_next( _mesh, _list,
+ _cpos, _enod, _seen, _conn) ;
+ }
+ }
}
}
- /*------------------------- main sign-flip driver fn. */
-
__static_call
__normal_call void_type flip_sign (
- mesh_type &_mesh ,
- pred_type &_pred
+ mesh_type &_mesh
)
{
- iptr_list _tset, _list, _seen ;
-
- __unreferenced(_pred); // for MSVC...
+ # define SEENTRI3( _CELL) _seen._tri3[_CELL]
+ # define SEENQUAD( _CELL) _seen._quad[_CELL]
- _seen.set_count( _mesh.
- _set3.count(),
- containers::tight_alloc , +0) ;
+ conn_list _list;
+ mark_list _seen;
+ init_mark(_mesh, _seen, +0) ;
- /*----------- an incremental BFS to correct mesh sign */
+ /*------------------------- flip to correct mesh sign */
iptr_type _tnum = +0 ;
- iptr_type _epos = +0 ;
-
- for (auto _tria = _mesh._set3.head() ;
- _tria != _mesh._set3.tend() ;
+ for (auto _tria = _mesh.tri3().head();
+ _tria != _mesh.tri3().tend();
++_tria, ++_tnum )
{
- if (_tria->mark() < +0) continue ;
- if (_seen[_tnum ] > +0) continue ;
+ if (_tria->mark () < +0) continue;
+ if (SEENTRI3(_tnum) > +0) continue;
/*--------------------- flip seed for +ve quality */
real_type _cost =
- _pred.cost_tria (
- &_mesh._set1[
- _tria->node(0)].pval(0),
- &_mesh._set1[
- _tria->node(1)].pval(0),
- &_mesh._set1[
- _tria->node(2)].pval(0)) ;
+ pred_type::tri3_cost (
+ &_mesh. node(
+ _tria->node(0)).pval(0),
+ &_mesh. node(
+ _tria->node(1)).pval(0),
+ &_mesh. node(
+ _tria->node(2)).pval(0),
+ typename
+ pred_type::cell_kind()) ;
if (_cost < (real_type) +0.)
{
std::swap (
- _tria->node(0) ,
- _tria->node(1));
+ _tria->node(0),
+ _tria->node(1)) ;
}
/*--------------------- a BFS from seed via topo. */
- _list.push_tail(_tnum) ;
- _seen [_tnum] = +1;
+ _list.push_tail(typename conn_list
+ ::data_type (_tnum, TRIA3_tag)) ;
- for ( ; !_list.empty() ; )
- {
- iptr_type _tpos;
- _list._pop_tail(_tpos) ;
+ SEENTRI3( _tnum ) = 1 ;
- for (_epos = +3; _epos-- != +0; )
- {
- iptr_type _tadj = -1 ;
- iptr_type _eadj = -1 ;
+ flip_bfs_(_mesh, _list, _seen) ;
+ }
- flip_next( _mesh, _tpos ,
- _epos, _tadj, _eadj ,
- _tset) ;
+ iptr_type _qnum = +0 ;
+ for (auto _quad = _mesh.quad().head();
+ _quad != _mesh.quad().tend();
+ ++_quad, ++_qnum )
+ {
+ if (_quad->mark () < +0) continue;
+ if (SEENQUAD(_qnum) > +0) continue;
- if (_tadj == -1) continue ;
+ /*--------------------- flip seed for +ve quality */
+ real_type _cost =
+ pred_type::quad_cost (
+ &_mesh. node(
+ _quad->node(0)).pval(0),
+ &_mesh. node(
+ _quad->node(1)).pval(0),
+ &_mesh. node(
+ _quad->node(2)).pval(0),
+ &_mesh. node(
+ _quad->node(3)).pval(0),
+ typename
+ pred_type::cell_kind()) ;
- if (_seen[_tadj] == +0 )
- {
- _seen[_tadj] = +1 ;
- _list.push_tail(_tadj);
- }
- }
+ if (_cost < (real_type) +0.)
+ {
+ // TODO: reverse quad indexes
}
- }
+ /*--------------------- a BFS from seed via topo. */
+ _list.push_tail(typename conn_list
+ ::data_type (_qnum, QUAD4_tag)) ;
+
+ SEENQUAD( _qnum ) = 1 ;
+
+ flip_bfs_(_mesh, _list, _seen) ;
+ }
+ # undef SEENQUAD
+ # undef SEENTRI3
}
/*
@@ -245,26 +355,6 @@
--------------------------------------------------------
*/
- __static_call
- __inline_call void_type move_okay (
- real_list &_cdst ,
- real_list &_csrc ,
- bool_type &_okay ,
- real_type _good = +9.25E-01,
- real_type _qtol = +1.00E-04,
- real_type _xdel = +0.00E+00,
- real_type _xtol =
- std::numeric_limits::infinity()
- )
- {
- iptr_type _move;
- move_okay(_cdst, _csrc, _move ,
- _good,_qtol,
- _xdel,_xtol) ;
-
- _okay = ( _move>(iptr_type)0 );
- }
-
__static_call
__normal_call void_type move_okay (
real_list &_cdst ,
@@ -283,14 +373,19 @@
if (_csrc.empty()) return ;
/*--------------------- calc. min. + mean metrics */
+ real_type _zero =
+ +std::numeric_limits
+ ::epsilon ();
real_type _0src =
+std::numeric_limits
::infinity();
-
real_type _0dst =
+std::numeric_limits
::infinity();
+ real_type _GOOD =
+ +std::pow(_good, +7./8.);
+
real_type _msrc, _mdst;
_msrc = (real_type) +0. ;
_mdst = (real_type) +0. ;
@@ -301,12 +396,10 @@
++_iter )
{
_0src =
- std::min(_0src, *_iter);
-
- //_msrc += *_iter ;
+ std::min(_0src, *_iter) ;
- _msrc +=
- (real_type)1. / *_iter ;
+ _msrc += std::pow(
+ (real_type)1. / *_iter, +7);
}
for (auto _iter = _cdst.head(),
_tend = _cdst.tend();
@@ -314,84 +407,39 @@
++_iter )
{
_0dst =
- std::min(_0dst, *_iter);
-
- //_mdst += *_iter ;
+ std::min(_0dst, *_iter) ;
- _mdst +=
- (real_type)1. / *_iter ;
+ _mdst += std::pow (
+ (real_type)1. / *_iter, +7);
}
- //_msrc /= _csrc.count() ;
- //_mdst /= _cdst.count() ;
-
- _msrc =
- _csrc.count()/_msrc;
- _mdst =
- _cdst.count()/_mdst;
-
- /*--------------------- calc. min. + mean rel-tol */
- _qtol *= std::max(
- _0src, (real_type) +0.);
-
- real_type _mtol = _qtol;
- real_type _0tol = _qtol;
+ _qtol *= std::max(_0src, _zero);
- _mtol /= _csrc.count() ;
- _mtol /= _cdst.count() ;
+ _msrc = std::pow(
+ _csrc.count() / _msrc, +1./7.) ;
+ _mdst = std::pow(
+ _cdst.count() / _mdst, +1./7.) ;
- /*--------------------- calc. min. + mean delta's */
- real_type _0del , _mdel;
- _0del = _0dst - _0src;
- _mdel = _mdst - _msrc;
+ _qtol /=
+ std::pow(_csrc.count(), 1./7.) ;
+ _qtol /=
+ std::pow(_cdst.count(), 1./7.) ;
- _0del /= std::min(
- _cdst.count(),
- _csrc.count()) ;
-
- _mdel *= std::min(
- _cdst.count(),
- _csrc.count()) ;
-
- _0del =
- std::max(_0del,-_0tol) ;
- _mdel =
- std::max(_mdel,-_mtol) ;
-
- /*---------------------------- test move = 'okay' */
- if (true)
+ /*---------------------------- test move = "okay" */
+ if (_0dst >= _GOOD)
+ if (_0src >= _GOOD)
{
- /*--------------------- okay if min. is improving */
- if (_0dst > _0src+_0tol)
- if (_mdst > _msrc-_0del)
+ /*--------------------- okay if moves unconverged */
+ if (_xdel > _xtol)
_move = +1;
if (_move > +0) return ;
}
- if (_0dst >=
- std::pow(_good, +2))
+ if (_0dst >= _zero)
{
/*--------------------- okay if mean is improving */
- if (_mdst > _msrc+_mtol)
- if (_0dst > _0src-_mdel)
- _move = +1;
-
- if (_move > +0) return ;
- }
-
- if (_0dst >= _good)
- {
- /*--------------------- okay if moves unconverged */
- if (_xdel > _xtol)
- if (_0dst > _0src-_xdel)
- _move = +1;
-
- real_type _XDEL =
- _xdel/_cdst.count();
-
- if (_xdel > _xtol)
- if (_mdst > _msrc-_XDEL)
+ if (_mdst > _msrc+_qtol)
_move = +1;
if (_move > +0) return ;
@@ -408,39 +456,67 @@
__static_call
__normal_call real_type loop_cost (
mesh_type &_mesh ,
- pred_type &_pred ,
- iptr_list &_tset ,
+ conn_list &_cset ,
real_list &_cost ,
- tria_kind const&
+ cell_kind const& // cell costs on CSET
)
{
- real_type _qmin =
- +std::numeric_limits
- ::infinity();
-
- __unreferenced(_pred) ; // for MSVC...
+ real_type _qmin = (real_type)1. ;
- for (auto _tria = _tset.head(),
- _tend = _tset.tend();
- _tria != _tend;
- ++_tria )
+ for (auto _next = _cset.head() ,
+ _tend = _cset.tend() ;
+ _next != _tend;
+ ++_next )
{
- real_type _tscr =
- _pred.cost_tria (
- &_mesh._set1[
- _mesh._set3[
- *_tria].node(0)].pval(0),
- &_mesh._set1[
- _mesh._set3[
- *_tria].node(1)].pval(0),
- &_mesh._set1[
- _mesh._set3[
- *_tria].node(2)].pval(0)) ;
+ real_type _cscr = (real_type)+1. ;
+
+ iptr_type _cell = _next->_cell ;
+ iptr_type _kind = _next->_kind ;
+
+ switch (_kind)
+ {
+ case TRIA3_tag:
+ {
+ _cscr = pred_type::tri3_cost (
+ &_mesh .node(
+ _mesh .tri3(
+ _cell).node(0)).pval(0),
+ &_mesh .node(
+ _mesh .tri3(
+ _cell).node(1)).pval(0),
+ &_mesh .node(
+ _mesh .tri3(
+ _cell).node(2)).pval(0),
+ typename
+ pred_type::cell_kind ()) ;
+ break ;
+ }
+
+ case QUAD4_tag:
+ {
+ _cscr = pred_type::quad_cost (
+ &_mesh .node(
+ _mesh .quad(
+ _cell).node(0)).pval(0),
+ &_mesh .node(
+ _mesh .quad(
+ _cell).node(1)).pval(0),
+ &_mesh .node(
+ _mesh .quad(
+ _cell).node(2)).pval(0),
+ &_mesh .node(
+ _mesh .quad(
+ _cell).node(3)).pval(0),
+ typename
+ pred_type::cell_kind ()) ;
+ break ;
+ }
+ }
_qmin =
- std::min (_qmin, _tscr) ;
+ std::min (_qmin, _cscr) ;
- _cost.push_tail (_tscr) ;
+ _cost.push_tail (_cscr) ;
}
return ( _qmin ) ;
@@ -449,39 +525,67 @@
__static_call
__normal_call real_type loop_cost (
mesh_type &_mesh ,
- pred_type &_pred ,
- iptr_list &_tset ,
+ conn_list &_cset ,
real_list &_cost ,
- dual_kind const&
+ dual_kind const& // dual costs on CSET
)
{
- real_type _qmin =
- +std::numeric_limits
- ::infinity();
-
- __unreferenced(_pred) ; // for MSVC...
+ real_type _qmin = (real_type)1. ;
- for (auto _tria = _tset.head(),
- _tend = _tset.tend();
- _tria != _tend;
- ++_tria )
+ for (auto _next = _cset.head() ,
+ _tend = _cset.tend() ;
+ _next != _tend;
+ ++_next )
{
- real_type _tscr =
- _pred.cost_dual (
- &_mesh._set1[
- _mesh._set3[
- *_tria].node(0)].pval(0),
- &_mesh._set1[
- _mesh._set3[
- *_tria].node(1)].pval(0),
- &_mesh._set1[
- _mesh._set3[
- *_tria].node(2)].pval(0)) ;
+ real_type _cscr = (real_type)+1. ;
+
+ iptr_type _cell = _next->_cell ;
+ iptr_type _kind = _next->_kind ;
+
+ switch (_kind)
+ {
+ case TRIA3_tag:
+ {
+ _cscr = pred_type::tri3_cost (
+ &_mesh .node(
+ _mesh .tri3(
+ _cell).node(0)).pval(0),
+ &_mesh .node(
+ _mesh .tri3(
+ _cell).node(1)).pval(0),
+ &_mesh .node(
+ _mesh .tri3(
+ _cell).node(2)).pval(0),
+ typename
+ pred_type::dual_kind ()) ;
+ break ;
+ }
+
+ case QUAD4_tag:
+ {
+ _cscr = pred_type::quad_cost (
+ &_mesh .node(
+ _mesh .quad(
+ _cell).node(0)).pval(0),
+ &_mesh .node(
+ _mesh .quad(
+ _cell).node(1)).pval(0),
+ &_mesh .node(
+ _mesh .quad(
+ _cell).node(2)).pval(0),
+ &_mesh .node(
+ _mesh .quad(
+ _cell).node(3)).pval(0),
+ typename
+ pred_type::dual_kind ()) ;
+ break ;
+ }
+ }
_qmin =
- std::min (_qmin, _tscr) ;
+ std::min (_qmin, _cscr) ;
- _cost.push_tail (_tscr) ;
+ _cost.push_tail (_cscr) ;
}
return ( _qmin ) ;
@@ -489,7 +593,7 @@
/*
--------------------------------------------------------
- * MOVE-NODE: "smart" coord. update for single node.
+ * MOVE-NODE: "limited" single node coord. update.
--------------------------------------------------------
*/
@@ -502,31 +606,36 @@
__inline_call void_type move_node (
geom_type &_geom ,
mesh_type &_mesh ,
- size_type &_hfun ,
- pred_type &_pred ,
+ hfun_type &_hfun ,
real_list &_hval ,
iter_opts &_opts ,
node_iter _node ,
char_type _kern ,
iptr_type &_move ,
- iptr_list &_tset ,
- real_list &_told ,
- real_list &_tnew ,
- real_type _TMIN ,
- real_type _TLIM
+ conn_list &_conn ,
+ real_list &_qold ,
+ real_list &_qnew ,
+ real_type _QMIN ,
+ real_type _QLIM
)
{
+ /*---------------- try variational; fallback on dQ/dx */
+ real_type _last[geom_dims] =
+ {(real_type) +0.00};
+
move_kern( _geom, _mesh, _hfun,
- _pred, _hval, _opts, _node,
- _kern, _move, _tset, _told,
- _tnew, _TMIN, _TLIM) ;
+ _hval, _opts, _node, _last,
+ _kern, _move, _conn,
+ _qold, _qnew,
+ _QMIN, _QLIM) ; // variational
if (_move >= +0 ) return ;
move_kern( _geom, _mesh, _hfun,
- _pred, _hval, _opts, _node,
- dqdx_kern, _move, _tset, _told,
- _tnew, _TMIN, _TLIM) ;
+ _hval, _opts, _node, _last,
+ dqdx_kern, _move, _conn,
+ _qold, _qnew,
+ _QMIN, _QLIM) ; // local dQ/dx
if (_move >= +0 ) return ;
}
@@ -538,41 +647,44 @@
__normal_call void_type move_kern (
geom_type &_geom ,
mesh_type &_mesh ,
- size_type &_hfun ,
- pred_type &_pred ,
+ hfun_type &_hfun ,
real_list &_hval ,
iter_opts &_opts ,
node_iter _node ,
+ real_type *_last ,
char_type _kern ,
iptr_type &_move ,
- iptr_list &_tset ,
- real_list &_told ,
- real_list &_tnew ,
- real_type _TMIN ,
- real_type _TLIM
+ conn_list &_conn ,
+ real_list &_qold ,
+ real_list &_qnew ,
+ real_type _QMIN ,
+ real_type _QLIM
)
{
+ /*---------------- optimise single node's coordinates */
iptr_type static
- constexpr _ITER = (iptr_type)+5 ;
+ constexpr _ITER = (iptr_type) +4 ;
_move = (iptr_type)-1 ;
/*---------------- calc. line search direction vector */
- real_type _line [_dims] = {
- (real_type) +0.0 } ;
- real_type _save [_dims] = {
- (real_type) +0.0 } ;
- real_type _proj [_dims] = {
- (real_type) +0.0 } ;
+ real_type _line[geom_dims] =
+ {(real_type)+0.0} ;
+
+ real_type _save[geom_dims] =
+ {(real_type)+0.0} ;
- real_type _ladj = (real_type) +0.00 ;
+ real_type _proj[geom_dims] =
+ {(real_type)+0.0} ;
+
+ real_type _ladj = (real_type) +0. ;
if (_kern == _odt_kern)
{
/*--------------------------- ODT-style update vector */
_odt_move_2 (
- _mesh, _hfun, _pred ,
- _hval, _tset, _node ,
+ _geom, _mesh, _hfun, _hval,
+ _conn, _node,
_line, _ladj) ;
}
else
@@ -580,81 +692,97 @@
{
/*--------------------------- CVT-style update vector */
_cvt_move_2 (
- _mesh, _hfun, _pred ,
- _hval, _tset, _node ,
+ _geom, _mesh, _hfun, _hval,
+ _conn, _node,
_line, _ladj) ;
}
else
if (_kern == dqdx_kern)
{
- if (_TMIN<=_TLIM)
+ if (_QMIN<=_QLIM)
{
/*--------------------------- d./dx Q^T update vector */
dqdx_move_2 (
- _mesh, _hfun, _pred ,
- _tset, _node, _told ,
+ _mesh, _conn, _node, _qold,
_line, _ladj) ;
}
else { return ; }
}
/*---------------- scale line search direction vector */
- real_type _xtol = // delta_x reltol
- (real_type) +5.00E-004 ;
-
real_type _xeps = // delta_x ~= 0.0
- (real_type)+.01 *_opts.qtol() ;
+ (real_type)+0.01*_opts.qtol() ;
- if (_kern == dqdx_kern)
+ real_type _xtol = // delta_x reltol
+ +std::sqrt(_opts.qtol()) / +10.0 ;
+
+ if (_kern == dqdx_kern) // test cost-only
{
- _xtol = (real_type)+1. ;
+ _QLIM =
+ +std::numeric_limits::infinity() ;
}
+ auto _ppos = &_node->pval(0) ;
+
real_type _lsqr ;
_lsqr = std::pow(_ladj, 2) ;
- _xtol = std::pow(_xtol, 2) ;
_xeps = std::pow(_xeps, 2) ;
+ _xtol = std::pow(_xtol, 2) ;
real_type _scal = // overrelaxation
- (real_type) +5.0 / 4.0 ;
+ (real_type) +1.0 / 1.0 ;
/*---------------- do backtracking line search iter's */
- for (auto _idim = _dims; _idim-- != +0; )
+ if (_kern == dqdx_kern) // "relax" dQ./dx
{
- _save[_idim] =
- _node->pval(_idim) ;
+ real_type _BIAS =
+ (real_type) +3.0 / 4.0 ;
- //_line[_idim] /= _llen ;
+ for (auto _idim =
+ pred_type::geom_dims; _idim-- != +0; )
+ {
+ _line[_idim] =
+ (+0. + _BIAS) * _line [_idim] +
+ (+1. - _BIAS) * _last [_idim] ;
+ }
}
- for (auto _iter = +0 ;
- _iter != _ITER ; ++_iter)
+ for (auto _idim =
+ pred_type::geom_dims; _idim-- != +0; )
{
- _tnew.set_count(0) ;
+ _save[_idim] = _ppos [_idim] ;
+ _last[_idim] = _line [_idim] ;
+ }
+ for (auto _iter = +0 ;
+ _iter != _ITER; ++_iter )
+ {
/*---------------- push update along search direction */
- for (auto _idim = _dims; _idim-- != +0; )
+ for (auto _idim =
+ pred_type::geom_dims; _idim-- != +0; )
{
_proj[_idim] =
_save[_idim] +
- _scal * _line[_idim];
+ _scal* _line[_idim] ;
}
- _pred.proj_node (
- _geom, _save, _proj) ;
+ pred_type::
+ proj_node (_geom, _save, _proj) ;
- for (auto _idim = _dims; _idim-- != +0; )
+ for (auto _idim =
+ pred_type::geom_dims; _idim-- != +0; )
{
- _node->pval(_idim)
- = _proj[_idim] ;
+ _ppos[_idim] = _proj[_idim] ;
}
- real_type _XTOL = _xtol * _scal ;
real_type _XEPS = _xeps * _scal ;
+ real_type _XTOL = _xtol * _scal ;
+
+ real_type _lmov =
+ pred_type::length_sq(_save, _proj) ;
- real_type _lmov = _pred.
- length_sq(_save , _proj)/ _lsqr ;
+ _lmov = _lmov / _lsqr;
if (_lmov <= _XEPS) break ;
@@ -663,25 +791,25 @@
_scal *= (real_type).5 ;
/*---------------- test quasi-monotonicity w.r.t. Q^T */
- loop_cost( _mesh, _pred,
- _tset,
- _tnew,
- tria_kind()) ;
+ _qnew.set_count(0) ;
+
+ loop_cost( _mesh, _conn, _qnew,
+ cell_kind ()) ;
- move_okay( _tnew,
- _told, _move,
- _TLIM, _opts.qtol(),
- _lmov, _XTOL) ;
+ move_okay( _qnew, _qold, _move,
+ _QLIM, _opts.qtol(),
+ _lmov, _XTOL ) ;
- if (_move > 0) break ;
+ if (_move > +0) break ;
}
- if (_move <= (iptr_type)0)
+ /*---------------- swap with the saved coord. if fail */
+ if (_move <= +0)
{
- for (auto _idim = _dims; _idim-- != +0; )
+ for (auto _idim =
+ pred_type::geom_dims; _idim-- != +0; )
{
- _node->pval(_idim)
- = _save[_idim] ;
+ _ppos[_idim] = _save[_idim] ;
}
}
@@ -689,11 +817,11 @@
/*
--------------------------------------------------------
- * MOVE-DUAL: "smart" weight update for single node.
+ * MOVE-DUAL: "limited" single node weight update.
--------------------------------------------------------
*/
- #include "iter_dual_2.inc"
+ #include "iter_dual_2.inc"
template <
typename node_iter
@@ -702,90 +830,90 @@
__normal_call void_type move_dual (
geom_type &_geom ,
mesh_type &_mesh ,
- size_type &_hfun ,
- pred_type &_pred ,
+ hfun_type &_hfun ,
real_list &_hval ,
iter_opts &_opts ,
node_iter _node ,
iptr_type &_move ,
- iptr_list &_tset ,
+ conn_list &_conn ,
real_list &_dold ,
real_list &_dnew ,
real_type _DMIN ,
real_type _DLIM
)
{
+ /*---------------- optimise single node's coordinates */
iptr_type static
- constexpr _ITER = (iptr_type)+5 ;
+ constexpr _ITER = (iptr_type) +4 ;
+ __unreferenced(_geom);
+ __unreferenced(_hfun);
__unreferenced(_hval);
- __unreferenced(_DMIN);
_move = (iptr_type)-1;
real_type _wadj, _step, _save;
/*---------------- calc. line search direction vector */
- if (true) // (_DMIN < _DLIM)
+ if (_DMIN <= _DLIM)
{
dqdw_move_2 (
- _geom, _mesh, _hfun,
- _pred, _tset, _node,
- _dold, _step, _wadj) ;
+ _mesh, _conn, _node, _dold,
+ _step, _wadj) ;
}
else { return ; }
/*---------------- scale line search direction vector */
- real_type _xeps = // delta_w ~= 0.0
- (real_type)+.01 *_opts.qtol() ;
+ real_type _weps = // delta_w ~= 0.0
+ (real_type)+0.01*_opts.qtol() ;
real_type _scal = // overrelaxation
- (real_type) +5.0 / 4.0 ;
+ (real_type) +1.0 / 1.0 ;
- _save = _node->pval(_dims) ;
+ _save = _node->pval(
+ pred_type::real_dims- 1) ;
/*---------------- do backtracking line search iter's */
for (auto _iter = +0 ;
_iter != _ITER; ++_iter )
{
- _node->pval(_dims) =
- _save + _scal * _step ;
+ _node->pval(real_dims-1) =
+ _save + ( _scal * _step ) ;
- _node->pval(_dims) = // not too large!
- std::max(-_wadj,
- _node->pval(_dims));
- _node->pval(_dims) =
- std::min(+_wadj,
- _node->pval(_dims));
+ _node->pval(real_dims-1) =
+ std::max(-_wadj ,
+ _node->pval(real_dims-1));
+
+ _node->pval(real_dims-1) =
+ std::min(+_wadj ,
+ _node->pval(real_dims-1));
real_type _wmov =
- std::abs (_save
- - _node->pval(_dims));
+ std::abs (_save -
+ _node->pval(real_dims-1));
if (_wmov <=
- _xeps * _scal * _wadj) break;
-
- _dnew.set_count(0);
+ _weps * _scal * _wadj) break;
_scal *= (real_type).5 ;
/*---------------- test quasi-monotonicity w.r.t. Q^D */
- loop_cost( _mesh, _pred,
- _tset,
- _dnew,
- dual_kind()) ;
+ _dnew.set_count(0) ;
- move_okay( _dnew,
- _dold, _move,
- _DLIM, _opts.qtol()) ;
+ loop_cost( _mesh, _conn, _dnew,
+ dual_kind ()) ;
- if (_move > 0) break ;
+ move_okay( _dnew, _dold, _move,
+ +1. , _opts.qtol()) ;
+
+ if (_move > +0) break ;
}
- if (_move <= (iptr_type) +0)
+ /*---------------- swap with the saved coord. if fail */
+ if (_move <= +0)
{
- _node->pval(_dims) = _save ;
+ _node->pval(real_dims-1) = _save ;
}
}
@@ -796,33 +924,56 @@
--------------------------------------------------------
*/
- __static_call void_type sort_node (
- geom_type &_geom ,
+ __static_call
+ __normal_call void_type sort_node (
mesh_type &_mesh ,
- size_type &_hfun ,
- pred_type &_pred ,
- real_list &_hval ,
- real_list &_qscr ,
iptr_list &_nset ,
iptr_list &_aset ,
- iptr_list &_amrk ,
iptr_list &_nmrk ,
+ iptr_list &_amrk ,
iptr_type _iout ,
iptr_type _isub ,
- iter_opts &_opts ,
- real_type _TLIM ,
- real_type _DLIM
+ iter_opts &_opts
)
{
+ # define PUSHSORT(_NODE) \
+ if (_amrk[_NODE] != _isub) \
+ { \
+ _amrk[_NODE] = _isub; \
+ _sset.push_tail( \
+ cost_pair(_NODE, 1.)) ; \
+ }
+
+ # define PUSHCONN(_NODE) \
+ if (_amrk[_NODE] != _isub) \
+ { \
+ _amrk[_NODE] = _isub; \
+ _aset.push_tail(_NODE) ; \
+ }
+
+ # define PUSHCOST(_NODE , _COST) \
+ _qbar[_NODE] += _COST ; \
+ _nadj[_NODE] += +1 ;\
+ _qmin[_NODE] = \
+ std::min (_qmin[_NODE], _COST) ;
+
class cost_pair
{
public :
/*------------------------ tuple for node re-ordering */
iptr_type _node ;
float _cost ;
+
+ /*------------------------ construct inline from src. */
+ __inline_call cost_pair (
+ iptr_type const&_nsrc ,
+ real_type const&_csrc
+ ) :
+ _node (_nsrc),
+ _cost((float)_csrc) {}
} ;
- class cost_less
+ class cost_pred
{
public :
/*------------------------ less-than op. for cost-tup */
@@ -831,123 +982,138 @@
cost_pair const&_idat ,
cost_pair const&_jdat
) const
- { return
- _idat._cost < _jdat._cost ;
+ { return _idat._cost > _jdat._cost ;
}
} ;
- typedef containers::
- arraycost_list ;
+ typedef
+ containers::array cost_list ;
- iptr_list _eset ;
+ real_list _qbar, _qmin ;
+ iptr_list _nadj ;
+ conn_list _conn ;
cost_list _sset ;
- __unreferenced(_geom) ;
- __unreferenced(_hfun) ;
- __unreferenced(_pred) ;
- __unreferenced(_hval) ;
__unreferenced(_opts) ;
- __unreferenced(_DLIM) ;
- if (_isub == (iptr_type) +0 )
+ if (_isub == (iptr_type) +0)
{
/*-------------------- 1ST SUB-ITER: build full init. */
- for (auto _iter = _qscr.head();
- _iter != _qscr.tend();
- ++_iter )
- {
- *_iter = (real_type) +1.;
- }
+ _qbar.set_count(
+ _mesh.node().count(),
+ containers::tight_alloc, +0.0) ;
- for (auto _tria = _mesh._set3.head();
- _tria != _mesh._set3.tend();
+ _qmin.set_count(
+ _mesh.node().count(),
+ containers::tight_alloc, +1.0) ;
+
+ _nadj.set_count(
+ _mesh.node().count(),
+ containers::tight_alloc, + 0 ) ;
+
+ for (auto _tria = _mesh.tri3().head() ;
+ _tria != _mesh.tri3().tend() ;
++_tria )
{
- if (_tria->mark() >= +0 )
+ if (_tria->mark() >= +0)
{
/*-------------------- calc. min. scores at nodes */
iptr_type _inod, _jnod, _knod;
- _inod = _tria->node(0);
- _jnod = _tria->node(1);
- _knod = _tria->node(2);
-
- real_type _cost =
- _pred.cost_tria (
- &_mesh._set1[_inod].pval(0),
- &_mesh._set1[_jnod].pval(0),
- &_mesh._set1[_knod].pval(0)
- ) ;
-
- iptr_type _flag = _iout-2 ;
-
- real_type _TURN =
- std::pow(_TLIM, 1./4.);
-
- if (_cost <= _TURN ||
- std::abs(
- _nmrk[_inod])>= _flag ||
- std::abs(
- _nmrk[_jnod])>= _flag ||
- std::abs(
- _nmrk[_knod])>= _flag )
- {
-
- if (_amrk[_inod] != _isub )
- {
- _amrk[_inod] = _isub ;
- _sset.push_tail() ;
- _sset.tail()->
- _node = _inod ;
- }
-
- if (_amrk[_jnod] != _isub )
- {
- _amrk[_jnod] = _isub ;
- _sset.push_tail() ;
- _sset.tail()->
- _node = _jnod ;
- }
-
- if (_amrk[_knod] != _isub )
- {
- _amrk[_knod] = _isub ;
- _sset.push_tail() ;
- _sset.tail()->
- _node = _knod ;
- }
-
- }
-
- _qscr[_inod] = std::min (
- _cost,_qscr[_inod]) ;
-
- _qscr[_jnod] = std::min (
- _cost,_qscr[_jnod]) ;
+ _inod = _tria->node( 0);
+ _jnod = _tria->node( 1);
+ _knod = _tria->node( 2);
+
+ real_type _cost;
+ _cost = pred_type::tri3_cost (
+ &_mesh .node(
+ _tria->node(0)).pval(0),
+ &_mesh .node(
+ _tria->node(1)).pval(0),
+ &_mesh .node(
+ _tria->node(2)).pval(0),
+ typename
+ pred_type::cell_kind ()) ;
+
+ PUSHSORT( _inod )
+ PUSHCOST( _inod, _cost )
+ PUSHSORT( _jnod )
+ PUSHCOST( _jnod, _cost )
+ PUSHSORT( _knod )
+ PUSHCOST( _knod, _cost )
+ }
+ }
- _qscr[_knod] = std::min (
- _cost,_qscr[_knod]) ;
+ for (auto _quad = _mesh.quad().head() ;
+ _quad != _mesh.quad().tend() ;
+ ++_quad )
+ {
+ if (_quad->mark() >= +0)
+ {
+ /*-------------------- calc. min. scores at nodes */
+ iptr_type _inod, _jnod, _knod,
+ _lnod;
+ _inod = _quad->node( 0);
+ _jnod = _quad->node( 1);
+ _knod = _quad->node( 2);
+ _lnod = _quad->node( 3);
+
+ real_type _cost;
+ _cost = pred_type::quad_cost (
+ &_mesh .node(
+ _quad->node(0)).pval(0),
+ &_mesh .node(
+ _quad->node(1)).pval(0),
+ &_mesh .node(
+ _quad->node(2)).pval(0),
+ &_mesh .node(
+ _quad->node(3)).pval(0),
+ typename
+ pred_type::cell_kind ()) ;
+
+ PUSHSORT( _inod )
+ PUSHCOST( _inod, _cost )
+ PUSHSORT( _jnod )
+ PUSHCOST( _jnod, _cost )
+ PUSHSORT( _knod )
+ PUSHCOST( _knod, _cost )
+ PUSHSORT( _lnod )
+ PUSHCOST( _lnod, _cost )
}
}
+ for (auto _iter =
+ _qbar.count(); _iter-- != +0; )
+ {
+ /*------------------------ assign score for each node */
+ _qbar[_iter] /=
+ std::max(+1, _nadj [_iter]) ;
+ }
+
for (auto _iter = _sset.head() ;
_iter != _sset.tend() ;
++_iter )
{
- /*------------------------ assign min.-cost for nodes */
_iter->_cost =
- (float)_qscr[_iter->_node];
+ (float)_qbar [_iter->_node] -
+ (float)_qmin [_iter->_node] ;
}
algorithms::qsort( _sset.head() ,
_sset.tend() ,
- cost_less () ) ;
+ cost_pred () ) ;
+
+ iptr_type _FLAG = _iout - 8 ; // append "recent"
for (auto _iter = _sset.head() ;
_iter != _sset.tend() ;
++_iter )
{
/*------------------------ push sorted wrt. min.-cost */
- _aset.push_tail(_iter->_node) ;
+ if (std::abs(
+ _nmrk[_iter->_node]) >= _FLAG )
+ {
+ _aset.push_tail( _iter->_node ) ;
+ }
}
}
@@ -966,38 +1132,61 @@
_iter != _nset.tend() ;
++_iter )
{
- _eset.set_count(0) ;
-
- _mesh.node_edge (
- &*_iter, _eset) ;
-
- for (auto _edge = _eset.head();
- _edge != _eset.tend();
- ++_edge )
+ /*-------------------- push any 1-cell neighbours */
+ _conn.set_count(0) ;
+ _mesh.connect_1(
+ &*_iter, POINT_tag, _conn);
+
+ for (auto _next = _conn.head();
+ _next != _conn.tend();
+ ++_next )
+ {
+ if (_next->_kind == EDGE2_tag)
{
auto _eptr =
- _mesh._set2.head() + *_edge;
+ _mesh. edge().head()+_next->_cell ;
- iptr_type _inod, _jnod;
- _inod = _eptr->node(0);
- _jnod = _eptr->node(1);
+ PUSHCONN( _eptr->node(0) )
+ PUSHCONN( _eptr->node(1) )
+ }
+ }
- if (_amrk[_inod] != _isub)
- {
- _amrk[_inod] = _isub;
- _aset.push_tail(_inod) ;
- }
+ /*-------------------- push any 2-cell neighbours */
+ _conn.set_count(0) ;
+ _mesh.connect_2(
+ &*_iter, POINT_tag, _conn);
- if (_amrk[_jnod] != _isub)
- {
- _amrk[_jnod] = _isub;
- _aset.push_tail(_jnod) ;
- }
+ for (auto _next = _conn.head();
+ _next != _conn.tend();
+ ++_next )
+ {
+ if (_next->_kind == TRIA3_tag)
+ {
+ auto _tptr =
+ _mesh. tri3().head()+_next->_cell ;
+
+ PUSHCONN( _tptr->node(0) )
+ PUSHCONN( _tptr->node(1) )
+ PUSHCONN( _tptr->node(2) )
}
- }
+ else
+ if (_next->_kind == QUAD4_tag)
+ {
+ auto _qptr =
+ _mesh. quad().head()+_next->_cell ;
+ PUSHCONN( _qptr->node(0) )
+ PUSHCONN( _qptr->node(1) )
+ PUSHCONN( _qptr->node(2) )
+ PUSHCONN( _qptr->node(3) )
+ }
+ }
}
+ }
+ # undef PUSHCOST
+ # undef PUSHSORT
+ # undef PUSHCONN
}
/*
@@ -1010,40 +1199,33 @@
__normal_call void_type move_node (
geom_type &_geom ,
mesh_type &_mesh ,
- size_type &_hfun ,
- pred_type &_pred ,
+ hfun_type &_hfun ,
char_type _kern ,
real_list &_hval ,
- real_list &_qscr ,
iptr_list &_nset ,
iptr_list &_amrk ,
- iptr_list &_nmrk ,
- iptr_list &_emrk ,
- iptr_list &_tmrk ,
+ mark_list &_mark ,
iptr_type _iout ,
iptr_type _isub ,
iter_opts &_opts ,
iptr_type &_nmov ,
- real_type _TLIM ,
- real_type _DLIM
+ real_type _QLIM
)
{
- iptr_list _aset, _tset;
- real_list _told, _tnew, _dold, _dnew;
-
- __unreferenced ( _emrk) ;
- __unreferenced ( _tmrk) ;
+ # define MARK(_NODE) _mark._node[_NODE]
- _nmov = (iptr_type) +0 ;
+ iptr_list _aset;
+ conn_list _conn;
+ real_list _qold, _qnew, _dold, _dnew;
/*-------------------- permute nodes for optimisation */
- sort_node( _geom, _mesh, _hfun,
- _pred, _hval, _qscr,
- _nset, _aset,
- _amrk, _nmrk, _iout, _isub,
- _opts, _TLIM, _DLIM ) ;
+ sort_node(_mesh, _nset, _aset,
+ _mark._node, _amrk, _iout, _isub,
+ _opts) ;
- /*-------------------- GAUSS-SEIDEL iteration on TRIA */
+ _nmov = (iptr_type) +0;
+
+ /*-------------------- GAUSS-SEIDEL iteration on CELL */
if (_opts .tria())
{
for (auto _apos = _aset.head() ;
@@ -1051,54 +1233,52 @@
++_apos )
{
auto _node =
- _mesh._set1.head() + *_apos ;
-
- _tset.set_count( +0);
+ _mesh.node().head()+ *_apos ;
/*---------------- assemble a local tria. stencil */
- _mesh.node_tri3(
- &_node->node(+0), _tset);
+ _conn.set_count( +0) ;
+ _mesh.connect_2(
+ &*_apos, POINT_tag, _conn);
- if (_tset.empty()) continue ;
+ if (_conn.empty()) continue ;
- if (_nmrk[*_apos] >= +0)
+ if (_mark._node[*_apos] >= +0)
{
- /*---------------- attempt to optimise TRIA geom. */
- _told.set_count( +0);
- _tnew.set_count( +0);
+ /*---------------- attempt to optimise CELL geom. */
+ _qold.set_count( +0) ;
+ _qnew.set_count( +0) ;
- real_type _TMIN =
- loop_cost( _mesh,
- _pred, _tset,
- _told, tria_kind());
+ real_type _QMIN =
+ loop_cost( _mesh,
+ _conn, _qold, cell_kind());
- iptr_type _move = -1;
+ iptr_type _move = -1 ;
if(_move < +0)
{
/*---------------- do optimisation of node coord. */
- move_node( _geom, _mesh ,
- _hfun, _pred, _hval ,
- _opts, _node, _kern ,
- _move, _tset,
- _told, _tnew,
- _TMIN, _TLIM ) ;
+ move_node( _geom, _mesh,
+ _hfun, _hval,
+ _opts, _node, _kern,
+ _move, _conn,
+ _qold, _qnew,
+ _QMIN, _QLIM ) ;
}
if (_move > +0)
{
/*---------------- update when state is improving */
- _hval[*_apos] = (real_type)-1. ;
+ _hval[*_apos] = (real_type)-1;
if (std::abs(
- _nmrk[*_apos]) != _iout)
+ MARK( *_apos )) != _iout)
{
- if (_nmrk[*_apos] >= 0)
- _nmrk[*_apos] = +_iout;
+ if (MARK( *_apos ) >= 0)
+ MARK( *_apos ) = +_iout;
else
- _nmrk[*_apos] = -_iout;
+ MARK( *_apos ) = -_iout;
- _nset.push_tail(*_apos) ;
+ _nset.push_tail (*_apos) ;
}
_nmov += +1 ;
@@ -1106,6 +1286,43 @@
}
}
}
+ # undef MARK
+ }
+
+ /*
+ --------------------------------------------------------
+ * MOVE-DUAL: do a single dual smoothing pass.
+ --------------------------------------------------------
+ */
+
+ __static_call
+ __normal_call void_type move_dual (
+ geom_type &_geom ,
+ mesh_type &_mesh ,
+ hfun_type &_hfun ,
+ real_list &_hval ,
+ iptr_list &_nset ,
+ iptr_list &_amrk ,
+ mark_list &_mark ,
+ iptr_type _iout ,
+ iptr_type _isub ,
+ iter_opts &_opts ,
+ iptr_type &_nmov ,
+ real_type _DLIM
+ )
+ {
+ # define MARK(_NODE) _mark._node[_NODE]
+
+ iptr_list _aset;
+ conn_list _conn;
+ real_list _qold, _qnew, _dold, _dnew;
+
+ /*-------------------- permute nodes for optimisation */
+ sort_node(_mesh, _nset, _aset,
+ _mark._node, _amrk, _iout, _isub,
+ _opts) ;
+
+ _nmov = (iptr_type) +0;
/*-------------------- GAUSS-SEIDEL iteration on DUAL */
if (_opts .dual())
@@ -1115,34 +1332,32 @@
++_apos )
{
auto _node =
- _mesh._set1.head() + *_apos ;
-
- _tset.set_count( +0);
+ _mesh.node().head()+ *_apos ;
/*---------------- assemble a local tria. stencil */
- _mesh.node_tri3(
- &_node->node(+0), _tset);
+ _conn.set_count( +0) ;
+ _mesh.connect_2(
+ &*_apos, POINT_tag, _conn);
- if (_tset.empty()) continue ;
+ if (_conn.empty()) continue ;
/*---------------- attempt to optimise DUAL geom. */
- _dold.set_count( +0);
- _dnew.set_count( +0);
+ _dold.set_count( +0) ;
+ _dnew.set_count( +0) ;
- real_type _DMIN =
- loop_cost( _mesh,
- _pred, _tset,
- _dold, dual_kind());
+ real_type _DMIN =
+ loop_cost( _mesh,
+ _conn, _dold, dual_kind());
- iptr_type _move = -1;
+ iptr_type _move = -1 ;
if(_move < +0)
{
/*---------------- do optimisation of node weight */
- move_dual( _geom, _mesh ,
- _hfun, _pred, _hval ,
+ move_dual( _geom, _mesh,
+ _hfun, _hval,
_opts, _node,
- _move, _tset,
+ _move, _conn,
_dold, _dnew,
_DMIN, _DLIM ) ;
}
@@ -1151,21 +1366,21 @@
{
/*---------------- update when state is improving */
if (std::abs(
- _nmrk[*_apos]) != _iout)
+ MARK( *_apos )) != _iout)
{
- if (_nmrk[*_apos] >= 0)
- _nmrk[*_apos] = +_iout;
+ if (MARK( *_apos ) >= 0)
+ MARK( *_apos ) = +_iout;
else
- _nmrk[*_apos] = -_iout;
+ MARK( *_apos ) = -_iout;
- _nset.push_tail(*_apos) ;
+ _nset.push_tail (*_apos) ;
}
_nmov += +1 ;
}
}
}
-
+ # undef MARK
}
/*
@@ -1176,143 +1391,63 @@
#include "iter_flip_2.inc"
- __static_call
- __inline_call void_type flip_tria (
- geom_type &_geom ,
- mesh_type &_mesh ,
- size_type &_hfun ,
- pred_type &_pred ,
- iptr_type _tria ,
- bool_type &_flip ,
- iptr_list &_told ,
- iptr_list &_tnew ,
- real_list &_qold ,
- real_list &_qnew
- )
- {
- _flip = false ;
-
- auto
- _coin = std::rand() % +3 ;
-
- if (_coin == +0)
- {
- /*--------------------------------- flip edges: 0,1,2 */
- flip_t2t2( _geom, _mesh ,
- _hfun, _pred,
- _tria, +0 ,
- _told, _tnew, _flip ,
- _qold, _qnew) ;
- if (_flip) return ;
-
- flip_t2t2( _geom, _mesh ,
- _hfun, _pred,
- _tria, +1 ,
- _told, _tnew, _flip ,
- _qold, _qnew) ;
- if (_flip) return ;
-
- flip_t2t2( _geom, _mesh ,
- _hfun, _pred,
- _tria, +2 ,
- _told, _tnew, _flip ,
- _qold, _qnew) ;
- if (_flip) return ;
- }
- else
- if (_coin == +1)
- {
- /*--------------------------------- flip edges: 1,2,0 */
- flip_t2t2( _geom, _mesh ,
- _hfun, _pred,
- _tria, +1 ,
- _told, _tnew, _flip ,
- _qold, _qnew) ;
- if (_flip) return ;
-
- flip_t2t2( _geom, _mesh ,
- _hfun, _pred,
- _tria, +2 ,
- _told, _tnew, _flip ,
- _qold, _qnew) ;
- if (_flip) return ;
-
- flip_t2t2( _geom, _mesh ,
- _hfun, _pred,
- _tria, +0 ,
- _told, _tnew, _flip ,
- _qold, _qnew) ;
- if (_flip) return ;
- }
- else
- {
- /*--------------------------------- flip edges: 2,0,1 */
- flip_t2t2( _geom, _mesh ,
- _hfun, _pred,
- _tria, +2 ,
- _told, _tnew, _flip ,
- _qold, _qnew) ;
- if (_flip) return ;
-
- flip_t2t2( _geom, _mesh ,
- _hfun, _pred,
- _tria, +0 ,
- _told, _tnew, _flip ,
- _qold, _qnew) ;
- if (_flip) return ;
-
- flip_t2t2( _geom, _mesh ,
- _hfun, _pred,
- _tria, +1 ,
- _told, _tnew, _flip ,
- _qold, _qnew) ;
- if (_flip) return ;
- }
-
- }
-
__static_call
__normal_call void_type flip_mesh (
geom_type &_geom ,
mesh_type &_mesh ,
- size_type &_hfun ,
- pred_type &_pred ,
+ hfun_type &_hfun ,
iptr_list &_nset ,
- iptr_list &_nmrk ,
- iptr_list &_emrk ,
- iptr_list &_tmrk ,
+ mark_list &_mark ,
iptr_type _imrk ,
iptr_type &_nflp
)
{
- init_mark(_mesh, _nmrk, _emrk, _tmrk,
- std::max(+0, _imrk - 1)) ;
+ # define MARKTRI3(_CELL) \
+ _mark._tri3[_CELL->_cell]
+
+ # define MARKQUAD(_CELL) \
+ _mark._quad[_CELL->_cell]
+
+ init_mark(_mesh, _mark ,
+ std::max(+0, _imrk - 1) ) ;
+
+ __unreferenced ( _hfun);
/*--------------------- init. flip stack as ADJ(NSET) */
- iptr_list _tset, _next;
- iptr_list _told, _tnew;
- real_list _qold, _qnew;
+ conn_list _flip, _next ;
+ conn_list _conn, _CONN ;
+ real_list _qold, _qnew ;
for (auto _iter = _nset.head();
_iter != _nset.tend();
++_iter )
{
- if ( _mesh.
- _set1[*_iter].mark() >= +0)
+ if (_mesh.node(*_iter).mark() >= +0)
{
- _tnew.set_count(+0);
-
- _mesh.node_tri3(
- &*_iter, _tnew);
+ _conn.set_count(0);
+ _mesh.connect_2(
+ &*_iter, POINT_tag, _conn);
- for (auto _tadj = _tnew.head();
- _tadj != _tnew.tend();
- ++_tadj )
+ for (auto _cell = _conn.head();
+ _cell != _conn.tend();
+ ++_cell )
{
- if (_tmrk[*_tadj] != _imrk)
+ if (_cell->_kind == TRIA3_tag)
{
- _tmrk[*_tadj] = _imrk;
- _tset.push_tail(*_tadj) ;
+ if (MARKTRI3( _cell ) != _imrk)
+ {
+ MARKTRI3( _cell ) = _imrk;
+ _flip.push_tail(*_cell) ;
+ }
+ }
+ else
+ if (_cell->_kind == QUAD4_tag)
+ {
+ if (MARKQUAD( _cell ) != _imrk)
+ {
+ MARKQUAD( _cell ) = _imrk;
+ _flip.push_tail(*_cell) ;
+ }
}
}
}
@@ -1321,34 +1456,63 @@
/*--------------------- exhaustive, incremental flips */
_nflp = +0 ;
- for ( ; !_tset.empty() ; )
+ for ( ; !_flip.empty() ; )
{
- for (auto _tria = _tset.head();
- _tria != _tset.tend();
- ++_tria )
+ for (auto _cell = _flip.head();
+ _cell != _flip.tend();
+ ++_cell )
{
+ if (_cell->_kind == TRIA3_tag)
+ {
if ( _mesh.
- _set3[*_tria].mark() >= +0)
+ tri3(_cell->_cell).mark() >= +0)
{
- bool_type _flip = false ;
- flip_tria( _geom, _mesh,
- _hfun, _pred,
- *_tria, _flip,
- _told, _tnew,
+ bool_type _okay = false ;
+
+ flip_tri3( _geom, _mesh,
+ _cell->_cell,
+ _okay, _conn, _CONN,
_qold, _qnew );
- if (_flip) _nflp += +1 ;
- for (auto _iter = _tnew.head();
- _iter != _tnew.tend();
+ if (_okay) _nflp += +1 ;
+
+ for (auto _iter = _CONN.head();
+ _iter != _CONN.tend();
++_iter )
{
- _next.push_tail(*_iter) ;
+ _next. push_tail(*_iter) ;
}
}
+ }
+ else
+ if (_cell->_kind == QUAD4_tag)
+ {
+ if ( _mesh.
+ quad(_cell->_cell).mark() >= +0)
+ {
+ bool_type _okay = false ;
+
+ //flip_quad( _geom, _mesh,
+ // _cell->_cell,
+ // _okay, _conn, _CONN,
+ // _qold, _qnew );
+
+ if (_okay) _nflp += +1 ;
+
+ for (auto _iter = _CONN.head();
+ _iter != _CONN.tend();
+ ++_iter )
+ {
+ _next. push_tail(*_iter) ;
+ }
+ }
+ }
}
- _tset = std::move(_next) ;
+ _flip = std::move (_next) ;
}
+ # undef MARKQUAD
+ # undef MARKTRI3
}
/*
@@ -1364,17 +1528,14 @@
__normal_call void_type _zip_mesh (
geom_type &_geom ,
mesh_type &_mesh ,
- size_type &_hfun ,
- pred_type &_pred ,
+ hfun_type &_hfun ,
char_type _kern ,
real_list &_hval ,
iptr_list &_nset ,
- iptr_list &_nmrk ,
- iptr_list &_emrk ,
- iptr_list &_tmrk ,
+ mark_list &_mark ,
iptr_type _imrk ,
iter_opts &_opts ,
- real_type _TLIM ,
+ real_type _QLIM ,
real_type _DLIM ,
iptr_type &_nzip ,
iptr_type &_ndiv
@@ -1384,10 +1545,17 @@
{
public :
/*------------------------ tuple for edge re-ordering */
- iptr_type _edge ;
+ iptr_type _inod ;
+ iptr_type _jnod ;
float _cost ;
+ public :
+ __inline_call sort_pair (
+ iptr_type _isrc ,
+ iptr_type _jsrc ,
+ float _csrc
+ ) : _inod(_isrc), _jnod(_jsrc),
+ _cost(_csrc) {}
} ;
-
class sort_less
{
public :
@@ -1397,259 +1565,167 @@
sort_pair const&_idat ,
sort_pair const&_jdat
) const
- { return
- _idat._cost < _jdat._cost ;
+ { return _idat._cost < _jdat._cost;
}
} ;
- # define __marknode \
- init_mark( _mesh, _nmrk, _emrk, \
- _tmrk, std::max(_imrk-1, +0)) ; \
- if (std::abs( \
- _nmrk[_nnew])!= _imrk+1) \
- { \
- if (_nmrk[_nnew] >= +0) \
- { \
- _nmrk[_nnew] = +_imrk+1; \
- } \
- else \
- { \
- _nmrk[_nnew] = -_imrk-1; \
- } \
+ # define MARKNODE(_NODE) _mark._node[_NODE]
+
+ # define PUSHMARK \
+ init_mark( _mesh, _mark, \
+ std::max(_imrk - 1, +0)); \
+ if (std::abs( \
+ _mark._node[_nnew])!= _imrk+1) \
+ { \
+ if (_mark._node[_nnew] >= +0) \
+ { \
+ _mark._node[_nnew] = +_imrk+1; \
+ } \
+ else \
+ { \
+ _mark._node[_nnew] = -_imrk-1; \
+ } \
_nset.push_tail(_nnew) ; \
- } \
-
- iptr_type static
- constexpr _DEG_MIN = (iptr_type) +5 ;
- iptr_type static
- constexpr _DEG_MAX = (iptr_type) +7 ;
+ } \
+ /*------------------------ add/pop nodes to fix topo. */
typedef containers::
- arraysort_list ;
+ array sort_list ;
- __unreferenced (_DLIM) ;
+ __unreferenced ( _DLIM );
- _nzip = +0 ; _ndiv = +0 ;
+ sort_list _sort ;
+ conn_list _aset , _bset, _cset ;
+ conn_list _conn , _iset, _jset ;
+ real_list _qold , _qnew, _qtmp ;
- sort_list _sort;
+ _nzip = +0 ; _ndiv = +0 ;
- iptr_list _aset, _bset, _cset ;
- iptr_list _eset, _done;
- iptr_list _iset, _jset;
- real_list _told, _tnew, _ttmp ;
+ // assemble list of edges attached to "recent" nodes
- for (auto _node =
- _mesh._set1.count() ; _node-- != +0; )
+ for (auto _enum =
+ _mesh. edge().count(); _enum-- != 0; )
{
- /*--------------------- scan nodes and zip//div edges */
- if ( _mesh.
- _set1[_node].mark () >= +0 &&
- std::abs (
- _nmrk[_node]) >= _imrk - 2 )
- {
- _eset.set_count(+0) ;
- _sort.set_count(+0) ;
- _mesh.node_edge(
- (iptr_type) _node, _eset) ;
-
- for (auto _eadj = _eset.head();
- _eadj != _eset.tend();
- ++_eadj )
- {
- auto _eptr =
- _mesh._set2.head() + *_eadj;
+ auto _eptr =&_mesh.edge(_enum) ;
- auto _iptr = _mesh.
- _set1.head()+ _eptr->node(0) ;
- auto _jptr = _mesh.
- _set1.head()+ _eptr->node(1) ;
+ auto _inod = _eptr->node(0) ;
+ auto _jnod = _eptr->node(1) ;
- real_type _line[_dims] ;
- iptr_type _idim=_dims;
+ auto _iptr = _mesh.
+ node().head()+_eptr->node(0) ;
+ auto _jptr = _mesh.
+ node().head()+_eptr->node(1) ;
- for ( ; _idim-- != +0; )
- {
- _line[_idim] =
- _jptr->pval(_idim) -
- _iptr->pval(_idim) ;
- }
+ if (_eptr->mark() >= +0 &&
+ ( std::abs (
+ _mark._node[_inod]) > _imrk - 4 ||
+ std::abs (
+ _mark._node[_jnod]) > _imrk - 4 ))
+ {
+ float _lsqr =
+ (float)pred_type::length_sq (
+ & _iptr->pval(0) ,
+ & _jptr->pval(0) ) ;
- float _lsqr = (float)
- _pred.length_sq(_line) ;
+ _sort.push_tail(
+ sort_pair(_inod, _jnod, _lsqr)) ;
+ }
+ }
- sort_pair _pair;
- _pair._cost = _lsqr ;
- _pair._edge =*_eadj ;
+ if (_sort.empty()) return ;
- _sort.push_tail(_pair) ;
- }
+ algorithms::qsort( // sort edge list by lsqr
+ _sort.head() ,
+ _sort.tend() , sort_less());
- if (_sort.empty()) continue;
+ // scan edges longest-to-shortest and try to div any
+ // unvisited edges
- /*------------------- scan local edges by len */
- algorithms::isort (
- _sort.head(),
- _sort.tend(), sort_less()) ;
+ for (auto _iter = _sort.tail();
+ _iter != _sort.hend();
+ --_iter )
+ {
+ /*--------------------------- try to "div" local edge */
+ iptr_type _eadj, _enod[2] ;
+ _enod[0] = _iter->_inod;
+ _enod[1] = _iter->_jnod;
- bool_type _move = false ;
+ if (MARKNODE(_enod[0])>_imrk) continue ;
+ if (MARKNODE(_enod[1])>_imrk) continue ;
- for (auto _iter = _sort.tail();
- _iter != _sort.hend();
- --_iter )
- {
- auto _eadj = _iter->_edge;
-
- auto _eptr =
- _mesh._set2.head() + _eadj;
-
- iptr_type _enod[2] ;
- _enod[0] = _eptr->node(0);
- _enod[1] = _eptr->node(1);
-
- if (std::abs(
- _nmrk[_enod[0]]) > _imrk ||
- std::abs(
- _nmrk[_enod[1]]) > _imrk )
- continue ;
-
- /*------------------- try to "div" local edge */
- if (_nmrk[_enod[0]] >= 0 &&
- _nmrk[_enod[1]] >= 0 )
- {
- if (_eset.count() > _DEG_MAX)
- {
- real_type _qinc =
- (real_type) -1./9. ;
- real_type _ltol =
- (real_type) +8./9. ;
-
- _qinc *=
- _eset.count() - 6;
-
- _qinc /= // don't ping-pong w zip
- std::sqrt (_imrk);
-
- iptr_type _nnew = -1;
-
- if (_opts.div_())
- _div_edge( _geom, _mesh,
- _hfun, _pred,
- _hval, _opts, _eadj,
- _kern, _move, _nnew,
- _iset, _jset,
- _told, _tnew,
- _ttmp, _TLIM,
- _ltol, _qinc) ;
-
- if (_move)
- {
- __marknode; _ndiv += +1; break ;
- }
- }
- else
- {
- iptr_type _nnew = -1;
-
- if (_opts.div_())
- _div_edge( _geom, _mesh,
- _hfun, _pred,
- _hval, _opts, _eadj,
- _kern, _move, _nnew,
- _iset, _jset,
- _told, _tnew,
- _ttmp, _TLIM) ;
-
- if (_move)
- {
- __marknode; _ndiv += +1; break ;
- }
- }
- }
- }
+ if (MARKNODE(_enod[0]) < +0 ||
+ MARKNODE(_enod[1]) < +0 ) continue ;
- if (_move) continue ;
+ if(!_mesh.find_edge(
+ _enod, _eadj) ) continue ;
- /*------------------- scan local edges by len */
- for (auto _iter = _sort.head();
- _iter != _sort.tend();
- ++_iter )
+ if (_opts.div_())
+ {
+ /*--------------------------- "div" for topo. + score */
+ iptr_type _nnew = -1;
+
+ bool_type _move;
+ _div_edge( _geom, _mesh,
+ _hfun, _hval, _opts,
+ _imrk, _eadj,
+ _kern, _move, _nnew,
+ _iset, _jset,
+ _aset, _bset,
+ _qold, _qnew,
+ _qtmp, _QLIM) ;
+
+ if (_move)
{
- auto _eadj = _iter->_edge;
-
- auto _eptr =
- _mesh._set2.head() + _eadj;
-
- iptr_type _enod[2] ;
- _enod[0] = _eptr->node(0);
- _enod[1] = _eptr->node(1);
-
- if (std::abs(
- _nmrk[_enod[0]]) > _imrk ||
- std::abs(
- _nmrk[_enod[1]]) > _imrk )
- continue ;
-
- /*------------------- try to "zip" local edge */
- if (_nmrk[_enod[0]] >= 0 &&
- _nmrk[_enod[1]] >= 0 )
- {
- if (_eset.count() < _DEG_MIN)
- {
- real_type _qinc =
- (real_type) -1./9. ;
- real_type _ltol =
- (real_type) +9./8. ;
-
- _qinc /= // don't ping-pong w div
- std::sqrt (_imrk);
-
- iptr_type _nnew = -1;
-
- if (_opts.zip_())
- _zip_edge( _geom, _mesh,
- _hfun, _pred,
- _hval, _opts, _eadj,
- _kern, _move, _nnew,
- _iset, _jset,
- _aset, _bset, _cset,
- _told, _tnew,
- _ttmp, _TLIM,
- _ltol, _qinc) ;
-
- if (_move)
- {
- __marknode; _nzip += +1; break ;
- }
- }
- else
- {
- iptr_type _nnew = -1;
-
- if (_opts.zip_())
- _zip_edge( _geom, _mesh,
- _hfun, _pred,
- _hval, _opts, _eadj,
- _kern, _move, _nnew,
- _iset, _jset,
- _aset, _bset, _cset,
- _told, _tnew,
- _ttmp, _TLIM) ;
-
- if (_move)
- {
- __marknode; _nzip += +1; break ;
- }
- }
- }
+ PUSHMARK; _ndiv += +1;
}
+ }
+ }
+
+ // scan edges shortest-to-longest and try to zip any
+ // unvisited edges
+
+ for (auto _iter = _sort.head();
+ _iter != _sort.tend();
+ ++_iter )
+ {
+ /*--------------------------- try to "zip" local edge */
+ iptr_type _eadj, _enod[2] ;
+ _enod[0] = _iter->_inod;
+ _enod[1] = _iter->_jnod;
+
+ if (MARKNODE(_enod[0])>_imrk) continue ;
+ if (MARKNODE(_enod[1])>_imrk) continue ;
- if (_move) continue ;
+ if (MARKNODE(_enod[0]) < +0 ||
+ MARKNODE(_enod[1]) < +0 ) continue ;
+ if(!_mesh.find_edge(
+ _enod, _eadj) ) continue ;
+
+ if (_opts.zip_())
+ {
+ /*--------------------------- "zip" for topo. + score */
+ iptr_type _nnew = -1;
+
+ bool_type _move;
+ _zip_edge( _geom, _mesh,
+ _hfun, _hval, _opts,
+ _eadj,
+ _kern, _move, _nnew,
+ _iset, _jset,
+ _aset, _bset, _cset,
+ _qold, _qnew,
+ _qtmp, _QLIM) ;
+
+ if (_move)
+ {
+ PUSHMARK; _nzip += +1;
+ }
}
}
- for (auto _iter = _nmrk.head() ;
- _iter != _nmrk.tend() ;
+ for (auto _iter = _mark._node.head() ;
+ _iter != _mark._node.tend() ;
++_iter )
{
/*--------------------- undo local inc. on node flags */
@@ -1660,8 +1736,8 @@
*_iter = - _imrk;
}
- # undef __marknode
-
+ # undef PUSHMARK
+ # undef MARKNODE
}
/*------------------------------ helper: init. marker */
@@ -1669,34 +1745,38 @@
__static_call
__normal_call void_type init_mark (
mesh_type &_mesh ,
- iptr_list &_nmrk ,
- iptr_list &_emrk ,
- iptr_list &_tmrk ,
+ mark_list &_mark ,
iptr_type _flag = +0
)
{
- iptr_type _nmax =
- (iptr_type)std::max( _nmrk.count() ,
- _mesh._set1.count()
- ) ;
- iptr_type _emax =
- (iptr_type)std::max( _emrk.count() ,
- _mesh._set2.count()
- ) ;
- iptr_type _tmax =
- (iptr_type)std::max( _tmrk.count() ,
- _mesh._set3.count()
- ) ;
-
- _nmrk.set_count(_nmax,
- containers::
- loose_alloc, _flag) ;
- _emrk.set_count(_emax,
- containers::
- loose_alloc, _flag) ;
- _tmrk.set_count(_tmax,
- containers::
- loose_alloc, _flag) ;
+ iptr_type _nnN1 = std::max(
+ (iptr_type) _mark. _node.count() ,
+ (iptr_type) _mesh.node().count()
+ ) ;
+ iptr_type _nnE2 = std::max(
+ (iptr_type) _mark. _edge.count() ,
+ (iptr_type) _mesh.edge().count()
+ ) ;
+ iptr_type _nnT3 = std::max(
+ (iptr_type) _mark. _tri3.count() ,
+ (iptr_type) _mesh.tri3().count()
+ ) ;
+ iptr_type _nnQ4 = std::max(
+ (iptr_type) _mark. _quad.count() ,
+ (iptr_type) _mesh.quad().count()
+ ) ;
+
+ _mark._node.set_count(_nnN1,
+ containers::loose_alloc, _flag) ;
+
+ _mark._edge.set_count(_nnE2,
+ containers::loose_alloc, _flag) ;
+
+ _mark._tri3.set_count(_nnT3,
+ containers::loose_alloc, _flag) ;
+
+ _mark._quad.set_count(_nnQ4,
+ containers::loose_alloc, _flag) ;
}
/*
@@ -1711,10 +1791,9 @@
__static_call
__normal_call void_type iter_mesh (
geom_type &_geom ,
- size_type &_hfun ,
+ hfun_type &_hfun ,
mesh_type &_mesh ,
char_type _kern ,
- pred_type &_pred ,
iter_opts &_opts ,
text_dump &_dump
)
@@ -1733,11 +1812,9 @@
# ifdef __use_timers
typename std ::chrono::
- high_resolution_clock::
- time_point _ttic ;
+ high_resolution_clock::time_point _ttic;
typename std ::chrono::
- high_resolution_clock::
- time_point _ttoc ;
+ high_resolution_clock::time_point _ttoc;
typename std ::chrono::
high_resolution_clock _time;
@@ -1748,108 +1825,137 @@
std::srand( +1 ) ;
/*------------------------------ push boundary marker */
- iptr_list _nmrk, _emrk, _tmrk,
- _nset, _tset;
-
- init_mark(_mesh, _nmrk, _emrk, _tmrk) ;
+ iptr_list _nset ;
+ conn_list _conn ;
+ mark_list _mark ;
- iptr_type _nnum = +0 ;
- iptr_type _enum = +0 ;
+ init_mark(_mesh, _mark) ;
- for (auto _node = _mesh._set1.head() ;
- _node != _mesh._set1.tend() ;
- ++_node, ++_nnum )
+ iptr_type _nnN1 = +0 ;
+ for (auto _node = _mesh.node().head() ;
+ _node != _mesh.node().tend() ;
+ ++_node, ++_nnN1 )
{
if (_node->mark() >= +0)
{
if (_node->feat()
!= mesh::null_feat)
{
- _nmrk[_nnum] = -1;
+ _mark._node[_nnN1] = -1 ;
}
}
}
- for (auto _edge = _mesh._set2.head() ;
- _edge != _mesh._set2.tend() ;
- ++_edge, ++_enum )
+ iptr_type _nnE2 = +0 ;
+ for (auto _edge = _mesh.edge().head() ;
+ _edge != _mesh.edge().tend() ;
+ ++_edge, ++_nnE2 )
{
if (_edge->mark() >= +0)
{
if (_edge->self() >= +1)
{
- _nmrk[_edge->node(0)] = -1 ;
- _nmrk[_edge->node(1)] = -1 ;
+ _mark._node[
+ _edge->node(0)] = -1 ;
+ _mark._node[
+ _edge->node(1)] = -1 ;
}
else
{
- _tset.set_count(0) ;
+ _conn.set_count(0) ;
- _mesh.edge_tri3 (
- &_edge->node(0), _tset) ;
+ _mesh.connect_2(
+ &_edge->node(0), EDGE2_tag, _conn) ;
- if (_tset.count() != +2)
+ if (_conn.count () != +2)
{
- _nmrk[_edge->node(0)] = -1 ;
- _nmrk[_edge->node(1)] = -1 ;
+ _mark._node[
+ _edge->node(0)] = -1 ;
+ _mark._node[
+ _edge->node(1)] = -1 ;
}
}
}
}
- flip_sign (_mesh, _pred) ;
+ flip_sign(_mesh) ;
/*------------------------------ do optimisation loop */
- iptr_type static constexpr
- ITER_MIN_ = + 4 ;
- iptr_type static constexpr
- ITER_MAX_ = + 8 ;
+ bool_type
+ static constexpr ITER_FLIP = true;
- bool_type static constexpr
- ITER_FLIP = true ;
+ iptr_type
+ static constexpr ITER_MIN_ = +4 ;
+ iptr_type
+ static constexpr ITER_MAX_ = +8 ;
- real_type _QMIN = (real_type) +1. ;
+ real_type _QMIN = (real_type) +1.;
- for (auto _tria = _mesh._set3.head() ;
- _tria != _mesh._set3.tend() ;
- ++_tria )
+ for (auto _cell = _mesh.tri3().head() ;
+ _cell != _mesh.tri3().tend() ;
+ ++_cell )
{
- if (_tria->mark() >= +0 )
+ if (_cell->mark() >= +0 )
{
/*--------------------- test initial cell quality */
- real_type _cost =
- _pred.cost_tria (
- &_mesh._set1[
- _tria->node(0)].pval(0),
- &_mesh._set1[
- _tria->node(1)].pval(0),
- &_mesh._set1[
- _tria->node(2)].pval(0)
- ) ;
+ real_type _cost;
+ _cost = pred_type::tri3_cost (
+ &_mesh .node(
+ _cell->node(0)).pval(0),
+ &_mesh .node(
+ _cell->node(1)).pval(0),
+ &_mesh .node(
+ _cell->node(2)).pval(0),
+ typename
+ pred_type::cell_kind ()) ;
+
+ _QMIN = std::min (_QMIN, _cost) ;
+ _QMIN = std::max (_QMIN,
+ _opts.qlim()) ;
+ }
+ }
+
+ for (auto _cell = _mesh.quad().head() ;
+ _cell != _mesh.quad().tend() ;
+ ++_cell )
+ {
+ if (_cell->mark() >= +0 )
+ {
+ /*--------------------- test initial cell quality */
+ real_type _cost;
+ _cost = pred_type::quad_cost (
+ &_mesh .node(
+ _cell->node(0)).pval(0),
+ &_mesh .node(
+ _cell->node(1)).pval(0),
+ &_mesh .node(
+ _cell->node(2)).pval(0),
+ &_mesh .node(
+ _cell->node(3)).pval(0),
+ typename
+ pred_type::cell_kind ()) ;
_QMIN = std::min (_QMIN, _cost) ;
+ _QMIN = std::max (_QMIN,
+ _opts.qlim()) ;
}
}
for (auto _iter = +1 ;
_iter <= _opts.iter(); ++_iter)
{
- /*-------------------------- set-up current iter. */
- init_mark(_mesh, _nmrk,
- _emrk, _tmrk, std::max(_iter-1, +0));
+ /*------------------------------ set-up current iter. */
+ init_mark(_mesh, _mark,
+ std::max(_iter-1, +0)) ;
- real_list _hval, _qmin;
+ real_list _hval;
_hval.set_count(
- _mesh._set1.count(),
+ _mesh. node().count(),
containers::tight_alloc, (real_type)-1.);
- _qmin.set_count(
- _mesh._set1.count(),
- containers::tight_alloc, (real_type)+1.);
-
iptr_list _amrk;
_amrk.set_count(
- _mesh._set1.count(),
+ _mesh. node().count(),
containers::tight_alloc, (iptr_type)-1 );
_nset.set_count( +0);
@@ -1860,47 +1966,46 @@
iptr_type _ndiv = +0 ;
/*------------------------------ scale quality thresh */
- iptr_type _nsub = _iter + 0 ;
+ iptr_type _nsub = _iter +0 ;
- _nsub = std::min(
- ITER_MAX_, _nsub) ;
- _nsub = std::max(
- ITER_MIN_, _nsub) ;
+ _nsub =
+ std::min(ITER_MAX_, _nsub) ;
+ _nsub =
+ std::max(ITER_MIN_, _nsub) ;
- real_type _TLIM =
- (real_type).750*_opts.qlim() +
- (real_type).075*_iter;
+ real_type _QLIM =
+ (real_type)+.750 * _QMIN +
+ (real_type)+.075 * _iter ;
- _TLIM = std::max( _TLIM,
- _QMIN) ;
- _TLIM = std::min(
- _opts.qlim(), _TLIM) ;
+ _QLIM = std::min(
+ _opts.qlim(), _QLIM);
real_type _DLIM =
(real_type)(1. -
- 1. * std::pow(1.-_TLIM, 2)) ;
+ .5 * std::pow(1.0-_QLIM, +2)) ;
+ /*------------------------------ 1. CELL GEOM. PASSES */
+
+ if (_opts.tria())
+ {
/*------------------------------ update mesh geometry */
# ifdef __use_timers
_ttic = _time.now() ;
# endif//__use_timers
for (auto _isub = + 0 ;
- _isub != _nsub; ++_isub )
+ _isub != _nsub/1; ++_isub )
{
if (_opts.verb() >= +3)
_dump.push(
- " CALL MOVE-NODE...\n") ;
+ "**CALL MOVE-NODE...\n" ) ;
iptr_type _nloc;
move_node( _geom, _mesh ,
- _hfun, _pred, _kern ,
- _hval, _qmin,
- _nset, _amrk,
- _nmrk, _emrk, _tmrk ,
+ _hfun, _kern, _hval ,
+ _nset, _amrk, _mark ,
_iter, _isub,
- _opts, _nloc,
- _TLIM, _DLIM) ;
+ _opts, _nloc, _QLIM ) ;
_nmov = std::max (_nmov ,
_nloc ) ;
@@ -1908,8 +2013,7 @@
# ifdef __use_timers
_ttoc = _time.now() ;
-
- _tcpu._move_full +=
+ _tcpu._move_node +=
_tcpu.time_span(_ttic, _ttoc);
# endif//__use_timers
@@ -1922,47 +2026,136 @@
{
if (_opts.verb() >= +3)
_dump.push(
- " CALL FLIP-MESH...\n") ;
+ "**CALL FLIP-MESH...\n" ) ;
+ iptr_type _nloc;
flip_mesh( _geom, _mesh ,
- _hfun, _pred, _nset ,
- _nmrk, _emrk, _tmrk ,
- _iter, _nflp) ;
+ _hfun, _nset, _mark ,
+ +3 * _iter - 2 , _nloc ) ;
+
+ _nflp += _nloc;
}
# ifdef __use_timers
_ttoc = _time.now() ;
+ _tcpu._topo_flip +=
+ _tcpu.time_span(_ttic, _ttoc);
+ # endif//__use_timers
+ }
+
+ /*------------------------------ 2. DUAL GEOM. PASSES */
+
+ if (_opts.dual())
+ {
+ /*------------------------------ update mesh geometry */
+ # ifdef __use_timers
+ _ttic = _time.now() ;
+ # endif//__use_timers
+
+ _amrk.fill( -1 );
+
+ for (auto _isub = + 0 ;
+ _isub != _nsub/2; ++_isub )
+ {
+ if (_opts.verb() >= +3)
+ _dump.push(
+ "**CALL MOVE-DUAL...\n" ) ;
+
+ iptr_type _nloc;
+ move_dual( _geom, _mesh ,
+ _hfun, _hval,
+ _nset, _amrk, _mark ,
+ _iter, _isub,
+ _opts, _nloc, _DLIM ) ;
- _tcpu._topo_full +=
+ _nmov = std::max (_nmov ,
+ _nloc ) ;
+ }
+
+ # ifdef __use_timers
+ _ttoc = _time.now() ;
+ _tcpu._move_dual +=
_tcpu.time_span(_ttic, _ttoc);
# endif//__use_timers
- /*------------------------------ zip/div mesh subface */
+ /*------------------------------ update mesh topology */
# ifdef __use_timers
_ttic = _time.now() ;
# endif//__use_timers
- if (_iter < _opts.iter() )
- if (_opts.zip_() ||
- _opts.div_() )
+ if (ITER_FLIP)
{
if (_opts.verb() >= +3)
_dump.push(
- " CALL _ZIP-MESH...\n") ;
+ "**CALL FLIP-MESH...\n" ) ;
+
+ iptr_type _nloc;
+ flip_mesh( _geom, _mesh ,
+ _hfun, _nset, _mark ,
+ +3 * _iter - 1 , _nloc ) ;
+
+ _nflp += _nloc;
+ }
+
+ # ifdef __use_timers
+ _ttoc = _time.now() ;
+ _tcpu._topo_flip +=
+ _tcpu.time_span(_ttic, _ttoc);
+ # endif//__use_timers
+ }
+
+ /*------------------------------ 3. ZIP + DIV SUBFACE */
+
+ # ifdef __use_timers
+ _ttic = _time.now() ;
+ # endif//__use_timers
+
+ _nset.set_count(+0) ; // don't flip twice!
+
+ if (_iter < _opts.iter())
+ if (_opts.zip_ () ||
+ _opts.div_ () )
+ {
+ if (_opts.verb() >= +3)
+ _dump.push(
+ "**CALL _ZIP-MESH...\n" ) ;
_zip_mesh( _geom, _mesh ,
- _hfun, _pred, _kern ,
+ _hfun, _kern,
_hval, _nset,
- _nmrk, _emrk, _tmrk ,
- _iter, _opts,
- _TLIM, _DLIM,
+ _mark, _iter, _opts ,
+ _QLIM, _DLIM,
_nzip, _ndiv) ;
}
# ifdef __use_timers
_ttoc = _time.now() ;
+ _tcpu._topo_zips +=
+ _tcpu.time_span(_ttic, _ttoc);
+ # endif//__use_timers
+
+ /*------------------------------ update mesh topology */
+ # ifdef __use_timers
+ _ttic = _time.now() ;
+ # endif//__use_timers
+
+ if (ITER_FLIP)
+ {
+ if (_opts.verb() >= +3)
+ _dump.push(
+ "**CALL FLIP-MESH...\n" ) ;
+
+ iptr_type _nloc;
+ flip_mesh( _geom, _mesh ,
+ _hfun, _nset, _mark ,
+ +3 * _iter - 0 , _nloc ) ;
- _tcpu._zips_full +=
+ _nflp += _nloc;
+ }
+
+ # ifdef __use_timers
+ _ttoc = _time.now() ;
+ _tcpu._topo_flip +=
_tcpu.time_span(_ttic, _ttoc);
# endif//__use_timers
@@ -1979,7 +2172,7 @@
}
/*------------------------------ has iter. converged? */
- if (_nset.count() == 0) break ;
+ // if (_nset.count() == 0) break ;
if (_nmov == +0 &&
_nzip == +0 &&
_ndiv == +0 &&
@@ -1991,19 +2184,27 @@
/*------------------------------ print method metrics */
_dump.push("\n");
- _dump.push(" MOVE-FULL: ");
+ _dump.push("**FUNCTION timing: ") ;
+ _dump.push("\n");
+
+ _dump.push(" MOVE-NODE: ");
+ _dump.push(
+ std::to_string(_tcpu._move_node)) ;
+ _dump.push("\n");
+
+ _dump.push(" MOVE-DUAL: ");
_dump.push(
- std::to_string(_tcpu._move_full)) ;
+ std::to_string(_tcpu._move_dual)) ;
_dump.push("\n");
- _dump.push(" TOPO-FULL: ");
+ _dump.push(" TOPO-FLIP: ");
_dump.push(
- std::to_string(_tcpu._topo_full)) ;
+ std::to_string(_tcpu._topo_flip)) ;
_dump.push("\n");
- _dump.push(" ZIPS-FULL: ");
+ _dump.push(" TOPO-ZIPS: ");
_dump.push(
- std::to_string(_tcpu._zips_full)) ;
+ std::to_string(_tcpu._topo_zips)) ;
_dump.push("\n");
_dump.push("\n");
diff --git a/external/jigsaw/src/libcpp/iter_mesh/iter_mesh_3.hpp b/external/jigsaw/src/libcpp/iter_mesh/iter_mesh_3.hpp
index b8951e5..6db6b79 100644
--- a/external/jigsaw/src/libcpp/iter_mesh/iter_mesh_3.hpp
+++ b/external/jigsaw/src/libcpp/iter_mesh/iter_mesh_3.hpp
@@ -35,7 +35,7 @@
*
* Copyright 2013-2018
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
--------------------------------------------------------
@@ -54,46 +54,6 @@
--------------------------------------------------------
*/
- template <
- typename G ,
- typename M ,
- typename H ,
- typename P
- >
- class iter_mesh_3
- {
- public :
- typedef M mesh_type ;
- typedef G geom_type ;
- typedef H size_type ;
- typedef P pred_type ;
-
- typedef typename
- mesh_type::real_type real_type ;
- typedef typename
- mesh_type::iptr_type iptr_type ;
-
- iptr_type static
- constexpr _dims = pred_type::_dims ;
-
- typedef mesh::iter_params <
- real_type ,
- iptr_type > iter_opts ;
-
- typedef mesh::iter_timers <
- real_type ,
- iptr_type > iter_stat ;
-
- typedef containers
- ::array< iptr_type > iptr_list ;
- typedef containers
- ::array< real_type > real_list ;
-
- public :
-
-
-
- } ;
}
diff --git a/external/jigsaw/src/libcpp/iter_mesh/iter_mesh_euclidean_2.hpp b/external/jigsaw/src/libcpp/iter_mesh/iter_mesh_euclidean_2.hpp
index 4148e99..3087dd2 100644
--- a/external/jigsaw/src/libcpp/iter_mesh/iter_mesh_euclidean_2.hpp
+++ b/external/jigsaw/src/libcpp/iter_mesh/iter_mesh_euclidean_2.hpp
@@ -31,11 +31,11 @@
*
--------------------------------------------------------
*
- * Last updated: 09 April, 2019
+ * Last updated: 04 March, 2020
*
- * Copyright 2013-2019
+ * Copyright 2013-2020
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
--------------------------------------------------------
@@ -65,7 +65,9 @@
iptr_type > edge_base ;
typedef mesh::mesh_complex_tria_3 <
- iptr_type > tria_base ;
+ iptr_type > tri3_base ;
+ typedef mesh::mesh_complex_quad_4 <
+ iptr_type > quad_base ;
typedef mesh::mesh_complex_node_3 <
iptr_type ,
@@ -137,9 +139,9 @@
}
} ;
- class tria_type : public tria_base
+ class tri3_type : public tri3_base
{
- /*------------------------- tria type for ITER-MESH-2 */
+ /*------------------------- face type for ITER-MESH-2 */
public :
iptr_type _itag ;
@@ -156,10 +158,30 @@
}
} ;
- typedef mesh::tria_complex_2 <
+ class quad_type : public quad_base
+ {
+ /*------------------------- face type for ITER-MESH-2 */
+ public :
+
+ iptr_type _itag ;
+
+ public :
+
+ __inline_call iptr_type & itag (
+ )
+ { return this->_itag ;
+ }
+ __inline_call iptr_type const& itag (
+ ) const
+ { return this->_itag ;
+ }
+ } ;
+
+ typedef mesh::mesh_complex_2 <
node_type ,
edge_type ,
- tria_type > mesh_type ;
+ tri3_type ,
+ quad_type > mesh_type ;
public :
diff --git a/external/jigsaw/src/libcpp/iter_mesh/iter_mesh_euclidean_3.hpp b/external/jigsaw/src/libcpp/iter_mesh/iter_mesh_euclidean_3.hpp
index c3dc972..856ed0c 100644
--- a/external/jigsaw/src/libcpp/iter_mesh/iter_mesh_euclidean_3.hpp
+++ b/external/jigsaw/src/libcpp/iter_mesh/iter_mesh_euclidean_3.hpp
@@ -35,7 +35,7 @@
*
* Copyright 2013-2019
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
--------------------------------------------------------
@@ -65,10 +65,18 @@ template <
iptr_type > edge_base ;
typedef mesh::mesh_complex_tria_3 <
- iptr_type > face_base ;
+ iptr_type > tri3_base ;
+ typedef mesh::mesh_complex_quad_4 <
+ iptr_type > quad_base ;
typedef mesh::mesh_complex_tria_4 <
- iptr_type > tria_base ;
+ iptr_type > tri4_base ;
+ typedef mesh::mesh_complex_hexa_8 <
+ iptr_type > hexa_base ;
+ typedef mesh::mesh_complex_wedg_6 <
+ iptr_type > wedg_base ;
+ typedef mesh::mesh_complex_pyra_5 <
+ iptr_type > pyra_base ;
typedef mesh::mesh_complex_node_4 <
iptr_type ,
@@ -140,7 +148,7 @@ template <
}
} ;
- class face_type : public face_base
+ class tri3_type : public tri3_base
{
/*------------------------- face type for ITER-MESH-3 */
public :
@@ -159,9 +167,85 @@ template <
}
} ;
- class tria_type : public tria_base
+ class quad_type : public quad_base
{
- /*------------------------- tria type for ITER-MESH-3 */
+ /*------------------------- face type for ITER-MESH-3 */
+ public :
+
+ iptr_type _itag ;
+
+ public :
+
+ __inline_call iptr_type & itag (
+ )
+ { return this->_itag ;
+ }
+ __inline_call iptr_type const& itag (
+ ) const
+ { return this->_itag ;
+ }
+ } ;
+
+ class tri4_type : public tri4_base
+ {
+ /*------------------------- cell type for ITER-MESH-3 */
+ public :
+
+ iptr_type _itag ;
+
+ public :
+
+ __inline_call iptr_type & itag (
+ )
+ { return this->_itag ;
+ }
+ __inline_call iptr_type const& itag (
+ ) const
+ { return this->_itag ;
+ }
+ } ;
+
+ class hexa_type : public hexa_base
+ {
+ /*------------------------- cell type for ITER-MESH-3 */
+ public :
+
+ iptr_type _itag ;
+
+ public :
+
+ __inline_call iptr_type & itag (
+ )
+ { return this->_itag ;
+ }
+ __inline_call iptr_type const& itag (
+ ) const
+ { return this->_itag ;
+ }
+ } ;
+
+ class wedg_type : public wedg_base
+ {
+ /*------------------------- cell type for ITER-MESH-3 */
+ public :
+
+ iptr_type _itag ;
+
+ public :
+
+ __inline_call iptr_type & itag (
+ )
+ { return this->_itag ;
+ }
+ __inline_call iptr_type const& itag (
+ ) const
+ { return this->_itag ;
+ }
+ } ;
+
+ class pyra_type : public pyra_base
+ {
+ /*------------------------- cell type for ITER-MESH-3 */
public :
iptr_type _itag ;
@@ -178,11 +262,13 @@ template <
}
} ;
- typedef mesh::tria_complex_3 <
+ typedef mesh::mesh_complex_3 <
node_type ,
edge_type ,
- face_type ,
- tria_type > mesh_type ;
+ tri3_type , quad_type,
+ tri4_type , hexa_type,
+ wedg_type ,
+ pyra_type > mesh_type ;
public :
diff --git a/external/jigsaw/src/libcpp/iter_mesh/iter_node_1.inc b/external/jigsaw/src/libcpp/iter_mesh/iter_node_1.inc
index a993f98..2d4b86c 100644
--- a/external/jigsaw/src/libcpp/iter_mesh/iter_node_1.inc
+++ b/external/jigsaw/src/libcpp/iter_mesh/iter_node_1.inc
@@ -35,7 +35,7 @@
*
* Copyright 2013-2018
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
--------------------------------------------------------
@@ -56,7 +56,7 @@
__static_call
__normal_call void_type sprg_move_1 (
mesh_type &_mesh ,
- size_type &_hfun ,
+ hfun_type &_hfun ,
pred_type &_pred ,
real_list &_hval ,
iptr_list &_eset ,
diff --git a/external/jigsaw/src/libcpp/iter_mesh/iter_node_2.inc b/external/jigsaw/src/libcpp/iter_mesh/iter_node_2.inc
index 8917dbe..e5ab0c6 100644
--- a/external/jigsaw/src/libcpp/iter_mesh/iter_node_2.inc
+++ b/external/jigsaw/src/libcpp/iter_mesh/iter_node_2.inc
@@ -31,11 +31,11 @@
*
--------------------------------------------------------
*
- * Last updated: 27 October, 2019
+ * Last updated: 30 April, 2020
*
- * Copyright 2013-2019
+ * Copyright 2013-2020
* Darren Engwirda
- * de2363@columbia.edu
+ * d.engwirda@gmail.com
* https://github.com/dengwirda/
*
--------------------------------------------------------
@@ -46,7 +46,233 @@
/*
--------------------------------------------------------
- * _ODT-MOVE: optimal delaunay tessellation update.
+ * ~ODT-TRI3: optimal delaunay tessellation update.
+ --------------------------------------------------------
+ */
+
+ template <
+ typename node_iter
+ >
+ __static_call
+ __normal_call void_type _odt_tri3_k (
+ geom_type &_geom ,
+ mesh_type &_mesh ,
+ hfun_type &_hfun ,
+ real_list &_hval ,
+ iptr_type _cell ,
+ node_iter _node ,
+ real_type *_move ,
+ real_type &_wsum ,
+ real_type &_ladj
+ )
+ {
+ iptr_type static constexpr
+ _last = pred_type::geom_dims + 0;
+
+ # define EVALHFUN( _NODE, _NPTR ) \
+ if (_hval[_NODE] < (real_type)+0.) \
+ _hval[_NODE] = _hfun.eval ( \
+ &_NPTR->pval(0), _NPTR->hidx()) ;
+
+ # define LOOPDIMS( _ITER ) \
+ for ( auto _idim = \
+ pred_type::geom_dims; _idim-- != 0; )
+
+ __unreferenced(_node) ;
+
+ /*------------------------------------- cell indexing */
+ auto _tptr =
+ _mesh. tri3().head() + _cell ;
+
+ auto _inod = _tptr->node(0) ;
+ auto _jnod = _tptr->node(1) ;
+ auto _knod = _tptr->node(2) ;
+
+ auto _iptr =
+ _mesh. node().head() + _inod ;
+ auto _jptr =
+ _mesh. node().head() + _jnod ;
+ auto _kptr =
+ _mesh. node().head() + _knod ;
+
+ /*------------------------------------- dual geometry */
+ real_type _ball [_last + 1] ;
+ pred_type::tri3_ball(_ball,
+ &_iptr->pval(+0),
+ &_jptr->pval(+0),
+ &_kptr->pval(+0), true) ;
+
+ real_type _tmag =
+ pred_type::tri3_mass (
+ &_iptr->pval(+0),
+ &_jptr->pval(+0),
+ &_kptr->pval(+0)) ;
+
+ _tmag = std::abs(_tmag) ;
+
+ /*------------------------------------- odt weighting */
+ pred_type::proj_node(
+ _geom ,
+ &_node->pval( +0), &_ball[+0]) ;
+
+ real_type _lsqr = std::max(
+ _ball[_last], (real_type)+0.) ;
+
+ EVALHFUN( _inod , _iptr )
+ EVALHFUN( _jnod , _jptr )
+ EVALHFUN( _knod , _kptr )
+
+ real_type _irho = (real_type)+1.
+ / _hval [ _inod ] ;
+
+ real_type _jrho = (real_type)+1.
+ / _hval [ _jnod ] ;
+
+ real_type _krho = (real_type)+1.
+ / _hval [ _knod ] ;
+
+ real_type _rbar =
+ _irho * (real_type) 1./3. +
+ _jrho * (real_type) 1./3. +
+ _krho * (real_type) 1./3. ;
+
+ real_type _wval =
+ _tmag * std::pow(_rbar, +3) ;
+
+ LOOPDIMS( _idim )
+ {
+ _move[_idim]
+ += _wval * _ball [_idim] ;
+ }
+
+ _wsum += _wval ;
+ _ladj += _lsqr ;
+
+ # undef LOOPDIMS
+ # undef EVALHFUN
+ }
+
+ /*
+ --------------------------------------------------------
+ * ~ODT-QUAD: optimal delaunay tessellation update.
+ --------------------------------------------------------
+ */
+
+ template <
+ typename node_iter
+ >
+ __static_call
+ __normal_call void_type _odt_quad_k (
+ geom_type &_geom ,
+ mesh_type &_mesh ,
+ hfun_type &_hfun ,
+ real_list &_hval ,
+ iptr_type _cell ,
+ node_iter _node ,
+ real_type *_move ,
+ real_type &_wsum ,
+ real_type &_ladj
+ )
+ {
+ iptr_type static constexpr
+ _last = pred_type::geom_dims + 0;
+
+ # define EVALHFUN( _NODE, _NPTR ) \
+ if (_hval[_NODE] < (real_type)+0.) \
+ _hval[_NODE] = _hfun.eval ( \
+ &_NPTR->pval(0), _NPTR->hidx()) ;
+
+ # define LOOPDIMS( _ITER ) \
+ for ( auto _idim = \
+ pred_type::geom_dims; _idim-- != 0; )
+
+ __unreferenced(_node) ;
+
+ /*------------------------------------- cell indexing */
+ auto _qptr =
+ _mesh. quad().head() + _cell ;
+
+ auto _inod = _qptr->node(0) ;
+ auto _jnod = _qptr->node(1) ;
+ auto _knod = _qptr->node(2) ;
+ auto _lnod = _qptr->node(3) ;
+
+ auto _iptr =
+ _mesh. node().head() + _inod ;
+ auto _jptr =
+ _mesh. node().head() + _jnod ;
+ auto _kptr =
+ _mesh. node().head() + _knod ;
+ auto _lptr =
+ _mesh. node().head() + _lnod ;
+
+ /*------------------------------------- dual geometry */
+ real_type _ball [_last + 1] ;
+ pred_type::quad_ball(_ball,
+ &_iptr->pval(+0),
+ &_jptr->pval(+0),
+ &_kptr->pval(+0),
+ &_lptr->pval(+0), true) ;
+
+ real_type _qmag =
+ pred_type::quad_mass (
+ &_iptr->pval(+0),
+ &_jptr->pval(+0),
+ &_kptr->pval(+0),
+ &_lptr->pval(+0)) ;
+
+ _qmag = std::abs(_qmag) ;
+
+ /*------------------------------------- odt weighting */
+ pred_type::proj_node(
+ _geom ,
+ &_node->pval( +0), &_ball[+0]) ;
+
+ real_type _lsqr = std::max(
+ _ball[_last], (real_type)+0.) ;
+
+ EVALHFUN( _inod , _iptr )
+ EVALHFUN( _jnod , _jptr )
+ EVALHFUN( _knod , _kptr )
+ EVALHFUN( _lnod , _lptr )
+
+ real_type _irho = (real_type)+1.
+ / _hval [ _inod ] ;
+
+ real_type _jrho = (real_type)+1.
+ / _hval [ _jnod ] ;
+
+ real_type _krho = (real_type)+1.
+ / _hval [ _knod ] ;
+
+ real_type _lrho = (real_type)+1.
+ / _hval [ _lnod ] ;
+
+ real_type _rbar =
+ _irho * (real_type) 1./4. +
+ _jrho * (real_type) 1./4. +
+ _krho * (real_type) 1./4. +
+ _lrho * (real_type) 1./4. ;
+
+ real_type _wval =
+ _qmag * std::pow(_rbar, +3) ;
+
+ LOOPDIMS( _idim )
+ {
+ _move[_idim]
+ += _wval * _ball [_idim] ;
+ }
+
+ _wsum += _wval ;
+ _ladj += _lsqr ;
+
+ # undef LOOPDIMS
+ # undef EVALHFUN
+ }
+
+ /*
+ --------------------------------------------------------
+ * ~ODT-MOVE: optimal delaunay tessellation update.
--------------------------------------------------------
*/
@@ -55,159 +281,425 @@
// xnew <=== SUM( |t_i|_r * c_i ) / SUM( |t_i|_r )
//
- // with |t_i|_r = INT|i rho(x) dA
- //
- // ~ |t_i| / (h_i)^3
+ // with |t_i|_r = INT|i rho(x) dA ~ |t_i| / h_i**3
template <
typename node_iter
>
__static_call
__normal_call void_type _odt_move_2 (
+ geom_type &_geom ,
mesh_type &_mesh ,
- size_type &_hfun ,
- pred_type &_pred ,
+ hfun_type &_hfun ,
real_list &_hval ,
- iptr_list &_tset ,
+ conn_list &_conn ,
node_iter _node ,
real_type *_line ,
real_type &_ladj
)
{
- real_type _move[_dims] = {
- (real_type) +0.0 } ;
+ iptr_type static constexpr
+ _last = pred_type::geom_dims + 0;
- _ladj =
- (real_type) +0.0 ;
+ real_type _move[_last + 0] = {
+ (real_type) +0.0} ;
- __unreferenced (_pred) ; // for MSVC...
+ _ladj =
+ (real_type) +0.0 ;
real_type _wsum =
- +std::numeric_limits::epsilon() ;
+ +std::numeric_limits::epsilon();
- iptr_type _tnum = +0 ;
+ iptr_type _cnum = +0 ;
- for (auto _tria = _tset.head() ,
- _tend = _tset.tend() ;
- _tria != _tend ;
- ++_tria, ++_tnum )
+ for (auto _next = _conn.head() ,
+ _tend = _conn.tend() ;
+ _next != _tend ;
+ ++_next, ++_cnum )
{
- auto _tptr =
- _mesh._set3.head()+*_tria ;
-
- iptr_type _tnod[3] ;
- _tnod[ 0] = _tptr->node( 0) ;
- _tnod[ 1] = _tptr->node( 1) ;
- _tnod[ 2] = _tptr->node( 2) ;
-
- algorithms::isort(
- &_tnod[0], &_tnod[3],
- std::less()) ;
-
- auto _inod =
- _mesh._set1.head()+_tnod[0] ;
- auto _jnod =
- _mesh._set1.head()+_tnod[1] ;
- auto _knod =
- _mesh._set1.head()+_tnod[2] ;
-
- real_type _ball [_dims + 1] ;
- real_type _kpos [_dims + 1] ;
- real_type _jpos [_dims + 1] ;
- real_type _ipos [_dims + 1] ;
-
- _ipos[_dims] =
- (real_type)+.75 *
- _inod->pval (_dims) ;
- _jpos[_dims] =
- (real_type)+.75 *
- _jnod->pval (_dims) ;
- _kpos[_dims] =
- (real_type)+.75 *
- _knod->pval (_dims) ;
-
- for (auto _idim = _dims; _idim-- != +0; )
- {
- _ipos[_idim] =
- _inod->pval (_idim) ;
- _jpos[_idim] =
- _jnod->pval (_idim) ;
- _kpos[_idim] =
- _knod->pval (_idim) ;
- }
-
- _pred.perp_ball (_ball ,
- &_ipos [+0] ,
- &_jpos [+0] ,
- &_kpos [+0] , true);
-
- real_type _tmag =
- _pred.mass_tria (
- &_ipos [+0] ,
- &_jpos [+0] ,
- &_kpos [+0] ) ;
+ auto _cell = _next->_cell ;
+ auto _kind = _next->_kind ;
- _tmag = std::abs(_tmag);
-
- if (_hval[_tnod[0]] < (real_type)+0.)
+ if (_kind == TRIA3_tag)
{
- _hval[_tnod[0]] = _hfun.eval (
- &_inod->pval(0) ,
- _inod->hidx()) ;
+ _odt_tri3_k(_geom, _mesh, _hfun,
+ _hval , _cell, _node, _move,
+ _wsum , _ladj ) ;
}
-
- if (_hval[_tnod[1]] < (real_type)+0.)
+ else
+ if (_kind == QUAD4_tag)
{
- _hval[_tnod[1]] = _hfun.eval (
- &_jnod->pval(0) ,
- _jnod->hidx()) ;
+ _odt_quad_k(_geom, _mesh, _hfun,
+ _hval , _cell, _node, _move,
+ _wsum , _ladj ) ;
}
+ }
- if (_hval[_tnod[2]] < (real_type)+0.)
+ if (_cnum > +0)
+ {
+ for (auto _idim =
+ pred_type::geom_dims ; _idim-- != 0; )
{
- _hval[_tnod[2]] = _hfun.eval (
- &_knod->pval(0) ,
- _knod->hidx()) ;
+ _line[_idim] =
+ _move[_idim] / _wsum
+ - _node->pval(_idim) ;
}
- real_type _tsqr = std::max(
- (real_type) +0., _ball[_dims]);
+ _ladj = std::sqrt(_ladj / _cnum) ;
+ }
+ }
- real_type _irho = (real_type)+1.
- / _hval[_tnod[0]] ;
- real_type _jrho = (real_type)+1.
- / _hval[_tnod[1]] ;
- real_type _krho = (real_type)+1.
- / _hval[_tnod[2]] ;
+ /*
+ --------------------------------------------------------
+ * ~CVT-TRI3: optimal delaunay tessellation update.
+ --------------------------------------------------------
+ */
+
+ template <
+ typename node_iter
+ >
+ __static_call
+ __normal_call void_type _cvt_tri3_k (
+ geom_type &_geom ,
+ mesh_type &_mesh ,
+ hfun_type &_hfun ,
+ real_list &_hval ,
+ iptr_type _cell ,
+ node_iter _node ,
+ real_type *_move ,
+ real_type &_wsum ,
+ real_type &_ladj
+ )
+ {
+ iptr_type static constexpr
+ _last = pred_type::geom_dims + 0;
- real_type _rbar =
- (_irho+_jrho+_krho) / (real_type)+3. ;
+ # define EVALHFUN( _NODE, _NPTR ) \
+ if (_hval[_NODE] < (real_type)+0.) \
+ _hval[_NODE] = _hfun.eval ( \
+ &_NPTR->pval(0), _NPTR->hidx()) ;
- real_type _wval =
- _tmag * std::pow(_rbar, +3) ;
+ # define LOOPDIMS( _ITER ) \
+ for ( auto _idim = \
+ pred_type::geom_dims; _idim-- != 0; )
- for (auto _idim = _dims; _idim-- != +0; )
- {
- _move[_idim]
- += _wval * _ball [_idim] ;
- }
+ /*------------------------------------- cell indexing */
+ auto _tptr =
+ _mesh. tri3().head() + _cell ;
+
+ auto _inod = _tptr->node(0) ;
+ auto _jnod = _tptr->node(1) ;
+ auto _knod = _tptr->node(2) ;
- _wsum += _wval ;
- _ladj += _tsqr ;
+ if ( _jnod ==_node->node(0) )
+ {
+ _inod = _tptr->node(1) ;
+ _jnod = _tptr->node(2) ;
+ _knod = _tptr->node(0) ;
+ }
+ else
+ if ( _knod ==_node->node(0) )
+ {
+ _inod = _tptr->node(2) ;
+ _jnod = _tptr->node(0) ;
+ _knod = _tptr->node(1) ;
}
- if (_tnum > +0)
+ auto _iptr =
+ _mesh. node().head() + _inod ;
+ auto _jptr =
+ _mesh. node().head() + _jnod ;
+ auto _kptr =
+ _mesh. node().head() + _knod ;
+
+ /*------------------------------------- dual geometry */
+ real_type _0bal [_last + 1] ;
+ pred_type::tri3_ball(_0bal,
+ &_iptr->pval(+0),
+ &_jptr->pval(+0),
+ &_kptr->pval(+0), true) ;
+
+ real_type _1bal [_last + 1] ;
+ pred_type::edge_ball(_1bal,
+ &_iptr->pval(+0),
+ &_jptr->pval(+0), true) ;
+
+ real_type _2bal [_last + 1] ;
+ pred_type::edge_ball(_2bal,
+ &_iptr->pval(+0),
+ &_kptr->pval(+0), true) ;
+
+ real_type _1mag =
+ std::abs(pred_type::tri3_mass (
+ &_iptr->pval(+0),
+ &_1bal [+0] ,
+ &_0bal [+0] ) ) ;
+
+ real_type _2mag =
+ std::abs(pred_type::tri3_mass (
+ &_iptr->pval(+0),
+ &_0bal [+0] ,
+ &_2bal [+0] ) ) ;
+
+ /*------------------------------------- cvt weighting */
+ pred_type::proj_node(
+ _geom ,
+ &_node->pval( +0), &_0bal[ +0]);
+
+ pred_type::proj_node(
+ _geom ,
+ &_node->pval( +0), &_1bal[ +0]);
+
+ pred_type::proj_node(
+ _geom ,
+ &_node->pval( +0), &_2bal[ +0]);
+
+ real_type _lsqr = std::max(
+ _0bal[_last], (real_type) +0.);
+
+ EVALHFUN( _inod , _iptr )
+ EVALHFUN( _jnod , _jptr )
+ EVALHFUN( _knod , _kptr )
+
+ real_type _irho = (real_type) +1.
+ / _hval [ _inod ] ;
+
+ real_type _jrho = (real_type) +1.
+ / _hval [ _jnod ] ;
+
+ real_type _krho = (real_type) +1.
+ / _hval [ _knod ] ;
+
+ real_type _0rho =
+ _irho * (real_type) 1./3. +
+ _jrho * (real_type) 1./3. +
+ _krho * (real_type) 1./3. ;
+
+ real_type _1rho =
+ _irho * (real_type) 1./2. +
+ _jrho * (real_type) 1./2. ;
+
+ real_type _2rho =
+ _irho * (real_type) 1./2. +
+ _krho * (real_type) 1./2. ;
+
+ _0rho = std::pow(_0rho, +3) ;
+ _1rho = std::pow(_1rho, +3) ;
+ _2rho = std::pow(_2rho, +3) ;
+ _irho = std::pow(_irho, +3) ;
+
+ for (auto _idim =
+ pred_type::geom_dims; _idim-- != 0; )
{
- for (auto _idim = _dims; _idim-- != +0; )
- {
- _line[_idim] =
- _move[_idim] / _wsum
- - _node->pval(_idim) ;
- }
+ _move[_idim] +=
+ // 1st sub-tria in voro. cell
+ _1mag * (
+ _0rho * _0bal[_idim] +
+ _1rho * _1bal[_idim] +
+ _irho * _iptr->pval(_idim)
+ ) +
+
+ // 2nd sub-tria in voro. cell
+ _2mag * (
+ _0rho * _0bal[_idim] +
+ _2rho * _2bal[_idim] +
+ _irho * _iptr->pval(_idim)
+ ) ;
+ }
+
+ _wsum += _1mag*(_0rho+_1rho+_irho);
+ _wsum += _2mag*(_0rho+_2rho+_irho);
- _ladj = std::sqrt(_ladj / _tnum) ;
+ _ladj += _lsqr ;
+
+ # undef LOOPDIMS
+ # undef EVALHFUN
+ }
+
+ /*
+ --------------------------------------------------------
+ * ~CVT-QUAD: optimal delaunay tessellation update.
+ --------------------------------------------------------
+ */
+
+ template <
+ typename node_iter
+ >
+ __static_call
+ __normal_call void_type _cvt_quad_k (
+ geom_type &_geom ,
+ mesh_type &_mesh ,
+ hfun_type &_hfun ,
+ real_list &_hval ,
+ iptr_type _cell ,
+ node_iter _node ,
+ real_type *_move ,
+ real_type &_wsum ,
+ real_type &_ladj
+ )
+ {
+ iptr_type static constexpr
+ _last = pred_type::geom_dims + 0;
+
+ # define EVALHFUN( _NODE, _NPTR ) \
+ if (_hval[_NODE] < (real_type)+0.) \
+ _hval[_NODE] = _hfun.eval ( \
+ &_NPTR->pval(0), _NPTR->hidx()) ;
+
+ # define LOOPDIMS( _ITER ) \
+ for ( auto _idim = \
+ pred_type::geom_dims; _idim-- != 0; )
+
+ /*------------------------------------- cell indexing */
+ auto _qptr =
+ _mesh. quad().head() + _cell ;
+
+ auto _inod = _qptr->node(0) ;
+ auto _jnod = _qptr->node(1) ;
+ auto _knod = _qptr->node(2) ;
+ auto _lnod = _qptr->node(3) ;
+
+ if ( _jnod ==_node->node(0) )
+ {
+ _inod = _qptr->node(1) ;
+ _jnod = _qptr->node(2) ;
+ _knod = _qptr->node(3) ;
+ _lnod = _qptr->node(0) ;
+ }
+ else
+ if ( _knod ==_node->node(0) )
+ {
+ _inod = _qptr->node(2) ;
+ _jnod = _qptr->node(3) ;
+ _knod = _qptr->node(0) ;
+ _lnod = _qptr->node(1) ;
+ }
+ else
+ if ( _lnod ==_node->node(0) )
+ {
+ _inod = _qptr->node(3) ;
+ _jnod = _qptr->node(0) ;
+ _knod = _qptr->node(1) ;
+ _lnod = _qptr->node(2) ;
}
+ auto _iptr =
+ _mesh. node().head() + _inod ;
+ auto _jptr =
+ _mesh. node().head() + _jnod ;
+ auto _kptr =
+ _mesh. node().head() + _knod ;
+ auto _lptr =
+ _mesh. node().head() + _lnod ;
+
+ /*------------------------------------- dual geometry */
+ real_type _0bal [_last + 1] ;
+ pred_type::quad_ball(_0bal,
+ &_iptr->pval(+0),
+ &_jptr->pval(+0),
+ &_kptr->pval(+0),
+ &_lptr->pval(+0), true) ;
+
+ real_type _1bal [_last + 1] ;
+ pred_type::edge_ball(_1bal,
+ &_iptr->pval(+0),
+ &_jptr->pval(+0), true) ;
+
+ real_type _2bal [_last + 1] ;
+ pred_type::edge_ball(_2bal,
+ &_iptr->pval(+0),
+ &_lptr->pval(+0), true) ;
+
+ real_type _1mag =
+ std::abs(pred_type::tri3_mass (
+ &_iptr->pval(+0),
+ &_1bal [+0] ,
+ &_0bal [+0] ) ) ;
+
+ real_type _2mag =
+ std::abs(pred_type::tri3_mass (
+ &_iptr->pval(+0),
+ &_0bal [+0] ,
+ &_2bal [+0] ) ) ;
+
+ /*------------------------------------- cvt weighting */
+ pred_type::proj_node(
+ _geom ,
+ &_node->pval( +0), &_0bal[ +0]);
+
+ pred_type::proj_node(
+ _geom ,
+ &_node->pval( +0), &_1bal[ +0]);
+
+ pred_type::proj_node(
+ _geom ,
+ &_node->pval( +0), &_2bal[ +0]);
+
+ real_type _lsqr = std::max(
+ _0bal[_last], (real_type) +0.);
+
+ EVALHFUN( _inod , _iptr )
+ EVALHFUN( _jnod , _jptr )
+ EVALHFUN( _knod , _kptr )
+ EVALHFUN( _lnod , _lptr )
+
+ real_type _irho = (real_type) +1.
+ / _hval [ _inod ] ;
+
+ real_type _jrho = (real_type) +1.
+ / _hval [ _jnod ] ;
+
+ real_type _krho = (real_type) +1.
+ / _hval [ _knod ] ;
+
+ real_type _lrho = (real_type) +1.
+ / _hval [ _lnod ] ;
+
+ real_type _0rho =
+ _irho * (real_type) 1./4. +
+ _jrho * (real_type) 1./4. +
+ _krho * (real_type) 1./4. +
+ _lrho * (real_type) 1./4. ;
+
+ real_type _1rho =
+ _irho * (real_type) 1./2. +
+ _jrho * (real_type) 1./2. ;
+
+ real_type _2rho =
+ _irho * (real_type) 1./2. +
+ _lrho * (real_type) 1./2. ;
+
+ _0rho = std::pow(_0rho, +3) ;
+ _1rho = std::pow(_1rho, +3) ;
+ _2rho = std::pow(_2rho, +3) ;
+ _irho = std::pow(_irho, +3) ;
+
+ for (auto _idim =
+ pred_type::geom_dims; _idim-- != 0; )
+ {
+ _move[_idim] +=
+ // 1st sub-tria in voro. cell
+ _1mag * (
+ _0rho * _0bal[_idim] +
+ _1rho * _1bal[_idim] +
+ _irho * _iptr->pval(_idim)
+ ) +
+
+ // 2nd sub-tria in voro. cell
+ _2mag * (
+ _0rho * _0bal[_idim] +
+ _2rho * _2bal[_idim] +
+ _irho * _iptr->pval(_idim)
+ ) ;
+ }
+
+ _wsum += _1mag*(_0rho+_1rho+_irho);
+ _wsum += _2mag*(_0rho+_2rho+_irho);
+
+ _ladj += _lsqr ;
+
+ # undef LOOPDIMS
+ # undef EVALHFUN
}
/*
@@ -225,211 +717,267 @@
>
__static_call
__normal_call void_type _cvt_move_2 (
+ geom_type &_geom ,
mesh_type &_mesh ,
- size_type &_hfun ,
- pred_type &_pred ,
+ hfun_type &_hfun ,
real_list &_hval ,
- iptr_list &_tset ,
+ conn_list &_conn ,
node_iter _node ,
real_type *_line ,
real_type &_ladj
)
{
- real_type _move[_dims] = {
- (real_type) +0.0 } ;
+ iptr_type static constexpr
+ _last = pred_type::geom_dims + 0;
- _ladj =
- (real_type) +0.0 ;
+ real_type _move[_last + 0] = {
+ (real_type) +0.0} ;
- __unreferenced (_pred) ; // for MSVC...
+ _ladj =
+ (real_type) +0.0 ;
real_type _wsum =
- +std::numeric_limits::epsilon() ;
+ +std::numeric_limits::epsilon();
- iptr_type _tnum = +0 ;
+ iptr_type _cnum = +0 ;
- for (auto _tria = _tset.head() ,
- _tend = _tset.tend() ;
- _tria != _tend ;
- ++_tria, ++_tnum )
+ for (auto _next = _conn.head() ,
+ _tend = _conn.tend() ;
+ _next != _tend ;
+ ++_next, ++_cnum )
{
- auto _tptr =
- _mesh._set3.head()+*_tria ;
-
- iptr_type _tnod[3] ;
- _tnod[ 0] = _tptr->node( 0) ;
- _tnod[ 1] = _tptr->node( 1) ;
- _tnod[ 2] = _tptr->node( 2) ;
-
- algorithms::isort(
- &_tnod[0], &_tnod[3],
- std::less()) ;
-
- auto _inod =
- _mesh._set1.head()+_tnod[0] ;
- auto _jnod =
- _mesh._set1.head()+_tnod[1] ;
- auto _knod =
- _mesh._set1.head()+_tnod[2] ;
-
- if (_hval[_tnod[0]] < (real_type)+0.)
+ auto _cell = _next->_cell ;
+ auto _kind = _next->_kind ;
+
+ if (_kind == TRIA3_tag)
{
- _hval[_tnod[0]] = _hfun.eval (
- &_inod->pval(0) ,
- _inod->hidx()) ;
+ _cvt_tri3_k(_geom, _mesh, _hfun,
+ _hval , _cell, _node, _move,
+ _wsum , _ladj ) ;
}
-
- if (_hval[_tnod[1]] < (real_type)+0.)
+ else
+ if (_kind == QUAD4_tag)
{
- _hval[_tnod[1]] = _hfun.eval (
- &_jnod->pval(0) ,
- _jnod->hidx()) ;
+ _cvt_quad_k(_geom, _mesh, _hfun,
+ _hval , _cell, _node, _move,
+ _wsum , _ladj ) ;
}
+ }
- if (_hval[_tnod[2]] < (real_type)+0.)
+ if (_cnum > +0)
+ {
+ for (auto _idim =
+ pred_type::geom_dims ; _idim-- != 0; )
{
- _hval[_tnod[2]] = _hfun.eval (
- &_knod->pval(0) ,
- _knod->hidx()) ;
+ _line[_idim] =
+ _move[_idim] / _wsum
+ - _node->pval(_idim) ;
}
- real_type _irho = (real_type)+1.
- / _hval[_tnod[0]] ;
- real_type _jrho = (real_type)+1.
- / _hval[_tnod[1]] ;
- real_type _krho = (real_type)+1.
- / _hval[_tnod[2]] ;
-
- node_iter _anod, _bnod, _cnod;
- real_type _arho, _brho, _crho;
+ _ladj = std::sqrt(_ladj / _cnum) ;
+ }
+ }
- if (_inod == _node)
- {
- _anod = _inod; _arho = _irho;
- _bnod = _jnod; _brho = _jrho;
- _cnod = _knod; _crho = _krho;
- }
- else
- if (_jnod == _node)
- {
- _anod = _jnod; _arho = _jrho;
- _bnod = _knod; _brho = _krho;
- _cnod = _inod; _crho = _irho;
- }
- else
- // (_knod == _node)
- {
- _anod = _knod; _arho = _krho;
- _bnod = _inod; _brho = _irho;
- _cnod = _jnod; _crho = _jrho;
- }
+ /*
+ --------------------------------------------------------
+ * DQDX-TRI3: "local-ascent" node movement vector.
+ --------------------------------------------------------
+ */
- real_type _cpos [_dims + 1] ;
- real_type _bpos [_dims + 1] ;
- real_type _apos [_dims + 1] ;
-
- _apos[_dims] =
- (real_type)+.75 *
- _anod->pval (_dims) ;
- _bpos[_dims] =
- (real_type)+.75 *
- _bnod->pval (_dims) ;
- _cpos[_dims] =
- (real_type)+.75 *
- _cnod->pval (_dims) ;
-
- for (auto _idim = _dims; _idim-- != +0; )
- {
- _apos[_idim] =
- _anod->pval (_idim) ;
- _bpos[_idim] =
- _bnod->pval (_idim) ;
- _cpos[_idim] =
- _cnod->pval (_idim) ;
- }
+ template <
+ typename node_iter
+ >
+ __static_call
+ __normal_call void_type halo_tri3_k (
+ mesh_type &_mesh ,
+ iptr_type _cell ,
+ node_iter _node ,
+ real_type *_bmin ,
+ real_type *_bmax ,
+ real_type &_ladj
+ )
+ {
+ iptr_type static constexpr
+ _last = pred_type::geom_dims + 0;
+
+ /*------------------------------------- cell indexing */
+ auto _tptr =
+ _mesh. tri3().head() + _cell ;
+
+ auto _inod = _tptr->node(0) ;
+ auto _jnod = _tptr->node(1) ;
+ auto _knod = _tptr->node(2) ;
+
+ auto _iptr =
+ _mesh. node().head() + _inod ;
+ auto _jptr =
+ _mesh. node().head() + _jnod ;
+ auto _kptr =
+ _mesh. node().head() + _knod ;
+
+ /*------------------------------------- cell centroid */
+ real_type _pmid[_last + 0] = {
+ (real_type) +0.0} ;
+
+ for (auto _idim =
+ pred_type::geom_dims; _idim-- != +0; )
+ {
+ _pmid[_idim] +=
+ _iptr->pval(_idim) ;
+ _pmid[_idim] +=
+ _jptr->pval(_idim) ;
+ _pmid[_idim] +=
+ _kptr->pval(_idim) ;
+ }
+ for (auto _idim =
+ pred_type::geom_dims; _idim-- != +0; )
+ {
+ _pmid[_idim]
+ /= (real_type) +3. ;
+ }
- real_type _0bal [_dims + 1] ;
- _pred.perp_ball (_0bal ,
- &_apos [+0] ,
- &_bpos [+0] ,
- &_cpos [+0] , true);
+ for (auto _idim =
+ pred_type::geom_dims; _idim-- != +0; )
+ {
+ _bmin[_idim] = std::min(
+ _bmin[_idim],
+ _pmid[_idim]) ;
- real_type _1bal [_dims + 1] ;
- real_type _2bal [_dims + 1] ;
- _pred.perp_ball (_1bal ,
- &_apos [+0] ,
- &_bpos [+0] , true);
+ _bmax[_idim] = std::max(
+ _bmax[_idim],
+ _pmid[_idim]) ;
+ }
- _pred.perp_ball (_2bal ,
- &_apos [+0] ,
- &_cpos [+0] , true);
+ /*------------------------------------- cell "length" */
+ real_type _lsqr =
+ pred_type::length_sq (
+ _pmid, &_node->pval(0)) ;
- real_type _1mag =
- std::abs(_pred.mass_tria (
- &_apos [+0] ,
- &_1bal [+0] ,
- &_0bal [+0] ) ) ;
+ _ladj += _lsqr ;
+ }
- real_type _2mag =
- std::abs(_pred.mass_tria (
- &_apos [+0] ,
- &_0bal [+0] ,
- &_2bal [+0] ) ) ;
+ template <
+ typename node_iter
+ >
+ __static_call
+ __normal_call void_type dqdx_tri3_k (
+ mesh_type &_mesh ,
+ iptr_type _cell ,
+ node_iter _node ,
+ real_type _COST ,
+ real_type *_bmin ,
+ real_type *_bmax ,
+ real_type *_SAVE ,
+ real_type *_DQDX
+ )
+ {
+ real_type static const _HINC =
+ std::pow(std::numeric_limits
+ ::epsilon(), .50) ;
- real_type _0rho =
- (_arho+_brho+_crho) / (real_type)+3. ;
+ real_type static const _RMIN =
+ std::pow(std::numeric_limits
+ ::epsilon(), .75) ;
- real_type _1rho =
- (_arho+_brho) / (real_type)+2. ;
- real_type _2rho =
- (_arho+_crho) / (real_type)+2. ;
+ real_type static const _RMAX =
+ std::pow(std::numeric_limits
+ ::epsilon(), .25) ;
- _0rho = std::pow(_0rho, +3) ;
- _1rho = std::pow(_1rho, +3) ;
- _2rho = std::pow(_2rho, +3) ;
- _arho = std::pow(_arho, +3) ;
+ /*------------------------------------- cell indexing */
+ auto _ppos = &_node->pval(0);
- real_type _tsqr = std::max(
- (real_type)+0., _0bal[_dims]) ;
+ auto _tptr =
+ _mesh. tri3().head() + _cell ;
+ for (auto _idim =
+ pred_type::geom_dims; _idim-- != +0; )
+ {
+ /*------------------ local iter. on finite-diff. step */
+ real_type _binc = _bmax[_idim] -
+ _bmin[_idim] ;
- for (auto _idim = _dims; _idim-- != +0; )
- {
- _move[_idim] +=
- // 1st sub-tria in voro. cell
- _1mag*_0rho * _0bal[_idim] +
- _1mag*_1rho * _1bal[_idim] +
- _1mag*_arho * _apos[_idim] +
-
- // 2nd sub-tria in voro. cell
- _2mag*_0rho * _0bal[_idim] +
- _2mag*_2rho * _2bal[_idim] +
- _2mag*_arho * _apos[_idim] ;
- }
+ real_type _hdel = _HINC*_binc;
- _wsum += _1mag*(_0rho+_1rho+_arho) ;
- _wsum += _2mag*(_0rho+_2rho+_arho) ;
+ real_type _hsum = (real_type)0.;
- _ladj += _tsqr ;
- }
+ real_type _sdel = (real_type)0.;
+ real_type _sabs = (real_type)0.;
+ real_type _sbar = (real_type)0.;
- if (_tnum > +0)
+ for (auto _iter = +0; _iter++ != +2; )
{
- for (auto _idim = _dims; _idim-- != +0; )
+ /*------------------ centred finite-diff. for dQ / dx */
+ _ppos[_idim] =
+ _SAVE[_idim] + _hdel;
+
+ _hsum = (real_type)+0. ;
+ _hsum +=
+ _ppos[_idim] - _SAVE[_idim];
+
+ real_type _scr1 =
+ pred_type::tri3_cost (
+ &_mesh. node(
+ _tptr->node(0)).pval(0),
+ &_mesh. node(
+ _tptr->node(1)).pval(0),
+ &_mesh. node(
+ _tptr->node(2)).pval(0),
+ typename
+ pred_type::cell_kind ()
+ ) ;
+
+ _ppos[_idim] =
+ _SAVE[_idim] - _hdel;
+
+ _hsum -=
+ _ppos[_idim] - _SAVE[_idim];
+
+ real_type _scr0 =
+ pred_type::tri3_cost (
+ &_mesh. node(
+ _tptr->node(0)).pval(0),
+ &_mesh. node(
+ _tptr->node(1)).pval(0),
+ &_mesh. node(
+ _tptr->node(2)).pval(0),
+ typename
+ pred_type::cell_kind ()
+ ) ;
+
+ _sdel = _scr1 - _scr0 ;
+
+ _sbar = std::abs(_COST) ;
+ _sabs = std::abs(_sdel) ;
+
+ /*------------------ try to adjust step on rel. diff. */
+ if (_sabs > (real_type)0.)
{
- _line[_idim] =
- _move[_idim] / _wsum
- - _node->pval(_idim) ;
+ if (_sabs > _RMAX * _sbar)
+ {
+ _hdel/= (real_type) +10. ;
}
-
- _ladj = std::sqrt(_ladj / _tnum) ;
+ else
+ if (_sabs < _RMIN * _sbar)
+ {
+ _hdel*= (real_type) +10. ;
+ }
+ else { break ; }
+ }
+ else { break ; }
}
+ _ppos[_idim] = _SAVE [_idim];
+
+ /*------------------ finalise gradient and accumulate */
+
+ _DQDX[_idim] += _sdel / _hsum ;
+
+ }
}
/*
--------------------------------------------------------
- * DQDX-MOVE: "local-ascent" node movement vector.
+ * DQDX-QUAD: "local-ascent" node movement vector.
--------------------------------------------------------
*/
@@ -437,250 +985,333 @@
typename node_iter
>
__static_call
- __normal_call void_type dqdx_move_2 (
+ __normal_call void_type halo_quad_k (
mesh_type &_mesh ,
- size_type &_hfun ,
- pred_type &_pred ,
- iptr_list &_tset ,
+ iptr_type _cell ,
node_iter _node ,
- real_list &_cost ,
- real_type *_line ,
+ real_type *_bmin ,
+ real_type *_bmax ,
real_type &_ladj
)
+ {
+ iptr_type static constexpr
+ _last = pred_type::geom_dims + 0;
+
+ /*------------------------------------- cell indexing */
+ auto _qptr =
+ _mesh. quad().head() + _cell ;
+
+ auto _inod = _qptr->node(0) ;
+ auto _jnod = _qptr->node(1) ;
+ auto _knod = _qptr->node(2) ;
+ auto _lnod = _qptr->node(3) ;
+
+ auto _iptr =
+ _mesh. node().head() + _inod ;
+ auto _jptr =
+ _mesh. node().head() + _jnod ;
+ auto _kptr =
+ _mesh. node().head() + _knod ;
+ auto _lptr =
+ _mesh. node().head() + _lnod ;
+
+ /*------------------------------------- cell centroid */
+ real_type _pmid[_last + 0] = {
+ (real_type) +0.0} ;
+
+ for (auto _idim =
+ pred_type::geom_dims; _idim-- != +0; )
+ {
+ _pmid[_idim] +=
+ _iptr->pval(_idim) ;
+ _pmid[_idim] +=
+ _jptr->pval(_idim) ;
+ _pmid[_idim] +=
+ _kptr->pval(_idim) ;
+ _pmid[_idim] +=
+ _lptr->pval(_idim) ;
+ }
+ for (auto _idim =
+ pred_type::geom_dims; _idim-- != +0; )
+ {
+ _pmid[_idim]
+ /= (real_type) +4. ;
+ }
+
+ for (auto _idim =
+ pred_type::geom_dims; _idim-- != +0; )
+ {
+ _bmin[_idim] = std::min(
+ _bmin[_idim],
+ _pmid[_idim]) ;
+
+ _bmax[_idim] = std::max(
+ _bmax[_idim],
+ _pmid[_idim]) ;
+ }
+
+ /*------------------------------------- cell "length" */
+ real_type _lsqr =
+ pred_type::length_sq (
+ _pmid, &_node->pval(0)) ;
+
+ _ladj += _lsqr ;
+ }
+
+ template <
+ typename node_iter
+ >
+ __static_call
+ __normal_call void_type dqdx_quad_k (
+ mesh_type &_mesh ,
+ iptr_type _cell ,
+ node_iter _node ,
+ real_type _COST ,
+ real_type *_bmin ,
+ real_type *_bmax ,
+ real_type *_SAVE ,
+ real_type *_DQDX
+ )
{
real_type static const _HINC =
std::pow(std::numeric_limits
- ::epsilon(), +.50) ;
+ ::epsilon(), .50) ;
real_type static const _RMIN =
std::pow(std::numeric_limits
- ::epsilon(), +.75) ;
+ ::epsilon(), .75) ;
real_type static const _RMAX =
std::pow(std::numeric_limits
-