From 7857ded3025b3d7eb06ea7a0a51d74f1298ad6c7 Mon Sep 17 00:00:00 2001 From: dengwirda Date: Sun, 13 Sep 2020 14:39:21 -0600 Subject: [PATCH 1/6] Update bindings for jigsaw-0.9.13.xx --- bisect.m | 2 +- certify.m | 48 ++++- compile.m | 2 +- details.m | 2 +- example.m | 115 ++++++++++- extrude.m | 2 +- globals.m | 3 +- initjig.m | 2 +- inspect.m | 15 +- jigsaw.m | 2 +- jitter.m | 68 +++++-- loadjig.m | 2 +- loadmsh.m | 172 ++++++++++++++-- marche.m | 2 +- parse/loadoff.m | 2 +- parse/loadstl.m | 2 +- parse/saveoff.m | 2 +- parse/savestl.m | 2 +- parse/savevtk.m | 4 +- parse/savewav.m | 2 +- project.m | 2 +- savejig.m | 2 +- savemsh.m | 37 +++- tetris.m | 65 +++++- tools/aabb_tree/drawtree.m | 2 +- tools/aabb_tree/exchange.m | 67 ++++++ tools/aabb_tree/findball.m | 4 +- tools/aabb_tree/findline.m | 4 +- tools/aabb_tree/findpoly.m | 173 ++++++++++++++++ tools/aabb_tree/findtria.m | 4 +- tools/aabb_tree/lineline.m | 4 +- tools/aabb_tree/linenear.m | 2 +- tools/aabb_tree/maketree.m | 2 +- tools/aabb_tree/maprect.m | 2 +- tools/aabb_tree/mapvert.m | 2 +- tools/aabb_tree/queryset.m | 2 +- tools/aabb_tree/scantree.m | 2 +- tools/draw_util/drawedge_2.m | 2 +- tools/draw_util/drawhexa_8.m | 2 +- tools/draw_util/drawpyra_5.m | 2 +- tools/draw_util/drawquad_4.m | 2 +- tools/draw_util/drawtria_3.m | 2 +- tools/draw_util/drawtria_4.m | 2 +- tools/draw_util/drawwedg_6.m | 2 +- tools/drawcost.m | 2 +- tools/drawmesh.m | 2 +- tools/ellipsoid/R3toS2.m | 2 +- tools/ellipsoid/S2toR3.m | 2 +- tools/ellipsoid/cubedsphere.m | 130 ++++++++++-- tools/ellipsoid/icosahedron.m | 150 +++++++++++++- tools/geom_util/getiso2.m | 2 +- tools/geom_util/getnan2.m | 2 +- tools/geom_util/stereo3.m | 2 +- tools/math_util/inv_2x2.m | 2 +- tools/math_util/inv_3x3.m | 2 +- tools/mesh_util/idxtri2.m | 2 +- tools/mesh_util/idxtri3.m | 2 +- tools/mesh_util/trifun2.m | 2 +- tools/mesh_util/trifun3.m | 2 +- tools/meshcost.m | 2 +- tools/orthoball/pwrbal1.m | 2 +- tools/orthoball/pwrbal2.m | 2 +- tools/orthoball/pwrbal3.m | 2 +- tools/orthoball/quadbal2.m | 190 +++++++++++++++++ tools/orthoball/quadbal2.m~ | 190 +++++++++++++++++ tools/orthoball/tribal1.m | 2 +- tools/orthoball/tribal2.m | 2 +- tools/orthoball/tribal3.m | 2 +- tools/poly_sign/README.md | 4 + tools/poly_sign/inpoly2.m | 351 +++++++++++++++++--------------- tools/poly_sign/inpoly2_mat.m | 74 +++---- tools/poly_sign/inpoly2_oct.cpp | 72 +++---- tools/predicate/normal2.m | 2 +- tools/predicate/orient1.m | 2 +- tools/predicate/orient2.m | 2 +- tools/predicate/trivol2.m | 2 +- tools/predicate/trivol3.m | 2 +- tools/scorecard/pwrscr2.m | 2 +- tools/scorecard/pwrscr3.m | 6 +- tools/scorecard/relfun2.m | 2 +- tools/scorecard/relfun3.m | 2 +- tools/scorecard/triang2.m | 2 +- tools/scorecard/triang3.m | 2 +- tools/scorecard/trideg2.m | 2 +- tools/scorecard/trideg3.m | 2 +- tools/scorecard/triscr2.m | 2 +- tools/scorecard/triscr3.m | 2 +- tools/scorecard/welcen2.m | 2 +- tools/scorecard/welcen3.m | 2 +- tripod.m | 2 +- 90 files changed, 1693 insertions(+), 389 deletions(-) create mode 100644 tools/aabb_tree/exchange.m create mode 100644 tools/aabb_tree/findpoly.m create mode 100644 tools/orthoball/quadbal2.m create mode 100644 tools/orthoball/quadbal2.m~ 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..c838153 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 %----------------------------------------------------------- % @@ -80,6 +80,33 @@ function example(varargin) % construction of geometry + user-defined mesh-size const- % raints. + %{ + SEEDS=N + X;Y;Z;PART + + after rdel, before optm + project onto IDIM geometry closest feature + find intersecting cell, if any + bfs to all d-1 connected cells, stop at d-1 face that's a boundary + or external + + If there's no IDIM=k, just return the full k-DEL as now? + + Maybe we can worry about using this within rdel-mesh later? + + Are SEEDS part of the geometry definition? I think so... + + Build an aabb-tree for the mesh to facilitate the scan? + + Will TRIPOD do this too? Probably? + + What happens if you only pass input for optm? Prune the mesh passed? + Yes, I guess so. + So this is not so different from the mesh_func infrastructure... + Steal this and put somewhere common? + %} + + demo_A(); demo_B(); demo_C(); @@ -160,12 +187,86 @@ function example(varargin) opts.mesh_dims = +2 ; % 2-dim. simplexes opts.optm_qlim = +.95 ; - + opts.mesh_top1 = true ; % for sharp feat's opts.geom_feat = true ; + %opts.optm_kern = 'cvt+dqdx'; + + %opts.verbosity = +3 ; + mesh = jigsaw (opts) ; + + + %{ + for iter = 1:32 + + pmid = mesh.point.coord(mesh.tria3.index(:,1),1:2) ... + + mesh.point.coord(mesh.tria3.index(:,2),1:2) ... + + mesh.point.coord(mesh.tria3.index(:,3),1:2) ; + pmid = pmid / 3. ; + + move = zeros(size(mesh.point.coord,1),2); + wsum = zeros(size(mesh.point.coord,1),1); + nadj = zeros(size(mesh.point.coord,1),1); + ladj = zeros(size(mesh.point.coord,1),1); + + area = trivol2(mesh.point.coord(:,1:2), ... + mesh.tria3.index(:,1:3)) ; + + ball = tribal2(mesh.point.coord(:,1:2), ... + mesh.tria3.index(:,1:3)) ; + + pmid = (pmid + ball(:,1:2)) * .5 ; + + for cell = 1:size(mesh.tria3.index,1) + + inod = mesh.tria3.index(cell,1); + jnod = mesh.tria3.index(cell,2); + knod = mesh.tria3.index(cell,3); + + move(inod,:) = move(inod,:) + area(cell) * pmid(cell,1:2); + move(jnod,:) = move(jnod,:) + area(cell) * pmid(cell,1:2); + move(knod,:) = move(knod,:) + area(cell) * pmid(cell,1:2); + + wsum(inod,1) = wsum(inod,1) + area(cell,1); + wsum(jnod,1) = wsum(jnod,1) + area(cell,1); + wsum(knod,1) = wsum(knod,1) + area(cell,1); + + nadj(inod,1) = nadj(inod,1) + 1; + nadj(jnod,1) = nadj(jnod,1) + 1; + nadj(knod,1) = nadj(knod,1) + 1; + + ladj(inod,1) = ladj(inod,1) + ball(cell,3); + ladj(jnod,1) = ladj(jnod,1) + ball(cell,3); + ladj(knod,1) = ladj(knod,1) + ball(cell,3); + + end + + ladj = ladj ./ [nadj]; + move = move ./ [wsum,wsum]; + + ladj(mesh.edge2.index(:,1:2)) = inf ; + + lmov = sum((mesh.point.coord(:,1:2)-move).^2,2); + + ltol = 1.E-04; nmov = 0; + for node = 1:size(mesh.point.coord,1) + if (lmov(node) > ltol * ladj(node)) + nmov = nmov + 1; + mesh.point.coord(node,1:2) = move(node,:); + end + end + + disp(nmov); + + if (nmov <= 0), break; end + + end + %} + + figure('color','w'); patch ('faces',mesh.tria3.index(:,1:3), ... 'vertices',mesh.point.coord(:,1:2), ... @@ -184,7 +285,7 @@ function example(varargin) 'linewidth',1.5) ; drawcost(mesh) ; - + end function demo_B @@ -496,13 +597,17 @@ function example(varargin) %------------------------------------ make mesh using JIGSAW - opts.hfun_hmax = 0.08 ; % push HFUN limits + opts.hfun_hmax = 0.02 ; % push HFUN limits opts.mesh_dims = +3 ; % 3-dim. simplexes opts.mesh_top1 = true ; % for sharp feat's opts.geom_feat = true ; + %opts.mesh_iter = 1000 ; + + %opts.mesh_kern = 'delaunay'; + mesh = jigsaw (opts) ; mask = []; @@ -1122,6 +1227,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/extrude.m b/extrude.m index 208c830..f52c323 100644 --- a/extrude.m +++ b/extrude.m @@ -15,7 +15,7 @@ % Darren Engwirda % github.com/dengwirda/jigsaw-matlab % 09-Aug-2019 -% darren.engwirda@columbia.edu +% d.engwirda@gmail.com %----------------------------------------------------------- % diff --git a/globals.m b/globals.m index 5a9d6ea..2892ffc 100644 --- a/globals.m +++ b/globals.m @@ -7,7 +7,7 @@ % Darren Engwirda % github.com/dengwirda/jigsaw-matlab % 27-Nov-2019 -% darren.engwirda@columbia.edu +% d.engwirda@gmail.com %----------------------------------------------------------- % @@ -90,6 +90,7 @@ JIGSAW_KERN_ODT_DQDX = +404 ; JIGSAW_KERN_CVT_DQDX = +405 ; + JIGSAW_KERN_H95_DQDX = +406 ; end diff --git a/initjig.m b/initjig.m index 475b840..959cb25 100644 --- a/initjig.m +++ b/initjig.m @@ -8,7 +8,7 @@ % Darren Engwirda % github.com/dengwirda/jigsaw-matlab % 26-Jul-2019 -% darren.engwirda@columbia.edu +% d.engwirda@gmail.com %----------------------------------------------------------- % diff --git a/inspect.m b/inspect.m index 5da0c64..056791e 100644 --- a/inspect.m +++ b/inspect.m @@ -4,8 +4,8 @@ %----------------------------------------------------------- % Darren Engwirda % github.com/dengwirda/jigsaw-matlab -% 19-Dec-2018 -% darren.engwirda@columbia.edu +% 30-May-2020 +% d.engwirda@gmail.com %----------------------------------------------------------- % @@ -44,18 +44,19 @@ case 'wedg6', item = 'index' ; case 'pyra5', item = 'index' ; case 'bound', item = 'index' ; + case 'seeds', item = 'coord' ; end end if (isempty(item)) %-- check whether MESH.BASE exists - okay = isfield(mesh,base) && ... - ~isempty(mesh.(base)) ; + okay = isfield(mesh, base) && ... + ~isempty(mesh.(base)) ; else %-- check whether MESH.BASE.ITEM exists - okay = isfield(mesh,base) && ... - isfield(mesh.(base),item) && ... - ~isempty(mesh.(base).(item)) ; + okay = isfield(mesh, base) && ... + isfield(mesh.(base), item) && ... + ~isempty(mesh.(base).(item)) ; end end diff --git a/jigsaw.m b/jigsaw.m index 7f141b6..fad2820 100644 --- a/jigsaw.m +++ b/jigsaw.m @@ -248,7 +248,7 @@ % Darren Engwirda % github.com/dengwirda/jigsaw-matlab % 29-Oct-2019 -% darren.engwirda@columbia.edu +% d.engwirda@gmail.com %----------------------------------------------------------- % diff --git a/jitter.m b/jitter.m index 88c30a2..a752e41 100644 --- a/jitter.m +++ b/jitter.m @@ -6,8 +6,8 @@ %----------------------------------------------------------- % Darren Engwirda % github.com/dengwirda/jigsaw-matlab -% 12-Feb-2020 -% darren.engwirda@columbia.edu +% 03-Sep-2020 +% d.engwirda@gmail.com %----------------------------------------------------------- % @@ -20,12 +20,14 @@ end + next = mesh ; best = metric (mesh); + for iter = +1 : imax - if (~isempty(mesh)) + if (~isempty(next)) keep = ... - true(size(mesh.point.coord, 1), 1) ; + true(size(next.point.coord, 1), 1) ; %---------------------------------- setup initial conditions [path,name,fext] = ... @@ -38,28 +40,28 @@ OPTS.init_file = ... [path,name,'-INIT',fext] ; - if (inspect(mesh,'tria3')) + if (inspect(next,'tria3')) %---------------------------------- mark any irregular nodes vdeg = trideg2 ( ... - mesh.point.coord(:,1:end-1), ... - mesh.tria3.index(:,1:end-1)) ; + next.point.coord(:,1:end-1), ... + next.tria3.index(:,1:end-1)) ; ierr = abs(vdeg - 6) ; % error wrt. topol. degree ierr(vdeg > 6) = ierr(vdeg > 6) * +2 ; M = sum(ierr( ... - mesh.tria3.index(:,1:3)), 2) >= ibad ; + next.tria3.index(:,1:3)), 2) >= ibad ; - keep(mesh.tria3.index(M,1:3)) = false; + keep(next.tria3.index(M,1:3)) = false; end - if (inspect(mesh,'edge2')) + if (inspect(next,'edge2')) - keep(mesh.edge2.index(:,1:2)) = true ; + keep(next.edge2.index(:,1:2)) = true ; end @@ -82,7 +84,17 @@ end %---------------------------------- call JIGSAW with new ICs - mesh = jigsaw(OPTS) ; + next = jigsaw(OPTS) ; + + cost = metric(next) ; + + if (cost > best) + +%---------------------------------- keep "best" mesh so far! + mesh = next; + best = cost; + + end if (done), break; end @@ -90,5 +102,37 @@ end +function [cnrm] = metric(mesh) +%METRIC assemble a combined "cosst" metric for a given mesh. + + cost = [] ; cnrm = +0.0 ; + + if (inspect(mesh,'tria3')) +%--------------------------------------- append TRIA3 scores + COST = triscr2( ... + mesh.point.coord(:,1:end-1), ... + mesh.tria3.index(:,1:end-1)) ; + + cost = [cost; COST] ; + end + + if (inspect(mesh,'tria4')) +%--------------------------------------- append TRIA4 scores + COST = triscr3( ... + mesh.point.coord(:,1:end-1), ... + mesh.tria4.index(:,1:end-1)) ; + + cost = [cost; COST] ; + end + + if (isempty(cost)), return ; end + + norm = sum ((+1.0 ./ cost) .^ 3) ; + + cnrm = ... + nthroot(length(cost) ./ norm, 3) ; + +end + diff --git a/loadjig.m b/loadjig.m index 9d5ece9..84c7bd9 100644 --- a/loadjig.m +++ b/loadjig.m @@ -5,7 +5,7 @@ % Darren Engwirda % github.com/dengwirda/jigsaw-matlab % 29-Oct-2019 -% darren.engwirda@columbia.edu +% d.engwirda@gmail.com %----------------------------------------------------------- % diff --git a/loadmsh.m b/loadmsh.m index 829b61d..6cd8874 100644 --- a/loadmsh.m +++ b/loadmsh.m @@ -59,7 +59,7 @@ % element numbering and INDEX(:,3) is an array of % element "tags", describing which element "kind" is % numbered via INDEX(:,2). Element tags are defined -% via a series of constants instantiated in LIBDATA. +% via constants defined in GLOBALS.m. % In the default case, where BOUND is not specified, % all elements in the geometry are assumed to define % the boundaries of enclosed "parts". @@ -106,8 +106,8 @@ %----------------------------------------------------------- % Darren Engwirda % github.com/dengwirda/jigsaw-matlab -% 20-Aug-2019 -% darren.engwirda@columbia.edu +% 30-May-2020 +% d.engwirda@gmail.com %----------------------------------------------------------- % @@ -155,6 +155,13 @@ nver = str2double(stag{1}) ; + if (isnan(nver)) + + warning(['Invalid MSHID: ', lstr]); + continue; + + end + if (length(stag) >= +2) kind = ... strtrim(upper(stag{2})); @@ -180,6 +187,13 @@ str2double(stag{3}) ... ] ; + if (any(isnan(mesh.radii))) + + warning(['Invalid RADII: ', lstr]); + continue; + + end + else warning(['Invalid RADII: ', lstr]); @@ -195,9 +209,16 @@ numr = nnum*(ndim+1); - data = ... + [data,have] = ... fscanf(ffid,[repmat(real,1,ndim),'%i'],numr); + if (have ~= numr) + + warning('Invalid POINT! ') ; + continue ; + + end + if (ndim == +2) mesh.point.coord = [ ... data(1:3:end), ... @@ -212,6 +233,38 @@ data(4:4:end)] ; end + case 'seeds' + + %-- read "SEEDS" data + + nnum = str2double(tstr{2}) ; + + numr = nnum*(ndim+1); + + [data,have] = ... + fscanf(ffid,[repmat(real,1,ndim),'%i'],numr); + + if (have ~= numr) + + warning('Invalid SEEDS! ') ; + continue ; + + end + + if (ndim == +2) + mesh.seeds.coord = [ ... + data(1:3:end), ... + data(2:3:end), ... + data(3:3:end)] ; + end + if (ndim == +3) + mesh.seeds.coord = [ ... + data(1:4:end), ... + data(2:4:end), ... + data(3:4:end), ... + data(4:4:end)] ; + end + case 'coord' %-- read "COORD" data @@ -223,8 +276,16 @@ ndim = max(ndim,idim); - data = fscanf(ffid,'%f',cnum) ; + [data,have] = ... + fscanf(ffid,'%f',cnum) ; + if (have ~= cnum) + + warning('Invalid COORD! ') ; + continue ; + + end + mesh.point.coord{idim}= data ; case 'edge2' @@ -235,9 +296,16 @@ numr = nnum * 3; - data = ... + [data,have] = ... fscanf(ffid,[repmat(ints,1,2),'%i'],numr); + if (have ~= numr) + + warning('Invalid EDGE2! ') ; + continue ; + + end + mesh.edge2.index = [ ... data(1:3:end), ... data(2:3:end), ... @@ -254,9 +322,16 @@ numr = nnum * 4; - data = ... + [data,have] = ... fscanf(ffid,[repmat(ints,1,3),'%i'],numr); + if (have ~= numr) + + warning('Invalid TRIA3! ') ; + continue ; + + end + mesh.tria3.index = [ ... data(1:4:end), ... data(2:4:end), ... @@ -274,9 +349,16 @@ numr = nnum * 5; - data = ... + [data,have] = ... fscanf(ffid,[repmat(ints,1,4),'%i'],numr); + if (have ~= numr) + + warning('Invalid QUAD4! ') ; + continue ; + + end + mesh.quad4.index = [ ... data(1:5:end), ... data(2:5:end), ... @@ -295,9 +377,16 @@ numr = nnum * 5; - data = ... + [data,have] = ... fscanf(ffid,[repmat(ints,1,4),'%i'],numr); + if (have ~= numr) + + warning('Invalid TRIA4! ') ; + continue ; + + end + mesh.tria4.index = [ ... data(1:5:end), ... data(2:5:end), ... @@ -316,9 +405,16 @@ numr = nnum * 9; - data = ... + [data,have] = ... fscanf(ffid,[repmat(ints,1,8),'%i'],numr); + if (have ~= numr) + + warning('Invalid HEXA8! ') ; + continue ; + + end + mesh.hexa8.index = [ ... data(1:9:end), ... data(2:9:end), ... @@ -341,9 +437,16 @@ numr = nnum * 7; - data = ... + [data,have] = ... fscanf(ffid,[repmat(ints,1,6),'%i'],numr); + if (have ~= numr) + + warning('Invalid WEDG6! ') ; + continue ; + + end + mesh.wedg6.index = [ ... data(1:7:end), ... data(2:7:end), ... @@ -364,9 +467,16 @@ numr = nnum * 6; - data = ... + [data,have] = ... fscanf(ffid,[repmat(ints,1,5),'%i'],numr); + if (have ~= numr) + + warning('Invalid PYRA5! ') ; + continue ; + + end + mesh.pyra5.index = [ ... data(1:6:end), ... data(2:6:end), ... @@ -386,9 +496,16 @@ numr = nnum * 3; - data = ... + [data,have] = ... fscanf(ffid,[repmat(ints,1,2),'%i'],numr); + if (have ~= numr) + + warning('Invalid BOUND! ') ; + continue ; + + end + mesh.bound.index = [ ... data(1:3:end), ... data(2:3:end), ... @@ -415,13 +532,20 @@ end - numr = nnum * (vnum+1) ; + numr = nnum * (vnum+0) ; fstr = repmat(real,1,vnum) ; - data = fscanf( ... + [data,have] = fscanf( ... ffid,fstr(1:end-1),numr) ; + if (have ~= numr) + + warning(['Invalid VALUE: ', lstr]); + continue ; + + end + mesh.value = zeros(nnum, vnum); for vpos = +1 : vnum @@ -453,9 +577,16 @@ fstr = repmat(real,1,pnum) ; - data = fscanf( ... + [data,have] = fscanf( ... ffid,fstr(1:end-1),numr) ; + if (have ~= numr) + + warning(['Invalid POWER: ', lstr]); + continue ; + + end + mesh.point.power = ... zeros(nnum, pnum) ; @@ -488,9 +619,16 @@ fstr = repmat(real,1,vnum) ; - data = fscanf( ... + [data,have] = fscanf( ... ffid,fstr(1:end-1),numr) ; + if (have ~= numr) + + warning(['Invalid SLOPE: ', lstr]); + continue ; + + end + mesh.slope = ... zeros(nnum, vnum) ; diff --git a/marche.m b/marche.m index 194997d..57138cf 100644 --- a/marche.m +++ b/marche.m @@ -39,7 +39,7 @@ % Darren Engwirda % github.com/dengwirda/jigsaw-matlab % 05-Aug-2019 -% darren.engwirda@columbia.edu +% d.engwirda@gmail.com %----------------------------------------------------------- % diff --git a/parse/loadoff.m b/parse/loadoff.m index 02b4c33..b2d9fcf 100644 --- a/parse/loadoff.m +++ b/parse/loadoff.m @@ -26,7 +26,7 @@ % Darren Engwirda % github.com/dengwirda/jigsaw-matlab % 14-Jul-2018 -% darren.engwirda@columbia.edu +% d.engwirda@gmail.com %----------------------------------------------------------- % diff --git a/parse/loadstl.m b/parse/loadstl.m index d1e7d97..157412b 100644 --- a/parse/loadstl.m +++ b/parse/loadstl.m @@ -21,7 +21,7 @@ % Darren Engwirda % github.com/dengwirda/jigsaw-matlab % 14-Jul-2018 -% darren.engwirda@columbia.edu +% d.engwirda@gmail.com %----------------------------------------------------------- % diff --git a/parse/saveoff.m b/parse/saveoff.m index 4512068..a70593d 100644 --- a/parse/saveoff.m +++ b/parse/saveoff.m @@ -26,7 +26,7 @@ function saveoff(name,mesh) % Darren Engwirda % github.com/dengwirda/jigsaw-matlab % 15-Jul-2018 -% darren.engwirda@columbia.edu +% d.engwirda@gmail.com %----------------------------------------------------------- % diff --git a/parse/savestl.m b/parse/savestl.m index 18dc859..e31979b 100644 --- a/parse/savestl.m +++ b/parse/savestl.m @@ -38,7 +38,7 @@ function savestl(name,mesh,varargin) % Darren Engwirda % github.com/dengwirda/jigsaw-matlab % 15-Jul-2018 -% darren.engwirda@columbia.edu +% d.engwirda@gmail.com %----------------------------------------------------------- % diff --git a/parse/savevtk.m b/parse/savevtk.m index 14f3ff0..0fb8363 100644 --- a/parse/savevtk.m +++ b/parse/savevtk.m @@ -84,7 +84,7 @@ function savevtk(name,mesh) % Darren Engwirda % github.com/dengwirda/jigsaw-matlab % 20-Aug-2019 -% darren.engwirda@columbia.edu +% d.engwirda@gmail.com %----------------------------------------------------------- % @@ -244,7 +244,7 @@ function save_mesh_format(ffid,file,mesh,kind) if (inspect(mesh,'quad4')) %-- write "QUAD4" data fprintf(ffid,['4 ',repmat('%u ',1,4),'\n'], ... - mesh.quad4.index(:,1:3)'-1); + mesh.quad4.index(:,1:4)'-1); end if (inspect(mesh,'tria4')) %-- write "TRIA4" data diff --git a/parse/savewav.m b/parse/savewav.m index f9e42c4..be11486 100644 --- a/parse/savewav.m +++ b/parse/savewav.m @@ -31,7 +31,7 @@ function savewav(name,mesh) % Darren Engwirda % github.com/dengwirda/jigsaw-matlab % 05-Mar-2019 -% darren.engwirda@columbia.edu +% d.engwirda@gmail.com %----------------------------------------------------------- % diff --git a/project.m b/project.m index 0670cd0..88b8b02 100644 --- a/project.m +++ b/project.m @@ -19,7 +19,7 @@ % Darren Engwirda % github.com/dengwirda/jigsaw-matlab % 30-Aug-2019 -% darren.engwirda@columbia.edu +% d.engwirda@gmail.com %----------------------------------------------------------- % diff --git a/savejig.m b/savejig.m index 6f6046b..8361bca 100644 --- a/savejig.m +++ b/savejig.m @@ -5,7 +5,7 @@ function savejig(name,opts) % Darren Engwirda % github.com/dengwirda/jigsaw-matlab % 29-Oct-2019 -% darren.engwirda@columbia.edu +% d.engwirda@gmail.com %----------------------------------------------------------- % diff --git a/savemsh.m b/savemsh.m index eecf03d..a9067b8 100644 --- a/savemsh.m +++ b/savemsh.m @@ -59,7 +59,7 @@ function savemsh(name,mesh) % element numbering and INDEX(:,3) is an array of % element "tags", describing which element "kind" is % numbered via INDEX(:,2). Element tags are defined -% via a series of constants instantiated in LIBDATA. +% via constants defined in GLOBALS.m. % In the default case, where BOUND is not specified, % all elements in the geometry are assumed to define % the boundaries of enclosed "parts". @@ -76,7 +76,7 @@ function savemsh(name,mesh) % .IF. MESH.MSHID == 'ELLIPSOID-MESH': % ----------------------------------- % -% MESH.RADII - [ 3x 1] array of principle ellipsoid radii. +% MESH.RADII - [ 3x 1] array of principal ellipsoid radii. % % Additionally, entities described in the 'EUCLIDEAN-MESH' % data-type are optionally written. @@ -107,8 +107,8 @@ function savemsh(name,mesh) %----------------------------------------------------------- % Darren Engwirda % github.com/dengwirda/jigsaw-matlab -% 20-Aug-2019 -% darren.engwirda@columbia.edu +% 30-May-2020 +% d.engwirda@gmail.com %----------------------------------------------------------- % @@ -255,6 +255,35 @@ function save_mesh_format(ffid,nver,mesh,kind) end + if (isfield(mesh,'seeds') && ... + isfield(mesh.seeds,'coord') && ... + ~isempty(mesh.seeds.coord) ) + + %------------------------------------ write "SEEDS" data + + if (~isnumeric(mesh.seeds.coord)) + error('Incorrect input type!'); + end + if (ndims(mesh.seeds.coord) ~= 2) + error('Incorrect dimensions!'); + end + + sdim = size(mesh.seeds.coord,2)-1 ; + + fprintf(ffid, ... + ['SEEDS=%u','\n'],size(mesh.seeds.coord,1)); + + if (isa(mesh.seeds.coord,'double')) + vstr = sprintf('%%1.%ug;',+16); + else + vstr = sprintf('%%1.%ug;',+ 8); + end + + fprintf(ffid, ... + [repmat(vstr,1,sdim),'%i\n'],mesh.seeds.coord'); + + end + if (isfield(mesh,'point') && ... isfield(mesh.point,'power') && ... ~isempty(mesh.point.power) ) diff --git a/tetris.m b/tetris.m index d0ce2c1..78e8c1f 100644 --- a/tetris.m +++ b/tetris.m @@ -14,8 +14,8 @@ %----------------------------------------------------------- % Darren Engwirda % github.com/dengwirda/jigsaw-matlab -% 12-Feb-2020 -% darren.engwirda@columbia.edu +% 03-Sep-2020 +% d.engwirda@gmail.com %----------------------------------------------------------- % @@ -36,7 +36,7 @@ %---------------------------- call JIGSAW via inc. bisection SCAL = +2. ^ nlev; - OPTS = opts ; + OPTS = opts ; NLEV = nlev ; while (nlev >= +0) @@ -85,16 +85,37 @@ end - if (nlev >= +1) + if (isfield(opts,'optm_qlim')) +%---------------------------- create/write current QLIM flag + scal = min( ... + 2.0, (nlev + 1) ^ (1./4.)); + + QLIM = opts.optm_qlim ; + + OPTS.optm_qlim = QLIM / scal; + + else + + scal = min( ... + 2.0, (nlev + 1) ^ (1./4.)); + + QLIM = 0.93750 ; + + OPTS.optm_qlim = QLIM / scal; + + end + + if (mod(nlev, 2) ~= 0) + %---------------------------- call JIGSAW kernel at this lev - mesh = jitter (OPTS,round( ... - +3*(nlev+1)^(5./4.)), +2) ; + mesh = jitter ( ... + OPTS, 3 + nlev * (nlev - 1), 2) ; else - mesh = jitter (OPTS,round( ... - +3*(nlev+1)^(5./4.)), +3) ; + mesh = jitter ( ... + OPTS, 3 + nlev * (nlev - 1), 3) ; end @@ -150,6 +171,13 @@ function [mesh] = attach(mesh) %ATTACH attach points to the underlying geometry definition. + if (inspect(mesh,'hexa8')) + + mark = mesh.hexa8.index(:,1:8); + mesh.point.coord(mark,end) = 3; + + end + if (inspect(mesh,'tria4')) mark = mesh.tria3.index(:,1:4); @@ -157,6 +185,27 @@ end + if (inspect(mesh,'wedg6')) + + mark = mesh.wedg6.index(:,1:6); + mesh.point.coord(mark,end) = 3; + + end + + if (inspect(mesh,'pyra5')) + + mark = mesh.pyra5.index(:,1:5); + mesh.point.coord(mark,end) = 3; + + end + + if (inspect(mesh,'quad4')) + + mark = mesh.quad4.index(:,1:4); + mesh.point.coord(mark,end) = 2; + + end + if (inspect(mesh,'tria3')) mark = mesh.tria3.index(:,1:3); diff --git a/tools/aabb_tree/drawtree.m b/tools/aabb_tree/drawtree.m index be5d530..d4b271a 100644 --- a/tools/aabb_tree/drawtree.m +++ b/tools/aabb_tree/drawtree.m @@ -5,7 +5,7 @@ function drawtree(tr,varargin) % See also MAKETREE % Darren Engwirda : 2014 -- -% Email : darren.engwirda@columbia.edu +% Email : d.engwirda@gmail.com % Last updated : 18/12/2014 %---------------------------------------------- basic checks diff --git a/tools/aabb_tree/exchange.m b/tools/aabb_tree/exchange.m new file mode 100644 index 0000000..31ed862 --- /dev/null +++ b/tools/aabb_tree/exchange.m @@ -0,0 +1,67 @@ +function [qp,qx] = exchange(pp,px) +%EXCHANGE change the "associativity" of a sparse list set. +% [QP,QX] = EXCHANGE(PP,PX) returns a new set of sparse +% lists {QP,QX} as the "transpose" of the input collection +% {PP,PX}. This operation can be used to form the inverse +% associations between two collections of objects. For +% example, given two collections A and B, if the input set +% {PP,PI} represents the indexing of A-into-B, the new set +% {QP,QI} represents the indexing of B-into-A. +% List sets are defined via a "compressed sparse" format, +% with the II-th list in a given collection {XP,XX} stored +% as XX(XP(II,1):XP(II,2)). +% +% See also QUERYSET + +% Darren Engwirda : 2020 -- +% Email : d.engwirda@gmail.com +% Last updated : 05/06/2020 + +%---------------------------------------------- basic checks + if ( ~isnumeric(pp) || ~isnumeric(px)) + error('exchange:incorrectInputClass', ... + 'Incorrect input class.') ; + end + + if (size(pp,2) ~= 2 || size(px,2) ~= 1 ) + error('exchange:incorrectDimensions', ... + 'Incorrect input dimensions.') ; + end + + if (min(px(:)) <= 0 || ... + max(pp(:)) > length(px) ) + error('exchange:invalidListIndexing', ... + 'Invalid list indexing.') ; + end + +%----------------------------------- compute list "tranpose" + + qp = zeros(max(px),2); + qx = zeros(length(px),1); + + for ip = 1:length(pp) % accumulate column count + for ii = pp(ip,1):pp(ip,2) + qp(px(ii),2) = qp(px(ii),2) + 1; + end + end + + Z = qp(:,2) == +0 ; % deal with "empty" lists + + qp(:,2) = cumsum(qp(:,2)); + qp(:,1) = [+1;qp(1:end-1,2)+1]; + + for ip = 1:length(pp) % tranpose of items array + for ii = pp(ip,1):pp(ip,2) + qx(qp(px(ii),1)) = ip; + qp(px(ii),1) = qp(px(ii),1) + 1; + end + end + + qp(:,1) = [+1;qp(1:end-1,2)+1]; + + qp(Z,1) = +0; % deal with "empty" lists + qp(Z,2) = -1; + +end + + diff --git a/tools/aabb_tree/findball.m b/tools/aabb_tree/findball.m index 35e1eea..c2d847c 100644 --- a/tools/aabb_tree/findball.m +++ b/tools/aabb_tree/findball.m @@ -24,7 +24,7 @@ % [...] = FINDBALL(BB,PI,TR,OP). See MAKETREE for additio- % nal information. % -% See also MAKETREE, FINDTRIA +% See also MAKETREE, EXCHANGE % Please see the following for additional information: % @@ -34,7 +34,7 @@ % http://hdl.handle.net/2123/13148 % Darren Engwirda : 2017 -- -% Email : de2363@columbia.edu +% Email : d.engwirda@gmail.com % Last updated : 27/04/2017 bp = []; bj = []; tr = []; op = []; diff --git a/tools/aabb_tree/findline.m b/tools/aabb_tree/findline.m index 1f21a7c..2177c05 100644 --- a/tools/aabb_tree/findline.m +++ b/tools/aabb_tree/findline.m @@ -25,7 +25,7 @@ % passed via [...] = FINDLINE(...,TR,OP). See MAKETREE for % additional information. % -% See also MAKETREE, FINDTRIA, FINDBALL, LINELINE +% See also MAKETREE, EXCHANGE % Please see the following for additional information: % @@ -36,7 +36,7 @@ %----------------------------------------------------------- % Darren Engwirda : 2017 -- -% Email : de2363@columbia.edu +% Email : d.engwirda@gmail.com % Last updated : 02/08/2017 %----------------------------------------------------------- diff --git a/tools/aabb_tree/findpoly.m b/tools/aabb_tree/findpoly.m new file mode 100644 index 0000000..f4dd261 --- /dev/null +++ b/tools/aabb_tree/findpoly.m @@ -0,0 +1,173 @@ +function [ip,ix,tr] = findpoly(pp,ee,pj,varargin) +%FINDPOLY point-in-polygon queries for polygon collections. +% [IP,IX] = FINDPOLY(PP,EE,PJ) returns the set of polygons +% that enclose the points in the distribution PJ. Polygons +% are specified via the cell arrays: +% +% PP{kk} = [X11,Y11;X22,Y22;...;XNN,YNN]; +% EE{kk} = [E11,E12;E21,E22;...;EM1;EM2]; +% +% where PP{kk} defines the vertex coordinates of the KK-th +% polygon, and EE{kk} defines its edges. Each edge is +% specified as a pair of vertex indices, such that +% PP{kk}(EE{kk}(II,1),:) and PP{kk}(EE{kk}(II,2),:) define +% the endpoints of the II-th edge in the KK-th polygon. +% +% A set of intersecting polygons is returned for each +% query point in PJ, such that the II-th point is associa- +% ted with the polygons IX(IP(II,1):IP(II,2)). Unenclosed +% points have IP(II,1) == +0. +% +% In general, query points may be matched to multiple pol- +% gons (in cases where polygons overlap). +% +% [IP,IX,TR] = FINDPOLY(PP,EE,PJ) additionally returns the +% supporting aabb-tree used internally to compute the que- +% ry. If the underlying collection [PP,EE] is static, the +% tree TR may be passed to subsequent calls, via [...] = +% FINDPOLY(PP,EE,PJ,TR). This syntax may lead to improved +% performance, especially when the number of polygons +% is large w.r.t. the number of query points. Note that in +% such cases the underlying polygons are NOT permitted to +% change between calls, or erroneous results may be retur- +% ned. Additional parameters used to control the creation +% of the underlying aabb-tree may also be passed via [...] +% = FINDPOLY(PP,EE,PI,TR,OP). See MAKETREE for additional +% information. +% +% See also MAKETREE, EXCHANGE + +% Given K polygons (each with M edges on average) the task +% is to find the enclosing polygons for a set of N points. +% The (obvious) naive implementation is expensive, leading +% to O(K*M*N) complexity (based on a simple loop over all +% polygons, and calling a standard points-in-polygon test +% for each individually). This code aims to do better: +% +% * Employing a "fast" inpolygon routine, reducing the comp- +% lexity of each points-in-polygon test (based on spatial +% sorting) to approximately O((N+M)*log(N)). +% +% * Employing a spatial tree (an aabb-tree) to localise each +% points-in-polygon query within a spatially local "tile". +% This typically gains another logarithmic factor, so is a +% big win for large K. + +% Darren Engwirda : 2020 -- +% Email : d.engwirda@gmail.com +% Last updated : 29/03/2020 + + ip = []; ix = []; tr = []; op = []; + +%---------------------------------------------- basic checks + if (nargin < +3 || nargin > +5) + error('findpoly:incorrectNumInputs', ... + 'Incorrect number of inputs.'); + end + +%------------------------------- fast return on empty inputs + if (isempty(pj)), return; end + +%------------------------------- extract user-defined inputs + if (nargin >= +4), tr = varargin{1}; end + if (nargin >= +5), op = varargin{2}; end + +%---------------------------------------------- basic checks + if (~iscell(pp) || ~iscell(ee) || ... + ~isnumeric(pj) ) + error('findpoly:incorrectInputClass', ... + 'Incorrect input class.') ; + end + +%---------------------------------------------- basic checks + if (any(cellfun('ndims', pp) ~= +2) || ... + any(cellfun('size', pp, 2) ~= +2)) + error('findpoly:incorrectDimensions', ... + 'Incorrect input dimensions.'); + end + if (any(cellfun('ndims', ee) ~= +2) || ... + any(cellfun('size', ee, 2) ~= +2)) + error('findpoly:incorrectDimensions', ... + 'Incorrect input dimensions.'); + end + +%------------------------------- test query array for VERT's + if (ndims(pj) ~= +2 || size(pj,2) ~= +2 ) + error('findpoly:incorrectDimensions', ... + 'Incorrect input dimensions.'); + end + +%---------------------------------------------- basic checks + if (~isempty(tr) && ~isstruct(tr) ) + error('findpoly:incorrectInputClass', ... + 'Incorrect input class.') ; + end + if (~isempty(op) && ~isstruct(op) ) + error('findpoly:incorrectInputClass', ... + 'Incorrect input class.') ; + end + + if (isempty(tr)) +%------------------------------ compute aabb's for poly-sets + bb = zeros(numel(ee),4); + xx = cellfun( ... + @min,pp,'uniformoutput',false) ; + xx = [xx{:}]; + bb(:,1) = xx(1:2:end-1); + bb(:,2) = xx(2:2:end-0); + + xx = cellfun( ... + @max,pp,'uniformoutput',false) ; + xx = [xx{:}]; + bb(:,3) = xx(1:2:end-1); + bb(:,4) = xx(2:2:end-0); + +%------------------------------ compute aabb-tree for aabb's + if (isempty(op) || ... + ~isfield(op,'nobj')) + op.nobj = +4; % "aggressive" tree + end + tr = maketree(bb,op); % compute aabb-tree + end + +%------------------------------ compute tree-to-vert mapping + tm = mapvert(tr,pj) ; + +%------------------------------ compute vert-to-poly queries + [ii,px,ix] = ... + queryset(tr,tm,@polykern,pj,pp,ee) ; + +%------------------------------ re-index onto full obj. list + ip = zeros(size(pj,1),2); + ip( :,2) = -1 ; + + if (isempty(ii)), return; end + + ip(ii,:) = px ; + +end + +function [ip,ix] = polykern(pk,ik,pj,pp,ee) +%POLYKERN compute the "point vs. poly" matches within a tile + + Ip = cell(length(ik),1); + Ix = cell(length(ik),1); + + for kk = 1:length(ik) + + in = inpoly2( ... + pj(pk,:),pp{ik(kk)},ee{ik(kk)}) ; + + Ip{kk} = pk(in) ; + Ix{kk} = ... + ik(kk) * ones(length(Ip{kk}),1) ; + + end + + ip = vertcat(Ip{:}) ; + ix = vertcat(Ix{:}) ; + +end + + + diff --git a/tools/aabb_tree/findtria.m b/tools/aabb_tree/findtria.m index 9df6069..176aa98 100644 --- a/tools/aabb_tree/findtria.m +++ b/tools/aabb_tree/findtria.m @@ -42,7 +42,7 @@ % = FINDTRIA(PP,TT,PI,TR,OP). See MAKETREE for additional % information. % -% See also MAKETREE, QUERYSET +% See also MAKETREE, EXCHANGE % Please see the following for additional information: % @@ -52,7 +52,7 @@ % http://hdl.handle.net/2123/13148 % Darren Engwirda : 2014 -- -% Email : de2363@columbia.edu +% Email : d.engwirda@gmail.com % Last updated : 10/03/2018 tp = []; tj = []; tr = []; op = []; diff --git a/tools/aabb_tree/lineline.m b/tools/aabb_tree/lineline.m index e985fe9..c6adbe9 100644 --- a/tools/aabb_tree/lineline.m +++ b/tools/aabb_tree/lineline.m @@ -25,7 +25,7 @@ % passed via [...] = LINELINE(...,TR,OP). See MAKETREE for % additional information. % -% See also MAKETREE, FINDTRIA, FINDBALL, FINDLINE +% See also MAKETREE, EXCHANGE % Please see the following for additional information: % @@ -36,7 +36,7 @@ %----------------------------------------------------------- % Darren Engwirda : 2017 -- -% Email : de2363@columbia.edu +% Email : d.engwirda@gmail.com % Last updated : 10/10/2017 %----------------------------------------------------------- diff --git a/tools/aabb_tree/linenear.m b/tools/aabb_tree/linenear.m index 39f64ad..99b5599 100644 --- a/tools/aabb_tree/linenear.m +++ b/tools/aabb_tree/linenear.m @@ -4,7 +4,7 @@ %----------------------------------------------------------- % Darren Engwirda : 2017 -- -% Email : de2363@columbia.edu +% Email : d.engwirda@gmail.com % Last updated : 10/10/2017 %----------------------------------------------------------- diff --git a/tools/aabb_tree/maketree.m b/tools/aabb_tree/maketree.m index 76e4ee6..5fc8f84 100644 --- a/tools/aabb_tree/maketree.m +++ b/tools/aabb_tree/maketree.m @@ -56,7 +56,7 @@ % http://hdl.handle.net/2123/13148 % Darren Engwirda : 2014 -- -% Email : de2363@columbia.edu +% Email : d.engwirda@gmail.com % Last updated : 08/10/2017 tr.xx = []; tr.ii = []; tr.ll = {}; op = []; diff --git a/tools/aabb_tree/maprect.m b/tools/aabb_tree/maprect.m index c97a278..fe3cdf5 100644 --- a/tools/aabb_tree/maprect.m +++ b/tools/aabb_tree/maprect.m @@ -19,7 +19,7 @@ % See also QUERYSET, MAPVERT, MAKETREE % Darren Engwirda : 2017 -- -% Email : de2363@columbia.edu +% Email : d.engwirda@gmail.com % Last updated : 09/04/2017 %----------------------- call SCANTREE to do the actual work diff --git a/tools/aabb_tree/mapvert.m b/tools/aabb_tree/mapvert.m index 6276893..5d2c85b 100644 --- a/tools/aabb_tree/mapvert.m +++ b/tools/aabb_tree/mapvert.m @@ -19,7 +19,7 @@ % See also QUERYSET, MAPRECT, MAKETREE % Darren Engwirda : 2014 -- -% Email : de2363@columbia.edu +% Email : d.engwirda@gmail.com % Last updated : 06/04/2017 %----------------------- call SCANTREE to do the actual work diff --git a/tools/aabb_tree/queryset.m b/tools/aabb_tree/queryset.m index f7c045e..d5c0ba3 100644 --- a/tools/aabb_tree/queryset.m +++ b/tools/aabb_tree/queryset.m @@ -23,7 +23,7 @@ % See also MAPVERT, MAPRECT, MAKETREE % Darren Engwirda : 2017 -- -% Email : de2363@columbia.edu +% Email : d.engwirda@gmail.com % Last updated : 07/10/2017 qi = []; qp = []; qj = []; diff --git a/tools/aabb_tree/scantree.m b/tools/aabb_tree/scantree.m index 18ecb9f..70b4ca5 100644 --- a/tools/aabb_tree/scantree.m +++ b/tools/aabb_tree/scantree.m @@ -25,7 +25,7 @@ % See also QUERYSET, MAPVERT, MAPRECT, MAKETREE % Darren Engwirda : 2014 -- -% Email : de2363@columbia.edu +% Email : d.engwirda@gmail.com % Last updated : 06/04/2017 tm.ii = [] ; tm.ll = {} ; diff --git a/tools/draw_util/drawedge_2.m b/tools/draw_util/drawedge_2.m index 08b5d49..169b9d1 100644 --- a/tools/draw_util/drawedge_2.m +++ b/tools/draw_util/drawedge_2.m @@ -11,7 +11,7 @@ function drawedge_2(pp,e2,varargin) % Darren Engwirda % github.com/dengwirda/jigsaw-matlab % 13-Aug-2018 -% darren.engwirda@columbia.edu +% d.engwirda@gmail.com %----------------------------------------------------------- % diff --git a/tools/draw_util/drawhexa_8.m b/tools/draw_util/drawhexa_8.m index 80459a0..d5772b1 100644 --- a/tools/draw_util/drawhexa_8.m +++ b/tools/draw_util/drawhexa_8.m @@ -11,7 +11,7 @@ function drawhexa_8(pp,h8,varargin) % Darren Engwirda % github.com/dengwirda/jigsaw-matlab % 07-Aug-2019 -% darren.engwirda@columbia.edu +% d.engwirda@gmail.com %----------------------------------------------------------- % diff --git a/tools/draw_util/drawpyra_5.m b/tools/draw_util/drawpyra_5.m index 8768aa6..fa33b09 100644 --- a/tools/draw_util/drawpyra_5.m +++ b/tools/draw_util/drawpyra_5.m @@ -11,7 +11,7 @@ function drawpyra_5(pp,p5,varargin) % Darren Engwirda % github.com/dengwirda/jigsaw-matlab % 07-Aug-2019 -% darren.engwirda@columbia.edu +% d.engwirda@gmail.com %----------------------------------------------------------- % diff --git a/tools/draw_util/drawquad_4.m b/tools/draw_util/drawquad_4.m index 566001b..cb130c2 100644 --- a/tools/draw_util/drawquad_4.m +++ b/tools/draw_util/drawquad_4.m @@ -11,7 +11,7 @@ function drawquad_4(pp,q4,varargin) % Darren Engwirda % github.com/dengwirda/jigsaw-matlab % 13-Aug-2018 -% darren.engwirda@columbia.edu +% d.engwirda@gmail.com %----------------------------------------------------------- % diff --git a/tools/draw_util/drawtria_3.m b/tools/draw_util/drawtria_3.m index 6cfb86b..7e64aeb 100644 --- a/tools/draw_util/drawtria_3.m +++ b/tools/draw_util/drawtria_3.m @@ -11,7 +11,7 @@ function drawtria_3(pp,t3,varargin) % Darren Engwirda % github.com/dengwirda/jigsaw-matlab % 13-Aug-2018 -% darren.engwirda@columbia.edu +% d.engwirda@gmail.com %----------------------------------------------------------- % diff --git a/tools/draw_util/drawtria_4.m b/tools/draw_util/drawtria_4.m index 80fa8ba..eba689f 100644 --- a/tools/draw_util/drawtria_4.m +++ b/tools/draw_util/drawtria_4.m @@ -11,7 +11,7 @@ function drawtria_4(pp,t4,varargin) % Darren Engwirda % github.com/dengwirda/jigsaw-matlab % 07-Aug-2019 -% darren.engwirda@columbia.edu +% d.engwirda@gmail.com %----------------------------------------------------------- % diff --git a/tools/draw_util/drawwedg_6.m b/tools/draw_util/drawwedg_6.m index b308fdd..effa515 100644 --- a/tools/draw_util/drawwedg_6.m +++ b/tools/draw_util/drawwedg_6.m @@ -11,7 +11,7 @@ function drawwedg_6(pp,w6,varargin) % Darren Engwirda % github.com/dengwirda/jigsaw-matlab % 07-Aug-2019 -% darren.engwirda@columbia.edu +% d.engwirda@gmail.com %----------------------------------------------------------- % diff --git a/tools/drawcost.m b/tools/drawcost.m index d68af85..407e568 100644 --- a/tools/drawcost.m +++ b/tools/drawcost.m @@ -5,7 +5,7 @@ function drawcost(varargin) % Darren Engwirda % github.com/dengwirda/jigsaw-matlab % 01-Aug-2019 -% darren.engwirda@columbia.edu +% d.engwirda@gmail.com %----------------------------------------------------------- % diff --git a/tools/drawmesh.m b/tools/drawmesh.m index b68596e..342b039 100644 --- a/tools/drawmesh.m +++ b/tools/drawmesh.m @@ -5,7 +5,7 @@ function drawmesh(mesh,varargin) % Darren Engwirda % github.com/dengwirda/jigsaw-matlab % 07-Aug-2019 -% darren.engwirda@columbia.edu +% d.engwirda@gmail.com %----------------------------------------------------------- % diff --git a/tools/ellipsoid/R3toS2.m b/tools/ellipsoid/R3toS2.m index 9f12daf..d2069c9 100644 --- a/tools/ellipsoid/R3toS2.m +++ b/tools/ellipsoid/R3toS2.m @@ -5,7 +5,7 @@ % Darren Engwirda % github.com/dengwirda/jigsaw-matlab % 30-Jul-2019 -% darren.engwirda@columbia.edu +% d.engwirda@gmail.com %----------------------------------------------------------- % diff --git a/tools/ellipsoid/S2toR3.m b/tools/ellipsoid/S2toR3.m index 0fb7bdd..eaf19a2 100644 --- a/tools/ellipsoid/S2toR3.m +++ b/tools/ellipsoid/S2toR3.m @@ -5,7 +5,7 @@ % Darren Engwirda % github.com/dengwirda/jigsaw-matlab % 30-Jul-2019 -% darren.engwirda@columbia.edu +% d.engwirda@gmail.com %----------------------------------------------------------- % diff --git a/tools/ellipsoid/cubedsphere.m b/tools/ellipsoid/cubedsphere.m index ee651a6..c50645f 100644 --- a/tools/ellipsoid/cubedsphere.m +++ b/tools/ellipsoid/cubedsphere.m @@ -1,30 +1,134 @@ -function [mesh] = cubedsphere(geom) +function [mesh] = cubedsphere(opts,nlev) +%CUBEDSPHERE an Nth-level cubedsphere mesh of the ellipsoid +%defined by GEOM.RADII. +% +% See also JIGSAW +% - aa = 0.19592; +%----------------------------------------------------------- +% Darren Engwirda +% github.com/dengwirda/jigsaw-matlab +% 03-Sep-2020 +% d.engwirda@gmail.com +%----------------------------------------------------------- +% + if (~isempty(opts) && ~isstruct (opts)) + error('JIGSAW: invalid input types.'); + end + if (~isempty(nlev) && ~isnumeric(nlev)) + error('JIGSAW: invalid input types.'); + end + + if (~isfield(opts, 'geom_file')) + error('JIGSAW: need OPTS.GEOM_FILE.'); + end + if (~isfield(opts, 'mesh_file')) + error('JIGSAW: need OPTS.MESH_FILE.'); + end + + geom = loadmsh(opts.geom_file); + +%-------------------------------- setup cubedsphere geometry + aval = atan(sqrt(2.)/2.) / pi ; + + mesh.mshID = 'euclidean-mesh'; apos = [ - +.25*pi, -aa*pi - +.75*pi, -aa*pi - -.75*pi, -aa*pi - -.25*pi, -aa*pi - +.25*pi, +aa*pi - +.75*pi, +aa*pi - -.75*pi, +aa*pi - -.25*pi, +aa*pi + +.25*pi, -aval*pi + +.75*pi, -aval*pi + -.75*pi, -aval*pi + -.25*pi, -aval*pi + +.25*pi, +aval*pi + +.75*pi, +aval*pi + -.75*pi, +aval*pi + -.25*pi, +aval*pi ] ; mesh.point.coord = ... S2toR3(geom.radii,apos); - mesh.point.coord(:,4) = +0 ; + mesh.point.coord(:,4) = -1 ; % fix "corners" + +%-------------------------------- setup icosahedron topology mesh.quad4.index = [ 1, 2, 3, 4, 0 1, 2, 6, 5, 0 2, 3, 7, 6, 0 3, 4, 8, 7, 0 4, 1, 5, 8, 0 - 5, 6, 7, 8, 0 - ] ; + 5, 6, 7, 8, 0 ] ; + + if (nlev <= +0) return, end ; + + opts.init_file = opts.mesh_file; + + savemsh(opts.init_file,mesh); + + mesh = refine(opts,nlev) ; + +end + +function [mesh] = refine (opts,nlev) + +%---------------------------- call JIGSAW via inc. bisection + + opts.mesh_iter = +0; + opts.optm_div_ = false; + opts.optm_zip_ = false; + + for ilev = nlev : -1 : +0 + + if (isfield(opts,'optm_dual')) + +%---------------------------- create/write current DUAL flag + opts.optm_dual = (ilev == +0) ; + + end + +%---------------------------- call JIGSAW kernel at this lev + mesh = jigsaw(opts) ; + + if (ilev >= +1) + +%---------------------------- create/write current INIT data + [path,name,fext] = ... + fileparts(opts.mesh_file) ; + + if (~isempty(path)) + path = [path, '/']; + end + + opts.init_file = ... + [path,name,'-ITER', fext] ; + + mesh = bisect (mesh); + + mesh = attach (mesh); + + savemsh (opts.init_file,mesh) ; + + end + + end + +end + +function [mesh] = attach(mesh) +%ATTACH attach points to the underlying geometry definition. + + if (inspect(mesh,'quad4')) + + mark = mesh.quad4.index(:,1:4) ; + mesh.point.coord(mark,end) = 2 ; + + end + + if (inspect(mesh,'edge2')) + + mark = mesh.edge2.index(:,1:2) ; + mesh.point.coord(mark,end) = 1 ; + + end end diff --git a/tools/ellipsoid/icosahedron.m b/tools/ellipsoid/icosahedron.m index 046cf42..11bde9d 100644 --- a/tools/ellipsoid/icosahedron.m +++ b/tools/ellipsoid/icosahedron.m @@ -1,6 +1,154 @@ -function [mesh] = icosahedron(geom) +function [mesh] = icosahedron(opts,nlev) +%ICOSAHEDRON an Nth-level icosahedral mesh of the ellipsoid +%defined by GEOM.RADII. +% +% See also JIGSAW +% +%----------------------------------------------------------- +% Darren Engwirda +% github.com/dengwirda/jigsaw-matlab +% 09-Jul-2020 +% d.engwirda@gmail.com +%----------------------------------------------------------- +% + + if (~isempty(opts) && ~isstruct (opts)) + error('JIGSAW: invalid input types.'); + end + if (~isempty(nlev) && ~isnumeric(nlev)) + error('JIGSAW: invalid input types.'); + end + + if (~isfield(opts, 'geom_file')) + error('JIGSAW: need OPTS.GEOM_FILE.'); + end + if (~isfield(opts, 'mesh_file')) + error('JIGSAW: need OPTS.MESH_FILE.'); + end + + geom = loadmsh(opts.geom_file); + +%-------------------------------- setup icosahedron geometry + la = atan(+1.0 / 2.0); + lo = +1.0 / 5.0 * pi ; + + mesh.mshID = 'euclidean-mesh'; + apos = [ + +.00*pi, -.50*pi + +.00*pi, +.50*pi + +0.0*lo, +1.0*la + +1.0*lo, -1.0*la + +2.0*lo, +1.0*la + +3.0*lo, -1.0*la + +4.0*lo, +1.0*la + +5.0*lo, -1.0*la + +6.0*lo, +1.0*la + +7.0*lo, -1.0*la + +8.0*lo, +1.0*la + +9.0*lo, -1.0*la + ] ; + + mesh.point.coord = ... + S2toR3(geom.radii,apos); + + mesh.point.coord(:,4) = -1 ; % fix "corners" + +%-------------------------------- setup icosahedron topology + mesh.tria3.index = [ + 1, 4, 6, 0 + 1, 6, 8, 0 + 1, 8, 10, 0 + 1, 10, 12, 0 + 1, 12, 4, 0 + 2, 3, 5, 0 + 2, 5, 7, 0 + 2, 7, 9, 0 + 2, 9, 11, 0 + 2, 11, 3, 0 + 4, 3, 5, 0 + 6, 5, 7, 0 + 8, 7, 9, 0 + 10, 9, 11, 0 + 12, 11, 3, 0 + 5, 4, 6, 0 + 7, 6, 8, 0 + 9, 8, 10, 0 + 11, 10, 12, 0 + 3, 12, 4, 0 ] ; + + if (nlev <= +0) return, end ; + + opts.init_file = opts.mesh_file; + + savemsh(opts.init_file,mesh); + + mesh = refine(opts,nlev) ; + end +function [mesh] = refine (opts,nlev) + +%---------------------------- call JIGSAW via inc. bisection + + opts.mesh_iter = +0; + opts.optm_div_ = false; + opts.optm_zip_ = false; + + for ilev = nlev : -1 : +0 + + if (isfield(opts,'optm_dual')) + +%---------------------------- create/write current DUAL flag + opts.optm_dual = (ilev == +0) ; + + end + +%---------------------------- call JIGSAW kernel at this lev + mesh = jigsaw(opts) ; + + if (ilev >= +1) + +%---------------------------- create/write current INIT data + [path,name,fext] = ... + fileparts(opts.mesh_file) ; + + if (~isempty(path)) + path = [path, '/']; + end + + opts.init_file = ... + [path,name,'-ITER', fext] ; + + mesh = bisect (mesh); + + mesh = attach (mesh); + + savemsh (opts.init_file,mesh) ; + + end + + end + +end + +function [mesh] = attach(mesh) +%ATTACH attach points to the underlying geometry definition. + + if (inspect(mesh,'tria3')) + + mark = mesh.tria3.index(:,1:3) ; + mesh.point.coord(mark,end) = 2 ; + + end + + if (inspect(mesh,'edge2')) + + mark = mesh.edge2.index(:,1:2) ; + mesh.point.coord(mark,end) = 1 ; + + end + +end diff --git a/tools/geom_util/getiso2.m b/tools/geom_util/getiso2.m index f0fb609..4b7bb9a 100644 --- a/tools/geom_util/getiso2.m +++ b/tools/geom_util/getiso2.m @@ -12,7 +12,7 @@ %----------------------------------------------------------- % Darren Engwirda : 2018 -- -% Email : de2363@columbia.edu +% Email : d.engwirda@gmail.com % Last updated : 25/03/2018 %----------------------------------------------------------- diff --git a/tools/geom_util/getnan2.m b/tools/geom_util/getnan2.m index 554649d..cfd6ea2 100644 --- a/tools/geom_util/getnan2.m +++ b/tools/geom_util/getnan2.m @@ -17,7 +17,7 @@ %----------------------------------------------------------- % Darren Engwirda : 2017 -- -% Email : de2363@columbia.edu +% Email : d.engwirda@gmail.com % Last updated : 25/03/2018 %----------------------------------------------------------- diff --git a/tools/geom_util/stereo3.m b/tools/geom_util/stereo3.m index 12cb20d..fdd224b 100644 --- a/tools/geom_util/stereo3.m +++ b/tools/geom_util/stereo3.m @@ -24,7 +24,7 @@ %----------------------------------------------------------- % Darren Engwirda : 2017 -- -% Email : de2363@columbia.edu +% Email : d.engwirda@gmail.com % Last updated : 03/05/2018 %----------------------------------------------------------- diff --git a/tools/math_util/inv_2x2.m b/tools/math_util/inv_2x2.m index 2b99d77..293ac56 100644 --- a/tools/math_util/inv_2x2.m +++ b/tools/math_util/inv_2x2.m @@ -12,7 +12,7 @@ % See also INV_3X3 % Darren Engwirda : 2018 -- -% Email : de2363@columbia.edu +% Email : d.engwirda@gmail.com % Last updated : 03/05/2018 %---------------------------------------------- basic checks diff --git a/tools/math_util/inv_3x3.m b/tools/math_util/inv_3x3.m index b6e1ed6..742c2e9 100644 --- a/tools/math_util/inv_3x3.m +++ b/tools/math_util/inv_3x3.m @@ -12,7 +12,7 @@ % See also INV_2X2 % Darren Engwirda : 2018 -- -% Email : de2363@columbia.edu +% Email : d.engwirda@gmail.com % Last updated : 03/05/2018 %---------------------------------------------- basic checks diff --git a/tools/mesh_util/idxtri2.m b/tools/mesh_util/idxtri2.m index e22f45e..66025a5 100644 --- a/tools/mesh_util/idxtri2.m +++ b/tools/mesh_util/idxtri2.m @@ -12,7 +12,7 @@ % See also MAKETREE % Darren Engwirda : 2017 -- -% Email : de2363@columbia.edu +% Email : d.engwirda@gmail.com % Last updated : 10/07/2018 %---------------------------------------------- basic checks diff --git a/tools/mesh_util/idxtri3.m b/tools/mesh_util/idxtri3.m index 563e443..745b310 100644 --- a/tools/mesh_util/idxtri3.m +++ b/tools/mesh_util/idxtri3.m @@ -12,7 +12,7 @@ % See also MAKETREE % Darren Engwirda : 2017 -- -% Email : de2363@columbia.edu +% Email : d.engwirda@gmail.com % Last updated : 10/07/2018 %---------------------------------------------- basic checks diff --git a/tools/mesh_util/trifun2.m b/tools/mesh_util/trifun2.m index 8a16386..79edf4a 100644 --- a/tools/mesh_util/trifun2.m +++ b/tools/mesh_util/trifun2.m @@ -17,7 +17,7 @@ % See also IDXTRI2 % Darren Engwirda : 2017 -- -% Email : de2363@columbia.edu +% Email : d.engwirda@gmail.com % Last updated : 25/07/2018 %---------------------------------------------- basic checks diff --git a/tools/mesh_util/trifun3.m b/tools/mesh_util/trifun3.m index a1575b7..f94888f 100644 --- a/tools/mesh_util/trifun3.m +++ b/tools/mesh_util/trifun3.m @@ -18,7 +18,7 @@ % See also IDXTRI3 % Darren Engwirda : 2017 -- -% Email : de2363@columbia.edu +% Email : d.engwirda@gmail.com % Last updated : 25/07/2018 %---------------------------------------------- basic checks diff --git a/tools/meshcost.m b/tools/meshcost.m index e109e3d..c5de27e 100644 --- a/tools/meshcost.m +++ b/tools/meshcost.m @@ -5,7 +5,7 @@ % Darren Engwirda % github.com/dengwirda/jigsaw-matlab % 01-Aug-2019 -% darren.engwirda@columbia.edu +% d.engwirda@gmail.com %----------------------------------------------------------- % diff --git a/tools/orthoball/pwrbal1.m b/tools/orthoball/pwrbal1.m index 8b8f914..45b14b6 100644 --- a/tools/orthoball/pwrbal1.m +++ b/tools/orthoball/pwrbal1.m @@ -6,7 +6,7 @@ % [XC,YC,RC.^2]. PW is a vector of vertex weights. % Darren Engwirda : 2017 -- -% Email : de2363@columbia.edu +% Email : d.engwirda@gmail.com % Last updated : 02/05/2018 %---------------------------------------------- basic checks diff --git a/tools/orthoball/pwrbal2.m b/tools/orthoball/pwrbal2.m index fd75cbd..26411b5 100644 --- a/tools/orthoball/pwrbal2.m +++ b/tools/orthoball/pwrbal2.m @@ -6,7 +6,7 @@ % [XC,YC,RC.^2]. PW is a vector of vertex weights. % Darren Engwirda : 2017 -- -% Email : de2363@columbia.edu +% Email : d.engwirda@gmail.com % Last updated : 02/05/2018 %---------------------------------------------- basic checks diff --git a/tools/orthoball/pwrbal3.m b/tools/orthoball/pwrbal3.m index 816d1e8..74ad7cf 100644 --- a/tools/orthoball/pwrbal3.m +++ b/tools/orthoball/pwrbal3.m @@ -6,7 +6,7 @@ % [XC,YC,ZC,RC.^2]. PW is a vector of vertex weights. % Darren Engwirda : 2017 -- -% Email : de2363@columbia.edu +% Email : d.engwirda@gmail.com % Last updated : 20/06/2018 %---------------------------------------------- basic checks diff --git a/tools/orthoball/quadbal2.m b/tools/orthoball/quadbal2.m new file mode 100644 index 0000000..c13a551 --- /dev/null +++ b/tools/orthoball/quadbal2.m @@ -0,0 +1,190 @@ +function [bb] = quadbal2(pp,pw,qq) +%QUADBAL... + +% Darren Engwirda : 2017 -- +% Email : d.engwirda@gmail.com +% Last updated : 02/05/2018 + + +% blah, checks + + + b1 = tribal2(pp,qq(:,[1,2,3])); + b2 = tribal2(pp,qq(:,[1,3,4])); + b3 = tribal2(pp,qq(:,[1,2,4])); + b4 = tribal2(pp,qq(:,[2,3,4])); + + bb = .25*(b1+b2+b3+b4); + return + + switch (size(pp,2)) + case +2 + %-------------------------------------------- alloc work + AA = zeros(2,2,size(tt,1)) ; + Rv = zeros(2,1,size(tt,1)) ; + bb = zeros(size(tt,1),3,1) ; + + %-------------------------------------------- lhs matrix + ab = pp(tt(:,2),:)-pp(tt(:,1),:); + ac = pp(tt(:,3),:)-pp(tt(:,1),:); + + AA(1,1,:) = ab(:,1) * +2.0 ; + AA(1,2,:) = ab(:,2) * +2.0 ; + AA(2,1,:) = ac(:,1) * +2.0 ; + AA(2,2,:) = ac(:,2) * +2.0 ; + + %-------------------------------------------- rhs vector + Rv(1,1,:) = sum(ab.*ab,2) ... + - ( pw(tt(:,2)) - pw(tt(:,1)) ) ; + + Rv(2,1,:) = sum(ac.*ac,2) ... + - ( pw(tt(:,3)) - pw(tt(:,1)) ) ; + + %-------------------------------------------- solve sys. + [II,dd] = inv_2x2(AA) ; + + bb(:,1) = ( ... + II(1,1,:).*Rv(1,1,:) + ... + II(1,2,:).*Rv(2,1,:) ) ... + ./ dd ; + + bb(:,2) = ( ... + II(2,1,:).*Rv(1,1,:) + ... + II(2,2,:).*Rv(2,1,:) ) ... + ./ dd ; + + bb(:,1:2) = ... + pp(tt(:,1),:) + bb(:,1:2) ; + + %-------------------------------------------- mean radii + r1 = sum( ... + (bb(:,1:2)-pp(tt(:,1),:)).^2,2) ; + r2 = sum( ... + (bb(:,1:2)-pp(tt(:,2),:)).^2,2) ; + r3 = sum( ... + (bb(:,1:2)-pp(tt(:,3),:)).^2,2) ; + + r1 = r1 - pw(tt(:,1)); + r2 = r2 - pw(tt(:,2)); + r3 = r3 - pw(tt(:,3)); + + bb(:,3) = ( r1+r2+r3 ) / +3.0 ; + + case +3 + %-------------------------------------------- alloc work + AA = zeros(3,3,size(qq,1)) ; + Rv = zeros(3,1,size(qq,1)) ; + bb = zeros(size(qq,1),4,1) ; + + %-------------------------------------------- lhs matrix + ab = pp(qq(:,2),:)-pp(qq(:,1),:); + ac = pp(qq(:,3),:)-pp(qq(:,1),:); + ad = pp(qq(:,4),:)-pp(qq(:,1),:); + + bc = pp(qq(:,3),:)-pp(qq(:,2),:); + bd = pp(qq(:,4),:)-pp(qq(:,2),:); + + n1 = cross(ab,ac) ; + n2 = cross(ac,ad) ; + n3 = cross(ab,bd) ; + n4 = cross(bd,bc) ; + + absq = sum(ab.*ab,2); + acsq = sum(ac.*ac,2); + adsq = sum(ad.*ad,2); + + for ii = 1:size(qq,1) + + As(1,1) = ab(ii,1) * +2.0 ; + As(1,2) = ab(ii,2) * +2.0 ; + As(1,3) = ab(ii,3) * +2.0 ; + As(2,1) = ac(ii,1) * +2.0 ; + As(2,2) = ac(ii,2) * +2.0 ; + As(2,3) = ac(ii,3) * +2.0 ; + As(3,1) = ad(ii,1) * +2.0 ; + As(3,2) = ad(ii,2) * +2.0 ; + As(3,3) = ad(ii,3) * +2.0 ; + + As(4,1) = n1(ii,1) * +1.0 ; + As(4,2) = n1(ii,2) * +1.0 ; + As(4,3) = n1(ii,3) * +1.0 ; + As(5,1) = n2(ii,1) * +1.0 ; + As(5,2) = n2(ii,2) * +1.0 ; + As(5,3) = n2(ii,3) * +1.0 ; + + As(6,1) = n3(ii,1) * +1.0 ; + As(6,2) = n3(ii,2) * +1.0 ; + As(6,3) = n3(ii,3) * +1.0 ; + As(7,1) = n4(ii,1) * +1.0 ; + As(7,2) = n4(ii,2) * +1.0 ; + As(7,3) = n4(ii,3) * +1.0 ; + + %-------------------------------------------- rhs vector + Rs(1,1) = absq(ii,:) ... + - ( pw(qq(ii,2)) - pw(qq(ii,1)) ) ; + + Rs(2,1) = acsq(ii,:) ... + - ( pw(qq(ii,3)) - pw(qq(ii,1)) ) ; + + Rs(3,1) = adsq(ii,:) ... + - ( pw(qq(ii,4)) - pw(qq(ii,1)) ) ; + + Rs(4:7,1) = 0.0 ; + + AA(1:3,:,ii) = As' * As ; + Rv(1:3,1,ii) = As' * Rs ; + + end + + %-------------------------------------------- solve sys. + [II,dd] = inv_3x3(AA) ; + + bb(:,1) = ( ... + II(1,1,:).*Rv(1,1,:) + ... + II(1,2,:).*Rv(2,1,:) + ... + II(1,3,:).*Rv(3,1,:) ) ... + ./ dd ; + + bb(:,2) = ( ... + II(2,1,:).*Rv(1,1,:) + ... + II(2,2,:).*Rv(2,1,:) + ... + II(2,3,:).*Rv(3,1,:) ) ... + ./ dd ; + + bb(:,3) = ( ... + II(3,1,:).*Rv(1,1,:) + ... + II(3,2,:).*Rv(2,1,:) + ... + II(3,3,:).*Rv(3,1,:) ) ... + ./ dd ; + + bb(:,1:3) = ... + pp(qq(:,1),:) + bb(:,1:3) ; + + %-------------------------------------------- mean radii + r1 = sum( ... + (bb(:,1:3)-pp(qq(:,1),:)).^2,2) ; + r2 = sum( ... + (bb(:,1:3)-pp(qq(:,2),:)).^2,2) ; + r3 = sum( ... + (bb(:,1:3)-pp(qq(:,3),:)).^2,2) ; + r4 = sum( ... + (bb(:,1:3)-pp(qq(:,4),:)).^2,2) ; + + r1 = r1 - pw(qq(:,1)); + r2 = r2 - pw(qq(:,2)); + r3 = r3 - pw(qq(:,3)); + r4 = r4 - pw(qq(:,4)); + + bb(:,4) = ( r1+r2+r3+r4 ) / +4. ; + + otherwise + + error('pwrbal2:unsupportedDimension' , ... + 'Dimension not supported.') ; + + end + +end + + + diff --git a/tools/orthoball/quadbal2.m~ b/tools/orthoball/quadbal2.m~ new file mode 100644 index 0000000..26cf818 --- /dev/null +++ b/tools/orthoball/quadbal2.m~ @@ -0,0 +1,190 @@ +function [bb] = quadbal2(pp,pw,qq) +%QUADBAL... + +% Darren Engwirda : 2017 -- +% Email : de2363@columbia.edu +% Last updated : 02/05/2018 + + +% blah, checks + + + b1 = tribal2(pp,qq(:,[1,2,3])); + b2 = tribal2(pp,qq(:,[1,3,4])); + b3 = tribal2(pp,qq(:,[1,2,4])); + b4 = tribal2(pp,qq(:,[2,3,4])); + + bb = .25*(b1+b2+b3+b4); + + + switch (size(pp,2)) + case +2 + %-------------------------------------------- alloc work + AA = zeros(2,2,size(tt,1)) ; + Rv = zeros(2,1,size(tt,1)) ; + bb = zeros(size(tt,1),3,1) ; + + %-------------------------------------------- lhs matrix + ab = pp(tt(:,2),:)-pp(tt(:,1),:); + ac = pp(tt(:,3),:)-pp(tt(:,1),:); + + AA(1,1,:) = ab(:,1) * +2.0 ; + AA(1,2,:) = ab(:,2) * +2.0 ; + AA(2,1,:) = ac(:,1) * +2.0 ; + AA(2,2,:) = ac(:,2) * +2.0 ; + + %-------------------------------------------- rhs vector + Rv(1,1,:) = sum(ab.*ab,2) ... + - ( pw(tt(:,2)) - pw(tt(:,1)) ) ; + + Rv(2,1,:) = sum(ac.*ac,2) ... + - ( pw(tt(:,3)) - pw(tt(:,1)) ) ; + + %-------------------------------------------- solve sys. + [II,dd] = inv_2x2(AA) ; + + bb(:,1) = ( ... + II(1,1,:).*Rv(1,1,:) + ... + II(1,2,:).*Rv(2,1,:) ) ... + ./ dd ; + + bb(:,2) = ( ... + II(2,1,:).*Rv(1,1,:) + ... + II(2,2,:).*Rv(2,1,:) ) ... + ./ dd ; + + bb(:,1:2) = ... + pp(tt(:,1),:) + bb(:,1:2) ; + + %-------------------------------------------- mean radii + r1 = sum( ... + (bb(:,1:2)-pp(tt(:,1),:)).^2,2) ; + r2 = sum( ... + (bb(:,1:2)-pp(tt(:,2),:)).^2,2) ; + r3 = sum( ... + (bb(:,1:2)-pp(tt(:,3),:)).^2,2) ; + + r1 = r1 - pw(tt(:,1)); + r2 = r2 - pw(tt(:,2)); + r3 = r3 - pw(tt(:,3)); + + bb(:,3) = ( r1+r2+r3 ) / +3.0 ; + + case +3 + %-------------------------------------------- alloc work + AA = zeros(3,3,size(qq,1)) ; + Rv = zeros(3,1,size(qq,1)) ; + bb = zeros(size(qq,1),4,1) ; + + %-------------------------------------------- lhs matrix + ab = pp(qq(:,2),:)-pp(qq(:,1),:); + ac = pp(qq(:,3),:)-pp(qq(:,1),:); + ad = pp(qq(:,4),:)-pp(qq(:,1),:); + + bc = pp(qq(:,3),:)-pp(qq(:,2),:); + bd = pp(qq(:,4),:)-pp(qq(:,2),:); + + n1 = cross(ab,ac) ; + n2 = cross(ac,ad) ; + n3 = cross(ab,bd) ; + n4 = cross(bd,bc) ; + + absq = sum(ab.*ab,2); + acsq = sum(ac.*ac,2); + adsq = sum(ad.*ad,2); + + for ii = 1:size(qq,1) + + As(1,1) = ab(ii,1) * +2.0 ; + As(1,2) = ab(ii,2) * +2.0 ; + As(1,3) = ab(ii,3) * +2.0 ; + As(2,1) = ac(ii,1) * +2.0 ; + As(2,2) = ac(ii,2) * +2.0 ; + As(2,3) = ac(ii,3) * +2.0 ; + As(3,1) = ad(ii,1) * +2.0 ; + As(3,2) = ad(ii,2) * +2.0 ; + As(3,3) = ad(ii,3) * +2.0 ; + + As(4,1) = n1(ii,1) * +1.0 ; + As(4,2) = n1(ii,2) * +1.0 ; + As(4,3) = n1(ii,3) * +1.0 ; + As(5,1) = n2(ii,1) * +1.0 ; + As(5,2) = n2(ii,2) * +1.0 ; + As(5,3) = n2(ii,3) * +1.0 ; + + As(6,1) = n3(ii,1) * +1.0 ; + As(6,2) = n3(ii,2) * +1.0 ; + As(6,3) = n3(ii,3) * +1.0 ; + As(7,1) = n4(ii,1) * +1.0 ; + As(7,2) = n4(ii,2) * +1.0 ; + As(7,3) = n4(ii,3) * +1.0 ; + + %-------------------------------------------- rhs vector + Rs(1,1) = absq(ii,:) ... + - ( pw(qq(ii,2)) - pw(qq(ii,1)) ) ; + + Rs(2,1) = acsq(ii,:) ... + - ( pw(qq(ii,3)) - pw(qq(ii,1)) ) ; + + Rs(3,1) = adsq(ii,:) ... + - ( pw(qq(ii,4)) - pw(qq(ii,1)) ) ; + + Rs(4:7,1) = 0.0 ; + + AA(1:3,:,ii) = As' * As ; + Rv(1:3,1,ii) = As' * Rs ; + + end + + %-------------------------------------------- solve sys. + [II,dd] = inv_3x3(AA) ; + + bb(:,1) = ( ... + II(1,1,:).*Rv(1,1,:) + ... + II(1,2,:).*Rv(2,1,:) + ... + II(1,3,:).*Rv(3,1,:) ) ... + ./ dd ; + + bb(:,2) = ( ... + II(2,1,:).*Rv(1,1,:) + ... + II(2,2,:).*Rv(2,1,:) + ... + II(2,3,:).*Rv(3,1,:) ) ... + ./ dd ; + + bb(:,3) = ( ... + II(3,1,:).*Rv(1,1,:) + ... + II(3,2,:).*Rv(2,1,:) + ... + II(3,3,:).*Rv(3,1,:) ) ... + ./ dd ; + + bb(:,1:3) = ... + pp(qq(:,1),:) + bb(:,1:3) ; + + %-------------------------------------------- mean radii + r1 = sum( ... + (bb(:,1:3)-pp(qq(:,1),:)).^2,2) ; + r2 = sum( ... + (bb(:,1:3)-pp(qq(:,2),:)).^2,2) ; + r3 = sum( ... + (bb(:,1:3)-pp(qq(:,3),:)).^2,2) ; + r4 = sum( ... + (bb(:,1:3)-pp(qq(:,4),:)).^2,2) ; + + r1 = r1 - pw(qq(:,1)); + r2 = r2 - pw(qq(:,2)); + r3 = r3 - pw(qq(:,3)); + r4 = r4 - pw(qq(:,4)); + + bb(:,4) = ( r1+r2+r3+r4 ) / +4. ; + + otherwise + + error('pwrbal2:unsupportedDimension' , ... + 'Dimension not supported.') ; + + end + +end + + + diff --git a/tools/orthoball/tribal1.m b/tools/orthoball/tribal1.m index a11ebc0..5b05146 100644 --- a/tools/orthoball/tribal1.m +++ b/tools/orthoball/tribal1.m @@ -6,7 +6,7 @@ % BB = [XC,YC,RC.^2]. % Darren Engwirda : 2017 -- -% Email : de2363@columbia.edu +% Email : d.engwirda@gmail.com % Last updated : 02/05/2018 bb = pwrbal1(pp,zeros(size(pp,1),1),ee) ; diff --git a/tools/orthoball/tribal2.m b/tools/orthoball/tribal2.m index 43dcc34..3353734 100644 --- a/tools/orthoball/tribal2.m +++ b/tools/orthoball/tribal2.m @@ -6,7 +6,7 @@ % [XC,YC,RC.^2]. % Darren Engwirda : 2017 -- -% Email : de2363@columbia.edu +% Email : d.engwirda@gmail.com % Last updated : 02/05/2018 bb = pwrbal2(pp,zeros(size(pp,1),1),tt) ; diff --git a/tools/orthoball/tribal3.m b/tools/orthoball/tribal3.m index bc78ec1..7425da9 100644 --- a/tools/orthoball/tribal3.m +++ b/tools/orthoball/tribal3.m @@ -6,7 +6,7 @@ % [XC,YC,ZC,RC.^2]. % Darren Engwirda : 2017 -- -% Email : de2363@columbia.edu +% Email : d.engwirda@gmail.com % Last updated : 20/06/2018 bb = pwrbal3(pp,zeros(size(pp,1),1),tt) ; diff --git a/tools/poly_sign/README.md b/tools/poly_sign/README.md index 1b14e00..fe95592 100644 --- a/tools/poly_sign/README.md +++ b/tools/poly_sign/README.md @@ -4,6 +4,10 @@ A fast 'point-in-polygon' routine for `MATLAB `INPOLY` returns the "inside/outside" status for a set of vertices `VERT` and a general polygon (`PSLG`) embedded in the two-dimensional plane. General non-convex and multiply-connected polygonal regions can be handled. `INPOLY` is intended as a (very) fast replacement for `MATLAB`'s default `INPOLYGON` routine. +

+ +

+ `INPOLY` is based on a 'crossing-number' test, counting the number of times a line extending from each point past the right-most region of the polygon intersects with the polygonal boundary. Points with odd counts are 'inside'. A simple implementation requires that each edge intersection be checked for each point, leading to (slow) `O(N*M)` overall complexity. This implementation seeks to improve these bounds. Query points are sorted by `y-value` and candidate intersection sets are determined via binary-search. Given a configuration with `N` test points, `M` edges and an average point-edge 'overlap' of `H`, the overall complexity scales like `O(M*H + M*LOG(N) + N*LOG(N))`, where `O(N*LOG(N))` operations are required for the initial sorting, `O(M*LOG(N))` operations are required for the set of binary-searches, and `O(M*H)` operations are required for the actual intersection tests. `H` is typically small on average, such that `H << N`. Overall, this leads to fast `O((N+M)*LOG(N))` complexity for average cases. diff --git a/tools/poly_sign/inpoly2.m b/tools/poly_sign/inpoly2.m index 5c2f6de..7bfc98b 100644 --- a/tools/poly_sign/inpoly2.m +++ b/tools/poly_sign/inpoly2.m @@ -1,168 +1,183 @@ -function [stat,bnds] = inpoly2(varargin) -%INPOLY2 compute "points-in-polygon" queries. -% [STAT] = INPOLY2(VERT,NODE,EDGE) returns the "inside/ou- -% tside" status for a set of vertices VERT and a polygon -% {NODE,EDGE} embedded in a two-dimensional plane. General -% non-convex and multiply-connected polygonal regions can -% be handled. VERT is an N-by-2 array of XY coordinates to -% be tested. STAT is an associated N-by-1 logical array, -% with STAT(II) = TRUE if VERT(II,:) is an interior point. -% The polygonal region is defined as a piecewise-straight- -% line-graph, where NODE is an M-by-2 array of polygon ve- -% rtices and EDGE is a P-by-2 array of edge indexing. Each -% row in EDGE represents an edge of the polygon, such that -% NODE(EDGE(KK,1),:) and NODE(EDGE(KK,2),:) are the coord- -% inates of the endpoints of the KK-TH edge. If the argum- -% ent EDGE is omitted it assumed that the vertices in NODE -% are connected in ascending order. -% -% [STAT,BNDS] = INPOLY2(..., FTOL) also returns an N-by-1 -% logical array BNDS, with BNDS(II) = TRUE if VERT(II,:) -% lies "on" a boundary segment, where FTOL is a floating- -% point tolerance for boundary comparisons. By default, -% FTOL = EPS ^ 0.85. -% -% See also INPOLYGON - -% This algorithm is based on a "crossing-number" test, co- -% unting the number of times a line extending from each -% point past the right-most region of the polygon interse- -% cts with the polygonal boundary. Points with odd counts -% are "inside". A simple implementation requires that each -% edge intersection be checked for each point, leading to -% O(N*M) complexity... -% -% This implementation seeks to improve these bounds: -% -% * Sorting the query points by y-value and determining can- -% didate edge intersection sets via binary-search. Given a -% configuration with N test points, M edges and an average -% point-edge "overlap" of H, the overall complexity scales -% like O(M*H + M*LOG(N) + N*LOG(N)), where O(N*LOG(N)) -% operations are required for sorting, O(M*LOG(N)) operat- -% ions required for the set of binary-searches, and O(M*H) -% operations required for the intersection tests, where H -% is typically small on average, such that H << N. -% -% * Carefully checking points against the bounding-box asso- -% ciated with each polygon edge. This minimises the number -% of calls to the (relatively) expensive edge intersection -% test. - -% Darren Engwirda : 2017 -- -% Email : de2363@columbia.edu -% Last updated : 27/10/2018 - -%---------------------------------------------- extract args - node = []; edge = []; vert = []; - - fTOL = eps ^ .85; - - if (nargin>=+1), vert = varargin{1}; end - if (nargin>=+2), node = varargin{2}; end - if (nargin>=+3), edge = varargin{3}; end - if (nargin>=+4), fTOL = varargin{4}; end - -%---------------------------------------------- default args - nnod = size(node,1) ; - nvrt = size(vert,1) ; - - if (isempty(edge)) - edge = [(1:nnod-1)',(2:nnod)'; nnod,1]; - end - -%---------------------------------------------- basic checks - if ( ~isnumeric(node) || ... - ~isnumeric(edge) || ... - ~isnumeric(vert) || ... - ~isnumeric(fTOL) ) - error('inpoly2:incorrectInputClass' , ... - 'Incorrect input class.') ; - end - -%---------------------------------------------- basic checks - if (ndims(node) ~= +2 || ... - ndims(edge) ~= +2 || ... - ndims(vert) ~= +2 || ... - numel(fTOL) ~= +1 ) - error('inpoly2:incorrectDimensions' , ... - 'Incorrect input dimensions.'); - end - if (size(node,2)~= +2 || ... - size(edge,2)~= +2 || ... - size(vert,2)~= +2 ) - error('inpoly2:incorrectDimensions' , ... - 'Incorrect input dimensions.'); - end - -%---------------------------------------------- basic checks - if (min([edge(:)]) < +1 || ... - max([edge(:)]) > nnod) - error('inpoly2:invalidInputs', ... - 'Invalid EDGE input array.') ; - end - -%-------------- flip to ensure the y-axis is the "long" axis - vmin = min(vert,[],1); - vmax = max(vert,[],1); - ddxy = vmax - vmin ; - - lbar = sum(ddxy) / 2.; - - if (ddxy(1) > ddxy(2)) - vert = vert(:,[2,1]) ; - node = node(:,[2,1]) ; - end - -%----------------------------------- sort points via y-value - swap = ... - node(edge(:,2),2) ... - < node(edge(:,1),2) ; - - edge(swap,[1,2]) = ... - edge(swap,[2,1]) ; - - [~,ivec] = ... - sort(vert(:,+2)) ; - vert = vert (ivec,:) ; - - if (exist( ... - 'OCTAVE_VERSION','builtin') > +0) - - if (exist('inpoly2_oct','file') == +3) - - %-- delegate to the compiled version of the code if it's - %-- available - - [stat,bnds] = ... - inpoly2_oct( ... - vert,node,edge,fTOL,lbar) ; - - else - - %-- otherwise, just call the native m-code version - - [stat,bnds] = ... - inpoly2_mat( ... - vert,node,edge,fTOL,lbar) ; - - end - - else - - %-- MATLAB's JIT is generally smart enough these days to - %-- run this efficiently - - [stat,bnds] = ... - inpoly2_mat( ... - vert,node,edge,fTOL,lbar) ; - - end - - stat(ivec) = stat ; - bnds(ivec) = bnds ; - -end - - - +function [STAT,BNDS] = inpoly2(varargin) +%INPOLY2 compute "points-in-polygon" queries. +% [STAT] = INPOLY2(VERT,NODE,EDGE) returns the "inside/ou- +% tside" status for a set of vertices VERT and a polygon +% {NODE,EDGE} embedded in a two-dimensional plane. General +% non-convex and multiply-connected polygonal regions can +% be handled. VERT is an N-by-2 array of XY coordinates to +% be tested. STAT is an associated N-by-1 logical array, +% with STAT(II) = TRUE if VERT(II,:) is an interior point. +% The polygonal region is defined as a piecewise-straight- +% line-graph, where NODE is an M-by-2 array of polygon ve- +% rtices and EDGE is a P-by-2 array of edge indexing. Each +% row in EDGE represents an edge of the polygon, such that +% NODE(EDGE(KK,1),:) and NODE(EDGE(KK,2),:) are the coord- +% inates of the endpoints of the KK-TH edge. If the argum- +% ent EDGE is omitted it assumed that the vertices in NODE +% are connected in ascending order. +% +% [STAT,BNDS] = INPOLY2(..., FTOL) also returns an N-by-1 +% logical array BNDS, with BNDS(II) = TRUE if VERT(II,:) +% lies "on" a boundary segment, where FTOL is a floating- +% point tolerance for boundary comparisons. By default, +% FTOL = EPS ^ 0.85. +% +% See also INPOLYGON + +% This algorithm is based on a "crossing-number" test, co- +% unting the number of times a line extending from each +% point past the right-most region of the polygon interse- +% cts with the polygonal boundary. Points with odd counts +% are "inside". A simple implementation requires that each +% edge intersection be checked for each point, leading to +% O(N*M) complexity... +% +% This implementation seeks to improve these bounds: +% +% * Sorting the query points by y-value and determining can- +% didate edge intersection sets via binary-search. Given a +% configuration with N test points, M edges and an average +% point-edge "overlap" of H, the overall complexity scales +% like O(M*H + M*LOG(N) + N*LOG(N)), where O(N*LOG(N)) +% operations are required for sorting, O(M*LOG(N)) operat- +% ions required for the set of binary-searches, and O(M*H) +% operations required for the intersection tests, where H +% is typically small on average, such that H << N. +% +% * Carefully checking points against the bounding-box asso- +% ciated with each polygon edge. This minimises the number +% of calls to the (relatively) expensive edge intersection +% test. + +% Darren Engwirda : 2017 -- +% Email : d.engwirda@gmail.com +% Last updated : 31/03/2020 + +%---------------------------------------------- extract args + node = []; edge = []; vert = []; + + fTOL = eps ^ .85; + + if (nargin>=+1), vert = varargin{1}; end + if (nargin>=+2), node = varargin{2}; end + if (nargin>=+3), edge = varargin{3}; end + if (nargin>=+4), fTOL = varargin{4}; end + +%---------------------------------------------- default args + nnod = size(node,1) ; + nvrt = size(vert,1) ; + + if (isempty(edge)) + edge = [(1:nnod-1)',(2:nnod)'; nnod,1]; + end + +%---------------------------------------------- basic checks + if ( ~isnumeric(node) || ... + ~isnumeric(edge) || ... + ~isnumeric(vert) || ... + ~isnumeric(fTOL) ) + error('inpoly2:incorrectInputClass' , ... + 'Incorrect input class.') ; + end + +%---------------------------------------------- basic checks + if (ndims(node) ~= +2 || ... + ndims(edge) ~= +2 || ... + ndims(vert) ~= +2 || ... + numel(fTOL) ~= +1 ) + error('inpoly2:incorrectDimensions' , ... + 'Incorrect input dimensions.'); + end + if (size(node,2)~= +2 || ... + size(edge,2)~= +2 || ... + size(vert,2)~= +2 ) + error('inpoly2:incorrectDimensions' , ... + 'Incorrect input dimensions.'); + end + +%---------------------------------------------- basic checks + if (min([edge(:)]) < +1 || ... + max([edge(:)]) > nnod) + error('inpoly2:invalidInputs', ... + 'Invalid EDGE input array.') ; + end + + STAT = false(size(vert,1),1) ; + BNDS = false(size(vert,1),1) ; + +%----------------------------------- prune points using bbox + mask = ... + vert(:,1) >= min (node(:,1)) & ... + vert(:,1) <= max (node(:,1)) & ... + vert(:,2) >= min (node(:,2)) & ... + vert(:,2) <= max (node(:,2)) ; + + vert = vert(mask, :) ; + +%-------------- flip to ensure the y-axis is the "long" axis + vmin = min(vert,[],1); + vmax = max(vert,[],1); + ddxy = vmax - vmin ; + + lbar = sum(ddxy) / 2.; + + if (ddxy(1) > ddxy(2)) + vert = vert(:,[2,1]) ; + node = node(:,[2,1]) ; + end + +%----------------------------------- sort points via y-value + swap = ... + node(edge(:,2),2) ... + < node(edge(:,1),2) ; + + edge(swap,[1,2]) = ... + edge(swap,[2,1]) ; + + [~,ivec] = ... + sort(vert(:,+2)) ; + vert = vert (ivec,:) ; + + if (exist( ... + 'OCTAVE_VERSION','builtin') > +0) + + if (exist('inpoly2_oct','file') == +3) + + %-- delegate to the compiled version of the code if it's + %-- available + + [stat,bnds] = ... + inpoly2_oct( ... + vert,node,edge,fTOL,lbar) ; + + else + + %-- otherwise, just call the native m-code version + + [stat,bnds] = ... + inpoly2_mat( ... + vert,node,edge,fTOL,lbar) ; + + end + + else + + %-- MATLAB's JIT is generally smart enough these days to + %-- run this efficiently + + [stat,bnds] = ... + inpoly2_mat( ... + vert,node,edge,fTOL,lbar) ; + + end + + stat(ivec) = stat ; + bnds(ivec) = bnds ; + + STAT(mask) = stat ; + BNDS(mask) = bnds ; + +end + + + diff --git a/tools/poly_sign/inpoly2_mat.m b/tools/poly_sign/inpoly2_mat.m index 212093e..ee9bb06 100644 --- a/tools/poly_sign/inpoly2_mat.m +++ b/tools/poly_sign/inpoly2_mat.m @@ -6,7 +6,7 @@ %mber comparisons; break when the local y-range is exceeded. % Darren Engwirda : 2017 -- -% Email : de2363@columbia.edu +% Email : d.engwirda@gmail.com % Last updated : 27/10/2018 feps = fTOL * lbar ^ +2 ; @@ -18,10 +18,10 @@ stat = false(nvrt,1) ; bnds = false(nvrt,1) ; - + %----------------------------------- loop over polygon edges for epos = +1 : size(edge,1) - + inod = edge(epos,1) ; jnod = edge(epos,2) ; @@ -30,107 +30,107 @@ ytwo = node(jnod,2) ; xone = node(inod,1) ; xtwo = node(jnod,1) ; - + xmin = min(xone,xtwo) ; xmax = max(xone,xtwo) ; - - xmax = xmax + veps; - + + xmax = xmax + veps; + ymin = yone - veps; ymax = ytwo + veps; - + ydel = ytwo - yone; xdel = xtwo - xone; %------------------------------- find top VERT(:,2)= ymin) ilow = ilow - 1 ; end %------------------------------- calc. edge-intersection for jpos = ilow+1 : nvrt - + if (bnds(jpos)), continue ; end - + xpos = vert(jpos,1) ; ypos = vert(jpos,2) ; - + if (ypos <= ymax) if (xpos >= xmin) if (xpos <= xmax) - - %------------------- compute crossing number + + %------------------- compute crossing number mul1 = ... ydel * (xpos - xone) ; mul2 = ... xdel * (ypos - yone) ; - + if (feps >= ... abs(mul2 - mul1) ) - + %------------------- BNDS -- approx. on edge bnds(jpos)= true ; stat(jpos)= true ; - + elseif (ypos == yone ... && xpos == xone ) - + %------------------- BNDS -- match about ONE bnds(jpos)= true ; stat(jpos)= true ; - + elseif (ypos == ytwo ... && xpos == xtwo ) - + %------------------- BNDS -- match about TWO bnds(jpos)= true ; stat(jpos)= true ; - + elseif (mul1 < mul2) - + if (ypos >= yone ... && ypos < ytwo) - + %------------------- advance crossing number stat(jpos) = ... ~stat (jpos) ; - + end - + end - + end else - + if (ypos >= yone ... && ypos < ytwo) - + %------------------- advance crossing number stat(jpos) = ... ~stat (jpos) ; - + end - + end else - + break ; % done -- due to the sort - + end - + end end diff --git a/tools/poly_sign/inpoly2_oct.cpp b/tools/poly_sign/inpoly2_oct.cpp index fe7a061..dbdad5b 100644 --- a/tools/poly_sign/inpoly2_oct.cpp +++ b/tools/poly_sign/inpoly2_oct.cpp @@ -1,6 +1,6 @@ -// a fast pre-sorted variant of the crossing-number test for -// INPOLY2.m +// a fast pre-sorted variant of the crossing-number test for +// INPOLY2.m //---------------------------------------------------------- // Darren Engwirda : 2017 -- @@ -15,16 +15,16 @@ DEFUN_DLD (inpoly2_oct, args, , "-- \n" "-- INPOLY2-OCT: low-level routine called by INPOLY2 to \n" "-- compute point-in-polygon queries. \n" ) -{ +{ octave_value_list rval; - + int const nargin = args.length () ; if (nargin != +5) { print_usage () ; return rval ; } - + Matrix const vert ( args(0).matrix_value ()) ; Matrix const node ( @@ -35,20 +35,20 @@ DEFUN_DLD (inpoly2_oct, args, , args(3).double_value ()) ; double const lbar ( args(4).double_value ()) ; - + if (error_state) return rval ; - octave_idx_type const nvrt + octave_idx_type const nvrt = vert.rows () ; - octave_idx_type const nnod + octave_idx_type const nnod = node.rows () ; - octave_idx_type const nedg + octave_idx_type const nedg = edge.rows () ; //---------------------------------- init. crossing no. bool boolMatrix stat(nvrt, 1) ; boolMatrix bnds(nvrt, 1) ; - + octave_idx_type vpos ; for (vpos = +0; vpos != nvrt; ++vpos) { @@ -58,15 +58,15 @@ DEFUN_DLD (inpoly2_oct, args, , //---------------------------------- loop over polygon edges double const veps = fTOL * lbar ; - double const feps = fTOL * lbar + double const feps = fTOL * lbar * lbar ; - + octave_idx_type epos ; for (epos = +0; epos != nedg; ++epos) { - octave_idx_type const inod + octave_idx_type const inod = edge(epos,0) - 1 ; - octave_idx_type const jnod + octave_idx_type const jnod = edge(epos,1) - 1 ; //------------------------------ calc. edge bounding-box @@ -74,31 +74,31 @@ DEFUN_DLD (inpoly2_oct, args, , double ytwo = node (jnod,1) ; double xone = node (inod,0) ; double xtwo = node (jnod,0) ; - - double xmin = xone < xtwo + + double xmin = xone < xtwo ? xone : xtwo ; - double xmax = xone < xtwo - ? xtwo : xone ; - + double xmax = xone < xtwo + ? xtwo : xone ; + xmax+= veps ; - + double ymin = yone - veps ; double ymax = ytwo + veps ; - + double ydel = ytwo - yone ; double xdel = xtwo - xone ; - + //------------------------------ find top VERT(:,2)=ymin) { - ilow -= +1 ; + ilow -= +1 ; } } - + //------------------------------ calc. edge-intersection octave_idx_type vpos = ilow+1 ; for ( ; vpos != nvrt; ++vpos) { if (bnds(vpos)) continue; - + double xpos = vert(vpos,0); double ypos = vert(vpos,1); - + if (ypos <= ymax) { if (xpos >= xmin) @@ -135,7 +135,7 @@ DEFUN_DLD (inpoly2_oct, args, , ydel * (xpos - xone) ; double mul2 = xdel * (ypos - yone) ; - + if (feps >= std::abs(mul2 - mul1) ) { // BNDS -- approx. on edge @@ -148,7 +148,7 @@ DEFUN_DLD (inpoly2_oct, args, , { // BNDS -- match about ONE bnds(vpos)= true ; stat(vpos)= true ; - } + } else if (ypos == ytwo && xpos == xtwo ) @@ -166,7 +166,7 @@ DEFUN_DLD (inpoly2_oct, args, , ! stat (vpos) ; } } - + } } else @@ -189,7 +189,7 @@ DEFUN_DLD (inpoly2_oct, args, , rval(0) = stat; rval(1) = bnds; - + return ( rval ) ; } diff --git a/tools/predicate/normal2.m b/tools/predicate/normal2.m index a632b06..6e2ad6c 100644 --- a/tools/predicate/normal2.m +++ b/tools/predicate/normal2.m @@ -13,7 +13,7 @@ % See also TRIVOL2, TRIVOL3 % Darren Engwirda : 2017 -- -% Email : de2363@columbia.edu +% Email : d.engwirda@gmail.com % Last updated : 10/07/2018 %---------------------------------------------- basic checks diff --git a/tools/predicate/orient1.m b/tools/predicate/orient1.m index 9c1ddd3..a31e092 100644 --- a/tools/predicate/orient1.m +++ b/tools/predicate/orient1.m @@ -4,7 +4,7 @@ % See also ORIENT2 % Darren Engwirda : 2018 -- -% Email : de2363@columbia.edu +% Email : d.engwirda@gmail.com % Last updated : 25/07/2018 %---------------------------------------------- calc. det(S) diff --git a/tools/predicate/orient2.m b/tools/predicate/orient2.m index 74f96fb..35e1293 100644 --- a/tools/predicate/orient2.m +++ b/tools/predicate/orient2.m @@ -4,7 +4,7 @@ % See also ORIENT1 % Darren Engwirda : 2018 -- -% Email : de2363@columbia.edu +% Email : d.engwirda@gmail.com % Last updated : 25/07/2018 %---------------------------------------------- calc. det(S) diff --git a/tools/predicate/trivol2.m b/tools/predicate/trivol2.m index 800f94e..77a4e17 100644 --- a/tools/predicate/trivol2.m +++ b/tools/predicate/trivol2.m @@ -11,7 +11,7 @@ % See also TRISCR2, TRIANG2, TRIBAL2 % Darren Engwirda : 2017 -- -% Email : de2363@columbia.edu +% Email : d.engwirda@gmail.com % Last updated : 03/05/2018 %---------------------------------------------- basic checks diff --git a/tools/predicate/trivol3.m b/tools/predicate/trivol3.m index 041fbb1..75b9254 100644 --- a/tools/predicate/trivol3.m +++ b/tools/predicate/trivol3.m @@ -12,7 +12,7 @@ % See also TRISCR3, TRIANG3, TRIBAL3 % Darren Engwirda : 2017 -- -% Email : de2363@columbia.edu +% Email : d.engwirda@gmail.com % Last updated : 10/0/2018 %---------------------------------------------- basic checks diff --git a/tools/scorecard/pwrscr2.m b/tools/scorecard/pwrscr2.m index bceadc7..0d2657c 100644 --- a/tools/scorecard/pwrscr2.m +++ b/tools/scorecard/pwrscr2.m @@ -13,7 +13,7 @@ % See also TRISCR2, PWRBAL2 % Darren Engwirda : 2017 -- -% Email : de2363@columbia.edu +% Email : d.engwirda@gmail.com % Last updated : 03/05/2018 nd = size(pp,2); diff --git a/tools/scorecard/pwrscr3.m b/tools/scorecard/pwrscr3.m index 5c8bcdc..e4ba1b7 100644 --- a/tools/scorecard/pwrscr3.m +++ b/tools/scorecard/pwrscr3.m @@ -1,4 +1,4 @@ -function [sc] = vorscr3(pp,pw,t3) +function [sc] = pwrscr3(pp,pw,t3) %PWRSCR3 calc. a dual grid quality metric for triangles in a %3-simplex triangulation in R^3. % [SCR3] = PWRSCR3(VERT,VPWR,TRIA) returns the dual metric @@ -13,7 +13,7 @@ % See also TRISCR3, PWRBAL3 % Darren Engwirda : 2018 -- -% Email : de2363@columbia.edu +% Email : d.engwirda@gmail.com % Last updated : 20/06/2018 nd = size(pp,2); @@ -104,7 +104,7 @@ q5 = +1.0 - d5 ./ r5 ; q6 = +1.0 - d6 ./ r6 ; - qe = (q1+q2+q3+q4+q5+q6) /3. ; + qe = (q1+q2+q3+q4+q5+q6) /6. ; sc = 0.50 * qf + 0.50 * qe ; diff --git a/tools/scorecard/relfun2.m b/tools/scorecard/relfun2.m index efc5ab2..59e4a9d 100644 --- a/tools/scorecard/relfun2.m +++ b/tools/scorecard/relfun2.m @@ -11,7 +11,7 @@ % See also TRISCR2, TRIVOL2, TRIANG2, TRIBAL2 % Darren Engwirda : 2017 -- -% Email : de2363@columbia.edu +% Email : d.engwirda@gmail.com % Last updated : 10/08/2018 %---------------------------------------------- basic checks diff --git a/tools/scorecard/relfun3.m b/tools/scorecard/relfun3.m index 0c00b43..d991f35 100644 --- a/tools/scorecard/relfun3.m +++ b/tools/scorecard/relfun3.m @@ -11,7 +11,7 @@ % See also TRISCR3, TRIVOL3, TRIANG3, TRIBAL3 % Darren Engwirda : 2017 -- -% Email : de2363@columbia.edu +% Email : d.engwirda@gmail.com % Last updated : 10/08/2018 %---------------------------------------------- basic checks diff --git a/tools/scorecard/triang2.m b/tools/scorecard/triang2.m index 19e2d19..dfb8d63 100644 --- a/tools/scorecard/triang2.m +++ b/tools/scorecard/triang2.m @@ -13,7 +13,7 @@ % See also TRISCR2, TRIVOL2, TRIBAL2 % Darren Engwirda : 2017 -- -% Email : de2363@columbia.edu +% Email : d.engwirda@gmail.com % Last updated : 08/07/2018 %---------------------------------------------- basic checks diff --git a/tools/scorecard/triang3.m b/tools/scorecard/triang3.m index 30e5255..ecec9c6 100644 --- a/tools/scorecard/triang3.m +++ b/tools/scorecard/triang3.m @@ -14,7 +14,7 @@ % See also TRISCR3, TRIVOL3, TRIBAL3 % Darren Engwirda : 2017 -- -% Email : de2363@columbia.edu +% Email : d.engwirda@gmail.com % Last updated : 10/07/2018 %---------------------------------------------- basic checks diff --git a/tools/scorecard/trideg2.m b/tools/scorecard/trideg2.m index 34e886b..a72dfb9 100644 --- a/tools/scorecard/trideg2.m +++ b/tools/scorecard/trideg2.m @@ -13,7 +13,7 @@ % See also TRISCR2, TRIVOL2, TRIANG2, TRIBAL2 % Darren Engwirda : 2017 -- -% Email : de2363@columbia.edu +% Email : d.engwirda@gmail.com % Last updated : 29/07/2018 %---------------------------------------------- basic checks diff --git a/tools/scorecard/trideg3.m b/tools/scorecard/trideg3.m index 1a03514..c813b9b 100644 --- a/tools/scorecard/trideg3.m +++ b/tools/scorecard/trideg3.m @@ -13,7 +13,7 @@ % See also TRISCR3, TRIVOL3, TRIANG3, TRIBAL3 % Darren Engwirda : 2017 -- -% Email : de2363@columbia.edu +% Email : d.engwirda@gmail.com % Last updated : 29/07/2018 %---------------------------------------------- basic checks diff --git a/tools/scorecard/triscr2.m b/tools/scorecard/triscr2.m index da0b822..ac2a474 100644 --- a/tools/scorecard/triscr2.m +++ b/tools/scorecard/triscr2.m @@ -11,7 +11,7 @@ % See also TRIVOL2, TRIANG2, TRIBAL2 % Darren Engwirda : 2017 -- -% Email : de2363@columbia.edu +% Email : d.engwirda@gmail.com % Last updated : 03/05/2018 %--------------------------- compute signed area-len. ratios diff --git a/tools/scorecard/triscr3.m b/tools/scorecard/triscr3.m index 8e1a39d..0632690 100644 --- a/tools/scorecard/triscr3.m +++ b/tools/scorecard/triscr3.m @@ -12,7 +12,7 @@ % See also TRIVOL3, TRIANG3, TRIBAL3 % Darren Engwirda : 2017 -- -% Email : de2363@columbia.edu +% Email : d.engwirda@gmail.com % Last updated : 10/08/2018 %--------------------------- compute signed area-len. ratios diff --git a/tools/scorecard/welcen2.m b/tools/scorecard/welcen2.m index 2400dc6..3b60a06 100644 --- a/tools/scorecard/welcen2.m +++ b/tools/scorecard/welcen2.m @@ -9,7 +9,7 @@ % and dual vertices are triangle circumcentres. % Darren Engwirda : 2017 -- -% Email : de2363@columbia.edu +% Email : d.engwirda@gmail.com % Last updated : 19/03/2018 %---------------------------------------------- basic checks diff --git a/tools/scorecard/welcen3.m b/tools/scorecard/welcen3.m index 04f70eb..2c59caa 100644 --- a/tools/scorecard/welcen3.m +++ b/tools/scorecard/welcen3.m @@ -9,7 +9,7 @@ % and dual vertices are triangle circumcentres. % Darren Engwirda : 2018 -- -% Email : de2363@columbia.edu +% Email : d.engwirda@gmail.com % Last updated : 10/07/2018 %---------------------------------------------- basic checks diff --git a/tripod.m b/tripod.m index ef249f2..bd7a01e 100644 --- a/tripod.m +++ b/tripod.m @@ -76,7 +76,7 @@ % Darren Engwirda % github.com/dengwirda/jigsaw-matlab % 27-Apr-2019 -% darren.engwirda@columbia.edu +% d.engwirda@gmail.com %----------------------------------------------------------- % From a65be470a254afdc7f89f4eb6367ce51f8b9db97 Mon Sep 17 00:00:00 2001 From: dengwirda Date: Sun, 13 Sep 2020 14:43:15 -0600 Subject: [PATCH 2/6] Update bindings for jigsaw-0.9.13.xx --- tools/orthoball/quadbal2.m | 190 ------------------------------------ tools/orthoball/quadbal2.m~ | 190 ------------------------------------ 2 files changed, 380 deletions(-) delete mode 100644 tools/orthoball/quadbal2.m delete mode 100644 tools/orthoball/quadbal2.m~ diff --git a/tools/orthoball/quadbal2.m b/tools/orthoball/quadbal2.m deleted file mode 100644 index c13a551..0000000 --- a/tools/orthoball/quadbal2.m +++ /dev/null @@ -1,190 +0,0 @@ -function [bb] = quadbal2(pp,pw,qq) -%QUADBAL... - -% Darren Engwirda : 2017 -- -% Email : d.engwirda@gmail.com -% Last updated : 02/05/2018 - - -% blah, checks - - - b1 = tribal2(pp,qq(:,[1,2,3])); - b2 = tribal2(pp,qq(:,[1,3,4])); - b3 = tribal2(pp,qq(:,[1,2,4])); - b4 = tribal2(pp,qq(:,[2,3,4])); - - bb = .25*(b1+b2+b3+b4); - return - - switch (size(pp,2)) - case +2 - %-------------------------------------------- alloc work - AA = zeros(2,2,size(tt,1)) ; - Rv = zeros(2,1,size(tt,1)) ; - bb = zeros(size(tt,1),3,1) ; - - %-------------------------------------------- lhs matrix - ab = pp(tt(:,2),:)-pp(tt(:,1),:); - ac = pp(tt(:,3),:)-pp(tt(:,1),:); - - AA(1,1,:) = ab(:,1) * +2.0 ; - AA(1,2,:) = ab(:,2) * +2.0 ; - AA(2,1,:) = ac(:,1) * +2.0 ; - AA(2,2,:) = ac(:,2) * +2.0 ; - - %-------------------------------------------- rhs vector - Rv(1,1,:) = sum(ab.*ab,2) ... - - ( pw(tt(:,2)) - pw(tt(:,1)) ) ; - - Rv(2,1,:) = sum(ac.*ac,2) ... - - ( pw(tt(:,3)) - pw(tt(:,1)) ) ; - - %-------------------------------------------- solve sys. - [II,dd] = inv_2x2(AA) ; - - bb(:,1) = ( ... - II(1,1,:).*Rv(1,1,:) + ... - II(1,2,:).*Rv(2,1,:) ) ... - ./ dd ; - - bb(:,2) = ( ... - II(2,1,:).*Rv(1,1,:) + ... - II(2,2,:).*Rv(2,1,:) ) ... - ./ dd ; - - bb(:,1:2) = ... - pp(tt(:,1),:) + bb(:,1:2) ; - - %-------------------------------------------- mean radii - r1 = sum( ... - (bb(:,1:2)-pp(tt(:,1),:)).^2,2) ; - r2 = sum( ... - (bb(:,1:2)-pp(tt(:,2),:)).^2,2) ; - r3 = sum( ... - (bb(:,1:2)-pp(tt(:,3),:)).^2,2) ; - - r1 = r1 - pw(tt(:,1)); - r2 = r2 - pw(tt(:,2)); - r3 = r3 - pw(tt(:,3)); - - bb(:,3) = ( r1+r2+r3 ) / +3.0 ; - - case +3 - %-------------------------------------------- alloc work - AA = zeros(3,3,size(qq,1)) ; - Rv = zeros(3,1,size(qq,1)) ; - bb = zeros(size(qq,1),4,1) ; - - %-------------------------------------------- lhs matrix - ab = pp(qq(:,2),:)-pp(qq(:,1),:); - ac = pp(qq(:,3),:)-pp(qq(:,1),:); - ad = pp(qq(:,4),:)-pp(qq(:,1),:); - - bc = pp(qq(:,3),:)-pp(qq(:,2),:); - bd = pp(qq(:,4),:)-pp(qq(:,2),:); - - n1 = cross(ab,ac) ; - n2 = cross(ac,ad) ; - n3 = cross(ab,bd) ; - n4 = cross(bd,bc) ; - - absq = sum(ab.*ab,2); - acsq = sum(ac.*ac,2); - adsq = sum(ad.*ad,2); - - for ii = 1:size(qq,1) - - As(1,1) = ab(ii,1) * +2.0 ; - As(1,2) = ab(ii,2) * +2.0 ; - As(1,3) = ab(ii,3) * +2.0 ; - As(2,1) = ac(ii,1) * +2.0 ; - As(2,2) = ac(ii,2) * +2.0 ; - As(2,3) = ac(ii,3) * +2.0 ; - As(3,1) = ad(ii,1) * +2.0 ; - As(3,2) = ad(ii,2) * +2.0 ; - As(3,3) = ad(ii,3) * +2.0 ; - - As(4,1) = n1(ii,1) * +1.0 ; - As(4,2) = n1(ii,2) * +1.0 ; - As(4,3) = n1(ii,3) * +1.0 ; - As(5,1) = n2(ii,1) * +1.0 ; - As(5,2) = n2(ii,2) * +1.0 ; - As(5,3) = n2(ii,3) * +1.0 ; - - As(6,1) = n3(ii,1) * +1.0 ; - As(6,2) = n3(ii,2) * +1.0 ; - As(6,3) = n3(ii,3) * +1.0 ; - As(7,1) = n4(ii,1) * +1.0 ; - As(7,2) = n4(ii,2) * +1.0 ; - As(7,3) = n4(ii,3) * +1.0 ; - - %-------------------------------------------- rhs vector - Rs(1,1) = absq(ii,:) ... - - ( pw(qq(ii,2)) - pw(qq(ii,1)) ) ; - - Rs(2,1) = acsq(ii,:) ... - - ( pw(qq(ii,3)) - pw(qq(ii,1)) ) ; - - Rs(3,1) = adsq(ii,:) ... - - ( pw(qq(ii,4)) - pw(qq(ii,1)) ) ; - - Rs(4:7,1) = 0.0 ; - - AA(1:3,:,ii) = As' * As ; - Rv(1:3,1,ii) = As' * Rs ; - - end - - %-------------------------------------------- solve sys. - [II,dd] = inv_3x3(AA) ; - - bb(:,1) = ( ... - II(1,1,:).*Rv(1,1,:) + ... - II(1,2,:).*Rv(2,1,:) + ... - II(1,3,:).*Rv(3,1,:) ) ... - ./ dd ; - - bb(:,2) = ( ... - II(2,1,:).*Rv(1,1,:) + ... - II(2,2,:).*Rv(2,1,:) + ... - II(2,3,:).*Rv(3,1,:) ) ... - ./ dd ; - - bb(:,3) = ( ... - II(3,1,:).*Rv(1,1,:) + ... - II(3,2,:).*Rv(2,1,:) + ... - II(3,3,:).*Rv(3,1,:) ) ... - ./ dd ; - - bb(:,1:3) = ... - pp(qq(:,1),:) + bb(:,1:3) ; - - %-------------------------------------------- mean radii - r1 = sum( ... - (bb(:,1:3)-pp(qq(:,1),:)).^2,2) ; - r2 = sum( ... - (bb(:,1:3)-pp(qq(:,2),:)).^2,2) ; - r3 = sum( ... - (bb(:,1:3)-pp(qq(:,3),:)).^2,2) ; - r4 = sum( ... - (bb(:,1:3)-pp(qq(:,4),:)).^2,2) ; - - r1 = r1 - pw(qq(:,1)); - r2 = r2 - pw(qq(:,2)); - r3 = r3 - pw(qq(:,3)); - r4 = r4 - pw(qq(:,4)); - - bb(:,4) = ( r1+r2+r3+r4 ) / +4. ; - - otherwise - - error('pwrbal2:unsupportedDimension' , ... - 'Dimension not supported.') ; - - end - -end - - - diff --git a/tools/orthoball/quadbal2.m~ b/tools/orthoball/quadbal2.m~ deleted file mode 100644 index 26cf818..0000000 --- a/tools/orthoball/quadbal2.m~ +++ /dev/null @@ -1,190 +0,0 @@ -function [bb] = quadbal2(pp,pw,qq) -%QUADBAL... - -% Darren Engwirda : 2017 -- -% Email : de2363@columbia.edu -% Last updated : 02/05/2018 - - -% blah, checks - - - b1 = tribal2(pp,qq(:,[1,2,3])); - b2 = tribal2(pp,qq(:,[1,3,4])); - b3 = tribal2(pp,qq(:,[1,2,4])); - b4 = tribal2(pp,qq(:,[2,3,4])); - - bb = .25*(b1+b2+b3+b4); - - - switch (size(pp,2)) - case +2 - %-------------------------------------------- alloc work - AA = zeros(2,2,size(tt,1)) ; - Rv = zeros(2,1,size(tt,1)) ; - bb = zeros(size(tt,1),3,1) ; - - %-------------------------------------------- lhs matrix - ab = pp(tt(:,2),:)-pp(tt(:,1),:); - ac = pp(tt(:,3),:)-pp(tt(:,1),:); - - AA(1,1,:) = ab(:,1) * +2.0 ; - AA(1,2,:) = ab(:,2) * +2.0 ; - AA(2,1,:) = ac(:,1) * +2.0 ; - AA(2,2,:) = ac(:,2) * +2.0 ; - - %-------------------------------------------- rhs vector - Rv(1,1,:) = sum(ab.*ab,2) ... - - ( pw(tt(:,2)) - pw(tt(:,1)) ) ; - - Rv(2,1,:) = sum(ac.*ac,2) ... - - ( pw(tt(:,3)) - pw(tt(:,1)) ) ; - - %-------------------------------------------- solve sys. - [II,dd] = inv_2x2(AA) ; - - bb(:,1) = ( ... - II(1,1,:).*Rv(1,1,:) + ... - II(1,2,:).*Rv(2,1,:) ) ... - ./ dd ; - - bb(:,2) = ( ... - II(2,1,:).*Rv(1,1,:) + ... - II(2,2,:).*Rv(2,1,:) ) ... - ./ dd ; - - bb(:,1:2) = ... - pp(tt(:,1),:) + bb(:,1:2) ; - - %-------------------------------------------- mean radii - r1 = sum( ... - (bb(:,1:2)-pp(tt(:,1),:)).^2,2) ; - r2 = sum( ... - (bb(:,1:2)-pp(tt(:,2),:)).^2,2) ; - r3 = sum( ... - (bb(:,1:2)-pp(tt(:,3),:)).^2,2) ; - - r1 = r1 - pw(tt(:,1)); - r2 = r2 - pw(tt(:,2)); - r3 = r3 - pw(tt(:,3)); - - bb(:,3) = ( r1+r2+r3 ) / +3.0 ; - - case +3 - %-------------------------------------------- alloc work - AA = zeros(3,3,size(qq,1)) ; - Rv = zeros(3,1,size(qq,1)) ; - bb = zeros(size(qq,1),4,1) ; - - %-------------------------------------------- lhs matrix - ab = pp(qq(:,2),:)-pp(qq(:,1),:); - ac = pp(qq(:,3),:)-pp(qq(:,1),:); - ad = pp(qq(:,4),:)-pp(qq(:,1),:); - - bc = pp(qq(:,3),:)-pp(qq(:,2),:); - bd = pp(qq(:,4),:)-pp(qq(:,2),:); - - n1 = cross(ab,ac) ; - n2 = cross(ac,ad) ; - n3 = cross(ab,bd) ; - n4 = cross(bd,bc) ; - - absq = sum(ab.*ab,2); - acsq = sum(ac.*ac,2); - adsq = sum(ad.*ad,2); - - for ii = 1:size(qq,1) - - As(1,1) = ab(ii,1) * +2.0 ; - As(1,2) = ab(ii,2) * +2.0 ; - As(1,3) = ab(ii,3) * +2.0 ; - As(2,1) = ac(ii,1) * +2.0 ; - As(2,2) = ac(ii,2) * +2.0 ; - As(2,3) = ac(ii,3) * +2.0 ; - As(3,1) = ad(ii,1) * +2.0 ; - As(3,2) = ad(ii,2) * +2.0 ; - As(3,3) = ad(ii,3) * +2.0 ; - - As(4,1) = n1(ii,1) * +1.0 ; - As(4,2) = n1(ii,2) * +1.0 ; - As(4,3) = n1(ii,3) * +1.0 ; - As(5,1) = n2(ii,1) * +1.0 ; - As(5,2) = n2(ii,2) * +1.0 ; - As(5,3) = n2(ii,3) * +1.0 ; - - As(6,1) = n3(ii,1) * +1.0 ; - As(6,2) = n3(ii,2) * +1.0 ; - As(6,3) = n3(ii,3) * +1.0 ; - As(7,1) = n4(ii,1) * +1.0 ; - As(7,2) = n4(ii,2) * +1.0 ; - As(7,3) = n4(ii,3) * +1.0 ; - - %-------------------------------------------- rhs vector - Rs(1,1) = absq(ii,:) ... - - ( pw(qq(ii,2)) - pw(qq(ii,1)) ) ; - - Rs(2,1) = acsq(ii,:) ... - - ( pw(qq(ii,3)) - pw(qq(ii,1)) ) ; - - Rs(3,1) = adsq(ii,:) ... - - ( pw(qq(ii,4)) - pw(qq(ii,1)) ) ; - - Rs(4:7,1) = 0.0 ; - - AA(1:3,:,ii) = As' * As ; - Rv(1:3,1,ii) = As' * Rs ; - - end - - %-------------------------------------------- solve sys. - [II,dd] = inv_3x3(AA) ; - - bb(:,1) = ( ... - II(1,1,:).*Rv(1,1,:) + ... - II(1,2,:).*Rv(2,1,:) + ... - II(1,3,:).*Rv(3,1,:) ) ... - ./ dd ; - - bb(:,2) = ( ... - II(2,1,:).*Rv(1,1,:) + ... - II(2,2,:).*Rv(2,1,:) + ... - II(2,3,:).*Rv(3,1,:) ) ... - ./ dd ; - - bb(:,3) = ( ... - II(3,1,:).*Rv(1,1,:) + ... - II(3,2,:).*Rv(2,1,:) + ... - II(3,3,:).*Rv(3,1,:) ) ... - ./ dd ; - - bb(:,1:3) = ... - pp(qq(:,1),:) + bb(:,1:3) ; - - %-------------------------------------------- mean radii - r1 = sum( ... - (bb(:,1:3)-pp(qq(:,1),:)).^2,2) ; - r2 = sum( ... - (bb(:,1:3)-pp(qq(:,2),:)).^2,2) ; - r3 = sum( ... - (bb(:,1:3)-pp(qq(:,3),:)).^2,2) ; - r4 = sum( ... - (bb(:,1:3)-pp(qq(:,4),:)).^2,2) ; - - r1 = r1 - pw(qq(:,1)); - r2 = r2 - pw(qq(:,2)); - r3 = r3 - pw(qq(:,3)); - r4 = r4 - pw(qq(:,4)); - - bb(:,4) = ( r1+r2+r3+r4 ) / +4. ; - - otherwise - - error('pwrbal2:unsupportedDimension' , ... - 'Dimension not supported.') ; - - end - -end - - - From c331d842fc1441c9dd94db2f6dcafe20657e9e59 Mon Sep 17 00:00:00 2001 From: dengwirda Date: Sun, 13 Sep 2020 14:46:40 -0600 Subject: [PATCH 3/6] Squashed 'external/jigsaw/' changes from 666718d..b48a83a b48a83a Merge pull request #36 from dengwirda/dev 3a80cb3 0.9.13 updates: support for non-simplex elements, etc 55a014c 0.9.13 updates: support for non-simplex elements, etc b131785 0.9.13 updates: support for non-simplex elements, etc 6798909 Merge pull request #35 from dengwirda/dev ecbe4a0 0.9.13 updates: support for non-simplex elements, etc f3a66a1 0.9.13 updates: support for non-simplex elements, etc 996036f 0.9.13 updates: support for non-simplex elements, etc f3c66b8 0.9.13 updates: revised off-centre refinement rules fad1db4 0.9.13 updates: (slightly) improved error flags 8eb2078 Merge pull request #29 from dengwirda/dev git-subtree-dir: external/jigsaw git-subtree-split: b48a83a9fb3315732a56658fa800e6d3f3679abf --- README.md | 10 +- inc/jigsaw_const.h | 10 +- inc/jigsaw_jig_t.h | 2 +- inc/jigsaw_msh_t.h | 9 +- inc/lib_jigsaw.h | 2 +- src/CMakeLists.txt | 2 +- src/geo_load.hpp | 302 +- src/hfn_init.hpp | 2 +- src/hfn_load.hpp | 128 +- src/ini_load.hpp | 290 +- src/jig_load.hpp | 30 +- src/jig_read.hpp | 43 +- src/jigsaw.cpp | 136 +- src/jigsaw.hpp | 286 +- src/libcpp/aabb_tree/aabb_mesh_k.hpp | 2 +- src/libcpp/aabb_tree/aabb_pred_k.hpp | 2 +- src/libcpp/aabb_tree/aabb_tree_k.hpp | 63 +- src/libcpp/aabb_tree/aabb_type_k.hpp | 2 +- src/libcpp/aabbtree.hpp | 2 +- src/libcpp/algorithms.hpp | 4 +- src/libcpp/algorithms/find.hpp | 2 +- src/libcpp/algorithms/sort.hpp | 2 +- src/libcpp/allocators.hpp | 4 +- src/libcpp/allocators/alloc_base.hpp | 2 +- src/libcpp/allocators/alloc_item.hpp | 2 +- src/libcpp/allocators/alloc_pool.hpp | 2 +- src/libcpp/allocators/alloc_wrap.hpp | 2 +- src/libcpp/{libbasic.hpp => basebase.hpp} | 50 +- src/libcpp/containers.hpp | 3 +- src/libcpp/containers/array.hpp | 47 +- src/libcpp/containers/array_iter.hpp | 2 +- src/libcpp/containers/arraylist.hpp | 3 +- src/libcpp/containers/basic_stack.hpp | 2 +- src/libcpp/containers/block_array.hpp | 24 +- src/libcpp/containers/block_iter.hpp | 2 +- src/libcpp/containers/double_list.hpp | 2 +- src/libcpp/containers/doubleiter.hpp | 2 +- src/libcpp/containers/fixed_array.hpp | 37 +- src/libcpp/containers/hashtable.hpp | 21 +- src/libcpp/containers/hashtwice.hpp | 773 ++++ src/libcpp/containers/iter_base.hpp | 2 +- src/libcpp/containers/prioritymap.hpp | 68 +- src/libcpp/containers/priorityset.hpp | 4 +- src/libcpp/containers/single_list.hpp | 2 +- src/libcpp/containers/singleiter.hpp | 2 +- src/libcpp/expansion/dd_float.hpp | 550 +++ src/libcpp/expansion/ia_float.hpp | 671 +++ src/libcpp/expansion/mp_basic.hpp | 660 +++ src/libcpp/expansion/mp_float.hpp | 1023 +++++ src/libcpp/expansion/mp_utils.hpp | 448 ++ .../{tria_ball_k.hpp => cell_ball_k.hpp} | 224 +- .../{tria_elem_k.hpp => cell_base_k.hpp} | 456 +- src/libcpp/geom_base/intersect_k.hpp | 8 +- src/libcpp/geom_base/predicate_k.hpp | 3818 ----------------- src/libcpp/geom_base/vect_base_k.hpp | 129 +- src/libcpp/geom_type/geom_base_2.hpp | 2 +- src/libcpp/geom_type/geom_base_3.hpp | 12 +- .../geom_type/geom_mesh_ellipsoid_3.hpp | 1146 +++-- .../geom_type/geom_mesh_euclidean_2.hpp | 260 +- .../geom_type/geom_mesh_euclidean_3.hpp | 680 +-- src/libcpp/geometry.hpp | 16 +- src/libcpp/geompred.hpp | 59 + src/libcpp/geomtype.hpp | 16 +- src/libcpp/hashfunc.hpp | 2 +- src/libcpp/iter_mesh/iter_divs_2.inc | 505 +-- src/libcpp/iter_mesh/iter_divs_3.inc | 81 +- src/libcpp/iter_mesh/iter_dual_2.inc | 458 +- src/libcpp/iter_mesh/iter_dual_3.inc | 232 +- src/libcpp/iter_mesh/iter_flip_2.inc | 453 +- src/libcpp/iter_mesh/iter_flip_3.inc | 2 +- src/libcpp/iter_mesh/iter_mesh_2.hpp | 2253 +++++----- src/libcpp/iter_mesh/iter_mesh_3.hpp | 42 +- .../iter_mesh/iter_mesh_euclidean_2.hpp | 38 +- .../iter_mesh/iter_mesh_euclidean_3.hpp | 104 +- src/libcpp/iter_mesh/iter_node_1.inc | 4 +- src/libcpp/iter_mesh/iter_node_2.inc | 1575 +++++-- src/libcpp/iter_mesh/iter_node_3.inc | 448 +- .../iter_mesh/iter_pred_ellipsoid_3.hpp | 270 +- .../iter_mesh/iter_pred_euclidean_2.hpp | 218 +- .../iter_mesh/iter_pred_euclidean_3.hpp | 241 -- src/libcpp/iter_mesh/iter_timers.hpp | 13 +- src/libcpp/iter_mesh/iter_zips_2.inc | 678 +-- src/libcpp/iter_mesh/iter_zips_3.inc | 493 +-- src/libcpp/itermesh.hpp | 7 +- src/libcpp/mathutil.hpp | 184 +- src/libcpp/mesh_func/hfun_base_k.hpp | 2 +- src/libcpp/mesh_func/hfun_clip_k.hpp | 2 +- .../mesh_func/hfun_constant_value_k.hpp | 2 +- .../mesh_func/hfun_grid_ellipsoid_3.hpp | 138 +- .../mesh_func/hfun_grid_euclidean_2.hpp | 38 +- .../mesh_func/hfun_grid_euclidean_3.hpp | 2 +- .../mesh_func/hfun_mesh_ellipsoid_3.hpp | 190 +- .../mesh_func/hfun_mesh_euclidean_2.hpp | 157 +- .../mesh_func/hfun_mesh_euclidean_3.hpp | 183 +- src/libcpp/mesh_type/base_complex_k.hpp | 3336 ++++++++++++++ src/libcpp/mesh_type/hash_complex_k.hpp | 766 ++++ src/libcpp/mesh_type/mesh_complex_1.hpp | 430 ++ src/libcpp/mesh_type/mesh_complex_2.hpp | 681 +++ src/libcpp/mesh_type/mesh_complex_3.hpp | 2422 +++-------- src/libcpp/mesh_type/mesh_complex_type_k.hpp | 225 +- src/libcpp/mesh_type/tria_complex_1.hpp | 843 +--- src/libcpp/mesh_type/tria_complex_2.hpp | 1398 +----- src/libcpp/mesh_type/tria_complex_3.hpp | 2118 ++------- src/libcpp/meshfunc.hpp | 2 +- src/libcpp/meshtype.hpp | 31 +- src/libcpp/mp_floats/dd_flt.hpp | 451 -- src/libcpp/mp_floats/dd_imp.hpp | 350 -- src/libcpp/mp_floats/mp_imp.hpp | 355 -- src/libcpp/mpfloats.hpp | 29 +- src/libcpp/parameters/iter_params.hpp | 2 +- src/libcpp/parameters/mesh_params.hpp | 4 +- src/libcpp/predicate/bisect_k.hpp | 966 +++++ src/libcpp/predicate/inball_k.hpp | 1621 +++++++ src/libcpp/predicate/orient_k.hpp | 848 ++++ src/libcpp/predicate/predicate_k.hpp | 719 ++++ src/libcpp/rdel_mesh/rdel_base_2.hpp | 151 +- src/libcpp/rdel_mesh/rdel_base_3.hpp | 263 +- src/libcpp/rdel_mesh/rdel_complex_2.hpp | 34 +- src/libcpp/rdel_mesh/rdel_complex_3.hpp | 34 +- src/libcpp/rdel_mesh/rdel_cost_delaunay_2.inc | 2 +- src/libcpp/rdel_mesh/rdel_cost_delaunay_3.inc | 4 +- src/libcpp/rdel_mesh/rdel_cost_delfront_2.inc | 43 +- src/libcpp/rdel_mesh/rdel_cost_delfront_3.inc | 80 +- src/libcpp/rdel_mesh/rdel_create_init_2.inc | 22 +- src/libcpp/rdel_mesh/rdel_create_init_3.inc | 26 +- src/libcpp/rdel_mesh/rdel_filt_k.hpp | 2 +- src/libcpp/rdel_mesh/rdel_make_2.hpp | 22 +- src/libcpp/rdel_mesh/rdel_make_3.hpp | 24 +- src/libcpp/rdel_mesh/rdel_mesh_2.hpp | 14 +- src/libcpp/rdel_mesh/rdel_mesh_3.hpp | 83 +- src/libcpp/rdel_mesh/rdel_offh_delfront_2.inc | 192 +- src/libcpp/rdel_mesh/rdel_offh_delfront_3.inc | 304 +- src/libcpp/rdel_mesh/rdel_pred_delaunay_2.hpp | 2 +- src/libcpp/rdel_mesh/rdel_pred_delaunay_3.hpp | 4 +- src/libcpp/rdel_mesh/rdel_pred_delfront_2.hpp | 118 +- src/libcpp/rdel_mesh/rdel_pred_delfront_3.hpp | 275 +- src/libcpp/rdel_mesh/rdel_refine_ball_2.inc | 260 +- src/libcpp/rdel_mesh/rdel_refine_ball_3.inc | 361 +- src/libcpp/rdel_mesh/rdel_refine_base_2.inc | 26 +- src/libcpp/rdel_mesh/rdel_refine_base_3.inc | 27 +- src/libcpp/rdel_mesh/rdel_refine_face_2.inc | 2 +- src/libcpp/rdel_mesh/rdel_refine_face_3.inc | 2 +- src/libcpp/rdel_mesh/rdel_refine_topo_2.inc | 190 +- src/libcpp/rdel_mesh/rdel_refine_topo_3.inc | 426 +- src/libcpp/rdel_mesh/rdel_sink_delfront_2.inc | 2 +- src/libcpp/rdel_mesh/rdel_sink_delfront_3.inc | 2 +- src/libcpp/rdel_mesh/rdel_test_bounds_2.inc | 2 +- src/libcpp/rdel_mesh/rdel_test_bounds_3.inc | 16 +- src/libcpp/rdel_mesh/rdel_timers.hpp | 2 +- src/libcpp/rdel_mesh/rdel_update_face_2.inc | 2 +- src/libcpp/rdel_mesh/rdel_update_face_3.inc | 6 +- src/libcpp/rdel_mesh/rdel_update_topo_2.inc | 2 +- src/libcpp/rdel_mesh/rdel_update_topo_3.inc | 2 +- src/libcpp/rdel_mesh/rvor_mesh_2.hpp | 2 +- src/libcpp/rdel_mesh/rvor_mesh_3.hpp | 2 +- src/libcpp/rdel_mesh/rvor_update_face_2.inc | 2 +- src/libcpp/rdelmesh.hpp | 4 +- src/libcpp/tessellate.hpp | 16 +- src/libcpp/tessellate/delaunay_scan_tria.inc | 4 +- src/libcpp/tessellate/delaunay_star_void.inc | 36 +- src/libcpp/tessellate/delaunay_tri_k.hpp | 98 +- ...uclidean_2.hpp => delaunay_tri_pred_2.hpp} | 21 +- ...uclidean_3.hpp => delaunay_tri_pred_3.hpp} | 21 +- src/libcpp/tessellate/delaunay_tri_pred_4.hpp | 363 ++ src/libcpp/tessellate/delaunay_tri_type_2.hpp | 243 +- src/libcpp/tessellate/delaunay_tri_type_3.hpp | 166 +- src/libcpp/tessellate/delaunay_tri_type_4.hpp | 533 +++ src/libcpp/tessellate/delaunay_walk_mesh.inc | 6 +- src/libcpp/tessellate/laguerre_tri_pred_2.hpp | 303 ++ src/libcpp/tessellate/laguerre_tri_pred_3.hpp | 330 ++ src/libcpp/tessellate/laguerre_tri_pred_4.hpp | 363 ++ src/libcpp/{libparse.hpp => textutil.hpp} | 10 +- src/libcpp/tree_mesh/tree_mesh_2.hpp | 4 +- src/libcpp/tree_mesh/tree_timers.hpp | 2 +- src/libcpp/treemesh.hpp | 2 +- src/libcpp/useropts.hpp | 2 +- src/liblib/init_jig_t.hpp | 2 +- src/liblib/init_msh_t.hpp | 76 +- src/liblib/load_jig_t.hpp | 2 +- src/liblib/load_msh_t.hpp | 88 +- src/liblib/save_jig_t.hpp | 11 +- src/liblib/save_msh_t.hpp | 2 +- src/marche.hpp | 16 +- src/msh_copy.hpp | 73 +- src/msh_init.hpp | 132 +- src/msh_read.hpp | 100 +- src/msh_save.hpp | 607 ++- src/netcdf/COPYRIGHT.md | 11 + src/netcdf/README.md | 81 + src/netcdf/lib_netcdf.h | 2001 +++++++++ src/tripod.hpp | 122 +- uni/test_1.c | 74 +- uni/test_2.c | 96 +- uni/test_3.c | 96 +- uni/test_4.c | 90 +- uni/test_5.c | 76 +- uni/test_6.c | 88 +- uni/test_7.c | 54 +- uni/test_8.c | 62 +- uni/test_9.c | 60 +- version.txt | 11 + 201 files changed, 29850 insertions(+), 18922 deletions(-) rename src/libcpp/{libbasic.hpp => basebase.hpp} (78%) create mode 100644 src/libcpp/containers/hashtwice.hpp create mode 100644 src/libcpp/expansion/dd_float.hpp create mode 100644 src/libcpp/expansion/ia_float.hpp create mode 100644 src/libcpp/expansion/mp_basic.hpp create mode 100644 src/libcpp/expansion/mp_float.hpp create mode 100644 src/libcpp/expansion/mp_utils.hpp rename src/libcpp/geom_base/{tria_ball_k.hpp => cell_ball_k.hpp} (89%) rename src/libcpp/geom_base/{tria_elem_k.hpp => cell_base_k.hpp} (51%) delete mode 100644 src/libcpp/geom_base/predicate_k.hpp create mode 100644 src/libcpp/geompred.hpp delete mode 100644 src/libcpp/iter_mesh/iter_pred_euclidean_3.hpp create mode 100644 src/libcpp/mesh_type/base_complex_k.hpp create mode 100644 src/libcpp/mesh_type/hash_complex_k.hpp create mode 100644 src/libcpp/mesh_type/mesh_complex_1.hpp create mode 100644 src/libcpp/mesh_type/mesh_complex_2.hpp delete mode 100644 src/libcpp/mp_floats/dd_flt.hpp delete mode 100644 src/libcpp/mp_floats/dd_imp.hpp delete mode 100644 src/libcpp/mp_floats/mp_imp.hpp create mode 100644 src/libcpp/predicate/bisect_k.hpp create mode 100644 src/libcpp/predicate/inball_k.hpp create mode 100644 src/libcpp/predicate/orient_k.hpp create mode 100644 src/libcpp/predicate/predicate_k.hpp rename src/libcpp/tessellate/{del_tri_euclidean_2.hpp => delaunay_tri_pred_2.hpp} (95%) rename src/libcpp/tessellate/{del_tri_euclidean_3.hpp => delaunay_tri_pred_3.hpp} (95%) create mode 100644 src/libcpp/tessellate/delaunay_tri_pred_4.hpp create mode 100644 src/libcpp/tessellate/delaunay_tri_type_4.hpp create mode 100644 src/libcpp/tessellate/laguerre_tri_pred_2.hpp create mode 100644 src/libcpp/tessellate/laguerre_tri_pred_3.hpp create mode 100644 src/libcpp/tessellate/laguerre_tri_pred_4.hpp rename src/libcpp/{libparse.hpp => textutil.hpp} (97%) create mode 100644 src/netcdf/COPYRIGHT.md create mode 100644 src/netcdf/README.md create mode 100644 src/netcdf/lib_netcdf.h diff --git a/README.md b/README.md index ce2b43c..9a02711 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/inc/jigsaw_const.h b/inc/jigsaw_const.h index 39f7f8e..1ad031f 100644 --- a/inc/jigsaw_const.h +++ b/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/inc/jigsaw_jig_t.h b/inc/jigsaw_jig_t.h index b911745..2e64066 100644 --- a/inc/jigsaw_jig_t.h +++ b/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/inc/jigsaw_msh_t.h b/inc/jigsaw_msh_t.h index 8b76ea6..7823e10 100644 --- a/inc/jigsaw_msh_t.h +++ b/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/inc/lib_jigsaw.h b/inc/lib_jigsaw.h index 1e2f94b..d84ff3f 100644 --- a/inc/lib_jigsaw.h +++ b/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/src/CMakeLists.txt b/src/CMakeLists.txt index eda1ba6..358d3c8 100644 --- a/src/CMakeLists.txt +++ b/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/src/geo_load.hpp b/src/geo_load.hpp index b8b2c04..c751960 100644 --- a/src/geo_load.hpp +++ b/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/src/hfn_init.hpp b/src/hfn_init.hpp index 4c51fde..78aeb43 100644 --- a/src/hfn_init.hpp +++ b/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/src/hfn_load.hpp b/src/hfn_load.hpp index 7a0ede8..230a1d1 100644 --- a/src/hfn_load.hpp +++ b/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/src/ini_load.hpp b/src/ini_load.hpp index aa60503..c02125d 100644 --- a/src/ini_load.hpp +++ b/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/src/jig_load.hpp b/src/jig_load.hpp index 37a31f2..0415bcd 100644 --- a/src/jig_load.hpp +++ b/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/src/jig_read.hpp b/src/jig_read.hpp index 5956cf9..3983429 100644 --- a/src/jig_read.hpp +++ b/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/src/jigsaw.cpp b/src/jigsaw.cpp index 46eae57..333e417 100644 --- a/src/jigsaw.cpp +++ b/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/src/jigsaw.hpp b/src/jigsaw.hpp index 5e769ac..8af1def 100644 --- a/src/jigsaw.hpp +++ b/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/src/libcpp/aabb_tree/aabb_mesh_k.hpp b/src/libcpp/aabb_tree/aabb_mesh_k.hpp index c1f7d5d..08b1f1d 100644 --- a/src/libcpp/aabb_tree/aabb_mesh_k.hpp +++ b/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/src/libcpp/aabb_tree/aabb_pred_k.hpp b/src/libcpp/aabb_tree/aabb_pred_k.hpp index 56e57a0..729795c 100644 --- a/src/libcpp/aabb_tree/aabb_pred_k.hpp +++ b/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/src/libcpp/aabb_tree/aabb_tree_k.hpp b/src/libcpp/aabb_tree/aabb_tree_k.hpp index 3a393ee..62db444 100644 --- a/src/libcpp/aabb_tree/aabb_tree_k.hpp +++ b/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/src/libcpp/aabb_tree/aabb_type_k.hpp b/src/libcpp/aabb_tree/aabb_type_k.hpp index 0c857d1..dd8cd43 100644 --- a/src/libcpp/aabb_tree/aabb_type_k.hpp +++ b/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/src/libcpp/aabbtree.hpp b/src/libcpp/aabbtree.hpp index deac021..52deac5 100644 --- a/src/libcpp/aabbtree.hpp +++ b/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/src/libcpp/algorithms.hpp b/src/libcpp/algorithms.hpp index def461d..330e328 100644 --- a/src/libcpp/algorithms.hpp +++ b/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/src/libcpp/algorithms/find.hpp b/src/libcpp/algorithms/find.hpp index 7686978..3564454 100644 --- a/src/libcpp/algorithms/find.hpp +++ b/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/src/libcpp/algorithms/sort.hpp b/src/libcpp/algorithms/sort.hpp index f59d4c9..f161c7e 100644 --- a/src/libcpp/algorithms/sort.hpp +++ b/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/src/libcpp/allocators.hpp b/src/libcpp/allocators.hpp index 55a5298..7f7e57a 100644 --- a/src/libcpp/allocators.hpp +++ b/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/src/libcpp/allocators/alloc_base.hpp b/src/libcpp/allocators/alloc_base.hpp index 52eb264..75f3d5c 100644 --- a/src/libcpp/allocators/alloc_base.hpp +++ b/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/src/libcpp/allocators/alloc_item.hpp b/src/libcpp/allocators/alloc_item.hpp index 1ff2744..b9c1727 100644 --- a/src/libcpp/allocators/alloc_item.hpp +++ b/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/src/libcpp/allocators/alloc_pool.hpp b/src/libcpp/allocators/alloc_pool.hpp index 7708ffd..68c839d 100644 --- a/src/libcpp/allocators/alloc_pool.hpp +++ b/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/src/libcpp/allocators/alloc_wrap.hpp b/src/libcpp/allocators/alloc_wrap.hpp index 4aede0f..5eb8404 100644 --- a/src/libcpp/allocators/alloc_wrap.hpp +++ b/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/src/libcpp/libbasic.hpp b/src/libcpp/basebase.hpp similarity index 78% rename from src/libcpp/libbasic.hpp rename to src/libcpp/basebase.hpp index 84769ef..d62e11b 100644 --- a/src/libcpp/libbasic.hpp +++ b/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/src/libcpp/containers.hpp b/src/libcpp/containers.hpp index d14b627..31e6b6f 100644 --- a/src/libcpp/containers.hpp +++ b/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/src/libcpp/containers/array.hpp b/src/libcpp/containers/array.hpp index 6ea55a1..5b89fe7 100644 --- a/src/libcpp/containers/array.hpp +++ b/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/src/libcpp/containers/array_iter.hpp b/src/libcpp/containers/array_iter.hpp index f899577..cf0cb97 100644 --- a/src/libcpp/containers/array_iter.hpp +++ b/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/src/libcpp/containers/arraylist.hpp b/src/libcpp/containers/arraylist.hpp index 6e26d0b..5bf8f9d 100644 --- a/src/libcpp/containers/arraylist.hpp +++ b/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/src/libcpp/containers/basic_stack.hpp b/src/libcpp/containers/basic_stack.hpp index 64ece32..2153dfa 100644 --- a/src/libcpp/containers/basic_stack.hpp +++ b/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/src/libcpp/containers/block_array.hpp b/src/libcpp/containers/block_array.hpp index d97e0bf..35f853e 100644 --- a/src/libcpp/containers/block_array.hpp +++ b/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/src/libcpp/containers/block_iter.hpp b/src/libcpp/containers/block_iter.hpp index 216c845..d658e4a 100644 --- a/src/libcpp/containers/block_iter.hpp +++ b/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/src/libcpp/containers/double_list.hpp b/src/libcpp/containers/double_list.hpp index 8114fa9..56bf71f 100644 --- a/src/libcpp/containers/double_list.hpp +++ b/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/src/libcpp/containers/doubleiter.hpp b/src/libcpp/containers/doubleiter.hpp index 1aebc32..7e3e5c8 100644 --- a/src/libcpp/containers/doubleiter.hpp +++ b/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/src/libcpp/containers/fixed_array.hpp b/src/libcpp/containers/fixed_array.hpp index 2aac51d..9240f71 100644 --- a/src/libcpp/containers/fixed_array.hpp +++ b/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/src/libcpp/containers/hashtable.hpp b/src/libcpp/containers/hashtable.hpp index 37792f4..77af72b 100644 --- a/src/libcpp/containers/hashtable.hpp +++ b/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/src/libcpp/containers/hashtwice.hpp b/src/libcpp/containers/hashtwice.hpp new file mode 100644 index 0000000..d82d64d --- /dev/null +++ b/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/src/libcpp/containers/iter_base.hpp b/src/libcpp/containers/iter_base.hpp index 188677d..6b5f32f 100644 --- a/src/libcpp/containers/iter_base.hpp +++ b/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/src/libcpp/containers/prioritymap.hpp b/src/libcpp/containers/prioritymap.hpp index 48245fb..f54c507 100644 --- a/src/libcpp/containers/prioritymap.hpp +++ b/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/src/libcpp/containers/priorityset.hpp b/src/libcpp/containers/priorityset.hpp index f959c7d..54d9cf1 100644 --- a/src/libcpp/containers/priorityset.hpp +++ b/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/src/libcpp/containers/single_list.hpp b/src/libcpp/containers/single_list.hpp index 7a05208..0e58672 100644 --- a/src/libcpp/containers/single_list.hpp +++ b/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/src/libcpp/containers/singleiter.hpp b/src/libcpp/containers/singleiter.hpp index 5919ed9..3a681de 100644 --- a/src/libcpp/containers/singleiter.hpp +++ b/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/src/libcpp/expansion/dd_float.hpp b/src/libcpp/expansion/dd_float.hpp new file mode 100644 index 0000000..d53e547 --- /dev/null +++ b/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/src/libcpp/expansion/ia_float.hpp b/src/libcpp/expansion/ia_float.hpp new file mode 100644 index 0000000..341b6a5 --- /dev/null +++ b/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/src/libcpp/expansion/mp_basic.hpp b/src/libcpp/expansion/mp_basic.hpp new file mode 100644 index 0000000..684d3cb --- /dev/null +++ b/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/src/libcpp/expansion/mp_float.hpp b/src/libcpp/expansion/mp_float.hpp new file mode 100644 index 0000000..e04fb98 --- /dev/null +++ b/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/src/libcpp/expansion/mp_utils.hpp b/src/libcpp/expansion/mp_utils.hpp new file mode 100644 index 0000000..36f3b0c --- /dev/null +++ b/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/src/libcpp/geom_base/tria_ball_k.hpp b/src/libcpp/geom_base/cell_ball_k.hpp similarity index 89% rename from src/libcpp/geom_base/tria_ball_k.hpp rename to src/libcpp/geom_base/cell_ball_k.hpp index 3ba816b..d54da66 100644 --- a/src/libcpp/geom_base/tria_ball_k.hpp +++ b/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/src/libcpp/geom_base/tria_elem_k.hpp b/src/libcpp/geom_base/cell_base_k.hpp similarity index 51% rename from src/libcpp/geom_base/tria_elem_k.hpp rename to src/libcpp/geom_base/cell_base_k.hpp index 9f02dce..1ba51ed 100644 --- a/src/libcpp/geom_base/tria_elem_k.hpp +++ b/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/src/libcpp/geom_base/intersect_k.hpp b/src/libcpp/geom_base/intersect_k.hpp index b1e2238..0d74eee 100644 --- a/src/libcpp/geom_base/intersect_k.hpp +++ b/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/src/libcpp/geom_base/predicate_k.hpp b/src/libcpp/geom_base/predicate_k.hpp deleted file mode 100644 index 3423723..0000000 --- a/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/src/libcpp/geom_base/vect_base_k.hpp b/src/libcpp/geom_base/vect_base_k.hpp index cf238be..cb979ba 100644 --- a/src/libcpp/geom_base/vect_base_k.hpp +++ b/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/src/libcpp/geom_type/geom_base_2.hpp b/src/libcpp/geom_type/geom_base_2.hpp index 31cbf64..886e29c 100644 --- a/src/libcpp/geom_type/geom_base_2.hpp +++ b/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/src/libcpp/geom_type/geom_base_3.hpp b/src/libcpp/geom_type/geom_base_3.hpp index cce2882..7adea5e 100644 --- a/src/libcpp/geom_type/geom_base_3.hpp +++ b/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/src/libcpp/geom_type/geom_mesh_ellipsoid_3.hpp b/src/libcpp/geom_type/geom_mesh_ellipsoid_3.hpp index a69095d..5ef4ff0 100644 --- a/src/libcpp/geom_type/geom_mesh_ellipsoid_3.hpp +++ b/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/src/libcpp/geom_type/geom_mesh_euclidean_2.hpp b/src/libcpp/geom_type/geom_mesh_euclidean_2.hpp index 223ae2f..b1da6f5 100644 --- a/src/libcpp/geom_type/geom_mesh_euclidean_2.hpp +++ b/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/src/libcpp/geom_type/geom_mesh_euclidean_3.hpp b/src/libcpp/geom_type/geom_mesh_euclidean_3.hpp index c1d5095..5cf35db 100644 --- a/src/libcpp/geom_type/geom_mesh_euclidean_3.hpp +++ b/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/src/libcpp/geometry.hpp b/src/libcpp/geometry.hpp index ccf9e75..56a2124 100644 --- a/src/libcpp/geometry.hpp +++ b/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/src/libcpp/geompred.hpp b/src/libcpp/geompred.hpp new file mode 100644 index 0000000..d4965a6 --- /dev/null +++ b/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/src/libcpp/geomtype.hpp b/src/libcpp/geomtype.hpp index 5448638..4722cef 100644 --- a/src/libcpp/geomtype.hpp +++ b/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/src/libcpp/hashfunc.hpp b/src/libcpp/hashfunc.hpp index d412de7..65b164a 100644 --- a/src/libcpp/hashfunc.hpp +++ b/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/src/libcpp/iter_mesh/iter_divs_2.inc b/src/libcpp/iter_mesh/iter_divs_2.inc index bab7e56..ca684b7 100644 --- a/src/libcpp/iter_mesh/iter_divs_2.inc +++ b/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/src/libcpp/iter_mesh/iter_divs_3.inc b/src/libcpp/iter_mesh/iter_divs_3.inc index 7a417e1..5eba1ae 100644 --- a/src/libcpp/iter_mesh/iter_divs_3.inc +++ b/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/src/libcpp/iter_mesh/iter_dual_2.inc b/src/libcpp/iter_mesh/iter_dual_2.inc index 9b9d868..3c2b6d0 100644 --- a/src/libcpp/iter_mesh/iter_dual_2.inc +++ b/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/src/libcpp/iter_mesh/iter_dual_3.inc b/src/libcpp/iter_mesh/iter_dual_3.inc index bcd80a9..5d85728 100644 --- a/src/libcpp/iter_mesh/iter_dual_3.inc +++ b/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/src/libcpp/iter_mesh/iter_flip_2.inc b/src/libcpp/iter_mesh/iter_flip_2.inc index 8edc2cb..821c9b3 100644 --- a/src/libcpp/iter_mesh/iter_flip_2.inc +++ b/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/src/libcpp/iter_mesh/iter_flip_3.inc b/src/libcpp/iter_mesh/iter_flip_3.inc index 2dbbc67..5fea529 100644 --- a/src/libcpp/iter_mesh/iter_flip_3.inc +++ b/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/src/libcpp/iter_mesh/iter_mesh_2.hpp b/src/libcpp/iter_mesh/iter_mesh_2.hpp index a44e3e9..aca69ec 100644 --- a/src/libcpp/iter_mesh/iter_mesh_2.hpp +++ b/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/src/libcpp/iter_mesh/iter_mesh_3.hpp b/src/libcpp/iter_mesh/iter_mesh_3.hpp index b8951e5..6db6b79 100644 --- a/src/libcpp/iter_mesh/iter_mesh_3.hpp +++ b/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/src/libcpp/iter_mesh/iter_mesh_euclidean_2.hpp b/src/libcpp/iter_mesh/iter_mesh_euclidean_2.hpp index 4148e99..3087dd2 100644 --- a/src/libcpp/iter_mesh/iter_mesh_euclidean_2.hpp +++ b/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/src/libcpp/iter_mesh/iter_mesh_euclidean_3.hpp b/src/libcpp/iter_mesh/iter_mesh_euclidean_3.hpp index c3dc972..856ed0c 100644 --- a/src/libcpp/iter_mesh/iter_mesh_euclidean_3.hpp +++ b/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/src/libcpp/iter_mesh/iter_node_1.inc b/src/libcpp/iter_mesh/iter_node_1.inc index a993f98..2d4b86c 100644 --- a/src/libcpp/iter_mesh/iter_node_1.inc +++ b/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/src/libcpp/iter_mesh/iter_node_2.inc b/src/libcpp/iter_mesh/iter_node_2.inc index 8917dbe..e5ab0c6 100644 --- a/src/libcpp/iter_mesh/iter_node_2.inc +++ b/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 - ::epsilon(), +.25) ; - - __unreferenced(_hfun); - __unreferenced(_pred); // for MSVC... - - /*------------------ calc. local characteristic scale */ - real_type _qmin = - +std::numeric_limits - ::infinity(); + ::epsilon(), .25) ; - real_type _bmin[_dims] = { - +std::numeric_limits - ::infinity() - } ; - real_type _bmax[_dims] = { - -std::numeric_limits - ::infinity() - } ; - - iptr_type _tnum = +0 ; - - _ladj = (real_type)0.; - - real_type _dqdx[_dims] = { - (real_type) +0.0 } ; + /*------------------------------------- cell indexing */ + auto _ppos = &_node->pval(0); - real_type _save [_dims] ; - for (auto _idim = _dims; _idim-- != +0; ) - { - _save[_idim] = - _node->pval(_idim) ; - } + auto _qptr = + _mesh. quad().head() + _cell ; - for (auto _tria = _tset.head(), - _tend = _tset.tend(); - _tria != _tend; - ++_tria, ++_tnum) + for (auto _idim = + pred_type::geom_dims; _idim-- != +0; ) { - auto _tptr = - _mesh._set3.head()+*_tria ; + /*------------------ local iter. on finite-diff. step */ + real_type _binc = _bmax[_idim] - + _bmin[_idim] ; - iptr_type _tnod[3] ; - _tnod[ 0] = _tptr->node( 0) ; - _tnod[ 1] = _tptr->node( 1) ; - _tnod[ 2] = _tptr->node( 2) ; + real_type _hdel = _HINC*_binc; - algorithms::isort( - &_tnod[0], &_tnod[3], - std::less()) ; + real_type _hsum = (real_type)0.; - auto _inod = - _mesh._set1.head()+_tnod[0] ; - auto _jnod = - _mesh._set1.head()+_tnod[1] ; - auto _knod = - _mesh._set1.head()+_tnod[2] ; - - _qmin = std::min( - _qmin, _cost[_tnum]) ; + real_type _sdel = (real_type)0.; + real_type _sabs = (real_type)0.; + real_type _sbar = (real_type)0.; - real_type _pmid[_dims] = { - (real_type) +0.0 } ; - - for (auto _idim = _dims; _idim-- != +0; ) + for (auto _iter = +0; _iter++ != +2; ) + { + /*------------------ 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::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::cell_kind () + ) ; + + _ppos[_idim] = + _SAVE[_idim] - _hdel; + + _hsum -= + _ppos[_idim] - _SAVE[_idim]; + + 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::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.) + { + if (_sabs > _RMAX * _sbar) { - _pmid[_idim] += - _inod->pval(_idim) ; - _pmid[_idim] += - _jnod->pval(_idim) ; - _pmid[_idim] += - _knod->pval(_idim) ; + _hdel/= (real_type) +10. ; } - for (auto _idim = _dims; _idim-- != +0; ) + else + if (_sabs < _RMIN * _sbar) { - _pmid[_idim] - /= (real_type) +3. ; + _hdel*= (real_type) +10. ; + } + else { break ; } } + else { break ; } + } - for (auto _idim = _dims; _idim-- != +0; ) - { - _bmin[_idim] = std::min( - _bmin[_idim], - _pmid[_idim]) ; + _ppos[_idim] = _SAVE [_idim]; - _bmax[_idim] = std::max( - _bmax[_idim], - _pmid[_idim]) ; - } + /*------------------ finalise gradient and accumulate */ - real_type _lsqr = - _pred.length_sq ( - _pmid, &_node->pval(0)) ; + _DQDX[_idim] += _sdel / _hsum ; - _ladj += _lsqr ; } + } - _ladj = std::sqrt (_ladj/_tnum) ; + /* + -------------------------------------------------------- + * DQDX-MOVE: "local-ascent" node movement vector. + -------------------------------------------------------- + */ - /*------------------ adj. gradients w.r.t. W: dQ / dw */ - real_type _qbar , _qlow ; - _qbar = (real_type) +1. ; - _qlow = (real_type) +0. ; + // Shift vertex via gradients of quality functions - iptr_type _lnum = +0 ; - iptr_type _hnum = +1 ; + // xnew <=== xold + beta * BEST[ d./dx Q(x,w)|_i ] - real_type _qlim = _qmin + - (real_type) +1.0E-002 ; + template < + typename node_iter + > + __static_call + __normal_call void_type dqdx_move_2 ( + mesh_type &_mesh , + conn_list &_conn , + node_iter _node , + real_list &_cost , + real_type *_line , + real_type &_ladj + ) + { + iptr_type static constexpr + _last = pred_type::geom_dims + 0 ; - _tnum = (iptr_type) +0 ; - for (auto _tria = _tset.head() , - _tend = _tset.tend() ; - _tria != _tend; - ++_tria, ++_tnum) + real_type static const _HINC = + std::pow(std::numeric_limits + ::epsilon(), .50) ; + + _ladj = (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]; + _qmin = std::min( + _qmin, _cost [_cnum]) ; - /*-------------- only do gradients for 'poor' set */ - if (_qtri <= _qlim) + if (_kind == TRIA3_tag) { - for (auto _idim = _dims ; - _idim-- != 0; ) - { - /*---------- local iter. on finite-diff. step */ - real_type _binc = _bmax[_idim] - - _bmin[_idim] ; + halo_tri3_k(_mesh, + _cell , _node, _bmin, _bmax, + _ladj ) ; + } + else + if (_kind == QUAD4_tag) + { + halo_quad_k(_mesh, + _cell , _node, _bmin, _bmax, + _ladj ) ; + } + } - real_type _hdel = _HINC*_binc; + _ladj = std::sqrt (_ladj / _cnum) ; - real_type _hsum = (real_type)0.; + /*------------------ adj. gradients wrt. pos: dQ / dx */ + real_type _qlim = _qmin + + (real_type) +1.0E-002 ; - real_type _sdel = (real_type)0.; - real_type _sabs = (real_type)0.; - real_type _sbar = (real_type)0.; + real_type _DQDX[_last] = { + (real_type) +0.0E+000} ; - for (auto _iter = +0; _iter++ != +2; ) - { + real_type _qbar = (real_type) 1.; + real_type _qlow = (real_type) 0.; - /*------ centred finite-diff. for dQ / dw */ - _node->pval(_idim) = - _save[_idim] + _hdel; - - _hsum = (real_type)0. ; - _hsum += _node-> - pval(_idim) - _save[_idim] ; - - real_type _scr1 = - _pred .cost_tria ( - &_mesh._set1[ - _tptr->node(0)].pval(0), - &_mesh._set1[ - _tptr->node(1)].pval(0), - &_mesh._set1[ - _tptr->node(2)].pval(0) - ) ; - - _node->pval(_idim) = - _save[_idim] - _hdel; - - _hsum -= _node-> - pval(_idim) - _save[_idim] ; - - real_type _scr0 = - _pred .cost_tria ( - &_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(_idim) - = _save[_idim] ; - - /*------ try to adjust step on rel. diff. */ - if (_sabs > (real_type)0.) - { - if (_sabs > _RMAX * _sbar) - { - _hdel *= - (real_type) +.10 ; - } - else - if (_sabs < _RMIN * _sbar) - { - _hdel *= - (real_type) +10. ; - } - else { break ; } - } - else { break ; } - } + real_type _SAVE[_last] ; + for (auto _idim = + pred_type::geom_dims; _idim-- != +0; ) + { + _SAVE[_idim] = + _node->pval(_idim) ; + } - /*---------- finalise gradient and accumulate */ - _dqdx[_idim]+= _sdel / _hsum ; + 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 ; + auto _COST = _cost [_nnum]; + + if (_COST <= _qlim) + { + if (_kind == TRIA3_tag) + { + dqdx_tri3_k(_mesh, _cell, + _node , _COST, _bmin, _bmax, + _SAVE , _DQDX) ; + } + else + if (_kind == QUAD4_tag) + { + dqdx_quad_k(_mesh, _cell, + _node , _COST, _bmin, _bmax, + _SAVE , _DQDX) ; } - _qlow += _qtri ; _lnum += +1 ; + _qlow += _COST ; _lnum += +1 ; } else { - /*---------- accumulate metrics in 'good' set */ - _qbar += _qtri ; _hnum += +1 ; + _qbar += _COST ; _hnum += +1 ; } } if (_lnum > +0) { - for (auto _idim = _dims; _idim-- != +0; ) + for (auto _idim = + pred_type::geom_dims; _idim-- != +0; ) { - _dqdx[_idim] /= _lnum ; + _DQDX[_idim] /= _lnum ; } _qlow /= _lnum ; @@ -689,11 +1320,12 @@ /*------------------ 1st ord. Taylor-series step est. */ real_type _scal = - std::sqrt(_pred.length_sq(_dqdx)) ; + std::sqrt (pred_type::length_sq(_DQDX)); if (_scal*_ladj <= _HINC) { - for (auto _idim = _dims; _idim-- != +0; ) + for (auto _idim = + pred_type::geom_dims; _idim-- != +0; ) { _line[_idim] = (real_type) +0. ; @@ -701,20 +1333,21 @@ } else { - for (auto _idim = _dims; _idim-- != +0; ) + for (auto _idim = + pred_type::geom_dims; _idim-- != +0; ) { _line[_idim] = - _dqdx[_idim] / _scal ; + _DQDX[_idim]/ _scal ; } _scal = (_qbar - _qlow) / - _pred .innerprod(_line, _dqdx) ; - - _scal*= (real_type)+.50 ; + pred_type::innerprod(_line, _DQDX) ; - _scal = std::min(_scal, _ladj) ; + _scal = std::min( + _scal / (real_type)2. , _ladj) ; - for (auto _idim = _dims; _idim-- != +0; ) + for (auto _idim = + pred_type::geom_dims; _idim-- != +0; ) { _line[_idim] *= _scal ; } diff --git a/src/libcpp/iter_mesh/iter_node_3.inc b/src/libcpp/iter_mesh/iter_node_3.inc index ca9a08b..84f795e 100644 --- a/src/libcpp/iter_mesh/iter_node_3.inc +++ b/src/libcpp/iter_mesh/iter_node_3.inc @@ -35,7 +35,7 @@ * * Copyright 2013-2018 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- @@ -44,450 +44,4 @@ // from iter_mesh_k.hpp - /* - -------------------------------------------------------- - * _ODT-MOVE: optimal delaunay tessellation update. - -------------------------------------------------------- - */ - - // Shift node to weighted mean of adj. dual vertex - // positions... - - // xnew = xold + SUM(|t_i|_r * c_i) / SUM(|t_i|_r) - // - // where |t_i|_r = INT|i rho(x) dA - // - // ~ |t_i| / (h_i)^2 - - template < - typename node_iter - > - __static_call - __normal_call void_type _odt_move_3 ( - mesh_type &_mesh , - size_type &_hfun , - pred_type &_pred , - real_list &_hval , - iptr_list &_tset , - node_iter _node , - real_type *_line , - real_type &_ladj - ) - { - real_type _move[_dims] = { - (real_type) +0.0 } ; - - _ladj = - (real_type) +0.0 ; - - __unreferenced (_pred) ; // for MSVC... - - real_type _wsum = - +std::numeric_limits::epsilon() ; - - iptr_type _tnum = +0 ; - - for (auto _tria = _tset.head() , - _tend = _tset.tend() ; - _tria != _tend ; - ++_tria, ++_tnum ) - { - auto _tptr = - _mesh._set4.head()+*_tria ; - - iptr_type _tnod[4] ; - _tnod[ 0] = _tptr->node( 0) ; - _tnod[ 1] = _tptr->node( 1) ; - _tnod[ 2] = _tptr->node( 2) ; - _tnod[ 3] = _tptr->node( 3) ; - - auto _inod = - _mesh._set1.head()+_tnod[0] ; - auto _jnod = - _mesh._set1.head()+_tnod[1] ; - auto _knod = - _mesh._set1.head()+_tnod[2] ; - auto _lnod = - _mesh._set1.head()+_tnod[3] ; - - real_type _ball [_dims + 1] ; - _pred.perp_ball (_ball , - &_inod->pval(0), - &_jnod->pval(0), - &_knod->pval(0), - &_lnod->pval(0), true) ; - - real_type _tmag = - _pred.mass_tria ( - &_inod->pval(0), - &_jnod->pval(0), - &_knod->pval(0) - &_lnod->pval(0) ) ; - - if (_hval[_tnod[0]] < (real_type)+0.) - { - _hval[_tnod[0]] = _hfun.eval ( - &_inod->pval(0) , - _inod->hidx()) ; - } - - if (_hval[_tnod[1]] < (real_type)+0.) - { - _hval[_tnod[1]] = _hfun.eval ( - &_jnod->pval(0) , - _jnod->hidx()) ; - } - - if (_hval[_tnod[2]] < (real_type)+0.) - { - _hval[_tnod[2]] = _hfun.eval ( - &_knod->pval(0) , - _knod->hidx()) ; - } - - if (_hval[_tnod[3]] < (real_type)+0.) - { - _hval[_tnod[3]] = _hfun.eval ( - &_knod->pval(0) , - _knod->hidx()) ; - } - - real_type _tsqr = std::max( - (real_type) +0., _ball[_dims]); - - 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]] ; - real_type _lrho = (real_type)+1. - / _hval[_tnod[3]] ; - - _irho = _irho * _irho ; - _jrho = _jrho * _jrho ; - _krho = _krho * _krho ; - _lrho = _lrho * _lrho ; - - real_type _rbar = - (_irho+_jrho+_krho+_lrho) / (real_type)4. ; - - real_type _wval = _tmag* _rbar ; - - for (auto _idim = _dims; _idim-- != +0; ) - { - _move[_idim] - += _wval * _ball [_idim] ; - } - - _wsum += _wval ; - _ladj += _tsqr ; - } - - if (_tnum > +0) - { - for (auto _idim = _dims; _idim-- != +0; ) - { - _line[_idim] = - _move[_idim] / _wsum - - _node->pval(_idim) ; - } - - _ladj = std::sqrt(_ladj / _tnum) ; - } - - } - - /* - -------------------------------------------------------- - * GRAD-MOVE: "local-ascent" node movement vector. - -------------------------------------------------------- - */ - - template < - typename node_iter - > - __static_call - __normal_call void_type grad_move_3 ( - 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 _HINC = - 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(_hfun); - __unreferenced(_pred); // for MSVC... - - iptr_type _tnum = +0 ; - - _ladj = (real_type)0.; - - real_type _bmin[_dims] = { - +std::numeric_limits - ::infinity() - } ; - real_type _bmax[_dims] = { - -std::numeric_limits - ::infinity() - } ; - - real_type _dqdx[_dims] = { - (real_type) +0.0 } ; - - real_type _save [_dims] ; - for (auto _idim = _dims; _idim-- != +0; ) - { - _save[_idim] = - _node->pval(_idim) ; - } - - 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 _pmid[_dims] = { - (real_type) +0.0 } ; - - for (auto _idim = _dims; _idim-- != +0; ) - { - _pmid[_idim] += - _inod->pval(_idim) ; - _pmid[_idim] += - _jnod->pval(_idim) ; - _pmid[_idim] += - _knod->pval(_idim) ; - _pmid[_idim] += - _lnod->pval(_idim) ; - } - for (auto _idim = _dims; _idim-- != +0; ) - { - _pmid[_idim] - /= (real_type) +4. ; - } - - for (auto _idim = _dims; _idim-- != +0; ) - { - _bmin[_idim] = std::min( - _bmin[_idim], - _pmid[_idim]) ; - - _bmax[_idim] = std::max( - _bmax[_idim], - _pmid[_idim]) ; - } - - real_type _llen = - std::sqrt(_pred.length_sq ( - _pmid, &_node->pval(0))) ; - - _ladj += _llen ; - } - - 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 ; - - _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]; - - if (_qtri <= _qlim) - { - for (auto _idim = _dims ; - _idim-- != 0; ) - { - real_type _binc = _bmax[_idim] - - _bmin[_idim] ; - - real_type _hdel = _HINC*_binc; - - real_type _hsum = (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++ != +8; ) - { - _node->pval(_idim) = - _save[_idim] + _hdel; - - _hsum = (real_type)0. ; - _hsum += _node-> - pval(_idim) - _save[_idim] ; - - real_type _scr1 = - _pred .cost_tria ( - &_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(_idim) = - _save[_idim] - _hdel; - - _hsum -= _node-> - pval(_idim) - _save[_idim] ; - - real_type _scr0 = - _pred .cost_tria ( - &_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(_idim) - = _save[_idim] ; - - if (_sabs > (real_type)0.) - { - if (_sabs > _RMAX * _sbar) - { - _hdel *= - (real_type) +.10 ; - } - else - if (_sabs < _RMIN * _sbar) - { - _hdel *= - (real_type) +10. ; - } - else { break ; } - } - else { break ; } - } - - _dqdx[_idim]+= _sdel / _hsum ; - - } - - _qlow += _qtri ; _lnum += +1 ; - - } - else - { - _qbar += _qtri ; _hnum += +1 ; - } - } - - if (_tnum > +0) - { - for (auto _idim = _dims; _idim-- != +0; ) - { - _dqdx[_idim] /= _lnum ; - } - - _qlow /= _lnum ; - _ladj /= _tnum ; - } - - if (_hnum > +0) - { - _qbar /= _hnum ; - } - - real_type _scal = - std::sqrt(_pred.length_sq(_dqdx)) ; - - if (_scal <= _ZERO * _ladj) - { - for (auto _idim = _dims; _idim-- != +0; ) - { - _line[_idim] - = (real_type) +0. ; - } - } - else - { - for (auto _idim = _dims; _idim-- != +0; ) - { - _line[_idim] = - _dqdx[_idim] / _scal ; - } - - _scal = (_qbar - _qlow) / - _pred .length_sq(_line, _dqdx) ; - - _scal = std::min(_scal, _ladj) ; - - for (auto _idim = _dims; _idim-- != +0; ) - { - _line[_idim] *= _scal ; - } - } - - } - - diff --git a/src/libcpp/iter_mesh/iter_pred_ellipsoid_3.hpp b/src/libcpp/iter_mesh/iter_pred_ellipsoid_3.hpp index 3e1fee3..a8be9e2 100644 --- a/src/libcpp/iter_mesh/iter_pred_ellipsoid_3.hpp +++ b/src/libcpp/iter_mesh/iter_pred_ellipsoid_3.hpp @@ -1,7 +1,7 @@ /* -------------------------------------------------------- - * ITER-PRED-ELLIPSOID-3: predicates for MESH-ITER-2. + * ITER-PRED-ELLIPSOID-3: predicates for ITER-MESH-k. -------------------------------------------------------- * * This program may be freely redistributed under the @@ -31,11 +31,11 @@ * -------------------------------------------------------- * - * Last updated: 23 November, 2018 + * Last updated: 26 July, 2020 * - * Copyright 2013-2018 + * Copyright 2013-2020 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- @@ -48,107 +48,34 @@ namespace mesh { - //_pred.vnrm(); - //_pred.vcos(); - - template < - typename R , - typename I + typename G , + typename M > class iter_pred_ellipsoid_3d { +/*------------------------ optimisation predicates in S^2 */ public : - typedef R real_type ; - typedef I iptr_type ; + typedef G geom_type ; + typedef M mesh_type ; - iptr_type static constexpr _dims = +3 ; + typedef typename + mesh_type::real_type real_type ; + typedef typename + mesh_type::iptr_type iptr_type ; - public : + struct cell_kind {}; + struct dual_kind {}; - __static_call - __inline_call real_type mass_tria ( - __const_ptr(real_type) _ipos , - __const_ptr(real_type) _jpos , - __const_ptr(real_type) _kpos - ) - { return geometry - ::tria_area_3d ( - _ipos, _jpos, _kpos) ; - } + iptr_type static + constexpr topo_dims = +2 ; + iptr_type static + constexpr geom_dims = +3 ; + iptr_type static + constexpr real_dims = +4 ; - __static_call - __inline_call void_type circ_ball ( - __write_ptr(real_type) _ball , - __const_ptr(real_type) _ipos , - __const_ptr(real_type) _jpos , - bool_type _bind = false - ) - { return geometry - ::circ_ball_3d ( - _ball, _ipos, _jpos, _bind) ; - } - - __static_call - __inline_call void_type circ_ball ( - __write_ptr(real_type) _ball , - __const_ptr(real_type) _ipos , - __const_ptr(real_type) _jpos , - __const_ptr(real_type) _kpos , - bool_type _bind = false - ) - { return geometry - ::circ_ball_3d ( - _ball, _ipos, _jpos, _kpos, _bind) ; - } - - __static_call - __inline_call void_type perp_ball ( - __write_ptr(real_type) _ball , - __const_ptr(real_type) _ipos , - __const_ptr(real_type) _jpos , - bool_type _bind = false - ) - { return geometry - ::perp_ball_3d ( - _ball, _ipos, _jpos, _bind) ; - } - - __static_call - __inline_call void_type perp_ball ( - __write_ptr(real_type) _ball , - __const_ptr(real_type) _ipos , - __const_ptr(real_type) _jpos , - __const_ptr(real_type) _kpos , - bool_type _bind = false - ) - { return geometry - ::perp_ball_3d ( - _ball, _ipos, _jpos, _kpos, _bind) ; - } - - __static_call - __inline_call real_type cost_tria ( - __const_ptr(real_type) _ipos , - __const_ptr(real_type) _jpos , - __const_ptr(real_type) _kpos - ) - { return geometry - ::tria_quality_3d ( - _ipos, _jpos, _kpos) ; - } - - __static_call - __inline_call real_type cost_dual ( - __const_ptr(real_type) _ipos , - __const_ptr(real_type) _jpos , - __const_ptr(real_type) _kpos - ) - { return geometry - ::dual_quality_3d ( - _ipos, _jpos, _kpos) ; - } + public : __static_call __inline_call real_type innerprod ( @@ -176,9 +103,6 @@ geometry::lensqr_3d (_vvec) ; } - template < - typename geom_type - > __static_call __inline_call void_type proj_node ( geom_type &_geom , @@ -217,25 +141,163 @@ if (_ttaa > (real_type)-1.) { _proj[0] = - _pmid[0] + _ttaa*_pdel[0] ; + _pmid[0] + _ttaa*_pdel[ 0] ; _proj[1] = - _pmid[1] + _ttaa*_pdel[1] ; + _pmid[1] + _ttaa*_pdel[ 1] ; _proj[2] = - _pmid[2] + _ttaa*_pdel[2] ; + _pmid[2] + _ttaa*_pdel[ 2] ; } else if (_ttbb > (real_type)-1.) { _proj[0] = - _pmid[0] + _ttbb*_pdel[0] ; + _pmid[0] + _ttbb*_pdel[ 0] ; _proj[1] = - _pmid[1] + _ttbb*_pdel[1] ; + _pmid[1] + _ttbb*_pdel[ 1] ; _proj[2] = - _pmid[2] + _ttbb*_pdel[2] ; + _pmid[2] + _ttbb*_pdel[ 2] ; } } } + __static_call + __inline_call real_type tri3_mass ( + __const_ptr(real_type) _ipos , + __const_ptr(real_type) _jpos , + __const_ptr(real_type) _kpos + ) + { + return geometry::tria_area_3d ( + &_ipos[0] , + &_jpos[0] , + &_kpos[0] ) ; + } + + __static_call + __inline_call real_type quad_mass ( + __const_ptr(real_type) _ipos , + __const_ptr(real_type) _jpos , + __const_ptr(real_type) _kpos , + __const_ptr(real_type) _lpos + ) + { + return geometry::quad_area_3d ( + &_ipos[0] , + &_jpos[0] , + &_kpos[0] , + &_lpos[0] ) ; + } + + __static_call + __inline_call void_type edge_ball ( + __write_ptr(real_type) _ball , + __const_ptr(real_type) _ipos , + __const_ptr(real_type) _jpos , + bool_type _bind = false + ) + { + return geometry::perp_ball_3d ( + &_ball[0], + &_ipos[0], + &_jpos[0], _bind) ; + } + + __static_call + __inline_call void_type tri3_ball ( + __write_ptr(real_type) _ball , + __const_ptr(real_type) _ipos , + __const_ptr(real_type) _jpos , + __const_ptr(real_type) _kpos , + bool_type _bind = false + ) + { + return geometry::perp_ball_3d ( + &_ball[0], + &_ipos[0], + &_jpos[0], + &_kpos[0], _bind) ; + } + + __static_call + __inline_call void_type quad_ball ( + __write_ptr(real_type) _ball , + __const_ptr(real_type) _ipos , + __const_ptr(real_type) _jpos , + __const_ptr(real_type) _kpos , + __const_ptr(real_type) _lpos , + bool_type _bind = false + ) + { + return geometry::quad_ball_3d ( + &_ball[0], + &_ipos[0], + &_jpos[0], + &_kpos[0], + &_lpos[0], _bind) ; + } + + __static_call + __inline_call real_type tri3_cost ( + __const_ptr(real_type) _ipos , + __const_ptr(real_type) _jpos , + __const_ptr(real_type) _kpos , + cell_kind const& + ) + { + return geometry::tria_quality_3d ( + &_ipos[0] , + &_jpos[0] , + &_kpos[0] ) ; + } + + __static_call + __inline_call real_type tri3_cost ( + __const_ptr(real_type) _ipos , + __const_ptr(real_type) _jpos , + __const_ptr(real_type) _kpos , + dual_kind const& + ) + { + return geometry::tria_duality_3d ( + &_ipos[0] , + &_jpos[0] , + &_kpos[0] ) ; + } + + __static_call + __inline_call real_type quad_cost ( + __const_ptr(real_type) _ipos , + __const_ptr(real_type) _jpos , + __const_ptr(real_type) _kpos , + __const_ptr(real_type) _lpos , + cell_kind const& + ) + { + return geometry::quad_quality_3d ( + &_ipos[0] , + &_jpos[0] , + &_kpos[0] , + &_lpos[0] ) ; + } + + __static_call + __inline_call real_type quad_cost ( + __const_ptr(real_type) /*_ipos*/ , + __const_ptr(real_type) /*_jpos*/ , + __const_ptr(real_type) /*_kpos*/ , + __const_ptr(real_type) /*_lpos*/ , + dual_kind const& + ) + { /* + return geometry::quad_duality_3d ( + &_ipos[0] , + &_jpos[0] , + &_kpos[0] , + &_lpos[0] ) ; + */ + return (real_type) +1. ; + } + } ; diff --git a/src/libcpp/iter_mesh/iter_pred_euclidean_2.hpp b/src/libcpp/iter_mesh/iter_pred_euclidean_2.hpp index 3a0a2eb..01f356b 100644 --- a/src/libcpp/iter_mesh/iter_pred_euclidean_2.hpp +++ b/src/libcpp/iter_mesh/iter_pred_euclidean_2.hpp @@ -1,7 +1,7 @@ /* -------------------------------------------------------- - * ITER-PRED-EUCLIDEAN-2: predicates for MESH-ITER-2. + * ITER-PRED-EUCLIDEAN-2: predicates for ITER-MESH-k. -------------------------------------------------------- * * This program may be freely redistributed under the @@ -31,11 +31,11 @@ * -------------------------------------------------------- * - * Last updated: 23 November, 2018 + * Last updated: 26 July, 2020 * - * Copyright 2013-2018 + * Copyright 2013-2020 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- @@ -48,153 +48,215 @@ namespace mesh { - //_pred.vnrm(); - //_pred.vcos(); - - template < - typename R , - typename I + typename G , + typename M > class iter_pred_euclidean_2d { +/*------------------------ optimisation predicates in E^2 */ public : - typedef R real_type ; - typedef I iptr_type ; - iptr_type static constexpr _dims = +2 ; + typedef G geom_type ; + typedef M mesh_type ; + + typedef typename + mesh_type::real_type real_type ; + typedef typename + mesh_type::iptr_type iptr_type ; + + struct cell_kind {}; + struct dual_kind {}; + + iptr_type static + constexpr topo_dims = +2 ; + iptr_type static + constexpr geom_dims = +2 ; + iptr_type static + constexpr real_dims = +3 ; public : __static_call - __inline_call real_type mass_tria ( - __const_ptr(real_type) _ipos , - __const_ptr(real_type) _jpos , - __const_ptr(real_type) _kpos + __inline_call real_type innerprod ( + __const_ptr(real_type) _avec , + __const_ptr(real_type) _bvec ) { return geometry - ::tria_area_2d ( - _ipos, _jpos, _kpos) ; + ::dot_2d (_avec, _bvec) ; } __static_call - __inline_call void_type circ_ball ( - __write_ptr(real_type) _ball , + __inline_call real_type length_sq ( + __const_ptr(real_type) _ipos , + __const_ptr(real_type) _jpos + ) + { return geometry:: + lensqr_2d(_ipos, _jpos) ; + } + + __static_call + __inline_call real_type length_sq ( + __const_ptr(real_type) _vvec + ) + { return + geometry::lensqr_2d (_vvec) ; + } + + __static_call + __inline_call void_type proj_node ( + geom_type &_geom , + real_type *_save , + real_type *_proj + ) + { + __unreferenced (_geom) ; + __unreferenced (_save) ; + __unreferenced (_proj) ; + } + + __static_call + __inline_call real_type tri3_mass ( __const_ptr(real_type) _ipos , __const_ptr(real_type) _jpos , - bool_type _bind = false + __const_ptr(real_type) _kpos ) - { return geometry - ::circ_ball_2d ( - _ball, _ipos, _jpos, _bind) ; + { + return geometry::tria_area_2d ( + &_ipos[0] , + &_jpos[0] , + &_kpos[0] ) ; } __static_call - __inline_call void_type circ_ball ( - __write_ptr(real_type) _ball , + __inline_call real_type quad_mass ( __const_ptr(real_type) _ipos , __const_ptr(real_type) _jpos , __const_ptr(real_type) _kpos , - bool_type _bind = false + __const_ptr(real_type) _lpos ) - { return geometry - ::circ_ball_2d ( - _ball, _ipos, _jpos, _kpos, _bind) ; + { + return geometry::quad_area_2d ( + &_ipos[0] , + &_jpos[0] , + &_kpos[0] , + &_lpos[0] ) ; } __static_call - __inline_call void_type perp_ball ( + __inline_call void_type edge_ball ( __write_ptr(real_type) _ball , __const_ptr(real_type) _ipos , __const_ptr(real_type) _jpos , bool_type _bind = false ) - { return geometry - ::perp_ball_2d ( - _ball, _ipos, _jpos, _bind) ; + { + return geometry::perp_ball_2d ( + &_ball[0], + &_ipos[0], + &_jpos[0], _bind) ; } __static_call - __inline_call void_type perp_ball ( + __inline_call void_type tri3_ball ( __write_ptr(real_type) _ball , __const_ptr(real_type) _ipos , __const_ptr(real_type) _jpos , __const_ptr(real_type) _kpos , bool_type _bind = false ) - { return geometry - ::perp_ball_2d ( - _ball, _ipos, _jpos, _kpos, _bind) ; + { + return geometry::perp_ball_2d ( + &_ball[0], + &_ipos[0], + &_jpos[0], + &_kpos[0], _bind) ; } __static_call - __inline_call real_type cost_tria ( + __inline_call void_type quad_ball ( + __write_ptr(real_type) _ball , __const_ptr(real_type) _ipos , __const_ptr(real_type) _jpos , - __const_ptr(real_type) _kpos + __const_ptr(real_type) _kpos , + __const_ptr(real_type) _lpos , + bool_type _bind = false ) - { return geometry - ::tria_quality_2d ( - _ipos, _jpos, _kpos) ; + { + return geometry::quad_ball_2d ( + &_ball[0], + &_ipos[0], + &_jpos[0], + &_kpos[0], + &_lpos[0], _bind) ; } __static_call - __inline_call real_type cost_dual ( + __inline_call real_type tri3_cost ( __const_ptr(real_type) _ipos , __const_ptr(real_type) _jpos , - __const_ptr(real_type) _kpos - ) - { return geometry - ::dual_quality_2d ( - _ipos, _jpos, _kpos) ; - } - - __static_call - __inline_call real_type innerprod ( - __const_ptr(real_type) _avec , - __const_ptr(real_type) _bvec + __const_ptr(real_type) _kpos , + cell_kind const& ) - { return geometry - ::dot_2d (_avec, _bvec) ; + { + return geometry::tria_quality_2d ( + &_ipos[0] , + &_jpos[0] , + &_kpos[0] ) ; } __static_call - __inline_call real_type length_sq ( + __inline_call real_type tri3_cost ( __const_ptr(real_type) _ipos , - __const_ptr(real_type) _jpos + __const_ptr(real_type) _jpos , + __const_ptr(real_type) _kpos , + dual_kind const& ) - { return geometry:: - lensqr_2d(_ipos, _jpos) ; + { + return geometry::tria_duality_2d ( + &_ipos[0] , + &_jpos[0] , + &_kpos[0] ) ; } __static_call - __inline_call real_type length_sq ( - __const_ptr(real_type) _vvec + __inline_call real_type quad_cost ( + __const_ptr(real_type) _ipos , + __const_ptr(real_type) _jpos , + __const_ptr(real_type) _kpos , + __const_ptr(real_type) _lpos , + cell_kind const& ) - { return - geometry::lensqr_2d (_vvec) ; + { + return geometry::quad_quality_2d ( + &_ipos[0] , + &_jpos[0] , + &_kpos[0] , + &_lpos[0] ) ; } - template < - typename geom_type - > __static_call - __inline_call void_type proj_node ( - geom_type &_geom , - __const_ptr(real_type) _save , - __write_ptr(real_type) _proj + __inline_call real_type quad_cost ( + __const_ptr(real_type) /*_ipos*/ , + __const_ptr(real_type) /*_jpos*/ , + __const_ptr(real_type) /*_kpos*/ , + __const_ptr(real_type) /*_lpos*/ , + dual_kind const& ) - { // R^2: do nothing! - __unreferenced(_geom) ; - __unreferenced(_save) ; - __unreferenced(_proj) ; + { /* + return geometry::quad_duality_2d ( + &_ipos[0] , + &_jpos[0] , + &_kpos[0] , + &_lpos[0] ) ; + */ + return (real_type) +1. ; } } ; } - # endif //__ITER_PRED_EUCLIDEAN_2__ diff --git a/src/libcpp/iter_mesh/iter_pred_euclidean_3.hpp b/src/libcpp/iter_mesh/iter_pred_euclidean_3.hpp deleted file mode 100644 index 0490b51..0000000 --- a/src/libcpp/iter_mesh/iter_pred_euclidean_3.hpp +++ /dev/null @@ -1,241 +0,0 @@ - - /* - -------------------------------------------------------- - * ITER-PRED-EUCLIDEAN-3: predicates for MESH-ITER-3. - -------------------------------------------------------- - * - * 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: 23 November, 2018 - * - * Copyright 2013-2018 - * Darren Engwirda - * de2363@columbia.edu - * https://github.com/dengwirda/ - * - -------------------------------------------------------- - */ - -# pragma once - -# ifndef __ITER_PRED_EUCLIDEAN_3__ -# define __ITER_PRED_EUCLIDEAN_3__ - - namespace mesh { - - //_pred.vnrm(); - //_pred.vcos(); - - - template < - typename R , - typename I - > - class iter_pred_euclidean_3d - { - public : - typedef R real_type ; - typedef I iptr_type ; - - iptr_type static constexpr _dims = +3 ; - - public : - - __static_call - __inline_call real_type mass_tria ( - __const_ptr(real_type) _ipos , - __const_ptr(real_type) _jpos , - __const_ptr(real_type) _kpos - ) - { return geometry - ::tria_area_3d ( - _ipos, _jpos, _kpos) ; - } - - __static_call - __inline_call real_type mass_tria ( - __const_ptr(real_type) _ipos , - __const_ptr(real_type) _jpos , - __const_ptr(real_type) _kpos , - __const_ptr(real_type) _lpos - ) - { return geometry - ::tetra_vol_3d ( - _ipos, _jpos, _kpos, _lpos) ; - } - - __static_call - __inline_call void_type circ_ball ( - __write_ptr(real_type) _ball , - __const_ptr(real_type) _ipos , - __const_ptr(real_type) _jpos , - __const_ptr(real_type) _kpos , - bool_type _bind = false - ) - { return geometry - ::circ_ball_3d ( - _ball, _ipos, _jpos, _kpos, _bind) ; - } - - __static_call - __inline_call void_type circ_ball ( - __write_ptr(real_type) _ball , - __const_ptr(real_type) _ipos , - __const_ptr(real_type) _jpos , - __const_ptr(real_type) _kpos , - __const_ptr(real_type) _lpos , - bool_type _bind = false - ) - { return geometry - ::circ_ball_3d ( _ball, - _ipos, _jpos, _kpos, _lpos, _bind) ; - } - - __static_call - __inline_call void_type perp_ball ( - __write_ptr(real_type) _ball , - __const_ptr(real_type) _ipos , - __const_ptr(real_type) _jpos , - __const_ptr(real_type) _kpos , - bool_type _bind = false - ) - { return geometry - ::perp_ball_3d ( - _ball, _ipos, _jpos, _kpos, _bind) ; - } - - __static_call - __inline_call void_type perp_ball ( - __write_ptr(real_type) _ball , - __const_ptr(real_type) _ipos , - __const_ptr(real_type) _jpos , - __const_ptr(real_type) _kpos , - __const_ptr(real_type) _lpos , - bool_type _bind = false - ) - { return geometry - ::perp_ball_3d ( _ball, - _ipos, _jpos, _kpos, _lpos, _bind) ; - } - - __static_call - __inline_call real_type cost_tria ( - __const_ptr(real_type) _ipos , - __const_ptr(real_type) _jpos , - __const_ptr(real_type) _kpos - ) - { return geometry - ::tria_quality_3d ( - _ipos, _jpos, _kpos) ; - } - - __static_call - __inline_call real_type cost_tria ( - __const_ptr(real_type) _ipos , - __const_ptr(real_type) _jpos , - __const_ptr(real_type) _kpos , - __const_ptr(real_type) _lpos - ) - { return geometry - ::tria_quality_3d ( - _ipos, _jpos, _kpos, _lpos) ; - } - - __static_call - __inline_call real_type cost_dual ( - __const_ptr(real_type) _ipos , - __const_ptr(real_type) _jpos , - __const_ptr(real_type) _kpos - ) - { return geometry - ::dual_quality_3d ( - _ipos, _jpos, _kpos) ; - } - - __static_call - __inline_call real_type cost_dual ( - __const_ptr(real_type) _ipos , - __const_ptr(real_type) _jpos , - __const_ptr(real_type) _kpos , - __const_ptr(real_type) _lpos - ) - { return geometry - ::dual_quality_3d ( - _ipos, _jpos, _kpos, _lpos) ; - } - - __static_call - __inline_call real_type innerprod ( - __const_ptr(real_type) _avec , - __const_ptr(real_type) _bvec - ) - { return geometry - ::dot_3d (_avec, _bvec) ; - } - - __static_call - __inline_call real_type length_sq ( - __const_ptr(real_type) _ipos , - __const_ptr(real_type) _jpos - ) - { return geometry:: - lensqr_3d(_ipos, _jpos) ; - } - - __static_call - __inline_call real_type length_sq ( - __const_ptr(real_type) _vvec - ) - { return - geometry::lensqr_3d (_vvec) ; - } - - template < - typename geom_type - > - __static_call - __inline_call void_type proj_node ( - geom_type &_geom , - __const_ptr(real_type) _save , - __write_ptr(real_type) _proj - ) - { // R^3: to-do! - __unreferenced(_geom) ; - __unreferenced(_save) ; - __unreferenced(_proj) ; - } - - } ; - - } - - -# endif //__ITER_PRED_EUCLIDEAN_3__ - - - diff --git a/src/libcpp/iter_mesh/iter_timers.hpp b/src/libcpp/iter_mesh/iter_timers.hpp index 3720676..0906cc5 100644 --- a/src/libcpp/iter_mesh/iter_timers.hpp +++ b/src/libcpp/iter_mesh/iter_timers.hpp @@ -31,11 +31,11 @@ * -------------------------------------------------------- * - * Last updated: 02 March, 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/ * -------------------------------------------------------- @@ -69,9 +69,10 @@ real_type _iter_full = (real_type) +0. ; - real_type _move_full = (real_type) +0. ; - real_type _topo_full = (real_type) +0. ; - real_type _zips_full = (real_type) +0. ; + real_type _move_node = (real_type) +0. ; + real_type _move_dual = (real_type) +0. ; + real_type _topo_flip = (real_type) +0. ; + real_type _topo_zips = (real_type) +0. ; public : diff --git a/src/libcpp/iter_mesh/iter_zips_2.inc b/src/libcpp/iter_mesh/iter_zips_2.inc index a143f76..c51a702 100644 --- a/src/libcpp/iter_mesh/iter_zips_2.inc +++ b/src/libcpp/iter_mesh/iter_zips_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/ * -------------------------------------------------------- @@ -54,34 +54,39 @@ __normal_call void_type _zip_edge ( geom_type &_geom , mesh_type &_mesh , - size_type &_hfun , - pred_type &_pred , + hfun_type &_hfun , real_list &_hval , iter_opts &_opts , iptr_type _edge , char_type _kern , bool_type &_okay , iptr_type &_nnew , - iptr_list &_iset , - iptr_list &_jset , - iptr_list &_aset , - iptr_list &_bset , - iptr_list &_cset , - real_list &_tsrc , - real_list &_tdst , - real_list &_ttmp , - real_type _TLIM , + conn_list &_iset , + conn_list &_jset , + conn_list &_aset , + conn_list &_bset , + conn_list &_cset , + real_list &_qsrc , + real_list &_qdst , + real_list &_qtmp , + real_type _QLIM , real_type _lmax - = (real_type) +8.25E-01 , + = (real_type) +7.50E-01 , real_type _qinc = (real_type) +1.00E-02 ) { - __unreferenced(_pred) ; // for MSVC... + 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 _eptr = - _mesh._set2.head() + _edge; + _mesh. edge().head()+_edge ; typename mesh_type:: edge_type _edat(*_eptr) ; @@ -91,9 +96,9 @@ _jnod = _eptr->node(1) ; auto _iptr = _mesh. - _set1.head()+ _eptr->node(0); + node().head() + _eptr->node(0); auto _jptr = _mesh. - _set1.head()+ _eptr->node(1); + node().head() + _eptr->node(1); _okay = false ; @@ -103,428 +108,451 @@ _bset.set_count(+0) ; _cset.set_count(+0) ; - _tsrc.set_count(+0) ; - _tdst.set_count(+0) ; - _ttmp.set_count(+0) ; + _qsrc.set_count(+0) ; + _qdst.set_count(+0) ; + _qtmp.set_count(+0) ; /*--------------------------------- exit if FEAT node */ - if (_iptr->feat() != mesh::null_feat) + if (_iptr->feat() != null_feat) return ; - if (_jptr->feat() != mesh::null_feat) + if (_jptr->feat() != null_feat) return ; - /*--------------------------------- get edge h-sizing */ - real_type _ipos[_dims + 1] ; - real_type _jpos[_dims + 1] ; - iptr_type _idim = +0; - for (_idim = _dims+1; _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 large */ - if (_lsqr >= _hbar * _lmax * - _hbar * _lmax ) - return ; - /*--------------------------------- get adjacent face */ - _mesh.node_tri3(_eptr->node (0), - _iset) ; - _mesh.node_tri3(_eptr->node (1), - _jset) ; - - /*--------------------------------- exit if poor topo */ - if (_iset.count() <= +1 || - _jset.count() <= +1 ) - return ; - if (_iset.count() >= +6 && - _jset.count() >= +6 ) - return ; - if (_iset.count() + - _jset.count() >= 12 ) - return ; + _mesh.connect_2(_eptr->node(+0), + POINT_tag, _iset) ; + _mesh.connect_2(_eptr->node(+1), + POINT_tag, _jset) ; /*--------------------------------- calc. local topo. */ + auto _ndeg = _iset.count() + + _jset.count() - 4 ; + auto _ideg = _iset.count() ; - auto _jdeg = _jset.count() ; + auto _ierr = + (iptr_type)(_DEG_TRIA3-_ideg) ; - auto _ndeg = _iset.count() - + _jset.count() - - 4 ; + auto _jdeg = _jset.count() ; + auto _jerr = + (iptr_type)(_DEG_TRIA3-_jdeg) ; - auto _ierr = std::abs( - (iptr_type)(+6-_ideg)) ; - auto _jerr = std::abs( - (iptr_type)(+6-_jdeg)) ; + auto _iabs = std::abs(_ierr) ; + auto _jabs = std::abs(_jerr) ; auto _nerr = std::abs( - (iptr_type)(+6-_ndeg)) ; + (iptr_type)(_DEG_TRIA3-_ndeg)); // bail-out early if the topological defect would be // made worse if the zip is done - if (_nerr > - std::max(_ierr,_jerr)) + if (_nerr> std::max(_ierr, _jerr)) return ; // if more regular topo. is constructed via the edge // zip, make it easier to do so! - //if (2*_nerr < _ierr+_jerr) - //_qinc = std::min(0.,_qinc) ; + real_type _qerr = + (real_type)-1./9. * _ierr + + (real_type)-1./9. * _jerr ; - /*--------------------------------- get disjoint face */ - for (auto _tria = _iset.head(); - _tria != _iset.tend(); - ++_tria ) - { - auto _tptr = - _mesh._set3.head()+*_tria ; - - iptr_type _same = +0 ; - if (_tptr->node(0) == - _eptr->node(0) ) - _same += +1 ; - if (_tptr->node(0) == - _eptr->node(1) ) - _same += +1 ; - if (_tptr->node(1) == - _eptr->node(0) ) - _same += +1 ; - if (_tptr->node(1) == - _eptr->node(1) ) - _same += +1 ; - if (_tptr->node(2) == - _eptr->node(0) ) - _same += +1 ; - if (_tptr->node(2) == - _eptr->node(1) ) - _same += +1 ; - if (_same >= +2) continue ; + real_type _lerr = + (real_type)+6./5. * _lmax ; - _aset.push_tail(*_tria) ; - } - - for (auto _tria = _jset.head(); - _tria != _jset.tend(); - ++_tria ) + if (2 * _nerr < _iabs + _jabs) { - auto _tptr = - _mesh._set3.head()+*_tria ; - - iptr_type _same = +0 ; - if (_tptr->node(0) == - _eptr->node(0) ) - _same += +1 ; - if (_tptr->node(0) == - _eptr->node(1) ) - _same += +1 ; - if (_tptr->node(1) == - _eptr->node(0) ) - _same += +1 ; - if (_tptr->node(1) == - _eptr->node(1) ) - _same += +1 ; - if (_tptr->node(2) == - _eptr->node(0) ) - _same += +1 ; - if (_tptr->node(2) == - _eptr->node(1) ) - _same += +1 ; - if (_same >= +2) continue ; - - _bset.push_tail(*_tria) ; + _qinc = std::min(_qinc, _qerr); + _lmax = std::max(_lmax, _lerr); } - /*--------------------------------- get adjacent cost */ - real_type _minA = - loop_cost(_mesh, _pred , - _iset, - _tsrc, - tria_kind()) ; - real_type _minB = - loop_cost(_mesh, _pred , - _bset, - _tsrc, - tria_kind()) ; - - real_type _TMIN = - std::min( _minA, _minB); + /*--------------------------------- get edge h-sizing */ + real_type _isiz, _jsiz ; + _isiz = _hfun.eval( + &_iptr->pval(0), _iptr->hidx()) ; + _jsiz = _hfun.eval( + &_jptr->pval(0), _jptr->hidx()) ; - real_type _TURN = - std::pow(_TLIM, +1./4.) ; + real_type _lsqr = + pred_type::length_sq ( + &_iptr->pval(0),&_jptr->pval(0)) ; - if (_TMIN>_TURN) return; + real_type _hbar = + std::min(_isiz , _jsiz); - /*--------------------------------- get adjacent ball */ - real_type _pbal[_dims+1] = { - (real_type) +0.000 } ; + /*--------------------------------- exit if too large */ + if (_lsqr >= _hbar * _lmax * + _hbar * _lmax ) + return ; - for (auto _tria = _iset.head(); - _tria != _iset.tend(); - ++_tria ) + /*--------------------------------- get disjoint sets */ + for (auto _cell = _iset.head(); + _cell != _iset.tend(); + ++_cell ) { - real_type _ball[_dims]; - for(_idim = _dims; - _idim-- != +0 ; ) + /*--------------------------------- set a = { i \ e } */ + if (_cell->_kind == TRIA3_tag) { - _ball[_idim] = - _mesh._set1[ - _mesh._set3[ - *_tria].node(0)].pval(_idim) + - _mesh._set1[ - _mesh._set3[ - *_tria].node(1)].pval(_idim) + - _mesh._set1[ - _mesh._set3[ - *_tria].node(2)].pval(_idim) ; - - _ball[_idim]/= - (real_type)+3.; + auto _tptr = + _mesh. tri3().head()+_cell->_cell ; + + iptr_type _nnum, _same = +0; + for(_nnum = 3; _nnum-- != 0; ) + { + if (_tptr->node(_nnum) == + _eptr->node( 0) ) + _same += +1 ; + + if (_tptr->node(_nnum) == + _eptr->node( 1) ) + _same += +1 ; } - for(_idim = _dims; - _idim-- != +0 ; ) + if (_same >= +2) continue ; + } + else + if (_cell->_kind == QUAD4_tag) + { + auto _qptr = + _mesh. quad().head()+_cell->_cell ; + + iptr_type _nnum, _same = +0; + for(_nnum = 4; _nnum-- != 0; ) { - _pbal [_idim] += - _ball [_idim] ; + if (_qptr->node(_nnum) == + _eptr->node( 0) ) + _same += +1 ; + + if (_qptr->node(_nnum) == + _eptr->node( 1) ) + _same += +1 ; + } + + if (_same >= +2) continue ; } + + _aset.push_tail( *_cell ) ; } - for (auto _tria = _jset.head(); - _tria != _jset.tend(); - ++_tria ) + for (auto _cell = _jset.head(); + _cell != _jset.tend(); + ++_cell ) { - real_type _ball[_dims]; - for(_idim = _dims; - _idim-- != +0 ; ) + /*--------------------------------- set b = { j \ e } */ + if (_cell->_kind == TRIA3_tag) + { + auto _tptr = + _mesh. tri3().head()+_cell->_cell ; + + iptr_type _nnum, _same = +0; + for(_nnum = 3; _nnum-- != 0; ) { - _ball[_idim] = - _mesh._set1[ - _mesh._set3[ - *_tria].node(0)].pval(_idim) + - _mesh._set1[ - _mesh._set3[ - *_tria].node(1)].pval(_idim) + - _mesh._set1[ - _mesh._set3[ - *_tria].node(2)].pval(_idim) ; - - _ball[_idim]/= - (real_type)+3.; + if (_tptr->node(_nnum) == + _eptr->node( 0) ) + _same += +1 ; + + if (_tptr->node(_nnum) == + _eptr->node( 1) ) + _same += +1 ; } - for(_idim = _dims; - _idim-- != +0 ; ) + if (_same >= +2) continue ; + } + else + if (_cell->_kind == QUAD4_tag) { - _pbal [_idim] += - _ball [_idim] ; + auto _qptr = + _mesh. quad().head()+_cell->_cell ; + + iptr_type _nnum, _same = +0; + for(_nnum = 4; _nnum-- != 0; ) + { + if (_qptr->node(_nnum) == + _eptr->node( 0) ) + _same += +1 ; + + if (_qptr->node(_nnum) == + _eptr->node( 1) ) + _same += +1 ; + } + + if (_same >= +2) continue ; } + + _bset.push_tail( *_cell ) ; } - for(_idim = _dims+0; _idim-- != 0; ) + /*--------------------------------- get adjacent cost */ + real_type _amin = loop_cost( + _mesh, _iset, _qsrc, cell_kind()) ; + + real_type _bmin = loop_cost( + _mesh, _bset, _qsrc, cell_kind()) ; + + real_type _qmin = + std::min(_amin, _bmin) ; + + /*--------------------------------- get adjacent ball */ + real_type _ball[_last + 1] ; + for (auto _idim = + pred_type::real_dims; _idim-- != 0; ) { - _pbal[_idim] /= (_iset.count() + - _jset.count() ) ; - } + _ball[_idim] = (real_type) +0. ; + _ball[_idim] += + _iptr->pval(_idim) ; + _ball[_idim] += + _jptr->pval(_idim) ; - _pbal[_dims] = (real_type)+0. ; - _pbal[_dims] += - _iptr->pval(_dims) ; - _pbal[_dims] += - _jptr->pval(_dims) ; + _ball[_idim] /= (real_type) +2. ; + } - _pbal[_dims] /= (real_type)+2. ; + pred_type:: + proj_node(_geom, _ball, _ball); /*--------------------------------- try to merge edge */ - typename mesh_type - ::node_type _ndat ; - typename mesh_type - ::tri3_type _tdat ; + # define NULLHINT hfun_type::null_hint() + # define NULLFEAT null_feat + + typename mesh_type::node_type _ndat ; - _ndat.fdim() = +2 ; - _ndat.feat() = - mesh::null_feat ; + typename mesh_type::tri3_type _tdat ; + typename mesh_type::quad_type _qdat ; - for(_idim =_dims+1; _idim-- != 0 ; ) + for (auto _idim = + pred_type::real_dims; _idim-- != 0; ) { - _ndat.pval(_idim) = _pbal[_idim] ; + _ndat.pval(_idim) = _ball[_idim]; } - _ndat.hidx() = - size_type::null_hint() ; - - iptr_type _inew = - _mesh.push_node(_ndat) ; - - _nnew = _inew ; + _ndat.fdim() = (iptr_type) +2 ; + _ndat.feat() = NULLFEAT ; + _ndat.hidx() = NULLHINT ; + _nnew = _mesh.push_node(_ndat); auto _nptr = - _mesh._set1.head() + _inew ; + _mesh. node().head () + _nnew ; - _hval.set_count(std::max ( - _inew + 1, - (iptr_type)_hval.count())) ; + _hval.set_count( std::max( + _nnew + 1, (iptr_type)_hval.count())) ; - _hval[_inew] = (real_type)-1. ; + _hval[_nnew] = (real_type)-1. ; /*--------------------------------- push a new cavity */ - for (auto _tria = _aset.head(); - _tria != _aset.tend(); - ++_tria ) + for (auto _cell = _aset.head(); + _cell != _aset.tend(); + ++_cell ) { + if (_cell->_kind == TRIA3_tag) + { auto _tptr = - _mesh._set3.head()+*_tria ; + _mesh. tri3().head()+_cell->_cell ; - _tdat.node(0) = - _tptr->node(0) ; - _tdat.node(1) = - _tptr->node(1) ; - _tdat.node(2) = - _tptr->node(2) ; + _tdat.node(0) = _tptr->node(0) ; + _tdat.node(1) = _tptr->node(1) ; + _tdat.node(2) = _tptr->node(2) ; - _tdat.itag () = - _tptr->itag () ; + _tdat.itag () = _tptr->itag () ; - if (_tdat. node(0) == + iptr_type _nnum ; + for(_nnum = 3; _nnum-- != 0; ) + { + if (_tdat. node(_nnum) == _edat. node(0) ) - _tdat. node(0) = _inew ; + _tdat. node(_nnum) = _nnew ; + } - if (_tdat. node(1) == - _edat. node(0) ) - _tdat. node(1) = _inew ; + auto _tnum = + _mesh.push_tri3(_tdat) ; - if (_tdat. node(2) == + _cset.push_tail( typename + conn_list::data_type(_tnum,TRIA3_tag)); + } + else + if (_cell->_kind == QUAD4_tag) + { + auto _qptr = + _mesh. quad().head()+_cell->_cell ; + + _qdat.node(0) = _qptr->node(0) ; + _qdat.node(1) = _qptr->node(1) ; + _qdat.node(2) = _qptr->node(2) ; + _qdat.node(3) = _qptr->node(3) ; + + _qdat.itag () = _qptr->itag () ; + + iptr_type _nnum ; + for(_nnum = 4; _nnum-- != 0; ) + { + if (_qdat. node(_nnum) == _edat. node(0) ) - _tdat. node(2) = _inew ; + _qdat. node(_nnum) = _nnew ; + } - _cset.push_tail( - _mesh.push_tri3(_tdat)) ; + auto _qnum = + _mesh.push_quad(_qdat) ; + + _cset.push_tail( typename + conn_list::data_type(_qnum,QUAD4_tag)); + } } - for (auto _tria = _bset.head(); - _tria != _bset.tend(); - ++_tria ) + for (auto _cell = _bset.head(); + _cell != _bset.tend(); + ++_cell ) { + if (_cell->_kind == TRIA3_tag) + { auto _tptr = - _mesh._set3.head()+*_tria ; + _mesh. tri3().head()+_cell->_cell ; - _tdat.node(0) = - _tptr->node(0) ; - _tdat.node(1) = - _tptr->node(1) ; - _tdat.node(2) = - _tptr->node(2) ; + _tdat.node(0) = _tptr->node(0) ; + _tdat.node(1) = _tptr->node(1) ; + _tdat.node(2) = _tptr->node(2) ; - _tdat.itag () = - _tptr->itag () ; + _tdat.itag () = _tptr->itag () ; - if (_tdat. node(0) == + iptr_type _nnum ; + for(_nnum = 3; _nnum-- != 0; ) + { + if (_tdat. node(_nnum) == _edat. node(1) ) - _tdat. node(0) = _inew ; + _tdat. node(_nnum) = _nnew ; + } - if (_tdat. node(1) == - _edat. node(1) ) - _tdat. node(1) = _inew ; + auto _tnum = + _mesh.push_tri3(_tdat) ; - if (_tdat. node(2) == + _cset.push_tail( typename + conn_list::data_type(_tnum,TRIA3_tag)); + } + else + if (_cell->_kind == QUAD4_tag) + { + auto _qptr = + _mesh. quad().head()+_cell->_cell ; + + _qdat.node(0) = _qptr->node(0) ; + _qdat.node(1) = _qptr->node(1) ; + _qdat.node(2) = _qptr->node(2) ; + _qdat.node(3) = _qptr->node(3) ; + + _qdat.itag () = _qptr->itag () ; + + iptr_type _nnum ; + for(_nnum = 4; _nnum-- != 0; ) + { + if (_qdat. node(_nnum) == _edat. node(1) ) - _tdat. node(2) = _inew ; + _qdat. node(_nnum) = _nnew ; + } + + auto _qnum = + _mesh.push_quad(_qdat) ; - _cset.push_tail( - _mesh.push_tri3(_tdat)) ; + _cset.push_tail( typename + conn_list::data_type(_qnum,QUAD4_tag)); + } } /*--------------------------------- optim. node coord */ iptr_type static - constexpr _INUM = (iptr_type) +4 ; + constexpr _INUM = (iptr_type) +8; - for (auto _iloc = +0; _iloc != _INUM ; - ++_iloc ) + iptr_type _move = -1; + for (auto _iter = +0; _iter != _INUM; + ++_iter ) { - iptr_type _move = (iptr_type) -1 ; - - _ttmp.set_count(0) ; + _qtmp.set_count(0) ; real_type _minC = - loop_cost( _mesh, _pred , - _cset, - _ttmp, - tria_kind() ) ; - - move_node( _geom, _mesh , - _hfun, _pred, _hval , - _opts, _nptr, _kern , + loop_cost( _mesh, + _cset, _qtmp, cell_kind() + ) ; + + move_node( _geom, _mesh, + _hfun, _hval, + _opts, _nptr, _kern, _move, _cset, - _ttmp, _tdst, - _minC, _TLIM ) ; + _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, _cset, - _tdst, - tria_kind() ) ; + real_type _QMIN = + loop_cost( _mesh, + _cset, _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 = _aset.head(); - _tria != _aset.tend(); - ++_tria ) + for (auto _cell = _aset.head(); + _cell != _aset.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); + } } - for (auto _tria = _jset.head(); - _tria != _jset.tend(); - ++_tria ) + for (auto _cell = _jset.head(); + _cell != _jset.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(& _inod) ; - _mesh. - _pop_node(& _jnod) ; + _mesh._pop_node ( &_inod ) ; + _mesh._pop_node ( &_jnod ) ; } else { /*--------------------------------- delete new cavity */ - for (auto _tria = _cset.head(); - _tria != _cset.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); + } } - _mesh. - _pop_node(& _inew) ; + _mesh._pop_node ( &_nnew ) ; } + # undef NULLHINT + # undef NULLFEAT } diff --git a/src/libcpp/iter_mesh/iter_zips_3.inc b/src/libcpp/iter_mesh/iter_zips_3.inc index af31b8b..ac6ff75 100644 --- a/src/libcpp/iter_mesh/iter_zips_3.inc +++ b/src/libcpp/iter_mesh/iter_zips_3.inc @@ -35,7 +35,7 @@ * * Copyright 2013-2018 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- @@ -44,496 +44,5 @@ // from iter_mesh_3.hpp - /* - -------------------------------------------------------- - * _ZIP-FACE: try face merge to improve adj. cost-fun. - -------------------------------------------------------- - */ - - /* - __static_call - __normal_call void_type _zip_face_3 ( - */ - - - /* - -------------------------------------------------------- - * _ZIP-EDGE: try edge merge to improve adj. cost-fun. - -------------------------------------------------------- - */ - - __static_call - __normal_call void_type _zip_edge_3 ( - geom_type &_geom , - mesh_type &_mesh , - size_type &_hfun , - pred_type &_pred , - real_list &_hval , - iter_opts &_opts , - iptr_type _edge , - bool_type &_okay , - iptr_list &_iset , - iptr_list &_jset , - iptr_list &_aset , - iptr_list &_bset , - iptr_list &_cset , - real_list &_tsrc , - real_list &_tdst , - real_list &_ttmp , - real_list &_dsrc , - real_list &_ddst , - real_type _lmax - = (real_type) +0.80E+00 , - real_type _good - = (real_type) +9.25E-01 , - real_type _qinc - = (real_type) +1.00E-08 - ) - { - __unreferenced(_pred) ; // for MSVC... - - /*--------------------------------- get edge indexing */ - auto _eptr = - _mesh._set2.head() + _edge; - - typename mesh_type:: - edge_type _edat(*_eptr) ; - - iptr_type _inod, _jnod ; - _inod = _eptr->node(0) ; - _jnod = _eptr->node(1) ; - - auto _iptr = _mesh. - _set1.head()+ _eptr->node(0); - auto _jptr = _mesh. - _set1.head()+ _eptr->node(1); - - _okay = false ; - - _iset.set_count(+0) ; - _jset.set_count(+0) ; - _aset.set_count(+0) ; - _bset.set_count(+0) ; - _cset.set_count(+0) ; - - _tsrc.set_count(+0) ; - _tdst.set_count(+0) ; - _ttmp.set_count(+0) ; - _dsrc.set_count(+0) ; - _ddst.set_count(+0) ; - - /*--------------------------------- exit if FEAT node */ - if (_iptr->feat() != mesh::null_feat) - return ; - if (_jptr->feat() != mesh::null_feat) - return ; - - /*--------------------------------- get edge h-sizing */ - real_type _ipos[_dims + 1] ; - real_type _jpos[_dims + 1] ; - iptr_type _idim = +0; - for (_idim = _dims+1; _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 large */ - if (_lsqr >= _hbar * _lmax * - _hbar * _lmax ) - return ; - - /*--------------------------------- get adjacent cell */ - _mesh.node_tri4(_eptr->node (0), - _iset) ; - _mesh.node_tri4(_eptr->node (1), - _jset) ; - - /*--------------------------------- exit if poor topo */ - /* - if (_iset.count() <= +1 || - _jset.count() <= +1 ) - return ; - if (_iset.count() >= +6 && - _jset.count() >= +6 ) - return ; - if (_iset.count() + - _jset.count() > +12 ) - return ; - */ - - /*--------------------------------- get disjoint face */ - for (auto _tria = _iset.head(); - _tria != _iset.tend(); - ++_tria ) - { - auto _tptr = - _mesh._set4.head()+*_tria ; - - iptr_type _same = +0 ; - if (_tptr->node(0) == - _eptr->node(0) ) - _same += +1 ; - if (_tptr->node(0) == - _eptr->node(1) ) - _same += +1 ; - if (_tptr->node(1) == - _eptr->node(0) ) - _same += +1 ; - if (_tptr->node(1) == - _eptr->node(1) ) - _same += +1 ; - if (_tptr->node(2) == - _eptr->node(0) ) - _same += +1 ; - if (_tptr->node(2) == - _eptr->node(1) ) - _same += +1 ; - if (_tptr->node(3) == - _eptr->node(0) ) - _same += +1 ; - if (_tptr->node(3) == - _eptr->node(1) ) - _same += +1 ; - if (_same >= +2) continue ; - - _aset.push_tail(*_tria) ; - } - - for (auto _tria = _jset.head(); - _tria != _jset.tend(); - ++_tria ) - { - auto _tptr = - _mesh._set4.head()+*_tria ; - - iptr_type _same = +0 ; - if (_tptr->node(0) == - _eptr->node(0) ) - _same += +1 ; - if (_tptr->node(0) == - _eptr->node(1) ) - _same += +1 ; - if (_tptr->node(1) == - _eptr->node(0) ) - _same += +1 ; - if (_tptr->node(1) == - _eptr->node(1) ) - _same += +1 ; - if (_tptr->node(2) == - _eptr->node(0) ) - _same += +1 ; - if (_tptr->node(2) == - _eptr->node(1) ) - _same += +1 ; - if (_tptr->node(3) == - _eptr->node(0) ) - _same += +1 ; - if (_tptr->node(3) == - _eptr->node(1) ) - _same += +1 ; - if (_same >= +2) continue ; - - _bset.push_tail(*_tria) ; - } - - /*--------------------------------- get adjacent cost */ - real_type _minA = - loop_tscr(_mesh, _pred , - _iset, - _tsrc) ; - real_type _minB = - loop_tscr(_mesh, _pred , - _bset, - _tsrc) ; - - real_type _TMIN = - std::min( _minA, _minB); - - if (_TMIN>_good) return; - - /*--------------------------------- get adjacent ball */ - real_type _pbal[_dims+1] = { - (real_type) +0.000 } ; - - for (auto _tria = _iset.head(); - _tria != _iset.tend(); - ++_tria ) - { - real_type _ball[_dims+1] ; - _pred. perp_ball(_ball , - &_mesh._set1[ - _mesh._set4[ - *_tria].node(0)].pval(0), - &_mesh._set1[ - _mesh._set4[ - *_tria].node(1)].pval(0), - &_mesh._set1[ - _mesh._set4[ - *_tria].node(2)].pval(0), - &_mesh._set1[ - _mesh._set4[ - *_tria].node(3)].pval(0), - true ) ; - - for(_idim = _dims; - _idim-- != +0 ; ) - { - _pbal [_idim] += - _ball [_idim] ; - } - } - - for (auto _tria = _jset.head(); - _tria != _jset.tend(); - ++_tria ) - { - real_type _ball[_dims+1] ; - _pred. perp_ball(_ball , - &_mesh._set1[ - _mesh._set4[ - *_tria].node(0)].pval(0), - &_mesh._set1[ - _mesh._set4[ - *_tria].node(1)].pval(0), - &_mesh._set1[ - _mesh._set4[ - *_tria].node(2)].pval(0), - &_mesh._set1[ - _mesh._set4[ - *_tria].node(3)].pval(0), - true ) ; - - for(_idim = _dims; - _idim-- != +0 ; ) - { - _pbal [_idim] += - _ball [_idim] ; - } - } - - for(_idim = _dims+0; _idim-- != 0; ) - { - _pbal[_idim] /= (_iset.count() + - _jset.count() ) ; - } - - _pbal[_dims+0] = (real_type) +0. ; - - /*--------------------------------- try to merge edge */ - typename mesh_type - ::node_type _ndat ; - typename mesh_type - ::tri4_type _tdat ; - - _ndat.hidx() = - size_type::null_hint() ; - - _ndat.fdim() = +3; - _ndat.feat() = - mesh::null_feat; - - for(_idim = _dims+1; _idim-- != 0; ) - { - _ndat.pval(_idim) = - _pbal[_idim] ; - } - - /*--------------------------------- push node at PBAL */ - iptr_type _inew = - _mesh.push_node(_ndat) ; - - auto _nptr = - _mesh._set1.head() + _inew ; - - _hval.set_count(std::max ( - _inew + 1, - (iptr_type)_hval.count())) ; - - _hval[_inew] = (real_type)-1. ; - - /*--------------------------------- push a new cavity */ - for (auto _tria = _aset.head(); - _tria != _aset.tend(); - ++_tria ) - { - auto _tptr = - _mesh._set4.head() +*_tria ; - - _tdat.node(0) = - _tptr->node(0) ; - _tdat.node(1) = - _tptr->node(1) ; - _tdat.node(2) = - _tptr->node(2) ; - _tdat.node(3) = - _tptr->node(3) ; - - if (_tdat. node(0) == - _edat. node(0) ) - _tdat. node(0) = _inew ; - - if (_tdat. node(1) == - _edat. node(0) ) - _tdat. node(1) = _inew ; - - if (_tdat. node(2) == - _edat. node(0) ) - _tdat. node(2) = _inew ; - - if (_tdat. node(3) == - _edat. node(0) ) - _tdat. node(3) = _inew ; - - _cset.push_tail( - _mesh.push_tri4(_tdat)) ; - } - - for (auto _tria = _bset.head(); - _tria != _bset.tend(); - ++_tria ) - { - auto _tptr = - _mesh._set4.head() +*_tria ; - - _tdat.node(0) = - _tptr->node(0) ; - _tdat.node(1) = - _tptr->node(1) ; - _tdat.node(2) = - _tptr->node(2) ; - _tdat.node(3) = - _tptr->node(3) ; - - if (_tdat. node(0) == - _edat. node(1) ) - _tdat. node(0) = _inew ; - - if (_tdat. node(1) == - _edat. node(1) ) - _tdat. node(1) = _inew ; - - if (_tdat. node(2) == - _edat. node(1) ) - _tdat. node(2) = _inew ; - - if (_tdat. node(3) == - _edat. node(1) ) - _tdat. node(3) = _inew ; - - _cset.push_tail( - _mesh.push_tri4(_tdat)) ; - } - - /*--------------------------------- optim. node coord */ - iptr_type static - constexpr _INUM = (iptr_type) +8 ; - - for (auto _iloc = +0; _iloc != _INUM ; - ++_iloc ) - { - bool_type _move = false ; - - _ttmp.set_count(0) ; - _dsrc.set_count(0) ; - - real_type _minC = - loop_tscr( _mesh, _pred , - _cset, - _ttmp ) ; - - real_type _minD = - loop_dscr( _mesh, _pred , - _cset, - _dsrc ) ; - - move_node( _geom, _mesh , - _hfun, _pred, _hval , - _opts, _nptr, +1 , - _move, _cset, - _ttmp, _tdst, - _dsrc, _ddst, - _minC, _good, - _minD, _good ) ; - - if (_move) continue; - - move_node( _geom, _mesh , - _hfun, _pred, _hval , - _opts, _nptr, +2 , - _move, _cset, - _ttmp, _tdst, - _dsrc, _ddst, - _minC, _good, - _minD, _good ) ; - - if (_move) continue; - - break ; - } - - /*--------------------------------- compare cost scr. */ - _tdst.set_count(0) ; - - loop_tscr(_mesh, _pred, _cset, - _tdst) ; - - move_okay(_tdst, _tsrc, _okay, - _good, - _qinc) ; - - if (_okay) - { - /*--------------------------------- delete old cavity */ - for (auto _tria = _aset.head(); - _tria != _aset.tend(); - ++_tria ) - { - _mesh. - _pop_tri4(* _tria) ; - } - for (auto _tria = _jset.head(); - _tria != _jset.tend(); - ++_tria ) - { - _mesh. - _pop_tri4(* _tria) ; - } - - _mesh. - _pop_node(& _inod) ; - _mesh. - _pop_node(& _jnod) ; - } - else - { - /*--------------------------------- delete new cavity */ - for (auto _tria = _cset.head(); - _tria != _cset.tend(); - ++_tria ) - { - _mesh. - _pop_tri4(* _tria) ; - } - - _mesh. - _pop_node(& _inew) ; - } - - } - diff --git a/src/libcpp/itermesh.hpp b/src/libcpp/itermesh.hpp index aaac0dc..61f373e 100644 --- a/src/libcpp/itermesh.hpp +++ b/src/libcpp/itermesh.hpp @@ -35,7 +35,7 @@ * * Copyright 2013-2019 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * ------------------------------------------------------------ @@ -58,11 +58,10 @@ # include "iter_mesh/iter_timers.hpp" # include "iter_mesh/iter_mesh_euclidean_2.hpp" -# include "iter_mesh/iter_pred_euclidean_2.hpp" - # include "iter_mesh/iter_mesh_euclidean_3.hpp" -# include "iter_mesh/iter_pred_euclidean_3.hpp" +# include "iter_mesh/iter_pred_euclidean_2.hpp" +// include "iter_mesh/iter_pred_euclidean_3.hpp" # include "iter_mesh/iter_pred_ellipsoid_3.hpp" # include "iter_mesh/iter_mesh_2.hpp" diff --git a/src/libcpp/mathutil.hpp b/src/libcpp/mathutil.hpp index 80fc8f9..00984ea 100644 --- a/src/libcpp/mathutil.hpp +++ b/src/libcpp/mathutil.hpp @@ -35,7 +35,7 @@ * * Copyright 2013-2019 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- @@ -56,7 +56,7 @@ */ template < - typename real_type + typename real_type > __normal_call bool_type polyroots ( real_type _aa, // aa*xx^2+bb*xx+cc=0 @@ -119,51 +119,51 @@ ((__ir)+(__ic)*(__nr)) template < - typename real_type, - typename size_type + typename real_type, + typename size_type > __inline_call real_type det_2x2 ( size_type _la, __const_ptr (real_type) _aa ) { return - _aa[__ij(0,0,_la)] * - _aa[__ij(1,1,_la)] - - _aa[__ij(0,1,_la)] * - _aa[__ij(1,0,_la)] ; + _aa[__ij(0, 0, _la)] * + _aa[__ij(1, 1, _la)] - + _aa[__ij(0, 1, _la)] * + _aa[__ij(1, 0, _la)] ; } template < - typename real_type, - typename size_type + typename real_type, + typename size_type > __inline_call real_type det_3x3 ( size_type _la, __const_ptr (real_type) _aa ) { return - _aa[__ij(0,0,_la)] * ( - _aa[__ij(1,1,_la)] * - _aa[__ij(2,2,_la)] - - _aa[__ij(1,2,_la)] * - _aa[__ij(2,1,_la)] ) - - - _aa[__ij(0,1,_la)] * ( - _aa[__ij(1,0,_la)] * - _aa[__ij(2,2,_la)] - - _aa[__ij(1,2,_la)] * - _aa[__ij(2,0,_la)] ) + - - _aa[__ij(0,2,_la)] * ( - _aa[__ij(1,0,_la)] * - _aa[__ij(2,1,_la)] - - _aa[__ij(1,1,_la)] * - _aa[__ij(2,0,_la)] ) ; + _aa[__ij(0, 0, _la)] * ( + _aa[__ij(1, 1, _la)] * + _aa[__ij(2, 2, _la)] - + _aa[__ij(1, 2, _la)] * + _aa[__ij(2, 1, _la)] ) - + + _aa[__ij(0, 1, _la)] * ( + _aa[__ij(1, 0, _la)] * + _aa[__ij(2, 2, _la)] - + _aa[__ij(1, 2, _la)] * + _aa[__ij(2, 0, _la)] ) + + + _aa[__ij(0, 2, _la)] * ( + _aa[__ij(1, 0, _la)] * + _aa[__ij(2, 1, _la)] - + _aa[__ij(1, 1, _la)] * + _aa[__ij(2, 0, _la)] ) ; } template < - typename real_type, - typename size_type + typename real_type, + typename size_type > __inline_call void_type inv_2x2 ( size_type _la, @@ -175,19 +175,19 @@ { _da = det_2x2(_la, _aa) ; - _xx[__ij(0,0,_lx)] = - _aa[__ij(1,1,_la)] ; - _xx[__ij(1,1,_lx)] = - _aa[__ij(0,0,_la)] ; - _xx[__ij(0,1,_lx)] = - -_aa[__ij(0,1,_la)] ; - _xx[__ij(1,0,_lx)] = - -_aa[__ij(1,0,_la)] ; + _xx[__ij(0, 0, _lx)] = + _aa[__ij(1, 1, _la)] ; + _xx[__ij(1, 1, _lx)] = + _aa[__ij(0, 0, _la)] ; + _xx[__ij(0, 1, _lx)] = + -_aa[__ij(0, 1, _la)] ; + _xx[__ij(1, 0, _lx)] = + -_aa[__ij(1, 0, _la)] ; } template < - typename real_type, - typename size_type + typename real_type, + typename size_type > __inline_call void_type inv_3x3 ( size_type _la, @@ -199,59 +199,59 @@ { _da = det_3x3(_la, _aa) ; - _xx[__ij(0,0,_lx)] = - _aa[__ij(2,2,_la)] * - _aa[__ij(1,1,_la)] - - _aa[__ij(2,1,_la)] * - _aa[__ij(1,2,_la)] ; - - _xx[__ij(0,1,_lx)] = - _aa[__ij(2,1,_la)] * - _aa[__ij(0,2,_la)] - - _aa[__ij(2,2,_la)] * - _aa[__ij(0,1,_la)] ; - - _xx[__ij(0,2,_lx)] = - _aa[__ij(1,2,_la)] * - _aa[__ij(0,1,_la)] - - _aa[__ij(1,1,_la)] * - _aa[__ij(0,2,_la)] ; - - _xx[__ij(1,0,_lx)] = - _aa[__ij(2,0,_la)] * - _aa[__ij(1,2,_la)] - - _aa[__ij(2,2,_la)] * - _aa[__ij(1,0,_la)] ; - - _xx[__ij(1,1,_lx)] = - _aa[__ij(2,2,_la)] * - _aa[__ij(0,0,_la)] - - _aa[__ij(2,0,_la)] * - _aa[__ij(0,2,_la)] ; - - _xx[__ij(1,2,_lx)] = - _aa[__ij(1,0,_la)] * - _aa[__ij(0,2,_la)] - - _aa[__ij(1,2,_la)] * - _aa[__ij(0,0,_la)] ; - - _xx[__ij(2,0,_lx)] = - _aa[__ij(2,1,_la)] * - _aa[__ij(1,0,_la)] - - _aa[__ij(2,0,_la)] * - _aa[__ij(1,1,_la)] ; - - _xx[__ij(2,1,_lx)] = - _aa[__ij(2,0,_la)] * - _aa[__ij(0,1,_la)] - - _aa[__ij(2,1,_la)] * - _aa[__ij(0,0,_la)] ; - - _xx[__ij(2,2,_lx)] = - _aa[__ij(1,1,_la)] * - _aa[__ij(0,0,_la)] - - _aa[__ij(1,0,_la)] * - _aa[__ij(0,1,_la)] ; + _xx[__ij(0, 0, _lx)] = + _aa[__ij(2, 2, _la)] * + _aa[__ij(1, 1, _la)] - + _aa[__ij(2, 1, _la)] * + _aa[__ij(1, 2, _la)] ; + + _xx[__ij(0, 1, _lx)] = + _aa[__ij(2, 1, _la)] * + _aa[__ij(0, 2, _la)] - + _aa[__ij(2, 2, _la)] * + _aa[__ij(0, 1, _la)] ; + + _xx[__ij(0, 2, _lx)] = + _aa[__ij(1, 2, _la)] * + _aa[__ij(0, 1, _la)] - + _aa[__ij(1, 1, _la)] * + _aa[__ij(0, 2, _la)] ; + + _xx[__ij(1, 0, _lx)] = + _aa[__ij(2, 0, _la)] * + _aa[__ij(1, 2, _la)] - + _aa[__ij(2, 2, _la)] * + _aa[__ij(1, 0, _la)] ; + + _xx[__ij(1, 1, _lx)] = + _aa[__ij(2, 2, _la)] * + _aa[__ij(0, 0, _la)] - + _aa[__ij(2, 0, _la)] * + _aa[__ij(0, 2, _la)] ; + + _xx[__ij(1, 2, _lx)] = + _aa[__ij(1, 0, _la)] * + _aa[__ij(0, 2, _la)] - + _aa[__ij(1, 2, _la)] * + _aa[__ij(0, 0, _la)] ; + + _xx[__ij(2, 0, _lx)] = + _aa[__ij(2, 1, _la)] * + _aa[__ij(1, 0, _la)] - + _aa[__ij(2, 0, _la)] * + _aa[__ij(1, 1, _la)] ; + + _xx[__ij(2, 1, _lx)] = + _aa[__ij(2, 0, _la)] * + _aa[__ij(0, 1, _la)] - + _aa[__ij(2, 1, _la)] * + _aa[__ij(0, 0, _la)] ; + + _xx[__ij(2, 2, _lx)] = + _aa[__ij(1, 1, _la)] * + _aa[__ij(0, 0, _la)] - + _aa[__ij(1, 0, _la)] * + _aa[__ij(0, 1, _la)] ; } diff --git a/src/libcpp/mesh_func/hfun_base_k.hpp b/src/libcpp/mesh_func/hfun_base_k.hpp index 4dcc894..6e0ac70 100644 --- a/src/libcpp/mesh_func/hfun_base_k.hpp +++ b/src/libcpp/mesh_func/hfun_base_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/src/libcpp/mesh_func/hfun_clip_k.hpp b/src/libcpp/mesh_func/hfun_clip_k.hpp index fc2edb5..09bd54e 100644 --- a/src/libcpp/mesh_func/hfun_clip_k.hpp +++ b/src/libcpp/mesh_func/hfun_clip_k.hpp @@ -35,7 +35,7 @@ * * Copyright 2013-2019 * Darren Engwirda - * darren.engwirda@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda * -------------------------------------------------------- diff --git a/src/libcpp/mesh_func/hfun_constant_value_k.hpp b/src/libcpp/mesh_func/hfun_constant_value_k.hpp index 762ee55..bd9ac7c 100644 --- a/src/libcpp/mesh_func/hfun_constant_value_k.hpp +++ b/src/libcpp/mesh_func/hfun_constant_value_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/src/libcpp/mesh_func/hfun_grid_ellipsoid_3.hpp b/src/libcpp/mesh_func/hfun_grid_ellipsoid_3.hpp index 047dec4..471290b 100644 --- a/src/libcpp/mesh_func/hfun_grid_ellipsoid_3.hpp +++ b/src/libcpp/mesh_func/hfun_grid_ellipsoid_3.hpp @@ -31,11 +31,11 @@ * -------------------------------------------------------- * - * Last updated: 28 June, 2019 + * Last updated: 23 April, 2020 * - * Copyright 2013-2019 + * Copyright 2013-2020 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- @@ -92,6 +92,9 @@ containers::array < real_type, allocator> _hmat ; + real_type _htop ; // mean at poles + real_type _hbot ; + containers::array < real_type, allocator> _dhdx ; @@ -179,7 +182,7 @@ { real_type static const _FTOL = std::pow(std::numeric_limits - ::epsilon(), (real_type).8); + ::epsilon(), (real_type)+.80) ; this->_xvar = false ; this->_yvar = false ; @@ -188,6 +191,7 @@ if (this->_xpos.empty()) return ; if (this->_ypos.empty()) return ; + /*-------------------------- test for uniform spacing */ real_type _xbar, _xmin, _xmax ; _xbar = *this->_xpos.tail() - *this->_xpos.head() ; @@ -206,10 +210,9 @@ _ymin = _ybar - _FTOL * _ybar ; _ymax = _ybar + _FTOL * _ybar ; - for (auto - _iter = this->_xpos.head() ; - _iter != this->_xpos.tail() ; - ++_iter ) + for (auto _iter = _xpos.head() ; + _iter != _xpos.tail() ; + ++_iter ) { real_type _xdel = *(_iter+1)-*(_iter+0) ; @@ -221,10 +224,9 @@ } } - for (auto - _iter = this->_ypos.head() ; - _iter != this->_ypos.tail() ; - ++_iter ) + for (auto _iter = _ypos.head() ; + _iter != _ypos.tail() ; + ++_iter ) { real_type _ydel = *(_iter+1)-*(_iter+0) ; @@ -236,12 +238,39 @@ } } + /*-------------------------- test for "x" periodicity */ real_type _xdel = - std::cos(*this->_xpos.tail()) - - std::cos(*this->_xpos.head()) ; + std::cos(*_xpos.tail()) - + std::cos(*_xpos.head()) ; this->_wrap = std::abs(_xdel) < _FTOL ; + + /*-------------------------- sum for extrap. at poles */ + this->_htop = (real_type)0. ; + this->_hbot = (real_type)0. ; + + iptr_type _indx, _jpos = +0 ; + for (auto _iter = _xpos.head() ; + _iter != _xpos.tail() ; + ++_iter, ++_jpos) + { + iptr_type _n = -1 + + (iptr_type)this->_ypos.count() ; + + indx_from_subs( + +0, _jpos, _indx) ; + + _htop += this->_hmat[_indx] ; + + indx_from_subs( + _n, _jpos, _indx) ; + + _hbot += this->_hmat[_indx] ; + } + + this->_htop/= this->_xpos.count() ; + this->_hbot/= this->_xpos.count() ; } /* @@ -357,6 +386,8 @@ subs_from_indx( _base, _ipos, _jpos); + real_type _hnow = _hmat[_base] ; + for (auto _IPOS = _ipos - 1 ; _IPOS < _ipos + 1 ; ++_IPOS ) @@ -406,6 +437,18 @@ if (_keys[_lnod] == _null && _lnod != _base) continue ; + /*-------------------- skip cells due to sorted order */ + real_type _hmax; + _hmax = this->_hmat[_inod] ; + _hmax = std::max( + _hmax , this->_hmat[_jnod]); + _hmax = std::max( + _hmax , this->_hmat[_knod]); + _hmax = std::max( + _hmax , this->_hmat[_lnod]); + + if (_hmax <= _hnow) continue ; + /*-------------------- set-up cell vertex coordinates */ real_type _alon, _alat ; real_type _IXYZ[3] ; @@ -456,6 +499,16 @@ _LXYZ[2] = this->_radC * std::sin(_alat) ; + /*-------------------- solve for local |dh/dx| limits */ + real_type _iold = + this->_hmat[_inod] ; + real_type _jold = + this->_hmat[_jnod] ; + real_type _kold = + this->_hmat[_knod] ; + real_type _lold = + this->_hmat[_lnod] ; + if (this->_dhdx.count() >1) { /*-------------------- update adj. set, g = g(x) case */ @@ -473,18 +526,22 @@ { if (_keys[_inod] != _null) + if (_hmat[_inod] != _iold) _sort.update( _keys[_inod] , _inod) ; if (_keys[_jnod] != _null) + if (_hmat[_jnod] != _jold) _sort.update( _keys[_jnod] , _jnod) ; if (_keys[_knod] != _null) + if (_hmat[_knod] != _kold) _sort.update( _keys[_knod] , _knod) ; if (_keys[_lnod] != _null) + if (_hmat[_lnod] != _lold) _sort.update( _keys[_lnod] , _lnod) ; @@ -501,6 +558,7 @@ this->_hmat [_inod] ; if (_keys[_pair] != _null) + if (_hmat[_inod] != _iold) _sort.update( _keys[_pair] , _pair) ; } @@ -515,6 +573,7 @@ this->_hmat [_jnod] ; if (_keys[_pair] != _null) + if (_hmat[_jnod] != _jold) _sort.update( _keys[_pair] , _pair) ; } @@ -529,6 +588,7 @@ this->_hmat [_knod] ; if (_keys[_pair] != _null) + if (_hmat[_knod] != _kold) _sort.update( _keys[_pair] , _pair) ; } @@ -543,6 +603,7 @@ this->_hmat [_lnod] ; if (_keys[_pair] != _null) + if (_hmat[_lnod] != _lold) _sort.update( _keys[_pair] , _pair) ; } @@ -568,18 +629,22 @@ { if (_keys[_inod] != _null) + if (_hmat[_inod] != _iold) _sort.update( _keys[_inod] , _inod) ; if (_keys[_jnod] != _null) + if (_hmat[_jnod] != _jold) _sort.update( _keys[_jnod] , _jnod) ; if (_keys[_knod] != _null) + if (_hmat[_knod] != _kold) _sort.update( _keys[_knod] , _knod) ; if (_keys[_lnod] != _null) + if (_hmat[_lnod] != _lold) _sort.update( _keys[_lnod] , _lnod) ; @@ -596,6 +661,7 @@ this->_hmat [_inod] ; if (_keys[_pair] != _null) + if (_hmat[_inod] != _iold) _sort.update( _keys[_pair] , _pair) ; } @@ -610,6 +676,7 @@ this->_hmat [_jnod] ; if (_keys[_pair] != _null) + if (_hmat[_jnod] != _jold) _sort.update( _keys[_pair] , _pair) ; } @@ -624,6 +691,7 @@ this->_hmat [_knod] ; if (_keys[_pair] != _null) + if (_hmat[_knod] != _kold) _sort.update( _keys[_pair] , _pair) ; } @@ -638,6 +706,7 @@ this->_hmat [_lnod] ; if (_keys[_pair] != _null) + if (_hmat[_lnod] != _lold) _sort.update( _keys[_pair] , _pair) ; } @@ -710,8 +779,11 @@ real_type _alon = _apos[ 0] ; real_type _alat = _apos[ 1] ; + iptr_type _pole = (iptr_type)0 ; + real_type _bias = (real_type)0.; + real_type static const PI = - (real_type)std::atan(+1.0) * 4. ; + (real_type)std::atan(+1.0) * +4.; real_type static const PI_h = (real_type)+.5 * PI ; @@ -732,15 +804,32 @@ if (_alat>=PI_h) _alat = PI_h ; if (_alat < *this->_ypos.head()) + { + _bias = // deal w interp. at pole + (_alat - *this->_ypos.head()) / + (-PI_h - *this->_ypos.head()) ; + _pole = -1 ; _alat = *this->_ypos.head(); + + _bias = std::sin(_bias*PI_h) ; + } + if (_alat > *this->_ypos.tail()) + { + _bias = // deal w interp. at pole + (_alat - *this->_ypos.tail()) / + ( PI_h - *this->_ypos.tail()) ; + _pole = +1 ; _alat = *this->_ypos.tail(); + _bias = std::sin(_bias*PI_h) ; + } + /*---------------------------- find enclosing x-range */ iptr_type _ipos = (iptr_type) -1 ; iptr_type _jpos = (iptr_type) -1 ; - if (this->_xvar == true) + if (this->_xvar) { auto _joff = algorithms::upper_bound ( @@ -765,7 +854,7 @@ } /*---------------------------- find enclosing y-range */ - if (this->_yvar == true) + if (this->_yvar) { auto _ioff = algorithms::upper_bound ( @@ -840,7 +929,20 @@ + _aa22*this->_hmat[_kk22] ) / ( _aa11+_aa12+_aa21+_aa22) ; - return ( _hbar ) ; + if (_pole >= +1) + { + return // deal w interp. at pole + ((real_type)1. - _bias) * _hbar + + ((real_type)0. + _bias) * _htop ; + } + else + if (_pole <= -1) + { + return // deal w interp. at pole + ((real_type)1. - _bias) * _hbar + + ((real_type)0. + _bias) * _hbot ; + } + else { return _hbar ; } // return interior interp } } ; diff --git a/src/libcpp/mesh_func/hfun_grid_euclidean_2.hpp b/src/libcpp/mesh_func/hfun_grid_euclidean_2.hpp index a1fe7d9..5694726 100644 --- a/src/libcpp/mesh_func/hfun_grid_euclidean_2.hpp +++ b/src/libcpp/mesh_func/hfun_grid_euclidean_2.hpp @@ -31,11 +31,11 @@ * -------------------------------------------------------- * - * Last updated: 28 June, 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/ * -------------------------------------------------------- @@ -208,6 +208,8 @@ subs_from_indx( _base, _ipos, _jpos); + real_type _hnow = _hmat[_base] ; + for (auto _IPOS = _ipos - 1 ; _IPOS < _ipos + 1 ; ++_IPOS ) @@ -257,6 +259,18 @@ if (_keys[_lnod] == _null && _lnod != _base) continue ; + /*-------------------- skip cells due to sorted order */ + real_type _hmax; + _hmax = this->_hmat[_inod] ; + _hmax = std::max( + _hmax , this->_hmat[_jnod]); + _hmax = std::max( + _hmax , this->_hmat[_knod]); + _hmax = std::max( + _hmax , this->_hmat[_lnod]); + + if (_hmax <= _hnow) continue ; + /*-------------------- set-up cell vertex coordinates */ real_type _IXYZ[2]; _IXYZ[0] = this->_xpos[_ipjj]; @@ -274,6 +288,16 @@ _LXYZ[0] = this->_xpos[_lpjj]; _LXYZ[1] = this->_ypos[_lpii]; + /*-------------------- solve for local |dh/dx| limits */ + real_type _iold = + this->_hmat[_inod] ; + real_type _jold = + this->_hmat[_jnod] ; + real_type _kold = + this->_hmat[_knod] ; + real_type _lold = + this->_hmat[_lnod] ; + if (this->_dhdx.count() >1) { /*-------------------- update adj. set, g = g(x) case */ @@ -291,18 +315,22 @@ { if (_keys[_inod] != _null) + if (_hmat[_inod] != _iold) _sort.update( _keys[_inod] , _inod) ; if (_keys[_jnod] != _null) + if (_hmat[_jnod] != _jold) _sort.update( _keys[_jnod] , _jnod) ; if (_keys[_knod] != _null) + if (_hmat[_knod] != _kold) _sort.update( _keys[_knod] , _knod) ; if (_keys[_lnod] != _null) + if (_hmat[_lnod] != _lold) _sort.update( _keys[_lnod] , _lnod) ; @@ -326,18 +354,22 @@ { if (_keys[_inod] != _null) + if (_hmat[_inod] != _iold) _sort.update( _keys[_inod] , _inod) ; if (_keys[_jnod] != _null) + if (_hmat[_jnod] != _jold) _sort.update( _keys[_jnod] , _jnod) ; if (_keys[_knod] != _null) + if (_hmat[_knod] != _kold) _sort.update( _keys[_knod] , _knod) ; if (_keys[_lnod] != _null) + if (_hmat[_lnod] != _lold) _sort.update( _keys[_lnod] , _lnod) ; diff --git a/src/libcpp/mesh_func/hfun_grid_euclidean_3.hpp b/src/libcpp/mesh_func/hfun_grid_euclidean_3.hpp index 3d1a2ba..db008b2 100644 --- a/src/libcpp/mesh_func/hfun_grid_euclidean_3.hpp +++ b/src/libcpp/mesh_func/hfun_grid_euclidean_3.hpp @@ -35,7 +35,7 @@ * * Copyright 2013-2019 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- diff --git a/src/libcpp/mesh_func/hfun_mesh_ellipsoid_3.hpp b/src/libcpp/mesh_func/hfun_mesh_ellipsoid_3.hpp index 496b73c..f2f7b89 100644 --- a/src/libcpp/mesh_func/hfun_mesh_ellipsoid_3.hpp +++ b/src/libcpp/mesh_func/hfun_mesh_ellipsoid_3.hpp @@ -1,7 +1,7 @@ /* -------------------------------------------------------- - * HFUN-MESH-ELLIPSOID-3D: ellipsoidal H(x) in R^3. + * HFUN-MESH-ELLIPSOID-3D: unstructured H(x) on S^2. -------------------------------------------------------- * * This program may be freely redistributed under the @@ -31,11 +31,11 @@ * -------------------------------------------------------- * - * Last updated: 12 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/ * -------------------------------------------------------- @@ -82,30 +82,31 @@ typedef mesh_complex_edge_2 edge_type ; typedef mesh_complex_tria_3 tri3_type ; + typedef mesh_complex_quad_4 quad_type ; - typedef mesh::tria_complex_2< - node_type, - edge_type, - tri3_type, - allocator > mesh_type ; + typedef mesh::mesh_complex_2< + node_type, + edge_type, + tri3_type, quad_type, + allocator > mesh_type ; typedef geom_tree::aabb_node_base_k tree_node ; typedef geom_tree::aabb_item_rect_k < - float, - iptr_type, - + 3 > tree_item ; + float, + iptr_type, + + 3 > tree_item ; typedef geom_tree::aabb_tree< - tree_item, - + 3 , - tree_node, - allocator > tree_type ; + tree_item, + + 3 , + tree_node, + allocator > tree_type ; typedef geom_tree::aabb_pred_node_3 < - float, - iptr_type > tree_pred ; + float, + iptr_type > tree_pred ; public : @@ -205,20 +206,19 @@ /*----------------------------- convert to R^3 coord. */ for (auto _iter = - this->_mesh._set1.head() ; + this->_mesh.node().head() ; _iter != - this->_mesh._set1.tend() ; + this->_mesh.node().tend() ; ++_iter ) { if (_iter->mark() >= +0) { - real_type _apos[2]; - real_type _ppos[3]; - + real_type _apos[2] ; _apos[0] = _iter->pval(0); _apos[1] = _iter->pval(1); - toR3(_apos, _ppos); + real_type _ppos[3] ; + toR3(_apos, _ppos) ; _iter->pval(0) = _ppos[0]; _iter->pval(1) = _ppos[1]; @@ -228,9 +228,9 @@ /*----------------------------- calc. aabb for inputs */ for (auto _iter = - this->_mesh._set1.head() ; + this->_mesh.node().head() ; _iter != - this->_mesh._set1.tend() ; + this->_mesh.node().tend() ; ++_iter ) { if (_iter->mark() >= +0) @@ -260,7 +260,7 @@ float static const _RTOL = std::pow ( std::numeric_limits - ::epsilon(), (float) +0.9) ; + ::epsilon(), (float) +0.8) ; iptr_type static constexpr _NBOX=(iptr_type)+8 ; @@ -280,8 +280,8 @@ * _RTOL ; /*-------------------- make aabb-tree and init. bbox. */ - aabb_mesh( this->_mesh._set1 , - this->_mesh._set3 , + aabb_mesh( this->_mesh.node(), + this->_mesh.tri3(), this->_tree,_BTOL , _NBOX , tria_pred()) ; } @@ -336,20 +336,19 @@ allocator:: size_type, allocator > _keys; - containers:: array < - iptr_type , - allocator > _tset; + typename + mesh_type::connector _conn; /*-------------------- push nodes onto priority queue */ _keys.set_count ( - _mesh._set1.count(), + _mesh.node().count() , containers::tight_alloc, _null) ; iptr_type _inum = +0; for (auto _iter = - this->_mesh._set1.head() ; + this->_mesh.node().head(); _iter != - this->_mesh._set1.tend() ; + this->_mesh.node().tend(); ++_iter , ++_inum) { if (_iter->mark() >= +0 ) @@ -367,20 +366,27 @@ _keys[_base] = _null ; - _tset.set_count( +0) ; - this-> - _mesh.node_tri3(_base, _tset); + _conn.set_count( +0) ; + this->_mesh. + connect_2(_base, POINT_tag, _conn) ; - for (auto _next = _tset.head(); - _next != _tset.tend(); - ++_next ) + real_type _hnow = _hval[_base]; + + for (auto _next = _conn.head(); + _next != _conn.tend(); + ++_next ) { + if (_next->_kind == TRIA3_tag) + { + /*--------------------------------------- TRIA-3 case */ + auto _cell =_next->_cell; + auto _inod = this-> - _mesh._set3[*_next].node(0); + _mesh. tri3( _cell).node(0); auto _jnod = this-> - _mesh._set3[*_next].node(1); + _mesh. tri3( _cell).node(1); auto _knod = this-> - _mesh._set3[*_next].node(2); + _mesh. tri3( _cell).node(2); /*-------------------- skip any cells with null nodes */ if (_keys[_inod] == _null && @@ -390,16 +396,34 @@ if (_keys[_knod] == _null && _knod != _base) continue ; + /*-------------------- skip cells due to sorted order */ + real_type _hmax; + _hmax = this->_hval[_inod] ; + _hmax = std::max( + _hmax , this->_hval[_jnod]); + _hmax = std::max( + _hmax , this->_hval[_knod]); + + if (_hmax <= _hnow) continue ; + + /*-------------------- solve for local |dh/dx| limits */ + real_type _iold = + this->_hval[_inod] ; + real_type _jold = + this->_hval[_jnod] ; + real_type _kold = + this->_hval[_knod] ; + if (this->_dhdx.count() >1) { /*-------------------- update adj. set, g = g(x) case */ if (eikonal_tria_3d ( &this-> - _mesh._set1[ _inod].pval(0), + _mesh. node( _inod).pval(0), &this-> - _mesh._set1[ _jnod].pval(0), + _mesh. node( _jnod).pval(0), &this-> - _mesh._set1[ _knod].pval(0), + _mesh. node( _knod).pval(0), this->_hval[_inod], this->_hval[_jnod], this->_hval[_knod], @@ -409,14 +433,17 @@ { if (_keys[_inod] != _null) + if (_hval[_inod] != _iold) _sort.update( _keys[_inod] , _inod) ; if (_keys[_jnod] != _null) + if (_hval[_jnod] != _jold) _sort.update( _keys[_jnod] , _jnod) ; if (_keys[_knod] != _null) + if (_hval[_knod] != _kold) _sort.update( _keys[_knod] , _knod) ; @@ -428,11 +455,11 @@ /*-------------------- update adj. set, const. g case */ if (eikonal_tria_3d ( &this-> - _mesh._set1[ _inod].pval(0), + _mesh. node( _inod).pval(0), &this-> - _mesh._set1[ _jnod].pval(0), + _mesh. node( _jnod).pval(0), &this-> - _mesh._set1[ _knod].pval(0), + _mesh. node( _knod).pval(0), this->_hval[_inod], this->_hval[_jnod], this->_hval[_knod], @@ -442,18 +469,31 @@ { if (_keys[_inod] != _null) + if (_hval[_inod] != _iold) _sort.update( _keys[_inod] , _inod) ; if (_keys[_jnod] != _null) + if (_hval[_jnod] != _jold) _sort.update( _keys[_jnod] , _jnod) ; if (_keys[_knod] != _null) + if (_hval[_knod] != _kold) _sort.update( _keys[_knod] , _knod) ; } + } + + } + else + if (_next->_kind == QUAD4_tag) + { + /*--------------------------------------- QUAD-4 case */ + + + } } } @@ -468,6 +508,7 @@ class find_tria { + /*--------------------------- point-"in"-tria functor */ public : real_type *_ppos ; @@ -520,6 +561,7 @@ class near_tria { + /*--------------------------- point-near-tria functor */ public : real_type *_ppos ; real_type *_qpos ; @@ -611,7 +653,7 @@ */ __static_call - __normal_call bool_type near_pred ( + __inline_call bool_type near_pred ( real_type*_ppos , real_type*_qpos , mesh_type&_mesh , @@ -620,15 +662,15 @@ { geometry::hits_type _hits ; if (geometry::proj_tria_3d(_ppos, - &_mesh._set1[ - _mesh._set3[ - _tpos].node(0)].pval(0) , - &_mesh._set1[ - _mesh._set3[ - _tpos].node(1)].pval(0) , - &_mesh._set1[ - _mesh._set3[ - _tpos].node(2)].pval(0) , + &_mesh. node( + _mesh. tri3( + _tpos).node(0)).pval(0) , + &_mesh. node( + _mesh. tri3( + _tpos).node(1)).pval(0) , + &_mesh. node( + _mesh. tri3( + _tpos).node(2)).pval(0) , _qpos,_hits) ) { return (_hits == @@ -651,11 +693,14 @@ ) { /*------------------------ test whether hint is valid */ - return _hint >= (iptr_type)0 - && _hint < (iptr_type) - this->_mesh._set3.count() - && this->_mesh. - _set3 [_hint].mark() >= 0 ; + iptr_type _iplo = (iptr_type)+0 ; + + iptr_type _iphi = (iptr_type) + this->_mesh.tri3 ().count() ; + + return _hint >= _iplo && + _hint < _iphi && + this-> _mesh.tri3(_hint).mark() >= +0 ; } /* @@ -708,7 +753,7 @@ this-> _tree.near(_PPOS, _func) ; - _hint = _func._tpos ; + _hint = _func. _tpos; } if (_hint != this->null_hint()) @@ -724,22 +769,23 @@ face_node(_fnod, _fpos, 2, 1) ; _fnod[0] = this->_mesh. - _set3[_hint].node(_fnod[0]); + tri3(_hint).node(_fnod[0]); _fnod[1] = this->_mesh. - _set3[_hint].node(_fnod[1]); + tri3(_hint).node(_fnod[1]); + _fnod[2] = this->_mesh. - _set3[_hint].node(_fnod[2]); + tri3(_hint).node(_fnod[2]); real_type _tvol = geometry::tria_area_3d ( &this->_mesh. - _set1[_fnod[0]].pval(0) , + node(_fnod[0]).pval(0) , &this->_mesh. - _set1[_fnod[1]].pval(0) , + node(_fnod[1]).pval(0) , _QPOS) ; _hsum += _tvol * - this->_hval[_fnod[2]] ; + this->_hval[_fnod [ 2 ]] ; _vsum += _tvol ; } diff --git a/src/libcpp/mesh_func/hfun_mesh_euclidean_2.hpp b/src/libcpp/mesh_func/hfun_mesh_euclidean_2.hpp index e10f6a1..2b6dab3 100644 --- a/src/libcpp/mesh_func/hfun_mesh_euclidean_2.hpp +++ b/src/libcpp/mesh_func/hfun_mesh_euclidean_2.hpp @@ -1,7 +1,7 @@ /* -------------------------------------------------------- - * HFUN-MESH-EUCLIDEAN-kD: unstructured H(X) in R^k. + * HFUN-MESH-EUCLIDEAN-2D: unstructured H(x) in E^2. -------------------------------------------------------- * * This program may be freely redistributed under the @@ -31,11 +31,11 @@ * -------------------------------------------------------- * - * Last updated: 12 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/ * -------------------------------------------------------- @@ -58,7 +58,7 @@ { public : - /*------------------------- euclidean size-fun in R^2 */ + /*------------------------- euclidean size-fun in E^2 */ typedef R real_type ; typedef I iptr_type ; @@ -82,11 +82,12 @@ typedef mesh_complex_edge_2 edge_type ; typedef mesh_complex_tria_3 tri3_type ; + typedef mesh_complex_quad_4 quad_type ; - typedef mesh::tria_complex_2< + typedef mesh::mesh_complex_2< node_type, edge_type, - tri3_type, + tri3_type, quad_type, allocator > mesh_type ; typedef geom_tree::aabb_node_base_k @@ -160,9 +161,9 @@ /*----------------------------- calc. aabb for inputs */ for (auto _iter = - this->_mesh._set1.head() ; + this->_mesh.node().head() ; _iter != - this->_mesh._set1.tend() ; + this->_mesh.node().tend() ; ++_iter ) { if (_iter->mark() >= +0) @@ -186,7 +187,7 @@ float static const _RTOL = std::pow ( std::numeric_limits - ::epsilon(), (float) +0.9) ; + ::epsilon(), (float) +0.8) ; iptr_type static constexpr _NBOX=(iptr_type)+4 ; @@ -202,8 +203,8 @@ * _RTOL ; /*-------------------- make aabb-tree and init. bbox. */ - aabb_mesh( this->_mesh._set1 , - this->_mesh._set3 , + aabb_mesh( this->_mesh.node(), + this->_mesh.tri3(), this->_tree,_BTOL , _NBOX , tria_pred()) ; } @@ -258,20 +259,19 @@ allocator:: size_type, allocator > _keys; - containers:: array < - iptr_type , - allocator > _tset; + typename + mesh_type::connector _conn; /*-------------------- push nodes onto priority queue */ _keys.set_count ( - _mesh._set1.count(), + _mesh.node().count() , containers::tight_alloc, _null) ; iptr_type _inum = +0; for (auto _iter = - this->_mesh._set1.head() ; + this->_mesh.node().head(); _iter != - this->_mesh._set1.tend() ; + this->_mesh.node().tend(); ++_iter , ++_inum) { if (_iter->mark() >= +0 ) @@ -289,20 +289,27 @@ _keys[_base] = _null ; - _tset.set_count( +0) ; - this-> - _mesh.node_tri3(_base, _tset); + _conn.set_count( +0) ; + this->_mesh. + connect_2(_base, POINT_tag, _conn) ; + + real_type _hnow = _hval[_base]; - for (auto _next = _tset.head(); - _next != _tset.tend(); - ++_next ) + for (auto _next = _conn.head(); + _next != _conn.tend(); + ++_next ) { + if (_next->_kind == TRIA3_tag) + { + /*--------------------------------------- TRIA-3 case */ + auto _cell =_next->_cell; + auto _inod = this-> - _mesh._set3[*_next].node(0); + _mesh. tri3( _cell).node(0); auto _jnod = this-> - _mesh._set3[*_next].node(1); + _mesh. tri3( _cell).node(1); auto _knod = this-> - _mesh._set3[*_next].node(2); + _mesh. tri3( _cell).node(2); /*-------------------- skip any cells with null nodes */ if (_keys[_inod] == _null && @@ -312,16 +319,34 @@ if (_keys[_knod] == _null && _knod != _base) continue ; + /*-------------------- skip cells due to sorted order */ + real_type _hmax; + _hmax = this->_hval[_inod] ; + _hmax = std::max( + _hmax , this->_hval[_jnod]); + _hmax = std::max( + _hmax , this->_hval[_knod]); + + if (_hmax <= _hnow) continue ; + + /*-------------------- solve for local |dh/dx| limits */ + real_type _iold = + this->_hval[_inod] ; + real_type _jold = + this->_hval[_jnod] ; + real_type _kold = + this->_hval[_knod] ; + if (this->_dhdx.count() >1) { /*-------------------- update adj. set, g = g(x) case */ if (eikonal_tria_2d ( &this-> - _mesh._set1[ _inod].pval(0), + _mesh. node( _inod).pval(0), &this-> - _mesh._set1[ _jnod].pval(0), + _mesh. node( _jnod).pval(0), &this-> - _mesh._set1[ _knod].pval(0), + _mesh. node( _knod).pval(0), this->_hval[_inod], this->_hval[_jnod], this->_hval[_knod], @@ -331,14 +356,17 @@ { if (_keys[_inod] != _null) + if (_hval[_inod] != _iold) _sort.update( _keys[_inod] , _inod) ; if (_keys[_jnod] != _null) + if (_hval[_jnod] != _jold) _sort.update( _keys[_jnod] , _jnod) ; if (_keys[_knod] != _null) + if (_hval[_knod] != _kold) _sort.update( _keys[_knod] , _knod) ; @@ -350,11 +378,11 @@ /*-------------------- update adj. set, const. g case */ if (eikonal_tria_2d ( &this-> - _mesh._set1[ _inod].pval(0), + _mesh. node( _inod).pval(0), &this-> - _mesh._set1[ _jnod].pval(0), + _mesh. node( _jnod).pval(0), &this-> - _mesh._set1[ _knod].pval(0), + _mesh. node( _knod).pval(0), this->_hval[_inod], this->_hval[_jnod], this->_hval[_knod], @@ -364,18 +392,31 @@ { if (_keys[_inod] != _null) + if (_hval[_inod] != _iold) _sort.update( _keys[_inod] , _inod) ; if (_keys[_jnod] != _null) + if (_hval[_jnod] != _jold) _sort.update( _keys[_jnod] , _jnod) ; if (_keys[_knod] != _null) + if (_hval[_knod] != _kold) _sort.update( _keys[_knod] , _knod) ; } + } + + } + else + if (_next->_kind == QUAD4_tag) + { + /*--------------------------------------- QUAD-4 case */ + + + } } } @@ -390,6 +431,7 @@ class find_tria { + /*--------------------------- point-"in"-tria functor */ public : real_type *_ppos ; @@ -442,6 +484,7 @@ class near_tria { + /*--------------------------- point-near-tria functor */ public : real_type *_ppos ; real_type *_qpos ; @@ -530,7 +573,7 @@ */ __static_call - __normal_call bool_type near_pred ( + __inline_call bool_type near_pred ( real_type*_ppos , real_type*_qpos , mesh_type&_mesh , @@ -539,15 +582,15 @@ { geometry::hits_type _hits ; if (geometry::proj_tria_2d(_ppos, - &_mesh._set1[ - _mesh._set3[ - _tpos].node(0)].pval(0) , - &_mesh._set1[ - _mesh._set3[ - _tpos].node(1)].pval(0) , - &_mesh._set1[ - _mesh._set3[ - _tpos].node(2)].pval(0) , + &_mesh. node( + _mesh. tri3( + _tpos).node(0)).pval(0) , + &_mesh. node( + _mesh. tri3( + _tpos).node(1)).pval(0) , + &_mesh. node( + _mesh. tri3( + _tpos).node(2)).pval(0) , _qpos,_hits) ) { return (_hits == @@ -570,11 +613,14 @@ ) { /*------------------------ test whether hint is valid */ - return _hint >= (iptr_type)0 - && _hint < (iptr_type) - this->_mesh._set3.count() - && this->_mesh. - _set3 [_hint].mark() >= 0 ; + iptr_type _iplo = (iptr_type)+0 ; + + iptr_type _iphi = (iptr_type) + this->_mesh.tri3 ().count() ; + + return _hint >= _iplo && + _hint < _iphi && + this-> _mesh.tri3(_hint).mark() >= +0 ; } /* @@ -640,7 +686,7 @@ this-> _tree.near(_PPOS, _func) ; - _hint = _func._tpos ; + _hint = _func. _tpos; } if (_hint != this->null_hint()) @@ -656,22 +702,23 @@ face_node(_fnod, _fpos, 2, 1) ; _fnod[0] = this->_mesh. - _set3[_hint].node(_fnod[0]); + tri3(_hint).node(_fnod[0]); _fnod[1] = this->_mesh. - _set3[_hint].node(_fnod[1]); + tri3(_hint).node(_fnod[1]); + _fnod[2] = this->_mesh. - _set3[_hint].node(_fnod[2]); + tri3(_hint).node(_fnod[2]); real_type _tvol = geometry::tria_area_2d ( &this->_mesh. - _set1[_fnod[0]].pval(0) , + node(_fnod[0]).pval(0) , &this->_mesh. - _set1[_fnod[1]].pval(0) , + node(_fnod[1]).pval(0) , _QPOS) ; _hsum += _tvol * - this->_hval[_fnod[2]] ; + this->_hval[_fnod [ 2 ]] ; _vsum += _tvol ; } diff --git a/src/libcpp/mesh_func/hfun_mesh_euclidean_3.hpp b/src/libcpp/mesh_func/hfun_mesh_euclidean_3.hpp index eeee023..3650ab5 100644 --- a/src/libcpp/mesh_func/hfun_mesh_euclidean_3.hpp +++ b/src/libcpp/mesh_func/hfun_mesh_euclidean_3.hpp @@ -1,7 +1,7 @@ /* -------------------------------------------------------- - * HFUN-MESH-EUCLIDEAN-kD: unstructured H(X) in R^k. + * HFUN-MESH-EUCLIDEAN-3D: unstructured H(x) in E^3. -------------------------------------------------------- * * This program may be freely redistributed under the @@ -11,7 +11,7 @@ * 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 REMAengIN UNDER COPYRIGHT OF THE + * 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 @@ -31,11 +31,11 @@ * -------------------------------------------------------- * - * Last updated: 12 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/ * -------------------------------------------------------- @@ -82,13 +82,18 @@ typedef mesh_complex_edge_2 edge_type ; typedef mesh_complex_tria_3 tri3_type ; + typedef mesh_complex_quad_4 quad_type ; typedef mesh_complex_tria_4 tri4_type ; + typedef mesh_complex_hexa_8 hexa_type ; + typedef mesh_complex_wedg_6 wedg_type ; + typedef mesh_complex_pyra_5 pyra_type ; - typedef mesh::tria_complex_3< + typedef mesh::mesh_complex_3< node_type, edge_type, - tri3_type, - tri4_type, + tri3_type, quad_type, + tri4_type, hexa_type, + wedg_type, pyra_type, allocator > mesh_type ; typedef geom_tree::aabb_node_base_k @@ -162,9 +167,9 @@ /*----------------------------- calc. aabb for inputs */ for (auto _iter = - this->_mesh._set1.head() ; + this->_mesh.node().head() ; _iter != - this->_mesh._set1.tend() ; + this->_mesh.node().tend() ; ++_iter ) { if (_iter->mark() >= +0) @@ -194,7 +199,7 @@ float static const _RTOL = std::pow ( std::numeric_limits - ::epsilon(), (float) +0.9) ; + ::epsilon(), (float) +0.8) ; iptr_type static constexpr _NBOX=(iptr_type)+8 ; @@ -214,8 +219,8 @@ * _RTOL ; /*-------------------- make aabb-tree and init. bbox. */ - aabb_mesh( this->_mesh._set1 , - this->_mesh._set4 , + aabb_mesh( this->_mesh.node(), + this->_mesh.tri4(), this->_tree,_BTOL , _NBOX , tria_pred()) ; } @@ -270,20 +275,19 @@ allocator:: size_type, allocator > _keys; - containers:: array < - iptr_type , - allocator > _tset; + typename + mesh_type::connector _conn; /*-------------------- push nodes onto priority queue */ _keys.set_count ( - _mesh._set1.count(), + _mesh.node().count() , containers::tight_alloc, _null) ; iptr_type _inum = +0; for (auto _iter = - this->_mesh._set1.head() ; + this->_mesh.node().head(); _iter != - this->_mesh._set1.tend() ; + this->_mesh.node().tend(); ++_iter , ++_inum) { if (_iter->mark() >= +0 ) @@ -301,22 +305,29 @@ _keys[_base] = _null ; - _tset.set_count( +0) ; - this-> - _mesh.node_tri4(_base, _tset); + _conn.set_count( +0) ; + this->_mesh. + connect_3(_base, POINT_tag, _conn) ; + + real_type _hnow = _hval[_base]; - for (auto _next = _tset.head(); - _next != _tset.tend(); - ++_next ) + for (auto _next = _conn.head(); + _next != _conn.tend(); + ++_next ) { + if (_next->_kind == TRIA4_tag) + { + /*--------------------------------------- TRIA-4 case */ + auto _cell =_next->_cell; + auto _inod = this-> - _mesh._set4[*_next].node(0); + _mesh. tri4( _cell).node(0); auto _jnod = this-> - _mesh._set4[*_next].node(1); + _mesh. tri4( _cell).node(1); auto _knod = this-> - _mesh._set4[*_next].node(2); + _mesh. tri4( _cell).node(2); auto _lnod = this-> - _mesh._set4[*_next].node(3); + _mesh. tri4( _cell).node(3); /*-------------------- skip any cells with null nodes */ if (_keys[_inod] == _null && @@ -328,18 +339,40 @@ if (_keys[_lnod] == _null && _lnod != _base) continue ; + /*-------------------- skip cells due to sorted order */ + real_type _hmax; + _hmax = this->_hval[_inod] ; + _hmax = std::max( + _hmax , this->_hval[_jnod]); + _hmax = std::max( + _hmax , this->_hval[_knod]); + _hmax = std::max( + _hmax , this->_hval[_lnod]); + + if (_hmax <= _hnow) continue ; + + /*-------------------- solve for local |dh/dx| limits */ + real_type _iold = + this->_hval[_inod] ; + real_type _jold = + this->_hval[_jnod] ; + real_type _kold = + this->_hval[_knod] ; + real_type _lold = + this->_hval[_lnod] ; + if (this->_dhdx.count() >1) { /*-------------------- update adj. set, g = g(x) case */ if (eikonal_tria_3d ( &this-> - _mesh._set1[ _inod].pval(0), + _mesh. node( _inod).pval(0), &this-> - _mesh._set1[ _jnod].pval(0), + _mesh. node( _jnod).pval(0), &this-> - _mesh._set1[ _knod].pval(0), + _mesh. node( _knod).pval(0), &this-> - _mesh._set1[ _lnod].pval(0), + _mesh. node( _lnod).pval(0), this->_hval[_inod], this->_hval[_jnod], this->_hval[_knod], @@ -351,18 +384,22 @@ { if (_keys[_inod] != _null) + if (_hval[_inod] != _iold) _sort.update( _keys[_inod] , _inod) ; if (_keys[_jnod] != _null) + if (_hval[_jnod] != _jold) _sort.update( _keys[_jnod] , _jnod) ; if (_keys[_knod] != _null) + if (_hval[_knod] != _kold) _sort.update( _keys[_knod] , _knod) ; if (_keys[_lnod] != _null) + if (_hval[_lnod] != _lold) _sort.update( _keys[_lnod] , _lnod) ; @@ -374,13 +411,13 @@ /*-------------------- update adj. set, const. g case */ if (eikonal_tria_3d ( &this-> - _mesh._set1[ _inod].pval(0), + _mesh. node( _inod).pval(0), &this-> - _mesh._set1[ _jnod].pval(0), + _mesh. node( _jnod).pval(0), &this-> - _mesh._set1[ _knod].pval(0), + _mesh. node( _knod).pval(0), &this-> - _mesh._set1[ _lnod].pval(0), + _mesh. node( _lnod).pval(0), this->_hval[_inod], this->_hval[_jnod], this->_hval[_knod], @@ -392,22 +429,36 @@ { if (_keys[_inod] != _null) + if (_hval[_inod] != _iold) _sort.update( _keys[_inod] , _inod) ; if (_keys[_jnod] != _null) + if (_hval[_jnod] != _jold) _sort.update( _keys[_jnod] , _jnod) ; if (_keys[_knod] != _null) + if (_hval[_knod] != _kold) _sort.update( _keys[_knod] , _knod) ; if (_keys[_lnod] != _null) + if (_hval[_lnod] != _lold) _sort.update( _keys[_lnod] , _lnod) ; } + } + + } + else + if (_next->_kind == HEXA8_tag) + { + /*--------------------------------------- HEXA-8 case */ + + + } } } @@ -422,6 +473,7 @@ class find_tria { + /*--------------------------- point-"in"-tria functor */ public : real_type *_ppos ; @@ -474,6 +526,7 @@ class near_tria { + /*--------------------------- point-near-tria functor */ public : real_type *_ppos ; real_type *_qpos ; @@ -573,18 +626,18 @@ { geometry::hits_type _hits ; if (geometry::proj_tria_3d(_ppos, - &_mesh._set1[ - _mesh._set4[ - _tpos].node(0)].pval(0) , - &_mesh._set1[ - _mesh._set4[ - _tpos].node(1)].pval(0) , - &_mesh._set1[ - _mesh._set4[ - _tpos].node(2)].pval(0) , - &_mesh._set1[ - _mesh._set4[ - _tpos].node(3)].pval(0) , + &_mesh. node( + _mesh. tri4( + _tpos).node(0)).pval(0) , + &_mesh. node( + _mesh. tri4( + _tpos).node(1)).pval(0) , + &_mesh. node( + _mesh. tri4( + _tpos).node(2)).pval(0) , + &_mesh. node( + _mesh. tri4( + _tpos).node(3)).pval(0) , _qpos,_hits) ) { return (_hits == @@ -607,11 +660,14 @@ ) { /*------------------------- test whether hint is valid */ - return _hint >= (iptr_type)0 - && _hint < (iptr_type) - this->_mesh._set4.count() - && this->_mesh. - _set4 [_hint].mark() >= 0 ; + iptr_type _iplo = (iptr_type)+0 ; + + iptr_type _iphi = (iptr_type) + this->_mesh.tri4 ().count() ; + + return _hint >= _iplo && + _hint < _iphi && + this-> _mesh.tri4(_hint).mark() >= +0 ; } /* @@ -679,7 +735,7 @@ this-> _tree.near(_PPOS, _func) ; - _hint = _func._tpos ; + _hint = _func. _tpos; } if (_hint != this->null_hint()) @@ -695,26 +751,27 @@ face_node(_fnod, _fpos, 3, 2) ; _fnod[0] = this->_mesh. - _set4[_hint].node(_fnod[0]); + tri4(_hint).node(_fnod[0]); _fnod[1] = this->_mesh. - _set4[_hint].node(_fnod[1]); + tri4(_hint).node(_fnod[1]); _fnod[2] = this->_mesh. - _set4[_hint].node(_fnod[2]); + tri4(_hint).node(_fnod[2]); + _fnod[3] = this->_mesh. - _set4[_hint].node(_fnod[3]); + tri4(_hint).node(_fnod[3]); real_type _tvol = geometry::tetra_vol_3d ( &this->_mesh. - _set1[_fnod[0]].pval(0) , + node(_fnod[0]).pval(0) , &this->_mesh. - _set1[_fnod[1]].pval(0) , + node(_fnod[1]).pval(0) , &this->_mesh. - _set1[_fnod[2]].pval(0) , + node(_fnod[2]).pval(0) , _QPOS) ; _hsum += _tvol * - this->_hval[_fnod[3]] ; + this->_hval[_fnod [ 3]] ; _vsum += _tvol ; } diff --git a/src/libcpp/mesh_type/base_complex_k.hpp b/src/libcpp/mesh_type/base_complex_k.hpp new file mode 100644 index 0000000..f1ee5d7 --- /dev/null +++ b/src/libcpp/mesh_type/base_complex_k.hpp @@ -0,0 +1,3336 @@ + + /* + -------------------------------------------------------- + * BASE-COMPLEX-k: mesh complex utilities in T^k. + -------------------------------------------------------- + * + * 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: 11 Sept., 2020 + * + * Copyright 2020-- + * Darren Engwirda + * d.engwirda@gmail.com + * https://github.com/dengwirda/ + * + -------------------------------------------------------- + */ + +# pragma once + +# ifndef __BASE_COMPLEX_K__ +# define __BASE_COMPLEX_K__ + + namespace mesh { + + /* + -------------------------------------------------------- + * BASE-COMPLEX-k utilities for k-cell complexes. + -------------------------------------------------------- + */ + + // Essentially an "unrolled" base class for mesh/tria + // complexes... + + // Concrete tria_complex_k and mesh_complex_k classes + // are composed of the various bits and pieces + // implemented here, depending on dimensionality, and + // whether simplical vs mixed-cell, etc. + + + struct tria_cell {} ; // simplicial vs mixed... + struct mesh_cell {} ; + +# define TOPO_DIMS mesh_type::topo_dims + +# define IPTR_TYPE typename \ + mesh_type::iptr_type +# define INDX_TYPE typename \ + mesh_type::indx_type +# define REAL_TYPE typename \ + mesh_type::real_type + +# define NODE_TYPE typename \ + mesh_type::node_type +# define EDGE_TYPE typename \ + mesh_type::edge_type +# define TRI3_TYPE typename \ + mesh_type::tri3_type +# define QUAD_TYPE typename \ + mesh_type::quad_type +# define TRI4_TYPE typename \ + mesh_type::tri4_type +# define HEXA_TYPE typename \ + mesh_type::hexa_type +# define WEDG_TYPE typename \ + mesh_type::wedg_type +# define PYRA_TYPE typename \ + mesh_type::pyra_type + + /* + -------------------------------------------------------- + * CONN-LIST: cell/kind pair for adjacency. + -------------------------------------------------------- + */ + + class conn_pair + { + /*----------------------- handle adj. mixed cell kind */ + public : + uint32_t _cell ; + char_type _kind ; + public : + /*----------------------- build conn _obj. from _src. */ + __inline_call conn_pair ( + uint32_t _csrc = +0, + char_type _ksrc = +0 + ) : _cell(_csrc), _kind(_ksrc) {} + } ; + + /* + -------------------------------------------------------- + * INIT-LIST: re-size adj. lists on demand. + -------------------------------------------------------- + */ + + template < + typename conn_list + > + __inline_call void_type init_list ( + conn_list&_list, + typename + conn_list::size_type _lpos + ) + { + if (_lpos >= _list._lptr.count()) + _list._lptr.set_count ( + _lpos + 1, + containers::loose_alloc, nullptr) ; + } + + /* + -------------------------------------------------------- + * _POP-LIST: delete item from adj. list. + -------------------------------------------------------- + */ + + template < + typename conn_list + > + __normal_call void_type _pop_list ( + conn_list &_list, + typename + conn_list::size_type _lpos , + typename + conn_list::data_type _item + ) + { + /*--------------------------- scan list and pop match */ + typename conn_list::_write_it + _prev = _list.hend(_lpos) , + _iter = _list.head(_lpos) , + _tend = _list.tend(_lpos) ; + + for ( ; _iter != _tend; + _prev = _iter, ++_iter ) + { + if (_iter->_cell == _item._cell && + _iter->_kind == _item._kind ) + { + _list._pop ( + _prev, _iter, _lpos ) ; + + break ; + } + } + } + + /* + -------------------------------------------------------- + * GET-NODE: "create" new node, push onto active set. + -------------------------------------------------------- + */ + + template < + typename mesh_type + > + __inline_call INDX_TYPE _get_node ( + mesh_type &_mesh + ) + { + INDX_TYPE _ipos; + if (_mesh._ffN1.count() != +0 ) + { + /*---------------------------- recycle from free list */ + _mesh._ffN1._pop_tail(_ipos) ; + } + else + { + /*---------------------------- alloc. from underlying */ + _ipos = + _mesh._llN1.push_tail() ; + } + + _mesh._llN1[_ipos].mark() = 0 ; + _mesh._llN1[_ipos].self() = 0 ; + + return ( _ipos ) ; + } + + /* + -------------------------------------------------------- + * GET-EDGE: "create" new edge, push onto active set. + -------------------------------------------------------- + */ + + template < + typename mesh_type + > + __inline_call INDX_TYPE _get_edge ( + mesh_type &_mesh + ) + { + INDX_TYPE _ipos; + if (_mesh._ffE2.count() != +0 ) + { + /*---------------------------- recycle from free list */ + _mesh._ffE2._pop_tail(_ipos) ; + } + else + { + /*---------------------------- alloc. from underlying */ + _ipos = + _mesh._llE2.push_tail() ; + } + + _mesh._llE2[_ipos].mark() = 0 ; + _mesh._llE2[_ipos].self() = 0 ; + + return ( _ipos ) ; + } + + /* + -------------------------------------------------------- + * GET-TRIA: "create" new tria, push onto active set. + -------------------------------------------------------- + */ + + template < + typename mesh_type + > + __inline_call INDX_TYPE _get_tri3 ( + mesh_type &_mesh + ) + { + INDX_TYPE _ipos; + if (_mesh._ffT3.count() != +0 ) + { + /*---------------------------- recycle from free list */ + _mesh._ffT3._pop_tail(_ipos) ; + } + else + { + /*---------------------------- alloc. from underlying */ + _ipos = + _mesh._llT3.push_tail() ; + } + + _mesh._llT3[_ipos].mark() = 0 ; + _mesh._llT3[_ipos].self() = 0 ; + + return ( _ipos ) ; + } + + /* + -------------------------------------------------------- + * GET-QUAD: "create" new quad, push onto active set. + -------------------------------------------------------- + */ + + template < + typename mesh_type + > + __inline_call INDX_TYPE _get_quad ( + mesh_type &_mesh + ) + { + INDX_TYPE _ipos; + if (_mesh._ffQ4.count() != +0 ) + { + /*---------------------------- recycle from free list */ + _mesh._ffQ4._pop_tail(_ipos) ; + } + else + { + /*---------------------------- alloc. from underlying */ + _ipos = + _mesh._llQ4.push_tail() ; + } + + _mesh._llQ4[_ipos].mark() = 0 ; + _mesh._llQ4[_ipos].self() = 0 ; + + return ( _ipos ) ; + } + + /* + -------------------------------------------------------- + * GET-TRIA: "create" new tria, push onto active set. + -------------------------------------------------------- + */ + + template < + typename mesh_type + > + __inline_call INDX_TYPE _get_tri4 ( + mesh_type &_mesh + ) + { + INDX_TYPE _ipos; + if (_mesh._ffT4.count() != +0 ) + { + /*---------------------------- recycle from free list */ + _mesh._ffT4._pop_tail(_ipos) ; + } + else + { + /*---------------------------- alloc. from underlying */ + _ipos = + _mesh._llT4.push_tail() ; + } + + _mesh._llT4[_ipos].mark() = 0 ; + _mesh._llT4[_ipos].self() = 0 ; + + return ( _ipos ) ; + } + + /* + -------------------------------------------------------- + * GET-HEXA: "create" new hexa, push onto active set. + -------------------------------------------------------- + */ + + template < + typename mesh_type + > + __inline_call INDX_TYPE _get_hexa ( + mesh_type &_mesh + ) + { + INDX_TYPE _ipos; + if (_mesh._ffH8.count() != +0 ) + { + /*---------------------------- recycle from free list */ + _mesh._ffH8._pop_tail(_ipos) ; + } + else + { + /*---------------------------- alloc. from underlying */ + _ipos = + _mesh._llH8.push_tail() ; + } + + _mesh._llH8[_ipos].mark() = 0 ; + _mesh._llH8[_ipos].self() = 0 ; + + return ( _ipos ) ; + } + + /* + -------------------------------------------------------- + * GET-WEDG: "create" new wedg, push onto active set. + -------------------------------------------------------- + */ + + template < + typename mesh_type + > + __inline_call INDX_TYPE _get_wedg ( + mesh_type &_mesh + ) + { + INDX_TYPE _ipos; + if (_mesh._ffW6.count() != +0 ) + { + /*---------------------------- recycle from free list */ + _mesh._ffW6._pop_tail(_ipos) ; + } + else + { + /*---------------------------- alloc. from underlying */ + _ipos = + _mesh._llW6.push_tail() ; + } + + _mesh._llW6[_ipos].mark() = 0 ; + _mesh._llW6[_ipos].self() = 0 ; + + return ( _ipos ) ; + } + + /* + -------------------------------------------------------- + * GET-PYRA: "create" new pyra, push onto active set. + -------------------------------------------------------- + */ + + template < + typename mesh_type + > + __inline_call INDX_TYPE _get_pyra ( + mesh_type &_mesh + ) + { + INDX_TYPE _ipos; + if (_mesh._ffP5.count() != +0 ) + { + /*---------------------------- recycle from free list */ + _mesh._ffP5._pop_tail(_ipos) ; + } + else + { + /*---------------------------- alloc. from underlying */ + _ipos = + _mesh._llP5.push_tail() ; + } + + _mesh._llP5[_ipos].mark() = 0 ; + _mesh._llP5[_ipos].self() = 0 ; + + return ( _ipos ) ; + } + + + + /* + -------------------------------------------------------- + * PUT-ITEM: "delete" old item, _pop from active set. + -------------------------------------------------------- + */ + + template < + typename mesh_type + > + __inline_call void_type _put_node ( + mesh_type&_mesh , + INDX_TYPE _ipos + ) + { + _mesh._ffN1.push_tail (_ipos); + _mesh._llN1[_ipos].mark() = -1 ; + _mesh._llN1[_ipos].self() = -1 ; + } + + template < + typename mesh_type + > + __inline_call void_type _put_edge ( + mesh_type&_mesh , + INDX_TYPE _ipos + ) + { + _mesh._ffE2.push_tail (_ipos); + _mesh._llE2[_ipos].mark() = -1 ; + _mesh._llE2[_ipos].self() = -1 ; + } + + template < + typename mesh_type + > + __inline_call void_type _put_tri3 ( + mesh_type&_mesh , + INDX_TYPE _ipos + ) + { + _mesh._ffT3.push_tail (_ipos); + _mesh._llT3[_ipos].mark() = -1 ; + _mesh._llT3[_ipos].self() = -1 ; + } + + template < + typename mesh_type + > + __inline_call void_type _put_quad ( + mesh_type&_mesh , + INDX_TYPE _ipos + ) + { + _mesh._ffQ4.push_tail (_ipos); + _mesh._llQ4[_ipos].mark() = -1 ; + _mesh._llQ4[_ipos].self() = -1 ; + } + + template < + typename mesh_type + > + __inline_call void_type _put_tri4 ( + mesh_type&_mesh , + INDX_TYPE _ipos + ) + { + _mesh._ffT4.push_tail (_ipos); + _mesh._llT4[_ipos].mark() = -1 ; + _mesh._llT4[_ipos].self() = -1 ; + } + + template < + typename mesh_type + > + __inline_call void_type _put_hexa ( + mesh_type&_mesh , + INDX_TYPE _ipos + ) + { + _mesh._ffH8.push_tail (_ipos); + _mesh._llH8[_ipos].mark() = -1 ; + _mesh._llH8[_ipos].self() = -1 ; + } + + template < + typename mesh_type + > + __inline_call void_type _put_wedg ( + mesh_type&_mesh , + INDX_TYPE _ipos + ) + { + _mesh._ffW6.push_tail (_ipos); + _mesh._llW6[_ipos].mark() = -1 ; + _mesh._llW6[_ipos].self() = -1 ; + } + + template < + typename mesh_type + > + __inline_call void_type _put_pyra ( + mesh_type&_mesh , + INDX_TYPE _ipos + ) + { + _mesh._ffP5.push_tail (_ipos); + _mesh._llP5[_ipos].mark() = -1 ; + _mesh._llP5[_ipos].self() = -1 ; + } + + /* + -------------------------------------------------------- + * PUSH-NODE: append new 0-node to complex. + -------------------------------------------------------- + */ + + template < + typename mesh_type + > + __normal_call IPTR_TYPE push_node ( + mesh_type & _mesh, + NODE_TYPE const& _ndat, + bool_type _link = true, + IPTR_TYPE _itop = -1 , + char_type _kind = EMPTY_tag + ) + { + IPTR_TYPE _ipos = -1 ; + + __unreferenced(_kind) ; // maybe, per TOPODIM + + if (!_link) + { + + __assert( _itop == -1 && + "mesh-complex: non-top node!" ) ; + + /*------------------------ init. external d-face data */ + _ipos = (IPTR_TYPE)_get_node(_mesh) ; + + _mesh._llN1[_ipos] = _ndat ; + _mesh._llN1[_ipos].mark() = 0 ; + + _mesh._llN1[_ipos].self() = 1 ; + _mesh. + _llN1[_ipos].node(0) =_ipos ; + + /*------------------------ init. local adj. index set */ + if constexpr (TOPO_DIMS > +0) + init_list(_mesh._aaN1, _ipos) ; + + } + else + { + + if (_itop == -1) + { + /*------------------------ init. external d-face data */ + _ipos = (IPTR_TYPE)_get_node(_mesh) ; + + _mesh._llN1[_ipos] = _ndat ; + _mesh._llN1[_ipos].mark() = 0 ; + _mesh._llN1[_ipos].self() = 1 ; + + _mesh. + _llN1[_ipos].node(0) = _ipos; + + /*------------------------ init. local adj. index set */ + if constexpr (TOPO_DIMS > +0) + init_list(_mesh._aaN1, _ipos) ; + + } + else + { + /*------------------------ init. internal d-face data */ + __assert(find_node( + _mesh, &_ndat.node(0), _ipos ) && + "mesh-complex: node not here") ; + + /*------------------------ append index to adj. lists */ + if constexpr (TOPO_DIMS > +0) + _mesh._aaN1.push(conn_pair( + _itop, _kind), _ndat.node( 0)) ; + + } + + } + + return _ipos ; + } + + /* + -------------------------------------------------------- + * PUSH-EDGE: append new 1-edge to complex. + -------------------------------------------------------- + */ + + template < + typename mesh_type + > + __normal_call IPTR_TYPE push_edge ( + mesh_type & _mesh, + EDGE_TYPE const& _edat, + bool_type _link = true, + IPTR_TYPE _itop = -1 , + char_type _kind = EMPTY_tag + ) + { + typedef typename + mesh_type::edge_maps EDGE_MAPS; + + __unreferenced(_kind); // maybe, per TOPODIM + + IPTR_TYPE _ipos = -1, _npos; + + if (!_link) + { + + __assert( _itop == -1 && + "mesh-complex: non-top cell!" ) ; + + /*------------------------ init. external d-face data */ + _ipos = (IPTR_TYPE)_get_edge(_mesh) ; + + _mesh._llE2[_ipos] = _edat ; + _mesh._llE2[_ipos].mark() = 0 ; + _mesh._llE2[_ipos].self() = 1 ; + + /*------------------------ init. local adj. index set */ + if constexpr (TOPO_DIMS > +1) + init_list(_mesh._aaE2, _ipos) ; + + } + else + { + + /*------------------------ init. external d-face data */ + _ipos = (IPTR_TYPE)_get_edge(_mesh) ; + + _mesh._llE2[_ipos] = _edat ; + _mesh._llE2[_ipos].mark() = 0 ; + + if (_itop == -1) + _mesh._llE2[_ipos].self() = 1 ; + else + _mesh._llE2[_ipos].self() = 0 ; + + typename + EDGE_MAPS::_write_it _same ; + if (_mesh. + _mmE2.find(_ipos, _same)) + { + /*---- existing d-face found: append to existing data */ + if (_itop == -1) + { + /*----- if it's a "top"-level face, copy data */ + _mesh._llE2[*_same] = + _mesh._llE2[ _ipos] ; + } + else + { + /*----- otherwise, append index to adj. lists */ + if constexpr (TOPO_DIMS > +1) + _mesh._aaE2.push( + conn_pair(_itop, _kind),*_same) ; + } + + _put_edge(_mesh, _ipos) ; + } + else + { + /*---- d-face is new: push and descend to (d-1)-faces */ + if (_itop == -1) + { + /*----- if it's a "top"-level face, keep data */ + if constexpr (TOPO_DIMS > +1) + init_list( + _mesh._aaE2, _ipos) ; + } + else + { + /*----- otherwise, append index to adj. lists */ + if constexpr (TOPO_DIMS > +1) + _mesh._aaE2.push( + conn_pair(_itop, _kind), _ipos) ; + } + + /*-------------- descend into (d-1)-face data */ + for (_npos = 2; _npos-- != 0; ) + { + NODE_TYPE _ndat; + _ndat.node(0) = + _edat.node(_npos) ; + + push_node(_mesh, _ndat, + _link,_ipos, EDGE2_tag) ; + } + + /*-------------- push new face data onto hash */ + _mesh._mmE2.push(_ipos) ; + } + + } + + return _ipos ; + } + + /* + -------------------------------------------------------- + * PUSH-TRIA: append new 2-tria to complex. + -------------------------------------------------------- + */ + + template < + typename mesh_type + > + __normal_call IPTR_TYPE push_tri3 ( + mesh_type & _mesh, + TRI3_TYPE const& _tdat, + bool_type _link = true, + IPTR_TYPE _itop = -1 , + char_type _kind = EMPTY_tag + ) + { + typedef typename + mesh_type::tri3_maps TRI3_MAPS; + + __unreferenced(_kind); // maybe, per TOPODIM + + IPTR_TYPE _ipos = -1, _epos; + + if (!_link) + { + + __assert( _itop == -1 && + "mesh-complex: non-top cell!" ) ; + + __unreferenced(_kind) ; + + /*------------------------ init. external d-face data */ + _ipos = (IPTR_TYPE)_get_tri3(_mesh) ; + + _mesh._llT3[_ipos] = _tdat ; + _mesh._llT3[_ipos].mark() = 0 ; + _mesh._llT3[_ipos].self() = 1 ; + + /*------------------------ init. local adj. index set */ + if constexpr (TOPO_DIMS > +2) + init_list(_mesh._aaT3, _ipos) ; + + } + else + { + + /*------------------------ init. external d-face data */ + _ipos = (IPTR_TYPE)_get_tri3(_mesh) ; + + _mesh._llT3[_ipos] = _tdat ; + _mesh._llT3[_ipos].mark() = 0 ; + + if (_itop == -1) + _mesh._llT3[_ipos].self() = 1 ; + else + _mesh._llT3[_ipos].self() = 0 ; + + typename + TRI3_MAPS::_write_it _same ; + if (_mesh. + _mmT3.find(_ipos, _same)) + { + /*---- existing d-face found: append to existing data */ + if (_itop == -1) + { + /*----- if it's a "top"-level face, copy data */ + _mesh._llT3[*_same] = + _mesh._llT3[ _ipos] ; + } + else + { + /*----- otherwise, append index to adj. lists */ + if constexpr (TOPO_DIMS > +2) + _mesh._aaT3.push( + conn_pair(_itop, _kind),*_same) ; + } + + _put_tri3(_mesh, _ipos) ; + } + else + { + /*---- d-face is new: push and descend to (d-1)-faces */ + if (_itop == -1) + { + /*----- if it's a "top"-level face, keep data */ + if constexpr (TOPO_DIMS > +2) + init_list( + _mesh._aaT3, _ipos) ; + } + else + { + /*----- otherwise, append index to adj. lists */ + if constexpr (TOPO_DIMS > +2) + _mesh._aaT3.push( + conn_pair(_itop, _kind), _ipos) ; + } + + /*-------------- descend into (d-1)-face data */ + for (_epos = +3; _epos-- != 0 ; ) + { + IPTR_TYPE _enod [3]; + mesh_type::tri3_type:: + face_node(_enod, _epos, 2, 1) ; + + EDGE_TYPE _edat; + _edat.node(0) = + _tdat.node(_enod[0]) ; + _edat.node(1) = + _tdat.node(_enod[1]) ; + + push_edge(_mesh, _edat, + _link,_ipos, TRIA3_tag) ; + } + + /*-------------- push new face data onto hash */ + _mesh._mmT3.push(_ipos) ; + } + + } + + return _ipos ; + } + + /* + -------------------------------------------------------- + * PUSH-QUAD: append new 2-quad to complex. + -------------------------------------------------------- + */ + + template < + typename mesh_type + > + __normal_call IPTR_TYPE push_quad ( + mesh_type & _mesh, + QUAD_TYPE const& _qdat, + bool_type _link = true, + IPTR_TYPE _itop = -1 , + char_type _kind = EMPTY_tag + ) + { + typedef typename + mesh_type::quad_maps QUAD_MAPS; + + __unreferenced(_kind); // maybe, per TOPODIM + + IPTR_TYPE _ipos = -1, _epos; + + if (!_link) + { + + __assert( _itop == -1 && + "mesh-complex: non-top cell!" ) ; + + __unreferenced(_kind) ; + + /*------------------------ init. external d-face data */ + _ipos = (IPTR_TYPE)_get_quad(_mesh) ; + + _mesh._llQ4[_ipos] = _qdat ; + _mesh._llQ4[_ipos].mark() = 0 ; + _mesh._llQ4[_ipos].self() = 1 ; + + /*------------------------ init. local adj. index set */ + if constexpr (TOPO_DIMS > +2) + init_list(_mesh._aaQ4, _ipos) ; + + } + else + { + + /*------------------------ init. external d-face data */ + _ipos = (IPTR_TYPE)_get_quad(_mesh) ; + + _mesh._llQ4[_ipos] = _qdat ; + _mesh._llQ4[_ipos].mark() = 0 ; + + if (_itop == -1) + _mesh._llQ4[_ipos].self() = 1 ; + else + _mesh._llQ4[_ipos].self() = 0 ; + + typename + QUAD_MAPS::_write_it _same ; + if (_mesh. + _mmQ4.find(_ipos, _same)) + { + /*---- existing d-face found: append to existing data */ + if (_itop == -1) + { + /*----- if it's a "top"-level face, copy data */ + _mesh._llQ4[*_same] = + _mesh._llQ4[ _ipos] ; + } + else + { + /*----- otherwise, append index to adj. lists */ + if constexpr (TOPO_DIMS > +2) + _mesh._aaQ4.push( + conn_pair(_itop, _kind),*_same) ; + } + + _put_quad(_mesh, _ipos) ; + } + else + { + /*---- d-face is new: push and descend to (d-1)-faces */ + if (_itop == -1) + { + /*----- if it's a "top"-level face, keep data */ + if constexpr (TOPO_DIMS > +2) + init_list( + _mesh._aaQ4, _ipos) ; + } + else + { + /*----- otherwise, append index to adj. lists */ + if constexpr (TOPO_DIMS > +2) + _mesh._aaQ4.push( + conn_pair(_itop, _kind), _ipos) ; + } + + /*-------------- descend into (d-1)-face data */ + for (_epos = +4; _epos-- != 0 ; ) + { + IPTR_TYPE _enod [4]; + mesh_type::quad_type:: + face_node(_enod, _epos, 2, 1) ; + + EDGE_TYPE _edat; + _edat.node(0) = + _qdat.node(_enod[0]) ; + _edat.node(1) = + _qdat.node(_enod[1]) ; + + push_edge(_mesh, _edat, + _link,_ipos, QUAD4_tag) ; + } + + /*-------------- push new face data onto hash */ + _mesh._mmQ4.push(_ipos) ; + } + + } + + return _ipos ; + } + + /* + -------------------------------------------------------- + * PUSH-TRIA: append new 3-tria to complex. + -------------------------------------------------------- + */ + + template < + typename mesh_type + > + __normal_call IPTR_TYPE push_tri4 ( + mesh_type & _mesh, + TRI4_TYPE const& _tdat, + bool_type _link = true, + IPTR_TYPE _itop = -1 , + char_type _kind = EMPTY_tag + ) + { + typedef typename + mesh_type::tri4_maps TRI4_MAPS; + + __unreferenced(_kind); // maybe, per TOPODIM + + IPTR_TYPE _ipos = -1, _fpos; + + if (!_link) + { + + __assert( _itop == -1 && + "mesh-complex: non-top cell!" ) ; + + __unreferenced(_kind) ; + + /*------------------------ init. external d-face data */ + _ipos = (IPTR_TYPE)_get_tri4(_mesh) ; + + _mesh._llT4[_ipos] = _tdat ; + _mesh._llT4[_ipos].mark() = 0 ; + _mesh._llT4[_ipos].self() = 1 ; + + /*------------------------ init. local adj. index set */ + if constexpr (TOPO_DIMS > +3) + init_list(_mesh._aaT4, _ipos) ; + + } + else + { + + /*------------------------ init. external d-face data */ + _ipos = (IPTR_TYPE)_get_tri4(_mesh) ; + + _mesh._llT4[_ipos] = _tdat ; + _mesh._llT4[_ipos].mark() = 0 ; + + if (_itop == -1) + _mesh._llT4[_ipos].self() = 1 ; + else + _mesh._llT4[_ipos].self() = 0 ; + + typename + TRI4_MAPS::_write_it _same ; + if (_mesh. + _mmT4.find(_ipos, _same)) + { + /*---- existing d-face found: append to existing data */ + if (_itop == -1) + { + /*----- if it's a "top"-level face, copy data */ + _mesh._llT4[*_same] = + _mesh._llT4[ _ipos] ; + } + else + { + /*----- otherwise, append index to adj. lists */ + if constexpr (TOPO_DIMS > +3) + _mesh._aaT4.push( + conn_pair(_itop, _kind),*_same) ; + } + + _put_tri4(_mesh, _ipos) ; + } + else + { + /*---- d-face is new: push and descend to (d-1)-faces */ + if (_itop == -1) + { + /*----- if it's a "top"-level face, keep data */ + if constexpr (TOPO_DIMS > +3) + init_list(_mesh, + _mesh._aaT4, _ipos) ; + } + else + { + /*----- otherwise, append index to adj. lists */ + if constexpr (TOPO_DIMS > +3) + _mesh._aaT4.push( + conn_pair(_itop, _kind), _ipos) ; + } + + /*-------------- descend into (d-1)-face data */ + for (_fpos = +4; _fpos-- != 0 ; ) + { + IPTR_TYPE _fnod [4]; + mesh_type::tri4_type:: + face_node(_fnod, _fpos, 3, 2) ; + + TRI3_TYPE _fdat; + _fdat.node(0) = + _tdat.node(_fnod[0]) ; + _fdat.node(1) = + _tdat.node(_fnod[1]) ; + _fdat.node(2) = + _tdat.node(_fnod[2]) ; + + push_tri3(_mesh, _fdat, + _link,_ipos, TRIA4_tag) ; + } + + /*-------------- push new face data onto hash */ + _mesh._mmT4.push(_ipos) ; + } + + } + + return _ipos ; + } + + /* + -------------------------------------------------------- + * MAKE-LINK: build item-to-item adj. + -------------------------------------------------------- + */ + + template < + typename mesh_type + > + __normal_call void_type link_edge ( + mesh_type&_mesh + ) + { + IPTR_TYPE _epos = +0 ; + for (auto _iter = _mesh._llE2.head() ; + _iter != _mesh._llE2.tend() ; + ++_iter, ++_epos ) + { + if (_iter->mark() < 0) continue ; + + /*-------------- push face data onto hash set */ + _mesh._mmE2.push(_epos) ; + + /*-------------- descend into (d-1)-face data */ + IPTR_TYPE _ipos; + for (_ipos = +2; _ipos-- != 0 ; ) + { + NODE_TYPE _ndat; + _ndat.node(0) = + _iter->node( _ipos) ; + + push_node(_mesh, _ndat, + true, _epos, EDGE2_tag) ; + } + } + } + + template < + typename mesh_type + > + __normal_call void_type link_tri3 ( + mesh_type&_mesh + ) + { + IPTR_TYPE _tpos = +0 ; + for (auto _iter = _mesh._llT3.head() ; + _iter != _mesh._llT3.tend() ; + ++_iter, ++_tpos ) + { + if (_iter->mark() < 0) continue ; + + /*-------------- push face data onto hash set */ + _mesh._mmT3.push(_tpos) ; + + /*-------------- descend into (d-1)-face data */ + IPTR_TYPE _ipos; + for (_ipos = +3; _ipos-- != 0 ; ) + { + IPTR_TYPE _enod [3]; + mesh_type::tri3_type:: + face_node(_enod, _ipos, 2, 1) ; + + EDGE_TYPE _edat ; + _edat.node(0) = + _iter->node(_enod[0]) ; + _edat.node(1) = + _iter->node(_enod[1]) ; + + push_edge(_mesh, _edat, + true, _tpos, TRIA3_tag) ; + } + } + } + + template < + typename mesh_type + > + __normal_call void_type link_quad ( + mesh_type&_mesh + ) + { + IPTR_TYPE _qpos = +0 ; + for (auto _iter = _mesh._llQ4.head() ; + _iter != _mesh._llQ4.tend() ; + ++_iter, ++_qpos ) + { + if (_iter->mark() < 0) continue ; + + /*-------------- push face data onto hash set */ + _mesh._mmQ4.push(_qpos) ; + + /*-------------- descend into (d-1)-face data */ + IPTR_TYPE _ipos; + for (_ipos = +4; _ipos-- != 0 ; ) + { + IPTR_TYPE _enod [4]; + mesh_type::quad_type:: + face_node(_enod, _ipos, 2, 1) ; + + EDGE_TYPE _edat ; + _edat.node(0) = + _iter->node(_enod[0]) ; + _edat.node(1) = + _iter->node(_enod[1]) ; + + push_edge(_mesh, _edat, + true, _qpos, QUAD4_tag) ; + } + } + } + + template < + typename mesh_type + > + __normal_call void_type link_tri4 ( + mesh_type&_mesh + ) + { + IPTR_TYPE _Tpos = +0 ; + for (auto _iter = _mesh._llT4.head() ; + _iter != _mesh._llT4.tend() ; + ++_iter, ++_Tpos ) + { + if (_iter->mark() < 0) continue ; + + /*-------------- push face data onto hash set */ + _mesh._mmT4.push(_Tpos) ; + + /*-------------- descend into (d-1)-face data */ + IPTR_TYPE _ipos; + for (_ipos = +4; _ipos-- != 0 ; ) + { + IPTR_TYPE _fnod [4]; + mesh_type::tri4_type:: + face_node(_fnod, _ipos, 3, 2) ; + + TRI3_TYPE _fdat ; + _fdat.node(0) = + _iter->node(_fnod[0]) ; + _fdat.node(1) = + _iter->node(_fnod[1]) ; + _fdat.node(2) = + _iter->node(_fnod[2]) ; + + push_tri3(_mesh, _fdat, + true, _Tpos, TRIA4_tag) ; + } + } + } + + /* + -------------------------------------------------------- + * NULL-ITEM: TRUE if item is delete-able. + -------------------------------------------------------- + */ + + template < + typename mesh_type + > + __inline_call bool_type null_node ( + mesh_type&_mesh , + IPTR_TYPE _npos + ) + { + if constexpr (TOPO_DIMS > +0 ) + { + return _mesh._llN1[_npos].self() == 0 + && _mesh._aaN1.empty(_npos); + } + else + return _mesh._llN1[_npos].self() == 0; + } + + template < + typename mesh_type + > + __inline_call bool_type null_edge ( + mesh_type&_mesh , + IPTR_TYPE _epos + ) + { + if constexpr (TOPO_DIMS > +1 ) + { + return _mesh._llE2[_epos].self() == 0 + && _mesh._aaE2.empty(_epos); + } + else + return _mesh._llE2[_epos].self() == 0; + } + + template < + typename mesh_type + > + __inline_call bool_type null_tri3 ( + mesh_type&_mesh , + IPTR_TYPE _tpos + ) + { + if constexpr (TOPO_DIMS > +2 ) + { + return _mesh._llT3[_tpos].self() == 0 + && _mesh._aaT3.empty(_tpos); + } + else + return _mesh._llT3[_tpos].self() == 0; + } + + template < + typename mesh_type + > + __inline_call bool_type null_quad ( + mesh_type&_mesh , + IPTR_TYPE _qpos + ) + { + if constexpr (TOPO_DIMS > +2 ) + { + return _mesh._llQ4[_qpos].self() == 0 + && _mesh._aaQ4.empty(_qpos); + } + else + return _mesh._llQ4[_qpos].self() == 0; + } + + template < + typename mesh_type + > + __inline_call bool_type null_tri4 ( + mesh_type&_mesh , + IPTR_TYPE _tpos + ) + { + if constexpr (TOPO_DIMS > +3 ) + { + return _mesh._llT4[_tpos].self() == 0 + && _mesh._aaT4.empty(_tpos); + } + else + return _mesh._llT4[_tpos].self() == 0; + } + + template < + typename mesh_type + > + __inline_call bool_type null_hexa ( + mesh_type&_mesh , + IPTR_TYPE _hpos + ) + { + if constexpr (TOPO_DIMS > +3 ) + { + return _mesh._llH8[_hpos].self() == 0 + && _mesh._aaH8.empty(_hpos); + } + else + return _mesh._llH8[_hpos].self() == 0; + } + + template < + typename mesh_type + > + __inline_call bool_type null_wedg ( + mesh_type&_mesh , + IPTR_TYPE _wpos + ) + { + if constexpr (TOPO_DIMS > +3 ) + { + return _mesh._llW6[_wpos].self() == 0 + && _mesh._aaW6.empty(_wpos); + } + else + return _mesh._llW6[_wpos].self() == 0; + } + + template < + typename mesh_type + > + __inline_call bool_type null_pyra ( + mesh_type&_mesh , + IPTR_TYPE _ppos + ) + { + if constexpr (TOPO_DIMS > +3 ) + { + return _mesh._llP5[_ppos].self() == 0 + && _mesh._aaP5.empty(_ppos); + } + else + return _mesh._llP5[_ppos].self() == 0; + } + + /* + -------------------------------------------------------- + * _POP-NODE: delete 0-node from complex. + -------------------------------------------------------- + */ + + template < + typename mesh_type + > + __inline_call void_type _pop_node ( + mesh_type&_mesh , + IPTR_TYPE const*_nptr, + IPTR_TYPE _itop = -1 , + char_type _kind = EMPTY_tag + ) + { + IPTR_TYPE _npos = -1 ; + + IPTR_TYPE _node[1]; + _node[0] = _nptr[0]; + + /*-------------------------- find current 0-node pos. */ + if ( !find_node (_mesh, _node, _npos)) + { + return ; + } + + /*-------------------------- _pop current 0-node data */ + _pop_node(_mesh, _npos, _itop, _kind); + } + + template < + typename mesh_type + > + __inline_call void_type _pop_node ( + mesh_type&_mesh , + IPTR_TYPE _npos , + IPTR_TYPE _itop = -1 , + char_type _kind = EMPTY_tag + ) + { + __unreferenced(_kind); // maybe, per TOPODIM + + if (_itop != -1) + { + /*---- deleteing (d+k)-face: scan adj. and _pop _itop */ + if constexpr ( TOPO_DIMS > 0 ) + _pop_list(_mesh. _aaN1 , + _npos, + conn_pair(_itop, _kind)) ; + } + else + { + /*---- deleting (d+0)-face: set "self" marker to null */ + _mesh. + _llN1[_npos].self() = +0 ; + } + + if (null_node(_mesh, _npos)) + { + /*---- ref. count: delete (d+0), (d-1)-faces if empty */ + _put_node(_mesh, _npos); + } + } + + /* + -------------------------------------------------------- + * _POP-EDGE: delete 1-edge from complex. + -------------------------------------------------------- + */ + + template < + typename mesh_type + > + __inline_call void_type _pop_edge ( + mesh_type&_mesh , + IPTR_TYPE const*_nptr, + IPTR_TYPE _itop = -1 , + char_type _kind = EMPTY_tag + ) + { + IPTR_TYPE _epos = -1 ; + + IPTR_TYPE _node[2]; + _node[0] = _nptr[0]; + _node[1] = _nptr[1]; + + /*-------------------------- find current 1-cell pos. */ + if ( !find_edge (_mesh, _node, _epos)) + { + return ; + } + + /*-------------------------- _pop current 1-cell data */ + _pop_edge(_mesh, _epos, _itop, _kind); + } + + template < + typename mesh_type + > + __normal_call void_type _pop_edge ( + mesh_type&_mesh , + IPTR_TYPE _epos , + IPTR_TYPE _itop = -1 , + char_type _kind = EMPTY_tag + ) + { + IPTR_TYPE _npos = -1 ; + + __unreferenced(_kind); // maybe, per TOPODIM + + if (_itop != -1) + { + /*---- deleteing (d+k)-face: scan adj. and _pop _itop */ + if constexpr ( TOPO_DIMS > 1 ) + _pop_list(_mesh. _aaE2 , + _epos, + conn_pair(_itop, _kind)) ; + } + else + { + /*---- deleting (d+0)-face: set "self" marker to null */ + _mesh. + _llE2[_epos].self() = +0 ; + } + + if (null_edge(_mesh, _epos)) + { + /*---- ref. count: delete (d+0), (d-1)-faces if empty */ + IPTR_TYPE _same ; + _mesh._mmE2._pop(_epos, _same) ; + + IPTR_TYPE _node [ 2] ; + _node[0] = + _mesh._llE2[_epos].node(0) ; + _node[1] = + _mesh._llE2[_epos].node(1) ; + + _put_edge(_mesh, _epos) ; + + for (_npos = 2; _npos-- != 0; ) + { + _pop_node(_mesh, + &_node [_npos], + _epos, EDGE2_tag) ; + } + } + } + + /* + -------------------------------------------------------- + * _POP-TRIA: delete 2-tria from complex. + -------------------------------------------------------- + */ + + template < + typename mesh_type + > + __inline_call void_type _pop_tri3 ( + mesh_type&_mesh , + IPTR_TYPE const*_nptr, + IPTR_TYPE _itop = -1 , + char_type _kind = EMPTY_tag + ) + { + IPTR_TYPE _tpos = -1 ; + + IPTR_TYPE _node[3]; + _node[0] = _nptr[0]; + _node[1] = _nptr[1]; + _node[2] = _nptr[2]; + + /*-------------------------- find current 2-cell pos. */ + if ( !find_tri3 (_mesh, _node, _tpos)) + { + return ; + } + + /*-------------------------- _pop current 2-cell data */ + _pop_tri3(_mesh, _tpos, _itop, _kind); + } + + template < + typename mesh_type + > + __normal_call void_type _pop_tri3 ( + mesh_type&_mesh , + IPTR_TYPE _tpos , + IPTR_TYPE _itop = -1 , + char_type _kind = EMPTY_tag + ) + { + IPTR_TYPE _epos = -1 ; + + __unreferenced(_kind); // maybe, per TOPODIM + + if (_itop != -1) + { + /*---- deleteing (d+k)-face: scan adj. and _pop _itop */ + if constexpr ( TOPO_DIMS > 2 ) + _pop_list(_mesh. _aaT3 , + _tpos, + conn_pair(_itop, _kind)) ; + } + else + { + /*---- deleting (d+0)-face: set "self" marker to null */ + _mesh. + _llT3[_tpos].self() = +0 ; + } + + if (null_tri3(_mesh, _tpos)) + { + /*---- ref. count: delete (d+0), (d-1)-faces if empty */ + + IPTR_TYPE _same ; + _mesh._mmT3._pop(_tpos, _same) ; + + IPTR_TYPE _node [ 3] ; + _node[0] = + _mesh._llT3[_tpos].node(0) ; + _node[1] = + _mesh._llT3[_tpos].node(1) ; + _node[2] = + _mesh._llT3[_tpos].node(2) ; + + _put_tri3(_mesh, _tpos); + + for (_epos = 3; _epos-- != 0; ) + { + IPTR_TYPE _enod [3]; + mesh_type::tri3_type:: + face_node(_enod, _epos, 2, 1) ; + + _enod[0] = + _node[_enod [0]] ; + _enod[1] = + _node[_enod [1]] ; + + _pop_edge(_mesh, + _enod,_tpos, TRIA3_tag) ; + } + } + } + + /* + -------------------------------------------------------- + * _POP-QUAD: delete 2-quad from complex. + -------------------------------------------------------- + */ + + template < + typename mesh_type + > + __inline_call void_type _pop_quad ( + mesh_type&_mesh , + IPTR_TYPE const*_nptr, + IPTR_TYPE _itop = -1 , + char_type _kind = EMPTY_tag + ) + { + IPTR_TYPE _qpos = -1 ; + + IPTR_TYPE _node[4]; + _node[0] = _nptr[0]; + _node[1] = _nptr[1]; + _node[2] = _nptr[2]; + _node[3] = _nptr[3]; + + /*-------------------------- find current 2-cell pos. */ + if ( !find_quad (_mesh, _node, _qpos)) + { + return ; + } + + /*-------------------------- _pop current 2-cell data */ + _pop_quad(_mesh, _qpos, _itop, _kind); + } + + template < + typename mesh_type + > + __normal_call void_type _pop_quad ( + mesh_type&_mesh , + IPTR_TYPE _qpos , + IPTR_TYPE _itop = -1 , + char_type _kind = EMPTY_tag + ) + { + IPTR_TYPE _epos = -1 ; + + __unreferenced(_kind); // maybe, per TOPODIM + + if (_itop != -1) + { + /*---- deleteing (d+k)-face: scan adj. and _pop _itop */ + if constexpr ( TOPO_DIMS > 2 ) + _pop_list(_mesh. _aaQ4 , + _qpos, + conn_pair(_itop, _kind)) ; + } + else + { + /*---- deleting (d+0)-face: set "self" marker to null */ + _mesh. + _llQ4[_qpos].self() = +0 ; + } + + if (null_quad(_mesh, _qpos)) + { + /*---- ref. count: delete (d+0), (d-1)-faces if empty */ + + IPTR_TYPE _same ; + _mesh._mmQ4._pop(_qpos, _same) ; + + IPTR_TYPE _node [ 4] ; + _node[0] = + _mesh._llQ4[_qpos].node(0) ; + _node[1] = + _mesh._llQ4[_qpos].node(1) ; + _node[2] = + _mesh._llQ4[_qpos].node(2) ; + _node[3] = + _mesh._llQ4[_qpos].node(3) ; + + _put_quad (_mesh, _qpos); + + for (_epos = 4; _epos-- != 0; ) + { + IPTR_TYPE _enod [4]; + mesh_type::quad_type:: + face_node(_enod, _epos, 2, 1) ; + + _enod[0] = + _node[_enod [0]] ; + _enod[1] = + _node[_enod [1]] ; + + _pop_edge(_mesh, + _enod,_qpos, QUAD4_tag) ; + } + } + } + + /* + -------------------------------------------------------- + * _POP-TRIA: delete 3-tria from complex. + -------------------------------------------------------- + */ + + template < + typename mesh_type + > + __inline_call void_type _pop_tri4 ( + mesh_type&_mesh , + IPTR_TYPE const*_nptr, + IPTR_TYPE _itop = -1 , + char_type _kind = EMPTY_tag + ) + { + IPTR_TYPE _tpos = -1 ; + + IPTR_TYPE _node[4]; + _node[0] = _nptr[0]; + _node[1] = _nptr[1]; + _node[2] = _nptr[2]; + _node[3] = _nptr[3]; + + /*-------------------------- find current 3-cell pos. */ + if ( !find_tri4 (_mesh, _node, _tpos)) + { + return ; + } + + /*-------------------------- _pop current 3-cell data */ + _pop_tri4(_mesh, _tpos, _itop, _kind); + } + + template < + typename mesh_type + > + __normal_call void_type _pop_tri4 ( + mesh_type&_mesh , + IPTR_TYPE _tpos , + IPTR_TYPE _itop = -1 , + char_type _kind = EMPTY_tag + ) + { + IPTR_TYPE _fpos = -1 ; + + __unreferenced(_kind); // maybe, per TOPODIM + + if (_itop != -1) + { + /*---- deleteing (d+k)-face: scan adj. and _pop _itop */ + if constexpr ( TOPO_DIMS > 3 ) + _pop_list(_mesh. _aaT4 , + _tpos, + conn_pair(_itop, _kind)) ; + } + else + { + /*---- deleting (d+0)-face: set "self" marker to null */ + _mesh. + _llT4[_tpos].self() = +0 ; + } + + if (null_tri4(_mesh, _tpos)) + { + /*---- ref. count: delete (d+0), (d-1)-faces if empty */ + + IPTR_TYPE _same ; + _mesh._mmT4._pop(_tpos, _same) ; + + IPTR_TYPE _node [ 4] ; + _node[0] = + _mesh._llT4[_tpos].node(0) ; + _node[1] = + _mesh._llT4[_tpos].node(1) ; + _node[2] = + _mesh._llT4[_tpos].node(2) ; + _node[3] = + _mesh._llT4[_tpos].node(3) ; + + _put_tri4 (_mesh, _tpos) ; + + for (_fpos = 4; _fpos-- != 0; ) + { + IPTR_TYPE _fnod [4]; + mesh_type::tri4_type:: + face_node(_fnod, _fpos, 3, 2) ; + + _fnod[0] = + _node[_fnod [0]] ; + _fnod[1] = + _node[_fnod [1]] ; + _fnod[2] = + _node[_fnod [2]] ; + + _pop_tri3(_mesh, + _fnod,_tpos, TRIA4_tag) ; + } + } + } + + /* + -------------------------------------------------------- + * FIND-NODE: return index of assoc. 0-node. + -------------------------------------------------------- + */ + + template < + typename mesh_type + > + __inline_call bool_type find_node ( + mesh_type&_mesh , + IPTR_TYPE const*_nptr , + IPTR_TYPE&_npos + ) + { + /*-------------------------- find current 0-node pos. */ + IPTR_TYPE _node = + (IPTR_TYPE) _nptr[0] ; + + if (_mesh._llN1.bounds(_node) && + _mesh._llN1[_node].mark() >= +0) + { + /*------------------------------- found matching node */ + _npos =_node ; + + return true ; + } + else + { + /*------------------------------- couldn't find match */ + return false ; + } + } + + /* + -------------------------------------------------------- + * FIND-EDGE: return index of assoc. 1-edge. + -------------------------------------------------------- + */ + + template < + typename mesh_type + > + __normal_call bool_type find_edge ( + mesh_type&_mesh , + IPTR_TYPE const*_node , + IPTR_TYPE&_epos + ) + { + /*-------------------------- find current 2-cell pos. */ + IPTR_TYPE _ipos = + (IPTR_TYPE) _get_edge(_mesh); + + _mesh. + _llE2[_ipos].node(0) = _node[0]; + _mesh. + _llE2[_ipos].node(1) = _node[1]; + + typename + mesh_type:: + edge_maps::_write_it _same ; + if (_mesh. + _mmE2.find(_ipos,_same)) + { + /*------------------------------- found matching cell */ + _put_edge(_mesh, _ipos); + + _epos=*_same ; + + return true ; + } + else + { + /*------------------------------- couldn't find match */ + _put_edge(_mesh, _ipos); + + return false ; + } + } + + /* + -------------------------------------------------------- + * FIND-TRIA: return index of assoc. 2-tria. + -------------------------------------------------------- + */ + + template < + typename mesh_type + > + __normal_call bool_type find_tri3 ( + mesh_type&_mesh , + IPTR_TYPE const*_node , + IPTR_TYPE&_tpos + ) + { + /*-------------------------- find current 2-cell pos. */ + IPTR_TYPE _ipos = + (IPTR_TYPE) _get_tri3(_mesh); + + _mesh. + _llT3[_ipos].node(0) = _node[0]; + _mesh. + _llT3[_ipos].node(1) = _node[1]; + _mesh. + _llT3[_ipos].node(2) = _node[2]; + + typename + mesh_type:: + tri3_maps::_write_it _same ; + if (_mesh. + _mmT3.find(_ipos,_same)) + { + /*------------------------------- found matching cell */ + _put_tri3(_mesh, _ipos); + + _tpos=*_same ; + + return true ; + } + else + { + /*------------------------------- couldn't find match */ + _put_tri3(_mesh, _ipos); + + return false ; + } + } + + /* + -------------------------------------------------------- + * FIND-QUAD: return index of assoc. 2-quad. + -------------------------------------------------------- + */ + + template < + typename mesh_type + > + __normal_call bool_type find_quad ( + mesh_type&_mesh , + IPTR_TYPE const*_node , + IPTR_TYPE&_qpos + ) + { + /*-------------------------- find current 2-cell pos. */ + IPTR_TYPE _ipos = + (IPTR_TYPE) _get_quad(_mesh); + + _mesh. + _llQ4[_ipos].node(0) = _node[0]; + _mesh. + _llQ4[_ipos].node(1) = _node[1]; + _mesh. + _llQ4[_ipos].node(2) = _node[2]; + _mesh. + _llQ4[_ipos].node(3) = _node[3]; + + typename + mesh_type:: + quad_maps::_write_it _same ; + if (_mesh. + _mmQ4.find(_ipos,_same)) + { + /*------------------------------- found matching cell */ + _put_quad(_mesh, _ipos); + + _qpos=*_same ; + + return true ; + } + else + { + /*------------------------------- couldn't find match */ + _put_quad(_mesh, _ipos); + + return false ; + } + } + + /* + -------------------------------------------------------- + * FIND-TRIA: return index of assoc. 3-tria. + -------------------------------------------------------- + */ + + template < + typename mesh_type + > + __normal_call bool_type find_tri4 ( + mesh_type&_mesh , + IPTR_TYPE const*_node , + IPTR_TYPE&_tpos + ) + { + /*-------------------------- find current 3-cell pos. */ + IPTR_TYPE _ipos = + (IPTR_TYPE) _get_tri4(_mesh); + + _mesh. + _llT4[_ipos].node(0) = _node[0]; + _mesh. + _llT4[_ipos].node(1) = _node[1]; + _mesh. + _llT4[_ipos].node(2) = _node[2]; + _mesh. + _llT4[_ipos].node(3) = _node[3]; + + typename + mesh_type:: + tri4_maps::_write_it _same ; + if (_mesh. + _mmT4.find(_ipos,_same)) + { + /*------------------------------- found matching cell */ + _put_tri4(_mesh, _ipos); + + _tpos=*_same ; + + return true ; + } + else + { + /*------------------------------- couldn't find match */ + _put_tri4(_mesh, _ipos); + + return false ; + } + } + + /* + -------------------------------------------------------- + * FIND-HEXA: return index of assoc. 3-hexa. + -------------------------------------------------------- + */ + + template < + typename mesh_type + > + __normal_call bool_type find_hexa ( + mesh_type&_mesh , + IPTR_TYPE const*_node , + IPTR_TYPE&_hpos + ) + { + /*-------------------------- find current 3-cell pos. */ + IPTR_TYPE _ipos = + (IPTR_TYPE) _get_hexa(_mesh); + + _mesh. + _llH8[_ipos].node(0) = _node[0]; + _mesh. + _llH8[_ipos].node(1) = _node[1]; + _mesh. + _llH8[_ipos].node(2) = _node[2]; + _mesh. + _llH8[_ipos].node(3) = _node[3]; + _mesh. + _llH8[_ipos].node(4) = _node[4]; + _mesh. + _llH8[_ipos].node(5) = _node[5]; + _mesh. + _llH8[_ipos].node(6) = _node[6]; + _mesh. + _llH8[_ipos].node(7) = _node[7]; + + typename + mesh_type:: + hexa_maps::_write_it _same ; + if (_mesh. + _mmH8.find(_ipos,_same)) + { + /*------------------------------- found matching cell */ + _put_hexa(_mesh, _ipos); + + _hpos=*_same ; + + return true ; + } + else + { + /*------------------------------- couldn't find match */ + _put_hexa(_mesh, _ipos); + + return false ; + } + } + + /* + -------------------------------------------------------- + * FIND-WEDG: return index of assoc. 3-wedg. + -------------------------------------------------------- + */ + + template < + typename mesh_type + > + __normal_call bool_type find_wedg ( + mesh_type&_mesh , + IPTR_TYPE const*_node , + IPTR_TYPE&_wpos + ) + { + /*-------------------------- find current 3-cell pos. */ + IPTR_TYPE _ipos = + (IPTR_TYPE) _get_wedg(_mesh); + + _mesh. + _llW6[_ipos].node(0) = _node[0]; + _mesh. + _llW6[_ipos].node(1) = _node[1]; + _mesh. + _llW6[_ipos].node(2) = _node[2]; + _mesh. + _llW6[_ipos].node(3) = _node[3]; + _mesh. + _llW6[_ipos].node(4) = _node[4]; + _mesh. + _llW6[_ipos].node(5) = _node[5]; + + typename + mesh_type:: + wedg_maps::_write_it _same ; + if (_mesh. + _mmW6.find(_ipos,_same)) + { + /*------------------------------- found matching cell */ + _put_wedg(_mesh, _ipos); + + _wpos=*_same ; + + return true ; + } + else + { + /*------------------------------- couldn't find match */ + _put_wedg(_mesh, _ipos); + + return false ; + } + } + + /* + -------------------------------------------------------- + * FIND-PYRA: return index of assoc. 3-pyra. + -------------------------------------------------------- + */ + + template < + typename mesh_type + > + __normal_call bool_type find_pyra ( + mesh_type&_mesh , + IPTR_TYPE const*_node , + IPTR_TYPE&_ppos + ) + { + /*-------------------------- find current 3-cell pos. */ + IPTR_TYPE _ipos = + (IPTR_TYPE) _get_pyra(_mesh); + + _mesh. + _llP5[_ipos].node(0) = _node[0]; + _mesh. + _llP5[_ipos].node(1) = _node[1]; + _mesh. + _llP5[_ipos].node(2) = _node[2]; + _mesh. + _llP5[_ipos].node(3) = _node[3]; + _mesh. + _llP5[_ipos].node(4) = _node[4]; + + typename + mesh_type:: + pyra_maps::_write_it _same ; + if (_mesh. + _mmP5.find(_ipos,_same)) + { + /*------------------------------- found matching cell */ + _put_pyra(_mesh, _ipos); + + _ppos=*_same ; + + return true ; + } + else + { + /*------------------------------- couldn't find match */ + _put_pyra(_mesh, _ipos); + + return false ; + } + } + + /* + -------------------------------------------------------- + * FIND-CELL: return index of assoc. k-cell. + -------------------------------------------------------- + */ + + template < + typename mesh_type + > + __inline_call bool_type find_cell ( // tria-complex + mesh_type&_mesh , + IPTR_TYPE const*_node , + char_type _kind , + IPTR_TYPE&_ipos , + tria_cell const & + ) + { + switch ( _kind ) + { + /*-------------------------- find current k-cell pos. */ + case POINT_tag: + { + if constexpr (TOPO_DIMS >= +0) + { + if (find_node(_mesh, _node, _ipos)) + return true ; + else + return false ; + } + else + return false ; + } + + case EDGE2_tag: + { + if constexpr (TOPO_DIMS >= +1) + { + if (find_edge(_mesh, _node, _ipos)) + return true ; + else + return false ; + } + else + return false ; + } + + case TRIA3_tag: + { + if constexpr (TOPO_DIMS >= +2) + { + if (find_tri3(_mesh, _node, _ipos)) + return true ; + else + return false ; + } + else + return false ; + } + + case TRIA4_tag: + { + if constexpr (TOPO_DIMS >= +3) + { + if (find_tri4(_mesh, _node, _ipos)) + return true ; + else + return false ; + } + else + return false ; + } + } + + return false ; + } + + template < + typename mesh_type + > + __inline_call bool_type find_cell ( // mesh-complex + mesh_type&_mesh , + IPTR_TYPE const*_node , + char_type _kind , + IPTR_TYPE&_ipos , + mesh_cell const & + ) + { + switch ( _kind ) + { + /*-------------------------- find current k-cell pos. */ + case POINT_tag: + { + if constexpr (TOPO_DIMS >= +0) + { + if (find_node(_mesh, _node, _ipos)) + return true ; + else + return false ; + } + else + return false ; + } + + case EDGE2_tag: + { + if constexpr (TOPO_DIMS >= +1) + { + if (find_edge(_mesh, _node, _ipos)) + return true ; + else + return false ; + } + else + return false ; + } + + case TRIA3_tag: + { + if constexpr (TOPO_DIMS >= +2) + { + if (find_tri3(_mesh, _node, _ipos)) + return true ; + else + return false ; + } + else + return false ; + } + + case QUAD4_tag: + { + if constexpr (TOPO_DIMS >= +2) + { + if (find_quad(_mesh, _node, _ipos)) + return true ; + else + return false ; + } + else + return false ; + } + + case TRIA4_tag: + { + if constexpr (TOPO_DIMS >= +3) + { + if (find_tri4(_mesh, _node, _ipos)) + return true ; + else + return false ; + } + else + return false ; + } + + case HEXA8_tag: + { + if constexpr (TOPO_DIMS >= +3) + { + if (find_hexa(_mesh, _node, _ipos)) + return true ; + else + return false ; + } + else + return false ; + } + + case WEDG6_tag: + { + if constexpr (TOPO_DIMS >= +3) + { + if (find_wedg(_mesh, _node, _ipos)) + return true ; + else + return false ; + } + else + return false ; + } + + case PYRA5_tag: + { + if constexpr (TOPO_DIMS >= +3) + { + if (find_pyra(_mesh, _node, _ipos)) + return true ; + else + return false ; + } + else + return false ; + } + } + + return false ; + } + + /* + -------------------------------------------------------- + * CONNECT-1: form this-to-1-cell adj. list. + -------------------------------------------------------- + */ + + template < + typename mesh_type , + typename connector + > + __inline_call void_type connect_1 ( // tria-complex + mesh_type&_mesh , + IPTR_TYPE const*_node , + char_type _kind , + connector&_conn , + tria_cell _type + ) + { + /*-------------------------- get adj. for k-cell pos. */ + IPTR_TYPE _ipos ; + if (find_cell(_mesh, _node, _kind, _ipos, + _type) ) + { + connect_1(_mesh, _ipos, _kind, _conn, + _type) ; + } + } + + template < + typename mesh_type , + typename connector + > + __inline_call void_type connect_1 ( // mesh-complex + mesh_type&_mesh , + IPTR_TYPE const*_node , + char_type _kind , + connector&_conn , + mesh_cell _type + ) + { + /*-------------------------- get adj. for k-cell pos. */ + IPTR_TYPE _ipos ; + if (find_cell(_mesh, _node, _kind, _ipos, + _type) ) + { + connect_1(_mesh, _ipos, _kind, _conn, + _type) ; + } + } + + template < + typename mesh_type , + typename connector + > + __normal_call void_type connect_1 ( // tria-complex + mesh_type&_mesh , + IPTR_TYPE _ipos , + char_type _kind , + connector&_conn , + tria_cell const & + ) + { + _mesh._tmp1.set_count( +0 ) ; + + switch ( _kind ) + { + /*-------------------------- init. "source" adj. list */ + case POINT_tag: + { + _mesh._tmp1.push_tail( + conn_pair (_ipos, _kind)) ; + break ; + } + } + + /*-------------------------- find set of adj. 1-cells */ + for (auto _iter = _mesh._tmp1.head(); + _iter != _mesh._tmp1.tend(); + ++_iter ) + { + if (_iter->_kind == POINT_tag) + for (auto _iadj = + _mesh._aaN1.head(_iter->_cell); + _iadj != + _mesh._aaN1.tend(_iter->_cell); + ++_iadj ) + { + if(_iadj->_kind == EDGE2_tag && + _mesh. _llE2[ + _iadj->_cell].mark() == 0) + { + _conn.push_tail (*_iadj) ; + _mesh. _llE2[ + _iadj->_cell].mark() += 1; + } + } + } + + /*-------------------------- flip d-face marker lists */ + for (auto _iter = _conn.head() ; + _iter != _conn.tend() ; + ++_iter ) + { + if(_iter->_kind == EDGE2_tag) + { + _mesh. _llE2[ + _iter->_cell].mark() = 0 ; + } + } + } + + template < + typename mesh_type , + typename connector + > + __normal_call void_type connect_1 ( // mesh-complex + mesh_type&_mesh , + IPTR_TYPE _ipos , + char_type _kind , + connector&_conn , + mesh_cell const & + ) + { + _mesh._tmp1.set_count( +0 ) ; + + switch ( _kind ) + { + /*-------------------------- init. "source" adj. list */ + case POINT_tag: + { + _mesh._tmp1.push_tail( + conn_pair (_ipos, _kind)) ; + break ; + } + } + + /*-------------------------- find set of adj. 1-cells */ + for (auto _iter = _mesh._tmp1.head(); + _iter != _mesh._tmp1.tend(); + ++_iter ) + { + if (_iter->_kind == POINT_tag) + for (auto _iadj = + _mesh._aaN1.head(_iter->_cell); + _iadj != + _mesh._aaN1.tend(_iter->_cell); + ++_iadj ) + { + if(_iadj->_kind == EDGE2_tag && + _mesh. _llE2[ + _iadj->_cell].mark() == 0) + { + _conn.push_tail (*_iadj) ; + _mesh. _llE2[ + _iadj->_cell].mark() += 1; + } + } + } + + /*-------------------------- flip d-face marker lists */ + for (auto _iter = _conn.head() ; + _iter != _conn.tend() ; + ++_iter ) + { + if(_iter->_kind == EDGE2_tag) + { + _mesh. _llE2[ + _iter->_cell].mark() = 0 ; + } + } + } + + /* + -------------------------------------------------------- + * CONNECT-2: form this-to-2-cell adj. list. + -------------------------------------------------------- + */ + + template < + typename mesh_type , + typename connector + > + __inline_call void_type connect_2 ( // tria-complex + mesh_type&_mesh , + IPTR_TYPE const*_node , + char_type _kind , + connector&_conn , + tria_cell _type + ) + { + /*-------------------------- get adj. for k-cell pos. */ + IPTR_TYPE _ipos ; + if (find_cell(_mesh, _node, _kind, _ipos, + _type) ) + { + connect_2(_mesh, _ipos, _kind, _conn, + _type) ; + } + } + + template < + typename mesh_type , + typename connector + > + __inline_call void_type connect_2 ( // mesh-complex + mesh_type&_mesh , + IPTR_TYPE const*_node , + char_type _kind , + connector&_conn , + mesh_cell _type + ) + { + /*-------------------------- get adj. for k-cell pos. */ + IPTR_TYPE _ipos ; + if (find_cell(_mesh, _node, _kind, _ipos, + _type) ) + { + connect_2(_mesh, _ipos, _kind, _conn, + _type) ; + } + } + + template < + typename mesh_type , + typename connector + > + __normal_call void_type connect_2 ( // tria-complex + mesh_type&_mesh , + IPTR_TYPE _ipos , + char_type _kind , + connector&_conn , + tria_cell const & + ) + { + _mesh._tmp1.set_count( +0 ) ; + _mesh._tmp2.set_count( +0 ) ; + + switch ( _kind ) + { + /*-------------------------- init. "source" adj. list */ + case POINT_tag: + { + _mesh._tmp1.push_tail( + conn_pair (_ipos, _kind)) ; + break ; + } + + case EDGE2_tag: + { + _mesh._tmp2.push_tail( + conn_pair (_ipos, _kind)) ; + break ; + } + } + + /*-------------------------- find set of adj. 1-cells */ + for (auto _iter = _mesh._tmp1.head(); + _iter != _mesh._tmp1.tend(); + ++_iter ) + { + if (_iter->_kind == POINT_tag) + for (auto _iadj = + _mesh._aaN1.head(_iter->_cell); + _iadj != + _mesh._aaN1.tend(_iter->_cell); + ++_iadj ) + { + if(_iadj->_kind == EDGE2_tag && + _mesh. _llE2[ + _iadj->_cell].mark() == 0) + { + _mesh. + _tmp2.push_tail (*_iadj); + _mesh. _llE2[ + _iadj->_cell].mark() += 1; + } + } + } + + /*-------------------------- find set of adj. 2-cells */ + for (auto _iter = _mesh._tmp2.head(); + _iter != _mesh._tmp2.tend(); + ++_iter ) + { + if (_iter->_kind == EDGE2_tag) + for (auto _iadj = + _mesh._aaE2.head(_iter->_cell); + _iadj != + _mesh._aaE2.tend(_iter->_cell); + ++_iadj ) + { + if(_iadj->_kind == TRIA3_tag && + _mesh. _llT3[ + _iadj->_cell].mark() == 0) + { + _conn.push_tail (*_iadj); + _mesh._llT3[ + _iadj->_cell].mark() += 1; + } + } + } + + /*-------------------------- flip d-face marker lists */ + for (auto _iter = _conn.head() ; + _iter != _conn.tend() ; + ++_iter ) + { + if(_iter->_kind == TRIA3_tag) + { + _mesh. _llT3[ + _iter->_cell].mark() = 0 ; + } + } + + for (auto _iter = _mesh._tmp2.head(); + _iter != _mesh._tmp2.tend(); + ++_iter ) + { + if(_iter->_kind == EDGE2_tag) + { + _mesh. _llE2[ + _iter->_cell].mark() = 0 ; + } + } + } + + template < + typename mesh_type , + typename connector + > + __normal_call void_type connect_2 ( // mesh-complex + mesh_type&_mesh , + IPTR_TYPE _ipos , + char_type _kind , + connector&_conn , + mesh_cell const & + ) + { + _mesh._tmp1.set_count( +0 ) ; + _mesh._tmp2.set_count( +0 ) ; + + switch ( _kind ) + { + /*-------------------------- init. "source" adj. list */ + case POINT_tag: + { + _mesh._tmp1.push_tail( + conn_pair (_ipos, _kind)) ; + break ; + } + + case EDGE2_tag: + { + _mesh._tmp2.push_tail( + conn_pair (_ipos, _kind)) ; + break ; + } + } + + /*-------------------------- find set of adj. 1-cells */ + for (auto _iter = _mesh._tmp1.head(); + _iter != _mesh._tmp1.tend(); + ++_iter ) + { + if (_iter->_kind == POINT_tag) + for (auto _iadj = + _mesh._aaN1.head(_iter->_cell); + _iadj != + _mesh._aaN1.tend(_iter->_cell); + ++_iadj ) + { + if(_iadj->_kind == EDGE2_tag && + _mesh. _llE2[ + _iadj->_cell].mark() == 0) + { + _mesh. + _tmp2.push_tail (*_iadj); + _mesh. _llE2[ + _iadj->_cell].mark() += 1; + } + } + } + + /*-------------------------- find set of adj. 2-cells */ + for (auto _iter = _mesh._tmp2.head(); + _iter != _mesh._tmp2.tend(); + ++_iter ) + { + if (_iter->_kind == EDGE2_tag) + for (auto _iadj = + _mesh._aaE2.head(_iter->_cell); + _iadj != + _mesh._aaE2.tend(_iter->_cell); + ++_iadj ) + { + if(_iadj->_kind == TRIA3_tag && + _mesh. _llT3[ + _iadj->_cell].mark() == 0) + { + _conn.push_tail (*_iadj); + _mesh._llT3[ + _iadj->_cell].mark() += 1; + } + else + if(_iadj->_kind == QUAD4_tag && + _mesh. _llQ4[ + _iadj->_cell].mark() == 0) + { + _conn.push_tail (*_iadj); + _mesh. _llQ4[ + _iadj->_cell].mark() += 1; + } + } + } + + /*-------------------------- flip d-face marker lists */ + for (auto _iter = _conn.head() ; + _iter != _conn.tend() ; + ++_iter ) + { + if(_iter->_kind == TRIA3_tag) + { + _mesh. _llT3[ + _iter->_cell].mark() = 0 ; + } + else + if(_iter->_kind == QUAD4_tag) + { + _mesh. _llQ4[ + _iter->_cell].mark() = 0 ; + } + } + + for (auto _iter = _mesh._tmp2.head(); + _iter != _mesh._tmp2.tend(); + ++_iter ) + { + if(_iter->_kind == EDGE2_tag) + { + _mesh. _llE2[ + _iter->_cell].mark() = 0 ; + } + } + } + + /* + -------------------------------------------------------- + * CONNECT-3: form this-to-3-cell adj. list. + -------------------------------------------------------- + */ + + template < + typename mesh_type , + typename connector + > + __inline_call void_type connect_3 ( // tria-complex + mesh_type&_mesh , + IPTR_TYPE const*_node , + char_type _kind , + connector&_conn , + tria_cell _type + ) + { + /*-------------------------- get adj. for k-cell pos. */ + IPTR_TYPE _ipos ; + if (find_cell(_mesh, _node, _kind, _ipos, + _type) ) + { + connect_3(_mesh, _ipos, _kind, _conn, + _type) ; + } + } + + template < + typename mesh_type , + typename connector + > + __inline_call void_type connect_3 ( // mesh-complex + mesh_type&_mesh , + IPTR_TYPE const*_node , + char_type _kind , + connector&_conn , + mesh_cell _type + ) + { + /*-------------------------- get adj. for k-cell pos. */ + IPTR_TYPE _ipos ; + if (find_cell(_mesh, _node, _kind, _ipos, + _type) ) + { + connect_3(_mesh, _ipos, _kind, _conn, + _type) ; + } + } + + template < + typename mesh_type , + typename connector + > + __normal_call void_type connect_3 ( // tria-complex + mesh_type&_mesh , + IPTR_TYPE _ipos , + char_type _kind , + connector&_conn , + tria_cell const & + ) + { + _mesh._tmp1.set_count( +0 ) ; + _mesh._tmp2.set_count( +0 ) ; + _mesh._tmp3.set_count( +0 ) ; + + switch ( _kind ) + { + /*-------------------------- init. "source" adj. list */ + case POINT_tag: + { + _mesh._tmp1.push_tail( + conn_pair (_ipos, _kind)) ; + break ; + } + + case EDGE2_tag: + { + _mesh._tmp2.push_tail( + conn_pair (_ipos, _kind)) ; + break ; + } + + case TRIA3_tag: + { + _mesh._tmp3.push_tail( + conn_pair (_ipos, _kind)) ; + break ; + } + } + + /*-------------------------- find set of adj. 1-cells */ + for (auto _iter = _mesh._tmp1.head(); + _iter != _mesh._tmp1.tend(); + ++_iter ) + { + if (_iter->_kind == POINT_tag) + for (auto _iadj = + _mesh._aaN1.head(_iter->_cell); + _iadj != + _mesh._aaN1.tend(_iter->_cell); + ++_iadj ) + { + if(_iadj->_kind == EDGE2_tag && + _mesh. _llE2[ + _iadj->_cell].mark() == 0) + { + _mesh. + _tmp2.push_tail (*_iadj); + _mesh. _llE2[ + _iadj->_cell].mark() += 1; + } + } + } + + /*-------------------------- find set of adj. 2-cells */ + for (auto _iter = _mesh._tmp2.head(); + _iter != _mesh._tmp2.tend(); + ++_iter ) + { + if (_iter->_kind == EDGE2_tag) + for (auto _iadj = + _mesh._aaE2.head(_iter->_cell); + _iadj != + _mesh._aaE2.tend(_iter->_cell); + ++_iadj ) + { + if(_iadj->_kind == TRIA3_tag && + _mesh. _llT3[ + _iadj->_cell].mark() == 0) + { + _mesh. + _tmp3.push_tail (*_iadj); + _mesh. _llT3[ + _iadj->_cell].mark() += 1; + } + } + } + + /*-------------------------- find set of adj. 3-cells */ + for (auto _iter = _mesh._tmp3.head(); + _iter != _mesh._tmp3.tend(); + ++_iter ) + { + if (_iter->_kind == TRIA3_tag) // from TRIA-3 + for (auto _iadj = + _mesh._aaT3.head(_iter->_cell); + _iadj != + _mesh._aaT3.tend(_iter->_cell); + ++_iadj ) + { + if(_iadj->_kind == TRIA4_tag && + _mesh. _llT4[ + _iadj->_cell].mark() == 0) + { + _conn.push_tail (*_iadj); + _mesh. _llT4[ + _iadj->_cell].mark() += 1; + } + } + } + + /*-------------------------- flip d-face marker lists */ + for (auto _iter = _conn.head() ; + _iter != _conn.tend() ; + ++_iter ) + { + if(_iter->_kind == TRIA4_tag) + { + _mesh. _llT4[ + _iter->_cell].mark() = 0 ; + } + } + + for (auto _iter = _mesh._tmp3.head(); + _iter != _mesh._tmp3.tend(); + ++_iter ) + { + if(_iter->_kind == TRIA3_tag) + { + _mesh. _llT3[ + _iter->_cell].mark() = 0 ; + } + } + + for (auto _iter = _mesh._tmp2.head(); + _iter != _mesh._tmp2.tend(); + ++_iter ) + { + if(_iter->_kind == EDGE2_tag) + { + _mesh. _llE2[ + _iter->_cell].mark() = 0 ; + } + } + } + + template < + typename mesh_type , + typename connector + > + __normal_call void_type connect_3 ( // mesh-complex + mesh_type&_mesh , + IPTR_TYPE _ipos , + char_type _kind , + connector&_conn , + mesh_cell const & + ) + { + _mesh._tmp1.set_count( +0 ) ; + _mesh._tmp2.set_count( +0 ) ; + _mesh._tmp3.set_count( +0 ) ; + + switch ( _kind ) + { + /*-------------------------- init. "source" adj. list */ + case POINT_tag: + { + _mesh._tmp1.push_tail( + conn_pair (_ipos, _kind)) ; + break ; + } + + case EDGE2_tag: + { + _mesh._tmp2.push_tail( + conn_pair (_ipos, _kind)) ; + break ; + } + + case TRIA3_tag: // fall-through + case QUAD4_tag: + { + _mesh._tmp3.push_tail( + conn_pair (_ipos, _kind)) ; + break ; + } + } + + /*-------------------------- find set of adj. 1-cells */ + for (auto _iter = _mesh._tmp1.head(); + _iter != _mesh._tmp1.tend(); + ++_iter ) + { + if (_iter->_kind == POINT_tag) + for (auto _iadj = + _mesh._aaN1.head(_iter->_cell); + _iadj != + _mesh._aaN1.tend(_iter->_cell); + ++_iadj ) + { + if(_iadj->_kind == EDGE2_tag && + _mesh. _llE2[ + _iadj->_cell].mark() == 0) + { + _mesh. + _tmp2.push_tail (*_iadj); + _mesh. _llE2[ + _iadj->_cell].mark() += 1; + } + } + } + + /*-------------------------- find set of adj. 2-cells */ + for (auto _iter = _mesh._tmp2.head(); + _iter != _mesh._tmp2.tend(); + ++_iter ) + { + if (_iter->_kind == EDGE2_tag) + for (auto _iadj = + _mesh._aaE2.head(_iter->_cell); + _iadj != + _mesh._aaE2.tend(_iter->_cell); + ++_iadj ) + { + if(_iadj->_kind == TRIA3_tag && + _mesh. _llT3[ + _iadj->_cell].mark() == 0) + { + _mesh. + _tmp3.push_tail (*_iadj); + _mesh. _llT3[ + _iadj->_cell].mark() += 1; + } + else + if(_iadj->_kind == QUAD4_tag && + _mesh. _llQ4[ + _iadj->_cell].mark() == 0) + { + _mesh. + _tmp3.push_tail (*_iadj); + _mesh. _llQ4[ + _iadj->_cell].mark() += 1; + } + } + } + + /*-------------------------- find set of adj. 3-cells */ + for (auto _iter = _mesh._tmp3.head(); + _iter != _mesh._tmp3.tend(); + ++_iter ) + { + if (_iter->_kind == TRIA3_tag) // from TRIA-3 + for (auto _iadj = + _mesh._aaT3.head(_iter->_cell); + _iadj != + _mesh._aaT3.tend(_iter->_cell); + ++_iadj ) + { + if(_iadj->_kind == TRIA4_tag && + _mesh. _llT4[ + _iadj->_cell].mark() == 0) + { + _conn.push_tail (*_iadj); + _mesh. _llT4[ + _iadj->_cell].mark() += 1; + } + else + if(_iadj->_kind == WEDG6_tag && + _mesh. _llW6[ + _iadj->_cell].mark() == 0) + { + _conn.push_tail (*_iadj); + _mesh. _llW6[ + _iadj->_cell].mark() += 1; + } + else + if(_iadj->_kind == PYRA5_tag && + _mesh. _llP5[ + _iadj->_cell].mark() == 0) + { + _conn.push_tail (*_iadj); + _mesh. _llP5[ + _iadj->_cell].mark() += 1; + } + } + + if (_iter->_kind == QUAD4_tag) // from QUAD-4 + for (auto _iadj = + _mesh._aaQ4.head(_iter->_cell); + _iadj != + _mesh._aaQ4.tend(_iter->_cell); + ++_iadj ) + { + if(_iadj->_kind == HEXA8_tag && + _mesh. _llH8[ + _iadj->_cell].mark() == 0) + { + _conn.push_tail (*_iadj); + _mesh. _llH8[ + _iadj->_cell].mark() += 1; + } + else + if(_iadj->_kind == WEDG6_tag && + _mesh. _llW6[ + _iadj->_cell].mark() == 0) + { + _conn.push_tail (*_iadj); + _mesh. _llW6[ + _iadj->_cell].mark() += 1; + } + else + if(_iadj->_kind == PYRA5_tag && + _mesh. _llP5[ + _iadj->_cell].mark() == 0) + { + _conn.push_tail (*_iadj); + _mesh. _llP5[ + _iadj->_cell].mark() += 1; + } + } + } + + /*-------------------------- flip d-face marker lists */ + for (auto _iter = _conn.head() ; + _iter != _conn.tend() ; + ++_iter ) + { + if(_iter->_kind == TRIA4_tag) + { + _mesh. _llT4[ + _iter->_cell].mark() = 0 ; + } + else + if(_iter->_kind == HEXA8_tag) + { + _mesh. _llH8[ + _iter->_cell].mark() = 0 ; + } + else + if(_iter->_kind == WEDG6_tag) + { + _mesh. _llW6[ + _iter->_cell].mark() = 0 ; + } + else + if(_iter->_kind == PYRA5_tag) + { + _mesh. _llP5[ + _iter->_cell].mark() = 0 ; + } + } + + for (auto _iter = _mesh._tmp3.head(); + _iter != _mesh._tmp3.tend(); + ++_iter ) + { + if(_iter->_kind == TRIA3_tag) + { + _mesh. _llT3[ + _iter->_cell].mark() = 0 ; + } + else + if(_iter->_kind == QUAD4_tag) + { + _mesh. _llQ4[ + _iter->_cell].mark() = 0 ; + } + } + + for (auto _iter = _mesh._tmp2.head(); + _iter != _mesh._tmp2.tend(); + ++_iter ) + { + if(_iter->_kind == EDGE2_tag) + { + _mesh. _llE2[ + _iter->_cell].mark() = 0 ; + } + } + } + +# undef TOPO_DIMS + +# undef IPTR_TYPE +# undef INDX_TYPE +# undef REAL_TYPE + +# undef NODE_TYPE +# undef EDGE_TYPE +# undef TRI3_TYPE +# undef QUAD_TYPE +# undef TRI4_TYPE +# undef HEXA_TYPE +# undef WEDG_TYPE +# undef PYRA_TYPE + + } + +# endif //__BASE_COMPLEX_k__ + + + diff --git a/src/libcpp/mesh_type/hash_complex_k.hpp b/src/libcpp/mesh_type/hash_complex_k.hpp new file mode 100644 index 0000000..57b1ef0 --- /dev/null +++ b/src/libcpp/mesh_type/hash_complex_k.hpp @@ -0,0 +1,766 @@ + + /* + -------------------------------------------------------- + * HASH-COMPLEX-k: utilities for hashing cells in T^k. + -------------------------------------------------------- + * + * 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: 27 April, 2020 + * + * Copyright 2020-- + * Darren Engwirda + * d.engwirda@gmail.com + * https://github.com/dengwirda/ + * + -------------------------------------------------------- + */ + +# pragma once + +# ifndef __HASH_COMPLEX_K__ +# define __HASH_COMPLEX_K__ + + namespace mesh { + + /* + -------------------------------------------------------- + * HASH-COMPLEX-k hashes for k-cell complexes. + -------------------------------------------------------- + */ + + template < + typename node_list + > + class node_hash + { + public : + __const_ptr(node_list) _nset ; + public : + /*----------------------- build hash _obj. from _src. */ + __inline_call node_hash ( + node_list *_nsrc + ) : _nset( _nsrc) {} + /*----------------------- hash node indexing for node */ + __inline_call uint32_t operator() ( + uint32_t _npos + ) const + { + return (uint32_t)this->_nset-> + operator[](_npos).node( 0) ; + } + } ; + + template < + typename edge_list + > + class edge_hash + { + public : + __const_ptr(edge_list) _eset ; + public : + /*----------------------- build hash _obj. from _src. */ + __inline_call edge_hash ( + edge_list *_esrc + ) : _eset( _esrc) {} + /*----------------------- hash node indexing for edge */ + __inline_call uint32_t operator() ( + uint32_t _epos + ) const + { + uint32_t _enod[2]; + _enod[0] = this->_eset-> + operator[](_epos).node( 0) ; + _enod[1] = this->_eset-> + operator[](_epos).node( 1) ; + + algorithms::isort ( + &_enod[0], &_enod[2] , + std::less()); + + return hash::hashword ( + (uint32_t *)&_enod[0], +2, +137); + } + } ; + + template < + typename tri3_list + > + class tri3_hash + { + public : + __const_ptr(tri3_list) _tset ; + public : + /*----------------------- build hash _obj. from _src. */ + __inline_call tri3_hash ( + tri3_list *_tsrc + ) : _tset( _tsrc) {} + /*----------------------- hash node indexing for face */ + __inline_call uint32_t operator() ( + uint32_t _tpos + ) const + { + uint32_t _tnod[3]; + _tnod[0] = this->_tset-> + operator[](_tpos).node( 0) ; + _tnod[1] = this->_tset-> + operator[](_tpos).node( 1) ; + _tnod[2] = this->_tset-> + operator[](_tpos).node( 2) ; + + algorithms::isort ( + &_tnod[0], &_tnod[3] , + std::less()); + + return hash::hashword ( + (uint32_t *)&_tnod[0], +3, +137); + } + } ; + + template < + typename quad_list + > + class quad_hash + { + public : + __const_ptr(quad_list) _qset ; + public : + /*----------------------- build hash _obj. from _src. */ + __inline_call quad_hash ( + quad_list *_qsrc + ) : _qset( _qsrc) {} + /*----------------------- hash node indexing for face */ + __inline_call uint32_t operator() ( + uint32_t _qpos + ) const + { + uint32_t _qnod[4]; + _qnod[0] = this->_qset-> + operator[](_qpos).node( 0) ; + _qnod[1] = this->_qset-> + operator[](_qpos).node( 1) ; + _qnod[2] = this->_qset-> + operator[](_qpos).node( 2) ; + _qnod[3] = this->_qset-> + operator[](_qpos).node( 3) ; + + algorithms::isort ( + &_qnod[0], &_qnod[4] , + std::less()); + + return hash::hashword ( + (uint32_t *)&_qnod[0], +4, +137); + } + } ; + + template < + typename tri4_list + > + class tri4_hash + { + public : + __const_ptr(tri4_list) _tset ; + public : + /*----------------------- build hash _obj. from _src. */ + __inline_call tri4_hash ( + tri4_list *_tsrc + ) : _tset( _tsrc) {} + /*----------------------- hash node indexing for face */ + __inline_call uint32_t operator() ( + uint32_t _tpos + ) const + { + uint32_t _tnod[4]; + _tnod[0] = this->_tset-> + operator[](_tpos).node( 0) ; + _tnod[1] = this->_tset-> + operator[](_tpos).node( 1) ; + _tnod[2] = this->_tset-> + operator[](_tpos).node( 2) ; + _tnod[3] = this->_tset-> + operator[](_tpos).node( 3) ; + + algorithms::isort ( + &_tnod[0], &_tnod[4] , + std::less()); + + return hash::hashword ( + (uint32_t *)&_tnod[0], +4, +137); + } + } ; + + template < + typename hexa_list + > + class hexa_hash + { + public : + __const_ptr(hexa_list) _hset ; + public : + /*----------------------- build hash _obj. from _src. */ + __inline_call hexa_hash ( + hexa_list *_hsrc + ) : _hset( _hsrc) {} + /*----------------------- hash node indexing for face */ + __inline_call uint32_t operator() ( + uint32_t _hpos + ) const + { + uint32_t _hnod[8]; + _hnod[0] = this->_hset-> + operator[](_hpos).node( 0) ; + _hnod[1] = this->_hset-> + operator[](_hpos).node( 1) ; + _hnod[2] = this->_hset-> + operator[](_hpos).node( 2) ; + _hnod[3] = this->_hset-> + operator[](_hpos).node( 3) ; + _hnod[4] = this->_hset-> + operator[](_hpos).node( 4) ; + _hnod[5] = this->_hset-> + operator[](_hpos).node( 5) ; + _hnod[6] = this->_hset-> + operator[](_hpos).node( 6) ; + _hnod[7] = this->_hset-> + operator[](_hpos).node( 7) ; + + algorithms::isort ( + &_hnod[0], &_hnod[8] , + std::less()); + + return hash::hashword ( + (uint32_t *)&_hnod[0], +8, +137); + } + } ; + + template < + typename wedg_list + > + class wedg_hash + { + public : + __const_ptr(wedg_list) _wset ; + public : + /*----------------------- build hash _obj. from _src. */ + __inline_call wedg_hash ( + wedg_list *_wsrc + ) : _wset( _wsrc) {} + /*----------------------- hash node indexing for face */ + __inline_call uint32_t operator() ( + uint32_t _wpos + ) const + { + uint32_t _wnod[6]; + _wnod[0] = this->_wset-> + operator[](_wpos).node( 0) ; + _wnod[1] = this->_wset-> + operator[](_wpos).node( 1) ; + _wnod[2] = this->_wset-> + operator[](_wpos).node( 2) ; + _wnod[3] = this->_wset-> + operator[](_wpos).node( 3) ; + _wnod[4] = this->_wset-> + operator[](_wpos).node( 4) ; + _wnod[5] = this->_wset-> + operator[](_wpos).node( 5) ; + + algorithms::isort ( + &_wnod[0], &_wnod[6] , + std::less()); + + return hash::hashword ( + (uint32_t *)&_wnod[0], +6, +137); + } + } ; + + template < + typename pyra_list + > + class pyra_hash + { + public : + __const_ptr(pyra_list) _pset ; + public : + /*----------------------- build hash _obj. from _src. */ + __inline_call pyra_hash ( + pyra_list *_psrc + ) : _pset( _psrc) {} + /*----------------------- hash node indexing for face */ + __inline_call uint32_t operator() ( + uint32_t _ppos + ) const + { + uint32_t _pnod[5]; + _pnod[0] = this->_pset-> + operator[](_ppos).node( 0) ; + _pnod[1] = this->_pset-> + operator[](_ppos).node( 1) ; + _pnod[2] = this->_pset-> + operator[](_ppos).node( 2) ; + _pnod[3] = this->_pset-> + operator[](_ppos).node( 3) ; + _pnod[4] = this->_pset-> + operator[](_ppos).node( 4) ; + + algorithms::isort ( + &_pnod[0], &_pnod[5] , + std::less()); + + return hash::hashword ( + (uint32_t *)&_pnod[0], +5, +137); + } + } ; + + template < + typename node_list + > + class node_pred + { + public : + __const_ptr(node_list) _nset ; + public : + /*----------------------- build hash _obj. from _src. */ + __inline_call node_pred ( + node_list *_nsrc + ) : _nset( _nsrc) {} + /*----------------------- compute "equal-to" for node */ + __inline_call bool_type operator() ( + uint32_t _ipos, + uint32_t _jpos + ) const + { + uint32_t _inod[1]; + _inod[0] = this->_nset-> + operator[](_ipos).node( 0) ; + + uint32_t _jnod[1]; + _jnod[0] = this->_nset-> + operator[](_jpos).node( 0) ; + + return _inod[0] == _jnod[0] ; + } + } ; + + template < + typename edge_list + > + class edge_pred + { + public : + __const_ptr(edge_list) _eset ; + public : + /*----------------------- build hash _obj. from _src. */ + __inline_call edge_pred ( + edge_list *_esrc + ) : _eset( _esrc) {} + /*----------------------- compute "equal-to" for edge */ + __inline_call bool_type operator() ( + uint32_t _ipos, + uint32_t _jpos + ) const + { + uint32_t _inod[2]; + _inod[0] = this->_eset-> + operator[](_ipos).node( 0) ; + _inod[1] = this->_eset-> + operator[](_ipos).node( 1) ; + + uint32_t _jnod[2]; + _jnod[0] = this->_eset-> + operator[](_jpos).node( 0) ; + _jnod[1] = this->_eset-> + operator[](_jpos).node( 1) ; + + algorithms::isort ( + &_inod[0], &_inod[2], + std::less()); + + algorithms::isort ( + &_jnod[0], &_jnod[2], + std::less()); + + return _inod[0] == _jnod[0] && + _inod[1] == _jnod[1] ; + } + } ; + + template < + typename tri3_list + > + class tri3_pred + { + public : + __const_ptr(tri3_list) _tset ; + public : + /*----------------------- build hash _obj. from _src. */ + __inline_call tri3_pred ( + tri3_list *_tsrc + ) : _tset( _tsrc) {} + /*----------------------- compute "equal-to" for face */ + __inline_call bool_type operator() ( + uint32_t _ipos, + uint32_t _jpos + ) const + { + uint32_t _inod[3]; + _inod[0] = this->_tset-> + operator[](_ipos).node( 0) ; + _inod[1] = this->_tset-> + operator[](_ipos).node( 1) ; + _inod[2] = this->_tset-> + operator[](_ipos).node( 2) ; + + uint32_t _jnod[3]; + _jnod[0] = this->_tset-> + operator[](_jpos).node( 0) ; + _jnod[1] = this->_tset-> + operator[](_jpos).node( 1) ; + _jnod[2] = this->_tset-> + operator[](_jpos).node( 2) ; + + algorithms::isort ( + &_inod[0], &_inod[3], + std::less()); + + algorithms::isort ( + &_jnod[0], &_jnod[3], + std::less()); + + return _inod[0] == _jnod[0] && + _inod[1] == _jnod[1] && + _inod[2] == _jnod[2] ; + } + } ; + + template < + typename quad_list + > + class quad_pred + { + public : + __const_ptr(quad_list) _qset ; + public : + /*----------------------- build hash _obj. from _src. */ + __inline_call quad_pred ( + quad_list *_qsrc + ) : _qset( _qsrc) {} + /*----------------------- compute "equal-to" for face */ + __inline_call bool_type operator() ( + uint32_t _ipos, + uint32_t _jpos + ) const + { + uint32_t _inod[4]; + _inod[0] = this->_qset-> + operator[](_ipos).node( 0) ; + _inod[1] = this->_qset-> + operator[](_ipos).node( 1) ; + _inod[2] = this->_qset-> + operator[](_ipos).node( 2) ; + _inod[3] = this->_qset-> + operator[](_ipos).node( 3) ; + + uint32_t _jnod[4]; + _jnod[0] = this->_qset-> + operator[](_jpos).node( 0) ; + _jnod[1] = this->_qset-> + operator[](_jpos).node( 1) ; + _jnod[2] = this->_qset-> + operator[](_jpos).node( 2) ; + _jnod[3] = this->_qset-> + operator[](_jpos).node( 3) ; + + algorithms::isort ( + &_inod[0], &_inod[4], + std::less()); + + algorithms::isort ( + &_jnod[0], &_jnod[4], + std::less()); + + return _inod[0] == _jnod[0] && + _inod[1] == _jnod[1] && + _inod[2] == _jnod[2] && + _inod[3] == _jnod[3] ; + } + } ; + + template < + typename tri4_list + > + class tri4_pred + { + public : + __const_ptr(tri4_list) _tset ; + public : + /*----------------------- build hash _obj. from _src. */ + __inline_call tri4_pred ( + tri4_list *_tsrc + ) : _tset( _tsrc) {} + /*----------------------- compute "equal-to" for face */ + __inline_call bool_type operator() ( + uint32_t _ipos, + uint32_t _jpos + ) const + { + uint32_t _inod[4]; + _inod[0] = this->_tset-> + operator[](_ipos).node( 0) ; + _inod[1] = this->_tset-> + operator[](_ipos).node( 1) ; + _inod[2] = this->_tset-> + operator[](_ipos).node( 2) ; + _inod[3] = this->_tset-> + operator[](_ipos).node( 3) ; + + uint32_t _jnod[4]; + _jnod[0] = this->_tset-> + operator[](_jpos).node( 0) ; + _jnod[1] = this->_tset-> + operator[](_jpos).node( 1) ; + _jnod[2] = this->_tset-> + operator[](_jpos).node( 2) ; + _jnod[3] = this->_tset-> + operator[](_jpos).node( 3) ; + + algorithms::isort ( + &_inod[0], &_inod[4], + std::less()); + + algorithms::isort ( + &_jnod[0], &_jnod[4], + std::less()); + + return _inod[0] == _jnod[0] && + _inod[1] == _jnod[1] && + _inod[2] == _jnod[2] && + _inod[3] == _jnod[3] ; + } + } ; + + template < + typename hexa_list + > + class hexa_pred + { + public : + __const_ptr(hexa_list) _hset ; + public : + /*----------------------- build hash _obj. from _src. */ + __inline_call hexa_pred ( + hexa_list *_hsrc + ) : _hset( _hsrc) {} + /*----------------------- compute "equal-to" for face */ + __inline_call bool_type operator() ( + uint32_t _ipos, + uint32_t _jpos + ) const + { + uint32_t _inod[8]; + _inod[0] = this->_hset-> + operator[](_ipos).node( 0) ; + _inod[1] = this->_hset-> + operator[](_ipos).node( 1) ; + _inod[2] = this->_hset-> + operator[](_ipos).node( 2) ; + _inod[3] = this->_hset-> + operator[](_ipos).node( 3) ; + _inod[4] = this->_hset-> + operator[](_ipos).node( 4) ; + _inod[5] = this->_hset-> + operator[](_ipos).node( 5) ; + _inod[6] = this->_hset-> + operator[](_ipos).node( 6) ; + _inod[7] = this->_hset-> + operator[](_ipos).node( 7) ; + + uint32_t _jnod[8]; + _jnod[0] = this->_hset-> + operator[](_jpos).node( 0) ; + _jnod[1] = this->_hset-> + operator[](_jpos).node( 1) ; + _jnod[2] = this->_hset-> + operator[](_jpos).node( 2) ; + _jnod[3] = this->_hset-> + operator[](_jpos).node( 3) ; + _jnod[4] = this->_hset-> + operator[](_jpos).node( 4) ; + _jnod[5] = this->_hset-> + operator[](_jpos).node( 5) ; + _jnod[6] = this->_hset-> + operator[](_jpos).node( 6) ; + _jnod[7] = this->_hset-> + operator[](_jpos).node( 7) ; + + algorithms::isort ( + &_inod[0], &_inod[8], + std::less()); + + algorithms::isort ( + &_jnod[0], &_jnod[8], + std::less()); + + return _inod[0] == _jnod[0] && + _inod[1] == _jnod[1] && + _inod[2] == _jnod[2] && + _inod[3] == _jnod[3] && + _inod[4] == _jnod[4] && + _inod[5] == _jnod[5] && + _inod[6] == _jnod[6] && + _inod[7] == _jnod[7] ; + } + } ; + + template < + typename wedg_list + > + class wedg_pred + { + public : + __const_ptr(wedg_list) _wset ; + public : + /*----------------------- build hash _obj. from _src. */ + __inline_call wedg_pred ( + wedg_list *_wsrc + ) : _wset( _wsrc) {} + /*----------------------- compute "equal-to" for face */ + __inline_call bool_type operator() ( + uint32_t _ipos, + uint32_t _jpos + ) const + { + uint32_t _inod[6]; + _inod[0] = this->_wset-> + operator[](_ipos).node( 0) ; + _inod[1] = this->_wset-> + operator[](_ipos).node( 1) ; + _inod[2] = this->_wset-> + operator[](_ipos).node( 2) ; + _inod[3] = this->_wset-> + operator[](_ipos).node( 3) ; + _inod[4] = this->_wset-> + operator[](_ipos).node( 4) ; + _inod[5] = this->_wset-> + operator[](_ipos).node( 5) ; + + uint32_t _jnod[6]; + _jnod[0] = this->_wset-> + operator[](_jpos).node( 0) ; + _jnod[1] = this->_wset-> + operator[](_jpos).node( 1) ; + _jnod[2] = this->_wset-> + operator[](_jpos).node( 2) ; + _jnod[3] = this->_wset-> + operator[](_jpos).node( 3) ; + _jnod[4] = this->_wset-> + operator[](_jpos).node( 4) ; + _jnod[5] = this->_wset-> + operator[](_jpos).node( 5) ; + + algorithms::isort ( + &_inod[0], &_inod[6], + std::less()); + + algorithms::isort ( + &_jnod[0], &_jnod[6], + std::less()); + + return _inod[0] == _jnod[0] && + _inod[1] == _jnod[1] && + _inod[2] == _jnod[2] && + _inod[3] == _jnod[3] && + _inod[4] == _jnod[4] && + _inod[5] == _jnod[5] ; + } + } ; + + template < + typename pyra_list + > + class pyra_pred + { + public : + __const_ptr(pyra_list) _pset ; + public : + /*----------------------- build hash _obj. from _src. */ + __inline_call pyra_pred ( + pyra_list *_psrc + ) : _pset( _psrc) {} + /*----------------------- compute "equal-to" for face */ + __inline_call bool_type operator() ( + uint32_t _ipos, + uint32_t _jpos + ) const + { + uint32_t _inod[5]; + _inod[0] = this->_pset-> + operator[](_ipos).node( 0) ; + _inod[1] = this->_pset-> + operator[](_ipos).node( 1) ; + _inod[2] = this->_pset-> + operator[](_ipos).node( 2) ; + _inod[3] = this->_pset-> + operator[](_ipos).node( 3) ; + _inod[4] = this->_pset-> + operator[](_ipos).node( 4) ; + + uint32_t _jnod[5]; + _jnod[0] = this->_pset-> + operator[](_jpos).node( 0) ; + _jnod[1] = this->_pset-> + operator[](_jpos).node( 1) ; + _jnod[2] = this->_pset-> + operator[](_jpos).node( 2) ; + _jnod[3] = this->_pset-> + operator[](_jpos).node( 3) ; + _jnod[4] = this->_pset-> + operator[](_jpos).node( 4) ; + + algorithms::isort ( + &_inod[0], &_inod[5], + std::less()); + + algorithms::isort ( + &_jnod[0], &_jnod[5], + std::less()); + + return _inod[0] == _jnod[0] && + _inod[1] == _jnod[1] && + _inod[2] == _jnod[2] && + _inod[3] == _jnod[3] && + _inod[4] == _jnod[4] ; + } + } ; + + + } + +# endif //__HASH_COMPLEX_k__ + + + diff --git a/src/libcpp/mesh_type/mesh_complex_1.hpp b/src/libcpp/mesh_type/mesh_complex_1.hpp new file mode 100644 index 0000000..32c5b8c --- /dev/null +++ b/src/libcpp/mesh_type/mesh_complex_1.hpp @@ -0,0 +1,430 @@ + + /* + -------------------------------------------------------- + * MESH-COMPLEX-1: piecewise mixed complex in T^1. + -------------------------------------------------------- + * + * 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 2020-- + * Darren Engwirda + * d.engwirda@gmail.com + * https://github.com/dengwirda/ + * + -------------------------------------------------------- + */ + +# pragma once + +# ifndef __MESH_COMPLEX_1__ +# define __MESH_COMPLEX_1__ + + namespace mesh { + + /* + -------------------------------------------------------- + * MESH-COMPLEX-1 generic mixed-cell 1-complex. + -------------------------------------------------------- + * NODE-TYPE - 0-cell type + coord.'s + * EDGE-TYPE - 1-cell type + * ALLOCATOR - memory allocator + -------------------------------------------------------- + */ + + template < + typename NN , + typename E2 , + typename AA = allocators::basic_alloc + > + class mesh_complex_1 + { +/*----------------------------------- mesh-complex in T^1 */ + public : + typedef NN node_type ; + typedef E2 edge_type ; + typedef AA allocator ; + + typedef typename + node_type::real_type real_type ; + typedef typename + edge_type::iptr_type iptr_type ; + typedef typename + allocator::size_type indx_type ; + + iptr_type static constexpr topo_dims = +1 ; + + typedef containers::block_array < + node_type, + allocator > node_list ; + + typedef containers::block_array < + edge_type, + allocator > edge_list ; + + typedef containers::array < + iptr_type, + allocator > iptr_list ; + + typedef containers::array < + indx_type, + allocator > indx_list ; + + typedef mesh::node_hash node_hash ; + typedef mesh::node_pred node_pred ; + + typedef mesh::edge_hash edge_hash ; + typedef mesh::edge_pred edge_pred ; + + indx_type static + constexpr pool_byte_size = 96 * 1024 ; + + typedef allocators::_pool_alloc < + allocators::basic_alloc , + pool_byte_size > pool_base ; + + typedef allocators::_wrap_alloc < + pool_base > pool_wrap ; + + typedef containers::hash_table < + iptr_type, + edge_hash, + edge_pred, + pool_wrap> edge_maps ; + + typedef containers::array < + conn_pair, + allocator > connector ; + + typedef containers::array_list < + conn_pair, + pool_wrap > conn_list ; + + public : + + pool_base _hsrc ; + pool_base _csrc ; + + conn_list _aaN1 ; + + edge_maps _mmE2 ; + + node_list _llN1 ; + edge_list _llE2 ; + + indx_list _ffN1 ; + indx_list _ffE2 ; + + connector _tmp1 ; + + public : + + /* + -------------------------------------------------------- + * Public access to underlying data for k-CELL types. + -------------------------------------------------------- + */ + + __inline_call node_list const& node ( + ) const + { return this->_llN1 ; + } + + __inline_call node_list & node ( + ) + { return this->_llN1 ; + } + + __inline_call node_type const& node ( + indx_type _ipos + ) const + { return this->_llN1[_ipos] ; + } + + __inline_call node_type & node ( + indx_type _ipos + ) + { return this->_llN1[_ipos] ; + } + + __inline_call edge_list const& edge ( + ) const + { return this->_llE2 ; + } + + __inline_call edge_list & edge ( + ) + { return this->_llE2 ; + } + + __inline_call edge_type const& edge ( + indx_type _ipos + ) const + { return this->_llE2[_ipos] ; + } + + __inline_call edge_type & edge ( + indx_type _ipos + ) + { return this->_llE2[_ipos] ; + } + + public : + + /* + -------------------------------------------------------- + * construct mesh-complex from alloc. etc... + -------------------------------------------------------- + */ + + __normal_call mesh_complex_1 ( + allocator const& _asrc = allocator() + ) : _hsrc(sizeof ( + typename edge_maps::item_type)), + _csrc(sizeof ( + typename conn_list::item_type)), + /*---------------------------------- init. adj. lists */ + _aaN1(pool_wrap(&_csrc)), + /*---------------------------------- init. hash lists */ + _mmE2( + edge_hash(& this->_llE2) , + edge_pred(& this->_llE2) , + +.8, (pool_wrap(&_hsrc))) , + /*---------------------------------- init. face lists */ + _llN1(_asrc),_llE2(_asrc) , + /*---------------------------------- init. free lists */ + _ffN1(_asrc),_ffE2(_asrc) , + /*---------------------------------- init. work lists */ + _tmp1(_asrc) + { + } + + __inline_call~mesh_complex_1 ( + ) + { + clear(containers::tight_alloc); + } + + /* + -------------------------------------------------------- + * "clear" a mesh-complex + -------------------------------------------------------- + */ + + __normal_call void_type clear ( + containers::alloc_types _kind = + containers::loose_alloc + ) + { + this->_aaN1.clear (_kind) ; + + this->_mmE2.clear (_kind) ; + + this->_llN1.clear (_kind) ; + this->_llE2.clear (_kind) ; + + this->_ffN1.clear (_kind) ; + this->_ffE2.clear (_kind) ; + + this->_tmp1.clear (_kind) ; + + this->_hsrc.clear (); + this->_csrc.clear (); + } + + /* + -------------------------------------------------------- + * MAKE-LINK: build item-to-item adj. + -------------------------------------------------------- + */ + + __normal_call void_type make_link ( + ) + { + this->_mmE2.set_slots( + (this->_llE2.count()*5) / 4 + 1 + ) ; + + this->_aaN1.empty () ; + + mesh::link_edge(*this) ; + } + + /* + -------------------------------------------------------- + * PUSH-NODE: append new 0-node to complex. + -------------------------------------------------------- + */ + + __inline_call iptr_type push_node ( + node_type const& _ndat, + bool_type _link = true, + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag + ) + { + return mesh::push_node( + *this, _ndat, _link, _itop, _kind) ; + } + + /* + -------------------------------------------------------- + * PUSH-EDGE: append new 1-edge to complex. + -------------------------------------------------------- + */ + + __inline_call iptr_type push_edge ( + edge_type const& _edat, + bool_type _link = true, + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag + ) + { + return mesh::push_edge( + *this, _edat, _link, _itop, _kind) ; + } + + /* + -------------------------------------------------------- + * _POP-NODE: delete 0-node from complex. + -------------------------------------------------------- + */ + + __inline_call void_type _pop_node ( + iptr_type const*_nptr, + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag + ) + { + mesh::_pop_node(*this, _nptr, _itop, _kind) ; + } + + /* + -------------------------------------------------------- + * _POP-EDGE: delete 1-edge from complex. + -------------------------------------------------------- + */ + + __inline_call void_type _pop_edge ( + iptr_type const*_nptr, + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag + ) + { + mesh::_pop_edge(*this, _nptr, _itop, _kind) ; + } + + __inline_call void_type _pop_edge ( + iptr_type _epos , + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag + ) + { + mesh::_pop_edge(*this, _epos, _itop, _kind) ; + } + + /* + -------------------------------------------------------- + * FIND-NODE: return index of assoc. 0-node. + -------------------------------------------------------- + */ + + __inline_call bool_type find_node ( + iptr_type const*_nptr , + iptr_type&_npos + ) const + { + return mesh::find_node(*this, _nptr, _npos) ; + } + + /* + -------------------------------------------------------- + * FIND-EDGE: return index of assoc. 1-edge. + -------------------------------------------------------- + */ + + __inline_call bool_type find_edge ( + iptr_type const*_node , + iptr_type&_epos + ) + { + return mesh::find_edge(*this, _node, _epos) ; + } + + /* + -------------------------------------------------------- + * FIND-CELL: return index of assoc. k-cell. + -------------------------------------------------------- + */ + + __inline_call bool_type find_cell ( + iptr_type const*_node , + char_type _kind , + iptr_type&_ipos + ) + { + return mesh::find_cell( + *this, _node, _kind, _ipos, mesh_cell()) ; + } + + /* + -------------------------------------------------------- + * CONNECT-1: form this-to-1-cell adj. list. + -------------------------------------------------------- + */ + + __inline_call void_type connect_1 ( + iptr_type const*_node , + char_type _kind , + connector&_conn + ) + { + mesh::connect_1( + *this, _node, _kind, _conn, mesh_cell()) ; + } + + __inline_call void_type connect_1 ( + iptr_type _ipos , + char_type _kind , + connector&_conn + ) + { + mesh::connect_1( + *this, _ipos, _kind, _conn, mesh_cell()) ; + } + + } ; + + + } + +# endif //__MESH_COMPLEX_1__ + + + diff --git a/src/libcpp/mesh_type/mesh_complex_2.hpp b/src/libcpp/mesh_type/mesh_complex_2.hpp new file mode 100644 index 0000000..9302dc1 --- /dev/null +++ b/src/libcpp/mesh_type/mesh_complex_2.hpp @@ -0,0 +1,681 @@ + + /* + -------------------------------------------------------- + * MESH-COMPLEX-2: piecewise mixed complex in T^2. + -------------------------------------------------------- + * + * 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 2020-- + * Darren Engwirda + * d.engwirda@gmail.com + * https://github.com/dengwirda/ + * + -------------------------------------------------------- + */ + +# pragma once + +# ifndef __MESH_COMPLEX_2__ +# define __MESH_COMPLEX_2__ + + namespace mesh { + + /* + -------------------------------------------------------- + * MESH-COMPLEX-2 generic mixed-cell 2-complex. + -------------------------------------------------------- + * NODE-TYPE - 0-cell type + coord.'s + * EDGE-TYPE - 1-cell type + * TRI3-TYPE - 2-cell type + * QUAD-TYPE - 2-cell type + * ALLOCATOR - memory allocator + -------------------------------------------------------- + */ + + template < + typename NN , + typename E2 , + typename T3 , + typename Q4 , + typename AA = allocators::basic_alloc + > + class mesh_complex_2 + { +/*----------------------------------- mesh-complex in T^2 */ + public : + typedef NN node_type ; + typedef E2 edge_type ; + typedef T3 tri3_type ; + typedef Q4 quad_type ; + typedef AA allocator ; + + typedef typename + node_type::real_type real_type ; + typedef typename + edge_type::iptr_type iptr_type ; + typedef typename + allocator::size_type indx_type ; + + indx_type static constexpr topo_dims = +2 ; + + typedef containers::block_array < + node_type, + allocator > node_list ; + + typedef containers::block_array < + edge_type, + allocator > edge_list ; + + typedef containers::block_array < + tri3_type, + allocator > tri3_list ; + + typedef containers::block_array < + quad_type, + allocator > quad_list ; + + typedef containers::array < + iptr_type, + allocator > iptr_list ; + + typedef containers::array < + indx_type, + allocator > indx_list ; + + typedef mesh::node_hash node_hash ; + typedef mesh::node_pred node_pred ; + + typedef mesh::edge_hash edge_hash ; + typedef mesh::edge_pred edge_pred ; + + typedef mesh::tri3_hash tri3_hash ; + typedef mesh::tri3_pred tri3_pred ; + + typedef mesh::quad_hash quad_hash ; + typedef mesh::quad_pred quad_pred ; + + indx_type static + constexpr pool_byte_size = 96 * 1024 ; + + typedef allocators::_pool_alloc < + allocators::basic_alloc , + pool_byte_size > pool_base ; + + typedef allocators::_wrap_alloc < + pool_base > pool_wrap ; + + typedef containers::hash_table < + iptr_type, + edge_hash, + edge_pred, + pool_wrap> edge_maps ; + + typedef containers::hash_table < + iptr_type, + tri3_hash, + tri3_pred, + pool_wrap> tri3_maps ; + + typedef containers::hash_table < + iptr_type, + quad_hash, + quad_pred, + pool_wrap> quad_maps ; + + typedef containers::array < + conn_pair, + allocator > connector ; + + typedef containers::array_list < + conn_pair, + pool_wrap > conn_list ; + + public : + + pool_base _hsrc ; + pool_base _csrc ; + + conn_list _aaN1 ; + conn_list _aaE2 ; + + edge_maps _mmE2 ; + tri3_maps _mmT3 ; + quad_maps _mmQ4 ; + + node_list _llN1 ; + edge_list _llE2 ; + tri3_list _llT3 ; + quad_list _llQ4 ; + + indx_list _ffN1 ; + indx_list _ffE2 ; + indx_list _ffT3 ; + indx_list _ffQ4 ; + + connector _tmp1 ; + connector _tmp2 ; + + public : + + /* + -------------------------------------------------------- + * Public access to underlying data for k-CELL types. + -------------------------------------------------------- + */ + + __inline_call node_list const& node ( + ) const + { return this->_llN1 ; + } + + __inline_call node_list & node ( + ) + { return this->_llN1 ; + } + + __inline_call node_type const& node ( + indx_type _ipos + ) const + { return this->_llN1[_ipos] ; + } + + __inline_call node_type & node ( + indx_type _ipos + ) + { return this->_llN1[_ipos] ; + } + + __inline_call edge_list const& edge ( + ) const + { return this->_llE2 ; + } + + __inline_call edge_list & edge ( + ) + { return this->_llE2 ; + } + + __inline_call edge_type const& edge ( + indx_type _ipos + ) const + { return this->_llE2[_ipos] ; + } + + __inline_call edge_type & edge ( + indx_type _ipos + ) + { return this->_llE2[_ipos] ; + } + + __inline_call tri3_list const& tri3 ( + ) const + { return this->_llT3 ; + } + + __inline_call tri3_list & tri3 ( + ) + { return this->_llT3 ; + } + + __inline_call tri3_type const& tri3 ( + indx_type _ipos + ) const + { return this->_llT3[_ipos] ; + } + + __inline_call tri3_type & tri3 ( + indx_type _ipos + ) + { return this->_llT3[_ipos] ; + } + + __inline_call quad_list const& quad ( + ) const + { return this->_llQ4 ; + } + + __inline_call quad_list & quad ( + ) + { return this->_llQ4 ; + } + + __inline_call quad_type const& quad ( + indx_type _ipos + ) const + { return this->_llQ4[_ipos] ; + } + + __inline_call quad_type & quad ( + indx_type _ipos + ) + { return this->_llQ4[_ipos] ; + } + + public : + + /* + -------------------------------------------------------- + * construct mesh-complex from alloc. etc... + -------------------------------------------------------- + */ + + __normal_call mesh_complex_2 ( + allocator const& _asrc = allocator() + ) : _hsrc(sizeof ( + typename edge_maps::item_type)), + _csrc(sizeof ( + typename conn_list::item_type)), + /*---------------------------------- init. adj. lists */ + _aaN1(pool_wrap(&_csrc)), + _aaE2(pool_wrap(&_csrc)), + /*---------------------------------- init. hash lists */ + _mmE2( + edge_hash(& this->_llE2) , + edge_pred(& this->_llE2) , + +.8, (pool_wrap(&_hsrc))) , + _mmT3( + tri3_hash(& this->_llT3) , + tri3_pred(& this->_llT3) , + +.8, (pool_wrap(&_hsrc))) , + _mmQ4( + quad_hash(& this->_llQ4) , + quad_pred(& this->_llQ4) , + +.8, (pool_wrap(&_hsrc))) , + /*---------------------------------- init. face lists */ + _llN1(_asrc),_llE2(_asrc) , + _llT3(_asrc),_llQ4(_asrc) , + /*---------------------------------- init. free lists */ + _ffN1(_asrc),_ffE2(_asrc) , + _ffT3(_asrc),_ffQ4(_asrc) , + /*---------------------------------- init. work lists */ + _tmp1(_asrc),_tmp2(_asrc) + { + } + + __inline_call~mesh_complex_2 ( + ) + { + clear(containers::tight_alloc); + } + + /* + -------------------------------------------------------- + * "clear" a mesh-complex + -------------------------------------------------------- + */ + + __normal_call void_type clear ( + containers::alloc_types _kind = + containers::loose_alloc + ) + { + this->_aaN1.clear (_kind) ; + this->_aaE2.clear (_kind) ; + + this->_mmE2.clear (_kind) ; + this->_mmT3.clear (_kind) ; + this->_mmQ4.clear (_kind) ; + + this->_llN1.clear (_kind) ; + this->_llE2.clear (_kind) ; + this->_llT3.clear (_kind) ; + this->_llQ4.clear (_kind) ; + + this->_ffN1.clear (_kind) ; + this->_ffE2.clear (_kind) ; + this->_ffT3.clear (_kind) ; + this->_ffQ4.clear (_kind) ; + + this->_tmp1.clear (_kind) ; + this->_tmp2.clear (_kind) ; + + this->_hsrc.clear (); + this->_csrc.clear (); + } + + /* + -------------------------------------------------------- + * MAKE-LINK: build item-to-item adj. + -------------------------------------------------------- + */ + + __normal_call void_type make_link ( + ) + { + this->_mmE2.set_slots( + (this->_llE2.count()*5) / 4 + 1 + + (this->_llT3.count()*3) / 2 + 1 + + (this->_llQ4.count()*4) / 2 + 1 + ) ; + + this->_mmT3.set_slots( + (this->_llT3.count()*5) / 4 + 1 + ) ; + this->_mmQ4.set_slots( + (this->_llQ4.count()*5) / 4 + 1 + ) ; + + this->_aaN1.empty () ; + this->_aaE2.empty () ; + + mesh::link_edge(*this) ; + mesh::link_tri3(*this) ; + mesh::link_quad(*this) ; + } + + /* + -------------------------------------------------------- + * PUSH-NODE: append new 0-node to complex. + -------------------------------------------------------- + */ + + __inline_call iptr_type push_node ( + node_type const& _ndat, + bool_type _link = true, + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag + ) + { + return mesh::push_node( + *this, _ndat, _link, _itop, _kind) ; + } + + /* + -------------------------------------------------------- + * PUSH-EDGE: append new 1-edge to complex. + -------------------------------------------------------- + */ + + __inline_call iptr_type push_edge ( + edge_type const& _edat, + bool_type _link = true, + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag + ) + { + return mesh::push_edge( + *this, _edat, _link, _itop, _kind) ; + } + + /* + -------------------------------------------------------- + * PUSH-TRIA: append new 2-tria to complex. + -------------------------------------------------------- + */ + + __inline_call iptr_type push_tri3 ( + tri3_type const& _tdat, + bool_type _link = true, + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag + ) + { + return mesh::push_tri3( + *this, _tdat, _link, _itop, _kind) ; + } + + /* + -------------------------------------------------------- + * PUSH-QUAD: append new 2-quad to complex. + -------------------------------------------------------- + */ + + __inline_call iptr_type push_quad ( + quad_type const& _qdat, + bool_type _link = true, + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag + ) + { + return mesh::push_quad( + *this, _qdat, _link, _itop, _kind) ; + } + + /* + -------------------------------------------------------- + * _POP-NODE: delete 0-node from complex. + -------------------------------------------------------- + */ + + __inline_call void_type _pop_node ( + iptr_type const*_nptr, + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag + ) + { + mesh::_pop_node(*this, _nptr, _itop, _kind) ; + } + + /* + -------------------------------------------------------- + * _POP-EDGE: delete 1-edge from complex. + -------------------------------------------------------- + */ + + __inline_call void_type _pop_edge ( + iptr_type const*_nptr, + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag + ) + { + mesh::_pop_edge(*this, _nptr, _itop, _kind) ; + } + + __inline_call void_type _pop_edge ( + iptr_type _epos , + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag + ) + { + mesh::_pop_edge(*this, _epos, _itop, _kind) ; + } + + /* + -------------------------------------------------------- + * _POP-TRIA: delete 2-tria from complex. + -------------------------------------------------------- + */ + + __inline_call void_type _pop_tri3 ( + iptr_type const*_nptr, + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag + ) + { + mesh::_pop_tri3(*this, _nptr, _itop, _kind) ; + } + + __inline_call void_type _pop_tri3 ( + iptr_type _tpos , + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag + ) + { + mesh::_pop_tri3(*this, _tpos, _itop, _kind) ; + } + + /* + -------------------------------------------------------- + * _POP-QUAD: delete 2-quad from complex. + -------------------------------------------------------- + */ + + __inline_call void_type _pop_quad ( + iptr_type const*_nptr, + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag + ) + { + mesh::_pop_quad(*this, _nptr, _itop, _kind) ; + } + + __inline_call void_type _pop_quad ( + iptr_type _qpos , + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag + ) + { + mesh::_pop_quad(*this, _qpos, _itop, _kind) ; + } + + /* + -------------------------------------------------------- + * FIND-NODE: return index of assoc. 0-node. + -------------------------------------------------------- + */ + + __inline_call bool_type find_node ( + iptr_type const*_nptr , + iptr_type&_npos + ) const + { + return mesh::find_node(*this, _nptr, _npos) ; + } + + /* + -------------------------------------------------------- + * FIND-EDGE: return index of assoc. 1-edge. + -------------------------------------------------------- + */ + + __inline_call bool_type find_edge ( + iptr_type const*_node , + iptr_type&_epos + ) + { + return mesh::find_edge(*this, _node, _epos) ; + } + + /* + -------------------------------------------------------- + * FIND-TRIA: return index of assoc. 2-tria. + -------------------------------------------------------- + */ + + __inline_call bool_type find_tri3 ( + iptr_type const*_node , + iptr_type&_tpos + ) + { + return mesh::find_tri3(*this, _node, _tpos) ; + } + + /* + -------------------------------------------------------- + * FIND-QUAD: return index of assoc. 2-quad. + -------------------------------------------------------- + */ + + __inline_call bool_type find_quad ( + iptr_type const*_node , + iptr_type&_qpos + ) + { + return mesh::find_quad(*this, _node, _qpos) ; + } + + /* + -------------------------------------------------------- + * FIND-CELL: return index of assoc. k-cell. + -------------------------------------------------------- + */ + + __inline_call bool_type find_cell ( + iptr_type const*_node , + char_type _kind , + iptr_type&_ipos + ) + { + return mesh::find_cell( + *this, _node, _kind, _ipos, mesh_cell()) ; + } + + /* + -------------------------------------------------------- + * CONNECT-1: form this-to-1-cell adj. list. + -------------------------------------------------------- + */ + + __inline_call void_type connect_1 ( + iptr_type const*_node , + char_type _kind , + connector&_conn + ) + { + mesh::connect_1( + *this, _node, _kind, _conn, mesh_cell()) ; + } + + __inline_call void_type connect_1 ( + iptr_type _ipos , + char_type _kind , + connector&_conn + ) + { + mesh::connect_1( + *this, _ipos, _kind, _conn, mesh_cell()) ; + } + + /* + -------------------------------------------------------- + * CONNECT-2: form this-to-2-cell adj. list. + -------------------------------------------------------- + */ + + __inline_call void_type connect_2 ( + iptr_type const*_node , + char_type _kind , + connector&_conn + ) + { + mesh::connect_2( + *this, _node, _kind, _conn, mesh_cell()) ; + } + + __inline_call void_type connect_2 ( + iptr_type _ipos , + char_type _kind , + connector&_conn + ) + { + mesh::connect_2( + *this, _ipos, _kind, _conn, mesh_cell()) ; + } + + } ; + + + } + +# endif //__MESH_COMPLEX_2__ + + + diff --git a/src/libcpp/mesh_type/mesh_complex_3.hpp b/src/libcpp/mesh_type/mesh_complex_3.hpp index d08871e..37034fd 100644 --- a/src/libcpp/mesh_type/mesh_complex_3.hpp +++ b/src/libcpp/mesh_type/mesh_complex_3.hpp @@ -1,7 +1,7 @@ /* -------------------------------------------------------- - * MESH-COMPLEX-3: piecewise mixed complex in R^3. + * MESH-COMPLEX-3: piecewise mixed complex in T^3. -------------------------------------------------------- * * This program may be freely redistributed under the @@ -31,11 +31,11 @@ * -------------------------------------------------------- * - * Last updated: 09 November, 2019 + * Last updated: 28 April, 2020 * - * Copyright 2013-2019 + * Copyright 2020-- * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- @@ -52,14 +52,14 @@ -------------------------------------------------------- * MESH-COMPLEX-3 generic mixed-cell 3-complex. -------------------------------------------------------- - * NODE-TYPE - 0-face type + coord.'s - * EDGE-TYPE - 1-face type - * TRI3-TYPE - 2-face type - * QUAD-TYPE - 2-face type - * TRI4-TYPE - 3-face type - * HEXA-TYPE - 3-face type - * PYRA-TYPE - 3-face type - * WEDG-TYPE - 3-face type + * NODE-TYPE - 0-cell type + coord.'s + * EDGE-TYPE - 1-cell type + * TRI3-TYPE - 2-cell type + * QUAD-TYPE - 2-cell type + * TRI4-TYPE - 3-cell type + * HEXA-TYPE - 3-cell type + * WEDG-TYPE - 3-cell type + * PYRA-TYPE - 3-cell type * ALLOCATOR - memory allocator -------------------------------------------------------- */ @@ -71,13 +71,13 @@ typename Q4 , typename T4 , typename H8 , - typename P5 , typename W6 , + typename P5 , typename AA = allocators::basic_alloc > class mesh_complex_3 { -/*----------------------------------- mesh-complex in R^3 */ +/*----------------------------------- mesh-complex in T^3 */ public : typedef NN node_type ; typedef E2 edge_type ; @@ -85,8 +85,8 @@ typedef Q4 quad_type ; typedef T4 tri4_type ; typedef H8 hexa_type ; - typedef P5 pyra_type ; typedef W6 wedg_type ; + typedef P5 pyra_type ; typedef AA allocator ; typedef typename @@ -94,9 +94,9 @@ typedef typename edge_type::iptr_type iptr_type ; typedef typename - allocator::size_type size_type ; + allocator::size_type indx_type ; - iptr_type static constexpr _dims = +3 ; + iptr_type static constexpr topo_dims = +3 ; typedef containers::block_array < node_type, @@ -122,309 +122,48 @@ hexa_type, allocator > hexa_list ; - typedef containers::block_array < - pyra_type, - allocator > pyra_list ; - typedef containers::block_array < wedg_type, allocator > wedg_list ; + typedef containers::block_array < + pyra_type, + allocator > pyra_list ; + typedef containers::array < iptr_type, allocator > iptr_list ; - #define __hashscal sizeof(iptr_type)/sizeof(uint32_t) - - class node_hash - { - public : - __const_ptr(node_list) _nset ; - public : - /*----------------------- build hash _obj. from _src. */ - __inline_call node_hash ( - node_list *_nsrc - ) : _nset( _nsrc) {} - /*----------------------- hash node indexing for node */ - __inline_call - uint32_t operator() ( - iptr_type _npos - ) const - { - return this->_nset-> - operator[](_npos).node( 0) ; - } - } ; - - class edge_hash - { - public : - __const_ptr(edge_list) _eset ; - public : - /*----------------------- build hash _obj. from _src. */ - __inline_call edge_hash ( - edge_list *_esrc - ) : _eset( _esrc) {} - /*----------------------- hash node indexing for edge */ - __inline_call - uint32_t operator() ( - iptr_type _epos - ) const - { - iptr_type _enod[2]; - _enod[0] = this->_eset-> - operator[](_epos).node( 0) ; - _enod[1] = this->_eset-> - operator[](_epos).node( 1) ; - - algorithms::isort ( - &_enod[0], &_enod[2] , - std::less()); - - return hash::hashword ( - (uint32_t*)&_enod[0] , - +2 * __hashscal, +137) ; - } - } ; - - class tri3_hash - { - public : - __const_ptr(tri3_list) _tset ; - public : - /*----------------------- build hash _obj. from _src. */ - __inline_call tri3_hash ( - tri3_list *_tsrc - ) : _tset( _tsrc) {} - /*----------------------- hash node indexing for face */ - __inline_call - uint32_t operator() ( - iptr_type _tpos - ) const - { - iptr_type _tnod[3]; - _tnod[0] = this->_tset-> - operator[](_tpos).node( 0) ; - _tnod[1] = this->_tset-> - operator[](_tpos).node( 1) ; - _tnod[2] = this->_tset-> - operator[](_tpos).node( 2) ; - - algorithms::isort ( - &_tnod[0], &_tnod[3] , - std::less()); - - return hash::hashword ( - (uint32_t*)&_tnod[0] , - +3 * __hashscal, +137) ; - } - } ; - - class tri4_hash - { - public : - __const_ptr(tri4_list) _tset ; - public : - /*----------------------- build hash _obj. from _src. */ - __inline_call tri4_hash ( - tri4_list *_tsrc - ) : _tset( _tsrc) {} - /*----------------------- hash node indexing for face */ - __inline_call - uint32_t operator() ( - iptr_type _tpos - ) const - { - iptr_type _tnod[4]; - _tnod[0] = this->_tset-> - operator[](_tpos).node( 0) ; - _tnod[1] = this->_tset-> - operator[](_tpos).node( 1) ; - _tnod[2] = this->_tset-> - operator[](_tpos).node( 2) ; - _tnod[3] = this->_tset-> - operator[](_tpos).node( 3) ; - - algorithms::isort ( - &_tnod[0], &_tnod[4] , - std::less()); - - return hash::hashword ( - (uint32_t*)&_tnod[0] , - +4 * __hashscal, +137) ; - } - } ; - - - class node_pred - { - public : - __const_ptr(node_list) _nset ; - public : - /*----------------------- build hash _obj. from _src. */ - __inline_call node_pred ( - node_list *_nsrc - ) : _nset( _nsrc) {} - /*----------------------- compute "equal-to" for node */ - __inline_call - bool_type operator() ( - iptr_type _ipos, - iptr_type _jpos - ) const - { - iptr_type _inod[1]; - _inod[0] = this->_nset-> - operator[](_ipos).node( 0) ; - - iptr_type _jnod[1]; - _jnod[0] = this->_nset-> - operator[](_jpos).node( 0) ; - - return _inod[0] == _jnod[0] ; - } - } ; - - class edge_pred - { - public : - __const_ptr(edge_list) _eset ; - public : - /*----------------------- build hash _obj. from _src. */ - __inline_call edge_pred ( - edge_list *_esrc - ) : _eset( _esrc) {} - /*----------------------- compute "equal-to" for edge */ - __inline_call - bool_type operator() ( - iptr_type _ipos, - iptr_type _jpos - ) const - { - iptr_type _inod[2]; - _inod[0] = this->_eset-> - operator[](_ipos).node( 0) ; - _inod[1] = this->_eset-> - operator[](_ipos).node( 1) ; - - iptr_type _jnod[2]; - _jnod[0] = this->_eset-> - operator[](_jpos).node( 0) ; - _jnod[1] = this->_eset-> - operator[](_jpos).node( 1) ; - - algorithms::isort ( - &_inod[0], &_inod[2], - std::less()); - - algorithms::isort ( - &_jnod[0], &_jnod[2], - std::less()); - - return _inod[0] == _jnod[0] && - _inod[1] == _jnod[1] ; - } - } ; - - class tri3_pred - { - public : - __const_ptr(tri3_list) _tset ; - public : - /*----------------------- build hash _obj. from _src. */ - __inline_call tri3_pred ( - tri3_list *_tsrc - ) : _tset( _tsrc) {} - /*----------------------- compute "equal-to" for face */ - __inline_call - bool_type operator() ( - iptr_type _ipos, - iptr_type _jpos - ) const - { - iptr_type _inod[3]; - _inod[0] = this->_tset-> - operator[](_ipos).node( 0) ; - _inod[1] = this->_tset-> - operator[](_ipos).node( 1) ; - _inod[2] = this->_tset-> - operator[](_ipos).node( 2) ; - - iptr_type _jnod[3]; - _jnod[0] = this->_tset-> - operator[](_jpos).node( 0) ; - _jnod[1] = this->_tset-> - operator[](_jpos).node( 1) ; - _jnod[2] = this->_tset-> - operator[](_jpos).node( 2) ; - - algorithms::isort ( - &_inod[0], &_inod[3], - std::less()); - - algorithms::isort ( - &_jnod[0], &_jnod[3], - std::less()); - - return _inod[0] == _jnod[0] && - _inod[1] == _jnod[1] && - _inod[2] == _jnod[2] ; - } - } ; - - class tri4_pred - { - public : - __const_ptr(tri4_list) _tset ; - public : - /*----------------------- build hash _obj. from _src. */ - __inline_call tri4_pred ( - tri4_list *_tsrc - ) : _tset( _tsrc) {} - /*----------------------- compute "equal-to" for face */ - __inline_call - bool_type operator() ( - iptr_type _ipos, - iptr_type _jpos - ) const - { - iptr_type _inod[4]; - _inod[0] = this->_tset-> - operator[](_ipos).node( 0) ; - _inod[1] = this->_tset-> - operator[](_ipos).node( 1) ; - _inod[2] = this->_tset-> - operator[](_ipos).node( 2) ; - _inod[3] = this->_tset-> - operator[](_ipos).node( 3) ; - - iptr_type _jnod[4]; - _jnod[0] = this->_tset-> - operator[](_jpos).node( 0) ; - _jnod[1] = this->_tset-> - operator[](_jpos).node( 1) ; - _jnod[2] = this->_tset-> - operator[](_jpos).node( 2) ; - _jnod[3] = this->_tset-> - operator[](_jpos).node( 3) ; - - algorithms::isort ( - &_inod[0], &_inod[4], - std::less()); - - algorithms::isort ( - &_jnod[0], &_jnod[4], - std::less()); - - return _inod[0] == _jnod[0] && - _inod[1] == _jnod[1] && - _inod[2] == _jnod[2] && - _inod[3] == _jnod[3] ; - } - } ; - - #undef __hashscal - - iptr_type static const pool_byte_size=96*1024 ; + typedef containers::array < + indx_type, + allocator > indx_list ; + + typedef mesh::node_hash node_hash ; + typedef mesh::node_pred node_pred ; + + typedef mesh::edge_hash edge_hash ; + typedef mesh::edge_pred edge_pred ; + + typedef mesh::tri3_hash tri3_hash ; + typedef mesh::tri3_pred tri3_pred ; + + typedef mesh::quad_hash quad_hash ; + typedef mesh::quad_pred quad_pred ; + + typedef mesh::tri4_hash tri4_hash ; + typedef mesh::tri4_pred tri4_pred ; + + typedef mesh::hexa_hash hexa_hash ; + typedef mesh::hexa_pred hexa_pred ; + + typedef mesh::wedg_hash wedg_hash ; + typedef mesh::wedg_pred wedg_pred ; + + typedef mesh::pyra_hash pyra_hash ; + typedef mesh::pyra_pred pyra_pred ; + + indx_type static + constexpr pool_byte_size = 96 * 1024 ; typedef allocators::_pool_alloc < allocators::basic_alloc , @@ -433,12 +172,6 @@ typedef allocators::_wrap_alloc < pool_base > pool_wrap ; - //typedef containers::hash_table < - // iptr_type, - // node_hash, - // node_pred, - // pool_wrap> node_maps ; - typedef containers::hash_table < iptr_type, edge_hash, @@ -451,268 +184,340 @@ tri3_pred, pool_wrap> tri3_maps ; + typedef containers::hash_table < + iptr_type, + quad_hash, + quad_pred, + pool_wrap> quad_maps ; + typedef containers::hash_table < iptr_type, tri4_hash, tri4_pred, pool_wrap> tri4_maps ; - typedef containers::array_list < + typedef containers::hash_table < + iptr_type, + hexa_hash, + hexa_pred, + pool_wrap> hexa_maps ; + + typedef containers::hash_table < + iptr_type, + wedg_hash, + wedg_pred, + pool_wrap> wedg_maps ; + + typedef containers::hash_table < iptr_type, + pyra_hash, + pyra_pred, + pool_wrap> pyra_maps ; + + typedef containers::array < + conn_pair, + allocator > connector ; + + typedef containers::array_list < + conn_pair, pool_wrap > conn_list ; public : - pool_base _hsrc ; - pool_base _csrc ; - - conn_list _N1E2 ; - conn_list _E2T3 ; - conn_list _E2Q4 ; - conn_list _T3T4 ; - conn_list _T3P5 ; - conn_list _T3W6 ; - conn_list _adj4 ; - - //node_maps _mmN1 ; - edge_maps _mmE2 ; - tri3_maps _mmT3 ; - quad_maps _mmQ4 ; - tri4_maps _mmT4 ; - hexa_maps _mmH8 ; - pyra_maps _mmP5 ; - wedg_maps _mmW6 ; - - node_list _llN1 ; - edge_list _llE2 ; - tri3_list _llT3 ; - quad_list _llQ4 ; - tri4_list _llT4 ; - hexa_list _llH8 ; - pyra_list _llP5 ; - wedg_list _llW6 ; - - iptr_list _del1 ; - iptr_list _del2 ; - iptr_list _del3 ; - iptr_list _del4 ; - - iptr_list _tmp1 ; - iptr_list _tmp2 ; - iptr_list _tmp3 ; - iptr_list _tmp4 ; + pool_base _hsrc ; + pool_base _csrc ; + + conn_list _aaN1 ; + conn_list _aaE2 ; + conn_list _aaT3 ; + conn_list _aaQ4 ; + + edge_maps _mmE2 ; + tri3_maps _mmT3 ; + quad_maps _mmQ4 ; + tri4_maps _mmT4 ; + hexa_maps _mmH8 ; + wedg_maps _mmW6 ; + pyra_maps _mmP5 ; + + node_list _llN1 ; + edge_list _llE2 ; + tri3_list _llT3 ; + quad_list _llQ4 ; + tri4_list _llT4 ; + hexa_list _llH8 ; + wedg_list _llW6 ; + pyra_list _llP5 ; + + indx_list _ffN1 ; + indx_list _ffE2 ; + indx_list _ffT3 ; + indx_list _ffQ4 ; + indx_list _ffT4 ; + indx_list _ffH8 ; + indx_list _ffW6 ; + indx_list _ffP5 ; + + connector _tmp1 ; + connector _tmp2 ; + connector _tmp3 ; public : /* -------------------------------------------------------- - * GET-NODE: "create" new node, push onto active set. + * Public access to underlying data for k-CELL types. -------------------------------------------------------- */ - __inline_call iptr_type _get_node ( + __inline_call node_list const& node ( // node + ) const + { return this->_llN1 ; + } + + __inline_call node_list & node ( ) - { - iptr_type _ipos = -1; - if (this->_del1.count() != +0 ) - { - /*---------------------------- recycle from free list */ - this->_del1._pop_tail(_ipos) ; - } - else - { - /*---------------------------- alloc. from underlying */ - _ipos = (iptr_type) - this->_set1.count() ; - this->_set1.push_tail() ; - } - - this->_set1[_ipos].mark() = +0 ; - this->_set1[_ipos].self() = +0 ; - - return ( _ipos ) ; + { return this->_llN1 ; } - /* - -------------------------------------------------------- - * GET-EDGE: "create" new edge, push onto active set. - -------------------------------------------------------- - */ + __inline_call node_type const& node ( + indx_type _ipos + ) const + { return this->_llN1[_ipos] ; + } - __inline_call iptr_type _get_edge ( + __inline_call node_type & node ( + indx_type _ipos ) - { - iptr_type _ipos = -1; - if (this->_del2.count() != +0 ) - { - /*---------------------------- recycle from free list */ - this->_del2._pop_tail(_ipos) ; - } - else - { - /*---------------------------- alloc. from underlying */ - _ipos = (iptr_type) - this->_set2.count() ; - this->_set2.push_tail() ; - } - - this->_set2[_ipos].mark() = +0 ; - this->_set2[_ipos].self() = +0 ; - - return ( _ipos ) ; + { return this->_llN1[_ipos] ; } - /* - -------------------------------------------------------- - * GET-TRIA: "create" new tria, push onto active set. - -------------------------------------------------------- - */ + __inline_call edge_list const& edge ( // edge + ) const + { return this->_llE2 ; + } - __inline_call iptr_type _get_tri3 ( + __inline_call edge_list & edge ( ) - { - iptr_type _ipos = -1; - if (this->_del3.count() != +0 ) - { - /*---------------------------- recycle from free list */ - this->_del3._pop_tail(_ipos) ; - } - else - { - /*---------------------------- alloc. from underlying */ - _ipos = (iptr_type) - this->_set3.count() ; - this->_set3.push_tail() ; - } - - this->_set3[_ipos].mark() = +0 ; - this->_set3[_ipos].self() = +0 ; - - return ( _ipos ) ; + { return this->_llE2 ; } - /* - -------------------------------------------------------- - * GET-TRIA: "create" new tria, push onto active set. - -------------------------------------------------------- - */ + __inline_call edge_type const& edge ( + indx_type _ipos + ) const + { return this->_llE2[_ipos] ; + } - __inline_call iptr_type _get_tri4 ( + __inline_call edge_type & edge ( + indx_type _ipos ) - { - iptr_type _ipos = -1; - if (this->_del4.count() != +0 ) - { - /*---------------------------- recycle from free list */ - this->_del4._pop_tail(_ipos) ; - } - else - { - /*---------------------------- alloc. from underlying */ - _ipos = (iptr_type) - this->_set4.count() ; - this->_set4.push_tail() ; - } - - this->_set4[_ipos].mark() = +0 ; - this->_set4[_ipos].self() = +0 ; - - return ( _ipos ) ; + { return this->_llE2[_ipos] ; } - /* - -------------------------------------------------------- - * PUT-ITEM: "delete" old item, _pop from active set. - -------------------------------------------------------- - */ + __inline_call tri3_list const& tri3 ( // tri3 + ) const + { return this->_llT3 ; + } - __inline_call void_type _put_node ( - iptr_type _ipos + __inline_call tri3_list & tri3 ( ) - { - this->_del1.push_tail (_ipos); - this->_set1[_ipos].mark() = -1 ; - this->_set1[_ipos].self() = -1 ; + { return this->_llT3 ; + } + + __inline_call tri3_type const& tri3 ( + indx_type _ipos + ) const + { return this->_llT3[_ipos] ; } - __inline_call void_type _put_edge ( - iptr_type _ipos + __inline_call tri3_type & tri3 ( + indx_type _ipos ) - { - this->_del2.push_tail (_ipos); - this->_set2[_ipos].mark() = -1 ; - this->_set2[_ipos].self() = -1 ; + { return this->_llT3[_ipos] ; + } + + __inline_call quad_list const& quad ( // quad + ) const + { return this->_llQ4 ; } - __inline_call void_type _put_tri3 ( - iptr_type _ipos + __inline_call quad_list & quad ( ) - { - this->_del3.push_tail (_ipos); - this->_set3[_ipos].mark() = -1 ; - this->_set3[_ipos].self() = -1 ; + { return this->_llQ4 ; + } + + __inline_call quad_type const& quad ( + indx_type _ipos + ) const + { return this->_llQ4[_ipos] ; } - __inline_call void_type _put_tri4 ( - iptr_type _ipos + __inline_call quad_type & quad ( + indx_type _ipos ) - { - this->_del4.push_tail (_ipos); - this->_set4[_ipos].mark() = -1 ; - this->_set4[_ipos].self() = -1 ; + { return this->_llQ4[_ipos] ; + } + + __inline_call tri4_list const& tri4 ( // tri4 + ) const + { return this->_llT4 ; + } + + __inline_call tri4_list & tri4 ( + ) + { return this->_llT4 ; + } + + __inline_call tri4_type const& tri4 ( + indx_type _ipos + ) const + { return this->_llT4[_ipos] ; + } + + __inline_call tri4_type & tri4 ( + indx_type _ipos + ) + { return this->_llT4[_ipos] ; + } + + __inline_call hexa_list const& hexa ( // hexa + ) const + { return this->_llH8 ; + } + + __inline_call hexa_list & hexa ( + ) + { return this->_llH8 ; + } + + __inline_call hexa_type const& hexa ( + indx_type _ipos + ) const + { return this->_llH8[_ipos] ; + } + + __inline_call hexa_type & hexa ( + indx_type _ipos + ) + { return this->_llH8[_ipos] ; + } + + __inline_call wedg_list const& wedg ( // wedg + ) const + { return this->_llW6 ; + } + + __inline_call wedg_list & wedg ( + ) + { return this->_llW6 ; + } + + __inline_call wedg_type const& wedg ( + indx_type _ipos + ) const + { return this->_llW6[_ipos] ; + } + + __inline_call wedg_type & wedg ( + indx_type _ipos + ) + { return this->_llW6[_ipos] ; + } + + __inline_call pyra_list const& pyra ( // pyra + ) const + { return this->_llP5 ; + } + + __inline_call pyra_list & pyra ( + ) + { return this->_llP5 ; + } + + __inline_call pyra_type const& pyra ( + indx_type _ipos + ) const + { return this->_llP5[_ipos] ; + } + + __inline_call pyra_type & pyra ( + indx_type _ipos + ) + { return this->_llP5[_ipos] ; } public : /* -------------------------------------------------------- - * construct tria_complex from alloc. etc... + * construct mesh-complex from alloc. etc... -------------------------------------------------------- */ - __normal_call tria_complex_3 ( + __normal_call mesh_complex_3 ( allocator const& _asrc = allocator() ) : _hsrc(sizeof ( - typename tri4_maps::item_type)), + typename edge_maps::item_type)), _csrc(sizeof ( - typename conn_list::item_type)), - /*------------------------------ init. adj. lists */ - _adj1(pool_wrap(&_csrc)), - _adj2(pool_wrap(&_csrc)), - _adj3(pool_wrap(&_csrc)), - _adj4(pool_wrap(&_csrc)), - /*------------------------------ init. hash lists */ - //_map1( - // node_hash(& this->_set1) , - // node_pred(& this->_set1) , - //+.8, (pool_wrap(&_hsrc))) , - _map2( - edge_hash(& this->_set2) , - edge_pred(& this->_set2) , - +.8, (pool_wrap(&_hsrc))) , - _map3( - tri3_hash(& this->_set3) , - tri3_pred(& this->_set3) , - +.8, (pool_wrap(&_hsrc))) , - _map4( - tri4_hash(& this->_set4) , - tri4_pred(& this->_set4) , - +.8, (pool_wrap(&_hsrc))) , - /*------------------------------ init. face lists */ - _set1(_asrc),_set2(_asrc) , - _set3(_asrc),_set4(_asrc) , - /*------------------------------ init. free lists */ - _del1(_asrc),_del2(_asrc) , - _del3(_asrc),_del4(_asrc) , - /*------------------------------ init. work lists */ - _tmp1(_asrc),_tmp2(_asrc) , - _tmp3(_asrc),_tmp4(_asrc) - { - } + typename conn_list::item_type)), + /*---------------------------------- init. adj. lists */ + _aaN1(pool_wrap(&_csrc)), + _aaE2(pool_wrap(&_csrc)), + _aaT3(pool_wrap(&_csrc)), + _aaQ4(pool_wrap(&_csrc)), + /*---------------------------------- init. hash lists */ + _mmE2( + edge_hash(& this->_llE2) , + edge_pred(& this->_llE2) , + +.8, (pool_wrap(&_hsrc))) , + _mmT3( + tri3_hash(& this->_llT3) , + tri3_pred(& this->_llT3) , + +.8, (pool_wrap(&_hsrc))) , + _mmQ4( + quad_hash(& this->_llQ4) , + quad_pred(& this->_llQ4) , + +.8, (pool_wrap(&_hsrc))) , + _mmT4( + tri4_hash(& this->_llT4) , + tri4_pred(& this->_llT4) , + +.8, (pool_wrap(&_hsrc))) , + _mmH8( + hexa_hash(& this->_llH8) , + hexa_pred(& this->_llH8) , + +.8, (pool_wrap(&_hsrc))) , + _mmW6( + wedg_hash(& this->_llW6) , + wedg_pred(& this->_llW6) , + +.8, (pool_wrap(&_hsrc))) , + _mmP5( + pyra_hash(& this->_llP5) , + pyra_pred(& this->_llP5) , + +.8, (pool_wrap(&_hsrc))) , + /*---------------------------------- init. face lists */ + _llN1(_asrc),_llE2(_asrc) , + _llT3(_asrc),_llQ4(_asrc) , + _llT4(_asrc),_llH8(_asrc) , + _llW6(_asrc),_llP5(_asrc) , + /*---------------------------------- init. free lists */ + _ffN1(_asrc),_ffE2(_asrc) , + _ffT3(_asrc),_ffQ4(_asrc) , + _ffT4(_asrc),_ffH8(_asrc) , + _ffW6(_asrc),_ffP5(_asrc) , + /*---------------------------------- init. work lists */ + _tmp1(_asrc),_tmp2(_asrc),_tmp3(_asrc) + { + } + + __inline_call~mesh_complex_3 ( + ) + { + clear(containers::tight_alloc); + } /* -------------------------------------------------------- - * 'clear' a tria-complex + * "clear" a mesh-complex -------------------------------------------------------- */ @@ -721,50 +526,83 @@ containers::loose_alloc ) { - this->_adj1.clear (_kind) ; - this->_adj2.clear (_kind) ; - this->_adj3.clear (_kind) ; - this->_adj4.clear (_kind) ; - - //this->_map1.clear (_kind) ; - this->_map2.clear (_kind) ; - this->_map3.clear (_kind) ; - this->_map4.clear (_kind) ; - - this->_set1.clear (_kind) ; - this->_set2.clear (_kind) ; - this->_set3.clear (_kind) ; - this->_set4.clear (_kind) ; - - this->_del1.clear (_kind) ; - this->_del2.clear (_kind) ; - this->_del3.clear (_kind) ; - this->_del4.clear (_kind) ; - - this->_tmp1.clear (_kind) ; - this->_tmp2.clear (_kind) ; - this->_tmp3.clear (_kind) ; - this->_tmp4.clear (_kind) ; - - this->_hsrc.clear (); - this->_csrc.clear (); + this->_aaN1.clear (_kind) ; + this->_aaE2.clear (_kind) ; + this->_aaT3.clear (_kind) ; + this->_aaQ4.clear (_kind) ; + + this->_mmE2.clear (_kind) ; + this->_mmT3.clear (_kind) ; + this->_mmQ4.clear (_kind) ; + this->_mmT4.clear (_kind) ; + this->_mmH8.clear (_kind) ; + this->_mmW6.clear (_kind) ; + this->_mmP5.clear (_kind) ; + + this->_llN1.clear (_kind) ; + this->_llE2.clear (_kind) ; + this->_llT3.clear (_kind) ; + this->_llQ4.clear (_kind) ; + this->_llT4.clear (_kind) ; + this->_llH8.clear (_kind) ; + this->_llW6.clear (_kind) ; + this->_llP5.clear (_kind) ; + + this->_ffN1.clear (_kind) ; + this->_ffE2.clear (_kind) ; + this->_ffT3.clear (_kind) ; + this->_ffQ4.clear (_kind) ; + this->_ffT4.clear (_kind) ; + this->_ffH8.clear (_kind) ; + this->_ffW6.clear (_kind) ; + this->_ffP5.clear (_kind) ; + + this->_tmp1.clear (_kind) ; + this->_tmp2.clear (_kind) ; + this->_tmp3.clear (_kind) ; + + this->_hsrc.clear (); + this->_csrc.clear (); } /* -------------------------------------------------------- - * INIT-LIST: re-size adj. lists on demand. + * MAKE-LINK: build item-to-item adj. -------------------------------------------------------- */ - __inline_call void_type init_list ( - conn_list&_list, - size_type _lpos + __normal_call void_type make_link ( ) { - if (_lpos >= _list._lptr.count()) - _list._lptr.set_count ( - _lpos + 1, - containers::loose_alloc, nullptr) ; + this->_mmE2.set_slots( + (this->_llE2.count()*5) / 4 + 1 + + (this->_llT3.count()*3) / 2 + 1 + + (this->_llQ4.count()*4) / 2 + 1 + + (this->_llT4.count()*6) / 2 + 1 + ) ; + + this->_mmT3.set_slots( + (this->_llT3.count()*5) / 4 + 1 + + (this->_llT4.count()*4) / 2 + 1 + ) ; + this->_mmQ4.set_slots( + (this->_llQ4.count()*5) / 4 + 1 + + (this->_llH8.count()*6) / 2 + 1 + ) ; + + this->_mmT4.set_slots( + (this->_llT4.count()*5) / 4 + 1 + ) ; + + this->_aaN1.empty () ; + this->_aaE2.empty () ; + this->_aaT3.empty () ; + this->_aaQ4.empty () ; + + mesh::link_edge(*this) ; + mesh::link_tri3(*this) ; + mesh::link_quad(*this) ; + mesh::link_tri4(*this) ; } /* @@ -773,69 +611,15 @@ -------------------------------------------------------- */ - __normal_call iptr_type push_node ( + __inline_call iptr_type push_node ( node_type const& _ndat, bool_type _link = true, - iptr_type _itop = -1 + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag ) { - iptr_type _ipos = -1 ; - - if (!_link) - { - - __assert( _itop == -1 && - "tria-complex: non-top node!" ) ; - - /*------------------------ init. external d-face data */ - _ipos = _get_node(); - - this->_set1[_ipos] = _ndat ; - this->_set1[_ipos].mark() = 0 ; - - this->_set1[_ipos].self() = 1 ; - this-> - _set1 [_ipos].node(0) =_ipos ; - - /*------------------------ init. local adj. index set */ - init_list(this->_adj1, _ipos) ; - - } - else - { - - if (_itop == -1) - { - /*------------------------ init. external d-face data */ - _ipos = _get_node(); - - this->_set1[_ipos] = _ndat ; - this->_set1[_ipos].mark() = 0 ; - this->_set1[_ipos].self() = 1 ; - - this-> - _set1 [_ipos].node(0) = _ipos; - - /*------------------------ init. local adj. index set */ - init_list(this->_adj1, _ipos) ; - - } - else - { - /*------------------------ init. internal d-face data */ - __assert(find_node( - &_ndat.node(0), _ipos) && - "tria-complex: node not here" ); - - /*------------------------ append index to adj. lists */ - this->_adj1.push( - _itop, _ndat.node(0)) ; - - } - - } - - return _ipos ; + return mesh::push_node( + *this, _ndat, _link, _itop, _kind) ; } /* @@ -844,97 +628,15 @@ -------------------------------------------------------- */ - __normal_call iptr_type push_edge ( + __inline_call iptr_type push_edge ( edge_type const& _edat, bool_type _link = true, - iptr_type _itop = -1 + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag ) { - iptr_type _ipos = _get_edge() ; - iptr_type _npos ; - - if (!_link) - { - - __assert( _itop == -1 && - "tria-complex: non-top cell!" ) ; - - /*------------------------ init. external d-face data */ - this->_set2[_ipos] = _edat ; - this->_set2[_ipos].mark() = 0 ; - this->_set2[_ipos].self() = 1 ; - - /*------------------------ init. local adj. index set */ - init_list(this->_adj2, _ipos) ; - - } - else - { - - /*------------------------ init. external d-face data */ - this->_set2[_ipos] = _edat ; - this->_set2[_ipos].mark() = 0 ; - - if (_itop == -1) - this->_set2[_ipos].self() = 1 ; - else - this->_set2[_ipos].self() = 0 ; - - typename - edge_maps::_write_it _same ; - if (this-> - _map2.find(_ipos , _same)) - { - /*---- existing d-face found: append to existing data */ - if (_itop == -1) - { - /*----- if it's a "top"-level face, copy data */ - this->_set2[*_same] = - this->_set2[ _ipos] ; - } - else - { - /*----- otherwise, append index to adj. lists */ - this-> - _adj2.push(_itop,*_same) ; - } - - _put_edge(_ipos) ; - } - else - { - /*---- d-face is new: push and descend to (d-1)-faces */ - if (_itop == -1) - { - /*----- if it's a "top"-level face, keep data */ - init_list( - this->_adj2, _ipos) ; - } - else - { - /*----- otherwise, append index to adj. lists */ - this-> - _adj2.push(_itop, _ipos) ; - } - - /*-------------- descend into (d-1)-face data */ - for (_npos = 2; _npos-- != 0; ) - { - node_type _ndat; - _ndat.node(0) = - _edat.node(_npos) ; - - push_node( - _ndat, _link, _ipos) ; - } - - /*-------------- push new face data onto hash */ - this->_map2.push(_ipos) ; - } - - } - - return _ipos ; + return mesh::push_edge( + *this, _edat, _link, _itop, _kind) ; } /* @@ -943,587 +645,136 @@ -------------------------------------------------------- */ - __normal_call iptr_type push_tri3 ( + __inline_call iptr_type push_tri3 ( tri3_type const& _tdat, bool_type _link = true, - iptr_type _itop = -1 + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag ) { - iptr_type _ipos = _get_tri3() ; - iptr_type _epos ; - - if (!_link) - { - - __assert( _itop == -1 && - "tria-complex: non-top cell!" ) ; - - /*-------------------- init. external d-face data */ - this->_set3[_ipos] = _tdat ; - this->_set3[_ipos].mark() = 0 ; - this->_set3[_ipos].self() = 1 ; - - /*-------------------- init. local adj. index set */ - init_list(this->_adj3, _ipos) ; - - } - else - { - - /*------------------------ init. external d-face data */ - this->_set3[_ipos] = _tdat ; - this->_set3[_ipos].mark() = 0 ; - - if (_itop == -1) - this->_set3[_ipos].self() = 1 ; - else - this->_set3[_ipos].self() = 0 ; - - typename - tri3_maps::_write_it _same ; - if (this-> - _map3.find(_ipos , _same)) - { - /*---- existing d-face found: append to existing data */ - if (_itop == -1) - { - /*----- if it's a "top"-level face, copy data */ - this->_set3[*_same] = - this->_set3[ _ipos] ; - } - else - { - /*----- otherwise, append index to adj. lists */ - this-> - _adj3.push(_itop,*_same) ; - } - - _put_tri3(_ipos) ; - } - else - { - /*---- d-face is new: push and descend to (d-1)-faces */ - if (_itop == -1) - { - /*----- if it's a "top"-level face, keep data */ - init_list( - this->_adj3, _ipos) ; - } - else - { - /*----- otherwise, append index to adj. lists */ - this-> - _adj3.push(_itop, _ipos) ; - } - - /*-------------- descend into (d-1)-face data */ - for (_epos = +3; _epos-- != 0 ; ) - { - iptr_type _enod [3]; - tri3_type::face_node( - _enod, _epos, 2, 1) ; - - edge_type _edat ; - _edat.node(0) = - _tdat.node(_enod[0]) ; - _edat.node(1) = - _tdat.node(_enod[1]) ; - - push_edge( - _edat, _link, _ipos) ; - } - - /*-------------- push new face data onto hash */ - this->_map3.push(_ipos) ; - } - - } - - return _ipos ; + return mesh::push_tri3( + *this, _tdat, _link, _itop, _kind) ; } /* -------------------------------------------------------- - * PUSH-TRIA: append new 3-tria to complex. + * PUSH-QUAD: append new 2-quad to complex. -------------------------------------------------------- */ - __normal_call iptr_type push_tri4 ( - tri4_type const& _tdat, + __inline_call iptr_type push_quad ( + quad_type const& _qdat, bool_type _link = true, - iptr_type _itop = -1 + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag ) { - iptr_type _ipos = _get_tri4() ; - iptr_type _fpos ; - - if (!_link) - { - - __assert( _itop == -1 && - "tria-complex: non-top cell!" ) ; - - /*------------------------ init. external d-face data */ - this->_set4[_ipos] = _tdat ; - this->_set4[_ipos].mark() = 0 ; - this->_set4[_ipos].self() = 1 ; - - /*------------------------ init. local adj. index set */ - init_list(this->_adj4, _ipos) ; - - } - else - { - - /*------------------------ init. external d-face data */ - this->_set4[_ipos] = _tdat ; - this->_set4[_ipos].mark() = 0 ; - - if (_itop == -1) - this->_set4[_ipos].self() = 1 ; - else - this->_set4[_ipos].self() = 0 ; - - typename - tri4_maps::_write_it _same ; - if (this-> - _map4.find(_ipos , _same)) - { - /*---- existing d-face found: append to existing data */ - if (_itop == -1) - { - /*----- if it's a "top"-level face, copy data */ - this->_set4[*_same] = - this->_set4[ _ipos] ; - } - else - { - /*----- otherwise, append index to adj. lists */ - this-> - _adj4.push(_itop,*_same) ; - } - - _put_tri4(_ipos) ; - } - else - { - /*---- d-face is new: push and descend to (d-1)-faces */ - if (_itop == -1) - { - /*----- if it's a "top"-level face, keep data */ - init_list( - this->_adj4, _ipos) ; - } - else - { - /*----- otherwise, append index to adj. lists */ - this-> - _adj4.push(_itop, _ipos) ; - } - - /*-------------- descend into (d-1)-face data */ - for (_fpos = +4; _fpos-- != 0 ; ) - { - iptr_type _fnod [4]; - tri4_type::face_node( - _fnod, _fpos, 3, 2) ; - - tri3_type _fdat ; - _fdat.node(0) = - _tdat.node(_fnod[0]) ; - _fdat.node(1) = - _tdat.node(_fnod[1]) ; - _fdat.node(2) = - _tdat.node(_fnod[2]) ; - - push_tri3( - _fdat, _link, _ipos) ; - } - - /*-------------- push new face data onto hash */ - this->_map4.push(_ipos) ; - } - - } - - return _ipos ; + return mesh::push_quad( + *this, _qdat, _link, _itop, _kind) ; } /* -------------------------------------------------------- - * MAKE-LINK: build item-to-item adj. + * PUSH-TRIA: append new 3-tria to complex. -------------------------------------------------------- */ - __normal_call void_type make_link ( + __normal_call iptr_type push_tri4 ( + tri4_type const& _tdat, + bool_type _link = true, + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag ) { - this->_map2.set_slots( - (this->_set2.count()*5)/4 + 1 - + (this->_set3.count()*5)/2 + 1 - + (this->_set4.count()*3)/2 + 1 - ) ; - - this->_map3.set_slots( - (this->_set3.count()*5)/4 + 1 - + (this->_set4.count()*5)/2 + 1 - ) ; - - this->_map4.set_slots( - (this->_set4.count()*5)/4 + 1 - ) ; - - this->_adj1.empty () ; - this->_adj2.empty () ; - this->_adj3.empty () ; - this->_adj4.empty () ; - - iptr_type _epos = +0 ; - for (auto _iter = this->_set2.head(); - _iter != this->_set2.tend(); - ++_iter, ++_epos ) - { - /*-------------- push face data onto hash set */ - this->_map2.push(_epos) ; - - /*-------------- descend into (d-1)-face data */ - iptr_type _ipos; - for (_ipos = +2; _ipos-- != 0; ) - { - node_type _ndat; - _ndat.node(0) = - _iter->node( _ipos) ; - - push_node( - _ndat, true, _epos) ; - } - } - - iptr_type _fpos = +0 ; - for (auto _iter = this->_set3.head(); - _iter != this->_set3.tend(); - ++_iter, ++_fpos ) - { - /*-------------- push face data onto hash set */ - this->_map3.push(_fpos) ; - - /*-------------- descend into (d-1)-face data */ - iptr_type _ipos; - for (_ipos = +3; _ipos-- != 0; ) - { - iptr_type _enod [3]; - tri3_type::face_node( - _enod, _ipos, 2, 1 ) ; - - edge_type _edat ; - _edat.node(0) = - _iter->node(_enod[0]) ; - _edat.node(1) = - _iter->node(_enod[1]) ; - - push_edge( - _edat, true , _fpos) ; - } - } - - iptr_type _tpos = +0 ; - for (auto _iter = this->_set4.head(); - _iter != this->_set4.tend(); - ++_iter, ++_tpos ) - { - /*-------------- push face data onto hash set */ - this->_map4.push(_tpos) ; - - /*-------------- descend into (d-1)-face data */ - iptr_type _ipos; - for (_ipos = +4; _ipos-- != 0; ) - { - iptr_type _fnod [4]; - tri4_type::face_node( - _fnod, _ipos, 3, 2 ) ; - - tri3_type _fdat ; - _fdat.node(0) = - _iter->node(_fnod[0]) ; - _fdat.node(1) = - _iter->node(_fnod[1]) ; - _fdat.node(2) = - _iter->node(_fnod[2]) ; - - push_tri3( - _fdat, true , _tpos) ; - } - } - } - - /* - -------------------------------------------------------- - * NULL-ITEM: TRUE if item is delete-able. - -------------------------------------------------------- - */ - - __inline_call bool_type null_node ( - iptr_type _npos - ) const - { - return this->_set1[_npos].self()==0 - && this->_adj1.empty(_npos); - } - - __inline_call bool_type null_edge ( - iptr_type _epos - ) const - { - return this->_set2[_epos].self()==0 - && this->_adj2.empty(_epos); - } - - __inline_call bool_type null_tri3 ( - iptr_type _tpos - ) const - { - return this->_set3[_tpos].self()==0 - && this->_adj3.empty(_tpos); - } - - __inline_call bool_type null_tri4 ( - iptr_type _tpos - ) const - { - return this->_set4[_tpos].self()==0 - && this->_adj4.empty(_tpos); + return mesh::push_tri4( + *this, _tdat, _link, _itop, _kind) ; } /* -------------------------------------------------------- - * _POP-LIST: delete item from adj. list. + * _POP-NODE: delete 0-node from complex. -------------------------------------------------------- */ - __normal_call void_type _pop_list ( - conn_list &_list, - iptr_type _lpos, - iptr_type _itop + __inline_call void_type _pop_node ( + iptr_type const*_nptr, + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag ) { - /*--------------------------- scan list and pop match */ - typename conn_list::_write_it - _prev = _list.hend(_lpos), - _iter = _list.head(_lpos), - _tend = _list.tend(_lpos); - - for ( ; _iter != _tend; - _prev = _iter, ++_iter) - { - if(*_iter == _itop) - { - _list._pop ( - _prev, _iter, _lpos) ; - - break ; - } - } + mesh::_pop_node(*this, _nptr, _itop, _kind) ; } /* -------------------------------------------------------- - * _POP-NODE: delete 0-node from complex. + * _POP-EDGE: delete 1-edge from complex. -------------------------------------------------------- */ - __normal_call void_type _pop_node ( + __inline_call void_type _pop_edge ( iptr_type const*_nptr, - iptr_type _itop = -1 + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag ) { - iptr_type _npos = -1 ; - - iptr_type _node[1]; - _node[0] = _nptr[0]; - - /*-------------------------- find current 0-node pos. */ - if ( !find_node (_node, _npos)) - { - return ; - } - - /*-------------------------- _pop current 0-node data */ - _pop_node(_npos, _itop) ; + mesh::_pop_edge(*this, _nptr, _itop, _kind) ; } - __normal_call void_type _pop_node ( - iptr_type _npos , - iptr_type _itop + __inline_call void_type _pop_edge ( + iptr_type _epos , + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag ) { - if (_itop != -1) - { - /*---- deleteing (d+k)-face: scan adj. and _pop _itop */ - _pop_list( - this->_adj1, _npos, _itop); - } - else - { - /*---- deleting (d+0)-face: set "self" marker to null */ - this-> - _set1[_npos].self() = 0 ; - } - - if (null_node (_npos)) - { - /*---- ref. count: delete (d+0), (d-1)-faces if empty */ - _put_node (_npos); - } + mesh::_pop_edge(*this, _epos, _itop, _kind) ; } /* -------------------------------------------------------- - * _POP-EDGE: delete 1-edge from complex. + * _POP-TRIA: delete 2-tria from complex. -------------------------------------------------------- */ - __normal_call void_type _pop_edge ( + __inline_call void_type _pop_tri3 ( iptr_type const*_nptr, - iptr_type _itop = -1 + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag ) { - iptr_type _epos = -1 ; - - iptr_type _node[2]; - _node[0] = _nptr[0]; - _node[1] = _nptr[1]; - - /*-------------------------- find current 1-edge pos. */ - if ( !find_edge (_node, _epos)) - { - return ; - } - - /*-------------------------- _pop current 1-edge data */ - _pop_edge(_epos, _itop) ; + mesh::_pop_tri3(*this, _nptr, _itop, _kind) ; } - __normal_call void_type _pop_edge ( - iptr_type _epos , - iptr_type _itop = -1 + __inline_call void_type _pop_tri3 ( + iptr_type _tpos , + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag ) { - iptr_type _npos = -1 ; - - if (_itop != -1) - { - /*---- deleteing (d+k)-face: scan adj. and _pop _itop */ - _pop_list( - this->_adj2, _epos, _itop); - } - else - { - /*---- deleting (d+0)-face: set "self" marker to null */ - this-> - _set2[_epos].self() = 0 ; - } - - if (null_edge (_epos)) - { - /*---- ref. count: delete (d+0), (d-1)-faces if empty */ - iptr_type _same ; - this->_map2._pop(_epos, _same); - - iptr_type _node [ 2] ; - _node[0] = this-> - _set2[_epos].node(0) ; - _node[1] = this-> - _set2[_epos].node(1) ; - - _put_edge(_epos); - - for (_npos = 2; _npos-- != 0; ) - { - _pop_node( - &_node[_npos], _epos); - } - } + mesh::_pop_tri3(*this, _tpos, _itop, _kind) ; } /* -------------------------------------------------------- - * _POP-TRIA: delete 2-tria from complex. + * _POP-QUAD: delete 2-quad from complex. -------------------------------------------------------- */ - __normal_call void_type _pop_tri3 ( + __inline_call void_type _pop_quad ( iptr_type const*_nptr, - iptr_type _itop = -1 + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag ) { - iptr_type _tpos = -1 ; - - iptr_type _node[3]; - _node[0] = _nptr[0]; - _node[1] = _nptr[1]; - _node[2] = _nptr[2]; - - /*-------------------------- find current 2-tria pos. */ - if ( !find_tri3 (_node, _tpos)) - { - return ; - } - - /*-------------------------- _pop current 2-tria data */ - _pop_tri3(_tpos, _itop) ; + mesh::_pop_quad(*this, _nptr, _itop, _kind) ; } - __normal_call void_type _pop_tri3 ( - iptr_type _tpos , - iptr_type _itop = -1 + __inline_call void_type _pop_quad ( + iptr_type _qpos , + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag ) { - iptr_type _epos = -1 ; - - if (_itop != -1) - { - /*---- deleteing (d+k)-face: scan adj. and _pop _itop */ - _pop_list( - this->_adj3, _tpos, _itop); - } - else - { - /*---- deleting (d+0)-face: set "self" marker to null */ - this-> - _set3[_tpos].self() = 0 ; - } - - if (null_tri3 (_tpos)) - { - /*---- ref. count: delete (d+0), (d-1)-faces if empty */ - - iptr_type _same ; - this->_map3._pop(_tpos, _same); - - iptr_type _node [ 3] ; - _node[0] = this-> - _set3[_tpos].node(0) ; - _node[1] = this-> - _set3[_tpos].node(1) ; - _node[2] = this-> - _set3[_tpos].node(2) ; - - _put_tri3(_tpos); - - for (_epos = 3; _epos-- != 0; ) - { - iptr_type _enod [3] ; - tri3_type::face_node ( - _enod, _epos, 2, 1) ; - - _enod[0] = - _node[_enod [0]]; - _enod[1] = - _node[_enod [1]]; - - _pop_edge(_enod, _tpos) ; - } - } + mesh::_pop_quad(*this, _qpos, _itop, _kind) ; } /* @@ -1532,84 +783,22 @@ -------------------------------------------------------- */ - __normal_call void_type _pop_tri4 ( + __inline_call void_type _pop_tri4 ( iptr_type const*_nptr, - iptr_type _itop = -1 + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag ) { - iptr_type _tpos = -1 ; - - iptr_type _node[4]; - _node[0] = _nptr[0]; - _node[1] = _nptr[1]; - _node[2] = _nptr[2]; - _node[3] = _nptr[3]; - - /*-------------------------- find current 3-tria pos. */ - if ( !find_tri4 (_node, _tpos)) - { - return ; - } - - /*-------------------------- _pop current 3-tria data */ - _pop_tri4(_tpos, _itop) ; + mesh::_pop_tri4(*this, _nptr, _itop, _kind) ; } - __normal_call void_type _pop_tri4 ( + __inline_call void_type _pop_tri4 ( iptr_type _tpos , - iptr_type _itop = -1 + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag ) { - iptr_type _fpos = -1 ; - - if (_itop != -1) - { - /*---- deleteing (d+k)-face: scan adj. and _pop _itop */ - _pop_list( - this->_adj4, _tpos, _itop); - } - else - { - /*---- deleting (d+0)-face: set "self" marker to null */ - this-> - _set4[_tpos].self() = 0 ; - } - - if (null_tri4 (_tpos)) - { - /*---- ref. count: delete (d+0), (d-1)-faces if empty */ - - iptr_type _same ; - this->_map4._pop(_tpos, _same); - - iptr_type _node [ 4] ; - _node[0] = this-> - _set4[_tpos].node(0) ; - _node[1] = this-> - _set4[_tpos].node(1) ; - _node[2] = this-> - _set4[_tpos].node(2) ; - _node[3] = this-> - _set4[_tpos].node(3) ; - - _put_tri4(_tpos); - - for (_fpos = 4; _fpos-- != 0; ) - { - iptr_type _fnod [4] ; - tri4_type::face_node ( - _fnod, _fpos, 3, 2) ; - - _fnod[0] = - _node[_fnod [0]]; - _fnod[1] = - _node[_fnod [1]]; - _fnod[2] = - _node[_fnod [2]]; - - _pop_tri3(_fnod, _tpos) ; - } - } + mesh::_pop_tri4(*this, _tpos, _itop, _kind) ; } /* @@ -1618,28 +807,12 @@ -------------------------------------------------------- */ - __normal_call bool_type find_node ( + __inline_call bool_type find_node ( iptr_type const*_nptr , iptr_type&_npos ) const { - /*-------------------------- find current 0-node pos. */ - iptr_type _node = *_nptr ; - - if (_node >= +0 && _node < - (iptr_type)this->_set1.count() && - _set1 [_node].mark() >= +0) - { - /*------------------------------- found matching node */ - _npos =_node ; - - return true ; - } - else - { - /*------------------------------- couldn't find match */ - return false ; - } + return mesh::find_node(*this, _nptr, _npos) ; } /* @@ -1648,38 +821,12 @@ -------------------------------------------------------- */ - __normal_call bool_type find_edge ( + __inline_call bool_type find_edge ( iptr_type const*_node , iptr_type&_epos ) { - /*-------------------------- find current 1-edge pos. */ - iptr_type _ipos = _get_edge() ; - - this-> - _set2[_ipos].node(0)=_node[0]; - this-> - _set2[_ipos].node(1)=_node[1]; - - typename edge_maps::_write_it - _same ; - if (this-> - _map2.find(_ipos, _same)) - { - /*------------------------------- found matching face */ - _put_edge(_ipos) ; - - _epos=*_same ; - - return true ; - } - else - { - /*------------------------------- couldn't find match */ - _put_edge(_ipos) ; - - return false ; - } + return mesh::find_edge(*this, _node, _epos) ; } /* @@ -1688,661 +835,134 @@ -------------------------------------------------------- */ - __normal_call bool_type find_tri3 ( - iptr_type const*_node , - iptr_type&_tpos - ) - { - /*-------------------------- find current 2-tria pos. */ - iptr_type _ipos = _get_tri3() ; - - this-> - _set3[_ipos].node(0)=_node[0]; - this-> - _set3[_ipos].node(1)=_node[1]; - this-> - _set3[_ipos].node(2)=_node[2]; - - typename tri3_maps::_write_it - _same ; - if (this-> - _map3.find(_ipos, _same)) - { - /*------------------------------- found matching face */ - _put_tri3(_ipos) ; - - _tpos=*_same ; - - return true ; - } - else - { - /*------------------------------- couldn't find match */ - _put_tri3(_ipos) ; - - return false ; - } - } - - /* - -------------------------------------------------------- - * FIND-TRIA: return index of assoc. 3-tria. - -------------------------------------------------------- - */ - - __normal_call bool_type find_tri4 ( + __inline_call bool_type find_tri3 ( iptr_type const*_node , iptr_type&_tpos ) { - /*-------------------------- find current 2-tria pos. */ - iptr_type _ipos = _get_tri4() ; - - this-> - _set4[_ipos].node(0)=_node[0]; - this-> - _set4[_ipos].node(1)=_node[1]; - this-> - _set4[_ipos].node(2)=_node[2]; - this-> - _set4[_ipos].node(3)=_node[3]; - - typename tri4_maps::_write_it - _same ; - if (this-> - _map4.find(_ipos, _same)) - { - /*------------------------------- found matching face */ - _put_tri4(_ipos) ; - - _tpos=*_same ; - - return true ; - } - else - { - /*------------------------------- couldn't find match */ - _put_tri4(_ipos) ; - - return false ; - } + return mesh::find_tri3(*this, _node, _tpos) ; } - /* -------------------------------------------------------- - * NODE-EDGE: form node-to-edge adj. list. + * FIND-QUAD: return index of assoc. 2-quad. -------------------------------------------------------- */ - template < - typename list_type - > - __inline_call void_type node_edge ( + __inline_call bool_type find_quad ( iptr_type const*_node , - list_type&_conn + iptr_type&_qpos ) { - node_edge(_node [ 0], _conn) ; - } - - template < - typename list_type - > - __normal_call void_type node_edge ( - iptr_type _npos, - list_type&_conn - ) - { - this->_tmp1.set_count( +0 ) ; - this->_tmp2.set_count( +0 ) ; - this->_tmp3.set_count( +0 ) ; - this->_tmp4.set_count( +0 ) ; - - this->_tmp1.push_tail(_npos) ; - - /*-------------------------- find set of adj. 1-edges */ - for (auto _iter = this->_tmp1.head(); - _iter != this->_tmp1.tend(); - ++_iter ) - { - for (auto _iadj = - this->_adj1.head(*_iter) ; - _iadj != - this->_adj1.tend(*_iter) ; - ++_iadj ) - { - if (this-> - _set2[*_iadj].mark() == 0) - { - _conn.push_tail (*_iadj); - this-> - _set2[*_iadj].mark() += 1; - } - } - } - - /*-------------------------- flip d-face marker lists */ - for (auto _iter = _conn.head() ; - _iter != _conn.tend() ; - ++_iter ) - { - this->_set2 [*_iter].mark() = +0; - } + return mesh::find_quad(*this, _node, _qpos) ; } /* -------------------------------------------------------- - * NODE-TRI3: form node-to-tria adj. list. + * FIND-TRIA: return index of assoc. 3-tria. -------------------------------------------------------- */ - template < - typename list_type - > - __inline_call void_type node_tri3 ( + __inline_call bool_type find_tri4 ( iptr_type const*_node , - list_type&_conn - ) - { - node_tri3(_node [ 0], _conn) ; - } - - template < - typename list_type - > - __normal_call void_type node_tri3 ( - iptr_type _npos, - list_type&_conn + iptr_type&_tpos ) { - this->_tmp1.set_count( +0 ) ; - this->_tmp2.set_count( +0 ) ; - this->_tmp3.set_count( +0 ) ; - this->_tmp4.set_count( +0 ) ; - - this->_tmp1.push_tail(_npos) ; - - /*-------------------------- find set of adj. 1-edges */ - for (auto _iter = this->_tmp1.head(); - _iter != this->_tmp1.tend(); - ++_iter ) - { - for (auto _iadj = - this->_adj1.head(*_iter) ; - _iadj != - this->_adj1.tend(*_iter) ; - ++_iadj ) - { - if (this-> - _set2[*_iadj].mark() == 0) - { - this-> - _tmp2.push_tail (*_iadj); - this-> - _set2[*_iadj].mark() += 1; - } - } - } - /*-------------------------- find set of adj. 2-trias */ - for (auto _iter = this->_tmp2.head(); - _iter != this->_tmp2.tend(); - ++_iter ) - { - for (auto _iadj = - this->_adj2.head(*_iter) ; - _iadj != - this->_adj2.tend(*_iter) ; - ++_iadj ) - { - if (this-> - _set3[*_iadj].mark() == 0) - { - _conn.push_tail (*_iadj); - this-> - _set3[*_iadj].mark() += 1; - } - } - } - - /*-------------------------- flip d-face marker lists */ - for (auto _iter = _conn.head() ; - _iter != _conn.tend() ; - ++_iter ) - { - this->_set3 [*_iter].mark() = 0 ; - } - for (auto _iter = this-> - _tmp2.head() ; - _iter != this-> - _tmp2.tend() ; - ++_iter ) - { - this->_set2 [*_iter].mark() = 0 ; - } + return mesh::find_tri4(*this, _node, _tpos) ; } /* -------------------------------------------------------- - * NODE-TRI4: form node-to-tria adj. list. + * FIND-CELL: return index of assoc. k-cell. -------------------------------------------------------- */ - template < - typename list_type - > - __inline_call void_type node_tri4 ( + __inline_call bool_type find_cell ( iptr_type const*_node , - list_type&_conn - ) - { - node_tri4(_node [ 0], _conn) ; - } - - template < - typename list_type - > - __normal_call void_type node_tri4 ( - iptr_type _npos, - list_type&_conn + char_type _kind , + iptr_type&_ipos ) { - this->_tmp1.set_count( +0 ) ; - this->_tmp2.set_count( +0 ) ; - this->_tmp3.set_count( +0 ) ; - this->_tmp4.set_count( +0 ) ; - - this->_tmp1.push_tail(_npos) ; - - /*-------------------------- find set of adj. 1-edges */ - for (auto _iter = this->_tmp1.head(); - _iter != this->_tmp1.tend(); - ++_iter ) - { - for (auto _iadj = - this->_adj1.head(*_iter) ; - _iadj != - this->_adj1.tend(*_iter) ; - ++_iadj ) - { - if (this-> - _set2[*_iadj].mark() == 0) - { - this-> - _tmp2.push_tail (*_iadj); - this-> - _set2[*_iadj].mark() += 1; - } - } - } - /*-------------------------- find set of adj. 2-trias */ - for (auto _iter = this->_tmp2.head(); - _iter != this->_tmp2.tend(); - ++_iter ) - { - for (auto _iadj = - this->_adj2.head(*_iter) ; - _iadj != - this->_adj2.tend(*_iter) ; - ++_iadj ) - { - if (this-> - _set3[*_iadj].mark() == 0) - { - this-> - _tmp3.push_tail (*_iadj); - this-> - _set3[*_iadj].mark() += 1; - } - } - } - /*-------------------------- find set of adj. 3-trias */ - for (auto _iter = this->_tmp3.head(); - _iter != this->_tmp3.tend(); - ++_iter ) - { - for (auto _iadj = - this->_adj3.head(*_iter) ; - _iadj != - this->_adj3.tend(*_iter) ; - ++_iadj ) - { - if (this-> - _set4[*_iadj].mark() == 0) - { - _conn.push_tail (*_iadj); - this-> - _set4[*_iadj].mark() += 1; - } - } - } - - /*-------------------------- flip d-face marker lists */ - for (auto _iter = _conn.head() ; - _iter != _conn.tend() ; - ++_iter ) - { - this->_set4 [*_iter].mark() = 0 ; - } - for (auto _iter = this-> - _tmp3.head() ; - _iter != this-> - _tmp3.tend() ; - ++_iter ) - { - this->_set3 [*_iter].mark() = 0 ; - } - for (auto _iter = this-> - _tmp2.head() ; - _iter != this-> - _tmp2.tend() ; - ++_iter ) - { - this->_set2 [*_iter].mark() = 0 ; - } + return mesh::find_cell( + *this, _node, _kind, _ipos, mesh_cell()) ; } /* -------------------------------------------------------- - * EDGE-TRI3: form edge-to-tria adj. list. + * CONNECT-1: form this-to-1-cell adj. list. -------------------------------------------------------- */ - template < - typename list_type - > - __inline_call void_type edge_tri3 ( + __inline_call void_type connect_1 ( iptr_type const*_node , - list_type&_conn + char_type _kind , + connector&_conn ) { - /*-------------------------- find current 1-edge pos. */ - iptr_type _epos = -1; - if (!find_edge(_node, _epos)) - { - return ; - } - - /*-------------------------- get adj. for 1-edge pos. */ - edge_tri3(_epos, _conn) ; + mesh::connect_1( + *this, _node, _kind, _conn, mesh_cell()) ; } - template < - typename list_type - > - __normal_call void_type edge_tri3 ( - iptr_type _epos, - list_type&_conn + __inline_call void_type connect_1 ( + iptr_type _ipos , + char_type _kind , + connector&_conn ) { - this->_tmp1.set_count( +0 ) ; - this->_tmp2.set_count( +0 ) ; - this->_tmp3.set_count( +0 ) ; - this->_tmp4.set_count( +0 ) ; - - this->_tmp2.push_tail(_epos) ; - - /*-------------------------- find set of adj. 2-faces */ - for (auto _iter = this->_tmp2.head(); - _iter != this->_tmp2.tend(); - ++_iter ) - { - for (auto _iadj = - this->_adj2.head(*_iter) ; - _iadj != - this->_adj2.tend(*_iter) ; - ++_iadj ) - { - if (this-> - _set3[*_iadj].mark() == 0) - { - _conn.push_tail (*_iadj); - this-> - _set3[*_iadj].mark() += 1; - } - } - } - - /*-------------------------- flip d-face marker lists */ - for (auto _iter = _conn.head() ; - _iter != _conn.tend() ; - ++_iter ) - { - this->_set3 [*_iter].mark() = 0 ; - } + mesh::connect_1( + *this, _ipos, _kind, _conn, mesh_cell()) ; } /* -------------------------------------------------------- - * EDGE-3CEL: form edge-to-cell adj. list. + * CONNECT-2: form this-to-2-cell adj. list. -------------------------------------------------------- */ - __inline_call void_type edge_cell ( + __inline_call void_type connect_2 ( iptr_type const*_node , char_type _kind , connector&_conn ) { - /*-------------------------- find current 1-edge pos. */ - iptr_type _epos = -1; - if (!find_edge(_node, _epos)) - { - return ; - } - - /*-------------------------- get adj. for 1-edge pos. */ - edge_cell(_epos, _kind, _conn) ; + mesh::connect_2( + *this, _node, _kind, _conn, mesh_cell()) ; } - __normal_call void_type edge_cell ( - iptr_type _epos, - char_type _kind, + __inline_call void_type connect_2 ( + iptr_type _ipos , + char_type _kind , connector&_conn ) { - this->_ttN1.set_count( +0 ) ; - this->_ttE2.set_count( +0 ) ; - this->_ttT3.set_count( +0 ) ; - this->_ttQ4.set_count( +0 ) ; - this->_ttT4.set_count( +0 ) ; - this->_ttH8.set_count( +0 ) ; - this->_ttP5.set_count( +0 ) ; - this->_ttW6.set_count( +0 ) ; - - this->_ttE2.push_tail(_epos) ; - - /*-------------------------- find set of adj. 2-faces */ - for (auto _iter = this->_ttE2.head(); - _iter != this->_ttE2.tend(); - ++_iter ) - { - for (auto _iadj = // tria-3 - this->_E2T3.head(*_iter) ; - _iadj != - this->_E2T3.tend(*_iter) ; - ++_iadj ) - { - if (this-> - _llT3[*_iadj].mark() == 0) - { - this-> - _ttT3.push_tail (*_iadj); - this-> - _llT3[*_iadj].mark() += 1; - } - } - for (auto _iadj = // quad-4 - this->_E2Q4.head(*_iter) ; - _iadj != - this->_E2Q4.tend(*_iter) ; - ++_iadj ) - { - if (this-> - _llQ4[*_iadj].mark() == 0) - { - this-> - _ttQ4.push_tail (*_iadj); - this-> - _llQ4[*_iadj].mark() += 1; - } - } - } - /*-------------------------- find set of adj. 3-faces */ - for (auto _iter = this->_ttT3.head(); - _iter != this->_ttT3.tend(); - ++_iter ) - { - for (auto _iadj = // tria-4 - this->_T3T4.head(*_iter) ; - _iadj != - this->_T3T4.tend(*_iter) ; - ++_iadj ) - { - if (this-> - _llT4[*_iadj].mark() == 0) - { - _conn.push_tail(conn_data( - *_iadj, tri4_flag)); - this-> - _llT4[*_iadj].mark() += 1; - } - } - for (auto _iadj = // pyra-5 - this->_T3P5.head(*_iter) ; - _iadj != - this->_T3P5.tend(*_iter) ; - ++_iadj ) - { - if (this-> - _llP5[*_iadj].mark() == 0) - { - _conn.push_tail(conn_data( - *_iadj, pyra_flag)); - this-> - _llP5[*_iadj].mark() += 1; - } - } - for (auto _iadj = // wedg-6 - this->_T3W6.head(*_iter) ; - _iadj != - this->_T3W6.tend(*_iter) ; - ++_iadj ) - { - if (this-> - _llW6[*_iadj].mark() == 0) - { - _conn.push_tail(conn_data( - *_iadj, wedg_flag)); - this-> - _llW6[*_iadj].mark() += 1; - } - } - } - - /*-------------------------- flip d-face marker lists */ - for (auto _iter = _conn.head() ; - _iter != _conn.tend() ; - ++_iter ) - { - if (_iter->_flag == tri4_flag) - _llT4[_iter->_ipos].mark() = 0 ; - else - if (_iter->_flag == hexa_flag) - _llH8[_iter->_ipos].mark() = 0 ; - else - if (_iter->_flag == pyra_flag) - _llP5[_iter->_ipos].mark() = 0 ; - else - if (_iter->_flag == wedg_flag) - _llW6[_iter->_ipos].mark() = 0 ; - } - for (auto _iter = this-> - _ttT3.head() ; - _iter != this-> - _ttT3.tend() ; - ++_iter ) - { - this->_llT3 [*_iter].mark() = 0 ; - } - for (auto _iter = this-> - _ttQ4.head() ; - _iter != this-> - _ttQ4.tend() ; - ++_iter ) - { - this->_llQ4 [*_iter].mark() = 0 ; - } + mesh::connect_2( + *this, _ipos, _kind, _conn, mesh_cell()) ; } /* -------------------------------------------------------- - * TRI3-TRI4: form tria-to-tria adj. list. + * CONNECT-3: form this-to-3-cell adj. list. -------------------------------------------------------- */ - template < - typename list_type - > - __inline_call void_type tri3_tri4 ( + __inline_call void_type connect_3 ( iptr_type const*_node , - list_type&_conn + char_type _kind , + connector&_conn ) { - /*-------------------------- find current 1-edge pos. */ - iptr_type _tpos = -1; - if (!find_tri3(_node, _tpos)) - { - return ; - } - - /*-------------------------- get adj. for 1-edge pos. */ - tri3_tri4(_tpos, _conn) ; + mesh::connect_3( + *this, _node, _kind, _conn, mesh_cell()) ; } - template < - typename list_type - > - __normal_call void_type tri3_tri4 ( - iptr_type _epos, - list_type&_conn + __inline_call void_type connect_3 ( + iptr_type _ipos , + char_type _kind , + connector&_conn ) { - this->_tmp1.set_count( +0 ) ; - this->_tmp2.set_count( +0 ) ; - this->_tmp3.set_count( +0 ) ; - this->_tmp4.set_count( +0 ) ; - - this->_tmp3.push_tail(_epos) ; - - /*-------------------------- find set of adj. 2-faces */ - for (auto _iter = this->_tmp3.head(); - _iter != this->_tmp3.tend(); - ++_iter ) - { - for (auto _iadj = - this->_adj3.head(*_iter) ; - _iadj != - this->_adj3.tend(*_iter) ; - ++_iadj ) - { - if (this-> - _set4[*_iadj].mark() == 0) - { - _conn.push_tail (*_iadj); - this-> - _set4[*_iadj].mark() += 1; - } - } - } - - /*-------------------------- flip d-face marker lists */ - for (auto _iter = _conn.head() ; - _iter != _conn.tend() ; - ++_iter ) - { - this->_set4 [*_iter].mark() = 0 ; - } + mesh::connect_3( + *this, _ipos, _kind, _conn, mesh_cell()) ; } } ; @@ -2350,7 +970,7 @@ } -# endif // __MESH_COMPLEX_3__ +# endif //__MESH_COMPLEX_3__ diff --git a/src/libcpp/mesh_type/mesh_complex_type_k.hpp b/src/libcpp/mesh_type/mesh_complex_type_k.hpp index f76548b..7b7b196 100644 --- a/src/libcpp/mesh_type/mesh_complex_type_k.hpp +++ b/src/libcpp/mesh_type/mesh_complex_type_k.hpp @@ -31,11 +31,11 @@ * -------------------------------------------------------- * - * Last updated: 08 December, 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/ * -------------------------------------------------------- @@ -52,8 +52,8 @@ -------------------------------------------------------- * BASE-NODE-2: node-type for mesh complexes in R^2. -------------------------------------------------------- - * IPTR-TYPE - signed-integer typedef. - * REAL-TYPE - floating-point typedef. + * IPTR-TYPE -- signed-integer typedef. + * REAL-TYPE -- floating-point typedef. -------------------------------------------------------- */ @@ -129,8 +129,8 @@ -------------------------------------------------------- * BASE-NODE-3: node-type for mesh complexes in R^3. -------------------------------------------------------- - * IPTR-TYPE - signed-integer typedef. - * REAL-TYPE - floating-point typedef. + * IPTR-TYPE -- signed-integer typedef. + * REAL-TYPE -- floating-point typedef. -------------------------------------------------------- */ @@ -206,8 +206,8 @@ -------------------------------------------------------- * BASE-NODE-4: node-type for mesh complexes in R^4. -------------------------------------------------------- - * IPTR-TYPE - signed-integer typedef. - * REAL-TYPE - floating-point typedef. + * IPTR-TYPE -- signed-integer typedef. + * REAL-TYPE -- floating-point typedef. -------------------------------------------------------- */ @@ -281,9 +281,9 @@ /* -------------------------------------------------------- - * BASE-EDGE-2: 1-simplex type for MESH-COMPLEX-K. + * BASE-EDGE-2: edge-2 cell for MESH-COMPLEX-k. -------------------------------------------------------- - * IPTR-TYPE - signed-integer typedef. + * IPTR-TYPE -- signed-integer typedef. -------------------------------------------------------- */ @@ -292,7 +292,7 @@ > class mesh_complex_edge_2 { -/*---------------------------------------- base 1-simplex */ +/*---------------------------------------- EDGE-2 element */ public : typedef I iptr_type ; @@ -401,9 +401,9 @@ /* -------------------------------------------------------- - * BASE-TRIA-3: 2-simplex type for MESH-COMPLEX-K. + * BASE-TRIA-3: tria-3 cell for MESH-COMPLEX-k. -------------------------------------------------------- - * IPTR-TYPE - signed-integer typedef. + * IPTR-TYPE -- signed-integer typedef. -------------------------------------------------------- */ @@ -412,7 +412,7 @@ > class mesh_complex_tria_3 { -/*---------------------------------------- base 2-simplex */ +/*---------------------------------------- TRIA-3 element */ public : typedef I iptr_type ; @@ -591,9 +591,9 @@ /* -------------------------------------------------------- - * BASE-QUAD-4: quad-4 cell type for MESH-COMPLEX-K. + * BASE-QUAD-4: quad-4 cell for MESH-COMPLEX-k. -------------------------------------------------------- - * IPTR-TYPE - signed-integer typedef. + * IPTR-TYPE -- signed-integer typedef. -------------------------------------------------------- */ @@ -602,7 +602,7 @@ > class mesh_complex_quad_4 { -/*-------------------------------------- base quad-4 cell */ +/*---------------------------------------- QUAD-4 element */ public : typedef I iptr_type ; @@ -794,9 +794,9 @@ /* -------------------------------------------------------- - * BASE-TRIA-4: 3-simplex type for MESH-COMPLEX-K. + * BASE-TRIA-4: tria-4 cell for MESH-COMPLEX-k. -------------------------------------------------------- - * IPTR-TYPE - signed-integer typedef. + * IPTR-TYPE -- signed-integer typedef. -------------------------------------------------------- */ @@ -805,7 +805,7 @@ > class mesh_complex_tria_4 { -/*---------------------------------------- base 3-simplex */ +/*---------------------------------------- TRIA-4 element */ public : typedef I iptr_type ; @@ -1118,6 +1118,189 @@ } ; + /* + -------------------------------------------------------- + * BASE-HEXA-8: hexa-8 cell for MESH-COMPLEX-k. + -------------------------------------------------------- + * IPTR-TYPE -- signed-integer typedef. + -------------------------------------------------------- + */ + + template < + typename I + > + class mesh_complex_hexa_8 + { +/*---------------------------------------- HEXA-8 element */ + public : + + typedef I iptr_type ; + + iptr_type static constexpr _dims = +3 ; + + containers:: + fixed_array _ndat ; // node indexing + + char _mark ; + char _self ; + + public : +/*---------------------------------------- "write" access */ + __inline_call iptr_type & node ( + iptr_type _ipos + ) + { return this->_ndat [_ipos]; + } + + __inline_call char & mark ( + ) + { return this->_mark ; + } + __inline_call char & self ( + ) + { return this->_self ; + } + +/*---------------------------------------- "const" access */ + __inline_call iptr_type const& node ( + iptr_type _ipos + ) const + { return this->_ndat[_ipos]; + } + + __inline_call char const& mark ( + ) const + { return this->_mark ; + } + __inline_call char const& self ( + ) const + { return this->_self ; + } + + } ; + + /* + -------------------------------------------------------- + * BASE-WEDG-6: wedg-6 cell for MESH-COMPLEX-k. + -------------------------------------------------------- + * IPTR-TYPE -- signed-integer typedef. + -------------------------------------------------------- + */ + + template < + typename I + > + class mesh_complex_wedg_6 + { +/*---------------------------------------- WEDG-6 element */ + public : + + typedef I iptr_type ; + + iptr_type static constexpr _dims = +3 ; + + containers:: + fixed_array _ndat ; // node indexing + + char _mark ; + char _self ; + + public : +/*---------------------------------------- "write" access */ + __inline_call iptr_type & node ( + iptr_type _ipos + ) + { return this->_ndat [_ipos]; + } + + __inline_call char & mark ( + ) + { return this->_mark ; + } + __inline_call char & self ( + ) + { return this->_self ; + } + +/*---------------------------------------- "const" access */ + __inline_call iptr_type const& node ( + iptr_type _ipos + ) const + { return this->_ndat[_ipos]; + } + + __inline_call char const& mark ( + ) const + { return this->_mark ; + } + __inline_call char const& self ( + ) const + { return this->_self ; + } + + } ; + + /* + -------------------------------------------------------- + * BASE-PYRA-5: pyra-5 cell for MESH-COMPLEX-k. + -------------------------------------------------------- + * IPTR-TYPE -- signed-integer typedef. + -------------------------------------------------------- + */ + + template < + typename I + > + class mesh_complex_pyra_5 + { +/*---------------------------------------- PYRA-5 element */ + public : + + typedef I iptr_type ; + + iptr_type static constexpr _dims = +3 ; + + containers:: + fixed_array _ndat ; // node indexing + + char _mark ; + char _self ; + + public : +/*---------------------------------------- "write" access */ + __inline_call iptr_type & node ( + iptr_type _ipos + ) + { return this->_ndat [_ipos]; + } + + __inline_call char & mark ( + ) + { return this->_mark ; + } + __inline_call char & self ( + ) + { return this->_self ; + } + +/*---------------------------------------- "const" access */ + __inline_call iptr_type const& node ( + iptr_type _ipos + ) const + { return this->_ndat[_ipos]; + } + + __inline_call char const& mark ( + ) const + { return this->_mark ; + } + __inline_call char const& self ( + ) const + { return this->_self ; + } + + } ; + } diff --git a/src/libcpp/mesh_type/tria_complex_1.hpp b/src/libcpp/mesh_type/tria_complex_1.hpp index 98842a0..f2ad6b6 100644 --- a/src/libcpp/mesh_type/tria_complex_1.hpp +++ b/src/libcpp/mesh_type/tria_complex_1.hpp @@ -1,7 +1,7 @@ /* -------------------------------------------------------- - * TRIA-COMPLEX-1: piecewise tria. complex in R^1. + * TRIA-COMPLEX-1: piecewise tria. complex in T^1. -------------------------------------------------------- * * This program may be freely redistributed under the @@ -31,20 +31,20 @@ * -------------------------------------------------------- * - * Last updated: 30 June, 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/ * -------------------------------------------------------- */ - #pragma once +# pragma once - #ifndef __TRIA_COMPLEX_1__ - #define __TRIA_COMPLEX_1__ +# ifndef __TRIA_COMPLEX_1__ +# define __TRIA_COMPLEX_1__ namespace mesh { @@ -76,9 +76,9 @@ typedef typename edge_type::iptr_type iptr_type ; typedef typename - allocator::size_type size_type ; + allocator::size_type indx_type ; - iptr_type static constexpr _dims = +1 ; + indx_type static constexpr topo_dims = +1 ; typedef containers::block_array < node_type, @@ -92,132 +92,18 @@ iptr_type, allocator > iptr_list ; - #define __hashscal sizeof(iptr_type)/sizeof(uint32_t) - - class node_hash - { - public : - __const_ptr(node_list) _nset ; - public : - /*----------------------- build hash _obj. from _src. */ - __inline_call node_hash ( - node_list *_nsrc - ) : _nset( _nsrc) {} - /*----------------------- hash node indexing for node */ - __inline_call - uint32_t operator() ( - iptr_type _npos - ) const - { - return this->_nset-> - operator[](_npos).node( 0) ; - } - } ; - - class edge_hash - { - public : - __const_ptr(edge_list) _eset ; - public : - /*----------------------- build hash _obj. from _src. */ - __inline_call edge_hash ( - edge_list *_esrc - ) : _eset( _esrc) {} - /*----------------------- hash node indexing for edge */ - __inline_call - uint32_t operator() ( - iptr_type _epos - ) const - { - iptr_type _enod[2]; - _enod[0] = this->_eset-> - operator[](_epos).node( 0) ; - _enod[1] = this->_eset-> - operator[](_epos).node( 1) ; - - algorithms::isort ( - &_enod[0], &_enod[2] , - std::less()); - - return hash::hashword ( - (uint32_t*)&_enod[0] , - +2 * __hashscal, +137) ; - } - } ; - - - class node_pred - { - public : - __const_ptr(node_list) _nset ; - public : - /*----------------------- build hash _obj. from _src. */ - __inline_call node_pred ( - node_list *_nsrc - ) : _nset( _nsrc) {} - /*----------------------- compute "equal-to" for node */ - __inline_call - bool_type operator() ( - iptr_type _ipos, - iptr_type _jpos - ) const - { - iptr_type _inod[1]; - _inod[0] = this->_nset-> - operator[](_ipos).node( 0) ; - - iptr_type _jnod[1]; - _jnod[0] = this->_nset-> - operator[](_jpos).node( 0) ; - - return _inod[0] == _jnod[0] ; - } - } ; - - class edge_pred - { - public : - __const_ptr(edge_list) _eset ; - public : - /*----------------------- build hash _obj. from _src. */ - __inline_call edge_pred ( - edge_list *_esrc - ) : _eset( _esrc) {} - /*----------------------- compute "equal-to" for edge */ - __inline_call - bool_type operator() ( - iptr_type _ipos, - iptr_type _jpos - ) const - { - iptr_type _inod[2]; - _inod[0] = this->_eset-> - operator[](_ipos).node( 0) ; - _inod[1] = this->_eset-> - operator[](_ipos).node( 1) ; - - iptr_type _jnod[2]; - _jnod[0] = this->_eset-> - operator[](_jpos).node( 0) ; - _jnod[1] = this->_eset-> - operator[](_jpos).node( 1) ; - - algorithms::isort ( - &_inod[0], &_inod[2], - std::less()); - - algorithms::isort ( - &_jnod[0], &_jnod[2], - std::less()); - - return _inod[0] == _jnod[0] && - _inod[1] == _jnod[1] ; - } - } ; - - #undef __hashscal - - iptr_type static const pool_byte_size=96*1024 ; + typedef containers::array < + indx_type, + allocator > indx_list ; + + typedef mesh::node_hash node_hash ; + typedef mesh::node_pred node_pred ; + + typedef mesh::edge_hash edge_hash ; + typedef mesh::edge_pred edge_pred ; + + indx_type static + constexpr pool_byte_size = 96 * 1024 ; typedef allocators::_pool_alloc < allocators::basic_alloc , @@ -226,125 +112,87 @@ typedef allocators::_wrap_alloc < pool_base > pool_wrap ; - //typedef containers::hash_table < - // iptr_type, - // node_hash, - // node_pred, - // pool_wrap> node_maps ; - typedef containers::hash_table < iptr_type, edge_hash, edge_pred, pool_wrap> edge_maps ; + typedef containers::array < + conn_pair, + allocator > connector ; + typedef containers::array_list < - iptr_type, + conn_pair, pool_wrap > conn_list ; public : - pool_base _hsrc ; - pool_base _csrc ; + pool_base _hsrc ; + pool_base _csrc ; - conn_list _adj1 ; - conn_list _adj2 ; + conn_list _aaN1 ; - //node_maps _map1 ; - edge_maps _map2 ; + edge_maps _mmE2 ; - node_list _set1 ; - edge_list _set2 ; + node_list _llN1 ; + edge_list _llE2 ; - iptr_list _del1 ; - iptr_list _del2 ; - - iptr_list _tmp1 ; - iptr_list _tmp2 ; + indx_list _ffN1 ; + indx_list _ffE2 ; + connector _tmp1 ; public : /* -------------------------------------------------------- - * GET-NODE: "create" new node, push onto active set. + * Public access to underlying data for k-CELL types. -------------------------------------------------------- */ - __inline_call iptr_type _get_node ( + __inline_call node_list const& node ( + ) const + { return this->_llN1 ; + } + + __inline_call node_list & node ( ) - { - iptr_type _ipos = -1; - if (this->_del1.count() != +0 ) - { - /*---------------------------- recycle from free list */ - this->_del1._pop_tail(_ipos) ; - } - else - { - /*---------------------------- alloc. from underlying */ - _ipos = (iptr_type) - this->_set1.count() ; - this->_set1.push_tail() ; - } - - this->_set1[_ipos].mark() = +0 ; - this->_set1[_ipos].self() = +0 ; - - return ( _ipos ) ; + { return this->_llN1 ; } - /* - -------------------------------------------------------- - * GET-EDGE: "create" new edge, push onto active set. - -------------------------------------------------------- - */ + __inline_call node_type const& node ( + indx_type _ipos + ) const + { return this->_llN1[_ipos] ; + } - __inline_call iptr_type _get_edge ( + __inline_call node_type & node ( + indx_type _ipos ) - { - iptr_type _ipos = -1; - if (this->_del2.count() != +0 ) - { - /*---------------------------- recycle from free list */ - this->_del2._pop_tail(_ipos) ; - } - else - { - /*---------------------------- alloc. from underlying */ - _ipos = (iptr_type) - this->_set2.count() ; - this->_set2.push_tail() ; - } - - this->_set2[_ipos].mark() = +0 ; - this->_set2[_ipos].self() = +0 ; - - return ( _ipos ) ; + { return this->_llN1[_ipos] ; } - /* - -------------------------------------------------------- - * PUT-ITEM: "delete" old item, _pop from active set. - -------------------------------------------------------- - */ + __inline_call edge_list const& edge ( + ) const + { return this->_llE2 ; + } - __inline_call void_type _put_node ( - iptr_type _ipos + __inline_call edge_list & edge ( ) - { - this->_del1.push_tail (_ipos); - this->_set1[_ipos].mark() = -1 ; - this->_set1[_ipos].self() = -1 ; + { return this->_llE2 ; + } + + __inline_call edge_type const& edge ( + indx_type _ipos + ) const + { return this->_llE2[_ipos] ; } - __inline_call void_type _put_edge ( - iptr_type _ipos + __inline_call edge_type & edge ( + indx_type _ipos ) - { - this->_del2.push_tail (_ipos); - this->_set2[_ipos].mark() = -1 ; - this->_set2[_ipos].self() = -1 ; + { return this->_llE2[_ipos] ; } public : @@ -358,245 +206,56 @@ __normal_call tria_complex_1 ( allocator const& _asrc = allocator() ) : _hsrc(sizeof ( - typename edge_maps::item_type)), + typename edge_maps::item_type)), _csrc(sizeof ( - typename conn_list::item_type)), - /*------------------------------ init. adj. lists */ - _adj1(pool_wrap(&_csrc)), - _adj2(pool_wrap(&_csrc)), - /*------------------------------ init. hash lists */ - //_map1( - // node_hash(& this->_set1) , - // node_pred(& this->_set1) , - //+.8, (pool_wrap(&_hsrc))) , - _map2( - edge_hash(& this->_set2) , - edge_pred(& this->_set2) , - +.8, (pool_wrap(&_hsrc))) , - /*------------------------------ init. face lists */ - _set1(_asrc),_set2(_asrc) , - /*------------------------------ init. free lists */ - _del1(_asrc),_del2(_asrc) , - /*------------------------------ init. work lists */ - _tmp1(_asrc),_tmp2(_asrc) - { - } - - /* - -------------------------------------------------------- - * 'clear' a tria-complex - -------------------------------------------------------- - */ - - __normal_call void_type clear ( - containers::alloc_types _kind = - containers::loose_alloc - ) + typename conn_list::item_type)), + /*---------------------------------- init. adj. lists */ + _aaN1(pool_wrap(&_csrc)), + /*---------------------------------- init. hash lists */ + _mmE2( + edge_hash(& this->_llE2) , + edge_pred(& this->_llE2) , + +.8, (pool_wrap(&_hsrc))) , + /*---------------------------------- init. face lists */ + _llN1(_asrc),_llE2(_asrc) , + /*---------------------------------- init. free lists */ + _ffN1(_asrc),_ffE2(_asrc) , + /*---------------------------------- init. work lists */ + _tmp1(_asrc) { - this->_adj1.clear (_kind) ; - this->_adj2.clear (_kind) ; - - //this->_map1.clear (_kind) ; - this->_map2.clear (_kind) ; - - this->_set1.clear (_kind) ; - this->_set2.clear (_kind) ; - - this->_del1.clear (_kind) ; - this->_del2.clear (_kind) ; - - this->_tmp1.clear (_kind) ; - this->_tmp2.clear (_kind) ; - - this->_hsrc.clear (); - this->_csrc.clear (); } - /* - -------------------------------------------------------- - * INIT-LIST: re-size adj. lists on demand. - -------------------------------------------------------- - */ - - __inline_call void_type init_list ( - conn_list&_list, - size_type _lpos + __inline_call~tria_complex_1 ( ) { - if (_lpos >= _list._lptr.count()) - _list._lptr.set_count ( - _lpos + 1, - containers::loose_alloc, nullptr) ; + clear(containers::tight_alloc); } /* -------------------------------------------------------- - * PUSH-NODE: append new 0-node to complex. + * "clear" a tria-complex -------------------------------------------------------- */ - __normal_call iptr_type push_node ( - node_type const& _ndat, - bool_type _link = true, - iptr_type _itop = -1 + __normal_call void_type clear ( + containers::alloc_types _kind = + containers::loose_alloc ) { - iptr_type _ipos = -1 ; - - if (!_link) - { - - __assert( _itop == -1 && - "tria-complex: non-top node!" ) ; + this->_aaN1.clear (_kind) ; - /*------------------------ init. external d-face data */ - _ipos = _get_node(); + this->_mmE2.clear (_kind) ; - this->_set1[_ipos] = _ndat ; - this->_set1[_ipos].mark() = 0 ; + this->_llN1.clear (_kind) ; + this->_llE2.clear (_kind) ; - this->_set1[_ipos].self() = 1 ; - this-> - _set1 [_ipos].node(0) =_ipos ; + this->_ffN1.clear (_kind) ; + this->_ffE2.clear (_kind) ; - /*------------------------ init. local adj. index set */ - init_list(this->_adj1, _ipos) ; + this->_tmp1.clear (_kind) ; - } - else - { - - if (_itop == -1) - { - /*------------------------ init. external d-face data */ - _ipos = _get_node(); - - this->_set1[_ipos] = _ndat ; - this->_set1[_ipos].mark() = 0 ; - this->_set1[_ipos].self() = 1 ; - - this-> - _set1 [_ipos].node(0) = _ipos; - - /*------------------------ init. local adj. index set */ - init_list(this->_adj1, _ipos) ; - - } - else - { - /*------------------------ init. internal d-face data */ - __assert(find_node( - &_ndat.node(0), _ipos) && - "tria-complex: node not here" ); - - /*------------------------ append index to adj. lists */ - this->_adj1.push( - _itop, _ndat.node(0)) ; - - } - - } - - return _ipos ; - } - - /* - -------------------------------------------------------- - * PUSH-EDGE: append new 1-edge to complex. - -------------------------------------------------------- - */ - - __normal_call iptr_type push_edge ( - edge_type const& _edat, - bool_type _link = true, - iptr_type _itop = -1 - ) - { - iptr_type _ipos = _get_edge() ; - iptr_type _npos ; - - if (!_link) - { - - __assert( _itop == -1 && - "tria-complex: non-top cell!" ) ; - - /*------------------------ init. external d-face data */ - this->_set2[_ipos] = _edat ; - this->_set2[_ipos].mark() = 0 ; - this->_set2[_ipos].self() = 1 ; - - /*------------------------ init. local adj. index set */ - init_list(this->_adj2, _ipos) ; - - } - else - { - - /*------------------------ init. external d-face data */ - this->_set2[_ipos] = _edat ; - this->_set2[_ipos].mark() = 0 ; - - if (_itop == -1) - this->_set2[_ipos].self() = 1 ; - else - this->_set2[_ipos].self() = 0 ; - - typename - edge_maps::_write_it _same ; - if (this-> - _map2.find(_ipos , _same)) - { - /*---- existing d-face found: append to existing data */ - if (_itop == -1) - { - /*----- if it's a "top"-level face, copy data */ - this->_set2[*_same] = - this->_set2[ _ipos] ; - } - else - { - /*----- otherwise, append index to adj. lists */ - this-> - _adj2.push(_itop,*_same) ; - } - - _put_edge(_ipos) ; - } - else - { - /*---- d-face is new: push and descend to (d-1)-faces */ - if (_itop == -1) - { - /*----- if it's a "top"-level face, keep data */ - init_list( - this->_adj2, _ipos) ; - } - else - { - /*----- otherwise, append index to adj. lists */ - this-> - _adj2.push(_itop, _ipos) ; - } - - /*-------------- descend into (d-1)-face data */ - for (_npos = 2; _npos-- != 0; ) - { - node_type _ndat; - _ndat.node(0) = - _edat.node(_npos) ; - - push_node( - _ndat, _link, _ipos) ; - } - - /*-------------- push new face data onto hash */ - this->_map2.push(_ipos) ; - } - - } - - return _ipos ; + this->_hsrc.clear (); + this->_csrc.clear (); } /* @@ -608,86 +267,47 @@ __normal_call void_type make_link ( ) { - this->_map2.set_slots( - (this->_set2.count()*5)/4 + 1 + this->_mmE2.set_slots( + (this->_llE2.count()*5) / 4 + 1 ) ; - this->_adj1.empty () ; - this->_adj2.empty () ; - - iptr_type _epos = +0 ; - for (auto _iter = this->_set2.head(); - _iter != this->_set2.tend(); - ++_iter, ++_epos ) - { - /*-------------- push face data onto hash set */ - this->_map2.push(_epos) ; - - /*-------------- descend into (d-1)-face data */ - iptr_type _ipos; - for (_ipos = +2; _ipos-- != 0; ) - { - node_type _ndat; - _ndat.node(0) = - _iter->node( _ipos) ; - - push_node( - _ndat, true, _epos) ; - } - } + this->_aaN1.empty () ; + + mesh::link_edge(*this) ; } /* -------------------------------------------------------- - * NULL-ITEM: TRUE if item is delete-able. + * PUSH-NODE: append new 0-node to complex. -------------------------------------------------------- */ - __inline_call bool_type null_node ( - iptr_type _npos - ) const - { - return this->_set1[_npos].self()==0 - && this->_adj1.empty(_npos); - } - - __inline_call bool_type null_edge ( - iptr_type _epos - ) const + __inline_call iptr_type push_node ( + node_type const& _ndat, + bool_type _link = true, + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag + ) { - return this->_set2[_epos].self()==0 - && this->_adj2.empty(_epos); + return mesh::push_node( + *this, _ndat, _link, _itop, _kind) ; } /* -------------------------------------------------------- - * _POP-LIST: delete item from adj. list. + * PUSH-EDGE: append new 1-edge to complex. -------------------------------------------------------- */ - __normal_call void_type _pop_list ( - conn_list &_list, - iptr_type _lpos, - iptr_type _itop + __inline_call iptr_type push_edge ( + edge_type const& _edat, + bool_type _link = true, + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag ) { - /*--------------------------- scan list and pop match */ - typename conn_list::_write_it - _prev = _list.hend(_lpos), - _iter = _list.head(_lpos), - _tend = _list.tend(_lpos); - - for ( ; _iter != _tend; - _prev = _iter, ++_iter) - { - if(*_iter == _itop) - { - _list._pop ( - _prev, _iter, _lpos) ; - - break ; - } - } + return mesh::push_edge( + *this, _edat, _link, _itop, _kind) ; } /* @@ -698,47 +318,11 @@ __inline_call void_type _pop_node ( iptr_type const*_nptr, - iptr_type _itop = -1 + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag ) { - iptr_type _npos = -1 ; - - iptr_type _node[1]; - _node[0] = _nptr[0]; - - /*-------------------------- find current 0-node pos. */ - if ( !find_node (_node, _npos)) - { - return ; - } - - /*-------------------------- _pop current 0-node data */ - _pop_node(_npos, _itop) ; - } - - __normal_call void_type _pop_node ( - iptr_type _npos , - iptr_type _itop - ) - { - if (_itop != -1) - { - /*---- deleteing (d+k)-face: scan adj. and _pop _itop */ - _pop_list( - this->_adj1, _npos, _itop); - } - else - { - /*---- deleting (d+0)-face: set "self" marker to null */ - this-> - _set1[_npos].self() = 0 ; - } - - if (null_node (_npos)) - { - /*---- ref. count: delete (d+0), (d-1)-faces if empty */ - _put_node (_npos); - } + mesh::_pop_node(*this, _nptr, _itop, _kind) ; } /* @@ -747,67 +331,22 @@ -------------------------------------------------------- */ - __normal_call void_type _pop_edge ( + __inline_call void_type _pop_edge ( iptr_type const*_nptr, - iptr_type _itop = -1 + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag ) { - iptr_type _epos = -1 ; - - iptr_type _node[2]; - _node[0] = _nptr[0]; - _node[1] = _nptr[1]; - - /*-------------------------- find current 1-edge pos. */ - if ( !find_edge (_node, _epos)) - { - return ; - } - - /*-------------------------- _pop current 1-edge data */ - _pop_edge(_epos, _itop) ; + mesh::_pop_edge(*this, _nptr, _itop, _kind) ; } - __normal_call void_type _pop_edge ( + __inline_call void_type _pop_edge ( iptr_type _epos , - iptr_type _itop = -1 + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag ) { - iptr_type _npos = -1 ; - - if (_itop != -1) - { - /*---- deleteing (d+k)-face: scan adj. and _pop _itop */ - _pop_list( - this->_adj2, _epos, _itop); - } - else - { - /*---- deleting (d+0)-face: set "self" marker to null */ - this-> - _set2[_epos].self() = 0 ; - } - - if (null_edge (_epos)) - { - /*---- ref. count: delete (d+0), (d-1)-faces if empty */ - iptr_type _same ; - this->_map2._pop(_epos, _same); - - iptr_type _node [ 2] ; - _node[0] = this-> - _set2[_epos].node(0) ; - _node[1] = this-> - _set2[_epos].node(1) ; - - _put_edge(_epos); - - for (_npos = 2; _npos-- != 0; ) - { - _pop_node( - &_node[_npos], _epos); - } - } + mesh::_pop_edge(*this, _epos, _itop, _kind) ; } /* @@ -816,28 +355,12 @@ -------------------------------------------------------- */ - __normal_call bool_type find_node ( + __inline_call bool_type find_node ( iptr_type const*_nptr , iptr_type&_npos ) const { - /*-------------------------- find current 0-node pos. */ - iptr_type _node = *_nptr ; - - if (_node >= +0 && _node < - (iptr_type)this->_set1.count() && - _set1 [_node].mark() >= +0) - { - /*------------------------------- found matching node */ - _npos =_node ; - - return true ; - } - else - { - /*------------------------------- couldn't find match */ - return false ; - } + return mesh::find_node(*this, _nptr, _npos) ; } /* @@ -846,98 +369,54 @@ -------------------------------------------------------- */ - __normal_call bool_type find_edge ( + __inline_call bool_type find_edge ( iptr_type const*_node , iptr_type&_epos ) { - /*-------------------------- find current 1-edge pos. */ - iptr_type _ipos = _get_edge() ; - - this-> - _set2[_ipos].node(0)=_node[0]; - this-> - _set2[_ipos].node(1)=_node[1]; - - typename edge_maps::_write_it - _same ; - if (this-> - _map2.find(_ipos, _same)) - { - /*------------------------------- found matching face */ - _put_edge(_ipos) ; - - _epos=*_same ; - - return true ; - } - else - { - /*------------------------------- couldn't find match */ - _put_edge(_ipos) ; - - return false ; - } + return mesh::find_edge(*this, _node, _epos) ; } /* -------------------------------------------------------- - * NODE-EDGE: form node-to-edge adj. list. + * FIND-CELL: return index of assoc. k-cell. -------------------------------------------------------- */ - template < - typename list_type - > - __inline_call void_type node_edge ( + __inline_call bool_type find_cell ( iptr_type const*_node , - list_type&_conn + char_type _kind , + iptr_type&_ipos ) { - node_edge(_node [ 0], _conn) ; + return mesh::find_cell( + *this, _node, _kind, _ipos, tria_cell()) ; } - template < - typename list_type - > - __normal_call void_type node_edge ( - iptr_type _npos, - list_type&_conn + /* + -------------------------------------------------------- + * CONNECT-1: form this-to-1-cell adj. list. + -------------------------------------------------------- + */ + + __inline_call void_type connect_1 ( + iptr_type const*_node , + char_type _kind , + connector&_conn + ) + { + mesh::connect_1( + *this, _node, _kind, _conn, tria_cell()) ; + } + + __inline_call void_type connect_1 ( + iptr_type _ipos , + char_type _kind , + connector&_conn ) { - this->_tmp1.set_count( +0 ) ; - this->_tmp2.set_count( +0 ) ; - - this->_tmp1.push_tail(_npos) ; - - /*-------------------------- find set of adj. 1-edges */ - for (auto _iter = this->_tmp1.head(); - _iter != this->_tmp1.tend(); - ++_iter ) - { - for (auto _iadj = - this->_adj1.head(*_iter) ; - _iadj != - this->_adj1.tend(*_iter) ; - ++_iadj ) - { - if (this-> - _set2[*_iadj].mark() == 0) - { - _conn.push_tail (*_iadj); - this-> - _set2[*_iadj].mark() += 1; - } - } - } - - /*-------------------------- flip d-face marker lists */ - for (auto _iter = _conn.head() ; - _iter != _conn.tend() ; - ++_iter ) - { - this->_set2 [*_iter].mark() = +0; - } + mesh::connect_1( + *this, _ipos, _kind, _conn, tria_cell()) ; } } ; diff --git a/src/libcpp/mesh_type/tria_complex_2.hpp b/src/libcpp/mesh_type/tria_complex_2.hpp index 048f44e..2508804 100644 --- a/src/libcpp/mesh_type/tria_complex_2.hpp +++ b/src/libcpp/mesh_type/tria_complex_2.hpp @@ -1,7 +1,7 @@ /* -------------------------------------------------------- - * TRIA-COMPLEX-2: piecewise tria. complex in R^2. + * TRIA-COMPLEX-2: piecewise tria. complex in T^2. -------------------------------------------------------- * * This program may be freely redistributed under the @@ -31,20 +31,20 @@ * -------------------------------------------------------- * - * Last updated: 30 June, 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/ * -------------------------------------------------------- */ - #pragma once +# pragma once - #ifndef __TRIA_COMPLEX_2__ - #define __TRIA_COMPLEX_2__ +# ifndef __TRIA_COMPLEX_2__ +# define __TRIA_COMPLEX_2__ namespace mesh { @@ -79,9 +79,9 @@ typedef typename tri3_type::iptr_type iptr_type ; typedef typename - allocator::size_type size_type ; + allocator::size_type indx_type ; - iptr_type static constexpr _dims = +2 ; + indx_type static constexpr topo_dims = +2 ; typedef containers::block_array < node_type, @@ -99,211 +99,21 @@ iptr_type, allocator > iptr_list ; - #define __hashscal sizeof(iptr_type)/sizeof(uint32_t) - - class node_hash - { - public : - __const_ptr(node_list) _nset ; - public : - /*----------------------- build hash _obj. from _src. */ - __inline_call node_hash ( - node_list *_nsrc - ) : _nset( _nsrc) {} - /*----------------------- hash node indexing for node */ - __inline_call - uint32_t operator() ( - iptr_type _npos - ) const - { - return (uint32_t)this->_nset-> - operator[](_npos).node( 0) ; - } - } ; - - class edge_hash - { - public : - __const_ptr(edge_list) _eset ; - public : - /*----------------------- build hash _obj. from _src. */ - __inline_call edge_hash ( - edge_list *_esrc - ) : _eset( _esrc) {} - /*----------------------- hash node indexing for edge */ - __inline_call - uint32_t operator() ( - iptr_type _epos - ) const - { - iptr_type _enod[2]; - _enod[0] = this->_eset-> - operator[](_epos).node( 0) ; - _enod[1] = this->_eset-> - operator[](_epos).node( 1) ; - - algorithms::isort ( - &_enod[0], &_enod[2] , - std::less()); - - return hash::hashword ( - (uint32_t*)&_enod[0] , - +2 * __hashscal, +137) ; - } - } ; - - class tri3_hash - { - public : - __const_ptr(tri3_list) _tset ; - public : - /*----------------------- build hash _obj. from _src. */ - __inline_call tri3_hash ( - tri3_list *_tsrc - ) : _tset( _tsrc) {} - /*----------------------- hash node indexing for face */ - __inline_call - uint32_t operator() ( - iptr_type _tpos - ) const - { - iptr_type _tnod[3]; - _tnod[0] = this->_tset-> - operator[](_tpos).node( 0) ; - _tnod[1] = this->_tset-> - operator[](_tpos).node( 1) ; - _tnod[2] = this->_tset-> - operator[](_tpos).node( 2) ; - - algorithms::isort ( - &_tnod[0], &_tnod[3] , - std::less()); - - return hash::hashword ( - (uint32_t*)&_tnod[0] , - +3 * __hashscal, +137) ; - } - } ; - - - class node_pred - { - public : - __const_ptr(node_list) _nset ; - public : - /*----------------------- build hash _obj. from _src. */ - __inline_call node_pred ( - node_list *_nsrc - ) : _nset( _nsrc) {} - /*----------------------- compute "equal-to" for node */ - __inline_call - bool_type operator() ( - iptr_type _ipos, - iptr_type _jpos - ) const - { - iptr_type _inod[1]; - _inod[0] = this->_nset-> - operator[](_ipos).node( 0) ; - - iptr_type _jnod[1]; - _jnod[0] = this->_nset-> - operator[](_jpos).node( 0) ; - - return _inod[0] == _jnod[0] ; - } - } ; - - class edge_pred - { - public : - __const_ptr(edge_list) _eset ; - public : - /*----------------------- build hash _obj. from _src. */ - __inline_call edge_pred ( - edge_list *_esrc - ) : _eset( _esrc) {} - /*----------------------- compute "equal-to" for edge */ - __inline_call - bool_type operator() ( - iptr_type _ipos, - iptr_type _jpos - ) const - { - iptr_type _inod[2]; - _inod[0] = this->_eset-> - operator[](_ipos).node( 0) ; - _inod[1] = this->_eset-> - operator[](_ipos).node( 1) ; - - iptr_type _jnod[2]; - _jnod[0] = this->_eset-> - operator[](_jpos).node( 0) ; - _jnod[1] = this->_eset-> - operator[](_jpos).node( 1) ; - - algorithms::isort ( - &_inod[0], &_inod[2], - std::less()); - - algorithms::isort ( - &_jnod[0], &_jnod[2], - std::less()); - - return _inod[0] == _jnod[0] && - _inod[1] == _jnod[1] ; - } - } ; - - class tri3_pred - { - public : - __const_ptr(tri3_list) _tset ; - public : - /*----------------------- build hash _obj. from _src. */ - __inline_call tri3_pred ( - tri3_list *_tsrc - ) : _tset( _tsrc) {} - /*----------------------- compute "equal-to" for face */ - __inline_call - bool_type operator() ( - iptr_type _ipos, - iptr_type _jpos - ) const - { - iptr_type _inod[3]; - _inod[0] = this->_tset-> - operator[](_ipos).node( 0) ; - _inod[1] = this->_tset-> - operator[](_ipos).node( 1) ; - _inod[2] = this->_tset-> - operator[](_ipos).node( 2) ; - - iptr_type _jnod[3]; - _jnod[0] = this->_tset-> - operator[](_jpos).node( 0) ; - _jnod[1] = this->_tset-> - operator[](_jpos).node( 1) ; - _jnod[2] = this->_tset-> - operator[](_jpos).node( 2) ; - - algorithms::isort ( - &_inod[0], &_inod[3], - std::less()); - - algorithms::isort ( - &_jnod[0], &_jnod[3], - std::less()); - - return _inod[0] == _jnod[0] && - _inod[1] == _jnod[1] && - _inod[2] == _jnod[2] ; - } - } ; - - #undef __hashscal - - iptr_type static const pool_byte_size=96*1024 ; + typedef containers::array < + indx_type, + allocator > indx_list ; + + typedef mesh::node_hash node_hash ; + typedef mesh::node_pred node_pred ; + + typedef mesh::edge_hash edge_hash ; + typedef mesh::edge_pred edge_pred ; + + typedef mesh::tri3_hash tri3_hash ; + typedef mesh::tri3_pred tri3_pred ; + + indx_type static + constexpr pool_byte_size = 96 * 1024 ; typedef allocators::_pool_alloc < allocators::basic_alloc , @@ -312,12 +122,6 @@ typedef allocators::_wrap_alloc < pool_base > pool_wrap ; - //typedef containers::hash_table < - // iptr_type, - // node_hash, - // node_pred, - // pool_wrap> node_maps ; - typedef containers::hash_table < iptr_type, edge_hash, @@ -330,156 +134,108 @@ tri3_pred, pool_wrap> tri3_maps ; + typedef containers::array < + conn_pair, + allocator > connector ; + typedef containers::array_list < - iptr_type, + conn_pair, pool_wrap > conn_list ; public : - pool_base _hsrc ; - pool_base _csrc ; + pool_base _hsrc ; + pool_base _csrc ; - conn_list _adj1 ; - conn_list _adj2 ; - conn_list _adj3 ; + conn_list _aaN1 ; + conn_list _aaE2 ; - //node_maps _map1 ; - edge_maps _map2 ; - tri3_maps _map3 ; + edge_maps _mmE2 ; + tri3_maps _mmT3 ; - node_list _set1 ; - edge_list _set2 ; - tri3_list _set3 ; + node_list _llN1 ; + edge_list _llE2 ; + tri3_list _llT3 ; - iptr_list _del1 ; - iptr_list _del2 ; - iptr_list _del3 ; - - iptr_list _tmp1 ; - iptr_list _tmp2 ; - iptr_list _tmp3 ; + indx_list _ffN1 ; + indx_list _ffE2 ; + indx_list _ffT3 ; + connector _tmp1 ; + connector _tmp2 ; public : /* -------------------------------------------------------- - * GET-NODE: "create" new node, push onto active set. + * Public access to underlying data for k-CELL types. -------------------------------------------------------- */ - __inline_call iptr_type _get_node ( + __inline_call node_list const& node ( + ) const + { return this->_llN1 ; + } + + __inline_call node_list & node ( ) - { - iptr_type _ipos = -1; - if (this->_del1.count() != +0 ) - { - /*---------------------------- recycle from free list */ - this->_del1._pop_tail(_ipos) ; - } - else - { - /*---------------------------- alloc. from underlying */ - _ipos = (iptr_type) - this->_set1.count() ; - this->_set1.push_tail() ; - } - - this->_set1[_ipos].mark() = +0 ; - this->_set1[_ipos].self() = +0 ; - - return ( _ipos ) ; + { return this->_llN1 ; } - /* - -------------------------------------------------------- - * GET-EDGE: "create" new edge, push onto active set. - -------------------------------------------------------- - */ + __inline_call node_type const& node ( + indx_type _ipos + ) const + { return this->_llN1[_ipos] ; + } - __inline_call iptr_type _get_edge ( + __inline_call node_type & node ( + indx_type _ipos ) - { - iptr_type _ipos = -1; - if (this->_del2.count() != +0 ) - { - /*---------------------------- recycle from free list */ - this->_del2._pop_tail(_ipos) ; - } - else - { - /*---------------------------- alloc. from underlying */ - _ipos = (iptr_type) - this->_set2.count() ; - this->_set2.push_tail() ; - } - - this->_set2[_ipos].mark() = +0 ; - this->_set2[_ipos].self() = +0 ; - - return ( _ipos ) ; + { return this->_llN1[_ipos] ; } - /* - -------------------------------------------------------- - * GET-TRIA: "create" new tria, push onto active set. - -------------------------------------------------------- - */ + __inline_call edge_list const& edge ( + ) const + { return this->_llE2 ; + } - __inline_call iptr_type _get_tri3 ( + __inline_call edge_list & edge ( ) - { - iptr_type _ipos = -1; - if (this->_del3.count() != +0 ) - { - /*---------------------------- recycle from free list */ - this->_del3._pop_tail(_ipos) ; - } - else - { - /*---------------------------- alloc. from underlying */ - _ipos = (iptr_type) - this->_set3.count() ; - this->_set3.push_tail() ; - } - - this->_set3[_ipos].mark() = +0 ; - this->_set3[_ipos].self() = +0 ; - - return ( _ipos ) ; + { return this->_llE2 ; } - /* - -------------------------------------------------------- - * PUT-ITEM: "delete" old item, _pop from active set. - -------------------------------------------------------- - */ + __inline_call edge_type const& edge ( + indx_type _ipos + ) const + { return this->_llE2[_ipos] ; + } - __inline_call void_type _put_node ( - iptr_type _ipos + __inline_call edge_type & edge ( + indx_type _ipos ) - { - this->_del1.push_tail (_ipos); - this->_set1[_ipos].mark() = -1 ; - this->_set1[_ipos].self() = -1 ; + { return this->_llE2[_ipos] ; } - __inline_call void_type _put_edge ( - iptr_type _ipos + __inline_call tri3_list const& tri3 ( + ) const + { return this->_llT3 ; + } + + __inline_call tri3_list & tri3 ( ) - { - this->_del2.push_tail (_ipos); - this->_set2[_ipos].mark() = -1 ; - this->_set2[_ipos].self() = -1 ; + { return this->_llT3 ; } - __inline_call void_type _put_tri3 ( - iptr_type _ipos + __inline_call tri3_type const& tri3 ( + indx_type _ipos + ) const + { return this->_llT3[_ipos] ; + } + + __inline_call tri3_type & tri3 ( + indx_type _ipos ) - { - this->_del3.push_tail (_ipos); - this->_set3[_ipos].mark() = -1 ; - this->_set3[_ipos].self() = -1 ; + { return this->_llT3[_ipos] ; } public : @@ -493,41 +249,41 @@ __normal_call tria_complex_2 ( allocator const& _asrc = allocator() ) : _hsrc(sizeof ( - typename tri3_maps::item_type)), + typename edge_maps::item_type)), _csrc(sizeof ( - typename conn_list::item_type)), - /*------------------------------ init. adj. lists */ - _adj1(pool_wrap(&_csrc)), - _adj2(pool_wrap(&_csrc)), - _adj3(pool_wrap(&_csrc)), - /*------------------------------ init. hash lists */ - //_map1( - // node_hash(& this->_set1) , - // node_pred(& this->_set1) , - //+.8, (pool_wrap(&_hsrc))) , - _map2( - edge_hash(& this->_set2) , - edge_pred(& this->_set2) , - +.8, (pool_wrap(&_hsrc))) , - _map3( - tri3_hash(& this->_set3) , - tri3_pred(& this->_set3) , - +.8, (pool_wrap(&_hsrc))) , - /*------------------------------ init. face lists */ - _set1(_asrc),_set2(_asrc) , - _set3(_asrc), - /*------------------------------ init. free lists */ - _del1(_asrc),_del2(_asrc) , - _del3(_asrc), - /*------------------------------ init. work lists */ - _tmp1(_asrc),_tmp2(_asrc) , - _tmp3(_asrc) - { - } + typename conn_list::item_type)), + /*---------------------------------- init. adj. lists */ + _aaN1(pool_wrap(&_csrc)), + _aaE2(pool_wrap(&_csrc)), + /*---------------------------------- init. hash lists */ + _mmE2( + edge_hash(& this->_llE2) , + edge_pred(& this->_llE2) , + +.8, (pool_wrap(&_hsrc))) , + _mmT3( + tri3_hash(& this->_llT3) , + tri3_pred(& this->_llT3) , + +.8, (pool_wrap(&_hsrc))) , + /*---------------------------------- init. face lists */ + _llN1(_asrc),_llE2(_asrc) , + _llT3(_asrc), + /*---------------------------------- init. free lists */ + _ffN1(_asrc),_ffE2(_asrc) , + _ffT3(_asrc), + /*---------------------------------- init. work lists */ + _tmp1(_asrc),_tmp2(_asrc) + { + } + + __inline_call~tria_complex_2 ( + ) + { + clear(containers::tight_alloc); + } /* -------------------------------------------------------- - * 'clear' a tria-complex + * "clear" a tria-complex -------------------------------------------------------- */ @@ -536,45 +292,50 @@ containers::loose_alloc ) { - this->_adj1.clear (_kind) ; - this->_adj2.clear (_kind) ; - this->_adj3.clear (_kind) ; + this->_aaN1.clear (_kind) ; + this->_aaE2.clear (_kind) ; - //this->_map1.clear (_kind) ; - this->_map2.clear (_kind) ; - this->_map3.clear (_kind) ; + this->_mmE2.clear (_kind) ; + this->_mmT3.clear (_kind) ; - this->_set1.clear (_kind) ; - this->_set2.clear (_kind) ; - this->_set3.clear (_kind) ; + this->_llN1.clear (_kind) ; + this->_llE2.clear (_kind) ; + this->_llT3.clear (_kind) ; - this->_del1.clear (_kind) ; - this->_del2.clear (_kind) ; - this->_del3.clear (_kind) ; + this->_ffN1.clear (_kind) ; + this->_ffE2.clear (_kind) ; + this->_ffT3.clear (_kind) ; - this->_tmp1.clear (_kind) ; - this->_tmp2.clear (_kind) ; - this->_tmp3.clear (_kind) ; + this->_tmp1.clear (_kind) ; + this->_tmp2.clear (_kind) ; - this->_hsrc.clear (); - this->_csrc.clear (); + this->_hsrc.clear (); + this->_csrc.clear (); } /* -------------------------------------------------------- - * INIT-LIST: re-size adj. lists on demand. + * MAKE-LINK: build item-to-item adj. -------------------------------------------------------- */ - __inline_call void_type init_list ( - conn_list&_list, - size_type _lpos + __normal_call void_type make_link ( ) { - if (_lpos >= _list._lptr.count()) - _list._lptr.set_count ( - _lpos + 1, - containers::loose_alloc, nullptr) ; + this->_mmE2.set_slots( + (this->_llE2.count()*5) / 4 + 1 + + (this->_llT3.count()*3) / 2 + 1 + ) ; + + this->_mmT3.set_slots( + (this->_llT3.count()*5) / 4 + 1 + ) ; + + this->_aaN1.empty () ; + this->_aaE2.empty () ; + + mesh::link_edge(*this) ; + mesh::link_tri3(*this) ; } /* @@ -583,69 +344,15 @@ -------------------------------------------------------- */ - __normal_call iptr_type push_node ( + __inline_call iptr_type push_node ( node_type const& _ndat, bool_type _link = true, - iptr_type _itop = -1 + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag ) { - iptr_type _ipos = -1 ; - - if (!_link) - { - - __assert( _itop == -1 && - "tria-complex: non-top node!" ) ; - - /*------------------------ init. external d-face data */ - _ipos = _get_node(); - - this->_set1[_ipos] = _ndat ; - this->_set1[_ipos].mark() = 0 ; - - this->_set1[_ipos].self() = 1 ; - this-> - _set1 [_ipos].node(0) =_ipos ; - - /*------------------------ init. local adj. index set */ - init_list(this->_adj1, _ipos) ; - - } - else - { - - if (_itop == -1) - { - /*------------------------ init. external d-face data */ - _ipos = _get_node(); - - this->_set1[_ipos] = _ndat ; - this->_set1[_ipos].mark() = 0 ; - this->_set1[_ipos].self() = 1 ; - - this-> - _set1 [_ipos].node(0) = _ipos; - - /*------------------------ init. local adj. index set */ - init_list(this->_adj1, _ipos) ; - - } - else - { - /*------------------------ init. internal d-face data */ - __assert(find_node( - &_ndat.node(0), _ipos) && - "tria-complex: node not here" ); - - /*------------------------ append index to adj. lists */ - this->_adj1.push( - _itop, _ndat.node(0)) ; - - } - - } - - return _ipos ; + return mesh::push_node( + *this, _ndat, _link, _itop, _kind) ; } /* @@ -654,97 +361,15 @@ -------------------------------------------------------- */ - __normal_call iptr_type push_edge ( + __inline_call iptr_type push_edge ( edge_type const& _edat, bool_type _link = true, - iptr_type _itop = -1 + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag ) { - iptr_type _ipos = _get_edge() ; - iptr_type _npos ; - - if (!_link) - { - - __assert( _itop == -1 && - "tria-complex: non-top cell!" ) ; - - /*------------------------ init. external d-face data */ - this->_set2[_ipos] = _edat ; - this->_set2[_ipos].mark() = 0 ; - this->_set2[_ipos].self() = 1 ; - - /*------------------------ init. local adj. index set */ - init_list(this->_adj2, _ipos) ; - - } - else - { - - /*------------------------ init. external d-face data */ - this->_set2[_ipos] = _edat ; - this->_set2[_ipos].mark() = 0 ; - - if (_itop == -1) - this->_set2[_ipos].self() = 1 ; - else - this->_set2[_ipos].self() = 0 ; - - typename - edge_maps::_write_it _same ; - if (this-> - _map2.find(_ipos , _same)) - { - /*---- existing d-face found: append to existing data */ - if (_itop == -1) - { - /*----- if it's a "top"-level face, copy data */ - this->_set2[*_same] = - this->_set2[ _ipos] ; - } - else - { - /*----- otherwise, append index to adj. lists */ - this-> - _adj2.push(_itop,*_same) ; - } - - _put_edge(_ipos) ; - } - else - { - /*---- d-face is new: push and descend to (d-1)-faces */ - if (_itop == -1) - { - /*----- if it's a "top"-level face, keep data */ - init_list( - this->_adj2, _ipos) ; - } - else - { - /*----- otherwise, append index to adj. lists */ - this-> - _adj2.push(_itop, _ipos) ; - } - - /*-------------- descend into (d-1)-face data */ - for (_npos = 2; _npos-- != 0; ) - { - node_type _ndat; - _ndat.node(0) = - _edat.node(_npos) ; - - push_node( - _ndat, _link, _ipos) ; - } - - /*-------------- push new face data onto hash */ - this->_map2.push(_ipos) ; - } - - } - - return _ipos ; + return mesh::push_edge( + *this, _edat, _link, _itop, _kind) ; } /* @@ -753,235 +378,15 @@ -------------------------------------------------------- */ - __normal_call iptr_type push_tri3 ( + __inline_call iptr_type push_tri3 ( tri3_type const& _tdat, bool_type _link = true, - iptr_type _itop = -1 - ) - { - iptr_type _ipos = _get_tri3() ; - iptr_type _epos ; - - if (!_link) - { - - __assert( _itop == -1 && - "tria-complex: non-top cell!" ) ; - - /*-------------------- init. external d-face data */ - this->_set3[_ipos] = _tdat ; - this->_set3[_ipos].mark() = 0 ; - this->_set3[_ipos].self() = 1 ; - - /*-------------------- init. local adj. index set */ - init_list(this->_adj3, _ipos) ; - - } - else - { - - /*------------------------ init. external d-face data */ - this->_set3[_ipos] = _tdat ; - this->_set3[_ipos].mark() = 0 ; - - if (_itop == -1) - this->_set3[_ipos].self() = 1 ; - else - this->_set3[_ipos].self() = 0 ; - - typename - tri3_maps::_write_it _same ; - if (this-> - _map3.find(_ipos , _same)) - { - /*---- existing d-face found: append to existing data */ - if (_itop == -1) - { - /*----- if it's a "top"-level face, copy data */ - this->_set3[*_same] = - this->_set3[ _ipos] ; - } - else - { - /*----- otherwise, append index to adj. lists */ - this-> - _adj3.push(_itop,*_same) ; - } - - _put_tri3(_ipos) ; - } - else - { - /*---- d-face is new: push and descend to (d-1)-faces */ - if (_itop == -1) - { - /*----- if it's a "top"-level face, keep data */ - init_list( - this->_adj3, _ipos) ; - } - else - { - /*----- otherwise, append index to adj. lists */ - this-> - _adj3.push(_itop, _ipos) ; - } - - /*-------------- descend into (d-1)-face data */ - for (_epos = +3; _epos-- != 0 ; ) - { - iptr_type _enod [3]; - tri3_type::face_node( - _enod, _epos, 2, 1) ; - - edge_type _edat ; - _edat.node(0) = - _tdat.node(_enod[0]) ; - _edat.node(1) = - _tdat.node(_enod[1]) ; - - push_edge( - _edat, _link, _ipos) ; - } - - /*-------------- push new face data onto hash */ - this->_map3.push(_ipos) ; - } - - } - - return _ipos ; - } - - /* - -------------------------------------------------------- - * MAKE-LINK: build item-to-item adj. - -------------------------------------------------------- - */ - - __normal_call void_type make_link ( - ) - { - this->_map2.set_slots( - (this->_set2.count()*5)/4 + 1 - + (this->_set3.count()*5)/2 + 1 - ) ; - - this->_map3.set_slots( - (this->_set3.count()*5)/4 + 1 - ) ; - - this->_adj1.empty () ; - this->_adj2.empty () ; - this->_adj3.empty () ; - - iptr_type _epos = +0 ; - for (auto _iter = this->_set2.head(); - _iter != this->_set2.tend(); - ++_iter, ++_epos ) - { - /*-------------- push face data onto hash set */ - this->_map2.push(_epos) ; - - /*-------------- descend into (d-1)-face data */ - iptr_type _ipos; - for (_ipos = +2; _ipos-- != 0; ) - { - node_type _ndat; - _ndat.node(0) = - _iter->node( _ipos) ; - - push_node( - _ndat, true, _epos) ; - } - } - - iptr_type _tpos = +0 ; - for (auto _iter = this->_set3.head(); - _iter != this->_set3.tend(); - ++_iter, ++_tpos ) - { - /*-------------- push face data onto hash set */ - this->_map3.push(_tpos) ; - - /*-------------- descend into (d-1)-face data */ - iptr_type _ipos; - for (_ipos = +3; _ipos-- != 0; ) - { - iptr_type _enod [3]; - tri3_type::face_node( - _enod, _ipos, 2, 1 ) ; - - edge_type _edat ; - _edat.node(0) = - _iter->node(_enod[0]) ; - _edat.node(1) = - _iter->node(_enod[1]) ; - - push_edge( - _edat, true , _tpos) ; - } - } - } - - /* - -------------------------------------------------------- - * NULL-ITEM: TRUE if item is delete-able. - -------------------------------------------------------- - */ - - __inline_call bool_type null_node ( - iptr_type _npos - ) const - { - return this->_set1[_npos].self()==0 - && this->_adj1.empty(_npos); - } - - __inline_call bool_type null_edge ( - iptr_type _epos - ) const - { - return this->_set2[_epos].self()==0 - && this->_adj2.empty(_epos); - } - - __inline_call bool_type null_tri3 ( - iptr_type _tpos - ) const - { - return this->_set3[_tpos].self()==0 - && this->_adj3.empty(_tpos); - } - - /* - -------------------------------------------------------- - * _POP-LIST: delete item from adj. list. - -------------------------------------------------------- - */ - - __normal_call void_type _pop_list ( - conn_list &_list, - iptr_type _lpos, - iptr_type _itop + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag ) { - /*--------------------------- scan list and pop match */ - typename conn_list::_write_it - _prev = _list.hend(_lpos), - _iter = _list.head(_lpos), - _tend = _list.tend(_lpos); - - for ( ; _iter != _tend; - _prev = _iter, ++_iter) - { - if(*_iter == _itop) - { - _list._pop ( - _prev, _iter, _lpos) ; - - break ; - } - } + return mesh::push_tri3( + *this, _tdat, _link, _itop, _kind) ; } /* @@ -990,49 +395,13 @@ -------------------------------------------------------- */ - __normal_call void_type _pop_node ( + __inline_call void_type _pop_node ( iptr_type const*_nptr, - iptr_type _itop = -1 - ) - { - iptr_type _npos = -1 ; - - iptr_type _node[1]; - _node[0] = _nptr[0]; - - /*-------------------------- find current 0-node pos. */ - if ( !find_node (_node, _npos)) - { - return ; - } - - /*-------------------------- _pop current 0-node data */ - _pop_node(_npos, _itop) ; - } - - __normal_call void_type _pop_node ( - iptr_type _npos , - iptr_type _itop + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag ) { - if (_itop != -1) - { - /*---- deleteing (d+k)-face: scan adj. and _pop _itop */ - _pop_list( - this->_adj1, _npos, _itop); - } - else - { - /*---- deleting (d+0)-face: set "self" marker to null */ - this-> - _set1[_npos].self() = 0 ; - } - - if (null_node (_npos)) - { - /*---- ref. count: delete (d+0), (d-1)-faces if empty */ - _put_node (_npos); - } + mesh::_pop_node(*this, _nptr, _itop, _kind) ; } /* @@ -1041,67 +410,22 @@ -------------------------------------------------------- */ - __normal_call void_type _pop_edge ( + __inline_call void_type _pop_edge ( iptr_type const*_nptr, - iptr_type _itop = -1 + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag ) { - iptr_type _epos = -1 ; - - iptr_type _node[2]; - _node[0] = _nptr[0]; - _node[1] = _nptr[1]; - - /*-------------------------- find current 1-edge pos. */ - if ( !find_edge (_node, _epos)) - { - return ; - } - - /*-------------------------- _pop current 1-edge data */ - _pop_edge(_epos, _itop) ; + mesh::_pop_edge(*this, _nptr, _itop, _kind) ; } - __normal_call void_type _pop_edge ( + __inline_call void_type _pop_edge ( iptr_type _epos , - iptr_type _itop = -1 + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag ) { - iptr_type _npos = -1 ; - - if (_itop != -1) - { - /*---- deleteing (d+k)-face: scan adj. and _pop _itop */ - _pop_list( - this->_adj2, _epos, _itop); - } - else - { - /*---- deleting (d+0)-face: set "self" marker to null */ - this-> - _set2[_epos].self() = 0 ; - } - - if (null_edge (_epos)) - { - /*---- ref. count: delete (d+0), (d-1)-faces if empty */ - iptr_type _same ; - this->_map2._pop(_epos, _same); - - iptr_type _node [ 2] ; - _node[0] = this-> - _set2[_epos].node(0) ; - _node[1] = this-> - _set2[_epos].node(1) ; - - _put_edge(_epos); - - for (_npos = 2; _npos-- != 0; ) - { - _pop_node( - &_node[_npos], _epos); - } - } + mesh::_pop_edge(*this, _epos, _itop, _kind) ; } /* @@ -1110,79 +434,22 @@ -------------------------------------------------------- */ - __normal_call void_type _pop_tri3 ( + __inline_call void_type _pop_tri3 ( iptr_type const*_nptr, - iptr_type _itop = -1 + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag ) { - iptr_type _tpos = -1 ; - - iptr_type _node[3]; - _node[0] = _nptr[0]; - _node[1] = _nptr[1]; - _node[2] = _nptr[2]; - - /*-------------------------- find current 2-tria pos. */ - if ( !find_tri3 (_node, _tpos)) - { - return ; - } - - /*-------------------------- _pop current 2-tria data */ - _pop_tri3(_tpos, _itop) ; + mesh::_pop_tri3(*this, _nptr, _itop, _kind) ; } - __normal_call void_type _pop_tri3 ( + __inline_call void_type _pop_tri3 ( iptr_type _tpos , - iptr_type _itop = -1 + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag ) { - iptr_type _epos = -1 ; - - if (_itop != -1) - { - /*---- deleteing (d+k)-face: scan adj. and _pop _itop */ - _pop_list( - this->_adj3, _tpos, _itop); - } - else - { - /*---- deleting (d+0)-face: set "self" marker to null */ - this-> - _set3[_tpos].self() = 0 ; - } - - if (null_tri3 (_tpos)) - { - /*---- ref. count: delete (d+0), (d-1)-faces if empty */ - - iptr_type _same ; - this->_map3._pop(_tpos, _same); - - iptr_type _node [ 3] ; - _node[0] = this-> - _set3[_tpos].node(0) ; - _node[1] = this-> - _set3[_tpos].node(1) ; - _node[2] = this-> - _set3[_tpos].node(2) ; - - _put_tri3(_tpos); - - for (_epos = 3; _epos-- != 0; ) - { - iptr_type _enod [3] ; - tri3_type::face_node ( - _enod, _epos, 2, 1) ; - - _enod[0] = - _node[_enod [0]]; - _enod[1] = - _node[_enod [1]]; - - _pop_edge(_enod, _tpos) ; - } - } + mesh::_pop_tri3(*this, _tpos, _itop, _kind) ; } /* @@ -1191,28 +458,12 @@ -------------------------------------------------------- */ - __normal_call bool_type find_node ( + __inline_call bool_type find_node ( iptr_type const*_nptr , iptr_type&_npos ) const { - /*-------------------------- find current 0-node pos. */ - iptr_type _node = *_nptr ; - - if (_node >= +0 && _node < - (iptr_type)this->_set1.count() && - _set1 [_node].mark() >= +0) - { - /*------------------------------- found matching node */ - _npos =_node ; - - return true ; - } - else - { - /*------------------------------- couldn't find match */ - return false ; - } + return mesh::find_node(*this, _nptr, _npos) ; } /* @@ -1221,38 +472,12 @@ -------------------------------------------------------- */ - __normal_call bool_type find_edge ( + __inline_call bool_type find_edge ( iptr_type const*_node , iptr_type&_epos ) { - /*-------------------------- find current 1-edge pos. */ - iptr_type _ipos = _get_edge() ; - - this-> - _set2[_ipos].node(0)=_node[0]; - this-> - _set2[_ipos].node(1)=_node[1]; - - typename edge_maps::_write_it - _same ; - if (this-> - _map2.find(_ipos, _same)) - { - /*------------------------------- found matching face */ - _put_edge(_ipos) ; - - _epos=*_same ; - - return true ; - } - else - { - /*------------------------------- couldn't find match */ - _put_edge(_ipos) ; - - return false ; - } + return mesh::find_edge(*this, _node, _epos) ; } /* @@ -1261,261 +486,80 @@ -------------------------------------------------------- */ - __normal_call bool_type find_tri3 ( + __inline_call bool_type find_tri3 ( iptr_type const*_node , iptr_type&_tpos ) { - /*-------------------------- find current 2-tria pos. */ - iptr_type _ipos = _get_tri3() ; - - this-> - _set3[_ipos].node(0)=_node[0]; - this-> - _set3[_ipos].node(1)=_node[1]; - this-> - _set3[_ipos].node(2)=_node[2]; - - typename tri3_maps::_write_it - _same ; - if (this-> - _map3.find(_ipos, _same)) - { - /*------------------------------- found matching face */ - _put_tri3(_ipos) ; - - _tpos=*_same ; - - return true ; - } - else - { - /*------------------------------- couldn't find match */ - _put_tri3(_ipos) ; - - return false ; - } + return mesh::find_tri3(*this, _node, _tpos) ; } - /* -------------------------------------------------------- - * NODE-EDGE: form node-to-edge adj. list. + * FIND-CELL: return index of assoc. k-cell. -------------------------------------------------------- */ - template < - typename list_type - > - __inline_call void_type node_edge ( + __inline_call bool_type find_cell ( iptr_type const*_node , - list_type&_conn - ) - { - node_edge(_node [ 0], _conn) ; - } - - template < - typename list_type - > - __normal_call void_type node_edge ( - iptr_type _npos, - list_type&_conn + char_type _kind , + iptr_type&_ipos ) { - this->_tmp1.set_count( +0 ) ; - this->_tmp2.set_count( +0 ) ; - this->_tmp3.set_count( +0 ) ; - - this->_tmp1.push_tail(_npos) ; - - /*-------------------------- find set of adj. 1-edges */ - for (auto _iter = this->_tmp1.head(); - _iter != this->_tmp1.tend(); - ++_iter ) - { - for (auto _iadj = - this->_adj1.head(*_iter) ; - _iadj != - this->_adj1.tend(*_iter) ; - ++_iadj ) - { - if (this-> - _set2[*_iadj].mark() == 0) - { - _conn.push_tail (*_iadj); - this-> - _set2[*_iadj].mark() += 1; - } - } - } - - /*-------------------------- flip d-face marker lists */ - for (auto _iter = _conn.head() ; - _iter != _conn.tend() ; - ++_iter ) - { - this->_set2 [*_iter].mark() = +0; - } + return mesh::find_cell( + *this, _node, _kind, _ipos, tria_cell()) ; } /* -------------------------------------------------------- - * NODE-TRIA: form node-to-tria adj. list. + * CONNECT-1: form this-to-1-cell adj. list. -------------------------------------------------------- */ - template < - typename list_type - > - __inline_call void_type node_tri3 ( + __inline_call void_type connect_1 ( iptr_type const*_node , - list_type&_conn + char_type _kind , + connector&_conn ) { - node_tri3(_node [ 0], _conn) ; + mesh::connect_1( + *this, _node, _kind, _conn, tria_cell()) ; } - template < - typename list_type - > - __normal_call void_type node_tri3 ( - iptr_type _npos, - list_type&_conn + __inline_call void_type connect_1 ( + iptr_type _ipos , + char_type _kind , + connector&_conn ) { - this->_tmp1.set_count( +0 ) ; - this->_tmp2.set_count( +0 ) ; - this->_tmp3.set_count( +0 ) ; - - this->_tmp1.push_tail(_npos) ; - - /*-------------------------- find set of adj. 1-edges */ - for (auto _iter = this->_tmp1.head(); - _iter != this->_tmp1.tend(); - ++_iter ) - { - for (auto _iadj = - this->_adj1.head(*_iter) ; - _iadj != - this->_adj1.tend(*_iter) ; - ++_iadj ) - { - if (this-> - _set2[*_iadj].mark() == 0) - { - this-> - _tmp2.push_tail (*_iadj); - this-> - _set2[*_iadj].mark() += 1; - } - } - } - /*-------------------------- find set of adj. 2-trias */ - for (auto _iter = this->_tmp2.head(); - _iter != this->_tmp2.tend(); - ++_iter ) - { - for (auto _iadj = - this->_adj2.head(*_iter) ; - _iadj != - this->_adj2.tend(*_iter) ; - ++_iadj ) - { - if (this-> - _set3[*_iadj].mark() == 0) - { - _conn.push_tail (*_iadj); - this-> - _set3[*_iadj].mark() += 1; - } - } - } - - /*-------------------------- flip d-face marker lists */ - for (auto _iter = _conn.head() ; - _iter != _conn.tend() ; - ++_iter ) - { - this->_set3 [*_iter].mark() = 0 ; - } - for (auto _iter = this-> - _tmp2.head() ; - _iter != this-> - _tmp2.tend() ; - ++_iter ) - { - this->_set2 [*_iter].mark() = 0 ; - } + mesh::connect_1( + *this, _ipos, _kind, _conn, tria_cell()) ; } /* -------------------------------------------------------- - * EDGE-TRIA: form edge-to-tria adj. list. + * CONNECT-2: form this-to-2-cell adj. list. -------------------------------------------------------- */ - template < - typename list_type - > - __inline_call void_type edge_tri3 ( + __inline_call void_type connect_2 ( iptr_type const*_node , - list_type&_conn + char_type _kind , + connector&_conn ) { - /*-------------------------- find current 1-edge pos. */ - iptr_type _epos = -1; - if (!find_edge(_node, _epos)) - { - return ; - } - - /*-------------------------- get adj. for 1-edge pos. */ - edge_tri3(_epos, _conn) ; + mesh::connect_2( + *this, _node, _kind, _conn, tria_cell()) ; } - template < - typename list_type - > - __normal_call void_type edge_tri3 ( - iptr_type _epos, - list_type&_conn + __inline_call void_type connect_2 ( + iptr_type _ipos , + char_type _kind , + connector&_conn ) { - this->_tmp1.set_count( +0 ) ; - this->_tmp2.set_count( +0 ) ; - this->_tmp3.set_count( +0 ) ; - - this->_tmp2.push_tail(_epos) ; - - /*-------------------------- find set of adj. 2-faces */ - for (auto _iter = this->_tmp2.head(); - _iter != this->_tmp2.tend(); - ++_iter ) - { - for (auto _iadj = - this->_adj2.head(*_iter) ; - _iadj != - this->_adj2.tend(*_iter) ; - ++_iadj ) - { - if (this-> - _set3[*_iadj].mark() == 0) - { - _conn.push_tail (*_iadj); - this-> - _set3[*_iadj].mark() += 1; - } - } - } - - /*-------------------------- flip d-face marker lists */ - for (auto _iter = _conn.head() ; - _iter != _conn.tend() ; - ++_iter ) - { - this->_set3 [*_iter].mark() = 0 ; - } + mesh::connect_2( + *this, _ipos, _kind, _conn, tria_cell()) ; } } ; diff --git a/src/libcpp/mesh_type/tria_complex_3.hpp b/src/libcpp/mesh_type/tria_complex_3.hpp index 76b5504..08db9de 100644 --- a/src/libcpp/mesh_type/tria_complex_3.hpp +++ b/src/libcpp/mesh_type/tria_complex_3.hpp @@ -1,7 +1,7 @@ /* -------------------------------------------------------- - * TRIA-COMPLEX-3: piecewise tria. complex in R^3. + * TRIA-COMPLEX-3: piecewise tria. complex in T^3. -------------------------------------------------------- * * This program may be freely redistributed under the @@ -31,11 +31,11 @@ * -------------------------------------------------------- * - * Last updated: 30 June, 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/ * -------------------------------------------------------- @@ -82,9 +82,9 @@ typedef typename tri3_type::iptr_type iptr_type ; typedef typename - allocator::size_type size_type ; + allocator::size_type indx_type ; - iptr_type static constexpr _dims = +3 ; + indx_type static constexpr topo_dims = +3 ; typedef containers::block_array < node_type, @@ -106,297 +106,24 @@ iptr_type, allocator > iptr_list ; - #define __hashscal sizeof(iptr_type)/sizeof(uint32_t) - - class node_hash - { - public : - __const_ptr(node_list) _nset ; - public : - /*----------------------- build hash _obj. from _src. */ - __inline_call node_hash ( - node_list *_nsrc - ) : _nset( _nsrc) {} - /*----------------------- hash node indexing for node */ - __inline_call - uint32_t operator() ( - iptr_type _npos - ) const - { - return this->_nset-> - operator[](_npos).node( 0) ; - } - } ; - - class edge_hash - { - public : - __const_ptr(edge_list) _eset ; - public : - /*----------------------- build hash _obj. from _src. */ - __inline_call edge_hash ( - edge_list *_esrc - ) : _eset( _esrc) {} - /*----------------------- hash node indexing for edge */ - __inline_call - uint32_t operator() ( - iptr_type _epos - ) const - { - iptr_type _enod[2]; - _enod[0] = this->_eset-> - operator[](_epos).node( 0) ; - _enod[1] = this->_eset-> - operator[](_epos).node( 1) ; - - algorithms::isort ( - &_enod[0], &_enod[2] , - std::less()); - - return hash::hashword ( - (uint32_t*)&_enod[0] , - +2 * __hashscal, +137) ; - } - } ; - - class tri3_hash - { - public : - __const_ptr(tri3_list) _tset ; - public : - /*----------------------- build hash _obj. from _src. */ - __inline_call tri3_hash ( - tri3_list *_tsrc - ) : _tset( _tsrc) {} - /*----------------------- hash node indexing for face */ - __inline_call - uint32_t operator() ( - iptr_type _tpos - ) const - { - iptr_type _tnod[3]; - _tnod[0] = this->_tset-> - operator[](_tpos).node( 0) ; - _tnod[1] = this->_tset-> - operator[](_tpos).node( 1) ; - _tnod[2] = this->_tset-> - operator[](_tpos).node( 2) ; - - algorithms::isort ( - &_tnod[0], &_tnod[3] , - std::less()); - - return hash::hashword ( - (uint32_t*)&_tnod[0] , - +3 * __hashscal, +137) ; - } - } ; - - class tri4_hash - { - public : - __const_ptr(tri4_list) _tset ; - public : - /*----------------------- build hash _obj. from _src. */ - __inline_call tri4_hash ( - tri4_list *_tsrc - ) : _tset( _tsrc) {} - /*----------------------- hash node indexing for face */ - __inline_call - uint32_t operator() ( - iptr_type _tpos - ) const - { - iptr_type _tnod[4]; - _tnod[0] = this->_tset-> - operator[](_tpos).node( 0) ; - _tnod[1] = this->_tset-> - operator[](_tpos).node( 1) ; - _tnod[2] = this->_tset-> - operator[](_tpos).node( 2) ; - _tnod[3] = this->_tset-> - operator[](_tpos).node( 3) ; - - algorithms::isort ( - &_tnod[0], &_tnod[4] , - std::less()); - - return hash::hashword ( - (uint32_t*)&_tnod[0] , - +4 * __hashscal, +137) ; - } - } ; - - - class node_pred - { - public : - __const_ptr(node_list) _nset ; - public : - /*----------------------- build hash _obj. from _src. */ - __inline_call node_pred ( - node_list *_nsrc - ) : _nset( _nsrc) {} - /*----------------------- compute "equal-to" for node */ - __inline_call - bool_type operator() ( - iptr_type _ipos, - iptr_type _jpos - ) const - { - iptr_type _inod[1]; - _inod[0] = this->_nset-> - operator[](_ipos).node( 0) ; - - iptr_type _jnod[1]; - _jnod[0] = this->_nset-> - operator[](_jpos).node( 0) ; - - return _inod[0] == _jnod[0] ; - } - } ; - - class edge_pred - { - public : - __const_ptr(edge_list) _eset ; - public : - /*----------------------- build hash _obj. from _src. */ - __inline_call edge_pred ( - edge_list *_esrc - ) : _eset( _esrc) {} - /*----------------------- compute "equal-to" for edge */ - __inline_call - bool_type operator() ( - iptr_type _ipos, - iptr_type _jpos - ) const - { - iptr_type _inod[2]; - _inod[0] = this->_eset-> - operator[](_ipos).node( 0) ; - _inod[1] = this->_eset-> - operator[](_ipos).node( 1) ; - - iptr_type _jnod[2]; - _jnod[0] = this->_eset-> - operator[](_jpos).node( 0) ; - _jnod[1] = this->_eset-> - operator[](_jpos).node( 1) ; - - algorithms::isort ( - &_inod[0], &_inod[2], - std::less()); - - algorithms::isort ( - &_jnod[0], &_jnod[2], - std::less()); - - return _inod[0] == _jnod[0] && - _inod[1] == _jnod[1] ; - } - } ; - - class tri3_pred - { - public : - __const_ptr(tri3_list) _tset ; - public : - /*----------------------- build hash _obj. from _src. */ - __inline_call tri3_pred ( - tri3_list *_tsrc - ) : _tset( _tsrc) {} - /*----------------------- compute "equal-to" for face */ - __inline_call - bool_type operator() ( - iptr_type _ipos, - iptr_type _jpos - ) const - { - iptr_type _inod[3]; - _inod[0] = this->_tset-> - operator[](_ipos).node( 0) ; - _inod[1] = this->_tset-> - operator[](_ipos).node( 1) ; - _inod[2] = this->_tset-> - operator[](_ipos).node( 2) ; - - iptr_type _jnod[3]; - _jnod[0] = this->_tset-> - operator[](_jpos).node( 0) ; - _jnod[1] = this->_tset-> - operator[](_jpos).node( 1) ; - _jnod[2] = this->_tset-> - operator[](_jpos).node( 2) ; - - algorithms::isort ( - &_inod[0], &_inod[3], - std::less()); - - algorithms::isort ( - &_jnod[0], &_jnod[3], - std::less()); - - return _inod[0] == _jnod[0] && - _inod[1] == _jnod[1] && - _inod[2] == _jnod[2] ; - } - } ; - - class tri4_pred - { - public : - __const_ptr(tri4_list) _tset ; - public : - /*----------------------- build hash _obj. from _src. */ - __inline_call tri4_pred ( - tri4_list *_tsrc - ) : _tset( _tsrc) {} - /*----------------------- compute "equal-to" for face */ - __inline_call - bool_type operator() ( - iptr_type _ipos, - iptr_type _jpos - ) const - { - iptr_type _inod[4]; - _inod[0] = this->_tset-> - operator[](_ipos).node( 0) ; - _inod[1] = this->_tset-> - operator[](_ipos).node( 1) ; - _inod[2] = this->_tset-> - operator[](_ipos).node( 2) ; - _inod[3] = this->_tset-> - operator[](_ipos).node( 3) ; - - iptr_type _jnod[4]; - _jnod[0] = this->_tset-> - operator[](_jpos).node( 0) ; - _jnod[1] = this->_tset-> - operator[](_jpos).node( 1) ; - _jnod[2] = this->_tset-> - operator[](_jpos).node( 2) ; - _jnod[3] = this->_tset-> - operator[](_jpos).node( 3) ; - - algorithms::isort ( - &_inod[0], &_inod[4], - std::less()); - - algorithms::isort ( - &_jnod[0], &_jnod[4], - std::less()); - - return _inod[0] == _jnod[0] && - _inod[1] == _jnod[1] && - _inod[2] == _jnod[2] && - _inod[3] == _jnod[3] ; - } - } ; - - #undef __hashscal - - iptr_type static const pool_byte_size=96*1024 ; + typedef containers::array < + indx_type, + allocator > indx_list ; + + typedef mesh::node_hash node_hash ; + typedef mesh::node_pred node_pred ; + + typedef mesh::edge_hash edge_hash ; + typedef mesh::edge_pred edge_pred ; + + typedef mesh::tri3_hash tri3_hash ; + typedef mesh::tri3_pred tri3_pred ; + + typedef mesh::tri4_hash tri4_hash ; + typedef mesh::tri4_pred tri4_pred ; + + indx_type static + constexpr pool_byte_size = 96 * 1024 ; typedef allocators::_pool_alloc < allocators::basic_alloc , @@ -405,12 +132,6 @@ typedef allocators::_wrap_alloc < pool_base > pool_wrap ; - //typedef containers::hash_table < - // iptr_type, - // node_hash, - // node_pred, - // pool_wrap> node_maps ; - typedef containers::hash_table < iptr_type, edge_hash, @@ -429,198 +150,135 @@ tri4_pred, pool_wrap> tri4_maps ; + typedef containers::array < + conn_pair, + allocator > connector ; + typedef containers::array_list < - iptr_type, + conn_pair, pool_wrap > conn_list ; public : - pool_base _hsrc ; - pool_base _csrc ; + pool_base _hsrc ; + pool_base _csrc ; - conn_list _adj1 ; - conn_list _adj2 ; - conn_list _adj3 ; - conn_list _adj4 ; + conn_list _aaN1 ; + conn_list _aaE2 ; + conn_list _aaT3 ; - //node_maps _map1 ; - edge_maps _map2 ; - tri3_maps _map3 ; - tri4_maps _map4 ; + edge_maps _mmE2 ; + tri3_maps _mmT3 ; + tri4_maps _mmT4 ; - node_list _set1 ; - edge_list _set2 ; - tri3_list _set3 ; - tri4_list _set4 ; + node_list _llN1 ; + edge_list _llE2 ; + tri3_list _llT3 ; + tri4_list _llT4 ; - iptr_list _del1 ; - iptr_list _del2 ; - iptr_list _del3 ; - iptr_list _del4 ; + indx_list _ffN1 ; + indx_list _ffE2 ; + indx_list _ffT3 ; + indx_list _ffT4 ; - iptr_list _tmp1 ; - iptr_list _tmp2 ; - iptr_list _tmp3 ; - iptr_list _tmp4 ; + connector _tmp1 ; + connector _tmp2 ; + connector _tmp3 ; public : /* -------------------------------------------------------- - * GET-NODE: "create" new node, push onto active set. + * Public access to underlying data for k-CELL types. -------------------------------------------------------- */ - __inline_call iptr_type _get_node ( + __inline_call node_list const& node ( // node + ) const + { return this->_llN1 ; + } + + __inline_call node_list & node ( ) - { - iptr_type _ipos = -1; - if (this->_del1.count() != +0 ) - { - /*---------------------------- recycle from free list */ - this->_del1._pop_tail(_ipos) ; - } - else - { - /*---------------------------- alloc. from underlying */ - _ipos = (iptr_type) - this->_set1.count() ; - this->_set1.push_tail() ; - } - - this->_set1[_ipos].mark() = +0 ; - this->_set1[_ipos].self() = +0 ; - - return ( _ipos ) ; + { return this->_llN1 ; } - /* - -------------------------------------------------------- - * GET-EDGE: "create" new edge, push onto active set. - -------------------------------------------------------- - */ + __inline_call node_type const& node ( + indx_type _ipos + ) const + { return this->_llN1[_ipos] ; + } - __inline_call iptr_type _get_edge ( + __inline_call node_type & node ( + indx_type _ipos ) - { - iptr_type _ipos = -1; - if (this->_del2.count() != +0 ) - { - /*---------------------------- recycle from free list */ - this->_del2._pop_tail(_ipos) ; - } - else - { - /*---------------------------- alloc. from underlying */ - _ipos = (iptr_type) - this->_set2.count() ; - this->_set2.push_tail() ; - } - - this->_set2[_ipos].mark() = +0 ; - this->_set2[_ipos].self() = +0 ; - - return ( _ipos ) ; + { return this->_llN1[_ipos] ; } - /* - -------------------------------------------------------- - * GET-TRIA: "create" new tria, push onto active set. - -------------------------------------------------------- - */ + __inline_call edge_list const& edge ( // edge + ) const + { return this->_llE2 ; + } - __inline_call iptr_type _get_tri3 ( + __inline_call edge_list & edge ( ) - { - iptr_type _ipos = -1; - if (this->_del3.count() != +0 ) - { - /*---------------------------- recycle from free list */ - this->_del3._pop_tail(_ipos) ; - } - else - { - /*---------------------------- alloc. from underlying */ - _ipos = (iptr_type) - this->_set3.count() ; - this->_set3.push_tail() ; - } - - this->_set3[_ipos].mark() = +0 ; - this->_set3[_ipos].self() = +0 ; - - return ( _ipos ) ; + { return this->_llE2 ; } - /* - -------------------------------------------------------- - * GET-TRIA: "create" new tria, push onto active set. - -------------------------------------------------------- - */ + __inline_call edge_type const& edge ( + indx_type _ipos + ) const + { return this->_llE2[_ipos] ; + } - __inline_call iptr_type _get_tri4 ( + __inline_call edge_type & edge ( + indx_type _ipos ) - { - iptr_type _ipos = -1; - if (this->_del4.count() != +0 ) - { - /*---------------------------- recycle from free list */ - this->_del4._pop_tail(_ipos) ; - } - else - { - /*---------------------------- alloc. from underlying */ - _ipos = (iptr_type) - this->_set4.count() ; - this->_set4.push_tail() ; - } - - this->_set4[_ipos].mark() = +0 ; - this->_set4[_ipos].self() = +0 ; - - return ( _ipos ) ; + { return this->_llE2[_ipos] ; } - /* - -------------------------------------------------------- - * PUT-ITEM: "delete" old item, _pop from active set. - -------------------------------------------------------- - */ + __inline_call tri3_list const& tri3 ( // tri3 + ) const + { return this->_llT3 ; + } - __inline_call void_type _put_node ( - iptr_type _ipos + __inline_call tri3_list & tri3 ( ) - { - this->_del1.push_tail (_ipos); - this->_set1[_ipos].mark() = -1 ; - this->_set1[_ipos].self() = -1 ; + { return this->_llT3 ; + } + + __inline_call tri3_type const& tri3 ( + indx_type _ipos + ) const + { return this->_llT3[_ipos] ; } - __inline_call void_type _put_edge ( - iptr_type _ipos + __inline_call tri3_type & tri3 ( + indx_type _ipos ) - { - this->_del2.push_tail (_ipos); - this->_set2[_ipos].mark() = -1 ; - this->_set2[_ipos].self() = -1 ; + { return this->_llT3[_ipos] ; + } + + __inline_call tri4_list const& tri4 ( // tri4 + ) const + { return this->_llT4 ; } - __inline_call void_type _put_tri3 ( - iptr_type _ipos + __inline_call tri4_list & tri4 ( ) - { - this->_del3.push_tail (_ipos); - this->_set3[_ipos].mark() = -1 ; - this->_set3[_ipos].self() = -1 ; + { return this->_llT4 ; } - __inline_call void_type _put_tri4 ( - iptr_type _ipos + __inline_call tri4_type const& tri4 ( + indx_type _ipos + ) const + { return this->_llT4[_ipos] ; + } + + __inline_call tri4_type & tri4 ( + indx_type _ipos ) - { - this->_del4.push_tail (_ipos); - this->_set4[_ipos].mark() = -1 ; - this->_set4[_ipos].self() = -1 ; + { return this->_llT4[_ipos] ; } public : @@ -634,46 +292,46 @@ __normal_call tria_complex_3 ( allocator const& _asrc = allocator() ) : _hsrc(sizeof ( - typename tri4_maps::item_type)), + typename edge_maps::item_type)), _csrc(sizeof ( - typename conn_list::item_type)), - /*------------------------------ init. adj. lists */ - _adj1(pool_wrap(&_csrc)), - _adj2(pool_wrap(&_csrc)), - _adj3(pool_wrap(&_csrc)), - _adj4(pool_wrap(&_csrc)), - /*------------------------------ init. hash lists */ - //_map1( - // node_hash(& this->_set1) , - // node_pred(& this->_set1) , - //+.8, (pool_wrap(&_hsrc))) , - _map2( - edge_hash(& this->_set2) , - edge_pred(& this->_set2) , - +.8, (pool_wrap(&_hsrc))) , - _map3( - tri3_hash(& this->_set3) , - tri3_pred(& this->_set3) , - +.8, (pool_wrap(&_hsrc))) , - _map4( - tri4_hash(& this->_set4) , - tri4_pred(& this->_set4) , - +.8, (pool_wrap(&_hsrc))) , - /*------------------------------ init. face lists */ - _set1(_asrc),_set2(_asrc) , - _set3(_asrc),_set4(_asrc) , - /*------------------------------ init. free lists */ - _del1(_asrc),_del2(_asrc) , - _del3(_asrc),_del4(_asrc) , - /*------------------------------ init. work lists */ - _tmp1(_asrc),_tmp2(_asrc) , - _tmp3(_asrc),_tmp4(_asrc) - { - } + typename conn_list::item_type)), + /*---------------------------------- init. adj. lists */ + _aaN1(pool_wrap(&_csrc)), + _aaE2(pool_wrap(&_csrc)), + _aaT3(pool_wrap(&_csrc)), + /*---------------------------------- init. hash lists */ + _mmE2( + edge_hash(& this->_llE2) , + edge_pred(& this->_llE2) , + +.8, (pool_wrap(&_hsrc))) , + _mmT3( + tri3_hash(& this->_llT3) , + tri3_pred(& this->_llT3) , + +.8, (pool_wrap(&_hsrc))) , + _mmT4( + tri4_hash(& this->_llT4) , + tri4_pred(& this->_llT4) , + +.8, (pool_wrap(&_hsrc))) , + /*---------------------------------- init. face lists */ + _llN1(_asrc),_llE2(_asrc) , + _llT3(_asrc),_llT4(_asrc) , + /*---------------------------------- init. free lists */ + _ffN1(_asrc),_ffE2(_asrc) , + _ffT3(_asrc),_ffT4(_asrc) , + /*---------------------------------- init. work lists */ + _tmp1(_asrc),_tmp2(_asrc),_tmp3(_asrc) + { + } + + __inline_call~tria_complex_3 ( + ) + { + clear(containers::tight_alloc); + } /* -------------------------------------------------------- - * 'clear' a tria-complex + * "clear" a tria-complex -------------------------------------------------------- */ @@ -682,50 +340,63 @@ containers::loose_alloc ) { - this->_adj1.clear (_kind) ; - this->_adj2.clear (_kind) ; - this->_adj3.clear (_kind) ; - this->_adj4.clear (_kind) ; - - //this->_map1.clear (_kind) ; - this->_map2.clear (_kind) ; - this->_map3.clear (_kind) ; - this->_map4.clear (_kind) ; - - this->_set1.clear (_kind) ; - this->_set2.clear (_kind) ; - this->_set3.clear (_kind) ; - this->_set4.clear (_kind) ; - - this->_del1.clear (_kind) ; - this->_del2.clear (_kind) ; - this->_del3.clear (_kind) ; - this->_del4.clear (_kind) ; - - this->_tmp1.clear (_kind) ; - this->_tmp2.clear (_kind) ; - this->_tmp3.clear (_kind) ; - this->_tmp4.clear (_kind) ; - - this->_hsrc.clear (); - this->_csrc.clear (); + this->_aaN1.clear (_kind) ; + this->_aaE2.clear (_kind) ; + this->_aaT3.clear (_kind) ; + + this->_mmE2.clear (_kind) ; + this->_mmT3.clear (_kind) ; + this->_mmT4.clear (_kind) ; + + this->_llN1.clear (_kind) ; + this->_llE2.clear (_kind) ; + this->_llT3.clear (_kind) ; + this->_llT4.clear (_kind) ; + + this->_ffN1.clear (_kind) ; + this->_ffE2.clear (_kind) ; + this->_ffT3.clear (_kind) ; + this->_ffT4.clear (_kind) ; + + this->_tmp1.clear (_kind) ; + this->_tmp2.clear (_kind) ; + this->_tmp3.clear (_kind) ; + + this->_hsrc.clear (); + this->_csrc.clear (); } /* -------------------------------------------------------- - * INIT-LIST: re-size adj. lists on demand. + * MAKE-LINK: build item-to-item adj. -------------------------------------------------------- */ - __inline_call void_type init_list ( - conn_list&_list, - size_type _lpos + __normal_call void_type make_link ( ) { - if (_lpos >= _list._lptr.count()) - _list._lptr.set_count ( - _lpos + 1, - containers::loose_alloc, nullptr) ; + this->_mmE2.set_slots( + (this->_llE2.count()*5) / 4 + 1 + + (this->_llT3.count()*3) / 2 + 1 + + (this->_llT4.count()*4) / 2 + 1 + ) ; + + this->_mmT3.set_slots( + (this->_llT3.count()*5) / 4 + 1 + + (this->_llT4.count()*4) / 2 + 1 + ) ; + + this->_mmT4.set_slots( + (this->_llT4.count()*5) / 4 + 1 + ) ; + + this->_aaN1.empty () ; + this->_aaE2.empty () ; + this->_aaT3.empty () ; + + mesh::link_edge(*this) ; + mesh::link_tri3(*this) ; + mesh::link_tri4(*this) ; } /* @@ -734,69 +405,15 @@ -------------------------------------------------------- */ - __normal_call iptr_type push_node ( + __inline_call iptr_type push_node ( node_type const& _ndat, bool_type _link = true, - iptr_type _itop = -1 + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag ) { - iptr_type _ipos = -1 ; - - if (!_link) - { - - __assert( _itop == -1 && - "tria-complex: non-top node!" ) ; - - /*------------------------ init. external d-face data */ - _ipos = _get_node(); - - this->_set1[_ipos] = _ndat ; - this->_set1[_ipos].mark() = 0 ; - - this->_set1[_ipos].self() = 1 ; - this-> - _set1 [_ipos].node(0) =_ipos ; - - /*------------------------ init. local adj. index set */ - init_list(this->_adj1, _ipos) ; - - } - else - { - - if (_itop == -1) - { - /*------------------------ init. external d-face data */ - _ipos = _get_node(); - - this->_set1[_ipos] = _ndat ; - this->_set1[_ipos].mark() = 0 ; - this->_set1[_ipos].self() = 1 ; - - this-> - _set1 [_ipos].node(0) = _ipos; - - /*------------------------ init. local adj. index set */ - init_list(this->_adj1, _ipos) ; - - } - else - { - /*------------------------ init. internal d-face data */ - __assert(find_node( - &_ndat.node(0), _ipos) && - "tria-complex: node not here" ); - - /*------------------------ append index to adj. lists */ - this->_adj1.push( - _itop, _ndat.node(0)) ; - - } - - } - - return _ipos ; + return mesh::push_node( + *this, _ndat, _link, _itop, _kind) ; } /* @@ -805,97 +422,15 @@ -------------------------------------------------------- */ - __normal_call iptr_type push_edge ( + __inline_call iptr_type push_edge ( edge_type const& _edat, bool_type _link = true, - iptr_type _itop = -1 + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag ) { - iptr_type _ipos = _get_edge() ; - iptr_type _npos ; - - if (!_link) - { - - __assert( _itop == -1 && - "tria-complex: non-top cell!" ) ; - - /*------------------------ init. external d-face data */ - this->_set2[_ipos] = _edat ; - this->_set2[_ipos].mark() = 0 ; - this->_set2[_ipos].self() = 1 ; - - /*------------------------ init. local adj. index set */ - init_list(this->_adj2, _ipos) ; - - } - else - { - - /*------------------------ init. external d-face data */ - this->_set2[_ipos] = _edat ; - this->_set2[_ipos].mark() = 0 ; - - if (_itop == -1) - this->_set2[_ipos].self() = 1 ; - else - this->_set2[_ipos].self() = 0 ; - - typename - edge_maps::_write_it _same ; - if (this-> - _map2.find(_ipos , _same)) - { - /*---- existing d-face found: append to existing data */ - if (_itop == -1) - { - /*----- if it's a "top"-level face, copy data */ - this->_set2[*_same] = - this->_set2[ _ipos] ; - } - else - { - /*----- otherwise, append index to adj. lists */ - this-> - _adj2.push(_itop,*_same) ; - } - - _put_edge(_ipos) ; - } - else - { - /*---- d-face is new: push and descend to (d-1)-faces */ - if (_itop == -1) - { - /*----- if it's a "top"-level face, keep data */ - init_list( - this->_adj2, _ipos) ; - } - else - { - /*----- otherwise, append index to adj. lists */ - this-> - _adj2.push(_itop, _ipos) ; - } - - /*-------------- descend into (d-1)-face data */ - for (_npos = 2; _npos-- != 0; ) - { - node_type _ndat; - _ndat.node(0) = - _edat.node(_npos) ; - - push_node( - _ndat, _link, _ipos) ; - } - - /*-------------- push new face data onto hash */ - this->_map2.push(_ipos) ; - } - - } - - return _ipos ; + return mesh::push_edge( + *this, _edat, _link, _itop, _kind) ; } /* @@ -904,103 +439,15 @@ -------------------------------------------------------- */ - __normal_call iptr_type push_tri3 ( + __inline_call iptr_type push_tri3 ( tri3_type const& _tdat, bool_type _link = true, - iptr_type _itop = -1 + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag ) { - iptr_type _ipos = _get_tri3() ; - iptr_type _epos ; - - if (!_link) - { - - __assert( _itop == -1 && - "tria-complex: non-top cell!" ) ; - - /*-------------------- init. external d-face data */ - this->_set3[_ipos] = _tdat ; - this->_set3[_ipos].mark() = 0 ; - this->_set3[_ipos].self() = 1 ; - - /*-------------------- init. local adj. index set */ - init_list(this->_adj3, _ipos) ; - - } - else - { - - /*------------------------ init. external d-face data */ - this->_set3[_ipos] = _tdat ; - this->_set3[_ipos].mark() = 0 ; - - if (_itop == -1) - this->_set3[_ipos].self() = 1 ; - else - this->_set3[_ipos].self() = 0 ; - - typename - tri3_maps::_write_it _same ; - if (this-> - _map3.find(_ipos , _same)) - { - /*---- existing d-face found: append to existing data */ - if (_itop == -1) - { - /*----- if it's a "top"-level face, copy data */ - this->_set3[*_same] = - this->_set3[ _ipos] ; - } - else - { - /*----- otherwise, append index to adj. lists */ - this-> - _adj3.push(_itop,*_same) ; - } - - _put_tri3(_ipos) ; - } - else - { - /*---- d-face is new: push and descend to (d-1)-faces */ - if (_itop == -1) - { - /*----- if it's a "top"-level face, keep data */ - init_list( - this->_adj3, _ipos) ; - } - else - { - /*----- otherwise, append index to adj. lists */ - this-> - _adj3.push(_itop, _ipos) ; - } - - /*-------------- descend into (d-1)-face data */ - for (_epos = +3; _epos-- != 0 ; ) - { - iptr_type _enod [3]; - tri3_type::face_node( - _enod, _epos, 2, 1) ; - - edge_type _edat ; - _edat.node(0) = - _tdat.node(_enod[0]) ; - _edat.node(1) = - _tdat.node(_enod[1]) ; - - push_edge( - _edat, _link, _ipos) ; - } - - /*-------------- push new face data onto hash */ - this->_map3.push(_ipos) ; - } - - } - - return _ipos ; + return mesh::push_tri3( + *this, _tdat, _link, _itop, _kind) ; } /* @@ -1012,278 +459,12 @@ __normal_call iptr_type push_tri4 ( tri4_type const& _tdat, bool_type _link = true, - iptr_type _itop = -1 - ) - { - iptr_type _ipos = _get_tri4() ; - iptr_type _fpos ; - - if (!_link) - { - - __assert( _itop == -1 && - "tria-complex: non-top cell!" ) ; - - /*------------------------ init. external d-face data */ - this->_set4[_ipos] = _tdat ; - this->_set4[_ipos].mark() = 0 ; - this->_set4[_ipos].self() = 1 ; - - /*------------------------ init. local adj. index set */ - init_list(this->_adj4, _ipos) ; - - } - else - { - - /*------------------------ init. external d-face data */ - this->_set4[_ipos] = _tdat ; - this->_set4[_ipos].mark() = 0 ; - - if (_itop == -1) - this->_set4[_ipos].self() = 1 ; - else - this->_set4[_ipos].self() = 0 ; - - typename - tri4_maps::_write_it _same ; - if (this-> - _map4.find(_ipos , _same)) - { - /*---- existing d-face found: append to existing data */ - if (_itop == -1) - { - /*----- if it's a "top"-level face, copy data */ - this->_set4[*_same] = - this->_set4[ _ipos] ; - } - else - { - /*----- otherwise, append index to adj. lists */ - this-> - _adj4.push(_itop,*_same) ; - } - - _put_tri4(_ipos) ; - } - else - { - /*---- d-face is new: push and descend to (d-1)-faces */ - if (_itop == -1) - { - /*----- if it's a "top"-level face, keep data */ - init_list( - this->_adj4, _ipos) ; - } - else - { - /*----- otherwise, append index to adj. lists */ - this-> - _adj4.push(_itop, _ipos) ; - } - - /*-------------- descend into (d-1)-face data */ - for (_fpos = +4; _fpos-- != 0 ; ) - { - iptr_type _fnod [4]; - tri4_type::face_node( - _fnod, _fpos, 3, 2) ; - - tri3_type _fdat ; - _fdat.node(0) = - _tdat.node(_fnod[0]) ; - _fdat.node(1) = - _tdat.node(_fnod[1]) ; - _fdat.node(2) = - _tdat.node(_fnod[2]) ; - - push_tri3( - _fdat, _link, _ipos) ; - } - - /*-------------- push new face data onto hash */ - this->_map4.push(_ipos) ; - } - - } - - return _ipos ; - } - - /* - -------------------------------------------------------- - * MAKE-LINK: build item-to-item adj. - -------------------------------------------------------- - */ - - __normal_call void_type make_link ( - ) - { - this->_map2.set_slots( - (this->_set2.count()*5)/4 + 1 - + (this->_set3.count()*5)/2 + 1 - + (this->_set4.count()*3)/2 + 1 - ) ; - - this->_map3.set_slots( - (this->_set3.count()*5)/4 + 1 - + (this->_set4.count()*5)/2 + 1 - ) ; - - this->_map4.set_slots( - (this->_set4.count()*5)/4 + 1 - ) ; - - this->_adj1.empty () ; - this->_adj2.empty () ; - this->_adj3.empty () ; - this->_adj4.empty () ; - - iptr_type _epos = +0 ; - for (auto _iter = this->_set2.head(); - _iter != this->_set2.tend(); - ++_iter, ++_epos ) - { - /*-------------- push face data onto hash set */ - this->_map2.push(_epos) ; - - /*-------------- descend into (d-1)-face data */ - iptr_type _ipos; - for (_ipos = +2; _ipos-- != 0; ) - { - node_type _ndat; - _ndat.node(0) = - _iter->node( _ipos) ; - - push_node( - _ndat, true, _epos) ; - } - } - - iptr_type _fpos = +0 ; - for (auto _iter = this->_set3.head(); - _iter != this->_set3.tend(); - ++_iter, ++_fpos ) - { - /*-------------- push face data onto hash set */ - this->_map3.push(_fpos) ; - - /*-------------- descend into (d-1)-face data */ - iptr_type _ipos; - for (_ipos = +3; _ipos-- != 0; ) - { - iptr_type _enod [3]; - tri3_type::face_node( - _enod, _ipos, 2, 1 ) ; - - edge_type _edat ; - _edat.node(0) = - _iter->node(_enod[0]) ; - _edat.node(1) = - _iter->node(_enod[1]) ; - - push_edge( - _edat, true , _fpos) ; - } - } - - iptr_type _tpos = +0 ; - for (auto _iter = this->_set4.head(); - _iter != this->_set4.tend(); - ++_iter, ++_tpos ) - { - /*-------------- push face data onto hash set */ - this->_map4.push(_tpos) ; - - /*-------------- descend into (d-1)-face data */ - iptr_type _ipos; - for (_ipos = +4; _ipos-- != 0; ) - { - iptr_type _fnod [4]; - tri4_type::face_node( - _fnod, _ipos, 3, 2 ) ; - - tri3_type _fdat ; - _fdat.node(0) = - _iter->node(_fnod[0]) ; - _fdat.node(1) = - _iter->node(_fnod[1]) ; - _fdat.node(2) = - _iter->node(_fnod[2]) ; - - push_tri3( - _fdat, true , _tpos) ; - } - } - } - - /* - -------------------------------------------------------- - * NULL-ITEM: TRUE if item is delete-able. - -------------------------------------------------------- - */ - - __inline_call bool_type null_node ( - iptr_type _npos - ) const - { - return this->_set1[_npos].self()==0 - && this->_adj1.empty(_npos); - } - - __inline_call bool_type null_edge ( - iptr_type _epos - ) const - { - return this->_set2[_epos].self()==0 - && this->_adj2.empty(_epos); - } - - __inline_call bool_type null_tri3 ( - iptr_type _tpos - ) const - { - return this->_set3[_tpos].self()==0 - && this->_adj3.empty(_tpos); - } - - __inline_call bool_type null_tri4 ( - iptr_type _tpos - ) const - { - return this->_set4[_tpos].self()==0 - && this->_adj4.empty(_tpos); - } - - /* - -------------------------------------------------------- - * _POP-LIST: delete item from adj. list. - -------------------------------------------------------- - */ - - __normal_call void_type _pop_list ( - conn_list &_list, - iptr_type _lpos, - iptr_type _itop + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag ) { - /*--------------------------- scan list and pop match */ - typename conn_list::_write_it - _prev = _list.hend(_lpos), - _iter = _list.head(_lpos), - _tend = _list.tend(_lpos); - - for ( ; _iter != _tend; - _prev = _iter, ++_iter) - { - if(*_iter == _itop) - { - _list._pop ( - _prev, _iter, _lpos) ; - - break ; - } - } + return mesh::push_tri4( + *this, _tdat, _link, _itop, _kind) ; } /* @@ -1292,49 +473,13 @@ -------------------------------------------------------- */ - __normal_call void_type _pop_node ( + __inline_call void_type _pop_node ( iptr_type const*_nptr, - iptr_type _itop = -1 + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag ) { - iptr_type _npos = -1 ; - - iptr_type _node[1]; - _node[0] = _nptr[0]; - - /*-------------------------- find current 0-node pos. */ - if ( !find_node (_node, _npos)) - { - return ; - } - - /*-------------------------- _pop current 0-node data */ - _pop_node(_npos, _itop) ; - } - - __normal_call void_type _pop_node ( - iptr_type _npos , - iptr_type _itop - ) - { - if (_itop != -1) - { - /*---- deleteing (d+k)-face: scan adj. and _pop _itop */ - _pop_list( - this->_adj1, _npos, _itop); - } - else - { - /*---- deleting (d+0)-face: set "self" marker to null */ - this-> - _set1[_npos].self() = 0 ; - } - - if (null_node (_npos)) - { - /*---- ref. count: delete (d+0), (d-1)-faces if empty */ - _put_node (_npos); - } + mesh::_pop_node(*this, _nptr, _itop, _kind) ; } /* @@ -1343,67 +488,22 @@ -------------------------------------------------------- */ - __normal_call void_type _pop_edge ( + __inline_call void_type _pop_edge ( iptr_type const*_nptr, - iptr_type _itop = -1 + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag ) { - iptr_type _epos = -1 ; - - iptr_type _node[2]; - _node[0] = _nptr[0]; - _node[1] = _nptr[1]; - - /*-------------------------- find current 1-edge pos. */ - if ( !find_edge (_node, _epos)) - { - return ; - } - - /*-------------------------- _pop current 1-edge data */ - _pop_edge(_epos, _itop) ; + mesh::_pop_edge(*this, _nptr, _itop, _kind) ; } - __normal_call void_type _pop_edge ( + __inline_call void_type _pop_edge ( iptr_type _epos , - iptr_type _itop = -1 + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag ) { - iptr_type _npos = -1 ; - - if (_itop != -1) - { - /*---- deleteing (d+k)-face: scan adj. and _pop _itop */ - _pop_list( - this->_adj2, _epos, _itop); - } - else - { - /*---- deleting (d+0)-face: set "self" marker to null */ - this-> - _set2[_epos].self() = 0 ; - } - - if (null_edge (_epos)) - { - /*---- ref. count: delete (d+0), (d-1)-faces if empty */ - iptr_type _same ; - this->_map2._pop(_epos, _same); - - iptr_type _node [ 2] ; - _node[0] = this-> - _set2[_epos].node(0) ; - _node[1] = this-> - _set2[_epos].node(1) ; - - _put_edge(_epos); - - for (_npos = 2; _npos-- != 0; ) - { - _pop_node( - &_node[_npos], _epos); - } - } + mesh::_pop_edge(*this, _epos, _itop, _kind) ; } /* @@ -1412,79 +512,22 @@ -------------------------------------------------------- */ - __normal_call void_type _pop_tri3 ( + __inline_call void_type _pop_tri3 ( iptr_type const*_nptr, - iptr_type _itop = -1 + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag ) { - iptr_type _tpos = -1 ; - - iptr_type _node[3]; - _node[0] = _nptr[0]; - _node[1] = _nptr[1]; - _node[2] = _nptr[2]; - - /*-------------------------- find current 2-tria pos. */ - if ( !find_tri3 (_node, _tpos)) - { - return ; - } - - /*-------------------------- _pop current 2-tria data */ - _pop_tri3(_tpos, _itop) ; + mesh::_pop_tri3(*this, _nptr, _itop, _kind) ; } - __normal_call void_type _pop_tri3 ( + __inline_call void_type _pop_tri3 ( iptr_type _tpos , - iptr_type _itop = -1 + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag ) { - iptr_type _epos = -1 ; - - if (_itop != -1) - { - /*---- deleteing (d+k)-face: scan adj. and _pop _itop */ - _pop_list( - this->_adj3, _tpos, _itop); - } - else - { - /*---- deleting (d+0)-face: set "self" marker to null */ - this-> - _set3[_tpos].self() = 0 ; - } - - if (null_tri3 (_tpos)) - { - /*---- ref. count: delete (d+0), (d-1)-faces if empty */ - - iptr_type _same ; - this->_map3._pop(_tpos, _same); - - iptr_type _node [ 3] ; - _node[0] = this-> - _set3[_tpos].node(0) ; - _node[1] = this-> - _set3[_tpos].node(1) ; - _node[2] = this-> - _set3[_tpos].node(2) ; - - _put_tri3(_tpos); - - for (_epos = 3; _epos-- != 0; ) - { - iptr_type _enod [3] ; - tri3_type::face_node ( - _enod, _epos, 2, 1) ; - - _enod[0] = - _node[_enod [0]]; - _enod[1] = - _node[_enod [1]]; - - _pop_edge(_enod, _tpos) ; - } - } + mesh::_pop_tri3(*this, _tpos, _itop, _kind) ; } /* @@ -1493,84 +536,22 @@ -------------------------------------------------------- */ - __normal_call void_type _pop_tri4 ( + __inline_call void_type _pop_tri4 ( iptr_type const*_nptr, - iptr_type _itop = -1 + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag ) { - iptr_type _tpos = -1 ; - - iptr_type _node[4]; - _node[0] = _nptr[0]; - _node[1] = _nptr[1]; - _node[2] = _nptr[2]; - _node[3] = _nptr[3]; - - /*-------------------------- find current 3-tria pos. */ - if ( !find_tri4 (_node, _tpos)) - { - return ; - } - - /*-------------------------- _pop current 3-tria data */ - _pop_tri4(_tpos, _itop) ; + mesh::_pop_tri4(*this, _nptr, _itop, _kind) ; } - __normal_call void_type _pop_tri4 ( + __inline_call void_type _pop_tri4 ( iptr_type _tpos , - iptr_type _itop = -1 + iptr_type _itop = -1 , + char_type _kind = EMPTY_tag ) { - iptr_type _fpos = -1 ; - - if (_itop != -1) - { - /*---- deleteing (d+k)-face: scan adj. and _pop _itop */ - _pop_list( - this->_adj4, _tpos, _itop); - } - else - { - /*---- deleting (d+0)-face: set "self" marker to null */ - this-> - _set4[_tpos].self() = 0 ; - } - - if (null_tri4 (_tpos)) - { - /*---- ref. count: delete (d+0), (d-1)-faces if empty */ - - iptr_type _same ; - this->_map4._pop(_tpos, _same); - - iptr_type _node [ 4] ; - _node[0] = this-> - _set4[_tpos].node(0) ; - _node[1] = this-> - _set4[_tpos].node(1) ; - _node[2] = this-> - _set4[_tpos].node(2) ; - _node[3] = this-> - _set4[_tpos].node(3) ; - - _put_tri4(_tpos); - - for (_fpos = 4; _fpos-- != 0; ) - { - iptr_type _fnod [4] ; - tri4_type::face_node ( - _fnod, _fpos, 3, 2) ; - - _fnod[0] = - _node[_fnod [0]]; - _fnod[1] = - _node[_fnod [1]]; - _fnod[2] = - _node[_fnod [2]]; - - _pop_tri3(_fnod, _tpos) ; - } - } + mesh::_pop_tri4(*this, _tpos, _itop, _kind) ; } /* @@ -1579,28 +560,12 @@ -------------------------------------------------------- */ - __normal_call bool_type find_node ( + __inline_call bool_type find_node ( iptr_type const*_nptr , iptr_type&_npos ) const { - /*-------------------------- find current 0-node pos. */ - iptr_type _node = *_nptr ; - - if (_node >= +0 && _node < - (iptr_type)this->_set1.count() && - _set1 [_node].mark() >= +0) - { - /*------------------------------- found matching node */ - _npos =_node ; - - return true ; - } - else - { - /*------------------------------- couldn't find match */ - return false ; - } + return mesh::find_node(*this, _nptr, _npos) ; } /* @@ -1609,38 +574,12 @@ -------------------------------------------------------- */ - __normal_call bool_type find_edge ( + __inline_call bool_type find_edge ( iptr_type const*_node , iptr_type&_epos ) { - /*-------------------------- find current 1-edge pos. */ - iptr_type _ipos = _get_edge() ; - - this-> - _set2[_ipos].node(0)=_node[0]; - this-> - _set2[_ipos].node(1)=_node[1]; - - typename edge_maps::_write_it - _same ; - if (this-> - _map2.find(_ipos, _same)) - { - /*------------------------------- found matching face */ - _put_edge(_ipos) ; - - _epos=*_same ; - - return true ; - } - else - { - /*------------------------------- couldn't find match */ - _put_edge(_ipos) ; - - return false ; - } + return mesh::find_edge(*this, _node, _epos) ; } /* @@ -1649,40 +588,12 @@ -------------------------------------------------------- */ - __normal_call bool_type find_tri3 ( + __inline_call bool_type find_tri3 ( iptr_type const*_node , iptr_type&_tpos ) { - /*-------------------------- find current 2-tria pos. */ - iptr_type _ipos = _get_tri3() ; - - this-> - _set3[_ipos].node(0)=_node[0]; - this-> - _set3[_ipos].node(1)=_node[1]; - this-> - _set3[_ipos].node(2)=_node[2]; - - typename tri3_maps::_write_it - _same ; - if (this-> - _map3.find(_ipos, _same)) - { - /*------------------------------- found matching face */ - _put_tri3(_ipos) ; - - _tpos=*_same ; - - return true ; - } - else - { - /*------------------------------- couldn't find match */ - _put_tri3(_ipos) ; - - return false ; - } + return mesh::find_tri3(*this, _node, _tpos) ; } /* @@ -1691,555 +602,106 @@ -------------------------------------------------------- */ - __normal_call bool_type find_tri4 ( + __inline_call bool_type find_tri4 ( iptr_type const*_node , iptr_type&_tpos ) { - /*-------------------------- find current 2-tria pos. */ - iptr_type _ipos = _get_tri4() ; - - this-> - _set4[_ipos].node(0)=_node[0]; - this-> - _set4[_ipos].node(1)=_node[1]; - this-> - _set4[_ipos].node(2)=_node[2]; - this-> - _set4[_ipos].node(3)=_node[3]; - - typename tri4_maps::_write_it - _same ; - if (this-> - _map4.find(_ipos, _same)) - { - /*------------------------------- found matching face */ - _put_tri4(_ipos) ; - - _tpos=*_same ; - - return true ; - } - else - { - /*------------------------------- couldn't find match */ - _put_tri4(_ipos) ; - - return false ; - } + return mesh::find_tri4(*this, _node, _tpos) ; } - /* -------------------------------------------------------- - * NODE-EDGE: form node-to-edge adj. list. + * FIND-CELL: return index of assoc. k-cell. -------------------------------------------------------- */ - template < - typename list_type - > - __inline_call void_type node_edge ( + __inline_call bool_type find_cell ( iptr_type const*_node , - list_type&_conn + char_type _kind , + iptr_type&_ipos ) { - node_edge(_node [ 0], _conn) ; - } - - template < - typename list_type - > - __normal_call void_type node_edge ( - iptr_type _npos, - list_type&_conn - ) - { - this->_tmp1.set_count( +0 ) ; - this->_tmp2.set_count( +0 ) ; - this->_tmp3.set_count( +0 ) ; - this->_tmp4.set_count( +0 ) ; - - this->_tmp1.push_tail(_npos) ; - - /*-------------------------- find set of adj. 1-edges */ - for (auto _iter = this->_tmp1.head(); - _iter != this->_tmp1.tend(); - ++_iter ) - { - for (auto _iadj = - this->_adj1.head(*_iter) ; - _iadj != - this->_adj1.tend(*_iter) ; - ++_iadj ) - { - if (this-> - _set2[*_iadj].mark() == 0) - { - _conn.push_tail (*_iadj); - this-> - _set2[*_iadj].mark() += 1; - } - } - } - - /*-------------------------- flip d-face marker lists */ - for (auto _iter = _conn.head() ; - _iter != _conn.tend() ; - ++_iter ) - { - this->_set2 [*_iter].mark() = +0; - } - } - - /* - -------------------------------------------------------- - * NODE-TRI3: form node-to-tria adj. list. - -------------------------------------------------------- - */ - - template < - typename list_type - > - __inline_call void_type node_tri3 ( - iptr_type const*_node , - list_type&_conn - ) - { - node_tri3(_node [ 0], _conn) ; - } - - template < - typename list_type - > - __normal_call void_type node_tri3 ( - iptr_type _npos, - list_type&_conn - ) - { - this->_tmp1.set_count( +0 ) ; - this->_tmp2.set_count( +0 ) ; - this->_tmp3.set_count( +0 ) ; - this->_tmp4.set_count( +0 ) ; - - this->_tmp1.push_tail(_npos) ; - - /*-------------------------- find set of adj. 1-edges */ - for (auto _iter = this->_tmp1.head(); - _iter != this->_tmp1.tend(); - ++_iter ) - { - for (auto _iadj = - this->_adj1.head(*_iter) ; - _iadj != - this->_adj1.tend(*_iter) ; - ++_iadj ) - { - if (this-> - _set2[*_iadj].mark() == 0) - { - this-> - _tmp2.push_tail (*_iadj); - this-> - _set2[*_iadj].mark() += 1; - } - } - } - /*-------------------------- find set of adj. 2-trias */ - for (auto _iter = this->_tmp2.head(); - _iter != this->_tmp2.tend(); - ++_iter ) - { - for (auto _iadj = - this->_adj2.head(*_iter) ; - _iadj != - this->_adj2.tend(*_iter) ; - ++_iadj ) - { - if (this-> - _set3[*_iadj].mark() == 0) - { - _conn.push_tail (*_iadj); - this-> - _set3[*_iadj].mark() += 1; - } - } - } - - /*-------------------------- flip d-face marker lists */ - for (auto _iter = _conn.head() ; - _iter != _conn.tend() ; - ++_iter ) - { - this->_set3 [*_iter].mark() = 0 ; - } - for (auto _iter = this-> - _tmp2.head() ; - _iter != this-> - _tmp2.tend() ; - ++_iter ) - { - this->_set2 [*_iter].mark() = 0 ; - } - } - - /* - -------------------------------------------------------- - * NODE-TRI4: form node-to-tria adj. list. - -------------------------------------------------------- - */ - - template < - typename list_type - > - __inline_call void_type node_tri4 ( - iptr_type const*_node , - list_type&_conn - ) - { - node_tri4(_node [ 0], _conn) ; - } - - template < - typename list_type - > - __normal_call void_type node_tri4 ( - iptr_type _npos, - list_type&_conn - ) - { - this->_tmp1.set_count( +0 ) ; - this->_tmp2.set_count( +0 ) ; - this->_tmp3.set_count( +0 ) ; - this->_tmp4.set_count( +0 ) ; - - this->_tmp1.push_tail(_npos) ; - - /*-------------------------- find set of adj. 1-edges */ - for (auto _iter = this->_tmp1.head(); - _iter != this->_tmp1.tend(); - ++_iter ) - { - for (auto _iadj = - this->_adj1.head(*_iter) ; - _iadj != - this->_adj1.tend(*_iter) ; - ++_iadj ) - { - if (this-> - _set2[*_iadj].mark() == 0) - { - this-> - _tmp2.push_tail (*_iadj); - this-> - _set2[*_iadj].mark() += 1; - } - } - } - /*-------------------------- find set of adj. 2-trias */ - for (auto _iter = this->_tmp2.head(); - _iter != this->_tmp2.tend(); - ++_iter ) - { - for (auto _iadj = - this->_adj2.head(*_iter) ; - _iadj != - this->_adj2.tend(*_iter) ; - ++_iadj ) - { - if (this-> - _set3[*_iadj].mark() == 0) - { - this-> - _tmp3.push_tail (*_iadj); - this-> - _set3[*_iadj].mark() += 1; - } - } - } - /*-------------------------- find set of adj. 3-trias */ - for (auto _iter = this->_tmp3.head(); - _iter != this->_tmp3.tend(); - ++_iter ) - { - for (auto _iadj = - this->_adj3.head(*_iter) ; - _iadj != - this->_adj3.tend(*_iter) ; - ++_iadj ) - { - if (this-> - _set4[*_iadj].mark() == 0) - { - _conn.push_tail (*_iadj); - this-> - _set4[*_iadj].mark() += 1; - } - } - } - - /*-------------------------- flip d-face marker lists */ - for (auto _iter = _conn.head() ; - _iter != _conn.tend() ; - ++_iter ) - { - this->_set4 [*_iter].mark() = 0 ; - } - for (auto _iter = this-> - _tmp3.head() ; - _iter != this-> - _tmp3.tend() ; - ++_iter ) - { - this->_set3 [*_iter].mark() = 0 ; - } - for (auto _iter = this-> - _tmp2.head() ; - _iter != this-> - _tmp2.tend() ; - ++_iter ) - { - this->_set2 [*_iter].mark() = 0 ; - } + return mesh::find_cell( + *this, _node, _kind, _ipos, tria_cell()) ; } /* -------------------------------------------------------- - * EDGE-TRI3: form edge-to-tria adj. list. + * CONNECT-1: form this-to-1-cell adj. list. -------------------------------------------------------- */ - template < - typename list_type - > - __inline_call void_type edge_tri3 ( + __inline_call void_type connect_1 ( iptr_type const*_node , - list_type&_conn + char_type _kind , + connector&_conn ) { - /*-------------------------- find current 1-edge pos. */ - iptr_type _epos = -1; - if (!find_edge(_node, _epos)) - { - return ; - } - - /*-------------------------- get adj. for 1-edge pos. */ - edge_tri3(_epos, _conn) ; + mesh::connect_1( + *this, _node, _kind, _conn, tria_cell()) ; } - template < - typename list_type - > - __normal_call void_type edge_tri3 ( - iptr_type _epos, - list_type&_conn + __inline_call void_type connect_1 ( + iptr_type _ipos , + char_type _kind , + connector&_conn ) { - this->_tmp1.set_count( +0 ) ; - this->_tmp2.set_count( +0 ) ; - this->_tmp3.set_count( +0 ) ; - this->_tmp4.set_count( +0 ) ; - - this->_tmp2.push_tail(_epos) ; - - /*-------------------------- find set of adj. 2-faces */ - for (auto _iter = this->_tmp2.head(); - _iter != this->_tmp2.tend(); - ++_iter ) - { - for (auto _iadj = - this->_adj2.head(*_iter) ; - _iadj != - this->_adj2.tend(*_iter) ; - ++_iadj ) - { - if (this-> - _set3[*_iadj].mark() == 0) - { - _conn.push_tail (*_iadj); - this-> - _set3[*_iadj].mark() += 1; - } - } - } - - /*-------------------------- flip d-face marker lists */ - for (auto _iter = _conn.head() ; - _iter != _conn.tend() ; - ++_iter ) - { - this->_set3 [*_iter].mark() = 0 ; - } + mesh::connect_1( + *this, _ipos, _kind, _conn, tria_cell()) ; } /* -------------------------------------------------------- - * EDGE-TRI4: form edge-to-tria adj. list. + * CONNECT-2: form this-to-2-cell adj. list. -------------------------------------------------------- */ - template < - typename list_type - > - __inline_call void_type edge_tri4 ( + __inline_call void_type connect_2 ( iptr_type const*_node , - list_type&_conn + char_type _kind , + connector&_conn ) { - /*-------------------------- find current 1-edge pos. */ - iptr_type _epos = -1; - if (!find_edge(_node, _epos)) - { - return ; - } - - /*-------------------------- get adj. for 1-edge pos. */ - edge_tri4(_epos, _conn) ; + mesh::connect_2( + *this, _node, _kind, _conn, tria_cell()) ; } - template < - typename list_type - > - __normal_call void_type edge_tri4 ( - iptr_type _epos, - list_type&_conn + __inline_call void_type connect_2 ( + iptr_type _ipos , + char_type _kind , + connector&_conn ) { - this->_tmp1.set_count( +0 ) ; - this->_tmp2.set_count( +0 ) ; - this->_tmp3.set_count( +0 ) ; - this->_tmp4.set_count( +0 ) ; - - this->_tmp2.push_tail(_epos) ; - - /*-------------------------- find set of adj. 2-faces */ - for (auto _iter = this->_tmp2.head(); - _iter != this->_tmp2.tend(); - ++_iter ) - { - for (auto _iadj = - this->_adj2.head(*_iter) ; - _iadj != - this->_adj2.tend(*_iter) ; - ++_iadj ) - { - if (this-> - _set3[*_iadj].mark() == 0) - { - this-> - _tmp3.push_tail (*_iadj); - this-> - _set3[*_iadj].mark() += 1; - } - } - } - /*-------------------------- find set of adj. 3-faces */ - for (auto _iter = this->_tmp3.head(); - _iter != this->_tmp3.tend(); - ++_iter ) - { - for (auto _iadj = - this->_adj3.head(*_iter) ; - _iadj != - this->_adj3.tend(*_iter) ; - ++_iadj ) - { - if (this-> - _set4[*_iadj].mark() == 0) - { - _conn.push_tail (*_iadj); - this-> - _set4[*_iadj].mark() += 1; - } - } - } - - /*-------------------------- flip d-face marker lists */ - for (auto _iter = _conn.head() ; - _iter != _conn.tend() ; - ++_iter ) - { - this->_set4 [*_iter].mark() = 0 ; - } - for (auto _iter = this-> - _tmp3.head() ; - _iter != this-> - _tmp3.tend() ; - ++_iter ) - { - this->_set3 [*_iter].mark() = 0 ; - } + mesh::connect_2( + *this, _ipos, _kind, _conn, tria_cell()) ; } /* -------------------------------------------------------- - * TRI3-TRI4: form tria-to-tria adj. list. + * CONNECT-3: form this-to-3-cell adj. list. -------------------------------------------------------- */ - template < - typename list_type - > - __inline_call void_type tri3_tri4 ( + __inline_call void_type connect_3 ( iptr_type const*_node , - list_type&_conn + char_type _kind , + connector&_conn ) { - /*-------------------------- find current 1-edge pos. */ - iptr_type _tpos = -1; - if (!find_tri3(_node, _tpos)) - { - return ; - } - - /*-------------------------- get adj. for 1-edge pos. */ - tri3_tri4(_tpos, _conn) ; + mesh::connect_3( + *this, _node, _kind, _conn, tria_cell()) ; } - template < - typename list_type - > - __normal_call void_type tri3_tri4 ( - iptr_type _epos, - list_type&_conn + __inline_call void_type connect_3 ( + iptr_type _ipos , + char_type _kind , + connector&_conn ) { - this->_tmp1.set_count( +0 ) ; - this->_tmp2.set_count( +0 ) ; - this->_tmp3.set_count( +0 ) ; - this->_tmp4.set_count( +0 ) ; - - this->_tmp3.push_tail(_epos) ; - - /*-------------------------- find set of adj. 2-faces */ - for (auto _iter = this->_tmp3.head(); - _iter != this->_tmp3.tend(); - ++_iter ) - { - for (auto _iadj = - this->_adj3.head(*_iter) ; - _iadj != - this->_adj3.tend(*_iter) ; - ++_iadj ) - { - if (this-> - _set4[*_iadj].mark() == 0) - { - _conn.push_tail (*_iadj); - this-> - _set4[*_iadj].mark() += 1; - } - } - } - - /*-------------------------- flip d-face marker lists */ - for (auto _iter = _conn.head() ; - _iter != _conn.tend() ; - ++_iter ) - { - this->_set4 [*_iter].mark() = 0 ; - } + mesh::connect_3( + *this, _ipos, _kind, _conn, tria_cell()) ; } } ; diff --git a/src/libcpp/meshfunc.hpp b/src/libcpp/meshfunc.hpp index dbe1078..bb5bfbe 100644 --- a/src/libcpp/meshfunc.hpp +++ b/src/libcpp/meshfunc.hpp @@ -35,7 +35,7 @@ * * Copyright 2013-2019 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * ------------------------------------------------------------ diff --git a/src/libcpp/meshtype.hpp b/src/libcpp/meshtype.hpp index a06cc68..fcf5faf 100644 --- a/src/libcpp/meshtype.hpp +++ b/src/libcpp/meshtype.hpp @@ -31,11 +31,11 @@ * ------------------------------------------------------------ * - * Last updated: 08 December, 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/ * ------------------------------------------------------------ @@ -49,15 +49,15 @@ namespace mesh { /*-------------------------- classification of mesh cells */ - char_type EMPTY_tag = +0 ; - char_type POINT_tag = 10 ; - char_type EDGE2_tag = 20 ; - char_type TRIA3_tag = 30 ; - char_type QUAD4_tag = 40 ; - char_type TRIA4_tag = 50 ; - char_type HEXA8_tag = 60 ; - char_type WEDG6_tag = 70 ; - char_type PYRA5_tag = 80 ; + char_type constexpr EMPTY_tag = +0 ; + char_type constexpr POINT_tag = 10 ; + char_type constexpr EDGE2_tag = 20 ; + char_type constexpr TRIA3_tag = 30 ; + char_type constexpr QUAD4_tag = 40 ; + char_type constexpr TRIA4_tag = 50 ; + char_type constexpr HEXA8_tag = 60 ; + char_type constexpr WEDG6_tag = 70 ; + char_type constexpr PYRA5_tag = 80 ; } # include "containers.hpp" @@ -66,10 +66,17 @@ # include "mesh_type/mesh_complex_type_k.hpp" +# include "mesh_type/hash_complex_k.hpp" +# include "mesh_type/base_complex_k.hpp" + # include "mesh_type/tria_complex_1.hpp" # include "mesh_type/tria_complex_2.hpp" # include "mesh_type/tria_complex_3.hpp" +# include "mesh_type/mesh_complex_1.hpp" +# include "mesh_type/mesh_complex_2.hpp" +# include "mesh_type/mesh_complex_3.hpp" + # endif//__MESHTYPE__ diff --git a/src/libcpp/mp_floats/dd_flt.hpp b/src/libcpp/mp_floats/dd_flt.hpp deleted file mode 100644 index 0d21bf1..0000000 --- a/src/libcpp/mp_floats/dd_flt.hpp +++ /dev/null @@ -1,451 +0,0 @@ - -/* ------------------------------------------------------------- - * (double-double)^1 precision data-type ------------------------------------------------------------- - */ - -#pragma once - -#ifndef __DD_FLT__ -#define __DD_FLT__ - -#include "dd_imp.hpp" - -class dd_flt ; - -__inline_call dd_flt operator + ( - dd_flt const&, - double ) ; -__inline_call dd_flt operator + ( - double , - dd_flt const&) ; -__inline_call dd_flt operator + ( - dd_flt const&, - dd_flt const&) ; - -__inline_call dd_flt operator - ( - dd_flt const&, - double ) ; -__inline_call dd_flt operator - ( - double , - dd_flt const&) ; -__inline_call dd_flt operator - ( - dd_flt const&, - dd_flt const&) ; - -__inline_call dd_flt operator * ( - dd_flt const&, - double ) ; -__inline_call dd_flt operator * ( - double , - dd_flt const&) ; -__inline_call dd_flt operator * ( - dd_flt const&, - dd_flt const&) ; - -__inline_call dd_flt operator / ( - dd_flt const&, - double ) ; -__inline_call dd_flt operator / ( - double , - dd_flt const&) ; -__inline_call dd_flt operator / ( - dd_flt const&, - dd_flt const&) ; - -class dd_flt - { - private : - double _xx[2] ; - - public : - __inline_call double& hi ( - ) - { return this->_xx[0] ; - } - __inline_call double& lo ( - ) - { return this->_xx[1] ; - } - __inline_call double const& hi ( - ) const - { return this->_xx[0] ; - } - __inline_call double const& lo ( - ) const - { return this->_xx[1] ; - } - - public : - __inline_call dd_flt ( - double _hi = double(+0.0) , - double _lo = double(+0.0) - ) - { this->_xx[0] = _hi ; - this->_xx[1] = _lo ; - } - - __inline_call dd_flt ( - double const* _dx - ) - { this->_xx[0] = _dx[0] ; - this->_xx[1] = _dx[1] ; - } - - __inline_call dd_flt ( - int _ii - ) - { this->_xx[0] =(double)_ii ; - this->_xx[1] = +0. ; - } - - - __inline_call dd_flt ( - dd_flt const& _aa - ) - { - this->_xx[0] = _aa.hi(); - this->_xx[1] = _aa.lo(); - } - - - __inline_call dd_flt& operator = ( - double _aa - ) - { - this->_xx[0] = _aa ; - this->_xx[1] = +0. ; - - return ( *this ) ; - } - __inline_call dd_flt& operator = ( - dd_flt const& _aa - ) - { - this->_xx[0] = _aa.hi(); - this->_xx[1] = _aa.lo(); - - return ( *this ) ; - } - - - __inline_call operator double ( - ) const - { return ( (double)(hi()+lo()) ) ; - } - __inline_call operator int ( - ) const - { return ( (int )(hi()+lo()) ) ; - } - - - __inline_call dd_flt operator + ( - ) const - { return dd_flt(+hi(), +lo()) ; - } - __inline_call dd_flt operator - ( - ) const - { return dd_flt(-hi(), -lo()) ; - } - - - __inline_call dd_flt& operator += ( - double _aa - ) - { - dd_flt _tt = *this + _aa ; - - hi() = _tt.hi(); - lo() = _tt.lo(); - - return ( *this ) ; - } - - __inline_call dd_flt& operator -= ( - double _aa - ) - { - dd_flt _tt = *this - _aa ; - - hi() = _tt.hi(); - lo() = _tt.lo(); - - return ( *this ) ; - } - - __inline_call dd_flt& operator *= ( - double _aa - ) - { - dd_flt _tt = *this * _aa ; - - hi() = _tt.hi(); - lo() = _tt.lo(); - - return ( *this ) ; - } - - __inline_call dd_flt& operator /= ( - double _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 ) ; - } - - __inline_call dd_flt& operator /= ( - dd_flt const& _aa - ) - { - dd_flt _tt = *this / _aa ; - - hi() = _tt.hi(); - lo() = _tt.lo(); - - return ( *this ) ; - } - - } ; - -// a+b - __inline_call dd_flt operator + ( - dd_flt const& _aa, - double _bb - ) - { - double _y0, _y1; - dd_imp::two_one_add ( - _aa.hi(), - _aa.lo(), - _bb, _y1, _y0 ) ; - - return dd_flt(_y1, _y0) ; - } - - __inline_call dd_flt operator + ( - double _aa, - dd_flt const& _bb - ) - { return ( _bb + _aa ) ; - } - - __inline_call dd_flt operator + ( - dd_flt const& _aa, - dd_flt const& _bb - ) - { - double _y0, _y1; - dd_imp::two_two_add ( - _aa.hi(), _aa.lo(), - _bb.hi(), _bb.lo(), - _y1, _y0) ; - - return dd_flt(_y1, _y0) ; - } - -// a-b - __inline_call dd_flt operator - ( - dd_flt const& _aa, - double _bb - ) - { - double _y0, _y1; - dd_imp::two_one_sub ( - _aa.hi(), - _aa.lo(), - _bb, _y1, _y0 ) ; - - return dd_flt(_y1, _y0) ; - } - - __inline_call dd_flt operator - ( - double _aa, - dd_flt const& _bb - ) - { - double _y0, _y1; - dd_imp::one_two_sub (_aa, - _bb.hi(), - _bb.lo(), - _y1, _y0 ) ; - - return dd_flt(_y1, _y0) ; - } - - __inline_call dd_flt operator - ( - dd_flt const& _aa, - dd_flt const& _bb - ) - { - double _y0, _y1; - dd_imp::two_two_sub ( - _aa.hi(), _aa.lo(), - _bb.hi(), _bb.lo(), - _y1, _y0) ; - - return dd_flt(_y1, _y0) ; - } - -// a * b - __inline_call dd_flt operator * ( - dd_flt const& _aa, - double _bb - ) - { - double _y0, _y1; - dd_imp::two_one_mul ( - _aa.hi(), - _aa.lo(), - _bb, _y1, _y0 ) ; - - return dd_flt(_y1, _y0) ; - } - - __inline_call dd_flt operator * ( - double _aa, - dd_flt const& _bb - ) - { return ( _bb * _aa ) ; - } - - __inline_call dd_flt operator * ( - dd_flt const& _aa, - dd_flt const& _bb - ) - { - double _y0, _y1; - dd_imp::two_two_mul ( - _aa.hi(), _aa.lo(), - _bb.hi(), _bb.lo(), - _y1, _y0) ; - - return dd_flt(_y1, _y0) ; - } - -// a / b - __inline_call dd_flt operator / ( - dd_flt const& _aa, - double _bb - ) - { return ( _aa / dd_flt(_bb) ) ; - } - - __inline_call dd_flt operator / ( - double _aa, - dd_flt const& _bb - ) - { return ( dd_flt(_aa) / _bb ) ; - } - - __inline_call dd_flt operator / ( - dd_flt const& _aa, - dd_flt const& _bb - ) - { - double _y0, _y1; - dd_imp::two_two_div ( - _aa.hi(), _aa.lo(), - _bb.hi(), _bb.lo(), - _y1, _y0) ; - - return dd_flt(_y1, _y0) ; - } - - - __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() ; - } - - __inline_call bool operator <= ( - dd_flt const& _aa, - dd_flt const& _bb - ) - { return _aa.hi() == _bb.hi() ? - _aa.lo() <= _bb.lo() : - _aa.hi() <= _bb.hi() ; - } - - __inline_call bool operator >= ( - dd_flt const& _aa, - dd_flt const& _bb - ) - { return _aa.hi() == _bb.hi() ? - _aa.lo() >= _bb.lo() : - _aa.hi() >= _bb.hi() ; - } - -#endif//__DD_FLT__ - - diff --git a/src/libcpp/mp_floats/dd_imp.hpp b/src/libcpp/mp_floats/dd_imp.hpp deleted file mode 100644 index f135e9b..0000000 --- a/src/libcpp/mp_floats/dd_imp.hpp +++ /dev/null @@ -1,350 +0,0 @@ - - -/* ------------------------------------------------------------- - double-double precision arithmetic ------------------------------------------------------------- - */ - -class dd_imp - { - public : - typedef double word ; - - public : - __static_call - __inline_call void_type one_one_add_fast ( - word _aa , - word _bb , - word& _yy , - word& _er - ) - { - _yy = _aa + _bb ; - _er = _yy - _aa ; - _er = _bb - _er ; - } - - __static_call - __inline_call void_type one_one_sub_fast ( - word _aa , - word _bb , - word& _yy , - word& _er - ) - { - _yy = _aa - _bb ; - _er = _aa - _yy ; - _er = _er - _bb ; - } - - __static_call - __inline_call void_type one_one_add_full ( - word _aa , - word _bb , - word& _yy , - word& _er - ) - { - _yy = _aa + _bb ; - - word _t0 , _t1 ; - _t0 = _yy - _aa ; - _t1 = _yy - _t0 ; - - word _t2 , _t3 ; - _t2 = _aa - _t1 ; - _t3 = _bb - _t0 ; - - _er = _t2 + _t3 ; - } - - __static_call - __inline_call void_type one_one_sub_full ( - word _aa , - word _bb , - word& _yy , - word& _er - ) - { - _yy = _aa - _bb ; - - word _t0 , _t1 ; - _t0 = _yy - _aa ; - _t1 = _yy - _t0 ; - - word _t2 , _t3 ; - _t2 = _aa - _t1 ; - _t3 = _bb + _t0 ; - - _er = _t2 - _t3 ; - } - - __static_call - __inline_call void_type one_split ( - word _aa , - word& _a1 , - word& _a0 - ) - { - if (_aa > +6.69692879491417E+299 || - _aa < -6.69692879491417E+299 ) - { - word _tt , _ss ; - _aa*= +3.7252902984619140625E-09 ; - _tt = _aa * 134217729.0 ; - _ss = _tt - _aa ; - _a1 = _tt - _ss ; - _a0 = _aa - _a1 ; - _a1*= 268435456.0 ; - _a0*= 268435456.0 ; - } - else - { - word _tt , _ss ; - _tt = _aa * 134217729.0 ; - _ss = _tt - _aa ; - _a1 = _tt - _ss ; - _a0 = _aa - _a1 ; - } - } - - __static_call - __inline_call void_type one_one_mul_full ( - word _aa , - word _bb , - word& _y1 , - word& _y0 - ) - { - word _a1, _a0, _b1, _b0 ; - one_split(_aa, _a1, _a0); - one_split(_bb, _b1, _b0); - - _y1 = _aa * _bb ; - - word _e1, _e2, _e3 ; - _e1 = _y1 - (_a1 * _b1) ; - _e2 = _e1 - (_a0 * _b1) ; - _e3 = _e2 - (_a1 * _b0) ; - - _y0 = (_a0 * _b0) - _e3 ; - - } - - __static_call - __inline_call void_type two_one_add ( - word _a1 , - word _a0 , - word _bb , - word& _y1 , - word& _y0 - ) - { - word _t0, _t1 ; - one_one_add_full ( - _a1, _bb, - _t1, _t0) ; - - _t0 += _a0 ; - one_one_add_fast ( - _t1, _t0, - _y1, _y0) ; - } - - __static_call - __inline_call void_type two_one_sub ( - word _a1 , - word _a0 , - word _bb , - word& _y1 , - word& _y0 - ) - { - word _t0, _t1 ; - one_one_sub_full ( - _a1, _bb, - _t1, _t0) ; - - _t0 += _a0 ; - one_one_add_fast ( - _t1, _t0, - _y1, _y0) ; - } - - __static_call - __inline_call void_type one_two_sub ( - word _aa , - word _b1 , - word _b0 , - word& _y1 , - word& _y0 - ) - { - word _t0, _t1 ; - one_one_sub_full ( - _aa, _b1, - _t1, _t0) ; - - _t0 -= _b0 ; - one_one_add_fast ( - _t1, _t0, - _y1, _y0) ; - } - - __static_call - __inline_call void_type two_two_add ( - word _a1 , - word _a0 , - word _b1 , - word _b0 , - word& _y1 , - word& _y0 - ) - { - word _s0, _s1 ; - word _t0, _t1 ; - word _w0, _w1 ; - one_one_add_full ( - _a1, _b1, - _s1, _s0) ; - one_one_add_full ( - _a0, _b0, - _t1, _t0) ; - - _s0 += _t1; - one_one_add_fast ( - _s1, _s0, - _w1, _w0) ; - - _w0 += _t0; - one_one_add_fast ( - _w1, _w0, - _y1, _y0) ; - } - - __static_call - __inline_call void_type two_two_sub ( - word _a1 , - word _a0 , - word _b1 , - word _b0 , - word& _y1 , - word& _y0 - ) - { - word _s0, _s1 ; - word _t0, _t1 ; - word _w0, _w1 ; - one_one_sub_full ( - _a1, _b1, - _s1, _s0) ; - one_one_sub_full ( - _a0, _b0, - _t1, _t0) ; - - _s0 += _t1; - one_one_add_fast ( - _s1, _s0, - _w1, _w0) ; - - _w0 += _t0; - one_one_add_fast ( - _w1, _w0, - _y1, _y0) ; - } - - __static_call - __inline_call void_type two_one_mul ( - word _a1 , - word _a0 , - word _bb , - word& _y1 , - word& _y0 - ) - { - word _t0, _t1, _ss ; - one_one_mul_full ( - _a1, _bb, - _t1, _t0) ; - - _ss = _a0 * _bb ; - _t0 = _t0 + _ss ; - - one_one_add_fast ( - _t1, _t0, - _y1, _y0) ; - } - - __static_call - __inline_call void_type two_two_mul ( - word _a1 , - word _a0 , - word _b1 , - word _b0 , - word& _y1 , - word& _y0 - ) - { - word _t0, _t1, _ss ; - one_one_mul_full ( - _a1, _b1, - _t1, _t0) ; - - _ss = _a1 * _b0 + - _a0 * _b1 ; - _t0 = _t0 + _ss ; - - one_one_add_fast ( - _t1, _t0, - _y1, _y0) ; - } - - __static_call - __inline_call void_type two_two_div ( - word _a1 , - word _a0 , - word _b1 , - word _b0 , - word& _y1 , - word& _y0 - ) - { - word _t0 , _t1 , _ee ; - _t1 = _a1 / _b1 ; - - word _r0 , _r1 ; - word _w0 , _w1 ; - two_one_mul(_b1, _b0, // rr = bb * t1 - _t1, - _r1, _r0) ; - - two_two_sub(_a1, _a0, // ww = aa - rr - _r1, _r0, - _w1, _w0) ; - - _t0 = _w1 / _b1 ; - - word _u0 , _u1 ; - two_one_mul(_b1, _b0, // rr = bb * t0 - _t0, - _r1, _r0) ; - two_two_sub(_w1, _w0, // uu = ww - rr - _r1, _r0, - _u1, _u0) ; - - _ee = _u1 / _b1 ; - - word _q0 , _q1 ; - one_one_add_fast(_t1, _t0, _q1, _q0); - - two_one_add(_q1, _q0, - _ee, - _t1, _t0) ; - - _y1 = _t1; _y0 = _t0; - } - - } ; - - diff --git a/src/libcpp/mp_floats/mp_imp.hpp b/src/libcpp/mp_floats/mp_imp.hpp deleted file mode 100644 index 868e5f7..0000000 --- a/src/libcpp/mp_floats/mp_imp.hpp +++ /dev/null @@ -1,355 +0,0 @@ - -/* ------------------------------------------------------------- - multi-double precision arithmetic ------------------------------------------------------------- - */ - -class mp_imp - { - public : - typedef double word ; - - public : - - __static_call - __inline_call void_type one_one_add_full ( - word _aa , - word _bb , - word& _y0 , - word& _y1 - ) - { - _y0 = _aa + _bb ; - - word _t0 , _t1 ; - _t0 = _y0 - _aa ; - _t1 = _y0 - _t0 ; - - word _t2 , _t3 ; - _t2 = _aa - _t1 ; - _t3 = _bb - _t0 ; - - _y1 = _t2 + _t3 ; - } - - __static_call - __inline_call void_type one_one_sub_full ( - word _aa , - word _bb , - word& _y0 , - word& _y1 - ) - { - _y0 = _aa - _bb ; - - word _t0 , _t1 ; - _t0 = _y0 - _aa ; - _t1 = _y0 - _t0 ; - - word _t2 , _t3 ; - _t2 = _aa - _t1 ; - _t3 = _bb + _t0 ; - - _y1 = _t2 - _t3 ; - } - - __static_call - __inline_call void_type one_split ( - word _aa , - word& _a0 , - word& _a1 - ) - { - if (_aa > +6.69692879491417E+299 || - _aa < -6.69692879491417E+299 ) - { - word _tt , _ss ; - _aa*= - + 3.7252902984619140625E-09 ; - _tt = _aa * 134217729.0 ; - _ss = _tt - _aa ; - _a0 = _tt - _ss ; - _a1 = _aa - _a0 ; - _a0*= 268435456.0 ; - _a1*= 268435456.0 ; - } - else - { - word _tt , _ss ; - _tt = _aa * 134217729.0 ; - _ss = _tt - _aa ; - _a0 = _tt - _ss ; - _a1 = _aa - _a0 ; - } - } - - __static_call - __inline_call void_type one_one_mul_full ( - word _aa , - word _bb , - word& _y1 , - word& _y0 - ) - { - word _a1, _a0, _b1, _b0 ; - one_split(_aa, _a0, _a1); - one_split(_bb, _b0, _b1); - - _y0 = _aa * _bb ; - - word _e1, _e2, _e3 ; - _e1 = _y0 - (_a0 * _b0) ; - _e2 = _e1 - (_a1 * _b0) ; - _e3 = _e2 - (_a0 * _b1) ; - - _y1 = (_a1 * _b1) - _e3 ; - } - - } ; - - - template < - size_t N - > - class mp_flt - { - public : - - double _dx[N] = {0.0} ; - size_t _dn = +0 ; - - } ; - - - template < - size_t X - > - __inline_call double mp_est ( - mp_flt const& _xx - ) - { - double _tt = +0.0 ; - size_t _ii ; - - for (_ii = _xx._dn; _ii-- != 0; ) - { - _tt += _xx._dx [_ii]; - } - return _tt ; - } - - template < - size_t X - > - __inline_call void_type mp_neg ( - mp_flt & _xx - ) - { - size_t _ii ; - - for (_ii = _xx._dn; _ii-- != 0; ) - { - _xx._dx[_ii] *= -1. ; - } - } - - template < - size_t X - > - __inline_call void_type mp_add ( - double _aa, - double _bb, - mp_flt & _xx - ) - { - size_t _nn = +2 ; - _nn = std::min (_nn, X) ; - - double _tt ; - - __assert( _nn <= X && - "MP-FLT: N out of range" ) ; - - _xx._dn = _nn ; - - if (_nn == 2) - mp_imp::one_one_add_full ( - _aa, _bb, - _xx._dx [ 0], - _xx._dx [ 1]) ; - else - if (_nn == 1) - mp_imp::one_one_add_full ( - _aa, _bb, - _xx._dx [ 0], - _tt ) ; - } - - template < - size_t A , - size_t X - > - __inline_call void_type mp_add ( - mp_flt
const& _aa, - double _bb, - mp_flt & _xx - ) - { - mp_add (_aa, _bb, +0, _xx) ; - } - - template < - size_t A , - size_t X - > - __inline_call void_type mp_add ( - mp_flt const& _aa, - double _bb, - size_t _ib, - mp_flt & _xx - ) - { - size_t _nn = _aa._dn+1 ; - _nn = std::min(_nn, X) ; - - __assert( _nn <= X && - "MP-FLT: N out of range" ) ; - - _xx._dn = _nn ; - - double _tt = +0.0 ; - size_t _ii ; - - for (_ii = _ib; _ii < _xx._dn-1; ++_ii) - { - mp_imp::one_one_add_full ( - _aa._dx[_ii], _bb, - _xx._dx[_ii], _tt) ; - - _bb = _tt ; - } - _xx._dx[_xx._dn - 1]= _tt ; - } - - template < - size_t A , - size_t B , - size_t X - > - __inline_call void_type mp_add ( - mp_flt const& _aa, - mp_flt const& _bb, - mp_flt & _xx - ) - { - mp_add(_aa, _bb._dx[ +0], +0, _xx) ; - - size_t _ii; - - for (_ii = 1; _ii < _bb._dn; ++_ii) - { - mp_add(_xx, _bb._dx[_ii], _ii, _xx) ; - } - } - - template < - size_t X - > - __inline_call void_type mp_sub ( - double _aa, - double _bb, - mp_flt & _xx - ) - { - size_t _nn = +2 ; - _nn = std::min (_nn, X) ; - - double _tt ; - - __assert( _nn <= X && - "MP-FLT: N out of range" ) ; - - _xx._dn = _nn ; - - if (_nn == 2) - mp_imp::one_one_sub_full ( - _aa, _bb, - _xx._dx [ 0], - _xx._dx [ 1]) ; - else - if (_nn == 1) - mp_imp::one_one_sub_full ( - _aa, _bb, - _xx._dx [ 0], - _tt ) ; - } - - template < - size_t A , - size_t X - > - __inline_call void_type mp_sub ( - mp_flt const& _aa, - double _bb, - mp_flt & _xx - ) - { - mp_sub (_aa, _bb, +0, _xx) ; - } - - template < - size_t A , - size_t X - > - __inline_call void_type mp_sub ( - mp_flt const& _aa, - double _bb, - size_t _ib, - mp_flt & _xx - ) - { - size_t _nn = _aa._dn+1 ; - _nn = std::min(_nn, X) ; - - __assert( _nn <= X && - "MP-FLT: N out of range" ) ; - - _xx._dn = _nn ; - - double _tt = +0.0 ; - size_t _ii ; - - for (_ii = _ib; _ii < _xx._dn-1; ++_ii) - { - mp_imp::one_one_sub_full ( - _aa._dx[_ii], _bb, - _xx._dx[_ii], _tt) ; - - _bb = _tt ; - } - _xx._dx[_xx._dn - 1]= _tt ; - } - - template < - size_t A , - size_t B , - size_t X - > - __inline_call void_type mp_sub ( - mp_flt const& _aa, - mp_flt const& _bb, - mp_flt & _xx - ) - { - mp_sub(_aa, _bb._dx[ +0], +0, _xx) ; - - size_t _ii; - - for (_ii = 1; _ii < _bb._dn; ++_ii) - { - mp_sub(_xx, _bb._dx[_ii], _ii, _xx) ; - } - } - - diff --git a/src/libcpp/mpfloats.hpp b/src/libcpp/mpfloats.hpp index 03f2aa1..df2a796 100644 --- a/src/libcpp/mpfloats.hpp +++ b/src/libcpp/mpfloats.hpp @@ -1,7 +1,7 @@ /* ------------------------------------------------------------ - * multi-precision floating-point data-types... + * robust multi-precision floating-point expansions... ------------------------------------------------------------ * * This program may be freely redistributed under the @@ -31,11 +31,11 @@ * ------------------------------------------------------------ * - * Last updated: 05 May, 2017 + * Last updated: 11 April, 2020 * - * Copyright 2013-2017 + * Copyright 2020-- * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * ------------------------------------------------------------ @@ -46,18 +46,25 @@ # ifndef __MP_FLOATS__ # define __MP_FLOATS__ -# include "libbasic.hpp" +# include "basebase.hpp" -# include "mp_floats/dd_flt.hpp" + namespace mp_float + { + typedef double real_type; + typedef int indx_type; + } - /* +# include +# include +# include -//!! to-do... +// pragma STDC FENV_ACCESS ON -# include "mp_floats/qd_flt.hpp" -# include "mp_floats/ap_flt.hpp" +# include "expansion/dd_float.hpp" +# include "expansion/ia_float.hpp" +# include "expansion/mp_float.hpp" - */ +# include "expansion/mp_utils.hpp" # endif//__MP_FLOATS__ diff --git a/src/libcpp/parameters/iter_params.hpp b/src/libcpp/parameters/iter_params.hpp index b41da9c..f8eb31d 100644 --- a/src/libcpp/parameters/iter_params.hpp +++ b/src/libcpp/parameters/iter_params.hpp @@ -35,7 +35,7 @@ * * Copyright 2013-2019 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- diff --git a/src/libcpp/parameters/mesh_params.hpp b/src/libcpp/parameters/mesh_params.hpp index 91b6a16..13794fe 100644 --- a/src/libcpp/parameters/mesh_params.hpp +++ b/src/libcpp/parameters/mesh_params.hpp @@ -35,7 +35,7 @@ * * Copyright 2013-2019 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- @@ -146,7 +146,7 @@ iptr_type _rule = +0 ; __setbit( _rule, offH_kind) ; __setbit( _rule, offC_kind) ; - //__setbit( _rule, offT_kind) ; + // __setbit( _rule, offT_kind) ; __setbit( _rule, sink_kind) ; return _rule ; diff --git a/src/libcpp/predicate/bisect_k.hpp b/src/libcpp/predicate/bisect_k.hpp new file mode 100644 index 0000000..d1504ea --- /dev/null +++ b/src/libcpp/predicate/bisect_k.hpp @@ -0,0 +1,966 @@ + + /* + -------------------------------------------------------- + * PREDICATE-k: robust geometric predicates in E^k. + -------------------------------------------------------- + * + * 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/ + * + -------------------------------------------------------- + */ + + // from predicate_k.hpp... + + + /* + -------------------------------------------------------- + * + * Compute an exact orientation wrt. bisector using + * multi-precision expansions, a'la shewchuk + * + * |c-a|**2 - wa = |c-b|**2 - wb + * + * This is the unweighted "bisect" predicate in E^2. + * + -------------------------------------------------------- + */ + + __normal_call REAL_TYPE bisect2d_e ( + __const_ptr(REAL_TYPE) _pa , + __const_ptr(REAL_TYPE) _pb , + __const_ptr(REAL_TYPE) _pc , + bool_type &_OK + ) + { + /*--------------- bisect2d predicate, "exact" version */ + mp::expansion< 2 > _ab_xx_, _ab_yy_, + _ac_xx_, _ac_yy_, + _bc_xx_, _bc_yy_; + mp::expansion< 4 > _tt_xx_, _tt_yy_; + mp::expansion< 32> _absum_; + + _OK = true; + + /*----------------------------------- compute: d(p,q) */ + _ab_xx_.from_sub(_pa[0], _pb[0]); + _ab_yy_.from_sub(_pa[1], _pb[1]); + + _ac_xx_.from_sub(_pa[0], _pc[0]); + _ac_yy_.from_sub(_pa[1], _pc[1]); + + _bc_xx_.from_sub(_pb[0], _pc[0]); + _bc_yy_.from_sub(_pb[1], _pc[1]); + + mp::expansion_add(_ac_xx_, _bc_xx_, + _tt_xx_) ; + mp::expansion_add(_ac_yy_, _bc_yy_, + _tt_yy_) ; + + mp::expansion_dot(_ab_xx_, _tt_xx_, + _ab_yy_, _tt_yy_, + _absum_) ; + + /*----------------------------------- return signed d */ + return mp::expansion_est(_absum_) ; + } + + __normal_call REAL_TYPE bisect2d_i ( + __const_ptr(REAL_TYPE) _pa , + __const_ptr(REAL_TYPE) _pb , + __const_ptr(REAL_TYPE) _pc , + bool_type &_OK + ) + { + /*--------------- bisect2d predicate, "bound" version */ + ia_flt _acx, _acy, + _bcx, _bcy, + _abx, _aby, _sgn; + + ia_rnd _rnd; // up rounding! + + _abx.from_sub(_pa[0], _pb[0]) ; // coord. diff. + _aby.from_sub(_pa[1], _pb[1]) ; + + _acx.from_sub(_pa[0], _pc[0]) ; + _acy.from_sub(_pa[1], _pc[1]) ; + + _bcx.from_sub(_pb[0], _pc[0]) ; + _bcy.from_sub(_pb[1], _pc[1]) ; + + _sgn = (_abx * (_acx + _bcx)) + + (_aby * (_acy + _bcy)) ; + + _OK = + _sgn.lo() >= (REAL_TYPE)0. + || _sgn.up() <= (REAL_TYPE)0. ; + + return ( _sgn.mid () ) ; + } + + __normal_call REAL_TYPE bisect2d_f ( + __const_ptr(REAL_TYPE) _pa , + __const_ptr(REAL_TYPE) _pb , + __const_ptr(REAL_TYPE) _pc , + bool_type &_OK + ) + { + /*--------------- bisect2d predicate, "float" version */ + REAL_TYPE static const _ER = + + 5. * std::pow(mp::_epsilon, 1) ; + + REAL_TYPE _acx, _acy; + REAL_TYPE _bcx, _bcy; + REAL_TYPE _acsqr, _bcsqr ; + + REAL_TYPE _sgn, _FT ; + + REAL_TYPE _ACSQR, _BCSQR ; + + _acx = _pa [0] - _pc [0] ; // coord. diff. + _acy = _pa [1] - _pc [1] ; + + _bcx = _pb [0] - _pc [0] ; + _bcy = _pb [1] - _pc [1] ; + + _acsqr = _acx * _acx + + _acy * _acy ; + _bcsqr = _bcx * _bcx + + _bcy * _bcy ; + + _ACSQR = std::abs(_acsqr); + _BCSQR = std::abs(_bcsqr); + + _FT = _ACSQR + _BCSQR ; // roundoff tol + _FT *= _ER ; + + _sgn = _acsqr - _bcsqr ; // d_ab - d_bc + + _OK = _sgn > +_FT || _sgn < -_FT ; + + return _sgn ; + } + + /* + -------------------------------------------------------- + * + * Compute an exact orientation wrt. bisector using + * multi-precision expansions, a'la shewchuk + * + * |c-a|**2 - wa = |c-b|**2 - wb + * + * This is the weighted "bisect" predicate in E^2. + * + -------------------------------------------------------- + */ + + __normal_call REAL_TYPE bisect2w_e ( + __const_ptr(REAL_TYPE) _pa , + __const_ptr(REAL_TYPE) _pb , + __const_ptr(REAL_TYPE) _pc , + bool_type &_OK + ) + { + /*--------------- bisect2w predicate, "exact" version */ + mp::expansion< 2 > _ab_xx_, _ab_yy_, + _ab_ww_, + _ac_xx_, _ac_yy_, + _bc_xx_, _bc_yy_; + mp::expansion< 4 > _tt_xx_, _tt_yy_; + mp::expansion< 32> _ttsum_; + mp::expansion< 34> _absum_; + + _OK = true; + + /*----------------------------------- compute: d(p,q) */ + _ab_xx_.from_sub(_pa[0], _pb[0]); + _ab_yy_.from_sub(_pa[1], _pb[1]); + _ab_ww_.from_sub(_pa[2], _pb[2]); + + _ac_xx_.from_sub(_pa[0], _pc[0]); + _ac_yy_.from_sub(_pa[1], _pc[1]); + + _bc_xx_.from_sub(_pb[0], _pc[0]); + _bc_yy_.from_sub(_pb[1], _pc[1]); + + mp::expansion_add(_ac_xx_, _bc_xx_, + _tt_xx_) ; + mp::expansion_add(_ac_yy_, _bc_yy_, + _tt_yy_) ; + + mp::expansion_dot(_ab_xx_, _tt_xx_, + _ab_yy_, _tt_yy_, + _ttsum_) ; + + mp::expansion_sub(_ttsum_, _ab_ww_, + _absum_) ; + + /*----------------------------------- return signed d */ + return mp::expansion_est(_absum_) ; + } + + __normal_call REAL_TYPE bisect2w_i ( + __const_ptr(REAL_TYPE) _pa , + __const_ptr(REAL_TYPE) _pb , + __const_ptr(REAL_TYPE) _pc , + bool_type &_OK + ) + { + /*--------------- bisect2w predicate, "bound" version */ + ia_flt _acx, _acy, _abw, + _bcx, _bcy, + _abx, _aby, _sgn; + + ia_rnd _rnd; // up rounding! + + _abx.from_sub(_pa[0], _pb[0]) ; // coord. diff. + _aby.from_sub(_pa[1], _pb[1]) ; + _abw.from_sub(_pa[2], _pb[2]) ; + + _acx.from_sub(_pa[0], _pc[0]) ; + _acy.from_sub(_pa[1], _pc[1]) ; + + _bcx.from_sub(_pb[0], _pc[0]) ; + _bcy.from_sub(_pb[1], _pc[1]) ; + + _sgn = (_abx * (_acx + _bcx)) + + (_aby * (_acy + _bcy)) ; + + _sgn-= _abw ; + + _OK = + _sgn.lo() >= (REAL_TYPE)0. + || _sgn.up() <= (REAL_TYPE)0. ; + + return ( _sgn.mid () ) ; + } + + __normal_call REAL_TYPE bisect2w_f ( + __const_ptr(REAL_TYPE) _pa , + __const_ptr(REAL_TYPE) _pb , + __const_ptr(REAL_TYPE) _pc , + bool_type &_OK + ) + { + /*--------------- bisect2w predicate, "float" version */ + REAL_TYPE static const _ER = + + 6. * std::pow(mp::_epsilon, 1) ; + + REAL_TYPE _acx, _acy; + REAL_TYPE _bcx, _bcy; + REAL_TYPE _acsqr, _bcsqr ; + REAL_TYPE _a_sum, _b_sum ; + + REAL_TYPE _A_SUM, _B_SUM ; + + REAL_TYPE _sgn, _FT; + + _acx = _pa [0] - _pc [0] ; // coord. diff. + _acy = _pa [1] - _pc [1] ; + + _bcx = _pb [0] - _pc [0] ; + _bcy = _pb [1] - _pc [1] ; + + _acsqr = _acx * _acx + + _acy * _acy ; + _bcsqr = _bcx * _bcx + + _bcy * _bcy ; + + _a_sum = _acsqr - _pa[2] ; + _b_sum = _bcsqr - _pb[2] ; + + _A_SUM = std::abs(_acsqr) + + std::abs(_pa[2]); + _B_SUM = std::abs(_bcsqr) + + std::abs(_pb[2]); + + _FT = _A_SUM + _B_SUM ; // roundoff tol + _FT *= _ER ; + + _sgn = _a_sum - _b_sum ; // d_ab - d_bc + + _OK = _sgn > +_FT || _sgn < -_FT ; + + return _sgn ; + } + + /* + -------------------------------------------------------- + * + * Compute an exact orientation wrt. bisector using + * multi-precision expansions, a'la shewchuk + * + * |c-a|**2 - wa = |c-b|**2 - wb + * + * This is the unweighted "bisect" predicate in E^3. + * + -------------------------------------------------------- + */ + + __normal_call REAL_TYPE bisect3d_e ( + __const_ptr(REAL_TYPE) _pa , + __const_ptr(REAL_TYPE) _pb , + __const_ptr(REAL_TYPE) _pc , + bool_type &_OK + ) + { + /*--------------- bisect3d predicate, "exact" version */ + mp::expansion< 2 > _ab_xx_, _ab_yy_, + _ab_zz_, + _ac_xx_, _ac_yy_, + _ac_zz_, + _bc_xx_, _bc_yy_, + _bc_zz_; + mp::expansion< 4 > _tt_xx_, _tt_yy_, + _tt_zz_; + mp::expansion< 48> _absum_; + + _OK = true; + + /*----------------------------------- compute: d(p,q) */ + _ab_xx_.from_sub(_pa[0], _pb[0]); + _ab_yy_.from_sub(_pa[1], _pb[1]); + _ab_zz_.from_sub(_pa[2], _pb[2]); + + _ac_xx_.from_sub(_pa[0], _pc[0]); + _ac_yy_.from_sub(_pa[1], _pc[1]); + _ac_zz_.from_sub(_pa[2], _pc[2]); + + _bc_xx_.from_sub(_pb[0], _pc[0]); + _bc_yy_.from_sub(_pb[1], _pc[1]); + _bc_zz_.from_sub(_pb[2], _pc[2]); + + mp::expansion_add(_ac_xx_, _bc_xx_, + _tt_xx_) ; + mp::expansion_add(_ac_yy_, _bc_yy_, + _tt_yy_) ; + mp::expansion_add(_ac_zz_, _bc_zz_, + _tt_zz_) ; + + mp::expansion_dot(_ab_xx_, _tt_xx_, + _ab_yy_, _tt_yy_, + _ab_zz_, _tt_zz_, + _absum_) ; + + /*----------------------------------- return signed d */ + return mp::expansion_est(_absum_) ; + } + + __normal_call REAL_TYPE bisect3d_i ( + __const_ptr(REAL_TYPE) _pa , + __const_ptr(REAL_TYPE) _pb , + __const_ptr(REAL_TYPE) _pc , + bool_type &_OK + ) + { + /*--------------- bisect3d predicate, "bound" version */ + ia_flt _acx, _acy, _acz , + _bcx, _bcy, _bcz , + _abx, _aby, _abz ; + ia_flt _sgn; + + ia_rnd _rnd; // up rounding! + + _abx.from_sub(_pa[0], _pb[0]) ; // coord. diff. + _aby.from_sub(_pa[1], _pb[1]) ; + _abz.from_sub(_pa[2], _pb[2]) ; + + _acx.from_sub(_pa[0], _pc[0]) ; + _acy.from_sub(_pa[1], _pc[1]) ; + _acz.from_sub(_pa[2], _pc[2]) ; + + _bcx.from_sub(_pb[0], _pc[0]) ; + _bcy.from_sub(_pb[1], _pc[1]) ; + _bcz.from_sub(_pb[2], _pc[2]) ; + + _sgn = (_abx * (_acx + _bcx)) + + (_aby * (_acy + _bcy)) + + (_abz * (_acz + _bcz)) ; + + _OK = + _sgn.lo() >= (REAL_TYPE)0. + || _sgn.up() <= (REAL_TYPE)0. ; + + return ( _sgn.mid () ) ; + } + + __normal_call REAL_TYPE bisect3d_f ( + __const_ptr(REAL_TYPE) _pa , + __const_ptr(REAL_TYPE) _pb , + __const_ptr(REAL_TYPE) _pc , + bool_type &_OK + ) + { + /*--------------- bisect3d predicate, "float" version */ + REAL_TYPE static const _ER = + + 6. * std::pow(mp::_epsilon, 1) ; + + REAL_TYPE _acx, _acy, _acz ; + REAL_TYPE _bcx, _bcy, _bcz ; + REAL_TYPE _acsqr, _bcsqr ; + + REAL_TYPE _sgn, _FT ; + + REAL_TYPE _ACSQR, _BCSQR ; + + _acx = _pa [0] - _pc [0] ; // coord. diff. + _acy = _pa [1] - _pc [1] ; + _acz = _pa [2] - _pc [2] ; + + _bcx = _pb [0] - _pc [0] ; + _bcy = _pb [1] - _pc [1] ; + _bcz = _pb [2] - _pc [2] ; + + _acsqr = _acx * _acx + + _acy * _acy + + _acz * _acz ; + _bcsqr = _bcx * _bcx + + _bcy * _bcy + + _bcz * _bcz ; + + _ACSQR = std::abs(_acsqr); + _BCSQR = std::abs(_bcsqr); + + _FT = _ACSQR + _BCSQR ; // roundoff tol + _FT *= _ER ; + + _sgn = _acsqr - _bcsqr ; // d_ab - d_bc + + _OK = _sgn > +_FT || _sgn < -_FT ; + + return _sgn ; + } + + /* + -------------------------------------------------------- + * + * Compute an exact orientation wrt. bisector using + * multi-precision expansions, a'la shewchuk + * + * |c-a|**2 - wa = |c-b|**2 - wb + * + * This is the weighted "bisect" predicate in E^3. + * + -------------------------------------------------------- + */ + + __normal_call REAL_TYPE bisect3w_e ( + __const_ptr(REAL_TYPE) _pa , + __const_ptr(REAL_TYPE) _pb , + __const_ptr(REAL_TYPE) _pc , + bool_type &_OK + ) + { + /*--------------- bisect3w predicate, "exact" version */ + mp::expansion< 2 > _ab_xx_, _ab_yy_, + _ab_zz_, _ab_ww_, + _ac_xx_, _ac_yy_, + _ac_zz_, + _bc_xx_, _bc_yy_, + _bc_zz_; + mp::expansion< 4 > _tt_xx_, _tt_yy_, + _tt_zz_; + mp::expansion< 48> _ttsum_; + mp::expansion< 50> _absum_; + + _OK = true; + + /*----------------------------------- compute: d(p,q) */ + _ab_xx_.from_sub(_pa[0], _pb[0]); + _ab_yy_.from_sub(_pa[1], _pb[1]); + _ab_zz_.from_sub(_pa[2], _pb[2]); + _ab_ww_.from_sub(_pa[3], _pb[3]); + + _ac_xx_.from_sub(_pa[0], _pc[0]); + _ac_yy_.from_sub(_pa[1], _pc[1]); + _ac_zz_.from_sub(_pa[2], _pc[2]); + + _bc_xx_.from_sub(_pb[0], _pc[0]); + _bc_yy_.from_sub(_pb[1], _pc[1]); + _bc_zz_.from_sub(_pb[2], _pc[2]); + + mp::expansion_add(_ac_xx_, _bc_xx_, + _tt_xx_) ; + mp::expansion_add(_ac_yy_, _bc_yy_, + _tt_yy_) ; + mp::expansion_add(_ac_zz_, _bc_zz_, + _tt_zz_) ; + + mp::expansion_dot(_ab_xx_, _tt_xx_, + _ab_yy_, _tt_yy_, + _ab_zz_, _tt_zz_, + _ttsum_) ; + + mp::expansion_sub(_ttsum_, _ab_ww_, + _absum_) ; + + /*----------------------------------- return signed d */ + return mp::expansion_est(_absum_) ; + } + + __normal_call REAL_TYPE bisect3w_i ( + __const_ptr(REAL_TYPE) _pa , + __const_ptr(REAL_TYPE) _pb , + __const_ptr(REAL_TYPE) _pc , + bool_type &_OK + ) + { + /*--------------- bisect3w predicate, "bound" version */ + ia_flt _acx, _acy, _acz , + _abw, + _bcx, _bcy, _bcz , + _abx, _aby, _abz ; + ia_flt _sgn; + + ia_rnd _rnd; // up rounding! + + _abx.from_sub(_pa[0], _pb[0]) ; // coord. diff. + _aby.from_sub(_pa[1], _pb[1]) ; + _abz.from_sub(_pa[2], _pb[2]) ; + _abw.from_sub(_pa[3], _pb[3]) ; + + _acx.from_sub(_pa[0], _pc[0]) ; + _acy.from_sub(_pa[1], _pc[1]) ; + _acz.from_sub(_pa[2], _pc[2]) ; + + _bcx.from_sub(_pb[0], _pc[0]) ; + _bcy.from_sub(_pb[1], _pc[1]) ; + _bcz.from_sub(_pb[2], _pc[2]) ; + + _sgn = (_abx * (_acx + _bcx)) + + (_aby * (_acy + _bcy)) + + (_abz * (_acz + _bcz)) ; + + _sgn-= _abw ; + + _OK = + _sgn.lo() >= (REAL_TYPE)0. + || _sgn.up() <= (REAL_TYPE)0. ; + + return ( _sgn.mid () ) ; + } + + __normal_call REAL_TYPE bisect3w_f ( + __const_ptr(REAL_TYPE) _pa , + __const_ptr(REAL_TYPE) _pb , + __const_ptr(REAL_TYPE) _pc , + bool_type &_OK + ) + { + /*--------------- bisect3w predicate, "float" version */ + REAL_TYPE static const _ER = + + 7. * std::pow(mp::_epsilon, 1) ; + + REAL_TYPE _acx, _acy, _acz ; + REAL_TYPE _bcx, _bcy, _bcz ; + REAL_TYPE _acsqr, _bcsqr ; + REAL_TYPE _a_sum, _b_sum ; + + REAL_TYPE _A_SUM, _B_SUM ; + + REAL_TYPE _sgn, _FT; + + _acx = _pa [0] - _pc [0] ; // coord. diff. + _acy = _pa [1] - _pc [1] ; + _acz = _pa [2] - _pc [2] ; + + _bcx = _pb [0] - _pc [0] ; + _bcy = _pb [1] - _pc [1] ; + _bcz = _pb [2] - _pc [2] ; + + _acsqr = _acx * _acx + + _acy * _acy + + _acz * _acz ; + _bcsqr = _bcx * _bcx + + _bcy * _bcy + + _bcz * _bcz ; + + _a_sum = _acsqr - _pa[3] ; + _b_sum = _bcsqr - _pb[3] ; + + _A_SUM = std::abs(_acsqr) + + std::abs(_pa[3]); + _B_SUM = std::abs(_bcsqr) + + std::abs(_pb[3]); + + _FT = _A_SUM + _B_SUM ; // roundoff tol + _FT *= _ER ; + + _sgn = _a_sum - _b_sum ; // d_ab - d_bc + + _OK = _sgn > +_FT || _sgn < -_FT ; + + return _sgn ; + } + + /* + -------------------------------------------------------- + * + * Compute an exact orientation wrt. bisector using + * multi-precision expansions, a'la shewchuk + * + * |c-a|**2 - wa = |c-b|**2 - wb + * + * This is the unweighted "bisect" predicate in E^4. + * + -------------------------------------------------------- + */ + + __normal_call REAL_TYPE bisect4d_e ( + __const_ptr(REAL_TYPE) _pa , + __const_ptr(REAL_TYPE) _pb , + __const_ptr(REAL_TYPE) _pc , + bool_type &_OK + ) + { + /*--------------- bisect4d predicate, "exact" version */ + mp::expansion< 2 > _ab_xx_, _ab_yy_, + _ab_zz_, _ab_qq_, + _ac_xx_, _ac_yy_, + _ac_zz_, _ac_qq_, + _bc_xx_, _bc_yy_, + _bc_zz_, _bc_qq_; + mp::expansion< 4 > _tt_xx_, _tt_yy_, + _tt_zz_, _tt_qq_; + mp::expansion< 64> _absum_; + + _OK = true; + + /*----------------------------------- compute: d(p,q) */ + _ab_xx_.from_sub(_pa[0], _pb[0]); + _ab_yy_.from_sub(_pa[1], _pb[1]); + _ab_zz_.from_sub(_pa[2], _pb[2]); + _ab_qq_.from_sub(_pa[3], _pb[3]); + + _ac_xx_.from_sub(_pa[0], _pc[0]); + _ac_yy_.from_sub(_pa[1], _pc[1]); + _ac_zz_.from_sub(_pa[2], _pc[2]); + _ac_qq_.from_sub(_pa[3], _pc[3]); + + _bc_xx_.from_sub(_pb[0], _pc[0]); + _bc_yy_.from_sub(_pb[1], _pc[1]); + _bc_zz_.from_sub(_pb[2], _pc[2]); + _bc_qq_.from_sub(_pb[3], _pc[3]); + + mp::expansion_add(_ac_xx_, _bc_xx_, + _tt_xx_) ; + mp::expansion_add(_ac_yy_, _bc_yy_, + _tt_yy_) ; + mp::expansion_add(_ac_zz_, _bc_zz_, + _tt_zz_) ; + mp::expansion_add(_ac_qq_, _bc_qq_, + _tt_qq_) ; + + mp::expansion_dot(_ab_xx_, _tt_xx_, + _ab_yy_, _tt_yy_, + _ab_zz_, _tt_zz_, + _ab_qq_, _tt_qq_, + _absum_) ; + + /*----------------------------------- return signed d */ + return mp::expansion_est(_absum_) ; + } + + __normal_call REAL_TYPE bisect4d_i ( + __const_ptr(REAL_TYPE) _pa , + __const_ptr(REAL_TYPE) _pb , + __const_ptr(REAL_TYPE) _pc , + bool_type &_OK + ) + { + /*--------------- bisect4d predicate, "bound" version */ + ia_flt _acx, _acy, _acz, _acq , + _bcx, _bcy, _bcz, _bcq , + _abx, _aby, _abz, _abq ; + ia_flt _sgn; + + ia_rnd _rnd; // up rounding! + + _abx.from_sub(_pa[0], _pb[0]) ; // coord. diff. + _aby.from_sub(_pa[1], _pb[1]) ; + _abz.from_sub(_pa[2], _pb[2]) ; + _abq.from_sub(_pa[3], _pb[3]) ; + + _acx.from_sub(_pa[0], _pc[0]) ; + _acy.from_sub(_pa[1], _pc[1]) ; + _acz.from_sub(_pa[2], _pc[2]) ; + _acq.from_sub(_pa[3], _pc[3]) ; + + _bcx.from_sub(_pb[0], _pc[0]) ; + _bcy.from_sub(_pb[1], _pc[1]) ; + _bcz.from_sub(_pb[2], _pc[2]) ; + _bcq.from_sub(_pb[3], _pc[3]) ; + + _sgn = (_abx * (_acx + _bcx)) + + (_aby * (_acy + _bcy)) + + (_abz * (_acz + _bcz)) + + (_abq * (_acq + _bcq)) ; + + _OK = + _sgn.lo() >= (REAL_TYPE)0. + || _sgn.up() <= (REAL_TYPE)0. ; + + return ( _sgn.mid () ) ; + } + + __normal_call REAL_TYPE bisect4d_f ( + __const_ptr(REAL_TYPE) _pa , + __const_ptr(REAL_TYPE) _pb , + __const_ptr(REAL_TYPE) _pc , + bool_type &_OK + ) + { + /*--------------- bisect4d predicate, "float" version */ + REAL_TYPE static const _ER = + + 7. * std::pow(mp::_epsilon, 1) ; + + REAL_TYPE _acx, _acy, _acz, _acq; + REAL_TYPE _bcx, _bcy, _bcz, _bcq; + REAL_TYPE _acsqr, _bcsqr ; + + REAL_TYPE _sgn, _FT ; + + REAL_TYPE _ACSQR, _BCSQR ; + + _acx = _pa [0] - _pc [0] ; // coord. diff. + _acy = _pa [1] - _pc [1] ; + _acz = _pa [2] - _pc [2] ; + _acq = _pa [3] - _pc [3] ; + + _bcx = _pb [0] - _pc [0] ; + _bcy = _pb [1] - _pc [1] ; + _bcz = _pb [2] - _pc [2] ; + _bcq = _pb [3] - _pc [3] ; + + _acsqr = _acx * _acx + + _acy * _acy + + _acz * _acz + + _acq * _acq ; + _bcsqr = _bcx * _bcx + + _bcy * _bcy + + _bcz * _bcz + + _bcq * _bcq ; + + _ACSQR = std::abs(_acsqr); + _BCSQR = std::abs(_bcsqr); + + _FT = _ACSQR + _BCSQR ; // roundoff tol + _FT *= _ER ; + + _sgn = _acsqr - _bcsqr ; // d_ab - d_bc + + _OK = _sgn > +_FT || _sgn < -_FT ; + + return _sgn ; + } + + /* + -------------------------------------------------------- + * + * Compute an exact orientation wrt. bisector using + * multi-precision expansions, a'la shewchuk + * + * |c-a|**2 - wa = |c-b|**2 - wb + * + * This is the weighted "bisect" predicate in E^4. + * + -------------------------------------------------------- + */ + + __normal_call REAL_TYPE bisect4w_e ( + __const_ptr(REAL_TYPE) _pa , + __const_ptr(REAL_TYPE) _pb , + __const_ptr(REAL_TYPE) _pc , + bool_type &_OK + ) + { + /*--------------- bisect4w predicate, "exact" version */ + mp::expansion< 2 > _ab_xx_, _ab_yy_, + _ab_zz_, _ab_qq_, + _ab_ww_, + _ac_xx_, _ac_yy_, + _ac_zz_, _ac_qq_, + _bc_xx_, _bc_yy_, + _bc_zz_, _bc_qq_; + mp::expansion< 4 > _tt_xx_, _tt_yy_, + _tt_zz_, _tt_qq_; + mp::expansion< 64> _ttsum_; + mp::expansion< 66> _absum_; + + _OK = true; + + /*----------------------------------- compute: d(p,q) */ + _ab_xx_.from_sub(_pa[0], _pb[0]); + _ab_yy_.from_sub(_pa[1], _pb[1]); + _ab_zz_.from_sub(_pa[2], _pb[2]); + _ab_qq_.from_sub(_pa[3], _pb[3]); + _ab_ww_.from_sub(_pa[4], _pb[4]); + + _ac_xx_.from_sub(_pa[0], _pc[0]); + _ac_yy_.from_sub(_pa[1], _pc[1]); + _ac_zz_.from_sub(_pa[2], _pc[2]); + _ac_qq_.from_sub(_pa[3], _pc[3]); + + _bc_xx_.from_sub(_pb[0], _pc[0]); + _bc_yy_.from_sub(_pb[1], _pc[1]); + _bc_zz_.from_sub(_pb[2], _pc[2]); + _bc_qq_.from_sub(_pb[3], _pc[3]); + + mp::expansion_add(_ac_xx_, _bc_xx_, + _tt_xx_) ; + mp::expansion_add(_ac_yy_, _bc_yy_, + _tt_yy_) ; + mp::expansion_add(_ac_zz_, _bc_zz_, + _tt_zz_) ; + mp::expansion_add(_ac_qq_, _bc_qq_, + _tt_qq_) ; + + mp::expansion_dot(_ab_xx_, _tt_xx_, + _ab_yy_, _tt_yy_, + _ab_zz_, _tt_zz_, + _ab_qq_, _tt_qq_, + _ttsum_) ; + + mp::expansion_sub(_ttsum_, _ab_ww_, + _absum_) ; + + /*----------------------------------- return signed d */ + return mp::expansion_est(_absum_) ; + } + + __normal_call REAL_TYPE bisect4w_i ( + __const_ptr(REAL_TYPE) _pa , + __const_ptr(REAL_TYPE) _pb , + __const_ptr(REAL_TYPE) _pc , + bool_type &_OK + ) + { + /*--------------- bisect4w predicate, "bound" version */ + ia_flt _acx, _acy, _acz, _acq, + _abw, + _bcx, _bcy, _bcz, _bcq, + _abx, _aby, _abz, _abq; + ia_flt _sgn; + + ia_rnd _rnd; // up rounding! + + _abx.from_sub(_pa[0], _pb[0]) ; // coord. diff. + _aby.from_sub(_pa[1], _pb[1]) ; + _abz.from_sub(_pa[2], _pb[2]) ; + _abq.from_sub(_pa[3], _pb[3]) ; + _abw.from_sub(_pa[4], _pb[4]) ; + + _acx.from_sub(_pa[0], _pc[0]) ; + _acy.from_sub(_pa[1], _pc[1]) ; + _acz.from_sub(_pa[2], _pc[2]) ; + _acq.from_sub(_pa[3], _pc[3]) ; + + _bcx.from_sub(_pb[0], _pc[0]) ; + _bcy.from_sub(_pb[1], _pc[1]) ; + _bcz.from_sub(_pb[2], _pc[2]) ; + _bcq.from_sub(_pb[3], _pc[3]) ; + + _sgn = (_abx * (_acx + _bcx)) + + (_aby * (_acy + _bcy)) + + (_abz * (_acz + _bcz)) + + (_abq * (_acq + _bcq)) ; + + _sgn-= _abw ; + + _OK = + _sgn.lo() >= (REAL_TYPE)0. + || _sgn.up() <= (REAL_TYPE)0. ; + + return ( _sgn.mid () ) ; + } + + __normal_call REAL_TYPE bisect4w_f ( + __const_ptr(REAL_TYPE) _pa , + __const_ptr(REAL_TYPE) _pb , + __const_ptr(REAL_TYPE) _pc , + bool_type &_OK + ) + { + /*--------------- bisect4w predicate, "float" version */ + REAL_TYPE static const _ER = + + 8. * std::pow(mp::_epsilon, 1) ; + + REAL_TYPE _acx, _acy, _acz, _acq; + REAL_TYPE _bcx, _bcy, _bcz, _bcq; + REAL_TYPE _acsqr, _bcsqr ; + REAL_TYPE _a_sum, _b_sum ; + + REAL_TYPE _A_SUM, _B_SUM ; + + REAL_TYPE _sgn, _FT; + + _acx = _pa [0] - _pc [0] ; // coord. diff. + _acy = _pa [1] - _pc [1] ; + _acz = _pa [2] - _pc [2] ; + _acq = _pa [3] - _pc [3] ; + + _bcx = _pb [0] - _pc [0] ; + _bcy = _pb [1] - _pc [1] ; + _bcz = _pb [2] - _pc [2] ; + _bcq = _pb [3] - _pc [3] ; + + _acsqr = _acx * _acx + + _acy * _acy + + _acz * _acz + + _acq * _acq ; + _bcsqr = _bcx * _bcx + + _bcy * _bcy + + _bcz * _bcz + + _bcq * _bcq ; + + _a_sum = _acsqr - _pa[4] ; + _b_sum = _bcsqr - _pb[4] ; + + _A_SUM = std::abs(_acsqr) + + std::abs(_pa[4]); + _B_SUM = std::abs(_bcsqr) + + std::abs(_pb[4]); + + _FT = _A_SUM + _B_SUM ; // roundoff tol + _FT *= _ER ; + + _sgn = _a_sum - _b_sum ; // d_ab - d_bc + + _OK = _sgn > +_FT || _sgn < -_FT ; + + return _sgn ; + } + + + diff --git a/src/libcpp/predicate/inball_k.hpp b/src/libcpp/predicate/inball_k.hpp new file mode 100644 index 0000000..9d7db0e --- /dev/null +++ b/src/libcpp/predicate/inball_k.hpp @@ -0,0 +1,1621 @@ + + /* + -------------------------------------------------------- + * PREDICATE-k: robust geometric predicates in E^k. + -------------------------------------------------------- + * + * 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/ + * + -------------------------------------------------------- + */ + + // from predicate_k.hpp... + + + /* + -------------------------------------------------------- + * + * Compute an exact determinant using multi-precision + * expansions, a'la shewchuk + * + * | ax ay dot(a, a) +1. | + * | bx by dot(b, b) +1. | + * | cx cy dot(c, c) +1. | + * | dx dy dot(d, d) +1. | + * + * This is the unweighted "in-ball" predicate in E^2. + * + -------------------------------------------------------- + */ + + __normal_call REAL_TYPE inball2d_e ( + __const_ptr(REAL_TYPE) _pa , + __const_ptr(REAL_TYPE) _pb , + __const_ptr(REAL_TYPE) _pc , + __const_ptr(REAL_TYPE) _pd , + bool_type &_OK + ) + { + /*--------------- inball2d predicate, "exact" version */ + mp::expansion< 4 > _a_lift, _b_lift, + _c_lift, _d_lift; + mp::expansion< 4 > _d2_ab_, _d2_ac_, + _d2_ad_, + _d2_bc_, _d2_bd_, + _d2_cd_; + mp::expansion< 12> _d3_abc, _d3_abd, + _d3_acd, _d3_bcd; + mp::expansion<384> _d4full; + + _OK = true; + + /*-------------------------------------- lifted terms */ + mp::expansion_add( + mp::expansion_from_sqr(_pa[ 0]), + mp::expansion_from_sqr(_pa[ 1]), + _a_lift ) ; + + mp::expansion_add( + mp::expansion_from_sqr(_pb[ 0]), + mp::expansion_from_sqr(_pb[ 1]), + _b_lift ) ; + + mp::expansion_add( + mp::expansion_from_sqr(_pc[ 0]), + mp::expansion_from_sqr(_pc[ 1]), + _c_lift ) ; + + mp::expansion_add( + mp::expansion_from_sqr(_pd[ 0]), + mp::expansion_from_sqr(_pd[ 1]), + _d_lift ) ; + + /*-------------------------------------- 2 x 2 minors */ + compute_det_2x2(_pa[ 0], _pa[ 1], + _pb[ 0], _pb[ 1], + _d2_ab_ ) ; + + compute_det_2x2(_pa[ 0], _pa[ 1], + _pc[ 0], _pc[ 1], + _d2_ac_ ) ; + + compute_det_2x2(_pa[ 0], _pa[ 1], + _pd[ 0], _pd[ 1], + _d2_ad_ ) ; + + compute_det_2x2(_pb[ 0], _pb[ 1], + _pc[ 0], _pc[ 1], + _d2_bc_ ) ; + + compute_det_2x2(_pb[ 0], _pb[ 1], + _pd[ 0], _pd[ 1], + _d2_bd_ ) ; + + compute_det_2x2(_pc[ 0], _pc[ 1], + _pd[ 0], _pd[ 1], + _d2_cd_ ) ; + + /*-------------------------------------- 3 x 3 minors */ + unitary_det_3x3(_d2_cd_, _d2_bd_, + _d2_bc_, + _d3_bcd, +3) ; + + unitary_det_3x3(_d2_cd_, _d2_ad_, + _d2_ac_, + _d3_acd, +3) ; + + unitary_det_3x3(_d2_bd_, _d2_ad_, + _d2_ab_, + _d3_abd, +3) ; + + unitary_det_3x3(_d2_bc_, _d2_ac_, + _d2_ab_, + _d3_abc, +3) ; + + /*-------------------------------------- 4 x 4 result */ + compute_det_4x4(_d3_bcd, _a_lift, + _d3_acd, _b_lift, + _d3_abd, _c_lift, + _d3_abc, _d_lift, + _d4full, +3) ; + + /*-------------------------------------- leading det. */ + return mp::expansion_est(_d4full) ; + } + + __normal_call REAL_TYPE inball2d_i ( + __const_ptr(REAL_TYPE) _pa , + __const_ptr(REAL_TYPE) _pb , + __const_ptr(REAL_TYPE) _pc , + __const_ptr(REAL_TYPE) _pd , + bool_type &_OK + ) + { + /*--------------- inball2d predicate, "bound" version */ + ia_flt _adx, _ady, _adw , + _bdx, _bdy, _bdw , + _cdx, _cdy, _cdw ; + ia_flt _ali, _bli, _cli ; + ia_flt _bdxcdy, _cdxbdy , + _cdxady, _adxcdy , + _adxbdy, _bdxady ; + + ia_flt _d33; + + ia_rnd _rnd; // up rounding! + + _adx.from_sub(_pa[0], _pd[0]) ; // coord. diff. + _ady.from_sub(_pa[1], _pd[1]) ; + _adw.from_sub(_pa[2], _pd[2]) ; + + _bdx.from_sub(_pb[0], _pd[0]) ; + _bdy.from_sub(_pb[1], _pd[1]) ; + _bdw.from_sub(_pb[2], _pd[2]) ; + + _cdx.from_sub(_pc[0], _pd[0]) ; + _cdy.from_sub(_pc[1], _pd[1]) ; + _cdw.from_sub(_pc[2], _pd[2]) ; + + _ali = sqr (_adx) + sqr (_ady) ; // lifted terms + + _bli = sqr (_bdx) + sqr (_bdy) ; + + _cli = sqr (_cdx) + sqr (_cdy) ; + + _bdxcdy = _bdx * _cdy ; // 2 x 2 minors + _cdxbdy = _cdx * _bdy ; + _cdxady = _cdx * _ady ; + _adxcdy = _adx * _cdy ; + _adxbdy = _adx * _bdy ; + _bdxady = _bdx * _ady ; + + _d33 = // 3 x 3 result + _ali * (_bdxcdy - _cdxbdy) + + _bli * (_cdxady - _adxcdy) + + _cli * (_adxbdy - _bdxady) ; + + _OK = + _d33.lo() >= (REAL_TYPE)0. + ||_d33.up() <= (REAL_TYPE)0. ; + + return ( _d33.mid() ) ; + } + + __normal_call REAL_TYPE inball2d_f ( + __const_ptr(REAL_TYPE) _pa , + __const_ptr(REAL_TYPE) _pb , + __const_ptr(REAL_TYPE) _pc , + __const_ptr(REAL_TYPE) _pd , + bool_type &_OK + ) + { + /*--------------- inball2d predicate, "float" version */ + REAL_TYPE static const _ER = + + 11. * std::pow(mp::_epsilon, 1) ; + + REAL_TYPE _adx, _ady, _ali , + _bdx, _bdy, _bli , + _cdx, _cdy, _cli ; + REAL_TYPE _bdxcdy, _cdxbdy , + _cdxady, _adxcdy , + _adxbdy, _bdxady ; + + REAL_TYPE _BDXCDY, _CDXBDY , + _CDXADY, _ADXCDY , + _ADXBDY, _BDXADY ; + + REAL_TYPE _d33, _FT ; + + _adx = _pa [0] - _pd [0] ; // coord. diff. + _ady = _pa [1] - _pd [1] ; + + _bdx = _pb [0] - _pd [0] ; + _bdy = _pb [1] - _pd [1] ; + + _cdx = _pc [0] - _pd [0] ; + _cdy = _pc [1] - _pd [1] ; + + _ali = _adx * _adx + _ady * _ady; // lifted terms + + _bli = _bdx * _bdx + _bdy * _bdy; + + _cli = _cdx * _cdx + _cdy * _cdy; + + _bdxcdy = _bdx * _cdy ; // 2 x 2 minors + _cdxbdy = _cdx * _bdy ; + _cdxady = _cdx * _ady ; + _adxcdy = _adx * _cdy ; + _adxbdy = _adx * _bdy ; + _bdxady = _bdx * _ady ; + + _BDXCDY = std::abs (_bdxcdy) ; + _CDXBDY = std::abs (_cdxbdy) ; + _CDXADY = std::abs (_cdxady) ; + _ADXCDY = std::abs (_adxcdy) ; + _ADXBDY = std::abs (_adxbdy) ; + _BDXADY = std::abs (_bdxady) ; + + _FT = // roundoff tol + _ali * (_BDXCDY + _CDXBDY) + + _bli * (_CDXADY + _ADXCDY) + + _cli * (_ADXBDY + _BDXADY) ; + + _FT *= _ER ; + + _d33 = // 3 x 3 result + _ali * (_bdxcdy - _cdxbdy) + + _bli * (_cdxady - _adxcdy) + + _cli * (_adxbdy - _bdxady) ; + + _OK = + _d33 > +_FT || _d33 < -_FT ; + + return ( _d33 ) ; + } + + /* + -------------------------------------------------------- + * + * Compute an exact determinant using multi-precision + * expansions, a'la shewchuk + * + * | ax ay dot(a, a) - aw +1. | + * | bx by dot(b, b) - bw +1. | + * | cx cy dot(c, c) - cw +1. | + * | dx dy dot(d, d) - dw +1. | + * + * This is the weighted "in-ball" predicate in E^2. + * + -------------------------------------------------------- + */ + + __normal_call REAL_TYPE inball2w_e ( + __const_ptr(REAL_TYPE) _pa , + __const_ptr(REAL_TYPE) _pb , + __const_ptr(REAL_TYPE) _pc , + __const_ptr(REAL_TYPE) _pd , + bool_type &_OK + ) + { + /*--------------- inball2w predicate, "exact" version */ + mp::expansion< 5 > _a_lift, _b_lift, + _c_lift, _d_lift; + mp::expansion< 4 > _t_lift; + mp::expansion< 4 > _d2_ab_, _d2_ac_, + _d2_ad_, + _d2_bc_, _d2_bd_, + _d2_cd_; + mp::expansion< 12> _d3_abc, _d3_abd, + _d3_acd, _d3_bcd; + mp::expansion<480> _d4full; + + _OK = true; + + /*-------------------------------------- lifted terms */ + mp::expansion_add( + mp::expansion_from_sqr(_pa[ 0]), + mp::expansion_from_sqr(_pa[ 1]), + _t_lift ) ; + mp::expansion_sub( + _t_lift , _pa[ 2] , _a_lift); + + mp::expansion_add( + mp::expansion_from_sqr(_pb[ 0]), + mp::expansion_from_sqr(_pb[ 1]), + _t_lift ) ; + mp::expansion_sub( + _t_lift , _pb[ 2] , _b_lift); + + mp::expansion_add( + mp::expansion_from_sqr(_pc[ 0]), + mp::expansion_from_sqr(_pc[ 1]), + _t_lift ) ; + mp::expansion_sub( + _t_lift , _pc[ 2] , _c_lift); + + mp::expansion_add( + mp::expansion_from_sqr(_pd[ 0]), + mp::expansion_from_sqr(_pd[ 1]), + _t_lift ) ; + mp::expansion_sub( + _t_lift , _pd[ 2] , _d_lift); + + /*-------------------------------------- 2 x 2 minors */ + compute_det_2x2(_pa[ 0], _pa[ 1], + _pb[ 0], _pb[ 1], + _d2_ab_ ) ; + + compute_det_2x2(_pa[ 0], _pa[ 1], + _pc[ 0], _pc[ 1], + _d2_ac_ ) ; + + compute_det_2x2(_pa[ 0], _pa[ 1], + _pd[ 0], _pd[ 1], + _d2_ad_ ) ; + + compute_det_2x2(_pb[ 0], _pb[ 1], + _pc[ 0], _pc[ 1], + _d2_bc_ ) ; + + compute_det_2x2(_pb[ 0], _pb[ 1], + _pd[ 0], _pd[ 1], + _d2_bd_ ) ; + + compute_det_2x2(_pc[ 0], _pc[ 1], + _pd[ 0], _pd[ 1], + _d2_cd_ ) ; + + /*-------------------------------------- 3 x 3 minors */ + unitary_det_3x3(_d2_cd_, _d2_bd_, + _d2_bc_, + _d3_bcd, +3) ; + + unitary_det_3x3(_d2_cd_, _d2_ad_, + _d2_ac_, + _d3_acd, +3) ; + + unitary_det_3x3(_d2_bd_, _d2_ad_, + _d2_ab_, + _d3_abd, +3) ; + + unitary_det_3x3(_d2_bc_, _d2_ac_, + _d2_ab_, + _d3_abc, +3) ; + + /*-------------------------------------- 4 x 4 result */ + compute_det_4x4(_d3_bcd, _a_lift, + _d3_acd, _b_lift, + _d3_abd, _c_lift, + _d3_abc, _d_lift, + _d4full, +3) ; + + /*-------------------------------------- leading det. */ + return mp::expansion_est(_d4full) ; + } + + __normal_call REAL_TYPE inball2w_i ( + __const_ptr(REAL_TYPE) _pa , + __const_ptr(REAL_TYPE) _pb , + __const_ptr(REAL_TYPE) _pc , + __const_ptr(REAL_TYPE) _pd , + bool_type &_OK + ) + { + /*--------------- inball2w predicate, "bound" version */ + ia_flt _adx, _ady, _adw , + _bdx, _bdy, _bdw , + _cdx, _cdy, _cdw ; + ia_flt _ali, _bli, _cli ; + ia_flt _bdxcdy, _cdxbdy , + _cdxady, _adxcdy , + _adxbdy, _bdxady ; + + ia_flt _d33; + + ia_rnd _rnd; // up rounding! + + _adx.from_sub(_pa[0], _pd[0]) ; // coord. diff. + _ady.from_sub(_pa[1], _pd[1]) ; + _adw.from_sub(_pa[2], _pd[2]) ; + + _bdx.from_sub(_pb[0], _pd[0]) ; + _bdy.from_sub(_pb[1], _pd[1]) ; + _bdw.from_sub(_pb[2], _pd[2]) ; + + _cdx.from_sub(_pc[0], _pd[0]) ; + _cdy.from_sub(_pc[1], _pd[1]) ; + _cdw.from_sub(_pc[2], _pd[2]) ; + + _ali = sqr (_adx) + sqr (_ady) // lifted terms + - _adw ; + + _bli = sqr (_bdx) + sqr (_bdy) + - _bdw ; + + _cli = sqr (_cdx) + sqr (_cdy) + - _cdw ; + + _bdxcdy = _bdx * _cdy ; // 2 x 2 minors + _cdxbdy = _cdx * _bdy ; + _cdxady = _cdx * _ady ; + _adxcdy = _adx * _cdy ; + _adxbdy = _adx * _bdy ; + _bdxady = _bdx * _ady ; + + _d33 = // 3 x 3 result + _ali * (_bdxcdy - _cdxbdy) + + _bli * (_cdxady - _adxcdy) + + _cli * (_adxbdy - _bdxady) ; + + _OK = + _d33.lo() >= (REAL_TYPE)0. + ||_d33.up() <= (REAL_TYPE)0. ; + + return ( _d33.mid() ) ; + } + + __normal_call REAL_TYPE inball2w_f ( + __const_ptr(REAL_TYPE) _pa , + __const_ptr(REAL_TYPE) _pb , + __const_ptr(REAL_TYPE) _pc , + __const_ptr(REAL_TYPE) _pd , + bool_type &_OK + ) + { + /*--------------- inball2w predicate, "float" version */ + REAL_TYPE static const _ER = + + 12. * std::pow(mp::_epsilon, 1) ; + + REAL_TYPE _adx, _ady, _adw , + _bdx, _bdy, _bdw , + _cdx, _cdy, _cdw ; + REAL_TYPE _ali, _bli, _cli ; + REAL_TYPE _bdxcdy, _cdxbdy , + _cdxady, _adxcdy , + _adxbdy, _bdxady ; + + REAL_TYPE _ALI, _BLI, _CLI ; + REAL_TYPE _BDXCDY, _CDXBDY , + _CDXADY, _ADXCDY , + _ADXBDY, _BDXADY ; + + REAL_TYPE _d33, _FT ; + + _adx = _pa [0] - _pd [0] ; // coord. diff. + _ady = _pa [1] - _pd [1] ; + _adw = _pa [2] - _pd [2] ; + + _bdx = _pb [0] - _pd [0] ; + _bdy = _pb [1] - _pd [1] ; + _bdw = _pb [2] - _pd [2] ; + + _cdx = _pc [0] - _pd [0] ; + _cdy = _pc [1] - _pd [1] ; + _cdw = _pc [2] - _pd [2] ; + + _ali = _adx * _adx + _ady * _ady // lifted terms + - _adw ; + + _ALI = std::abs (_ali) ; + + _bli = _bdx * _bdx + _bdy * _bdy + - _bdw ; + + _BLI = std::abs (_bli) ; + + _cli = _cdx * _cdx + _cdy * _cdy + - _cdw ; + + _CLI = std::abs (_cli) ; + + _bdxcdy = _bdx * _cdy ; // 2 x 2 minors + _cdxbdy = _cdx * _bdy ; + _cdxady = _cdx * _ady ; + _adxcdy = _adx * _cdy ; + _adxbdy = _adx * _bdy ; + _bdxady = _bdx * _ady ; + + _BDXCDY = std::abs (_bdxcdy) ; + _CDXBDY = std::abs (_cdxbdy) ; + _CDXADY = std::abs (_cdxady) ; + _ADXCDY = std::abs (_adxcdy) ; + _ADXBDY = std::abs (_adxbdy) ; + _BDXADY = std::abs (_bdxady) ; + + _FT = // roundoff tol + _ALI * (_BDXCDY + _CDXBDY) + + _BLI * (_CDXADY + _ADXCDY) + + _CLI * (_ADXBDY + _BDXADY) ; + + _FT *= _ER ; + + _d33 = // 3 x 3 result + _ali * (_bdxcdy - _cdxbdy) + + _bli * (_cdxady - _adxcdy) + + _cli * (_adxbdy - _bdxady) ; + + _OK = + _d33 > +_FT || _d33 < -_FT ; + + return ( _d33 ) ; + } + + /* + -------------------------------------------------------- + * + * Compute an exact determinant using multi-precision + * expansions, a'la shewchuk + * + * | ax ay az dot(a, a) +1. | + * | bx by bz dot(b, b) +1. | + * | cx cy cz dot(c, c) +1. | + * | dx dy dz dot(d, d) +1. | + * | ex ey ez dot(e, e) +1. | + * + * This is the unweighted "in-ball" predicate in E^3. + * + -------------------------------------------------------- + */ + + __normal_call REAL_TYPE inball3d_e ( + __const_ptr(REAL_TYPE) _pa , + __const_ptr(REAL_TYPE) _pb , + __const_ptr(REAL_TYPE) _pc , + __const_ptr(REAL_TYPE) _pd , + __const_ptr(REAL_TYPE) _pe , + bool_type &_OK + ) + { + /*--------------- inball3d predicate, "exact" version */ + mp::expansion< 6 > _a_lift, _b_lift, + _c_lift, _d_lift, + _e_lift; + mp::expansion< 4 > _d2_ab_, _d2_ac_, + _d2_ad_, _d2_ae_, + _d2_bc_, _d2_bd_, + _d2_be_, + _d2_cd_, _d2_ce_, + _d2_de_; + mp::expansion< 24> _d3_abc, _d3_abd, + _d3_abe, + _d3_acd, _d3_ace, + _d3_ade, + _d3_bcd, _d3_bce, + _d3_bde, _d3_cde; + mp::expansion< 96> _d4abcd, _d4abce, + _d4abde, _d4acde, + _d4bcde; + mp::expansion<5760>_d5full; + + _OK = true; + + mp::expansion< 1 > _pa_zz_(_pa[ 2]); + mp::expansion< 1 > _pb_zz_(_pb[ 2]); + mp::expansion< 1 > _pc_zz_(_pc[ 2]); + mp::expansion< 1 > _pd_zz_(_pd[ 2]); + mp::expansion< 1 > _pe_zz_(_pe[ 2]); + + /*-------------------------------------- lifted terms */ + mp::expansion_add( + mp::expansion_from_sqr(_pa[ 0]), + mp::expansion_from_sqr(_pa[ 1]), + mp::expansion_from_sqr(_pa[ 2]), + _a_lift ) ; + + mp::expansion_add( + mp::expansion_from_sqr(_pb[ 0]), + mp::expansion_from_sqr(_pb[ 1]), + mp::expansion_from_sqr(_pb[ 2]), + _b_lift ) ; + + mp::expansion_add( + mp::expansion_from_sqr(_pc[ 0]), + mp::expansion_from_sqr(_pc[ 1]), + mp::expansion_from_sqr(_pc[ 2]), + _c_lift ) ; + + mp::expansion_add( + mp::expansion_from_sqr(_pd[ 0]), + mp::expansion_from_sqr(_pd[ 1]), + mp::expansion_from_sqr(_pd[ 2]), + _d_lift ) ; + + mp::expansion_add( + mp::expansion_from_sqr(_pe[ 0]), + mp::expansion_from_sqr(_pe[ 1]), + mp::expansion_from_sqr(_pe[ 2]), + _e_lift ) ; + + /*-------------------------------------- 2 x 2 minors */ + compute_det_2x2(_pa[ 0], _pa[ 1], + _pb[ 0], _pb[ 1], + _d2_ab_ ) ; + + compute_det_2x2(_pa[ 0], _pa[ 1], + _pc[ 0], _pc[ 1], + _d2_ac_ ) ; + + compute_det_2x2(_pa[ 0], _pa[ 1], + _pd[ 0], _pd[ 1], + _d2_ad_ ) ; + + compute_det_2x2(_pa[ 0], _pa[ 1], + _pe[ 0], _pe[ 1], + _d2_ae_ ) ; + + compute_det_2x2(_pb[ 0], _pb[ 1], + _pc[ 0], _pc[ 1], + _d2_bc_ ) ; + + compute_det_2x2(_pb[ 0], _pb[ 1], + _pd[ 0], _pd[ 1], + _d2_bd_ ) ; + + compute_det_2x2(_pb[ 0], _pb[ 1], + _pe[ 0], _pe[ 1], + _d2_be_ ) ; + + compute_det_2x2(_pc[ 0], _pc[ 1], + _pd[ 0], _pd[ 1], + _d2_cd_ ) ; + + compute_det_2x2(_pc[ 0], _pc[ 1], + _pe[ 0], _pe[ 1], + _d2_ce_ ) ; + + compute_det_2x2(_pd[ 0], _pd[ 1], + _pe[ 0], _pe[ 1], + _d2_de_ ) ; + + /*-------------------------------------- 3 x 3 minors */ + compute_det_3x3(_d2_bc_, _pa_zz_, + _d2_ac_, _pb_zz_, + _d2_ab_, _pc_zz_, + _d3_abc, +3) ; + + compute_det_3x3(_d2_bd_, _pa_zz_, + _d2_ad_, _pb_zz_, + _d2_ab_, _pd_zz_, + _d3_abd, +3) ; + + compute_det_3x3(_d2_be_, _pa_zz_, + _d2_ae_, _pb_zz_, + _d2_ab_, _pe_zz_, + _d3_abe, +3) ; + + compute_det_3x3(_d2_cd_, _pa_zz_, + _d2_ad_, _pc_zz_, + _d2_ac_, _pd_zz_, + _d3_acd, +3) ; + + compute_det_3x3(_d2_ce_, _pa_zz_, + _d2_ae_, _pc_zz_, + _d2_ac_, _pe_zz_, + _d3_ace, +3) ; + + compute_det_3x3(_d2_de_, _pa_zz_, + _d2_ae_, _pd_zz_, + _d2_ad_, _pe_zz_, + _d3_ade, +3) ; + + compute_det_3x3(_d2_cd_, _pb_zz_, + _d2_bd_, _pc_zz_, + _d2_bc_, _pd_zz_, + _d3_bcd, +3) ; + + compute_det_3x3(_d2_ce_, _pb_zz_, + _d2_be_, _pc_zz_, + _d2_bc_, _pe_zz_, + _d3_bce, +3) ; + + compute_det_3x3(_d2_de_, _pb_zz_, + _d2_be_, _pd_zz_, + _d2_bd_, _pe_zz_, + _d3_bde, +3) ; + + compute_det_3x3(_d2_de_, _pc_zz_, + _d2_ce_, _pd_zz_, + _d2_cd_, _pe_zz_, + _d3_cde, +3) ; + + /*-------------------------------------- 4 x 4 minors */ + unitary_det_4x4(_d3_cde, _d3_bde, + _d3_bce, _d3_bcd, + _d4bcde, +4) ; + + unitary_det_4x4(_d3_cde, _d3_ade, + _d3_ace, _d3_acd, + _d4acde, +4) ; + + unitary_det_4x4(_d3_bde, _d3_ade, + _d3_abe, _d3_abd, + _d4abde, +4) ; + + unitary_det_4x4(_d3_bce, _d3_ace, + _d3_abe, _d3_abc, + _d4abce, +4) ; + + unitary_det_4x4(_d3_bcd, _d3_acd, + _d3_abd, _d3_abc, + _d4abcd, +4) ; + + /*-------------------------------------- 5 x 5 result */ + compute_det_5x5(_d4bcde, _a_lift, + _d4acde, _b_lift, + _d4abde, _c_lift, + _d4abce, _d_lift, + _d4abcd, _e_lift, + _d5full, +4) ; + + /*-------------------------------------- leading det. */ + return mp::expansion_est(_d5full) ; + } + + __normal_call REAL_TYPE inball3d_i ( + __const_ptr(REAL_TYPE) _pa , + __const_ptr(REAL_TYPE) _pb , + __const_ptr(REAL_TYPE) _pc , + __const_ptr(REAL_TYPE) _pd , + __const_ptr(REAL_TYPE) _pe , + bool_type &_OK + ) + { + /*--------------- inball3d predicate, "bound" version */ + ia_flt _aex, _aey, _aez , + _ali, + _bex, _bey, _bez , + _bli, + _cex, _cey, _cez , + _cli, + _dex, _dey, _dez , + _dli; + ia_flt _aexbey, _bexaey , + _aexcey, _cexaey , + _bexcey, _cexbey , + _cexdey, _dexcey , + _dexaey, _aexdey , + _bexdey, _dexbey ; + ia_flt _ab_, _bc_, _cd_, _da_, + _ac_, _bd_; + ia_flt _abc, _bcd, _cda, _dab; + ia_flt _d44; + + ia_rnd _rnd; // up rounding! + + _aex.from_sub(_pa[0], _pe[0]) ; // coord. diff. + _aey.from_sub(_pa[1], _pe[1]) ; + _aez.from_sub(_pa[2], _pe[2]) ; + + _bex.from_sub(_pb[0], _pe[0]) ; + _bey.from_sub(_pb[1], _pe[1]) ; + _bez.from_sub(_pb[2], _pe[2]) ; + + _cex.from_sub(_pc[0], _pe[0]) ; + _cey.from_sub(_pc[1], _pe[1]) ; + _cez.from_sub(_pc[2], _pe[2]) ; + + _dex.from_sub(_pd[0], _pe[0]) ; + _dey.from_sub(_pd[1], _pe[1]) ; + _dez.from_sub(_pd[2], _pe[2]) ; + + _ali = sqr (_aex) + sqr (_aey) // lifted terms + + sqr (_aez) ; + + _bli = sqr (_bex) + sqr (_bey) + + sqr (_bez) ; + + _cli = sqr (_cex) + sqr (_cey) + + sqr (_cez) ; + + _dli = sqr (_dex) + sqr (_dey) + + sqr (_dez) ; + + _aexbey = _aex * _bey ; // 2 x 2 minors + _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 = // 3 x 3 minors + _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_ ; + + _d44 = // 4 x 4 result + _dli * _abc - _cli * _dab + + _bli * _cda - _ali * _bcd ; + + _OK = + _d44.lo() >= (REAL_TYPE)0. + ||_d44.up() <= (REAL_TYPE)0.; + + return ( _d44.mid() ) ; + } + + __normal_call REAL_TYPE inball3d_f ( + __const_ptr(REAL_TYPE) _pa , + __const_ptr(REAL_TYPE) _pb , + __const_ptr(REAL_TYPE) _pc , + __const_ptr(REAL_TYPE) _pd , + __const_ptr(REAL_TYPE) _pe , + bool_type &_OK + ) + { + /*--------------- inball3d predicate, "float" version */ + REAL_TYPE static const _ER = + + 17. * std::pow(mp::_epsilon, 1) ; + + REAL_TYPE _aex, _aey, _aez , + _ali, + _bex, _bey, _bez , + _bli, + _cex, _cey, _cez , + _cli, + _dex, _dey, _dez , + _dli; + REAL_TYPE _aexbey, _bexaey , + _aexcey, _cexaey , + _bexcey, _cexbey , + _cexdey, _dexcey , + _dexaey, _aexdey , + _bexdey, _dexbey ; + REAL_TYPE _ab_, _bc_, _cd_, _da_, + _ac_, _bd_; + REAL_TYPE _abc, _bcd, _cda, _dab; + + REAL_TYPE _AEZ, _BEZ, _CEZ, _DEZ; + REAL_TYPE _AEXBEY, _BEXAEY , + _AEXCEY, _CEXAEY , + _BEXCEY, _CEXBEY , + _CEXDEY, _DEXCEY , + _DEXAEY, _AEXDEY , + _BEXDEY, _DEXBEY ; + REAL_TYPE _AB_, _BC_, _CD_, _DA_, + _AC_, _BD_; + REAL_TYPE _ABC, _BCD, _CDA, _DAB; + + REAL_TYPE _d44, _FT ; + + _aex = _pa [0] - _pe [0] ; // coord. diff. + _aey = _pa [1] - _pe [1] ; + _aez = _pa [2] - _pe [2] ; + + _AEZ = std::abs (_aez) ; + + _bex = _pb [0] - _pe [0] ; + _bey = _pb [1] - _pe [1] ; + _bez = _pb [2] - _pe [2] ; + + _BEZ = std::abs (_bez) ; + + _cex = _pc [0] - _pe [0] ; + _cey = _pc [1] - _pe [1] ; + _cez = _pc [2] - _pe [2] ; + + _CEZ = std::abs (_cez) ; + + _dex = _pd [0] - _pe [0] ; + _dey = _pd [1] - _pe [1] ; + _dez = _pd [2] - _pe [2] ; + + _DEZ = std::abs (_dez) ; + + _ali = _aex * _aex + _aey * _aey // lifted terms + + _aez * _aez ; + + _bli = _bex * _bex + _bey * _bey + + _bez * _bez ; + + _cli = _cex * _cex + _cey * _cey + + _cez * _cez ; + + _dli = _dex * _dex + _dey * _dey + + _dez * _dez ; + + _aexbey = _aex * _bey ; // 2 x 2 minors + _bexaey = _bex * _aey ; + _ab_ = _aexbey - _bexaey ; + + _AEXBEY = std::abs (_aexbey) ; + _BEXAEY = std::abs (_bexaey) ; + _AB_ = _AEXBEY + _BEXAEY ; + + _bexcey = _bex * _cey; + _cexbey = _cex * _bey; + _bc_ = _bexcey - _cexbey ; + + _BEXCEY = std::abs (_bexcey) ; + _CEXBEY = std::abs (_cexbey) ; + _BC_ = _BEXCEY + _CEXBEY ; + + _cexdey = _cex * _dey; + _dexcey = _dex * _cey; + _cd_ = _cexdey - _dexcey ; + + _CEXDEY = std::abs (_cexdey) ; + _DEXCEY = std::abs (_dexcey) ; + _CD_ = _CEXDEY + _DEXCEY ; + + _dexaey = _dex * _aey; + _aexdey = _aex * _dey; + _da_ = _dexaey - _aexdey ; + + _DEXAEY = std::abs (_dexaey) ; + _AEXDEY = std::abs (_aexdey) ; + _DA_ = _DEXAEY + _AEXDEY ; + + _aexcey = _aex * _cey; + _cexaey = _cex * _aey; + _ac_ = _aexcey - _cexaey ; + + _AEXCEY = std::abs (_aexcey) ; + _CEXAEY = std::abs (_cexaey) ; + _AC_ = _AEXCEY + _CEXAEY ; + + _bexdey = _bex * _dey; + _dexbey = _dex * _bey; + _bd_ = _bexdey - _dexbey ; + + _BEXDEY = std::abs (_bexdey) ; + _DEXBEY = std::abs (_dexbey) ; + _BD_ = _BEXDEY + _DEXBEY ; + + _abc = // 3 x 3 minors + _aez * _bc_ - _bez * _ac_ + + _cez * _ab_ ; + _ABC = + _AEZ * _BC_ + _BEZ * _AC_ + + _CEZ * _AB_ ; + + _bcd = + _bez * _cd_ - _cez * _bd_ + + _dez * _bc_ ; + _BCD = + _BEZ * _CD_ + _CEZ * _BD_ + + _DEZ * _BC_ ; + + _cda = + _cez * _da_ + _dez * _ac_ + + _aez * _cd_ ; + _CDA = + _CEZ * _DA_ + _DEZ * _AC_ + + _AEZ * _CD_ ; + + _dab = + _dez * _ab_ + _aez * _bd_ + + _bez * _da_ ; + _DAB = + _DEZ * _AB_ + _AEZ * _BD_ + + _BEZ * _DA_ ; + + _FT = // roundoff tol + _dli * _ABC + _cli * _DAB + + _bli * _CDA + _ali * _BCD ; + + _FT *= _ER ; + + _d44 = // 4 x 4 result + _dli * _abc - _cli * _dab + + _bli * _cda - _ali * _bcd ; + + _OK = + _d44 > _FT || _d44 < -_FT ; + + return ( _d44 ) ; + } + + /* + -------------------------------------------------------- + * + * Compute an exact determinant using multi-precision + * expansions, a'la shewchuk + * + * | ax ay az dot(a, a) - aw +1. | + * | bx by bz dot(b, b) - bw +1. | + * | cx cy cz dot(c, c) - cw +1. | + * | dx dy dz dot(d, d) - dw +1. | + * | ex ey ez dot(e, e) - ew +1. | + * + * This is the weighted "in-ball" predicate in E^3. + * + -------------------------------------------------------- + */ + + __normal_call REAL_TYPE inball3w_e ( + __const_ptr(REAL_TYPE) _pa , + __const_ptr(REAL_TYPE) _pb , + __const_ptr(REAL_TYPE) _pc , + __const_ptr(REAL_TYPE) _pd , + __const_ptr(REAL_TYPE) _pe , + bool_type &_OK + ) + { + /*--------------- inball3w predicate, "exact" version */ + mp::expansion< 7 > _a_lift, _b_lift, + _c_lift, _d_lift, + _e_lift; + mp::expansion< 6 > _t_lift; + mp::expansion< 4 > _d2_ab_, _d2_ac_, + _d2_ad_, _d2_ae_, + _d2_bc_, _d2_bd_, + _d2_be_, + _d2_cd_, _d2_ce_, + _d2_de_; + mp::expansion< 24> _d3_abc, _d3_abd, + _d3_abe, + _d3_acd, _d3_ace, + _d3_ade, + _d3_bcd, _d3_bce, + _d3_bde, _d3_cde; + mp::expansion< 96> _d4abcd, _d4abce, + _d4abde, _d4acde, + _d4bcde; + mp::expansion<6720>_d5full; + + _OK = true; + + mp::expansion< 1 > _pa_zz_(_pa[ 2]); + mp::expansion< 1 > _pb_zz_(_pb[ 2]); + mp::expansion< 1 > _pc_zz_(_pc[ 2]); + mp::expansion< 1 > _pd_zz_(_pd[ 2]); + mp::expansion< 1 > _pe_zz_(_pe[ 2]); + + /*-------------------------------------- lifted terms */ + mp::expansion_add( + mp::expansion_from_sqr(_pa[ 0]), + mp::expansion_from_sqr(_pa[ 1]), + mp::expansion_from_sqr(_pa[ 2]), + _t_lift ) ; + mp::expansion_sub( + _t_lift , _pa[ 3] , _a_lift); + + mp::expansion_add( + mp::expansion_from_sqr(_pb[ 0]), + mp::expansion_from_sqr(_pb[ 1]), + mp::expansion_from_sqr(_pb[ 2]), + _t_lift ) ; + mp::expansion_sub( + _t_lift , _pb[ 3] , _b_lift); + + mp::expansion_add( + mp::expansion_from_sqr(_pc[ 0]), + mp::expansion_from_sqr(_pc[ 1]), + mp::expansion_from_sqr(_pc[ 2]), + _t_lift ) ; + mp::expansion_sub( + _t_lift , _pc[ 3] , _c_lift); + + mp::expansion_add( + mp::expansion_from_sqr(_pd[ 0]), + mp::expansion_from_sqr(_pd[ 1]), + mp::expansion_from_sqr(_pd[ 2]), + _t_lift ) ; + mp::expansion_sub( + _t_lift , _pd[ 3] , _d_lift); + + mp::expansion_add( + mp::expansion_from_sqr(_pe[ 0]), + mp::expansion_from_sqr(_pe[ 1]), + mp::expansion_from_sqr(_pe[ 2]), + _t_lift ) ; + mp::expansion_sub( + _t_lift , _pe[ 3] , _e_lift); + + /*-------------------------------------- 2 x 2 minors */ + compute_det_2x2(_pa[ 0], _pa[ 1], + _pb[ 0], _pb[ 1], + _d2_ab_ ) ; + + compute_det_2x2(_pa[ 0], _pa[ 1], + _pc[ 0], _pc[ 1], + _d2_ac_ ) ; + + compute_det_2x2(_pa[ 0], _pa[ 1], + _pd[ 0], _pd[ 1], + _d2_ad_ ) ; + + compute_det_2x2(_pa[ 0], _pa[ 1], + _pe[ 0], _pe[ 1], + _d2_ae_ ) ; + + compute_det_2x2(_pb[ 0], _pb[ 1], + _pc[ 0], _pc[ 1], + _d2_bc_ ) ; + + compute_det_2x2(_pb[ 0], _pb[ 1], + _pd[ 0], _pd[ 1], + _d2_bd_ ) ; + + compute_det_2x2(_pb[ 0], _pb[ 1], + _pe[ 0], _pe[ 1], + _d2_be_ ) ; + + compute_det_2x2(_pc[ 0], _pc[ 1], + _pd[ 0], _pd[ 1], + _d2_cd_ ) ; + + compute_det_2x2(_pc[ 0], _pc[ 1], + _pe[ 0], _pe[ 1], + _d2_ce_ ) ; + + compute_det_2x2(_pd[ 0], _pd[ 1], + _pe[ 0], _pe[ 1], + _d2_de_ ) ; + + /*-------------------------------------- 3 x 3 minors */ + compute_det_3x3(_d2_bc_, _pa_zz_, + _d2_ac_, _pb_zz_, + _d2_ab_, _pc_zz_, + _d3_abc, +3) ; + + compute_det_3x3(_d2_bd_, _pa_zz_, + _d2_ad_, _pb_zz_, + _d2_ab_, _pd_zz_, + _d3_abd, +3) ; + + compute_det_3x3(_d2_be_, _pa_zz_, + _d2_ae_, _pb_zz_, + _d2_ab_, _pe_zz_, + _d3_abe, +3) ; + + compute_det_3x3(_d2_cd_, _pa_zz_, + _d2_ad_, _pc_zz_, + _d2_ac_, _pd_zz_, + _d3_acd, +3) ; + + compute_det_3x3(_d2_ce_, _pa_zz_, + _d2_ae_, _pc_zz_, + _d2_ac_, _pe_zz_, + _d3_ace, +3) ; + + compute_det_3x3(_d2_de_, _pa_zz_, + _d2_ae_, _pd_zz_, + _d2_ad_, _pe_zz_, + _d3_ade, +3) ; + + compute_det_3x3(_d2_cd_, _pb_zz_, + _d2_bd_, _pc_zz_, + _d2_bc_, _pd_zz_, + _d3_bcd, +3) ; + + compute_det_3x3(_d2_ce_, _pb_zz_, + _d2_be_, _pc_zz_, + _d2_bc_, _pe_zz_, + _d3_bce, +3) ; + + compute_det_3x3(_d2_de_, _pb_zz_, + _d2_be_, _pd_zz_, + _d2_bd_, _pe_zz_, + _d3_bde, +3) ; + + compute_det_3x3(_d2_de_, _pc_zz_, + _d2_ce_, _pd_zz_, + _d2_cd_, _pe_zz_, + _d3_cde, +3) ; + + /*-------------------------------------- 4 x 4 minors */ + unitary_det_4x4(_d3_cde, _d3_bde, + _d3_bce, _d3_bcd, + _d4bcde, +4) ; + + unitary_det_4x4(_d3_cde, _d3_ade, + _d3_ace, _d3_acd, + _d4acde, +4) ; + + unitary_det_4x4(_d3_bde, _d3_ade, + _d3_abe, _d3_abd, + _d4abde, +4) ; + + unitary_det_4x4(_d3_bce, _d3_ace, + _d3_abe, _d3_abc, + _d4abce, +4) ; + + unitary_det_4x4(_d3_bcd, _d3_acd, + _d3_abd, _d3_abc, + _d4abcd, +4) ; + + /*-------------------------------------- 5 x 5 result */ + compute_det_5x5(_d4bcde, _a_lift, + _d4acde, _b_lift, + _d4abde, _c_lift, + _d4abce, _d_lift, + _d4abcd, _e_lift, + _d5full, +4) ; + + /*-------------------------------------- leading det. */ + return mp::expansion_est(_d5full) ; + } + + __normal_call REAL_TYPE inball3w_i ( + __const_ptr(REAL_TYPE) _pa , + __const_ptr(REAL_TYPE) _pb , + __const_ptr(REAL_TYPE) _pc , + __const_ptr(REAL_TYPE) _pd , + __const_ptr(REAL_TYPE) _pe , + bool_type &_OK + ) + { + /*--------------- inball3w predicate, "bound" version */ + ia_flt _aex, _aey, _aez , + _aew, _ali, + _bex, _bey, _bez , + _bew, _bli, + _cex, _cey, _cez , + _cew, _cli, + _dex, _dey, _dez , + _dew, _dli; + ia_flt _aexbey, _bexaey , + _aexcey, _cexaey , + _bexcey, _cexbey , + _cexdey, _dexcey , + _dexaey, _aexdey , + _bexdey, _dexbey ; + ia_flt _ab_, _bc_, _cd_, _da_, + _ac_, _bd_; + ia_flt _abc, _bcd, _cda, _dab; + ia_flt _d44; + + ia_rnd _rnd; // up rounding! + + _aex.from_sub(_pa[0], _pe[0]) ; // coord. diff. + _aey.from_sub(_pa[1], _pe[1]) ; + _aez.from_sub(_pa[2], _pe[2]) ; + _aew.from_sub(_pa[3], _pe[3]) ; + + _bex.from_sub(_pb[0], _pe[0]) ; + _bey.from_sub(_pb[1], _pe[1]) ; + _bez.from_sub(_pb[2], _pe[2]) ; + _bew.from_sub(_pb[3], _pe[3]) ; + + _cex.from_sub(_pc[0], _pe[0]) ; + _cey.from_sub(_pc[1], _pe[1]) ; + _cez.from_sub(_pc[2], _pe[2]) ; + _cew.from_sub(_pc[3], _pe[3]) ; + + _dex.from_sub(_pd[0], _pe[0]) ; + _dey.from_sub(_pd[1], _pe[1]) ; + _dez.from_sub(_pd[2], _pe[2]) ; + _dew.from_sub(_pd[3], _pe[3]) ; + + _ali = sqr(_aex) + sqr(_aey) // lifted terms + + sqr(_aez) - _aew ; + + _bli = sqr(_bex) + sqr(_bey) + + sqr(_bez) - _bew ; + + _cli = sqr(_cex) + sqr(_cey) + + sqr(_cez) - _cew ; + + _dli = sqr(_dex) + sqr(_dey) + + sqr(_dez) - _dew ; + + _aexbey = _aex * _bey ; // 2 x 2 minors + _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 = // 3 x 3 minors + _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_ ; + + _d44 = // 4 x 4 result + _dli * _abc - _cli * _dab + + _bli * _cda - _ali * _bcd ; + + _OK = + _d44.lo() >= (REAL_TYPE)0. + ||_d44.up() <= (REAL_TYPE)0.; + + return ( _d44.mid() ) ; + } + + __normal_call REAL_TYPE inball3w_f ( + __const_ptr(REAL_TYPE) _pa , + __const_ptr(REAL_TYPE) _pb , + __const_ptr(REAL_TYPE) _pc , + __const_ptr(REAL_TYPE) _pd , + __const_ptr(REAL_TYPE) _pe , + bool_type &_OK + ) + { + /*--------------- inball3w predicate, "float" version */ + REAL_TYPE static const _ER = + + 18. * std::pow(mp::_epsilon, 1) ; + + REAL_TYPE _aex, _aey, _aez , + _aew, _ali, + _bex, _bey, _bez , + _bew, _bli, + _cex, _cey, _cez , + _cew, _cli, + _dex, _dey, _dez , + _dew, _dli; + REAL_TYPE _aexbey, _bexaey , + _aexcey, _cexaey , + _bexcey, _cexbey , + _cexdey, _dexcey , + _dexaey, _aexdey , + _bexdey, _dexbey ; + REAL_TYPE _ab_, _bc_, _cd_, _da_, + _ac_, _bd_; + REAL_TYPE _abc, _bcd, _cda, _dab; + + REAL_TYPE _AEZ, _BEZ, _CEZ, _DEZ; + REAL_TYPE _ALI, _BLI, _CLI, _DLI; + REAL_TYPE _AEXBEY, _BEXAEY , + _CEXAEY, _AEXCEY , + _BEXCEY, _CEXBEY , + _CEXDEY, _DEXCEY , + _DEXAEY, _AEXDEY , + _BEXDEY, _DEXBEY ; + REAL_TYPE _AB_, _BC_, _CD_, _DA_, + _AC_, _BD_; + REAL_TYPE _ABC, _BCD, _CDA, _DAB; + + REAL_TYPE _d44, _FT ; + + _aex = _pa [0] - _pe [0] ; // coord. diff. + _aey = _pa [1] - _pe [1] ; + _aez = _pa [2] - _pe [2] ; + _aew = _pa [3] - _pe [3] ; + + _AEZ = std::abs (_aez) ; + + _bex = _pb [0] - _pe [0] ; + _bey = _pb [1] - _pe [1] ; + _bez = _pb [2] - _pe [2] ; + _bew = _pb [3] - _pe [3] ; + + _BEZ = std::abs (_bez) ; + + _cex = _pc [0] - _pe [0] ; + _cey = _pc [1] - _pe [1] ; + _cez = _pc [2] - _pe [2] ; + _cew = _pc [3] - _pe [3] ; + + _CEZ = std::abs (_cez) ; + + _dex = _pd [0] - _pe [0] ; + _dey = _pd [1] - _pe [1] ; + _dez = _pd [2] - _pe [2] ; + _dew = _pd [3] - _pe [3] ; + + _DEZ = std::abs (_dez) ; + + _ali = _aex * _aex + _aey * _aey // lifted terms + + _aez * _aez - _aew ; + + _ALI = std::abs (_ali) ; + + _bli = _bex * _bex + _bey * _bey + + _bez * _bez - _bew ; + + _BLI = std::abs (_bli) ; + + _cli = _cex * _cex + _cey * _cey + + _cez * _cez - _cew ; + + _CLI = std::abs (_cli) ; + + _dli = _dex * _dex + _dey * _dey + + _dez * _dez - _dew ; + + _DLI = std::abs (_dli) ; + + _aexbey = _aex * _bey ; // 2 x 2 minors + _bexaey = _bex * _aey ; + _ab_ = _aexbey - _bexaey ; + + _AEXBEY = std::abs (_aexbey) ; + _BEXAEY = std::abs (_bexaey) ; + _AB_ = _AEXBEY + _BEXAEY ; + + _bexcey = _bex * _cey; + _cexbey = _cex * _bey; + _bc_ = _bexcey - _cexbey ; + + _BEXCEY = std::abs (_bexcey) ; + _CEXBEY = std::abs (_cexbey) ; + _BC_ = _BEXCEY + _CEXBEY ; + + _cexdey = _cex * _dey; + _dexcey = _dex * _cey; + _cd_ = _cexdey - _dexcey ; + + _CEXDEY = std::abs (_cexdey) ; + _DEXCEY = std::abs (_dexcey) ; + _CD_ = _CEXDEY + _DEXCEY ; + + _dexaey = _dex * _aey; + _aexdey = _aex * _dey; + _da_ = _dexaey - _aexdey ; + + _DEXAEY = std::abs (_dexaey) ; + _AEXDEY = std::abs (_aexdey) ; + _DA_ = _DEXAEY + _AEXDEY ; + + _aexcey = _aex * _cey; + _cexaey = _cex * _aey; + _ac_ = _aexcey - _cexaey ; + + _AEXCEY = std::abs (_aexcey) ; + _CEXAEY = std::abs (_cexaey) ; + _AC_ = _AEXCEY + _CEXAEY ; + + _bexdey = _bex * _dey; + _dexbey = _dex * _bey; + _bd_ = _bexdey - _dexbey ; + + _BEXDEY = std::abs (_bexdey) ; + _DEXBEY = std::abs (_dexbey) ; + _BD_ = _BEXDEY + _DEXBEY ; + + _abc = // 3 x 3 minors + _aez * _bc_ - _bez * _ac_ + + _cez * _ab_ ; + _ABC = + _AEZ * _BC_ + _BEZ * _AC_ + + _CEZ * _AB_ ; + + _bcd = + _bez * _cd_ - _cez * _bd_ + + _dez * _bc_ ; + _BCD = + _BEZ * _CD_ + _CEZ * _BD_ + + _DEZ * _BC_ ; + + _cda = + _cez * _da_ + _dez * _ac_ + + _aez * _cd_ ; + _CDA = + _CEZ * _DA_ + _DEZ * _AC_ + + _AEZ * _CD_ ; + + _dab = + _dez * _ab_ + _aez * _bd_ + + _bez * _da_ ; + _DAB = + _DEZ * _AB_ + _AEZ * _BD_ + + _BEZ * _DA_ ; + + _FT = // roundoff tol + _DLI * _ABC + _CLI * _DAB + + _BLI * _CDA + _ALI * _BCD ; + + _FT *= _ER ; + + _d44 = // 4 x 4 result + _dli * _abc - _cli * _dab + + _bli * _cda - _ali * _bcd ; + + _OK = + _d44 > _FT || _d44 < -_FT ; + + return ( _d44 ) ; + } + + + + + + #define EVAL_FP_DET_2x2(__aa, __bb, __cc, __dd, \ + __r2, __R2) \ + { \ + REAL_TYPE __aadd, __bbcc; \ + __aadd = __aa * __dd ; \ + __bbcc = __bb * __cc ; \ + __r2 = __aadd - __bbcc ; \ + \ + REAL_TYPE __AADD, __BBCC; \ + __AADD = std::abs(__aadd) ; \ + __BBCC = std::abs(__bbcc) ; \ + __R2 = __AADD + __BBCC ; \ + } + + #define EVAL_FP_DET_3x3(__a2, __va, __b2, __vb, \ + __c2, __vc, \ + __A2, __VA, __B2, __VB, \ + __C2, __VC, \ + __r3, __R3) \ + { \ + __r3 = \ + __va * __a2 + __vb * __b2 \ + + __vc * __c2 ; \ + \ + __R3 = \ + __VA * __A2 + __VB * __B2 \ + + __VC * __C2 ; \ + } + + #define EVAL_FP_DET_4x4(__a3, __va, __b3, __vb, \ + __c3, __vc, __d3, __vd, \ + __A3, __VA, __B3, __VB, \ + __C3, __VC, __D3, __VD, \ + __r4, __R4) \ + { \ + __r4 = \ + __va * __a3 + __vb * __b3 \ + + __vc * __c3 + __vd * __d3 ; \ + \ + __R4 = \ + __VA * __A3 + __VB * __B3 \ + + __VC * __A3 + __VD * __D3 ; \ + } + + + + + + diff --git a/src/libcpp/predicate/orient_k.hpp b/src/libcpp/predicate/orient_k.hpp new file mode 100644 index 0000000..7fcac4b --- /dev/null +++ b/src/libcpp/predicate/orient_k.hpp @@ -0,0 +1,848 @@ + + /* + -------------------------------------------------------- + * PREDICATE-k: robust geometric predicates in E^k. + -------------------------------------------------------- + * + * 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/ + * + -------------------------------------------------------- + */ + + // from predicate_k.hpp... + + + /* + -------------------------------------------------------- + * + * Compute an exact determinant using multi-precision + * expansions, a'la shewchuk + * + * | ax ay +1. | + * | bx by +1. | + * | cx cy +1. | + * + * This is the planar "orientation" predicate in E^2. + * + -------------------------------------------------------- + */ + + __normal_call REAL_TYPE orient2d_e ( + __const_ptr(REAL_TYPE) _pa , + __const_ptr(REAL_TYPE) _pb , + __const_ptr(REAL_TYPE) _pc , + bool_type &_OK + ) + { + /*--------------- orient2d predicate, "exact" version */ + mp::expansion< 4 > _d2_ab_, _d2_ac_, + _d2_bc_; + mp::expansion< 12> _d3full; + + _OK = true; + + /*-------------------------------------- 2 x 2 minors */ + compute_det_2x2(_pa[ 0], _pa[ 1], + _pb[ 0], _pb[ 1], + _d2_ab_ ) ; + + compute_det_2x2(_pa[ 0], _pa[ 1], + _pc[ 0], _pc[ 1], + _d2_ac_ ) ; + + compute_det_2x2(_pb[ 0], _pb[ 1], + _pc[ 0], _pc[ 1], + _d2_bc_ ) ; + + /*-------------------------------------- 3 x 3 result */ + unitary_det_3x3(_d2_bc_, _d2_ac_, + _d2_ab_, + _d3full, +3) ; + + /*-------------------------------------- leading det. */ + return mp::expansion_est(_d3full) ; + } + + __normal_call REAL_TYPE orient2d_i ( + __const_ptr(REAL_TYPE) _pa , + __const_ptr(REAL_TYPE) _pb , + __const_ptr(REAL_TYPE) _pc , + bool_type &_OK + ) + { + /*--------------- orient2d predicate, "bound" version */ + ia_flt _acx, _acy ; + ia_flt _bcx, _bcy ; + ia_flt _acxbcy, _acybcx ; + + ia_flt _sgn; + + ia_rnd _rnd; // up rounding! + + _acx.from_sub(_pa[0], _pc[0]) ; // coord. diff. + _acy.from_sub(_pa[1], _pc[1]) ; + + _bcx.from_sub(_pb[0], _pc[0]) ; + _bcy.from_sub(_pb[1], _pc[1]) ; + + _acxbcy = _acx * _bcy ; + _acybcx = _acy * _bcx ; + + _sgn = _acxbcy - _acybcx ; // 2 x 2 result + + _OK = + _sgn.lo() >= (REAL_TYPE)0. + || _sgn.up() <= (REAL_TYPE)0. ; + + return ( _sgn.mid() ) ; + } + + __normal_call REAL_TYPE orient2d_f ( + __const_ptr(REAL_TYPE) _pa , + __const_ptr(REAL_TYPE) _pb , + __const_ptr(REAL_TYPE) _pc , + bool_type &_OK + ) + { + /*--------------- orient2d predicate, "float" version */ + REAL_TYPE static const _ER = + + 4. * std::pow(mp::_epsilon, 1) ; + + REAL_TYPE _acx, _acy ; + REAL_TYPE _bcx, _bcy ; + REAL_TYPE _acxbcy, _acybcx ; + + REAL_TYPE _ACXBCY, _ACYBCX ; + + REAL_TYPE _sgn, _FT; + + _acx = _pa [0] - _pc [0] ; // coord. diff. + _acy = _pa [1] - _pc [1] ; + + _bcx = _pb [0] - _pc [0] ; + _bcy = _pb [1] - _pc [1] ; + + _acxbcy = _acx * _bcy ; + _acybcx = _acy * _bcx ; + + _ACXBCY = std::abs(_acxbcy); + _ACYBCX = std::abs(_acybcx); + + _FT = _ACXBCY + _ACYBCX ; // roundoff tol + _FT *= _ER ; + + _sgn = _acxbcy - _acybcx ; // 2 x 2 result + + _OK = + _sgn > +_FT || _sgn < -_FT ; + + return ( _sgn ) ; + } + + /* + -------------------------------------------------------- + * + * Compute an exact determinant using multi-precision + * expansions, a'la shewchuk + * + * | ax ay az +1. | + * | bx by bz +1. | + * | cx cy cz +1. | + * | dx dy dz +1. | + * + * This is the planar "orientation" predicate in E^3. + * + -------------------------------------------------------- + */ + + __normal_call REAL_TYPE orient3d_e ( + __const_ptr(REAL_TYPE) _pa , + __const_ptr(REAL_TYPE) _pb , + __const_ptr(REAL_TYPE) _pc , + __const_ptr(REAL_TYPE) _pd , + bool_type &_OK + ) + { + /*--------------- orient3d predicate, "exact" version */ + mp::expansion< 4 > _d2_ab_, _d2_ac_, + _d2_ad_, + _d2_bc_, _d2_bd_, + _d2_cd_; + mp::expansion< 12> _d3_abc, _d3_abd, + _d3_acd, _d3_bcd; + mp::expansion< 96> _d4full; + + _OK = true; + + mp::expansion< 1 > _pa_zz_(_pa[ 2]); + mp::expansion< 1 > _pb_zz_(_pb[ 2]); + mp::expansion< 1 > _pc_zz_(_pc[ 2]); + mp::expansion< 1 > _pd_zz_(_pd[ 2]); + + /*-------------------------------------- 2 x 2 minors */ + compute_det_2x2(_pa[ 0], _pa[ 1], + _pb[ 0], _pb[ 1], + _d2_ab_ ) ; + + compute_det_2x2(_pa[ 0], _pa[ 1], + _pc[ 0], _pc[ 1], + _d2_ac_ ) ; + + compute_det_2x2(_pa[ 0], _pa[ 1], + _pd[ 0], _pd[ 1], + _d2_ad_ ) ; + + compute_det_2x2(_pb[ 0], _pb[ 1], + _pc[ 0], _pc[ 1], + _d2_bc_ ) ; + + compute_det_2x2(_pb[ 0], _pb[ 1], + _pd[ 0], _pd[ 1], + _d2_bd_ ) ; + + compute_det_2x2(_pc[ 0], _pc[ 1], + _pd[ 0], _pd[ 1], + _d2_cd_ ) ; + + /*-------------------------------------- 3 x 3 minors */ + unitary_det_3x3(_d2_cd_, _d2_bd_, + _d2_bc_, + _d3_bcd, +3) ; + + unitary_det_3x3(_d2_cd_, _d2_ad_, + _d2_ac_, + _d3_acd, +3) ; + + unitary_det_3x3(_d2_bd_, _d2_ad_, + _d2_ab_, + _d3_abd, +3) ; + + unitary_det_3x3(_d2_bc_, _d2_ac_, + _d2_ab_, + _d3_abc, +3) ; + + /*-------------------------------------- 4 x 4 result */ + compute_det_4x4(_d3_bcd, _pa_zz_, + _d3_acd, _pb_zz_, + _d3_abd, _pc_zz_, + _d3_abc, _pd_zz_, + _d4full, +3) ; + + /*-------------------------------------- leading det. */ + return mp::expansion_est(_d4full) ; + } + + __normal_call REAL_TYPE orient3d_i ( + __const_ptr(REAL_TYPE) _pa , + __const_ptr(REAL_TYPE) _pb , + __const_ptr(REAL_TYPE) _pc , + __const_ptr(REAL_TYPE) _pd , + bool_type &_OK + ) + { + /*--------------- orient3d predicate, "bound" version */ + ia_flt _adx, _ady, _adz , + _bdx, _bdy, _bdz , + _cdx, _cdy, _cdz ; + ia_flt _bdxcdy, _cdxbdy , + _cdxady, _adxcdy , + _adxbdy, _bdxady ; + + ia_flt _sgn; + + ia_rnd _rnd; // up rounding! + + _adx.from_sub(_pa[0], _pd[0]) ; // coord. diff. + _ady.from_sub(_pa[1], _pd[1]) ; + _adz.from_sub(_pa[2], _pd[2]) ; + + _bdx.from_sub(_pb[0], _pd[0]) ; + _bdy.from_sub(_pb[1], _pd[1]) ; + _bdz.from_sub(_pb[2], _pd[2]) ; + + _cdx.from_sub(_pc[0], _pd[0]) ; + _cdy.from_sub(_pc[1], _pd[1]) ; + _cdz.from_sub(_pc[2], _pd[2]) ; + + _bdxcdy = _bdx * _cdy ; // 2 x 2 minors + _cdxbdy = _cdx * _bdy ; + _cdxady = _cdx * _ady ; + _adxcdy = _adx * _cdy ; + _adxbdy = _adx * _bdy ; + _bdxady = _bdx * _ady ; + + _sgn = // 3 x 3 result + _adz * (_bdxcdy - _cdxbdy) + + _bdz * (_cdxady - _adxcdy) + + _cdz * (_adxbdy - _bdxady); + + _OK = + _sgn.lo() >= (REAL_TYPE)0. + ||_sgn.up() <= (REAL_TYPE)0.; + + return ( _sgn.mid() ) ; + } + + __normal_call REAL_TYPE orient3d_f ( + __const_ptr(REAL_TYPE) _pa , + __const_ptr(REAL_TYPE) _pb , + __const_ptr(REAL_TYPE) _pc , + __const_ptr(REAL_TYPE) _pd , + bool_type &_OK + ) + { + /*--------------- orient3d predicate, "float" version */ + REAL_TYPE static const _ER = + + 8. * std::pow(mp::_epsilon, 1) ; + + REAL_TYPE _adx, _ady, _adz , + _bdx, _bdy, _bdz , + _cdx, _cdy, _cdz ; + REAL_TYPE _bdxcdy, _cdxbdy , + _cdxady, _adxcdy , + _adxbdy, _bdxady ; + + REAL_TYPE _ADZ, _BDZ, _CDZ ; + REAL_TYPE _BDXCDY, _CDXBDY , + _CDXADY, _ADXCDY , + _ADXBDY, _BDXADY ; + + REAL_TYPE _sgn, _FT; + + _adx = _pa [0] - _pd [0] ; // coord. diff. + _ady = _pa [1] - _pd [1] ; + _adz = _pa [2] - _pd [2] ; + + _ADZ = std::abs (_adz) ; + + _bdx = _pb [0] - _pd [0] ; + _bdy = _pb [1] - _pd [1] ; + _bdz = _pb [2] - _pd [2] ; + + _BDZ = std::abs (_bdz) ; + + _cdx = _pc [0] - _pd [0] ; + _cdy = _pc [1] - _pd [1] ; + _cdz = _pc [2] - _pd [2] ; + + _CDZ = std::abs (_cdz) ; + + _bdxcdy = _bdx * _cdy ; // 2 x 2 minors + _cdxbdy = _cdx * _bdy ; + _cdxady = _cdx * _ady ; + _adxcdy = _adx * _cdy ; + _adxbdy = _adx * _bdy ; + _bdxady = _bdx * _ady ; + + _BDXCDY = std::abs (_bdxcdy) ; + _CDXBDY = std::abs (_cdxbdy) ; + _CDXADY = std::abs (_cdxady) ; + _ADXCDY = std::abs (_adxcdy) ; + _ADXBDY = std::abs (_adxbdy) ; + _BDXADY = std::abs (_bdxady) ; + + _FT = // roundoff tol + _ADZ * (_BDXCDY + _CDXBDY) + + _BDZ * (_CDXADY + _ADXCDY) + + _CDZ * (_ADXBDY + _BDXADY) ; + + _FT *= _ER ; + + _sgn = // 3 x 3 result + _adz * (_bdxcdy - _cdxbdy) + + _bdz * (_cdxady - _adxcdy) + + _cdz * (_adxbdy - _bdxady) ; + + _OK = + _sgn > +_FT || _sgn < -_FT ; + + return ( _sgn ) ; + } + + /* + -------------------------------------------------------- + * + * Compute an exact determinant using multi-precision + * expansions, a'la shewchuk + * + * | ax ay az aq +1. | + * | bx by bz bq +1. | + * | cx cy cz cq +1. | + * | dx dy dz dq +1. | + * | ex ey ez eq +1. | + * + * This is the planar "orientation" predicate in E^4. + * + -------------------------------------------------------- + */ + + __normal_call REAL_TYPE orient4d_e ( + __const_ptr(REAL_TYPE) _pa , + __const_ptr(REAL_TYPE) _pb , + __const_ptr(REAL_TYPE) _pc , + __const_ptr(REAL_TYPE) _pd , + __const_ptr(REAL_TYPE) _pe , + bool_type &_OK + ) + { + /*--------------- orient4d predicate, "exact" version */ + mp::expansion< 4 > _d2_ab_, _d2_ac_, + _d2_ad_, _d2_ae_, + _d2_bc_, _d2_bd_, + _d2_be_, + _d2_cd_, _d2_ce_, + _d2_de_; + mp::expansion< 24> _d3_abc, _d3_abd, + _d3_abe, + _d3_acd, _d3_ace, + _d3_ade, + _d3_bcd, _d3_bce, + _d3_bde, _d3_cde; + mp::expansion< 96> _d4abcd, _d4abce, + _d4abde, _d4acde, + _d4bcde; + mp::expansion<960> _d5full; + + _OK = true; + + mp::expansion< 1 > _pa_zz_(_pa[ 2]); + mp::expansion< 1 > _pb_zz_(_pb[ 2]); + mp::expansion< 1 > _pc_zz_(_pc[ 2]); + mp::expansion< 1 > _pd_zz_(_pd[ 2]); + mp::expansion< 1 > _pe_zz_(_pe[ 2]); + + mp::expansion< 1 > _pa_qq_(_pa[ 3]); + mp::expansion< 1 > _pb_qq_(_pb[ 3]); + mp::expansion< 1 > _pc_qq_(_pc[ 3]); + mp::expansion< 1 > _pd_qq_(_pd[ 3]); + mp::expansion< 1 > _pe_qq_(_pe[ 3]); + + /*-------------------------------------- 2 x 2 minors */ + compute_det_2x2(_pa[ 0], _pa[ 1], + _pb[ 0], _pb[ 1], + _d2_ab_ ) ; + + compute_det_2x2(_pa[ 0], _pa[ 1], + _pc[ 0], _pc[ 1], + _d2_ac_ ) ; + + compute_det_2x2(_pa[ 0], _pa[ 1], + _pd[ 0], _pd[ 1], + _d2_ad_ ) ; + + compute_det_2x2(_pa[ 0], _pa[ 1], + _pe[ 0], _pe[ 1], + _d2_ae_ ) ; + + compute_det_2x2(_pb[ 0], _pb[ 1], + _pc[ 0], _pc[ 1], + _d2_bc_ ) ; + + compute_det_2x2(_pb[ 0], _pb[ 1], + _pd[ 0], _pd[ 1], + _d2_bd_ ) ; + + compute_det_2x2(_pb[ 0], _pb[ 1], + _pe[ 0], _pe[ 1], + _d2_be_ ) ; + + compute_det_2x2(_pc[ 0], _pc[ 1], + _pd[ 0], _pd[ 1], + _d2_cd_ ) ; + + compute_det_2x2(_pc[ 0], _pc[ 1], + _pe[ 0], _pe[ 1], + _d2_ce_ ) ; + + compute_det_2x2(_pd[ 0], _pd[ 1], + _pe[ 0], _pe[ 1], + _d2_de_ ) ; + + /*-------------------------------------- 3 x 3 minors */ + compute_det_3x3(_d2_bc_, _pa_zz_, + _d2_ac_, _pb_zz_, + _d2_ab_, _pc_zz_, + _d3_abc, +3) ; + + compute_det_3x3(_d2_bd_, _pa_zz_, + _d2_ad_, _pb_zz_, + _d2_ab_, _pd_zz_, + _d3_abd, +3) ; + + compute_det_3x3(_d2_be_, _pa_zz_, + _d2_ae_, _pb_zz_, + _d2_ab_, _pe_zz_, + _d3_abe, +3) ; + + compute_det_3x3(_d2_cd_, _pa_zz_, + _d2_ad_, _pc_zz_, + _d2_ac_, _pd_zz_, + _d3_acd, +3) ; + + compute_det_3x3(_d2_ce_, _pa_zz_, + _d2_ae_, _pc_zz_, + _d2_ac_, _pe_zz_, + _d3_ace, +3) ; + + compute_det_3x3(_d2_de_, _pa_zz_, + _d2_ae_, _pd_zz_, + _d2_ad_, _pe_zz_, + _d3_ade, +3) ; + + compute_det_3x3(_d2_cd_, _pb_zz_, + _d2_bd_, _pc_zz_, + _d2_bc_, _pd_zz_, + _d3_bcd, +3) ; + + compute_det_3x3(_d2_ce_, _pb_zz_, + _d2_be_, _pc_zz_, + _d2_bc_, _pe_zz_, + _d3_bce, +3) ; + + compute_det_3x3(_d2_de_, _pb_zz_, + _d2_be_, _pd_zz_, + _d2_bd_, _pe_zz_, + _d3_bde, +3) ; + + compute_det_3x3(_d2_de_, _pc_zz_, + _d2_ce_, _pd_zz_, + _d2_cd_, _pe_zz_, + _d3_cde, +3) ; + + /*-------------------------------------- 4 x 4 minors */ + unitary_det_4x4(_d3_cde, _d3_bde, + _d3_bce, _d3_bcd, + _d4bcde, +4) ; + + unitary_det_4x4(_d3_cde, _d3_ade, + _d3_ace, _d3_acd, + _d4acde, +4) ; + + unitary_det_4x4(_d3_bde, _d3_ade, + _d3_abe, _d3_abd, + _d4abde, +4) ; + + unitary_det_4x4(_d3_bce, _d3_ace, + _d3_abe, _d3_abc, + _d4abce, +4) ; + + unitary_det_4x4(_d3_bcd, _d3_acd, + _d3_abd, _d3_abc, + _d4abcd, +4) ; + + /*-------------------------------------- 5 x 5 result */ + compute_det_5x5(_d4bcde, _pa_qq_, + _d4acde, _pb_qq_, + _d4abde, _pc_qq_, + _d4abce, _pd_qq_, + _d4abcd, _pe_qq_, + _d5full, +4) ; + + /*-------------------------------------- leading det. */ + return mp::expansion_est(_d5full) ; + } + + __normal_call REAL_TYPE orient4d_i ( + __const_ptr(REAL_TYPE) _pa , + __const_ptr(REAL_TYPE) _pb , + __const_ptr(REAL_TYPE) _pc , + __const_ptr(REAL_TYPE) _pd , + __const_ptr(REAL_TYPE) _pe , + bool_type &_OK + ) + { + /*--------------- orient4d predicate, "bound" version */ + ia_flt _aex, _aey, _aez , + _aeq, + _bex, _bey, _bez , + _beq, + _cex, _cey, _cez , + _ceq, + _dex, _dey, _dez , + _deq; + ia_flt _aexbey, _bexaey , + _aexcey, _cexaey , + _bexcey, _cexbey , + _cexdey, _dexcey , + _dexaey, _aexdey , + _bexdey, _dexbey ; + ia_flt _ab_, _bc_, _cd_, _da_, + _ac_, _bd_; + ia_flt _abc, _bcd, _cda, _dab; + ia_flt _sgn; + + ia_rnd _rnd; // up rounding! + + _aex.from_sub(_pa[0], _pe[0]) ; // coord. diff. + _aey.from_sub(_pa[1], _pe[1]) ; + _aez.from_sub(_pa[2], _pe[2]) ; + _aeq.from_sub(_pa[3], _pe[3]) ; + + _bex.from_sub(_pb[0], _pe[0]) ; + _bey.from_sub(_pb[1], _pe[1]) ; + _bez.from_sub(_pb[2], _pe[2]) ; + _beq.from_sub(_pb[3], _pe[3]) ; + + _cex.from_sub(_pc[0], _pe[0]) ; + _cey.from_sub(_pc[1], _pe[1]) ; + _cez.from_sub(_pc[2], _pe[2]) ; + _ceq.from_sub(_pc[3], _pe[3]) ; + + _dex.from_sub(_pd[0], _pe[0]) ; + _dey.from_sub(_pd[1], _pe[1]) ; + _dez.from_sub(_pd[2], _pe[2]) ; + _deq.from_sub(_pd[3], _pe[3]) ; + + _aexbey = _aex * _bey ; // 2 x 2 minors + _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 = // 3 x 3 minors + _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_ ; + + _sgn = // 4 x 4 result + _deq * _abc - _ceq * _dab + + _beq * _cda - _aeq * _bcd ; + + _OK = + _sgn.lo() >= (REAL_TYPE)0. + ||_sgn.up() <= (REAL_TYPE)0.; + + return ( _sgn.mid() ) ; + } + + __normal_call REAL_TYPE orient4d_f ( + __const_ptr(REAL_TYPE) _pa , + __const_ptr(REAL_TYPE) _pb , + __const_ptr(REAL_TYPE) _pc , + __const_ptr(REAL_TYPE) _pd , + __const_ptr(REAL_TYPE) _pe , + bool_type &_OK + ) + { + /*--------------- orient4d predicate, "float" version */ + REAL_TYPE static const _ER = + + 13. * std::pow(mp::_epsilon, 1) ; + + REAL_TYPE _aex, _aey, _aez , + _aeq, + _bex, _bey, _bez , + _beq, + _cex, _cey, _cez , + _ceq, + _dex, _dey, _dez , + _deq; + REAL_TYPE _aexbey, _bexaey , + _aexcey, _cexaey , + _bexcey, _cexbey , + _cexdey, _dexcey , + _dexaey, _aexdey , + _bexdey, _dexbey ; + REAL_TYPE _ab_, _bc_, _cd_, _da_, + _ac_, _bd_; + REAL_TYPE _abc, _bcd, _cda, _dab; + + REAL_TYPE _AEZ, _BEZ, _CEZ, _DEZ; + REAL_TYPE _AEQ, _BEQ, _CEQ, _DEQ; + REAL_TYPE _AEXBEY, _BEXAEY , + _CEXAEY, _AEXCEY , + _BEXCEY, _CEXBEY , + _CEXDEY, _DEXCEY , + _DEXAEY, _AEXDEY , + _BEXDEY, _DEXBEY ; + REAL_TYPE _AB_, _BC_, _CD_, _DA_, + _AC_, _BD_; + REAL_TYPE _ABC, _BCD, _CDA, _DAB; + + REAL_TYPE _sgn, _FT ; + + _aex = _pa [0] - _pe [0] ; // coord. diff. + _aey = _pa [1] - _pe [1] ; + _aez = _pa [2] - _pe [2] ; + _aeq = _pa [3] - _pe [3] ; + + _AEZ = std::abs (_aez) ; + _AEQ = std::abs (_aeq) ; + + _bex = _pb [0] - _pe [0] ; + _bey = _pb [1] - _pe [1] ; + _bez = _pb [2] - _pe [2] ; + _beq = _pb [3] - _pe [3] ; + + _BEZ = std::abs (_bez) ; + _BEQ = std::abs (_beq) ; + + _cex = _pc [0] - _pe [0] ; + _cey = _pc [1] - _pe [1] ; + _cez = _pc [2] - _pe [2] ; + _ceq = _pc [3] - _pe [3] ; + + _CEZ = std::abs (_cez) ; + _CEQ = std::abs (_ceq) ; + + _dex = _pd [0] - _pe [0] ; + _dey = _pd [1] - _pe [1] ; + _dez = _pd [2] - _pe [2] ; + _deq = _pd [3] - _pe [3] ; + + _DEZ = std::abs (_dez) ; + _DEQ = std::abs (_deq) ; + + _aexbey = _aex * _bey; // 2 x 2 minors + _bexaey = _bex * _aey; + _ab_ = _aexbey - _bexaey ; + + _AEXBEY = std::abs (_aexbey) ; + _BEXAEY = std::abs (_bexaey) ; + _AB_ = _AEXBEY + _BEXAEY ; + + _bexcey = _bex * _cey; + _cexbey = _cex * _bey; + _bc_ = _bexcey - _cexbey ; + + _BEXCEY = std::abs (_bexcey) ; + _CEXBEY = std::abs (_cexbey) ; + _BC_ = _BEXCEY + _CEXBEY ; + + _cexdey = _cex * _dey; + _dexcey = _dex * _cey; + _cd_ = _cexdey - _dexcey ; + + _CEXDEY = std::abs (_cexdey) ; + _DEXCEY = std::abs (_dexcey) ; + _CD_ = _CEXDEY + _DEXCEY ; + + _dexaey = _dex * _aey; + _aexdey = _aex * _dey; + _da_ = _dexaey - _aexdey ; + + _DEXAEY = std::abs (_dexaey) ; + _AEXDEY = std::abs (_aexdey) ; + _DA_ = _DEXAEY + _AEXDEY ; + + _aexcey = _aex * _cey; + _cexaey = _cex * _aey; + _ac_ = _aexcey - _cexaey ; + + _AEXCEY = std::abs (_aexcey) ; + _CEXAEY = std::abs (_cexaey) ; + _AC_ = _AEXCEY + _CEXAEY ; + + _bexdey = _bex * _dey; + _dexbey = _dex * _bey; + _bd_ = _bexdey - _dexbey ; + + _BEXDEY = std::abs (_bexdey) ; + _DEXBEY = std::abs (_dexbey) ; + _BD_ = _BEXDEY + _DEXBEY ; + + _abc = // 3 x 3 minors + _aez * _bc_ - _bez * _ac_ + + _cez * _ab_ ; + _ABC = + _AEZ * _BC_ + _BEZ * _AC_ + + _CEZ * _AB_ ; + + _bcd = + _bez * _cd_ - _cez * _bd_ + + _dez * _bc_ ; + _BCD = + _BEZ * _CD_ + _CEZ * _BD_ + + _DEZ * _BC_ ; + + _cda = + _cez * _da_ + _dez * _ac_ + + _aez * _cd_ ; + _CDA = + _CEZ * _DA_ + _DEZ * _AC_ + + _AEZ * _CD_ ; + + _dab = + _dez * _ab_ + _aez * _bd_ + + _bez * _da_ ; + _DAB = + _DEZ * _AB_ + _AEZ * _BD_ + + _BEZ * _DA_ ; + + _FT = // roundoff tol + _DEQ * _ABC + _CEQ * _DAB + + _BEQ * _CDA + _AEQ * _BCD ; + + _FT *= _ER ; + + _sgn = // 4 x 4 result + _deq * _abc - _ceq * _dab + + _beq * _cda - _aeq * _bcd ; + + _OK = + _sgn > _FT || _sgn < -_FT ; + + return ( _sgn ) ; + } + + diff --git a/src/libcpp/predicate/predicate_k.hpp b/src/libcpp/predicate/predicate_k.hpp new file mode 100644 index 0000000..114303d --- /dev/null +++ b/src/libcpp/predicate/predicate_k.hpp @@ -0,0 +1,719 @@ + + /* + -------------------------------------------------------- + * PREDICATE-k: robust geometric predicates in E^k. + -------------------------------------------------------- + * + * Compute "robust" geometric predicates using filtered + * floating-point + multi-precision expansions. + * + * The sign-correctness of each predicate is guaranteed + * --- using exact arithmetic where necessary to + * eliminate floating-point round-off. See Shewchuk for + * additional detail + * + * J. R. Shewchuk (1997), Adaptive Precision Floating- + * Point Arithmetic & Fast Robust Geometric Predicates + * Discrete & Computational Geometry, 18, pp. 305-363. + * + * A translational version of BFS semi-static filtering + * is employed, adapted from, e.g. + * + * C. Burnikel, S. Funke, and M. Seel (2001), Exact + * geometric computation using cascading. + * IJCGA (Special issue) 11 (3), pp. 245–266. + * + * O. Devillers and S. Pion (2002), Efficient Exact + * Geometric Predicates for Delaunay Triangulations. + * RR-4351, INRIA. inria-00072237 + * + -------------------------------------------------------- + * + * 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 __PREDICATE_K__ +# define __PREDICATE_K__ + +# define USE_KERNEL_FLTPOINT +// define USE_KERNEL_INTERVAL + + namespace geompred { + +# define REAL_TYPE mp_float::real_type +# define INDX_TYPE mp_float::indx_type + + namespace mp=mp_float; + + enum _kernel { + ORIENT2D_f, ORIENT2D_i, ORIENT2D_e , + ORIENT3D_f, ORIENT3D_i, ORIENT3D_e , + ORIENT4D_f, ORIENT4D_i, ORIENT4D_e , + BISECT2D_f, BISECT2D_i, BISECT2D_e , + BISECT2W_f, BISECT2W_i, BISECT2W_e , + BISECT3D_f, BISECT3D_i, BISECT3D_e , + BISECT3W_f, BISECT3W_i, BISECT3W_e , + BISECT4D_f, BISECT4D_i, BISECT4D_e , + BISECT4W_f, BISECT4W_i, BISECT4W_e , + INBALL2D_f, INBALL2D_i, INBALL2D_e , + INBALL2W_f, INBALL2W_i, INBALL2W_e , + INBALL3D_f, INBALL3D_i, INBALL3D_e , + INBALL3W_f, INBALL3W_i, INBALL3W_e , + INBALL4D_f, INBALL4D_i, INBALL4D_e , + INBALL4W_f, INBALL4W_i, INBALL4W_e , + LASTKERNEL } ; + + size_t _nn_calls[LASTKERNEL] = {0} ; + +# include "orient_k.hpp" +# include "bisect_k.hpp" +// include "linear_k.hpp" +# include "inball_k.hpp" + + __inline_call REAL_TYPE orient2d ( + __const_ptr(REAL_TYPE) _pa , + __const_ptr(REAL_TYPE) _pb , + __const_ptr(REAL_TYPE) _pc + ) + { + /*------------ orient2d predicate, "filtered" version */ + REAL_TYPE _rr; + bool_type _OK; + + # ifdef USE_KERNEL_FLTPOINT + _nn_calls[ORIENT2D_f] += +1; + + _rr = orient2d_f( // "float" kernel + _pa, _pb, _pc, _OK + ) ; + + if (_OK && std::isnormal(_rr)) + return _rr ; + # endif + + # ifdef USE_KERNEL_INTERVAL + _nn_calls[ORIENT2D_i] += +1; + + _rr = orient2d_i( // "bound" kernel + _pa, _pb, _pc, _OK + ) ; + + if (_OK) return _rr ; + # endif + + _nn_calls[ORIENT2D_e] += +1; + + _rr = orient2d_e( // "exact" kernel + _pa, _pb, _pc, _OK + ) ; + + if (_OK) return _rr ; + + return (REAL_TYPE) +0.0E+00; + } + + __inline_call REAL_TYPE orient3d ( + __const_ptr(REAL_TYPE) _pa , + __const_ptr(REAL_TYPE) _pb , + __const_ptr(REAL_TYPE) _pc , + __const_ptr(REAL_TYPE) _pd + ) + { + /*------------ orient3d predicate, "filtered" version */ + REAL_TYPE _rr; + bool_type _OK; + + # ifdef USE_KERNEL_FLTPOINT + _nn_calls[ORIENT3D_f] += +1; + + _rr = orient3d_f( // "float" kernel + _pa, _pb, _pc, _pd, _OK + ) ; + + if (_OK && std::isnormal(_rr)) + return _rr ; + # endif + + # ifdef USE_KERNEL_INTERVAL + _nn_calls[ORIENT3D_i] += +1; + + _rr = orient3d_i( // "bound" kernel + _pa, _pb, _pc, _pd, _OK + ) ; + + if (_OK) return _rr ; + # endif + + _nn_calls[ORIENT3D_e] += +1; + + _rr = orient3d_e( // "exact" kernel + _pa, _pb, _pc, _pd, _OK + ) ; + + if (_OK) return _rr ; + + return (REAL_TYPE) +0.0E+00; + } + + __inline_call REAL_TYPE orient4d ( + __const_ptr(REAL_TYPE) _pa , + __const_ptr(REAL_TYPE) _pb , + __const_ptr(REAL_TYPE) _pc , + __const_ptr(REAL_TYPE) _pd , + __const_ptr(REAL_TYPE) _pe + ) + { + /*------------ orient4d predicate, "filtered" version */ + REAL_TYPE _rr; + bool_type _OK; + + # ifdef USE_KERNEL_FLTPOINT + _nn_calls[ORIENT4D_f] += +1; + + _rr = orient4d_f( // "float" kernel + _pa, _pb, _pc, _pd, _pe, _OK + ) ; + + if (_OK && std::isnormal(_rr)) + return _rr ; + # endif + + # ifdef USE_KERNEL_INTERVAL + _nn_calls[ORIENT4D_i] += +1; + + _rr = orient4d_i( // "bound" kernel + _pa, _pb, _pc, _pd, _pe, _OK + ) ; + + if (_OK) return _rr ; + # endif + + _nn_calls[ORIENT4D_e] += +1; + + _rr = orient4d_e( // "exact" kernel + _pa, _pb, _pc, _pd, _pe, _OK + ) ; + + if (_OK) return _rr ; + + return (REAL_TYPE) +0.0E+00; + } + + __inline_call REAL_TYPE bisect2d ( + __const_ptr(REAL_TYPE) _pa , + __const_ptr(REAL_TYPE) _pb , + __const_ptr(REAL_TYPE) _pc + ) + { + /*------------ bisect2d predicate, "filtered" version */ + REAL_TYPE _rr; + bool_type _OK; + + # ifdef USE_KERNEL_FLTPOINT + _nn_calls[BISECT2D_f] += +1; + + _rr = bisect2d_f( // "float" kernel + _pa, _pb, _pc, _OK + ) ; + + if (_OK && std::isnormal(_rr)) + return _rr ; + # endif + + # ifdef USE_KERNEL_INTERVAL + _nn_calls[BISECT2D_i] += +1; + + _rr = bisect2d_i( // "bound" kernel + _pa, _pb, _pc, _OK + ) ; + + if (_OK) return _rr ; + # endif + + _nn_calls[BISECT2D_e] += +1; + + _rr = bisect2d_e( // "exact" kernel + _pa, _pb, _pc, _OK + ) ; + + if (_OK) return _rr ; + + return (REAL_TYPE) +0.0E+00; + } + + __inline_call REAL_TYPE bisect2w ( + __const_ptr(REAL_TYPE) _pa , + __const_ptr(REAL_TYPE) _pb , + __const_ptr(REAL_TYPE) _pc + ) + { + /*------------ bisect2w predicate, "filtered" version */ + if (_pa [ 2] == _pb [ 2] ) + { // equal weights, do bisect2d + return bisect2d(_pa, _pb, _pc) ; + } + else + { + REAL_TYPE _rr; // given weights, full kernel + bool_type _OK; + + # ifdef USE_KERNEL_FLTPOINT + _nn_calls[BISECT2W_f] += +1; + + _rr = bisect2w_f( // "float" kernel + _pa, _pb, _pc, _OK + ) ; + + if (_OK && std::isnormal(_rr)) + return _rr ; + # endif + + # ifdef USE_KERNEL_INTERVAL + _nn_calls[BISECT2W_i] += +1; + + _rr = bisect2w_i( // "bound" kernel + _pa, _pb, _pc, _OK + ) ; + + if (_OK) return _rr ; + # endif + + _nn_calls[BISECT2W_e] += +1; + + _rr = bisect2w_e( // "exact" kernel + _pa, _pb, _pc, _OK + ) ; + + if (_OK) return _rr ; + + return (REAL_TYPE) +0.0E+00; + } + } + + __inline_call REAL_TYPE bisect3d ( + __const_ptr(REAL_TYPE) _pa , + __const_ptr(REAL_TYPE) _pb , + __const_ptr(REAL_TYPE) _pc + ) + { + /*------------ bisect3d predicate, "filtered" version */ + REAL_TYPE _rr; + bool_type _OK; + + # ifdef USE_KERNEL_FLTPOINT + _nn_calls[BISECT3D_f] += +1; + + _rr = bisect3d_f( // "float" kernel + _pa, _pb, _pc, _OK + ) ; + + if (_OK && std::isnormal(_rr)) + return _rr ; + # endif + + # ifdef USE_KERNEL_INTERVAL + _nn_calls[BISECT3D_i] += +1; + + _rr = bisect3d_i( // "bound" kernel + _pa, _pb, _pc, _OK + ) ; + + if (_OK) return _rr ; + # endif + + _nn_calls[BISECT3D_e] += +1; + + _rr = bisect3d_e( // "exact" kernel + _pa, _pb, _pc, _OK + ) ; + + if (_OK) return _rr ; + + return (REAL_TYPE) +0.0E+00; + } + + __inline_call REAL_TYPE bisect3w ( + __const_ptr(REAL_TYPE) _pa , + __const_ptr(REAL_TYPE) _pb , + __const_ptr(REAL_TYPE) _pc + ) + { + /*------------ bisect3w predicate, "filtered" version */ + if (_pa [ 3] == _pb [ 3] ) + { // equal weights, do bisect3d + return bisect3d(_pa, _pb, _pc) ; + } + else + { + REAL_TYPE _rr; // given weights, full kernel + bool_type _OK; + + # ifdef USE_KERNEL_FLTPOINT + _nn_calls[BISECT3W_f] += +1; + + _rr = bisect3w_f( // "float" kernel + _pa, _pb, _pc, _OK + ) ; + + if (_OK && std::isnormal(_rr)) + return _rr ; + # endif + + # ifdef USE_KERNEL_INTERVAL + _nn_calls[BISECT3W_i] += +1; + + _rr = bisect3w_i( // "bound" kernel + _pa, _pb, _pc, _OK + ) ; + + if (_OK) return _rr ; + # endif + + _nn_calls[BISECT3W_e] += +1; + + _rr = bisect3w_e( // "exact" kernel + _pa, _pb, _pc, _OK + ) ; + + if (_OK) return _rr ; + + return (REAL_TYPE) +0.0E+00; + } + } + + __inline_call REAL_TYPE bisect4d ( + __const_ptr(REAL_TYPE) _pa , + __const_ptr(REAL_TYPE) _pb , + __const_ptr(REAL_TYPE) _pc + ) + { + /*------------ bisect4d predicate, "filtered" version */ + REAL_TYPE _rr; + bool_type _OK; + + # ifdef USE_KERNEL_FLTPOINT + _nn_calls[BISECT4D_f] += +1; + + _rr = bisect4d_f( // "float" kernel + _pa, _pb, _pc, _OK + ) ; + + if (_OK && std::isnormal(_rr)) + return _rr ; + # endif + + # ifdef USE_KERNEL_INTERVAL + _nn_calls[BISECT4D_i] += +1; + + _rr = bisect4d_i( // "bound" kernel + _pa, _pb, _pc, _OK + ) ; + + if (_OK) return _rr ; + # endif + + _nn_calls[BISECT4D_e] += +1; + + _rr = bisect4d_e( // "exact" kernel + _pa, _pb, _pc, _OK + ) ; + + if (_OK) return _rr ; + + return (REAL_TYPE) +0.0E+00; + } + + __inline_call REAL_TYPE bisect4w ( + __const_ptr(REAL_TYPE) _pa , + __const_ptr(REAL_TYPE) _pb , + __const_ptr(REAL_TYPE) _pc + ) + { + /*------------ bisect3w predicate, "filtered" version */ + if (_pa [ 4] == _pb [ 4] ) + { // equal weights, do bisect3d + return bisect4d(_pa, _pb, _pc) ; + } + else + { + REAL_TYPE _rr; // given weights, full kernel + bool_type _OK; + + # ifdef USE_KERNEL_FLTPOINT + _nn_calls[BISECT4W_f] += +1; + + _rr = bisect4w_f( // "float" kernel + _pa, _pb, _pc, _OK + ) ; + + if (_OK && std::isnormal(_rr)) + return _rr ; + # endif + + # ifdef USE_KERNEL_INTERVAL + _nn_calls[BISECT4W_i] += +1; + + _rr = bisect4w_i( // "bound" kernel + _pa, _pb, _pc, _OK + ) ; + + if (_OK) return _rr ; + # endif + + _nn_calls[BISECT4W_e] += +1; + + _rr = bisect4w_e( // "exact" kernel + _pa, _pb, _pc, _OK + ) ; + + if (_OK) return _rr ; + + return (REAL_TYPE) +0.0E+00; + } + } + + __inline_call REAL_TYPE inball2d ( + __const_ptr(REAL_TYPE) _pa , + __const_ptr(REAL_TYPE) _pb , + __const_ptr(REAL_TYPE) _pc , + __const_ptr(REAL_TYPE) _pd + ) + { + /*------------ inball2d predicate, "filtered" version */ + REAL_TYPE _rr; + bool_type _OK; + + # ifdef USE_KERNEL_FLTPOINT + _nn_calls[INBALL2D_f] += +1; + + _rr = inball2d_f( // "float" kernel + _pa, _pb, _pc, _pd, _OK + ) ; + + if (_OK && std::isnormal(_rr)) + return _rr ; + # endif + + # ifdef USE_KERNEL_INTERVAL + _nn_calls[INBALL2D_i] += +1; + + _rr = inball2d_i( // "bound" kernel + _pa, _pb, _pc, _pd, _OK + ) ; + + if (_OK) return _rr ; + # endif + + _nn_calls[INBALL2D_e] += +1; + + _rr = inball2d_e( // "exact" kernel + _pa, _pb, _pc, _pd, _OK + ) ; + + if (_OK) return _rr ; + + return (REAL_TYPE) +0.0E+00; + } + + __inline_call REAL_TYPE inball2w ( + __const_ptr(REAL_TYPE) _pa , + __const_ptr(REAL_TYPE) _pb , + __const_ptr(REAL_TYPE) _pc , + __const_ptr(REAL_TYPE) _pd + ) + { + /*------------ inball2w predicate, "filtered" version */ + if (_pa [ 2] == _pb [ 2] && + _pb [ 2] == _pc [ 2] && + _pc [ 2] == _pd [ 2] ) + { + return inball2d ( // equal weights, do inball2d + _pa, _pb, _pc, _pd + ) ; + } + else + { + REAL_TYPE _rr; // given weights, full kernel + bool_type _OK; + + # ifdef USE_KERNEL_FLTPOINT + _nn_calls[INBALL2W_f] += +1; + + _rr = inball2w_f( // "float" kernel + _pa, _pb, _pc, _pd, _OK + ) ; + + if (_OK && std::isnormal(_rr)) + return _rr ; + # endif + + # ifdef USE_KERNEL_INTERVAL + _nn_calls[INBALL2W_i] += +1; + + _rr = inball2w_i( // "bound" kernel + _pa, _pb, _pc, _pd, _OK + ) ; + + if (_OK) return _rr ; + # endif + + _nn_calls[INBALL2W_e] += +1; + + _rr = inball2w_e( // "exact" kernel + _pa, _pb, _pc, _pd, _OK + ) ; + + if (_OK) return _rr ; + + return (REAL_TYPE) +0.0E+00; + } + } + + __inline_call REAL_TYPE inball3d ( + __const_ptr(REAL_TYPE) _pa , + __const_ptr(REAL_TYPE) _pb , + __const_ptr(REAL_TYPE) _pc , + __const_ptr(REAL_TYPE) _pd , + __const_ptr(REAL_TYPE) _pe + ) + { + /*------------ inball3d predicate, "filtered" version */ + REAL_TYPE _rr; + bool_type _OK; + + # ifdef USE_KERNEL_FLTPOINT + _nn_calls[INBALL3D_f] += +1; + + _rr = inball3d_f( // "float" kernel + _pa, _pb, _pc, _pd, _pe, _OK + ) ; + + if (_OK && std::isnormal(_rr)) + return _rr ; + # endif + + # ifdef USE_KERNEL_INTERVAL + _nn_calls[INBALL3D_i] += +1; + + _rr = inball3d_i( // "bound" kernel + _pa, _pb, _pc, _pd, _pe, _OK + ) ; + + if (_OK) return _rr ; + # endif + + _nn_calls[INBALL3D_e] += +1; + + _rr = inball3d_e( // "exact" kernel + _pa, _pb, _pc, _pd, _pe, _OK + ) ; + + if (_OK) return _rr ; + + return (REAL_TYPE) +0.0E+00; + } + + __inline_call REAL_TYPE inball3w ( + __const_ptr(REAL_TYPE) _pa , + __const_ptr(REAL_TYPE) _pb , + __const_ptr(REAL_TYPE) _pc , + __const_ptr(REAL_TYPE) _pd , + __const_ptr(REAL_TYPE) _pe + ) + { + /*------------ inball3w predicate, "filtered" version */ + if (_pa [ 3] == _pb [ 3] && + _pb [ 3] == _pc [ 3] && + _pc [ 3] == _pd [ 3] && + _pd [ 3] == _pe [ 3] ) + { + return inball3d ( // equal weights, do inball3d + _pa, _pb, _pc, _pd, _pe + ) ; + } + else + { + REAL_TYPE _rr; // given weights, full kernel + bool_type _OK; + + # ifdef USE_KERNEL_FLTPOINT + _nn_calls[INBALL3W_f] += +1; + + _rr = inball3w_f( // "float" kernal + _pa, _pb, _pc, _pd, _pe, _OK + ) ; + + if (_OK && std::isnormal(_rr)) + return _rr ; + # endif + + # ifdef USE_KERNEL_INTERVAL + _nn_calls[INBALL3D_i] += +1; + + _rr = inball3w_i( // "bound" kernel + _pa, _pb, _pc, _pd, _pe, _OK + ) ; + + if (_OK) return _rr ; + # endif + + _nn_calls[INBALL3W_e] += +1; + + _rr = inball3w_e( // "exact" kernel + _pa, _pb, _pc, _pd, _pe, _OK + ) ; + + if (_OK) return _rr ; + + return (REAL_TYPE) +0.0E+00; + } + } + +# undef REAL_TYPE +# undef INDX_TYPE + +# undef USE_KERNEL_FLTPOINT +# undef USE_KERNEL_INTERVAL + + } + +# endif//__PREDICATE_K__ + + + diff --git a/src/libcpp/rdel_mesh/rdel_base_2.hpp b/src/libcpp/rdel_mesh/rdel_base_2.hpp index 9fbdccc..4174e2f 100644 --- a/src/libcpp/rdel_mesh/rdel_base_2.hpp +++ b/src/libcpp/rdel_mesh/rdel_base_2.hpp @@ -31,11 +31,11 @@ * -------------------------------------------------------- * - * Last updated: 10 July, 2019 + * Last updated: 08 April, 2020 * - * Copyright 2013-2019 + * Copyright 2013-2020 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- @@ -133,39 +133,6 @@ -------------------------------------------------------- */ - __static_call - __normal_call double half_sign ( - __const_ptr (double) _pp, - __const_ptr (double) _pa, - __const_ptr (double) _pb - ) - { - /*-------- helper: eval. sign w.r.t. half-plane [a,b] */ - double _pm[2]; - _pm[0] = _pa[0] * 0.5 ; - _pm[1] = _pa[1] * 0.5 ; - _pm[0]+= _pb[0] * 0.5 ; - _pm[1]+= _pb[1] * 0.5 ; - - double _ab[2]; - _ab[0] = _pb[0] ; - _ab[1] = _pb[1] ; - _ab[0]-= _pa[0] ; - _ab[1]-= _pa[1] ; - - double _mp[2]; - _mp[0] = _pp[0] ; - _mp[1] = _pp[1] ; - _mp[0]-= _pm[0] ; - _mp[1]-= _pm[1] ; - - double _dp = - _ab[0] * _mp[0] + - _ab[1] * _mp[1] ; - - return ((double) _dp ); - } - template < typename half_list > @@ -191,29 +158,33 @@ auto _anod = _hset[_hpos][0] ; auto _bnod = _hset[_hpos][1] ; - double _APOS[2] ; + double _APOS[3] ; _APOS[0] = _mesh. _tria.node(_anod)->pval(0) ; _APOS[1] = _mesh. _tria.node(_anod)->pval(1) ; + _APOS[2] = _mesh. + _tria.node(_anod)->pval(2) ; - double _BPOS[2] ; + double _BPOS[3] ; _BPOS[0] = _mesh. _tria.node(_bnod)->pval(0) ; _BPOS[1] = _mesh. _tria.node(_bnod)->pval(1) ; + _BPOS[2] = _mesh. + _tria.node(_bnod)->pval(2) ; - double _sign = +0.0 ; + double _sign = +0.0; if (_bnod > _anod) - _sign = + half_sign ( - (double*) _PPOS, + _sign = +geompred::bisect2w ( (double*) _APOS, - (double*) _BPOS) ; + (double*) _BPOS, + (double*) _PPOS) ; else - _sign = - half_sign ( - (double*) _PPOS, + _sign = -geompred::bisect2w ( (double*) _BPOS, - (double*) _APOS) ; + (double*) _APOS, + (double*) _PPOS) ; /*-------- "fatten" dual cavity to filter imprecision */ if (_sign >= -_rtol && @@ -247,12 +218,7 @@ { real_type static const _rEPS = std::pow(std::numeric_limits - ::epsilon(),+.67); - - real_type _blen = - _geom._bmax[0]-_geom._bmin[0] - + _geom._bmax[1]-_geom._bmin[1] ; - _blen /= (real_type) +2. ; + ::epsilon(),+.85); /*--------------------------- init. output balls = 0. */ _ebal[0] = (real_type) +0. ; @@ -278,8 +244,8 @@ /*--------------------------- assemble local indexing */ if (_topp < _tadj) { - std::swap(_tadj, _topp) ; - std::swap(_eadj, _eopp) ; + std::swap(_tadj, _topp); + std::swap(_eadj, _eopp); } iptr_type _enod[ +3] ; @@ -311,73 +277,42 @@ &_ENOD[0], &_ENOD[2] , std::less()) ; - geometry:: - circ_ball_2d( _ebal, - &_mesh._tria. - node(_ENOD[0])->pval(0), - &_mesh._tria. - node(_ENOD[1])->pval(0)) ; - - /*--------------------------- est. dual voronoi patch */ - line_type _line; - _line._ipos[0] = - _mesh._tria. - tria(_tadj )->circ(0) ; - _line._ipos[1] = - _mesh._tria. - tria(_tadj )->circ(1) ; - - _line._jpos[0] = - _mesh._tria. - tria(_topp )->circ(0) ; - _line._jpos[1] = - _mesh._tria. - tria(_topp )->circ(1) ; + geometry::perp_ball_2d( _ebal , + &_mesh._tria. + node(_ENOD[0])->pval(0), + &_mesh._tria. + node(_ENOD[1])->pval(0)) ; - real_type _nvec[3]; + real_type _nvec[2]; geometry::line_norm_2d( - &_mesh._tria. - node(_enod[0])->pval(0) , - &_mesh._tria. - node(_enod[1])->pval(0) , - _nvec) ; - - _nvec[2] = - geometry::length_2d(_nvec) ; - _nvec[0]/= _nvec[2] ; - _nvec[1]/= _nvec[2] ; + &_mesh._tria. + node(_ENOD[0])->pval(0), + &_mesh._tria. + node(_ENOD[1])->pval(0), + _nvec) ; + /*--------------------------- est. dual voronoi patch */ real_type _ival, _jval; geometry::proj_line_2d( - _line. _ipos, + &_mesh._tria.tria(_tadj)->circ(0), _ebal, _nvec, _ival) ; geometry::proj_line_2d( - _line. _jpos, + &_mesh._tria.tria(_topp)->circ(0), _ebal, _nvec, _jval) ; real_type _diff ; _diff = _jval - _ival; - if (_diff > (real_type)0.) - { - _diff = - std::max( _diff, +_blen) ; - } - else - { - _diff = - std::min( _diff, -_blen) ; - } - - _ival -= _rEPS * _diff; + _ival -= _diff * _rEPS; + line_type _line; _line._ipos[0] = _ebal[0] + _ival*_nvec [0] ; _line._ipos[1] = _ebal[1] + _ival*_nvec [1] ; - _jval += _rEPS * _diff; + _jval += _diff * _rEPS; _line._jpos[0] = _ebal[0] + _jval*_nvec [0] ; @@ -386,8 +321,7 @@ /*--------------------------- find loc. intersections */ mesh::keep_all_2d < - real_type , - iptr_type > _pred ; + real_type, iptr_type> _pred ; if(!_geom.intersect ( _line, _pred) ) @@ -396,7 +330,7 @@ /*--------------------------- form list of halfplanes */ containers:: - fixed_array _hset ; + fixed_array _hset ; _hset[0][0] = _enod[2] ; _hset[0][1] = _enod[0] ; @@ -433,14 +367,19 @@ _safe, _RTOL) ) { /*--------------------------- prune near-degeneracies */ - if (!_safe) + if(!_safe) { + real_type _PPOS[3]; + _PPOS[0] = _iter->pval(0) ; + _PPOS[1] = _iter->pval(1) ; + _PPOS[2] = (real_type)+0. ; // weight = 0 + typename mesh_type:: tria_type:: tria_pred:: template circ_pred< typename mesh_type::tria_type> - _isDT (&_iter-> pval( 0)); + _isDT (&_PPOS[ +0]) ; bool_type _okay = _isDT(_mesh._tria, _tadj, 0)|| diff --git a/src/libcpp/rdel_mesh/rdel_base_3.hpp b/src/libcpp/rdel_mesh/rdel_base_3.hpp index dffe78f..bd7c77d 100644 --- a/src/libcpp/rdel_mesh/rdel_base_3.hpp +++ b/src/libcpp/rdel_mesh/rdel_base_3.hpp @@ -31,11 +31,11 @@ * -------------------------------------------------------- * - * Last updated: 10 July, 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/ * -------------------------------------------------------- @@ -145,46 +145,6 @@ -------------------------------------------------------- */ - __static_call - __normal_call double half_sign ( - __const_ptr (double) _pp, - __const_ptr (double) _pa, - __const_ptr (double) _pb - ) - { - /*-------- helper: eval. sign w.r.t. half-plane [a,b] */ - double _pm[3]; - _pm[0] = _pa[0] * 0.5 ; - _pm[1] = _pa[1] * 0.5 ; - _pm[2] = _pa[2] * 0.5 ; - _pm[0]+= _pb[0] * 0.5 ; - _pm[1]+= _pb[1] * 0.5 ; - _pm[2]+= _pb[2] * 0.5 ; - - double _ab[3]; - _ab[0] = _pb[0] ; - _ab[1] = _pb[1] ; - _ab[2] = _pb[2] ; - _ab[0]-= _pa[0] ; - _ab[1]-= _pa[1] ; - _ab[2]-= _pa[2] ; - - double _mp[3]; - _mp[0] = _pp[0] ; - _mp[1] = _pp[1] ; - _mp[2] = _pp[2] ; - _mp[0]-= _pm[0] ; - _mp[1]-= _pm[1] ; - _mp[2]-= _pm[2] ; - - double _dp = - _ab[0] * _mp[0] + - _ab[1] * _mp[1] + - _ab[2] * _mp[2] ; - - return ((double) _dp) ; - } - template < typename half_list > @@ -211,33 +171,37 @@ auto _anod = _hset[_hpos][0] ; auto _bnod = _hset[_hpos][1] ; - double _APOS[3] ; + double _APOS[4] ; _APOS[0] = _mesh. _tria.node(_anod)->pval(0) ; _APOS[1] = _mesh. _tria.node(_anod)->pval(1) ; _APOS[2] = _mesh. _tria.node(_anod)->pval(2) ; + _APOS[3] = _mesh. + _tria.node(_anod)->pval(3) ; - double _BPOS[3] ; + double _BPOS[4] ; _BPOS[0] = _mesh. _tria.node(_bnod)->pval(0) ; _BPOS[1] = _mesh. _tria.node(_bnod)->pval(1) ; _BPOS[2] = _mesh. _tria.node(_bnod)->pval(2) ; + _BPOS[3] = _mesh. + _tria.node(_bnod)->pval(3) ; double _sign = +0.0; if (_bnod > _anod) - _sign = + half_sign ( - (double*) _PPOS, + _sign = +geompred::bisect3w ( (double*) _APOS, - (double*) _BPOS) ; + (double*) _BPOS, + (double*) _PPOS) ; else - _sign = - half_sign ( - (double*) _PPOS, + _sign = -geompred::bisect3w ( (double*) _BPOS, - (double*) _APOS) ; + (double*) _APOS, + (double*) _PPOS) ; /*-------- "fatten" dual cavity to filter imprecision */ if (_sign >= -_rtol && @@ -334,7 +298,6 @@ iptr_type _eadj, real_type *_ebal, real_type *_sbal, - char_type &_hits, char_type &_feat, char_type &_topo, iptr_type &_part @@ -342,13 +305,7 @@ { real_type static const _rEPS = std::pow(std::numeric_limits - ::epsilon(),+.67); - - real_type _blen = - _geom._bmax[0]-_geom._bmin[0] - + _geom._bmax[1]-_geom._bmin[1] - + _geom._bmax[2]-_geom._bmin[2] ; - _blen /= (real_type) +3. ; + ::epsilon(),+.85); /*--------------------------- assemble local indexing */ iptr_type _enod[ +4] ; @@ -412,8 +369,9 @@ if (_tset.count()<+3) return false ; /*--------------------------- get the face circumball */ + flat_type _flat; geometry:: - circ_ball_3d( _ebal , + perp_ball_3d( _ebal , &_mesh._tria. node(_enod[0])->pval(0) , &_mesh._tria. @@ -434,72 +392,28 @@ node(_enod[0])->pval(2) } ; /*--------------------------- calc. intersection halo */ - real_type _RMIN[3] ; - _RMIN[0] = +std:: - numeric_limits::infinity(); - _RMIN[1] = +std:: - numeric_limits::infinity(); - _RMIN[2] = +std:: - numeric_limits::infinity(); - - real_type _RMAX[3] ; - _RMAX[0] = -std:: - numeric_limits::infinity(); - _RMAX[1] = -std:: - numeric_limits::infinity(); - _RMAX[2] = -std:: - numeric_limits::infinity(); + _flat._bnds.set_alloc (_tset.count ()) ; for (auto _tpos = _tset.head() ; _tpos != _tset.tend() ; ++_tpos ) { - _RMIN[0] = std::min( - _RMIN[0], _mesh._tria. - tria(*_tpos)->circ(0)) ; - _RMIN[1] = std::min( - _RMIN[1], _mesh._tria. - tria(*_tpos)->circ(1)) ; - _RMIN[2] = std::min( - _RMIN[2], _mesh._tria. - tria(*_tpos)->circ(2)) ; - - _RMAX[0] = std::max( - _RMAX[0], _mesh._tria. - tria(*_tpos)->circ(0)) ; - _RMAX[1] = std::max( - _RMAX[1], _mesh._tria. - tria(*_tpos)->circ(1)) ; - _RMAX[2] = std::max( - _RMAX[2], _mesh._tria. - tria(*_tpos)->circ(2)) ; + _flat._bnds.push_tail( + &_mesh._tria.tria(*_tpos)->circ(0)) ; } /*--------------------------- find loc. intersections */ - flat_type _flat ; - _flat._ppos[0] = _ebal [0] ; - _flat._ppos[1] = _ebal [1] ; - _flat._ppos[2] = _ebal [2] ; - _flat._nvec[0] = _evec [0] ; - _flat._nvec[1] = _evec [1] ; - _flat._nvec[2] = _evec [2] ; - - _flat._rmin[0] = _RMIN [0] - - _rEPS * _blen ; - _flat._rmin[1] = _RMIN [1] - - _rEPS * _blen ; - _flat._rmin[2] = _RMIN [2] - - _rEPS * _blen ; - _flat._rmax[0] = _RMAX [0] - + _rEPS * _blen ; - _flat._rmax[1] = _RMAX [1] - + _rEPS * _blen ; - _flat._rmax[2] = _RMAX [2] - + _rEPS * _blen ; + _flat._ppos[0] = _ebal[0] ; + _flat._ppos[1] = _ebal[1] ; + _flat._ppos[2] = _ebal[2] ; + + _flat._nvec[0] = _evec[0] ; + _flat._nvec[1] = _evec[1] ; + _flat._nvec[2] = _evec[2] ; mesh::keep_all_3d < real_type , - iptr_type > _pred ; + iptr_type > _pred ; if(!_geom.intersect ( _flat, _pred) ) @@ -576,12 +490,18 @@ /*--------------------------- prune near-degeneracies */ if(!_safe) { + real_type _PPOS[4]; + _PPOS[0] = _iter->pval(0) ; + _PPOS[1] = _iter->pval(1) ; + _PPOS[2] = _iter->pval(2) ; + _PPOS[3] = (real_type)+0. ; // weight = 0 + typename mesh_type:: tria_type:: tria_pred:: template circ_pred< typename mesh_type::tria_type> - _isDT (&_iter-> pval( 0)); + _isDT (&_PPOS[ +0]) ; bool_type _okay = false ; for (auto _tpos =_tset.head(); @@ -625,8 +545,6 @@ _sbal[ 2] = _iful->pval(2); _part = _iful->itag (); - - _hits = _iful->hits (); _feat = _iful->feat (); _topo = _iful->topo (); @@ -655,8 +573,6 @@ _sbal[ 2] = _imax->pval(2); _part = _imax->itag (); - - _hits = _imax->hits (); _feat = _imax->feat (); _topo = _imax->topo (); @@ -700,13 +616,7 @@ { real_type static const _rEPS = std::pow(std::numeric_limits - ::epsilon(),+.67); - - real_type _blen = - _geom._bmax[0]-_geom._bmin[0] - + _geom._bmax[1]-_geom._bmin[1] - + _geom._bmax[2]-_geom._bmin[2] ; - _blen /= (real_type) +3. ; + ::epsilon(),+.85); /*--------------------------- init. output balls = 0. */ _fbal[0] = (real_type) +0. ; @@ -734,8 +644,8 @@ /*--------------------------- assemble local indexing */ if (_topp < _tadj) { - std::swap(_tadj, _topp) ; - std::swap(_fadj, _fopp) ; + std::swap(_tadj, _topp); + std::swap(_fadj, _fopp); } iptr_type _fnod[ +4] ; @@ -772,78 +682,40 @@ &_FNOD[0], &_FNOD[3] , std::less()) ; - geometry:: - circ_ball_3d( _fbal, - &_mesh._tria. - node(_FNOD[0])->pval(0), - &_mesh._tria. - node(_FNOD[1])->pval(0), - &_mesh._tria. - node(_FNOD[2])->pval(0)) ; - - /*--------------------------- est. dual voronoi patch */ - line_type _line; - _line._ipos[0] = - _mesh._tria. - tria(_tadj )->circ(0) ; - _line._ipos[1] = - _mesh._tria. - tria(_tadj )->circ(1) ; - _line._ipos[2] = - _mesh._tria. - tria(_tadj )->circ(2) ; - - _line._jpos[0] = - _mesh._tria. - tria(_topp )->circ(0) ; - _line._jpos[1] = - _mesh._tria. - tria(_topp )->circ(1) ; - _line._jpos[2] = - _mesh._tria. - tria(_topp )->circ(2) ; + geometry::perp_ball_3d( _fbal , + &_mesh._tria. + node(_FNOD[0])->pval(0), + &_mesh._tria. + node(_FNOD[1])->pval(0), + &_mesh._tria. + node(_FNOD[2])->pval(0)) ; - real_type _nvec[4]; + real_type _nvec[3]; geometry::tria_norm_3d( - &_mesh._tria. - node(_fnod[0])->pval(0) , - &_mesh._tria. - node(_fnod[1])->pval(0) , - &_mesh._tria. - node(_fnod[2])->pval(0) , - _nvec) ; - - _nvec[3] = - geometry::length_3d(_nvec) ; - _nvec[0]/= _nvec[3] ; - _nvec[1]/= _nvec[3] ; - _nvec[2]/= _nvec[3] ; + &_mesh._tria. + node(_FNOD[0])->pval(0), + &_mesh._tria. + node(_FNOD[1])->pval(0), + &_mesh._tria. + node(_FNOD[2])->pval(0), + _nvec) ; + /*--------------------------- est. dual voronoi patch */ real_type _ival, _jval; geometry::proj_line_3d( - _line. _ipos, + &_mesh._tria.tria(_tadj)->circ(0), _fbal, _nvec, _ival) ; geometry::proj_line_3d( - _line. _jpos, + &_mesh._tria.tria(_topp)->circ(0), _fbal, _nvec, _jval) ; real_type _diff ; _diff = _jval - _ival; - if (_diff > (real_type)0.) - { - _diff = - std::max( _diff, +_blen) ; - } - else - { - _diff = - std::min( _diff, -_blen) ; - } - - _ival -= _rEPS * _diff; + _ival -= _diff * _rEPS; + line_type _line; _line._ipos[0] = _fbal[0] + _ival*_nvec [0] ; _line._ipos[1] = @@ -851,7 +723,7 @@ _line._ipos[2] = _fbal[2] + _ival*_nvec [2] ; - _jval += _rEPS * _diff; + _jval += _diff * _rEPS; _line._jpos[0] = _fbal[0] + _jval*_nvec [0] ; @@ -862,8 +734,7 @@ /*--------------------------- calc. intersection halo */ mesh::keep_all_3d < - real_type , - iptr_type > _pred ; + real_type, iptr_type> _pred ; if(!_geom.intersect ( _line, _pred) ) @@ -872,7 +743,7 @@ /*--------------------------- form list of halfplanes */ containers:: - fixed_array _hset ; + fixed_array _hset ; _hset[0][0] = _fnod[3] ; _hset[0][1] = _fnod[0] ; @@ -913,14 +784,20 @@ _safe, _RTOL) ) { /*--------------------------- prune near-degeneracies */ - if (!_safe) + if(!_safe) { + real_type _PPOS[4]; + _PPOS[0] = _iter->pval(0) ; + _PPOS[1] = _iter->pval(1) ; + _PPOS[2] = _iter->pval(2) ; + _PPOS[3] = (real_type)+0. ; // weight = 0 + typename mesh_type:: tria_type:: tria_pred:: template circ_pred< typename mesh_type::tria_type> - _isDT (&_iter-> pval( 0)); + _isDT (&_PPOS[ +0]) ; bool_type _okay = _isDT(_mesh._tria, _tadj, 0)|| diff --git a/src/libcpp/rdel_mesh/rdel_complex_2.hpp b/src/libcpp/rdel_mesh/rdel_complex_2.hpp index a20700c..a538037 100644 --- a/src/libcpp/rdel_mesh/rdel_complex_2.hpp +++ b/src/libcpp/rdel_mesh/rdel_complex_2.hpp @@ -31,11 +31,11 @@ * -------------------------------------------------------- * - * Last updated: 03 July, 2019 + * Last updated: 12 February, 2020 * - * Copyright 2013-2019 + * Copyright 2013-2020 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- @@ -61,15 +61,15 @@ typedef R real_type; typedef I iptr_type; - typedef mesh::delaunay_tri_node_2 < + typedef mesh::laguerre_tri_node_2 < iptr_type , - real_type > dtri_node_base ; + real_type > tria_node_base ; - typedef mesh::delaunay_tri_tria_2 < + typedef mesh::laguerre_tri_tria_2 < iptr_type , - real_type > dtri_tria_base ; + real_type > tria_tria_base ; - class dtri_node : public dtri_node_base + class tria_node : public tria_node_base { public : /*---------------------------- delaunay-tri node type */ @@ -135,7 +135,7 @@ } } ; - class dtri_tria : public dtri_tria_base + class tria_tria : public tria_tria_base { public : /*---------------------------- delaunay-tri tria type */ @@ -157,14 +157,14 @@ } } ; - typedef mesh::delaunay_tri_euclidean_2 < + typedef mesh::laguerre_tri_euclidean_2 < iptr_type , - real_type > dtri_pred ; + real_type > tria_core ; typedef mesh::delaunay_tri_k < - dtri_node , - dtri_tria , - dtri_pred > tria_type ; + tria_node , + tria_tria , + tria_core > tria_type ; #define __hashscal sizeof(iptr_type)/sizeof(uint32_t) @@ -425,6 +425,12 @@ { } + __inline_call~rdel_complex_2d ( + ) + { + clear (containers::tight_alloc); + } + __normal_call void_type clear ( containers::alloc_types _alloc = containers::loose_alloc diff --git a/src/libcpp/rdel_mesh/rdel_complex_3.hpp b/src/libcpp/rdel_mesh/rdel_complex_3.hpp index 4b55848..c4f3175 100644 --- a/src/libcpp/rdel_mesh/rdel_complex_3.hpp +++ b/src/libcpp/rdel_mesh/rdel_complex_3.hpp @@ -31,11 +31,11 @@ * -------------------------------------------------------- * - * Last updated: 03 July, 2019 + * Last updated: 22 February, 2020 * - * Copyright 2013-2019 + * Copyright 2013-2020 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- @@ -61,15 +61,15 @@ typedef R real_type; typedef I iptr_type; - typedef mesh::delaunay_tri_node_3 < + typedef mesh::laguerre_tri_node_3 < iptr_type , - real_type > dtri_node_base ; + real_type > tria_node_base ; - typedef mesh::delaunay_tri_tria_3 < + typedef mesh::laguerre_tri_tria_3 < iptr_type , - real_type > dtri_tria_base ; + real_type > tria_tria_base ; - class dtri_node : public dtri_node_base + class tria_node : public tria_node_base { public : /*---------------------------- delaunay-tri node type */ @@ -135,7 +135,7 @@ } } ; - class dtri_tria : public dtri_tria_base + class tria_tria : public tria_tria_base { public : /*---------------------------- delaunay-tri tria type */ @@ -157,14 +157,14 @@ } } ; - typedef mesh::delaunay_tri_euclidean_3 < + typedef mesh::laguerre_tri_euclidean_3 < iptr_type , - real_type > dtri_pred ; + real_type > tria_core ; typedef mesh::delaunay_tri_k < - dtri_node , - dtri_tria , - dtri_pred > tria_type ; + tria_node , + tria_tria , + tria_core > tria_type ; #define __hashscal sizeof(iptr_type)/sizeof(uint32_t) @@ -487,6 +487,12 @@ { } + __inline_call~rdel_complex_3d ( + ) + { + clear (containers::tight_alloc); + } + __normal_call void_type clear ( containers::alloc_types _alloc = containers::loose_alloc diff --git a/src/libcpp/rdel_mesh/rdel_cost_delaunay_2.inc b/src/libcpp/rdel_mesh/rdel_cost_delaunay_2.inc index 4aef371..d8badd0 100644 --- a/src/libcpp/rdel_mesh/rdel_cost_delaunay_2.inc +++ b/src/libcpp/rdel_mesh/rdel_cost_delaunay_2.inc @@ -35,7 +35,7 @@ * * Copyright 2013-2018 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- diff --git a/src/libcpp/rdel_mesh/rdel_cost_delaunay_3.inc b/src/libcpp/rdel_mesh/rdel_cost_delaunay_3.inc index 5c04bef..168df20 100644 --- a/src/libcpp/rdel_mesh/rdel_cost_delaunay_3.inc +++ b/src/libcpp/rdel_mesh/rdel_cost_delaunay_3.inc @@ -35,7 +35,7 @@ * * Copyright 2013-2018 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- @@ -60,7 +60,6 @@ rdel_opts &_args, edge_data &_edat, iptr_type &_part, - char_type &_hits, char_type &_feat, char_type &_topo, char_type &_kind, @@ -85,7 +84,6 @@ if (!base_type::edge_ball ( _geom, _mesh, _tadj, _eadj, _ebal, _pmax, - _hits, _feat, _topo, _part) ) /*--------------------------------- is not restricted */ return ; diff --git a/src/libcpp/rdel_mesh/rdel_cost_delfront_2.inc b/src/libcpp/rdel_mesh/rdel_cost_delfront_2.inc index 5da5d63..75c254c 100644 --- a/src/libcpp/rdel_mesh/rdel_cost_delfront_2.inc +++ b/src/libcpp/rdel_mesh/rdel_cost_delfront_2.inc @@ -35,7 +35,7 @@ * * Copyright 2013-2019 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- @@ -220,14 +220,19 @@ } /*------------------------- calc. refinement priority */ - iptr_type _ebnd=_emin ; - real_type _best; - _best = _llen[_emax]; - _best += (real_type)1.; + real_type static + constexpr _TRAP = (real_type)1.5 ; - _tdat._mark = +0 ; + iptr_type _ebnd = _emin ; + real_type _best = + std::numeric_limits + ::infinity () ; - # ifdef __bias_BNDS + bool_type _trap = false ; + + _tdat._mark = (iptr_type) +0; + + # ifdef __bias_bnds for(_enum = +3; _enum-- != +0; ) { iptr_type _enod[ +3]; @@ -257,6 +262,12 @@ _best = _llen[_enum]; } + if (_llen[_enum] >= + _llen[_emin] *_TRAP ) + { + _trap = true ; + } + _tdat._mark -= +1 ; } } @@ -268,7 +279,7 @@ /*------------------------- calc. refinement priority */ _tdat._cost = - (float) (_erat * _tbal[2]) ; + (float) (_tbal[2] * _erat) ; // scaling via node numbering seems to make slightly // better (more topologically regular) meshes @@ -286,10 +297,26 @@ _tdat._cost/= _enod[1] + 1 ; /*------------------------- refinement classification */ + + // flag cells "trapped" between boundaries -- having + // all nodes on lower dimensional facets and with at + // least one boundary face. + + _trap = _trap && + _mesh._tria. + node(_tnod[0])->fdim() < +2 && + _mesh._tria. + node(_tnod[1])->fdim() < +2 && + _mesh._tria. + node(_tnod[2])->fdim() < +2 ; + if (_erat >= _args.rad2() * _args.rad2() ) { + // if (!_trap) // don't refine trapped cells + { _kind = mesh::ring_item; return ; + } } /*------------------------- eval. size func. at _tbal */ diff --git a/src/libcpp/rdel_mesh/rdel_cost_delfront_3.inc b/src/libcpp/rdel_mesh/rdel_cost_delfront_3.inc index 94cc35c..9ab5623 100644 --- a/src/libcpp/rdel_mesh/rdel_cost_delfront_3.inc +++ b/src/libcpp/rdel_mesh/rdel_cost_delfront_3.inc @@ -35,7 +35,7 @@ * * Copyright 2013-2019 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- @@ -60,7 +60,6 @@ rdel_opts &_args, edge_data &_edat, iptr_type &_part, - char_type &_hits, char_type &_feat, char_type &_topo, char_type &_kind, @@ -84,8 +83,7 @@ /*--------------------------------- calc. circumballs */ if (!base_type::edge_ball ( _geom, _mesh, _tadj, - _eadj, _ebal, - _pmax, _hits, + _eadj, _ebal, _pmax, _feat, _topo, _part) ) /*--------------------------------- is not restricted */ return ; @@ -228,19 +226,24 @@ } /*------------------------- calc. refinement priority */ - iptr_type _ebnd=_emin ; - real_type _best; - _best = _llen[_emax]; - _best += (real_type)1.; + real_type static + constexpr _TRAP = (real_type)1.5 ; - _fdat._mark = +0 ; + iptr_type _ebnd = _emin ; + real_type _best = + std::numeric_limits + ::infinity () ; - # ifdef __bias_BNDS + bool_type _trap = false ; + + _fdat._mark = (iptr_type) +0; + + # ifdef __bias_bnds for(_enum = +3; _enum-- != +0; ) { + /*------------------------- are there bnd-adj. faces? */ iptr_type _enod[ +3]; - mesh_type::tria_type:: - tria_type:: + mesh_type::tria_type::tria_type:: face_node(_enod, _enum, 2, 1); _enod[ +0] = _fnod[_enod[+0]]; _enod[ +1] = _fnod[_enod[+1]]; @@ -265,6 +268,12 @@ _best = _llen[_enum]; } + if (_llen[_enum] >= + _llen[_emin] *_TRAP ) + { + _trap = true ; + } + _fdat._mark -= +1 ; } } @@ -273,15 +282,10 @@ /*------------------------- eval. radius--edge ratios */ real_type _prat = _pmax[ 3] / _llen[_emin] ; - real_type _erat = _tbal[ 3] / - _llen[_emin] ; - - __unreferenced(_prat) ; - __unreferenced(_erat) ; /*------------------------- calc. refinement priority */ _fdat._cost = - (float) (_prat * _pmax[3]) ; + (float) (_pmax[3] * _prat) ; // scaling via node numbering seems to make slightly // better (more topologically regular) meshes @@ -299,10 +303,26 @@ _fdat._cost/= _enod[1] + 1 ; /*------------------------- refinement classification */ + + // flag cells "trapped" between boundaries -- having + // all nodes on lower dimensional facets and with at + // least one boundary face. + + _trap = _trap && + _mesh._tria. + node(_fnod[0])->fdim() < +2 && + _mesh._tria. + node(_fnod[1])->fdim() < +2 && + _mesh._tria. + node(_fnod[2])->fdim() < +2 ; + if (_prat >= _args.rad2() * _args.rad2() ) { + // if (!_trap) // don't refine trapped cells + { _kind = mesh::ring_item; return ; + } } /*------------------------- eval. size func. at _fbal */ @@ -405,8 +425,7 @@ for (_enum = +6; _enum-- != +0; ) { iptr_type _enod[ +4] ; - mesh_type::tria_type:: - tria_type:: + mesh_type::tria_type::tria_type:: face_node(_enod, _enum, 3, 1); _enod[0] = _mesh._tria. tria(_tpos)->node(_enod[ 0]); @@ -427,8 +446,7 @@ for(_fnum = +4; _fnum-- != +0; ) { iptr_type _fnod [ +4]; - mesh_type::tria_type:: - tria_type:: + mesh_type::tria_type::tria_type:: face_node(_fnod, _fnum, 3, 2); _fnod[ +0] = _mesh._tria. tria(_tpos)->node(_fnod[ 0]); @@ -472,19 +490,18 @@ } /*------------------------- calc. refinement priority */ - iptr_type _fbnd=_fmin ; - real_type _best; - _best = _frad[_fmax]; - _best += (real_type)1.; + iptr_type _fbnd = _fmin ; + real_type _best = + std::numeric_limits + ::infinity () ; _tdat._mark = +0 ; - # ifdef __bias_BNDS + # ifdef __bias_bnds for(_fnum = +4; _fnum-- != +0; ) { iptr_type _fnod[ +4]; - mesh_type::tria_type:: - tria_type:: + mesh_type::tria_type::tria_type:: face_node(_fnod, _fnum, 3, 2); _fnod[0] = _mesh._tria. tria(_tpos)->node(_fnod[ 0]); @@ -530,7 +547,7 @@ /*------------------------- calc. refinement priority */ _tdat._cost = - (float) (_trat * _tbal[3]) ; + (float) (_tbal[3] * _trat) ; // scaling via node numbering seems to make slightly // better (more topologically regular) meshes @@ -611,7 +628,8 @@ &_mesh._tria. node(_tnod[2])->pval(0), &_mesh._tria. - node(_tnod[3])->pval(0)) ; + node(_tnod[3])->pval(0) + ) ; if (_vlen <= _args.vol3() ) { diff --git a/src/libcpp/rdel_mesh/rdel_create_init_2.inc b/src/libcpp/rdel_mesh/rdel_create_init_2.inc index 16d7eb8..85ad1aa 100644 --- a/src/libcpp/rdel_mesh/rdel_create_init_2.inc +++ b/src/libcpp/rdel_mesh/rdel_create_init_2.inc @@ -31,11 +31,11 @@ * -------------------------------------------------------- * - * Last updated: 09 August, 2019 + * Last updated: 05 March, 2020 * - * Copyright 2013-2019 + * Copyright 2013-2020 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- @@ -75,9 +75,9 @@ iptr_type _npos = 0 ; tree_type _tree ; for (auto _node = - _init._mesh._set1.head() ; + _init._mesh.node().head(); _node != - _init._mesh._set1.tend() ; + _init._mesh.node().tend(); ++_node, ++_npos) { if (_node->mark() >= +0) @@ -265,7 +265,7 @@ ++_iter ) { auto _node = - &_init._mesh._set1 [*_iter] ; + &_init._mesh. node (*_iter) ; _pmid[0] += _node->pval(0); @@ -281,7 +281,7 @@ ++_iter ) { auto _node = - &_init._mesh._set1 [*_iter] ; + &_init._mesh. node (*_iter) ; real_type _dsqr = geometry::lensqr_2d( @@ -299,7 +299,7 @@ if (_imid > -1) { auto _node = - &_init._mesh._set1 [ _imid] ; + &_init._mesh. node ( _imid) ; iptr_type _npos = -1 ; iptr_type _near = -1 ; @@ -372,7 +372,7 @@ auto _inum =*_iter; auto _node = - &_init._mesh ._set1[*_iter] ; + &_init._mesh . node(*_iter) ; iptr_type _near = -1 ; iptr_type _npos = -1 ; @@ -437,9 +437,9 @@ /*------------------------------ seed edge from init. */ for (auto _iter = - _init._mesh._set2.head(); + _init._mesh.edge().head() ; _iter != - _init._mesh._set2.tend(); + _init._mesh.edge().tend() ; ++_iter ) { if (_iter->mark() >= +0) diff --git a/src/libcpp/rdel_mesh/rdel_create_init_3.inc b/src/libcpp/rdel_mesh/rdel_create_init_3.inc index 2d92145..dbcded2 100644 --- a/src/libcpp/rdel_mesh/rdel_create_init_3.inc +++ b/src/libcpp/rdel_mesh/rdel_create_init_3.inc @@ -31,11 +31,11 @@ * -------------------------------------------------------- * - * Last updated: 09 August, 2019 + * Last updated: 05 March, 2020 * - * Copyright 2013-2019 + * Copyright 2013-2020 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- @@ -75,9 +75,9 @@ iptr_type _npos = 0 ; tree_type _tree ; for (auto _node = - _init._mesh._set1.head() ; + _init._mesh.node().head(); _node != - _init._mesh._set1.tend() ; + _init._mesh.node().tend(); ++_node, ++_npos) { if (_node->mark() >= +0) @@ -404,7 +404,7 @@ ++_iter ) { auto _node = - &_init._mesh._set1 [*_iter] ; + &_init._mesh. node (*_iter) ; _pmid[0] += _node->pval(0); @@ -423,7 +423,7 @@ ++_iter ) { auto _node = - &_init._mesh._set1 [*_iter] ; + &_init._mesh. node (*_iter) ; real_type _dsqr = geometry::lensqr_3d( @@ -441,7 +441,7 @@ if (_imid > -1) { auto _node = - &_init._mesh._set1 [ _imid] ; + &_init._mesh. node ( _imid) ; iptr_type _npos = -1 ; iptr_type _near = -1 ; @@ -514,7 +514,7 @@ auto _inum =*_iter; auto _node = - &_init._mesh ._set1[*_iter] ; + &_init._mesh . node(*_iter) ; iptr_type _near = -1 ; iptr_type _npos = -1 ; @@ -579,9 +579,9 @@ /*------------------------------ seed edge from init. */ for (auto _iter = - _init._mesh._set2.head(); + _init._mesh.edge().head() ; _iter != - _init._mesh._set2.tend(); + _init._mesh.edge().tend() ; ++_iter ) { if (_iter->mark() >= +0) @@ -636,9 +636,9 @@ /*------------------------------ seed face from init. */ for (auto _iter = - _init._mesh._set3.head(); + _init._mesh.tri3().head() ; _iter != - _init._mesh._set3.tend(); + _init._mesh.tri3().tend() ; ++_iter ) { if (_iter->mark() >= +0) diff --git a/src/libcpp/rdel_mesh/rdel_filt_k.hpp b/src/libcpp/rdel_mesh/rdel_filt_k.hpp index 075b6bc..7dbc09a 100644 --- a/src/libcpp/rdel_mesh/rdel_filt_k.hpp +++ b/src/libcpp/rdel_mesh/rdel_filt_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/src/libcpp/rdel_mesh/rdel_make_2.hpp b/src/libcpp/rdel_mesh/rdel_make_2.hpp index 5beb08c..8eefe18 100644 --- a/src/libcpp/rdel_mesh/rdel_make_2.hpp +++ b/src/libcpp/rdel_mesh/rdel_make_2.hpp @@ -31,11 +31,11 @@ * -------------------------------------------------------- * - * Last updated: 09 August, 2019 + * Last updated: 05 March, 2020 * - * Copyright 2013-2019 + * Copyright 2013-2020 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- @@ -375,9 +375,9 @@ iptr_type _npos = 0 ; tree_type _tree ; for (auto _node = - _init._mesh._set1.head() ; + _init._mesh.node().head(); _node != - _init._mesh._set1.tend() ; + _init._mesh.node().tend(); ++_node, ++_npos) { if (_node->mark() >= +0) @@ -432,7 +432,7 @@ ++_iter ) { auto _node = - &_init._mesh._set1 [*_iter] ; + &_init._mesh. node (*_iter) ; _pmid[0] += _node->pval(0); @@ -448,7 +448,7 @@ ++_iter ) { auto _node = - &_init._mesh._set1 [*_iter] ; + &_init._mesh. node (*_iter) ; real_type _dsqr = geometry::lensqr_2d( @@ -466,7 +466,7 @@ if (_imid > -1) { auto _node = - &_init._mesh._set1 [ _imid] ; + &_init._mesh. node ( _imid) ; if (_node->itag () >= +0 ) _geom.projector( @@ -504,7 +504,7 @@ if (*_iter == _imid) continue; auto _node = - &_init._mesh._set1 [*_iter] ; + &_init._mesh. node (*_iter) ; if (_node->itag () >= +0 ) _geom.projector( @@ -554,9 +554,9 @@ _pmax[ 1] = _geom._bmax[ 1] ; for (auto _node = - _init._mesh._set1.head(); + _init._mesh.node().head() ; _node != - _init._mesh._set1.tend(); + _init._mesh.node().tend() ; ++_node ) { if (_node->mark() >= + 0 ) diff --git a/src/libcpp/rdel_mesh/rdel_make_3.hpp b/src/libcpp/rdel_mesh/rdel_make_3.hpp index 28cff4c..1b42959 100644 --- a/src/libcpp/rdel_mesh/rdel_make_3.hpp +++ b/src/libcpp/rdel_mesh/rdel_make_3.hpp @@ -31,11 +31,11 @@ * -------------------------------------------------------- * - * Last updated: 06 July, 2019 + * Last updated: 05 March, 2020 * - * Copyright 2013-2019 + * Copyright 2013-2020 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- @@ -193,7 +193,6 @@ _edat._pass = +0 ; /*--------------------------- call edge predicate */ - char_type _hits; real_type _fbal[ 4]; real_type _sbal[ 4]; @@ -205,7 +204,6 @@ _edat._tadj, _edat._eadj, _fbal,_sbal, - _hits, _edat._feat, _edat._topo, _edat._part) ; @@ -483,9 +481,9 @@ iptr_type _npos = 0 ; tree_type _tree ; for (auto _node = - _init._mesh._set1.head() ; + _init._mesh.node().head(); _node != - _init._mesh._set1.tend() ; + _init._mesh.node().tend(); ++_node, ++_npos) { if (_node->mark() >= +0) @@ -543,7 +541,7 @@ ++_iter ) { auto _node = - &_init._mesh._set1 [*_iter] ; + &_init._mesh. node (*_iter) ; _pmid[0] += _node->pval(0); @@ -562,7 +560,7 @@ ++_iter ) { auto _node = - &_init._mesh._set1 [*_iter] ; + &_init._mesh. node (*_iter) ; real_type _dsqr = geometry::lensqr_3d( @@ -580,7 +578,7 @@ if (_imid > -1) { auto _node = - &_init._mesh._set1 [ _imid] ; + &_init._mesh. node ( _imid) ; if (_node->itag () >= +0 ) _geom.projector( @@ -618,7 +616,7 @@ if (*_iter == _imid) continue ; auto _node = - &_init._mesh._set1 [*_iter] ; + &_init._mesh. node (*_iter) ; if (_node->itag () >= +0 ) _geom.projector( @@ -670,9 +668,9 @@ _pmax[ 2] = _geom._bmax[ 2] ; for (auto _node = - _init._mesh._set1.head(); + _init._mesh.node().head() ; _node != - _init._mesh._set1.tend(); + _init._mesh.node().tend() ; ++_node ) { if (_node->mark() >= + 0 ) diff --git a/src/libcpp/rdel_mesh/rdel_mesh_2.hpp b/src/libcpp/rdel_mesh/rdel_mesh_2.hpp index 52d59a3..5400764 100644 --- a/src/libcpp/rdel_mesh/rdel_mesh_2.hpp +++ b/src/libcpp/rdel_mesh/rdel_mesh_2.hpp @@ -31,11 +31,11 @@ * -------------------------------------------------------- * - * Last updated: 09 August, 2019 + * Last updated: 05 March, 2020 * - * Copyright 2013-2019 + * Copyright 2013-2020 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- @@ -499,7 +499,7 @@ _mesh._tria._nset.head() ; _iter != _mesh._tria._nset.tend() ; - ++_iter , ++_npos) + ++_iter, ++_npos) { if (_iter->mark() >= +0) { @@ -510,7 +510,7 @@ _mesh._tria._tset.head() ; _iter != _mesh._tria._tset.tend() ; - ++_iter , ++_tpos) + ++_iter, ++_tpos) { if (_iter->mark() >= +0) { @@ -558,9 +558,9 @@ _pmax[ 1] = _geom._bmax[ 1] ; for (auto _node = - _init._mesh._set1.head(); + _init._mesh.node().head() ; _node != - _init._mesh._set1.tend(); + _init._mesh.node().tend() ; ++_node ) { if (_node->mark() >= + 0 ) diff --git a/src/libcpp/rdel_mesh/rdel_mesh_3.hpp b/src/libcpp/rdel_mesh/rdel_mesh_3.hpp index 6b06fb6..f005b6f 100644 --- a/src/libcpp/rdel_mesh/rdel_mesh_3.hpp +++ b/src/libcpp/rdel_mesh/rdel_mesh_3.hpp @@ -31,11 +31,11 @@ * -------------------------------------------------------- * - * Last updated: 30 June, 2019 + * Last updated: 05 March, 2020 * - * Copyright 2013-2019 + * Copyright 2013-2020 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- @@ -595,7 +595,7 @@ _mesh._tria._nset.head() ; _iter != _mesh._tria._nset.tend() ; - ++_iter , ++_npos) + ++_iter, ++_npos) { if (_iter->mark() >= +0) { @@ -606,7 +606,7 @@ _mesh._tria._tset.head() ; _iter != _mesh._tria._tset.tend() ; - ++_iter , ++_tpos) + ++_iter, ++_tpos) { if (_iter->mark() >= +0) { @@ -661,9 +661,9 @@ _pmax[ 2] = _geom._bmax[ 2] ; for (auto _node = - _init._mesh._set1.head(); + _init._mesh.node().head() ; _node != - _init._mesh._set1.tend(); + _init._mesh.node().tend() ; ++_node ) { if (_node->mark() >= + 0 ) @@ -761,6 +761,73 @@ seed_mesh(_mesh, _opts) ; } + + + + __static_call + __normal_call void_type init_dual ( + mesh_type &_mesh + ) + { + + //return; + + iptr_list _nsum; + _nsum.set_count( + _mesh._tria._nset.count(), + containers::tight_alloc, +0) ; + + for (auto _iter = + _mesh._eset._lptr.head() ; + _iter != + _mesh._eset._lptr.tend() ; + ++_iter ) + { + if ( *_iter == nullptr) continue ; + + for (auto _item = *_iter ; + _item != nullptr; + _item = _item->_next ) + { + if (_item->_data._feat == mesh::hard_feat) + { + auto _inod = _item->_data._node[0] ; + auto _jnod = _item->_data._node[1] ; + + auto _iptr = + & _mesh._tria._nset[_inod] ; + auto _jptr = + & _mesh._tria._nset[_jnod] ; + + auto _lsqr = geometry::lensqr_3d ( + & _iptr->pval( 0), + & _jptr->pval( 0)) ; + + _lsqr *= (real_type) std::pow(2./3., +2) ; + + _iptr->pval(3) += _lsqr ; + _nsum[_inod] += +1 ; + + _jptr->pval(3) += _lsqr ; + _nsum[_jnod] += +1 ; + } + } + } + + for (auto _iter = _nsum.head() , + _npos = +0 ; + _iter != _nsum.tend() ; + ++_iter, ++_npos) + { + if ( *_iter != +0 ) + _mesh._tria._nset[_npos].pval(3) /= *_iter ; + } + + } + + + + /* -------------------------------------------------------- * RDEL-MESH: build an rDT mesh in R^3. @@ -1079,6 +1146,8 @@ _mode, _args) ; */ + //init_dual( _mesh) ; + init_rdel( _geom, _hfun, _mesh, true, _nnew, _tnew, diff --git a/src/libcpp/rdel_mesh/rdel_offh_delfront_2.inc b/src/libcpp/rdel_mesh/rdel_offh_delfront_2.inc index dacaac4..7ef4215 100644 --- a/src/libcpp/rdel_mesh/rdel_offh_delfront_2.inc +++ b/src/libcpp/rdel_mesh/rdel_offh_delfront_2.inc @@ -31,11 +31,11 @@ * -------------------------------------------------------- * - * Last updated: 30 August, 2019 + * Last updated: 04 Februay, 2020 * - * Copyright 2013-2019 + * Copyright 2013-2020 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- @@ -63,70 +63,62 @@ ) { typename rdel_opts::node_kind - _kind = rdel_opts::null_kind ; + _kind = rdel_opts::null_kind; typename hfun_type::hint_type - _hint =_hfun .null_hint () ; + _hint = _hfun .null_hint() ; - real_type static const _rtol = - (real_type)+1.00E-03 ; + real_type static const + _rtol = (real_type)+1.00E-003 ; - real_type static const _dtol = - (real_type)+8.75E-01 ; + real_type static const + _dtol = (real_type)+8.00E-001 ; - real_type static const _lgap = - (real_type)+9.50E-01 ; + real_type static const + _lgap = (real_type)+9.00E-001 ; - real_type static const _ugap = - (real_type)+1.05E+00 ; + real_type static const + _ugap = (real_type)+1.10E+000 ; __unreferenced(_args) ; if (_enod[1] < _enod[0]) - std::swap(_enod[0], _enod[1]) ; - - real_type _nsiz [ 4] ; - _nsiz[ 0] = _hfun.eval ( - &_mesh._tria. - node(_enod[0])->pval(0) , - _mesh._tria. - node(_enod[0])->idxh()) ; - _nsiz[ 1] = _hfun.eval ( - &_mesh._tria. - node(_enod[1])->pval(0) , - _mesh._tria. - node(_enod[1])->idxh()) ; + std::swap( _enod[0], _enod[1]); + + real_type _hsiz [ 4] ; + _hsiz[ 0] = _hfun.eval ( + &_mesh._tria.node(_enod[0])->pval(0) , + _mesh._tria.node(_enod[0])->idxh()) ; + _hsiz[ 1] = _hfun.eval ( + &_mesh._tria.node(_enod[1])->pval(0) , + _mesh._tria.node(_enod[1])->idxh()) ; real_type _dvec[3] ; - real_type _ipos[2] = { - _mesh._tria. - node(_enod[0])->pval(0) , - _mesh._tria. - node(_enod[0])->pval(1) + real_type _base[2] = { + _mesh._tria.node(_enod[0])->pval(0) , + _mesh._tria.node(_enod[0])->pval(1) , } ; - _hint = _mesh._tria. - node (_enod[0])->idxh() ; + _hint = + _mesh._tria.node (_enod[0])->idxh() ; _dvec[ 0] = - _sbal[ 0] - _ipos[ 0] ; + _sbal[ 0] - _base[ 0] ; _dvec[ 1] = - _sbal[ 1] - _ipos[ 1] ; + _sbal[ 1] - _base[ 1] ; _dvec[ 2] = - geometry::length_2d(_dvec) ; - _dvec[ 0]/= _dvec[ 2] ; - _dvec[ 1]/= _dvec[ 2] ; + geometry:: normalise_2d (_dvec); _ppos[ 0] = _sbal[ 0] ; _ppos[ 1] = _sbal[ 1] ; typename - geom_type::ball_type _ball; + geom_type::ball_type _ball ; _ball. - _pmid[ 0] = _ipos[ 0] ; + _pmid[ 0] = _base[ 0] ; _ball. - _pmid[ 1] = _ipos[ 1] ; + _pmid[ 1] = _base[ 1] ; real_type static const _seps = (real_type)std::sqrt( @@ -141,26 +133,26 @@ for (auto _iter = +0; _iter++ != +4 ; ) { - _nsiz[2] = _hfun.eval(_ppos, _hint) ; + _hsiz[2] = _hfun.eval(_ppos, _hint) ; real_type _PMID[2] = { - (real_type)+.5 * (_ipos[0]+_ppos[0]) , - (real_type)+.5 * (_ipos[1]+_ppos[1]) , + (real_type)+.5 * (_base[0]+_ppos[0]) , + (real_type)+.5 * (_base[1]+_ppos[1]) , } ; typename hfun_type::hint_type _HINT = _hint ; - _nsiz[3] = _hfun.eval(_PMID, _HINT) ; + _hsiz[3] = _hfun.eval(_PMID, _HINT) ; real_type _hval = - _nsiz[0] * (real_type)1./3. + - _nsiz[2] * (real_type)1./3. + - _nsiz[3] * (real_type)1./3. ; + _hsiz[0] * (real_type)1./3. + + _hsiz[2] * (real_type)1./3. + + _hsiz[3] * (real_type)1./3. ; real_type _dist = _hval ; if (_dist >= _dvec[2] * _lgap && - _dist < _dvec[2] * _ugap ) + _dist <= _dvec[2] * _ugap ) { // circumball cushion _dist += _dvec[2] ; _dist /= (real_type)2.; @@ -168,7 +160,7 @@ _kind = rdel_opts::offH_kind ; } - else + if (_dist >= _dvec[2] * _ugap ) { // circumball limiter _ppos[0]=_sbal[0] ; @@ -188,7 +180,7 @@ _dist -= _pert * _dist ; iptr_type _dual = -1 ; - cosine_intersect _pred(_ipos,_dvec); + cosine_intersect _pred(_base,_dvec); _ball._rrad = _dist ; if (!_geom.intersect ( _ball, _pred) ) @@ -244,40 +236,54 @@ ) { typename rdel_opts::node_kind - _kind = rdel_opts::null_kind ; + _kind = rdel_opts::null_kind; typename hfun_type::hint_type - _hint =_hfun .null_hint () ; + _hint = _hfun .null_hint() ; - real_type static const _rtol = - (real_type)+1.00E-03 ; - - real_type static const _lgap = - (real_type)+9.50E-01 ; - - real_type static const _ugap = - (real_type)+1.05E+00 ; + real_type static const + _rtol = (real_type)+1.00E-003 ; real_type static const _alth = (real_type)std::sqrt(3.)/2. ; + real_type static const + _dtol = (real_type)+8.00E-001 ; + + real_type static const + _lgap = (real_type)+9.00E-001 ; + + real_type static const + _ugap = (real_type)+1.10E+000 ; + __unreferenced(_geom) ; __unreferenced(_args) ; - real_type _nsiz [ 4] ; - _nsiz[ 0] = _hfun.eval ( - &_mesh._tria. - node(_fnod[0])->pval(0) , - _mesh._tria. - node(_fnod[0])->idxh()) ; - _nsiz[ 1] = _hfun.eval ( - &_mesh._tria. - node(_fnod[1])->pval(0) , - _mesh._tria. - node(_fnod[1])->idxh()) ; + real_type _hsiz [ 4] ; + _hsiz[ 0] = _hfun.eval ( + &_mesh._tria.node(_fnod[0])->pval(0) , + _mesh._tria.node(_fnod[0])->idxh()) ; + _hsiz[ 1] = _hfun.eval ( + &_mesh._tria.node(_fnod[1])->pval(0) , + _mesh._tria.node(_fnod[1])->idxh()) ; _hint = - _mesh._tria.node(_fnod[0])->idxh() ; + _mesh._tria.node(_fnod[0])->idxh () ; + + real_type _bias[2] = { + _hsiz[ 1] / (_hsiz[0] + _hsiz[1]) , + _hsiz[ 0] / (_hsiz[0] + _hsiz[1]) , + } ; + + real_type _base[2] ; + _base[0] = _bias[0] * + _mesh._tria.node(_fnod[0])->pval(0) + + _bias[1] * + _mesh._tria.node(_fnod[1])->pval(0) ; + _base[1] = _bias[0] * + _mesh._tria.node(_fnod[0])->pval(1) + + _bias[1] * + _mesh._tria.node(_fnod[1])->pval(1) ; _ppos[ 0] = _tbal[ 0] ; _ppos[ 1] = _tbal[ 1] ; @@ -295,22 +301,22 @@ for (auto _iter = +0; _iter++ != +4 ; ) { - _nsiz[2] = _hfun.eval(_ppos, _hint) ; + _hsiz[2] = _hfun.eval(_ppos, _hint) ; real_type _PMID[2] = { - (real_type)+.5 * (_fbal[0]+_ppos[0]) , - (real_type)+.5 * (_fbal[1]+_ppos[1]) , + (real_type)+.5 * (_base[0]+_ppos[0]) , + (real_type)+.5 * (_base[1]+_ppos[1]) , } ; typename hfun_type::hint_type _HINT = _hint ; - _nsiz[3] = _hfun.eval(_PMID, _HINT) ; + _hsiz[3] = _hfun.eval(_PMID, _HINT) ; real_type _hmid = - _nsiz[0] * (real_type)1./6. + - _nsiz[1] * (real_type)1./6. + - _nsiz[2] * (real_type)2./6. + - _nsiz[3] * (real_type)2./6. ; + _hsiz[0] * (real_type)1./6. + + _hsiz[1] * (real_type)1./6. + + _hsiz[2] * (real_type)2./6. + + _hsiz[3] * (real_type)2./6. ; _kind = rdel_opts::offH_kind ; @@ -347,7 +353,7 @@ } if (_dist >= _dvec[2] * _lgap && - _dist < _dvec[2] * _ugap ) + _dist <= _dvec[2] * _ugap ) { // circumball cushion _dist += _dvec[2] ; _dist /= (real_type)2.; @@ -355,7 +361,7 @@ _kind = rdel_opts::offH_kind ; } - else + if (_dist >= _dvec[2] * _ugap ) { // circumball limiter _ppos[0]=_tbal[0] ; @@ -371,16 +377,32 @@ real_type _proj[2] ; _proj[ 0] = - _fbal[ 0] + _dist*_dvec[0]; + _base[ 0] + _dist * _dvec[0]; _proj[ 1] = - _fbal[ 1] + _dist*_dvec[1]; + _base[ 1] + _dist * _dvec[1]; + iptr_type _dual = -1 ; real_type _move = geometry::length_2d(_ppos, _proj); _ppos[ 0] = _proj[ 0]; _ppos[ 1] = _proj[ 1]; + _mesh._tria.find_node ( // test voro. limiter + &_ppos[0], _dual, _fnod[ 0]) ; + + real_type _dlen = + geometry::length_2d( + _ppos, &_mesh._tria. + node(_dual)->pval(0)) ; + + if (_dual != _fnod [ +0] && + _dual != _fnod [ +1] ) + if (_dlen <= _dtol*_hmid ) + { + return rdel_opts::null_kind ; + } + if (_move < _rtol * _hmid) break ; } diff --git a/src/libcpp/rdel_mesh/rdel_offh_delfront_3.inc b/src/libcpp/rdel_mesh/rdel_offh_delfront_3.inc index 81177b6..ee031d2 100644 --- a/src/libcpp/rdel_mesh/rdel_offh_delfront_3.inc +++ b/src/libcpp/rdel_mesh/rdel_offh_delfront_3.inc @@ -31,11 +31,11 @@ * -------------------------------------------------------- * - * Last updated: 30 August, 2019 + * Last updated: 04 Februay, 2020 * - * Copyright 2013-2019 + * Copyright 2013-2020 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- @@ -63,78 +63,68 @@ ) { typename rdel_opts::node_kind - _kind = rdel_opts::null_kind ; + _kind = rdel_opts::null_kind; typename hfun_type::hint_type - _hint =_hfun .null_hint () ; + _hint = _hfun .null_hint() ; - real_type static const _rtol = - (real_type)+1.00E-03 ; + real_type static const + _rtol = (real_type)+1.00E-003 ; - real_type static const _dtol = - (real_type)+8.75E-01 ; + real_type static const + _dtol = (real_type)+8.00E-001 ; - real_type static const _lgap = - (real_type)+9.50E-01 ; + real_type static const + _lgap = (real_type)+9.00E-001 ; - real_type static const _ugap = - (real_type)+1.05E+00 ; + real_type static const + _ugap = (real_type)+1.10E+000 ; __unreferenced(_args) ; if (_enod[1] < _enod[0]) - std::swap(_enod[0], _enod[1]) ; - - real_type _nsiz [ 4] ; - _nsiz[ 0] = _hfun.eval ( - &_mesh._tria. - node(_enod[0])->pval(0) , - _mesh._tria. - node(_enod[0])->idxh()) ; - _nsiz[ 1] = _hfun.eval ( - &_mesh._tria. - node(_enod[1])->pval(0) , - _mesh._tria. - node(_enod[1])->idxh()) ; + std::swap (_enod[0], _enod[1]); + + real_type _hsiz [ 4] ; + _hsiz[ 0] = _hfun.eval ( + &_mesh._tria.node(_enod[0])->pval(0) , + _mesh._tria.node(_enod[0])->idxh()) ; + _hsiz[ 1] = _hfun.eval ( + &_mesh._tria.node(_enod[1])->pval(0) , + _mesh._tria.node(_enod[1])->idxh()) ; real_type _dvec[4] ; - real_type _ipos[3] = { - _mesh._tria. - node(_enod[0])->pval(0) , - _mesh._tria. - node(_enod[0])->pval(1) , - _mesh._tria. - node(_enod[0])->pval(2) + real_type _base[3] = { + _mesh._tria.node(_enod[0])->pval(0) , + _mesh._tria.node(_enod[0])->pval(1) , + _mesh._tria.node(_enod[0])->pval(2) , } ; - _hint = _mesh._tria. - node (_enod[0])->idxh() ; + _hint = + _mesh._tria.node (_enod[0])->idxh() ; _dvec[ 0] = - _sbal[ 0] - _ipos[ 0] ; + _sbal[ 0] - _base[ 0] ; _dvec[ 1] = - _sbal[ 1] - _ipos[ 1] ; + _sbal[ 1] - _base[ 1] ; _dvec[ 2] = - _sbal[ 2] - _ipos[ 2] ; + _sbal[ 2] - _base[ 2] ; _dvec[ 3] = - geometry::length_3d(_dvec) ; - _dvec[ 0]/= _dvec[ 3] ; - _dvec[ 1]/= _dvec[ 3] ; - _dvec[ 2]/= _dvec[ 3] ; + geometry:: normalise_3d (_dvec); _ppos[ 0] = _sbal[ 0] ; _ppos[ 1] = _sbal[ 1] ; _ppos[ 2] = _sbal[ 2] ; typename - geom_type::ball_type _ball; + geom_type::ball_type _ball ; _ball. - _pmid[ 0] = _ipos[ 0] ; + _pmid[ 0] = _base[ 0] ; _ball. - _pmid[ 1] = _ipos[ 1] ; + _pmid[ 1] = _base[ 1] ; _ball. - _pmid[ 2] = _ipos[ 2] ; + _pmid[ 2] = _base[ 2] ; real_type static const _seps = (real_type)std::sqrt( @@ -149,27 +139,27 @@ for (auto _iter = +0; _iter++ != +4 ; ) { - _nsiz[2] = _hfun.eval(_ppos, _hint) ; + _hsiz[2] = _hfun.eval(_ppos, _hint) ; real_type _PMID[3] = { - (real_type)+.5 * (_ipos[0]+_ppos[0]) , - (real_type)+.5 * (_ipos[1]+_ppos[1]) , - (real_type)+.5 * (_ipos[2]+_ppos[2]) , + (real_type)+.5 * (_base[0]+_ppos[0]) , + (real_type)+.5 * (_base[1]+_ppos[1]) , + (real_type)+.5 * (_base[2]+_ppos[2]) , } ; typename hfun_type::hint_type _HINT = _hint ; - _nsiz[3] = _hfun.eval(_PMID, _HINT) ; + _hsiz[3] = _hfun.eval(_PMID, _HINT) ; real_type _hval = - _nsiz[0] * (real_type)1./3. + - _nsiz[2] * (real_type)1./3. + - _nsiz[3] * (real_type)1./3. ; + _hsiz[0] * (real_type)1./3. + + _hsiz[2] * (real_type)1./3. + + _hsiz[3] * (real_type)1./3. ; real_type _dist = _hval ; if (_dist >= _dvec[3] * _lgap && - _dist < _dvec[3] * _ugap ) + _dist <= _dvec[3] * _ugap ) { // circumball cushion _dist += _dvec[3] ; _dist /= (real_type)2.; @@ -177,7 +167,7 @@ _kind = rdel_opts::offH_kind ; } - else + if (_dist >= _dvec[3] * _ugap ) { // circumball limiter _ppos[0]=_sbal[0] ; @@ -198,7 +188,7 @@ _dist -= _pert * _dist ; iptr_type _dual = -1 ; - cosine_intersect _pred(_ipos,_dvec); + cosine_intersect _pred(_base,_dvec); _ball._rrad = _dist ; if (!_geom.intersect ( _ball, _pred) ) @@ -247,7 +237,6 @@ hfun_type &_hfun, mesh_type &_mesh, iptr_type *_enod, - real_type *_pmid, real_type *_evec, real_type *_dvec, real_type *_sbal, @@ -256,55 +245,70 @@ ) { typename rdel_opts::node_kind - _kind = rdel_opts::null_kind ; + _kind = rdel_opts::null_kind; typename hfun_type::hint_type - _hint =_hfun .null_hint () ; + _hint = _hfun .null_hint() ; - real_type static const _rtol = - (real_type)+1.00E-03 ; + real_type static const + _rtol = (real_type)+1.00E-003 ; - real_type static const _dtol = - (real_type)+8.75E-01 ; + real_type static const _alth = + (real_type)std::sqrt(3.)/2. ; - real_type static const _lgap = - (real_type)+9.50E-01 ; + real_type static const + _dtol = (real_type)+8.00E-001 ; - real_type static const _ugap = - (real_type)+1.05E+00 ; + real_type static const + _lgap = (real_type)+9.00E-001 ; - real_type static const _alth = - (real_type)std::sqrt(3.)/2. ; + real_type static const + _ugap = (real_type)+1.10E+000 ; __unreferenced(_args) ; - real_type _nsiz [ 4] ; - _nsiz[ 0] = _hfun.eval ( - &_mesh._tria. - node(_enod[0])->pval(0) , - _mesh._tria. - node(_enod[0])->idxh()) ; - _nsiz[ 1] = _hfun.eval ( - &_mesh._tria. - node(_enod[1])->pval(0) , - _mesh._tria. - node(_enod[1])->idxh()) ; - - _hint = _mesh._tria. - node (_enod[0])->idxh() ; + real_type _hsiz [ 4] ; + _hsiz[ 0] = _hfun.eval ( + &_mesh._tria.node(_enod[0])->pval(0) , + _mesh._tria.node(_enod[0])->idxh()) ; + _hsiz[ 1] = _hfun.eval ( + &_mesh._tria.node(_enod[1])->pval(0) , + _mesh._tria.node(_enod[1])->idxh()) ; + + _hint = + _mesh._tria.node(_enod[0])->idxh () ; + + real_type _bias[2] = { + _hsiz[ 1] / (_hsiz[0] + _hsiz[1]) , + _hsiz[ 0] / (_hsiz[0] + _hsiz[1]) , + } ; + + real_type _base[3] ; + _base[0] = _bias[0] * + _mesh._tria.node(_enod[0])->pval(0) + + _bias[1] * + _mesh._tria.node(_enod[1])->pval(0) ; + _base[1] = _bias[0] * + _mesh._tria.node(_enod[0])->pval(1) + + _bias[1] * + _mesh._tria.node(_enod[1])->pval(1) ; + _base[2] = _bias[0] * + _mesh._tria.node(_enod[0])->pval(2) + + _bias[1] * + _mesh._tria.node(_enod[1])->pval(2) ; _ppos[ 0] = _sbal[ 0] ; _ppos[ 1] = _sbal[ 1] ; _ppos[ 2] = _sbal[ 2] ; typename - geom_type::disc_type _disc; + geom_type::disc_type _disc ; _disc. - _pmid[ 0] = _pmid[ 0] ; + _pmid[ 0] = _base[ 0] ; _disc. - _pmid[ 1] = _pmid[ 1] ; + _pmid[ 1] = _base[ 1] ; _disc. - _pmid[ 2] = _pmid[ 2] ; + _pmid[ 2] = _base[ 2] ; _disc. _nvec[ 0] = _evec[ 0] ; _disc. @@ -328,23 +332,23 @@ for (auto _iter = +0; _iter++ != +4 ; ) { - _nsiz[2] = _hfun.eval(_ppos, _hint) ; + _hsiz[2] = _hfun.eval(_ppos, _hint) ; real_type _PMID[3] = { - (real_type)+.5 * (_pmid[0]+_ppos[0]) , - (real_type)+.5 * (_pmid[1]+_ppos[1]) , - (real_type)+.5 * (_pmid[2]+_ppos[2]) , + (real_type)+.5 * (_base[0]+_ppos[0]) , + (real_type)+.5 * (_base[1]+_ppos[1]) , + (real_type)+.5 * (_base[2]+_ppos[2]) , } ; typename hfun_type::hint_type _HINT = _hint ; - _nsiz[3] = _hfun.eval(_PMID, _HINT) ; + _hsiz[3] = _hfun.eval(_PMID, _HINT) ; real_type _hval = - _nsiz[0] * (real_type)1./6. + - _nsiz[1] * (real_type)1./6. + - _nsiz[2] * (real_type)2./6. + - _nsiz[3] * (real_type)2./6. ; + _hsiz[0] * (real_type)1./6. + + _hsiz[1] * (real_type)1./6. + + _hsiz[2] * (real_type)2./6. + + _hsiz[3] * (real_type)2./6. ; real_type _hmin ; _hmin = std::min (_hval , _epsh); @@ -387,7 +391,7 @@ } if (_dist >= _dvec[3] * _lgap && - _dist < _dvec[3] * _ugap ) + _dist <= _dvec[3] * _ugap ) { // circumball cushion _dist += _dvec[3] ; _dist /= (real_type)2.; @@ -395,7 +399,7 @@ _kind = rdel_opts::offH_kind ; } - else + if (_dist >= _dvec[3] * _ugap ) { // circumball limiter _ppos[0]=_sbal[0] ; @@ -411,7 +415,7 @@ _dist -= _pert * _dist ; iptr_type _dual = -1 ; - cosine_intersect _pred(_pmid,_dvec); + cosine_intersect _pred(_base,_dvec); _disc._rrad = _dist ; if (!_geom.intersect ( _disc, @@ -470,47 +474,42 @@ ) { typename rdel_opts::node_kind - _kind = rdel_opts::null_kind ; + _kind = rdel_opts::null_kind; typename hfun_type::hint_type - _hint =_hfun .null_hint () ; + _hint = _hfun .null_hint() ; - __unreferenced(_geom) ; + real_type static const + _rtol = (real_type)+1.00E-003 ; - real_type static const _rtol = - (real_type)+1.00E-03 ; + real_type static const _alth = + (real_type)std::sqrt(6.)/3. ; - real_type static const _lgap = - (real_type)+9.50E-01 ; + real_type static const + _dtol = (real_type)+8.00E-001 ; - real_type static const _ugap = - (real_type)+1.05E+00 ; + real_type static const + _lgap = (real_type)+9.00E-001 ; - real_type static const _alth = - (real_type)std::sqrt(6.)/3. ; + real_type static const + _ugap = (real_type)+1.10E+000 ; __unreferenced(_geom) ; __unreferenced(_args) ; - real_type _nsiz [ 5] ; - _nsiz[ 0] = _hfun.eval ( - &_mesh._tria. - node(_fnod[0])->pval(0) , - _mesh._tria. - node(_fnod[0])->idxh()) ; - _nsiz[ 1] = _hfun.eval ( - &_mesh._tria. - node(_fnod[1])->pval(0) , - _mesh._tria. - node(_fnod[1])->idxh()) ; - _nsiz[ 2] = _hfun.eval ( - &_mesh._tria. - node(_fnod[2])->pval(0) , - _mesh._tria. - node(_fnod[2])->idxh()) ; - - _hint = _mesh._tria. - node (_fnod[0])->idxh() ; + real_type _hsiz [ 5] ; + _hsiz[ 0] = _hfun.eval ( + &_mesh._tria.node(_fnod[0])->pval(0) , + _mesh._tria.node(_fnod[0])->idxh()) ; + _hsiz[ 1] = _hfun.eval ( + &_mesh._tria.node(_fnod[1])->pval(0) , + _mesh._tria.node(_fnod[1])->idxh()) ; + _hsiz[ 2] = _hfun.eval ( + &_mesh._tria.node(_fnod[2])->pval(0) , + _mesh._tria.node(_fnod[2])->idxh()) ; + + _hint = + _mesh._tria.node (_fnod[0])->idxh() ; _ppos[ 0] = _tbal[ 0] ; _ppos[ 1] = _tbal[ 1] ; @@ -529,7 +528,7 @@ for (auto _iter = +0; _iter++ != +4 ; ) { - _nsiz[3] = _hfun.eval(_ppos, _hint) ; + _hsiz[3] = _hfun.eval(_ppos, _hint) ; real_type _PMID[3] = { (real_type)+.5 * (_fbal[0]+_ppos[0]) , @@ -539,14 +538,14 @@ typename hfun_type::hint_type _HINT = _hint ; - _nsiz[4] = _hfun.eval(_PMID, _HINT) ; + _hsiz[4] = _hfun.eval(_PMID, _HINT) ; real_type _hmid = - _nsiz[0] * (real_type)1./9. + - _nsiz[1] * (real_type)1./9. + - _nsiz[2] * (real_type)1./9. + - _nsiz[3] * (real_type)3./9. + - _nsiz[4] * (real_type)3./9. ; + _hsiz[0] * (real_type)1./9. + + _hsiz[1] * (real_type)1./9. + + _hsiz[2] * (real_type)1./9. + + _hsiz[3] * (real_type)3./9. + + _hsiz[4] * (real_type)3./9. ; _kind = rdel_opts::offH_kind ; @@ -555,7 +554,7 @@ _hmid*_hmid - _fbal[ 3] ; real_type _near = - _fbal[3] * (real_type)2./3. ; + _fbal[3] * (real_type)1./3. ; if (_dsqr < _near) { // min.-space limiter @@ -565,7 +564,7 @@ else { _dist = - (real_type) std::sqrt(_dsqr) ; + (real_type)std::sqrt(_dsqr) ; } if (_dist > _alth * _hmid) @@ -583,7 +582,7 @@ } if (_dist >= _dvec[3] * _lgap && - _dist < _dvec[3] * _ugap ) + _dist <= _dvec[3] * _ugap ) { // circumball cushion _dist += _dvec[3] ; _dist /= (real_type)2.; @@ -591,7 +590,7 @@ _kind = rdel_opts::offH_kind ; } - else + if (_dist >= _dvec[3] * _ugap ) { // circumball limiter _ppos[0]=_tbal[0] ; @@ -608,12 +607,13 @@ real_type _proj[3] ; _proj[ 0] = - _fbal[ 0] + _dist*_dvec[0]; + _fbal[ 0] + _dist * _dvec[0]; _proj[ 1] = - _fbal[ 1] + _dist*_dvec[1]; + _fbal[ 1] + _dist * _dvec[1]; _proj[ 2] = - _fbal[ 2] + _dist*_dvec[2]; + _fbal[ 2] + _dist * _dvec[2]; + iptr_type _dual = -1 ; real_type _move = geometry::length_3d(_ppos, _proj); @@ -621,6 +621,22 @@ _ppos[ 1] = _proj[ 1]; _ppos[ 2] = _proj[ 2]; + _mesh._tria.find_node ( // test voro. limiter + &_ppos[0], _dual, _fnod[ 0]) ; + + real_type _dlen = + geometry::length_3d( + _ppos, &_mesh._tria. + node(_dual)->pval(0)) ; + + if (_dual != _fnod [ +0] && + _dual != _fnod [ +1] && + _dual != _fnod [ +2] ) + if (_dlen <= _dtol*_hmid ) + { + return rdel_opts::null_kind ; + } + if (_move < _rtol * _hmid) break ; } diff --git a/src/libcpp/rdel_mesh/rdel_pred_delaunay_2.hpp b/src/libcpp/rdel_mesh/rdel_pred_delaunay_2.hpp index b54fcd0..c629add 100644 --- a/src/libcpp/rdel_mesh/rdel_pred_delaunay_2.hpp +++ b/src/libcpp/rdel_mesh/rdel_pred_delaunay_2.hpp @@ -35,7 +35,7 @@ * * Copyright 2013-2017 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- diff --git a/src/libcpp/rdel_mesh/rdel_pred_delaunay_3.hpp b/src/libcpp/rdel_mesh/rdel_pred_delaunay_3.hpp index 14e4799..8768d15 100644 --- a/src/libcpp/rdel_mesh/rdel_pred_delaunay_3.hpp +++ b/src/libcpp/rdel_mesh/rdel_pred_delaunay_3.hpp @@ -35,7 +35,7 @@ * * Copyright 2013-2017 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- @@ -211,7 +211,6 @@ __unreferenced(_args); /*--------------------------------- calc. circumballs */ - char_type _hits; char_type _feat, _topo ; iptr_type _part; real_type _ebal[ +4] ; @@ -219,7 +218,6 @@ if (!base_type::edge_ball ( _geom, _mesh, _tadj, _eadj, _ebal, _pmax, - _hits, _feat, _topo, _part) ) { /*--------------------------------- is not restricted */ diff --git a/src/libcpp/rdel_mesh/rdel_pred_delfront_2.hpp b/src/libcpp/rdel_mesh/rdel_pred_delfront_2.hpp index a10dae6..a9e9f69 100644 --- a/src/libcpp/rdel_mesh/rdel_pred_delfront_2.hpp +++ b/src/libcpp/rdel_mesh/rdel_pred_delfront_2.hpp @@ -31,11 +31,11 @@ * -------------------------------------------------------- * - * Last updated: 10 July, 2019 + * Last updated: 07 February, 2020 * - * Copyright 2013-2019 + * Copyright 2013-2020 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- @@ -108,7 +108,7 @@ namespace mesh { -# define __bias_BNDS // preference "bnd" faces +# define __bias_bnds // preference "bnd" faces template < typename G , @@ -147,19 +147,23 @@ real_type, iptr_type > cosine_intersect ; + /*------------------------ max. frontal "redo" steps */ + + iptr_type static const _REDO = + 32 ; + /*------------------------ refinement priority types */ class edge_data { public : - iptr_type _mark = +0; + iptr_type _mark = +0 ; float _cost ; } ; class tria_data { public : - iptr_type _mark = +0; + iptr_type _mark = +0 ; float _cost ; } ; @@ -197,7 +201,7 @@ __static_call __inline_call uint32_t hash_ball ( - real_type*_ball + __const_ptr(real_type) _ball ) { uint32_t _rsiz = @@ -250,9 +254,13 @@ __normal_call bool_type base_edge ( mesh_type &_mesh, iptr_type _tpos, - iptr_type _fpos + iptr_type/*_fpos*/ ) { + iptr_type _fpos; + for (_fpos = +3; _fpos-- != +0; ) + { + /*--------------------- is any face of TPOS "frontal" */ iptr_type _fnod[ +3] ; mesh_type::tria_type::tria_type:: face_node(_fnod, _fpos, +2, +1); @@ -278,9 +286,8 @@ return ( true ) ; } - iptr_type _tadj = +0 ; - iptr_type _fadj = +0 ; - iptr_type _tmrk = +0 ; + iptr_type _tadj = +0 , _fadj = +0 , + _tmrk = +0 ; _mesh. _tria.find_pair ( _tpos, _tadj, _fpos, _fadj, _tmrk) ; @@ -311,6 +318,8 @@ return ( true ) ; } + } + return ( false ) ; } @@ -341,11 +350,11 @@ /*--------------------------- assemble local indexing */ iptr_type _enod[ +3] ; mesh_type::tria_type::tria_type:: - face_node(_enod, _eadj, 2, 1); + face_node(_enod, _eadj, 2, 1) ; _enod[0] =_mesh._tria. - tria(_tadj)->node(_enod[ 0]); + tria(_tadj)->node(_enod[ 0]) ; _enod[1] =_mesh._tria. - tria(_tadj)->node(_enod[ 1]); + tria(_tadj)->node(_enod[ 1]) ; /*--------------------------------- calc. circumballs */ char_type _feat, _topo ; @@ -353,8 +362,8 @@ real_type _ebal[ +3] ; real_type _pmax[ +3] ; if (!base_type::edge_ball ( - _geom, _mesh, _tadj, - _eadj, _ebal, _pmax, + _geom, _mesh, _tadj, _eadj, + _ebal, _pmax, _feat, _topo, _part) ) { /*--------------------------------- is not restricted */ @@ -377,11 +386,19 @@ if (_kind == rdel_opts::null_kind || _kind == rdel_opts::circ_kind ) { - /*----------------------- resort to circumball centre */ - _ppos[0] = _pmax[0] ; - _ppos[1] = _pmax[1] ; + if (_edat._mark++ <= +0) + { + /*---------------------- reject as "void" element */ + _kind = rdel_opts::null_kind ; + } + else + { + /*---------------------- take circumcentre direct */ + _ppos[ 0] = _pmax[ 0] ; + _ppos[ 1] = _pmax[ 1] ; - _kind = rdel_opts::circ_kind ; + _kind = rdel_opts::circ_kind ; + } } /*----------------------- report point-placement kind */ @@ -469,8 +486,8 @@ } /*--------------------------------- find min/max edge */ - iptr_type _emin = (iptr_type)+0; - iptr_type _emax = (iptr_type)+0; + iptr_type _emin = +0; + iptr_type _emax = +0; for(_enum = +3; _enum-- != +1; ) { if (_llen[_emax] < _llen[_enum]) @@ -480,18 +497,18 @@ } /*-------------------------- ask for "frontal" status */ - if(!base_edge(_mesh,_tpos,_emin)) + if(!base_edge(_mesh, _tpos, _emin)) { - if (_tdat._mark <= +512) // finite cycles! // + if (_tdat._mark <= _REDO) // finite cycles! { /*---------------------- reject as "void" element */ - uint32_t _hash = - hash_ball(_tbal) % +8u ; + uint32_t _push = + (hash_ball(_tbal) % 8) + 1 ; - _tdat._mark += - std::max(1u, _hash) ; + _tdat._mark += _push; - return ( _kind ) ; + return + rdel_opts::null_kind; } else { @@ -519,15 +536,11 @@ /*------------------------- assemble "frontal" vector */ real_type _dvec[4] ; - _dvec[0] = _tbal[0] - - _ebal[0] ; - _dvec[1] = _tbal[1] - - _ebal[1] ; + geometry:: + vector_2d( _ebal, _tbal, _dvec) ; _dvec[2] = - geometry::length_2d(_dvec) ; - _dvec[0]/= _dvec[2] ; - _dvec[1]/= _dvec[2] ; + geometry:: normalise_2d (_dvec) ; /*-------------------------- off-centre, a la "ungor" */ _dvec[3] = @@ -572,11 +585,38 @@ if (_kind == rdel_opts::null_kind || _kind == rdel_opts::circ_kind ) { - /*----------------------- resort to circumball centre */ + real_type static const + _OKAY = (real_type) +5./6.; + + real_type _alen = + geometry::tria_quality_2d ( + &_mesh. + _tria.node(_tnod[0])->pval(0) , + &_mesh. + _tria.node(_tnod[1])->pval(0) , + &_mesh. + _tria.node(_tnod[2])->pval(0) + ) ; + + if (_alen <= _OKAY && + _tdat._mark <= +8) + { + /*---------------------- reject as "void" element */ + uint32_t _push = + (hash_ball(_tbal) % 8) + 1; + + _tdat._mark += _push ; + + _kind = rdel_opts::null_kind ; + } + else + { + /*---------------------- take circumcentre direct */ _ppos[ 0] = _tbal[ 0] ; _ppos[ 1] = _tbal[ 1] ; - _kind = rdel_opts::circ_kind ; + _kind = rdel_opts::circ_kind ; + } } /*----------------------- report point-placement kind */ @@ -585,7 +625,7 @@ } ; -# undef __bias_BNDS +# undef __bias_bnds } diff --git a/src/libcpp/rdel_mesh/rdel_pred_delfront_3.hpp b/src/libcpp/rdel_mesh/rdel_pred_delfront_3.hpp index daa41bb..f5040e2 100644 --- a/src/libcpp/rdel_mesh/rdel_pred_delfront_3.hpp +++ b/src/libcpp/rdel_mesh/rdel_pred_delfront_3.hpp @@ -31,11 +31,11 @@ * -------------------------------------------------------- * - * Last updated: 10 July, 2019 + * Last updated: 07 February, 2020 * - * Copyright 2013-2019 + * Copyright 2013-2020 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- @@ -108,7 +108,7 @@ namespace mesh { -# define __bias_BNDS // preference "bnd" faces +# define __bias_bnds // preference "bnd" faces template < typename G , @@ -146,26 +146,30 @@ real_type, iptr_type > cosine_intersect ; + /*------------------------ max. frontal "redo" steps */ + + iptr_type static const _REDO = + 32 ; + /*------------------------ refinement priority types */ class edge_data { public : - iptr_type _mark = +0; + iptr_type _mark = +0 ; float _cost ; } ; class face_data { public : - iptr_type _mark = +0; + iptr_type _mark = +0 ; float _cost ; } ; class tria_data { public : - iptr_type _mark = +0; + iptr_type _mark = +0 ; float _cost ; } ; @@ -217,7 +221,7 @@ __static_call __inline_call uint32_t hash_ball ( - real_type*_ball + __const_ptr(real_type) _ball ) { uint32_t _rsiz = @@ -266,34 +270,49 @@ -------------------------------------------------------- */ - template < - typename list_type - > __static_call __normal_call bool_type base_edge ( mesh_type &_mesh, - iptr_type *_enod, - list_type &_tset + iptr_type *_FNOD, + iptr_type _tadj, + iptr_type _fadj ) { + containers::array _tset; + + _tset.set_alloc(8) ; + + iptr_type _epos; + for (_epos = +3; _epos-- != +0; ) + { + /*--------------------- is any face of FPOS "frontal" */ + iptr_type _enod[ +3]; + mesh_type::tria_type::tria_type:: + face_node(_enod, _epos, 2, 1); + _enod[0] = _FNOD[_enod[ 0]]; + _enod[1] = _FNOD[_enod[ 1]]; + + _tset.set_count(0) ; + + base_type::edge_loop (_mesh , + _enod, _tadj , + _fadj, _tset ) ; + + algorithms::isort ( + &_enod[0], &_enod[2], + std::less()); + typename mesh_type:: edge_data _edat; _edat._node[0] = _enod[0] ; _edat._node[1] = _enod[1] ; - algorithms::isort ( - _edat._node.head(), - _edat._node.tend(), - std::less()) ; - typename mesh_type:: edge_list:: - item_type *_eptr = nullptr ; - if (_mesh.find_edge(_edat,_eptr)) + item_type *_eptr = nullptr ; + if(_mesh.find_edge(_edat,_eptr)) { - if (_eptr->_data._kind - == mesh::good_item ) - return ( true ) ; + return ( true ) ; } iptr_type _fpos ; @@ -357,6 +376,8 @@ } } + } + return ( false ) ; } @@ -370,9 +391,13 @@ __normal_call bool_type base_face ( mesh_type &_mesh, iptr_type _tpos, - iptr_type _fpos + iptr_type/*_fpos*/ ) { + iptr_type _fpos; + for (_fpos = +4; _fpos-- != +0; ) + { + /*--------------------- is any face of TPOS "frontal" */ iptr_type _fnod[ +4] ; mesh_type::tria_type::tria_type:: face_node(_fnod, _fpos, +3, +2); @@ -401,12 +426,11 @@ return ( true ) ; } - iptr_type _tadj = +0 ; - iptr_type _fadj = +0 ; - iptr_type _tmrk = +0 ; + iptr_type _tadj = +0 , _fadj = +0 , + _tmrk = +0 ; _mesh. _tria.find_pair ( - _tpos, _tadj, - _fpos, _fadj, _tmrk) ; + _tpos, _tadj, + _fpos, _fadj, _tmrk) ; if (_tadj != _mesh._tria.null_flag()) { @@ -436,6 +460,8 @@ return ( true ) ; } + } + return ( false ) ; } @@ -466,21 +492,20 @@ /*--------------------------- assemble local indexing */ iptr_type _enod[ +4] ; mesh_type::tria_type::tria_type:: - face_node(_enod, _eadj, 3, 1); + face_node(_enod, _eadj, 3, 1) ; _enod[0] =_mesh._tria. - tria(_tadj)->node(_enod[ 0]); + tria(_tadj)->node(_enod[ 0]) ; _enod[1] =_mesh._tria. - tria(_tadj)->node(_enod[ 1]); + tria(_tadj)->node(_enod[ 1]) ; /*--------------------------------- calc. circumballs */ - char_type _hits, _feat, _topo; + char_type _feat, _topo ; iptr_type _part; real_type _ebal[ +4] ; real_type _pmax[ +4] ; if (!base_type::edge_ball ( - _geom, _mesh, _tadj, - _eadj, _ebal, - _pmax, _hits, + _geom, _mesh, _tadj, _eadj, + _ebal, _pmax, _feat, _topo, _part) ) { /*--------------------------------- is not restricted */ @@ -503,12 +528,20 @@ if (_kind == rdel_opts::null_kind || _kind == rdel_opts::circ_kind ) { - /*----------------------- resort to circumball centre */ - _ppos[0] = _pmax[0] ; - _ppos[1] = _pmax[1] ; - _ppos[2] = _pmax[2] ; + if (_edat._mark++ <= 0) + { + /*---------------------- reject as "void" element */ + _kind = rdel_opts::null_kind ; + } + else + { + /*---------------------- take circumcentre direct */ + _ppos[ 0] = _pmax[ 0] ; + _ppos[ 1] = _pmax[ 1] ; + _ppos[ 2] = _pmax[ 2] ; - _kind = rdel_opts::circ_kind ; + _kind = rdel_opts::circ_kind ; + } } /*----------------------- report point-placement kind */ @@ -554,8 +587,8 @@ real_type _fbal[ +4] ; real_type _pmax[ +4] ; if (!base_type::face_ball ( - _geom, _mesh, _tadj, - _fadj, _fbal, _pmax, + _geom, _mesh, _tadj, _fadj, + _fbal, _pmax, _feat, _topo, _part) ) { /*--------------------------------- is not restricted */ @@ -586,8 +619,8 @@ } /*--------------------------------- find min/max edge */ - iptr_type _emin = (iptr_type)+0; - iptr_type _emax = (iptr_type)+0; + iptr_type _emin = +0; + iptr_type _emax = +0; for(_enum = +3; _enum-- != +1; ) { if (_llen[_emax] < _llen[_enum]) @@ -596,34 +629,20 @@ _emin = _enum ; } - /*--------------------------------- pop edge indexing */ - iptr_type _enod[ +3]; - mesh_type::tria_type::tria_type:: - face_node(_enod, _emin, 2, 1); - _enod[0] = _fnod[_enod[ 0]]; - _enod[1] = _fnod[_enod[ 1]]; - _enod[2] = _fnod[_enod[ 2]]; - - containers - ::array _tset ; - _tset.set_alloc(8) ; - base_type::edge_loop ( _mesh , - _enod, _tadj , - _fadj, _tset ) ; - /*-------------------------- ask for "frontal" status */ - if(!base_edge(_mesh, _enod, _tset)) + if(!base_edge(_mesh, _fnod, _tadj , + _fadj) ) { - if (_fdat._mark <= +512) // finite cycles! // + if (_fdat._mark <= _REDO) // finite cycles! { /*---------------------- reject as "void" element */ - uint32_t _hash = - hash_ball(_pmax) % +8u ; + uint32_t _push = + (hash_ball(_pmax) % 8) + 1 ; - _fdat._mark += - std::max(1u, _hash) ; + _fdat._mark += _push; - return ( _kind ) ; + return + rdel_opts::null_kind; } else { @@ -632,6 +651,13 @@ } /*--------------------------------- eval edge metrics */ + iptr_type _enod[ +3]; + mesh_type::tria_type::tria_type:: + face_node(_enod, _emin, 2, 1) ; + _enod[0] = _fnod[_enod[ 0]] ; + _enod[1] = _fnod[_enod[ 1]] ; + _enod[2] = _fnod[_enod[ 2]] ; + real_type _evec[4] = { _mesh. _tria.node(_enod[1])->pval(0) - @@ -667,24 +693,14 @@ _pmid[ 2]*= (real_type) +.5 ; real_type _dvec[ +5] ; - _dvec[ 0] = _pmax[0] - - _pmid[0] ; - _dvec[ 1] = _pmax[1] - - _pmid[1] ; - _dvec[ 2] = _pmax[2] - - _pmid[2] ; + geometry:: + vector_3d( _pmid, _pmax, _dvec) ; _evec[ 3] = - geometry::length_3d(_evec) ; - _evec[ 0]/= _evec[3] ; - _evec[ 1]/= _evec[3] ; - _evec[ 2]/= _evec[3] ; + geometry:: normalise_3d (_evec) ; _dvec[ 3] = - geometry::length_3d(_dvec) ; - _dvec[ 0]/= _dvec[3] ; - _dvec[ 1]/= _dvec[3] ; - _dvec[ 2]/= _dvec[3] ; + geometry:: normalise_3d (_dvec) ; /*-------------------------- off-centre, a la "ungor" */ _dvec[4] = @@ -709,8 +725,7 @@ ::offH_kind) ) _kind = face_offh( _geom, _size , _mesh, _enod, - _pmid , _evec, _dvec, - _pmax , + _evec , _dvec, _pmax, _ppos , _args) ; } if (_kind == rdel_opts::null_kind || @@ -728,12 +743,39 @@ if (_kind == rdel_opts::null_kind || _kind == rdel_opts::circ_kind ) { - /*----------------------- resort to circumball centre */ + real_type static const + _OKAY = (real_type) +5./6.; + + real_type _alen = + geometry::tria_quality_3d ( + &_mesh. + _tria.node(_fnod[0])->pval(0) , + &_mesh. + _tria.node(_fnod[1])->pval(0) , + &_mesh. + _tria.node(_fnod[2])->pval(0) + ) ; + + if (_alen <= _OKAY && + _fdat._mark <= +8) + { + /*---------------------- reject as "void" element */ + uint32_t _push = + (hash_ball(_pmax) % 8) + 1; + + _fdat._mark += _push ; + + _kind = rdel_opts::null_kind ; + } + else + { + /*---------------------- take circumcentre direct */ _ppos[ 0] = _pmax[ 0] ; _ppos[ 1] = _pmax[ 1] ; _ppos[ 2] = _pmax[ 2] ; - _kind = rdel_opts::circ_kind ; + _kind = rdel_opts::circ_kind ; + } } /*----------------------- report point-placement kind */ @@ -829,8 +871,8 @@ } /*--------------------------------- find min/max edge */ - iptr_type _emin = (iptr_type)+0; - iptr_type _emax = (iptr_type)+0; + iptr_type _emin = +0; + iptr_type _emax = +0; for(_enum = +6; _enum-- != +1; ) { if (_llen[_emax] < _llen[_enum]) @@ -868,8 +910,8 @@ } /*--------------------------------- find min/max face */ - iptr_type _fmin = (iptr_type)+0; - iptr_type _fmax = (iptr_type)+0; + iptr_type _fmin = +0; + iptr_type _fmax = +0; for(_fpos = +4; _fpos-- != +1; ) { if (_frad[_fmax] < _frad[_fpos]) @@ -879,18 +921,18 @@ } /*-------------------------- ask for "frontal" status */ - if(!base_face(_mesh,_tpos,_fmin)) + if(!base_face(_mesh, _tpos, _fmin)) { - if (_tdat._mark <= +512) // finite cycles! // + if (_tdat._mark <= _REDO) // finite cycles! { /*---------------------- reject as "void" element */ - uint32_t _hash = - hash_ball(_tbal) % +8u ; + uint32_t _push = + (hash_ball(_tbal) % 8) + 1 ; - _tdat._mark += - std::max(1u, _hash) ; + _tdat._mark += _push; - return ( _kind ) ; + return + rdel_opts::null_kind; } else { @@ -939,18 +981,11 @@ /*------------------------- assemble "frontal" vector */ real_type _dvec[5] ; - _dvec[0] = _tbal[0] - - _fbal[0] ; - _dvec[1] = _tbal[1] - - _fbal[1] ; - _dvec[2] = _tbal[2] - - _fbal[2] ; + geometry:: + vector_3d( _fbal, _tbal, _dvec) ; _dvec[3] = - geometry::length_3d (_dvec) ; - _dvec[0]/= _dvec[3] ; - _dvec[1]/= _dvec[3] ; - _dvec[2]/= _dvec[3] ; + geometry:: normalise_3d (_dvec) ; /*------------------------- off-centre - a'la "ungor" */ _dvec[4] = @@ -993,15 +1028,29 @@ if (_kind == rdel_opts::null_kind || _kind == rdel_opts::circ_kind ) { - /*----------------------- resort to circumball centre */ - if (_tdat._mark <= +8 ) + real_type static const + _OKAY = (real_type) +5./6.; + + real_type _vlen = + geometry::tria_quality_3d ( + &_mesh. + _tria.node(_tnod[0])->pval(0) , + &_mesh. + _tria.node(_tnod[1])->pval(0) , + &_mesh. + _tria.node(_tnod[2])->pval(0) , + &_mesh. + _tria.node(_tnod[3])->pval(0) + ) ; + + if (_vlen <= _OKAY && + _tdat._mark <= +8) { /*---------------------- reject as "void" element */ - uint32_t _hash = - hash_ball(_tbal) % +8u; + uint32_t _push = + (hash_ball(_tbal) % 8) + 1; - _tdat._mark += - std::max(1u, _hash) ; + _tdat._mark += _push ; _kind = rdel_opts::null_kind ; } @@ -1022,7 +1071,7 @@ } ; -# undef __bias_BNDS +# undef __bias_bnds } diff --git a/src/libcpp/rdel_mesh/rdel_refine_ball_2.inc b/src/libcpp/rdel_mesh/rdel_refine_ball_2.inc index 2698d32..dfa866a 100644 --- a/src/libcpp/rdel_mesh/rdel_refine_ball_2.inc +++ b/src/libcpp/rdel_mesh/rdel_refine_ball_2.inc @@ -31,11 +31,11 @@ * -------------------------------------------------------- * - * Last updated: 25 January, 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/ * -------------------------------------------------------- @@ -83,7 +83,11 @@ mesh_type::tria_type tria_type ; public : - iptr_type _npos; + real_type _dist = + std::numeric_limits + ::infinity(); + + iptr_type _npos ; public : __inline_call node_pred ( @@ -91,30 +95,55 @@ ) : _npos(_nsrc) {} /*--------------------- find adj. set of tria-to-node */ __inline_call bool_type operator() ( - tria_type&_tria, - iptr_type _tpos, + tria_type&_tria , + iptr_type _tpos , iptr_type _fpos ) { - iptr_type _tnod[3] = { - _tria.tria(_tpos)->node(0) , - _tria.tria(_tpos)->node(1) , - _tria.tria(_tpos)->node(2) - } ; + # define CLOSEST(_pptr, _qptr) \ + real_type _dsqr ; \ + _dsqr = geometry::lensqr_2d ( \ + &_pptr->pval(0), \ + &_qptr->pval(0)) ; \ + if (this->_dist > _dsqr) \ + { \ + this->_dist = _dsqr; \ + return true ; \ + } \ + + /*--------------------- add if minimise dist. to node */ + auto _nptr = + _tria .node( this->_npos ) ; + + auto _iptr = _tria.node( + _tria .tria(_tpos)->node(0)) ; + auto _jptr = _tria.node( + _tria .tria(_tpos)->node(1)) ; + auto _kptr = _tria.node( + _tria .tria(_tpos)->node(2)) ; __unreferenced(_fpos) ; - if (_tnod[0] == this->_npos) - return true ; - if (_tnod[1] == this->_npos) - return true ; - if (_tnod[2] == this->_npos) - return true ; + if (_iptr != _nptr) + { + CLOSEST( _iptr, _nptr ) + } + if (_jptr != _nptr) + { + CLOSEST( _jptr, _nptr ) + } + if (_kptr != _nptr) + { + CLOSEST( _kptr, _nptr ) + } + + return false; - return false ; + # undef CLOSEST } } ; + /*--------------------- refine next "protecting ball" */ typename rdel_opts::node_kind _kind = rdel_opts::null_kind ; @@ -162,61 +191,58 @@ if ( !_find ) return _kind ; /*--------------------- check dist. to existing nodes */ - real_type static const _HTOL = - (real_type) +.333 * .333 ; + real_type static constexpr _HTOL = + (real_type) +3./8. * +3./8. ; - real_type static const _STOL = - (real_type) +.500 * .500 ; + real_type static constexpr _STOL = + (real_type) +1./2. * +1./2. ; - iptr_list _tset; - _tset.set_alloc( +32) ; + iptr_type _base = _ball._node[0]; + real_type _rmax = _ball._ball[2]; - iptr_type _nadj = - _ball._node [ 0] ; + iptr_list _tset ; + _tset.set_alloc ( +32 ); _mesh._tria.walk_node ( - _nadj, - node_pred(_nadj), _tset) ; - - real_type _rmax = - _ball._ball [ 2] ; + _base, node_pred(_base), _tset) ; for (auto _tpos = _tset.head() ; _tpos != _tset.tend() ; ++_tpos ) { - iptr_type _npos; - for (_npos = +3; _npos-- != +0; ) - { - iptr_type _node = - _mesh._tria. - tria(*_tpos)->node(_npos) ; + iptr_type _npos; + for (_npos = +3; _npos-- != +0; ) + { + iptr_type _node = + _mesh._tria. + tria(*_tpos)->node(_npos) ; - if (_node == _nadj) continue; + if (_node == _base) continue; - iptr_type _feat = - _mesh. - _tria.node(_node)->feat() ; + iptr_type _feat = + _mesh. + _tria.node(_node)->feat() ; - real_type _dsqr = - geometry::lensqr_2d ( - &_mesh._tria. - node(_nadj)->pval(0) , - &_mesh._tria. - node(_node)->pval(0) ) ; + real_type _dsqr = + geometry::lensqr_2d ( + &_mesh._tria. + node(_base)->pval(0) , + &_mesh._tria. + node(_node)->pval(0) + ) ; - if (_feat == hard_feat) - { - _rmax = std::min ( - _rmax, _HTOL * _dsqr) ; - } - else - { - _rmax = std::min ( - _rmax, _STOL * _dsqr) ; + if (_feat == hard_feat) + { + _rmax = std::min ( + _rmax, _HTOL * _dsqr) ; + } + else + { + _rmax = std::min ( + _rmax, _STOL * _dsqr) ; + } } } - } /*--------------------- otherwise push "collar" nodes */ _ball._ball[2] = std:: min ( @@ -225,9 +251,8 @@ _ball._ball[2] = std::sqrt ( _ball._ball [ 2]) ; - iptr_type _ndeg = - _mesh._tria. - node(_nadj)->topo() ; + auto _ndeg = + _mesh._tria.node(_base)->topo() ; /*--------------------- find intersections with GEOM. */ typename @@ -239,13 +264,11 @@ _hdat._pmid[1] = _ball._ball[1] ; mesh::keep_all_2d < - real_type , - iptr_type > _pred ; + real_type, iptr_type> _pred ; mesh::keep_all_2d < - real_type , - iptr_type > _halo ; + real_type, iptr_type> _halo ; - for (auto _iter = 32; _iter-- != 0 ; ) + for(auto _iter = 64; _iter-- != +0 ; ) { bool_type _okay = true; @@ -303,7 +326,76 @@ /* -------------------------------------------------------- - * INIT-BALL: setup ball "collar". + * MARK-FEAT: "feature" nodes in "collar". + -------------------------------------------------------- + */ + + template < + typename halo_type + > + __static_call + __normal_call void_type mark_feat ( + mesh_type &_mesh , + iptr_type _base , + halo_type &_halo , + iptr_list &_mark , + rdel_opts &_args + ) + { + /*------------ MARK[i] = 1 for nodes in "sharp-feat." */ + real_type _DtoR = + (real_type)+3.141592653589793 / +180.; + + real_type _PHI1 = + (real_type)+180. - _args.phi1() ; + + real_type _HARD = + std::cos(_PHI1 * _DtoR) ; + + auto _BASE = _mesh._tria.node(_base); + + _mark.set_count(_halo._list.count()); + _mark.fill( +0 ) ; + + for (auto _ipos = _halo._list.head() ; + _ipos != _halo._list.tend() ; + ++_ipos ) + for (auto _jpos = _ipos + 1; + _jpos != _halo._list.tend() ; + ++_jpos ) + { + /*--------------------- calc. angle from IPOS to JPOS */ + if (_ipos == _jpos) continue ; + + auto _inum = + _ipos - _halo._list.head(); + auto _jnum = + _jpos - _halo._list.head(); + + real_type _ivec[2], _jvec[2] ; + geometry::vector_2d ( + &_BASE->pval(0), + &_ipos->pval(0), _ivec); + + geometry::vector_2d ( + &_BASE->pval(0), + &_jpos->pval(0), _jvec); + + real_type _acos = + geometry::cosine_2d(_ivec, _jvec) ; + + if (_acos >= _HARD) + { + /*--------------------- MARK pair if feat. is "sharp" */ + _mark[_inum] = +1 ; + _mark[_jnum] = +1 ; + } + } + } + + /* + -------------------------------------------------------- + * INIT-BALL: set-up ball "collar". -------------------------------------------------------- */ @@ -323,8 +415,8 @@ __unreferenced(_hfun) ; __unreferenced(_mode) ; __unreferenced(_pass) ; - __unreferenced(_args) ; + iptr_list _mark ; for (auto _bpos = _mesh._bset._lptr.head () ; _bpos != @@ -337,9 +429,9 @@ _ball != nullptr; _ball = _ball->_next ) { - + /*--------------------- build "collar" for given ball */ typename - geom_type::ball_type _hdat ; + geom_type::ball_type _hdat ; _hdat._pmid[0] = _ball->_data._ball[0] ; _hdat._pmid[1] = @@ -348,28 +440,36 @@ _hdat._rrad = std::sqrt(_ball->_data._ball[2]) ; - iptr_type _nadj = + iptr_type _base = _ball->_data._node[0] ; mesh::keep_all_2d < - real_type , - iptr_type > _halo ; + real_type, iptr_type> _halo ; + + _geom.intersect( _hdat, _halo) ; - _geom. - intersect(_hdat, _halo) ; + mark_feat(_mesh, + _base,_halo, _mark, _args) ; + iptr_type _inum = +0 ; for (auto _iter = _halo._list.head() ; _iter != _halo._list.tend() ; - ++_iter ) + ++_iter, ++_inum) { + /*--------------------- push nodes + constraint faces */ + if (_mark[_inum] <= +0) continue; + iptr_type _hint = - _mesh._tria. - node(_nadj)->next() ; + _mesh._tria.node(_base)->next() ; + + real_type _PPOS[3] ; // weight = 0 + _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, - _hint ) ) + &_PPOS[ 0], _node, _hint) ) { _mesh._tria.node( _node)->idxh() = @@ -385,7 +485,7 @@ _node)->topo() = 2 ; edge_data _edat; - _edat._node[0] = _nadj ; + _edat._node[0] = _base ; _edat._node[1] = _node ; _epro.push(_edat) ; diff --git a/src/libcpp/rdel_mesh/rdel_refine_ball_3.inc b/src/libcpp/rdel_mesh/rdel_refine_ball_3.inc index d8a9cc5..08fb600 100644 --- a/src/libcpp/rdel_mesh/rdel_refine_ball_3.inc +++ b/src/libcpp/rdel_mesh/rdel_refine_ball_3.inc @@ -31,11 +31,11 @@ * -------------------------------------------------------- * - * Last updated: 15 February, 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/ * -------------------------------------------------------- @@ -86,7 +86,11 @@ mesh_type::tria_type tria_type ; public : - iptr_type _npos; + real_type _dist = + std::numeric_limits + ::infinity(); + + iptr_type _npos ; public : __inline_call node_pred ( @@ -94,33 +98,61 @@ ) : _npos(_nsrc) {} /*--------------------- find adj. set of tria-to-node */ __inline_call bool_type operator() ( - tria_type&_tria, - iptr_type _tpos, + tria_type&_tria , + iptr_type _tpos , iptr_type _fpos ) { - iptr_type _tnod[4] = { - _tria.tria(_tpos)->node(0) , - _tria.tria(_tpos)->node(1) , - _tria.tria(_tpos)->node(2) , - _tria.tria(_tpos)->node(3) - } ; + # define CLOSEST(_pptr, _qptr) \ + real_type _dsqr ; \ + _dsqr = geometry::lensqr_3d ( \ + &_pptr->pval(0), \ + &_qptr->pval(0)) ; \ + if (this->_dist > _dsqr) \ + { \ + this->_dist = _dsqr; \ + return true ; \ + } \ + + /*--------------------- add if minimise dist. to node */ + auto _nptr = + _tria .node( this->_npos ) ; + + auto _iptr = _tria.node( + _tria .tria(_tpos)->node(0)) ; + auto _jptr = _tria.node( + _tria .tria(_tpos)->node(1)) ; + auto _kptr = _tria.node( + _tria .tria(_tpos)->node(2)) ; + auto _lptr = _tria.node( + _tria .tria(_tpos)->node(3)) ; __unreferenced(_fpos) ; - if (_tnod[0] == this->_npos) - return true ; - if (_tnod[1] == this->_npos) - return true ; - if (_tnod[2] == this->_npos) - return true ; - if (_tnod[3] == this->_npos) - return true ; + if (_iptr != _nptr) + { + CLOSEST( _iptr, _nptr ) + } + if (_jptr != _nptr) + { + CLOSEST( _jptr, _nptr ) + } + if (_kptr != _nptr) + { + CLOSEST( _kptr, _nptr ) + } + if (_lptr != _nptr) + { + CLOSEST( _lptr, _nptr ) + } + + return false; - return false ; + # undef CLOSEST } } ; + /*--------------------- refine next "protecting ball" */ typename rdel_opts::node_kind _kind = rdel_opts::null_kind ; @@ -171,61 +203,58 @@ if ( !_find ) return _kind ; /*--------------------- check dist. to existing nodes */ - real_type static const _HTOL = - (real_type) +.333 * .333 ; + real_type static constexpr _HTOL = + (real_type) +3./8. * +3./8. ; - real_type static const _STOL = - (real_type) +.500 * .500 ; + real_type static constexpr _STOL = + (real_type) +1./2. * +1./2. ; - iptr_list _tset; - _tset.set_alloc( +32) ; + iptr_type _base = _ball._node[0]; + real_type _rmax = _ball._ball[3]; - iptr_type _nadj = - _ball._node [ 0] ; + iptr_list _tset ; + _tset.set_alloc ( +32 ); _mesh._tria.walk_node ( - _nadj, - node_pred(_nadj), _tset) ; - - real_type _rmax = - _ball._ball [ 3] ; + _base, node_pred(_base), _tset) ; for (auto _tpos = _tset.head() ; _tpos != _tset.tend() ; ++_tpos ) { - iptr_type _npos; - for (_npos = +3; _npos-- != +0; ) - { - iptr_type _node = - _mesh._tria. - tria(*_tpos)->node(_npos) ; + iptr_type _npos; + for (_npos = +3; _npos-- != +0; ) + { + iptr_type _node = + _mesh._tria. + tria(*_tpos)->node(_npos) ; - if (_node == _nadj) continue; + if (_node == _base) continue; - iptr_type _feat = - _mesh. - _tria.node(_node)->feat() ; + iptr_type _feat = + _mesh. + _tria.node(_node)->feat() ; - real_type _dsqr = - geometry::lensqr_3d ( - &_mesh._tria. - node(_nadj)->pval(0) , - &_mesh._tria. - node(_node)->pval(0) ) ; + real_type _dsqr = + geometry::lensqr_3d ( + &_mesh._tria. + node(_base)->pval(0) , + &_mesh._tria. + node(_node)->pval(0) + ) ; - if (_feat == hard_feat) - { - _rmax = std::min ( - _rmax, _HTOL * _dsqr) ; - } - else - { - _rmax = std::min ( - _rmax, _STOL * _dsqr) ; + if (_feat == hard_feat) + { + _rmax = std::min ( + _rmax, _HTOL * _dsqr) ; + } + else + { + _rmax = std::min ( + _rmax, _STOL * _dsqr) ; + } } } - } /*--------------------- otherwise form "collar" radii */ _ball._ball[3] = std:: min ( @@ -234,9 +263,8 @@ _ball._ball[3] = std::sqrt ( _ball._ball [ 3]) ; - iptr_type _ndeg = - _mesh._tria. - node(_nadj)->topo() ; + auto _ndeg = + _mesh._tria.node(_base)->topo() ; /*--------------------- find intersections with geom. */ typename @@ -250,13 +278,11 @@ _hdat._pmid[2] = _ball._ball[2] ; mesh::keep_all_3d < - real_type , - iptr_type > _pred ; + real_type, iptr_type> _pred ; mesh::keep_all_3d < - real_type , - iptr_type > _halo ; + real_type, iptr_type> _halo ; - for(auto _iter = 32; _iter-- != 0 ; ) + for(auto _iter = 64; _iter-- != +0 ; ) { bool_type _okay = true ; @@ -273,8 +299,8 @@ (real_type)+1.0 * _ball._ball[3] * _ball._ball[3] ; - _okay = _okay & _geom.intersect ( - _pdat, _pred) ; // actual! + _okay = _okay & + _geom.intersect (_pdat, _pred) ; // actual! if(!_okay) { @@ -290,8 +316,8 @@ continue ; } - _okay = _okay & _geom.intersect ( - _hdat, _halo) ; // bracket + _okay = _okay & + _geom.intersect (_hdat, _halo) ; // bracket if(!_okay) { @@ -314,7 +340,76 @@ /* -------------------------------------------------------- - * INIT-BALL: setup ball "collar". + * MARK-FEAT: "feature" nodes in "collar". + -------------------------------------------------------- + */ + + template < + typename halo_type + > + __static_call + __normal_call void_type mark_feat ( + mesh_type &_mesh , + iptr_type _base , + halo_type &_halo , + iptr_list &_mark , + rdel_opts &_args + ) + { + /*------------ MARK[i] = 1 for nodes in "sharp-feat." */ + real_type _DtoR = + (real_type)+3.141592653589793 / +180.; + + real_type _PHI1 = + (real_type)+180. - _args.phi1() ; + + real_type _HARD = + std::cos(_PHI1 * _DtoR) ; + + auto _BASE = _mesh._tria.node(_base); + + _mark.set_count(_halo._list.count()); + _mark.fill( +0 ) ; + + for (auto _ipos = _halo._list.head() ; + _ipos != _halo._list.tend() ; + ++_ipos ) + for (auto _jpos = _halo._list.head() ; + _jpos != _halo._list.tend() ; + ++_jpos ) + { + /*--------------------- calc. angle from IPOS to JPOS */ + if (_ipos == _jpos) continue ; + + auto _inum = + _ipos - _halo._list.head(); + auto _jnum = + _jpos - _halo._list.head(); + + real_type _ivec[3], _jvec[3] ; + geometry::vector_3d ( + &_BASE->pval(0), + &_ipos->pval(0), _ivec); + + geometry::vector_3d ( + &_BASE->pval(0), + &_jpos->pval(0), _jvec); + + real_type _acos = + geometry::cosine_3d(_ivec, _jvec) ; + + if (_acos >= _HARD) + { + /*--------------------- MARK pair if feat. is "sharp" */ + _mark[_inum] = +1 ; + _mark[_jnum] = +1 ; + } + } + } + + /* + -------------------------------------------------------- + * INIT-BALL: set-up ball "collar". -------------------------------------------------------- */ @@ -336,9 +431,9 @@ __unreferenced(_hfun) ; __unreferenced(_mode) ; __unreferenced(_pass) ; - __unreferenced(_args) ; __unreferenced(_fpro) ; + iptr_list _mark ; for (auto _bpos = _mesh._bset._lptr.head () ; _bpos != @@ -351,9 +446,9 @@ _ball != nullptr; _ball = _ball->_next ) { - + /*--------------------- build "collar" for given ball */ typename - geom_type::ball_type _hdat ; + geom_type::ball_type _hdat ; _hdat._pmid[0] = _ball->_data._ball[0] ; _hdat._pmid[1] = @@ -364,28 +459,37 @@ _hdat._rrad = std::sqrt(_ball->_data._ball[3]) ; - iptr_type _nadj = + iptr_type _base = _ball->_data._node[0] ; mesh::keep_all_3d < - real_type , - iptr_type > _halo ; + real_type, iptr_type> _halo ; + + _geom.intersect( _hdat, _halo) ; - _geom. - intersect(_hdat, _halo) ; + mark_feat(_mesh, + _base,_halo, _mark, _args) ; + iptr_type _inum = +0 ; for (auto _iter = _halo._list.head() ; _iter != _halo._list.tend() ; - ++_iter ) + ++_iter, ++_inum) { + /*--------------------- push nodes + constraint faces */ + if (_mark[_inum] <= +0) continue; + iptr_type _hint = - _mesh._tria. - node(_nadj)->next() ; + _mesh._tria.node(_base)->next() ; + + real_type _PPOS[4] ; // weight = 0 + _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, - _hint ) ) + &_PPOS[ 0], _node, _hint) ) { _mesh._tria.node( _node)->idxh() = @@ -401,7 +505,7 @@ _node)->topo() = 2 ; edge_data _edat; - _edat._node[0] = _nadj ; + _edat._node[0] = _base ; _edat._node[1] = _node ; _epro.push(_edat) ; @@ -414,7 +518,7 @@ /* -------------------------------------------------------- - * INIT-DISC: setup disc "collar". + * INIT-DISC: set-up disc "collar". -------------------------------------------------------- */ @@ -442,8 +546,6 @@ __unreferenced(_args) ; __unreferenced(_epro) ; - return; - for (auto _epos = _mesh._eset._lptr.head () ; _epos != @@ -456,30 +558,27 @@ _edge != nullptr; _edge = _edge->_next ) { - if (_edge->_data. - _feat == hard_feat ) + if (_edge->_data._feat == hard_feat) { - real_type _ebal[ 4]; - geometry - ::circ_ball_3d (_ebal , - &_mesh._tria.node( - _edge->_data. - _node[0])->pval(0), - &_mesh._tria.node( - _edge->_data. - _node[1])->pval(0) - ) ; - - real_type _evec[ 3]; - geometry::vector_3d( - &_mesh._tria.node( - _edge->_data. - _node[0])->pval(0), - &_mesh._tria.node( - _edge->_data. - _node[1])->pval(0), - _evec ) ; + auto _inod = _edge->_data._node[0] ; + auto _jnod = _edge->_data._node[1] ; + + auto _iptr = + _mesh._tria.node(_inod) ; + auto _jptr = + _mesh._tria.node(_jnod) ; + + real_type _ebal[4]; + geometry::circ_ball_3d(_ebal , + &_iptr->pval(0), + &_jptr->pval(0)) ; + + real_type _evec[3]; + geometry::vector_3d ( + &_iptr->pval(0), + &_jptr->pval(0), _evec) ; + typename geom_type::disc_type _hdat ; @@ -492,18 +591,14 @@ _hdat._nvec[2] = _evec[2] ; _hdat._rrad = - _DTOL* std::sqrt(_ebal[3]) ; + _DTOL * std::sqrt(_ebal[3]) ; mesh::keep_all_3d < - real_type , - iptr_type > _halo ; - + real_type, iptr_type> _halo ; - //!! - real_type _junk[3] = {+0.} ; + real_type _junk[3] = { +0. } ; - _geom. - intersect(_hdat, _junk, _halo) ; + _geom.intersect(_hdat, _junk, _halo) ; for (auto _iter = @@ -513,27 +608,27 @@ ++_iter ) { iptr_type _hint = - _mesh._tria.node(_edge-> - _data._node[0])->next(); + _mesh._tria.node(_inod)->next() ; /* iptr_type _near = -1; - _mesh._tria.find_node( - &_iter->pval(0), _near, - _edge-> - _data._node[0]) ; - - if (_near != - _edge->_data._node[0] && - _near != - _edge->_data._node[1] ) + _mesh._tria.find_node( + &_iter->pval(0), _near, _inod); + + if (_near != _inod && + _near != _jnod ) continue ; */ + real_type _PPOS[4] ; // weight = 0 + _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, - _hint ) ) + &_PPOS[ 0], _node, _hint) ) { _mesh._tria.node( _node)->idxh() = diff --git a/src/libcpp/rdel_mesh/rdel_refine_base_2.inc b/src/libcpp/rdel_mesh/rdel_refine_base_2.inc index c57d24a..cc67484 100644 --- a/src/libcpp/rdel_mesh/rdel_refine_base_2.inc +++ b/src/libcpp/rdel_mesh/rdel_refine_base_2.inc @@ -31,11 +31,11 @@ * -------------------------------------------------------- * - * Last updated: 24 January, 2019 + * Last updated: 23 February, 2020 * - * Copyright 2013-2019 + * Copyright 2013-2020 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- @@ -121,9 +121,14 @@ { _eold.set_count( +0) ; + real_type _PPOS[3] ; + _PPOS[0] = _ppos[0] ; + _PPOS[1] = _ppos[1] ; + _PPOS[2] = (real_type)+0. ; // laguerre w = 0 + iptr_type _node = -1; if(!_mesh._tria.push_node ( - _ppos, _node, + _PPOS, _node, _hint, &_tnew, &_told)) { /*------------------------- bail if DT push fails */ @@ -166,17 +171,16 @@ } /*------------------------- keep "old" rDT cavity */ - find_rdel( _geom, _mesh , - _told, _eold ) ; + find_rdel( + _geom, _mesh, _told, _eold + ) ; /*------------------------- form "new" rDT cavity */ - push_rdel( _geom, _hfun , - _mesh, true, - _nnew, _tnew, + push_rdel( _geom, _hfun, + _mesh, true, _nnew, _tnew , _escr, _ecav, _tscr, _tcav, - _bscr, _bcav, - _sign, _pass, + _bscr, _bcav, _sign, _pass , null_mode, _mode, _args ) ; diff --git a/src/libcpp/rdel_mesh/rdel_refine_base_3.inc b/src/libcpp/rdel_mesh/rdel_refine_base_3.inc index ce7477f..bec2b17 100644 --- a/src/libcpp/rdel_mesh/rdel_refine_base_3.inc +++ b/src/libcpp/rdel_mesh/rdel_refine_base_3.inc @@ -31,11 +31,11 @@ * -------------------------------------------------------- * - * Last updated: 24 January, 2019 + * Last updated: 23 February, 2020 * - * Copyright 2013-2019 + * Copyright 2013-2020 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- @@ -129,9 +129,15 @@ _eold.set_count( +0) ; _fold.set_count( +0) ; + real_type _PPOS[4] ; + _PPOS[0] = _ppos[0] ; + _PPOS[1] = _ppos[1] ; + _PPOS[2] = _ppos[2] ; + _PPOS[3] = (real_type)+0. ; // laguerre w = 0 + iptr_type _node = -1; if(!_mesh._tria.push_node ( - _ppos, _node, + _PPOS, _node, _hint, &_tnew, &_told)) { /*------------------------- bail if DT push fails */ @@ -178,18 +184,17 @@ } /*------------------------- keep "old" rDT cavity */ - find_rdel( _geom, _mesh , - _told, _eold, _fold ) ; + find_rdel( _geom, + _mesh, _told, _eold, _fold + ) ; /*------------------------- form "new" rDT cavity */ - push_rdel( _geom, _hfun , - _mesh, true, - _nnew, _tnew, + push_rdel( _geom, _hfun, + _mesh, true, _nnew, _tnew , _escr, _ecav, _fscr, _fcav, _tscr, _tcav, - _bscr, _bcav, - _sign, _pass, + _bscr, _bcav, _sign, _pass , null_mode, _mode, _args ) ; diff --git a/src/libcpp/rdel_mesh/rdel_refine_face_2.inc b/src/libcpp/rdel_mesh/rdel_refine_face_2.inc index bf37895..b3a4297 100644 --- a/src/libcpp/rdel_mesh/rdel_refine_face_2.inc +++ b/src/libcpp/rdel_mesh/rdel_refine_face_2.inc @@ -35,7 +35,7 @@ * * Copyright 2013-2018 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- diff --git a/src/libcpp/rdel_mesh/rdel_refine_face_3.inc b/src/libcpp/rdel_mesh/rdel_refine_face_3.inc index ce226c3..07e1cb9 100644 --- a/src/libcpp/rdel_mesh/rdel_refine_face_3.inc +++ b/src/libcpp/rdel_mesh/rdel_refine_face_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/src/libcpp/rdel_mesh/rdel_refine_topo_2.inc b/src/libcpp/rdel_mesh/rdel_refine_topo_2.inc index 810bd83..627fd75 100644 --- a/src/libcpp/rdel_mesh/rdel_refine_topo_2.inc +++ b/src/libcpp/rdel_mesh/rdel_refine_topo_2.inc @@ -31,11 +31,11 @@ * -------------------------------------------------------- * - * Last updated: 03 July, 2019 + * Last updated: 25 May, 2020 * - * Copyright 2013-2019 + * Copyright 2013-2020 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- @@ -178,10 +178,16 @@ tria(_edge->_tadj) ->node( _enod[ 1]) ; + auto _iptr = + _mesh._tria.node(_enod[0]) ; + auto _jptr = + _mesh._tria.node(_enod[1]) ; + char_type _feat, _topo ; iptr_type _part; real_type _fbal[ +3] ; real_type _sbal[ +3] ; + real_type _enrm[ +2] ; if (!mesh_pred::edge_ball ( _geom, _mesh , _edge->_tadj , @@ -191,18 +197,13 @@ __assert( false && "TOPO-NODE: edge-ball" ) ; - real_type _enrm[ +3] ; + /*--------------------- try to est. local normals */ geometry::line_norm_2d ( - &_mesh._tria. - node(_enod[0])->pval(0) , - &_mesh._tria. - node(_enod[1])->pval(0) , - _enrm) ; + &_iptr->pval(0), + &_jptr->pval(0), _enrm + ) ; - _enrm[2] = - geometry::length_2d(_enrm) ; - _enrm[0]/= _enrm[2] ; - _enrm[1]/= _enrm[2] ; + geometry::normalise_2d (_enrm) ; real_type _sign = geometry::dot_2d(_enrm, _vnrm) ; @@ -220,6 +221,7 @@ if (_pmax[2] < _sbal[2]) { + /*--------------------- keep max. SDB in edge-set */ _pmax[2] = _sbal[2]; _kind = @@ -239,95 +241,100 @@ ::offT_kind) ) { /*--------------------- calc. "skinny" off-centre */ - _vnrm[2] = - geometry::length_2d(_vnrm) ; - _vnrm[0]/= _vnrm[2] ; - _vnrm[1]/= _vnrm[2] ; + _vnrm[2] = + geometry::normalise_2d (_vnrm) ; - real_type _rrad = - std::sqrt(_pmax[ 2]); + real_type _rrad = + std::sqrt(_pmax[ 2]) ; - if (_vnrm[2] >= _rEPS * _rrad) - { + if (_vnrm[2] >= _rEPS * _rrad) + { /*--------------------- project on local "normal" */ - _vnrm[0]*= _rrad * - (real_type) +2. ; - _vnrm[1]*= _rrad * - (real_type) +2. ; + real_type _pvec[2] ; + geometry:: + vector_2d(_ppos, _pmax, _pvec) ; - typename - geom_type::line_type _ldat ; - _ldat._ipos[0] = _ppos[0] - - _vnrm[0]; - _ldat._ipos[1] = _ppos[1] - - _vnrm[1]; - - _ldat._jpos[0] = _ppos[0] - + _vnrm[0]; - _ldat._jpos[1] = _ppos[1] - + _vnrm[1]; - - mesh::keep_all_2d < - real_type , - iptr_type > _halo ; + real_type _sign = + geometry::dot_2d(_pvec, _vnrm) ; - _geom.intersect( _ldat , - _halo ) ; + if (_sign > (real_type)+0.) + { + _vnrm[0]*= + (real_type)+2. * _rrad ; + _vnrm[1]*= + (real_type)+2. * _rrad ; + } + else + { + _vnrm[0]*= + (real_type)-2. * _rrad ; + _vnrm[1]*= + (real_type)-2. * _rrad ; + } - auto _ioff = _halo._list.tend(); + /*--------------------- calc. local intersections */ + typename + geom_type::line_type _ldat ; + _ldat._ipos[0] = _ppos[0]; + _ldat._ipos[1] = _ppos[1]; - real_type _dmin = - _rEPS * std::pow(_rrad, +2); + _ldat._jpos[0] = _ppos[0]; + _ldat._jpos[1] = _ppos[1]; + _ldat._jpos[0]+= _vnrm[0]; + _ldat._jpos[1]+= _vnrm[1]; - real_type static constexpr - _NEAR = (real_type) +.75 ; + mesh::keep_all_2d < + real_type , + iptr_type > _halo ; - real_type _best = - +std::numeric_limits - ::infinity(); + _geom.intersect( _ldat , + _halo ) ; - for (auto _iter = - _halo._list.head() ; - _iter != - _halo._list.tend() ; - ++_iter ) - { - iptr_type _near = -1; - _mesh._tria.find_node ( - &_iter->pval(0), _near , _npos) ; - - auto _nptr = &_mesh. - _tria.node(_near)->pval(0) ; + if (_halo._list.count() <= +2) + { + /*--------------------- keep "best" intersections */ + auto _ioff = _halo._list.tend(); - real_type _nsqr = - geometry::lensqr_2d ( - &_iter->pval(0), _nptr) ; + real_type _dmin = + _rEPS * std::pow(_rrad, +2); - real_type _dsqr = - geometry::lensqr_2d ( - &_iter->pval(0), _ppos) ; + real_type _best = + +std::numeric_limits + ::infinity(); - if (_nsqr > _dsqr * - _NEAR ) - if (_dsqr < _best && - _dsqr > _dmin ) + for (auto + _iter = _halo._list.head(); + _iter != _halo._list.tend(); + ++_iter ) { - _kind = - rdel_opts::offT_kind ; - - _best = _dsqr ; - - _ioff = _iter ; + iptr_type _near = -1; + _mesh._tria.find_node ( + &_iter->pval(0), _near , _npos) ; + + real_type _dsqr = + geometry::lensqr_2d ( + &_iter->pval(0), _ppos) ; + + if (_near == _npos && + _dsqr >= _dmin && + _dsqr <= _best) + { + _kind = + rdel_opts::offT_kind ; + + _best = _dsqr ; + _ioff = _iter ; + } } - } - if (_ioff != _halo._list.tend()) - { - _pmax[0] = _ioff->pval (0) ; - _pmax[1] = _ioff->pval (1) ; - } + if (_ioff != _halo._list.tend()) + { + _pmax[0] = _ioff->pval (0) ; + _pmax[1] = _ioff->pval (1) ; + } + } - } + } } return _kind ; @@ -425,10 +432,8 @@ _bscr.set_count( + 0) ; _bcav.set_count( + 0) ; - containers:: - array _tset ; - containers:: - array _eset ; + containers::array _tset; + containers::array _eset; _tset.set_alloc( +32) ; _eset.set_alloc( +32) ; @@ -449,11 +454,10 @@ _eset.set_count( +0) ; _mesh._tria.walk_node( - _npos , - node_pred(_npos),_tset) ; + _npos, node_pred(_npos), _tset) ; - if (!etop_disk(_mesh, - _npos, _tset, _eset) ) + if (!etop_disk( + _mesh, _npos, _tset, _eset) ) { _find = true; break ; } diff --git a/src/libcpp/rdel_mesh/rdel_refine_topo_3.inc b/src/libcpp/rdel_mesh/rdel_refine_topo_3.inc index 4e91fbf..08c531c 100644 --- a/src/libcpp/rdel_mesh/rdel_refine_topo_3.inc +++ b/src/libcpp/rdel_mesh/rdel_refine_topo_3.inc @@ -31,11 +31,11 @@ * -------------------------------------------------------- * - * Last updated: 03 July, 2019 + * Last updated: 25 May, 2020 * - * Copyright 2013-2019 + * Copyright 2013-2020 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- @@ -231,7 +231,7 @@ } } - return ( _eset.count() <= _topo ) ; //!! what about missing edges? + return ( _eset.count() <= _topo ) ; } /* @@ -472,34 +472,32 @@ tria(_edge->_tadj) ->node( _enod[ 1]) ; - char_type _hits; + auto _iptr = + _mesh._tria.node(_enod[0]) ; + auto _jptr = + _mesh._tria.node(_enod[1]) ; + char_type _feat, _topo ; iptr_type _part; real_type _fbal[ +4] ; real_type _sbal[ +4] ; + real_type _edir[ +3] ; if (!mesh_pred::edge_ball ( _geom, _mesh , _edge->_tadj , _edge->_eadj , _fbal, _sbal , - _hits, _feat , - _topo, _part ) ) + _feat, _topo , _part) ) __assert( false && "TOPO-NODE: edge-ball" ) ; - real_type _edir[ +4] ; + /*--------------------- try to est. local normals */ geometry::vector_3d ( - &_mesh._tria. - node(_enod[0])->pval(0) , - &_mesh._tria. - node(_enod[1])->pval(0) , - _edir) ; - - _edir[3] = - geometry::length_3d(_edir) ; - _edir[0]/= _edir[3] ; - _edir[1]/= _edir[3] ; - _edir[2]/= _edir[3] ; + &_iptr->pval(0), + &_jptr->pval(0), _edir + ) ; + + geometry::normalise_3d (_edir) ; real_type _sign = geometry::dot_3d(_edir, _vdir) ; @@ -519,6 +517,7 @@ if (_pmax[3] < _sbal[3]) { + /*--------------------- keep max. SDB in edge-set */ _pmax[3] = _sbal[3]; _kind = @@ -539,103 +538,93 @@ ::offT_kind) ) { /*--------------------- calc. "skinny" off-centre */ - _vdir[3] = - geometry::length_3d(_vdir) ; - _vdir[0]/= _vdir[3] ; - _vdir[1]/= _vdir[3] ; - _vdir[2]/= _vdir[3] ; + _vdir[3] = + geometry::normalise_3d (_vdir) ; - real_type _rrad = - std::sqrt(_pmax[ 3]); + real_type _rrad = + std::sqrt(_pmax[ 3]); - if (_vdir[3] >= _rEPS * _rrad) - { + if (_vdir[3] >= _rEPS * _rrad) + { /*--------------------- project on local "normal" */ - typename - geom_type::flat_type _fdat ; - _fdat._ppos[0] = _ppos[0]; - _fdat._ppos[1] = _ppos[1]; - _fdat._ppos[2] = _ppos[2]; - _fdat._nvec[0] = _vdir[0]; - _fdat._nvec[1] = _vdir[1]; - _fdat._nvec[2] = _vdir[2]; - - _fdat._rmin[0] = _ppos[0] - - (real_type)+2.*_rrad ; - _fdat._rmin[1] = _ppos[1] - - (real_type)+2.*_rrad ; - _fdat._rmin[2] = _ppos[2] - - (real_type)+2.*_rrad ; - - _fdat._rmax[0] = _ppos[0] - + (real_type)+2.*_rrad ; - _fdat._rmax[1] = _ppos[1] - + (real_type)+2.*_rrad ; - _fdat._rmax[2] = _ppos[2] - + (real_type)+2.*_rrad ; - - mesh::keep_all_3d < - real_type , - iptr_type > _halo ; - - _geom.intersect( _fdat , - _halo ) ; - - auto _ioff = _halo._list.tend(); - - real_type _dmin = - _rEPS * std::pow(_rrad, +2); - - real_type static constexpr - _NEAR = (real_type) +.75 ; - - real_type _best = - +std::numeric_limits - ::infinity(); - - for (auto _iter = - _halo._list.head() ; - _iter != - _halo._list.tend() ; - ++_iter ) - { - iptr_type _near = -1; - _mesh._tria.find_node ( - &_iter->pval(0), _near , _npos) ; + typename + geom_type::flat_type _fdat ; + _fdat._ppos[0] = _ppos[0]; + _fdat._ppos[1] = _ppos[1]; + _fdat._ppos[2] = _ppos[2]; + + _fdat._nvec[0] = _vdir[0]; + _fdat._nvec[1] = _vdir[1]; + _fdat._nvec[2] = _vdir[2]; + + real_type _RMIN[3] = { + _ppos[0]-(real_type) +2.*_rrad , + _ppos[1]-(real_type) +2.*_rrad , + _ppos[2]-(real_type) +2.*_rrad , + } ; + _fdat._bnds.push_tail(_RMIN) ; - auto _nptr = &_mesh. - _tria.node(_near)->pval(0) ; + real_type _RMAX[3] = { + _ppos[0]+(real_type) +2.*_rrad , + _ppos[1]+(real_type) +2.*_rrad , + _ppos[2]+(real_type) +2.*_rrad , + } ; + _fdat._bnds.push_tail(_RMAX) ; - real_type _nsqr = - geometry::lensqr_3d ( - &_iter->pval(0), _nptr) ; + /*--------------------- calc. local intersections */ + mesh::keep_all_3d < + real_type , + iptr_type > _halo ; - real_type _dsqr = - geometry::lensqr_3d ( - &_iter->pval(0), _ppos) ; + _geom.intersect( _fdat , + _halo ) ; - if (_nsqr > _dsqr * - _NEAR ) - if (_dsqr < _best && - _dsqr > _dmin ) + if (_halo._list.count() <= +2) { - _kind = - rdel_opts::offT_kind ; + /*--------------------- keep "best" intersections */ + auto _ioff = _halo._list.tend(); - _best = _dsqr ; + real_type _dmin = + _rEPS * std::pow(_rrad, +2); - _ioff = _iter ; + real_type _best = + +std::numeric_limits + ::infinity(); + + for (auto + _iter = _halo._list.head(); + _iter != _halo._list.tend(); + ++_iter ) + { + iptr_type _near = -1; + _mesh._tria.find_node ( + &_iter->pval(0), _near , _npos) ; + + real_type _dsqr = + geometry::lensqr_3d ( + &_iter->pval(0), _ppos) ; + + if (_near == _npos && + _dsqr >= _dmin && + _dsqr <= _best) + { + _kind = + rdel_opts::offT_kind ; + + _best = _dsqr ; + _ioff = _iter ; + } } - } - if (_ioff != _halo._list.tend()) - { - _pmax[0] = _ioff->pval (0) ; - _pmax[1] = _ioff->pval (1) ; - _pmax[2] = _ioff->pval (2) ; - } + if (_ioff != _halo._list.tend()) + { + _pmax[0] = _ioff->pval (0) ; + _pmax[1] = _ioff->pval (1) ; + _pmax[2] = _ioff->pval (2) ; + } + } - } + } } return _kind ; @@ -689,10 +678,18 @@ tria(_face->_tadj) ->node( _fnod[ 2]) ; + auto _iptr = + _mesh._tria.node(_fnod[0]) ; + auto _jptr = + _mesh._tria.node(_fnod[1]) ; + auto _kptr = + _mesh._tria.node(_fnod[2]) ; + char_type _feat, _topo ; iptr_type _part; real_type _fbal[ +4] ; real_type _sbal[ +4] ; + real_type _fnrm[ +3] ; if (!mesh_pred::face_ball ( _geom, _mesh , _face->_tadj , @@ -702,21 +699,13 @@ __assert( false && "TOPO-NODE: face-ball" ) ; - real_type _fnrm[ +4] ; + /*--------------------- try to est. local normals */ geometry::tria_norm_3d ( - &_mesh._tria. - node(_fnod[0])->pval(0) , - &_mesh._tria. - node(_fnod[1])->pval(0) , - &_mesh._tria. - node(_fnod[2])->pval(0) , - _fnrm) ; - - _fnrm[3] = - geometry::length_3d(_fnrm) ; - _fnrm[0]/= _fnrm[3] ; - _fnrm[1]/= _fnrm[3] ; - _fnrm[2]/= _fnrm[3] ; + &_iptr->pval(0), + &_jptr->pval(0), + &_kptr->pval(0), _fnrm) ; + + geometry::normalise_3d (_fnrm) ; real_type _sign = geometry::dot_3d(_fnrm, _vnrm) ; @@ -736,6 +725,7 @@ if (_pmax[3] < _sbal[3]) { + /*--------------------- keep max. SDB in edge-set */ _pmax[3] = _sbal[3]; _kind = @@ -756,103 +746,108 @@ ::offT_kind) ) { /*--------------------- calc. "skinny" off-centre */ - _vnrm[3] = - geometry::length_3d(_vnrm) ; - _vnrm[0]/= _vnrm[3] ; - _vnrm[1]/= _vnrm[3] ; - _vnrm[2]/= _vnrm[3] ; + _vnrm[3] = + geometry::normalise_3d (_vnrm) ; - real_type _rrad = - std::sqrt(_pmax[ 3]); + real_type _rrad = + std::sqrt(_pmax[ 3]); - if (_vnrm[3] >= _rEPS * _rrad) - { + if (_vnrm[3] >= _rEPS * _rrad) + { /*--------------------- project on local "normal" */ - _vnrm[0]*= _rrad * - (real_type) +2. ; - _vnrm[1]*= _rrad * - (real_type) +2. ; - _vnrm[2]*= _rrad * - (real_type) +2. ; + real_type _pvec[3] ; + geometry:: + vector_3d(_ppos, _pmax, _pvec) ; - typename - geom_type::line_type _ldat ; - _ldat._ipos[0] = _ppos[0] - - _vnrm[0]; - _ldat._ipos[1] = _ppos[1] - - _vnrm[1]; - _ldat._ipos[2] = _ppos[2] - - _vnrm[2]; - - _ldat._jpos[0] = _ppos[0] - + _vnrm[0]; - _ldat._jpos[1] = _ppos[1] - + _vnrm[1]; - _ldat._jpos[2] = _ppos[2] - + _vnrm[2]; - - mesh::keep_all_3d < - real_type , - iptr_type > _halo ; - - _geom.intersect( _ldat , - _halo ) ; - - auto _ioff = _halo._list.tend(); - - real_type _dmin = - _rEPS * std::pow(_rrad, +2); - - real_type static constexpr - _NEAR = (real_type) +.75 ; - - real_type _best = - +std::numeric_limits - ::infinity(); - - for (auto _iter = - _halo._list.head() ; - _iter != - _halo._list.tend() ; - ++_iter ) - { - iptr_type _near = -1; - _mesh._tria.find_node ( - &_iter->pval(0), _near , _npos) ; + real_type _sign = + geometry::dot_3d(_pvec, _vnrm) ; + + if (_sign > (real_type)+0.) + { + _vnrm[0]*= + (real_type)+2. * _rrad ; + _vnrm[1]*= + (real_type)+2. * _rrad ; + _vnrm[2]*= + (real_type)+2. * _rrad ; + } + else + { + _vnrm[0]*= + (real_type)-2. * _rrad ; + _vnrm[1]*= + (real_type)-2. * _rrad ; + _vnrm[2]*= + (real_type)-2. * _rrad ; + } + + /*--------------------- calc. local intersections */ + typename + geom_type::line_type _ldat ; + _ldat._ipos[0] = _ppos[0]; + _ldat._ipos[1] = _ppos[1]; + _ldat._ipos[2] = _ppos[2]; + + _ldat._jpos[0] = _ppos[0]; + _ldat._jpos[1] = _ppos[1]; + _ldat._jpos[2] = _ppos[2]; + _ldat._jpos[0]+= _vnrm[0]; + _ldat._jpos[1]+= _vnrm[1]; + _ldat._jpos[2]+= _vnrm[2]; + + mesh::keep_all_3d < + real_type , + iptr_type > _halo ; - auto _nptr = &_mesh. - _tria.node(_near)->pval(0) ; + _geom.intersect( _ldat , + _halo ) ; - real_type _nsqr = - geometry::lensqr_3d ( - &_iter->pval(0), _nptr) ; + if (_halo._list.count() <= +2) + { + /*--------------------- keep "best" intersections */ + auto _ioff = _halo._list.tend(); + + real_type _dmin = + _rEPS * std::pow(_rrad, +2); - real_type _dsqr = - geometry::lensqr_3d ( - &_iter->pval(0), _ppos) ; + real_type _best = + +std::numeric_limits + ::infinity(); - if (_nsqr > _dsqr * - _NEAR ) - if (_dsqr < _best && - _dsqr > _dmin ) + for (auto + _iter = _halo._list.head(); + _iter != _halo._list.tend(); + ++_iter ) { - _kind = - rdel_opts::offT_kind ; + iptr_type _near = -1; + _mesh._tria.find_node ( + &_iter->pval(0), _near , _npos) ; - _best = _dsqr ; + real_type _dsqr = + geometry::lensqr_3d ( + &_iter->pval(0), _ppos) ; + + if (_near == _npos && + _dsqr >= _dmin && + _dsqr <= _best) + { + _kind = + rdel_opts::offT_kind ; - _ioff = _iter ; + _best = _dsqr ; + _ioff = _iter ; + } } - } - if (_ioff != _halo._list.tend()) - { - _pmax[0] = _ioff->pval (0) ; - _pmax[1] = _ioff->pval (1) ; - _pmax[2] = _ioff->pval (2) ; - } + if (_ioff != _halo._list.tend()) + { + _pmax[0] = _ioff->pval (0) ; + _pmax[1] = _ioff->pval (1) ; + _pmax[2] = _ioff->pval (2) ; + } + } - } + } } return _kind ; @@ -961,12 +956,9 @@ _bscr.set_count( + 0) ; _bcav.set_count( + 0) ; - containers:: - array _tset ; - containers:: - array _eset ; - containers:: - array _fset ; + containers::array _tset; + containers::array _eset; + containers::array _fset; _tset.set_alloc( +32) ; _eset.set_alloc( +32) ; @@ -987,11 +979,10 @@ _eset.set_count( +0) ; _mesh._tria.walk_node( - _npos , - node_pred(_npos),_tset) ; + _npos, node_pred(_npos), _tset) ; - if (!etop_disk(_mesh, - _npos, _tset, _eset) ) + if (!etop_disk( + _mesh, _npos, _tset, _eset) ) { _find = true; break ; } @@ -1129,12 +1120,9 @@ _bscr.set_count( + 0) ; _bcav.set_count( + 0) ; - containers:: //!! do we need these?? - array _tset ; - containers:: - array _eset ; - containers:: - array _fset ; + containers::array _tset; + containers::array _eset; + containers::array _fset; _tset.set_alloc( +32) ; _eset.set_alloc( +32) ; @@ -1157,12 +1145,10 @@ _fset.set_count( +0) ; _mesh._tria.walk_node( - _npos , - node_pred(_npos), _tset) ; + _npos, node_pred(_npos), _tset) ; if (!ftop_disk(_mesh, - _npos, - _tset, _eset, _fset) ) + _npos, _tset, _eset, _fset) ) { _find = true; break ; } diff --git a/src/libcpp/rdel_mesh/rdel_sink_delfront_2.inc b/src/libcpp/rdel_mesh/rdel_sink_delfront_2.inc index c014efb..7ae736f 100644 --- a/src/libcpp/rdel_mesh/rdel_sink_delfront_2.inc +++ b/src/libcpp/rdel_mesh/rdel_sink_delfront_2.inc @@ -35,7 +35,7 @@ * * Copyright 2013-2019 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- diff --git a/src/libcpp/rdel_mesh/rdel_sink_delfront_3.inc b/src/libcpp/rdel_mesh/rdel_sink_delfront_3.inc index da559db..361fe12 100644 --- a/src/libcpp/rdel_mesh/rdel_sink_delfront_3.inc +++ b/src/libcpp/rdel_mesh/rdel_sink_delfront_3.inc @@ -35,7 +35,7 @@ * * Copyright 2013-2019 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- diff --git a/src/libcpp/rdel_mesh/rdel_test_bounds_2.inc b/src/libcpp/rdel_mesh/rdel_test_bounds_2.inc index 0439050..29a8223 100644 --- a/src/libcpp/rdel_mesh/rdel_test_bounds_2.inc +++ b/src/libcpp/rdel_mesh/rdel_test_bounds_2.inc @@ -35,7 +35,7 @@ * * Copyright 2013-2019 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- diff --git a/src/libcpp/rdel_mesh/rdel_test_bounds_3.inc b/src/libcpp/rdel_mesh/rdel_test_bounds_3.inc index 75a516c..daa0110 100644 --- a/src/libcpp/rdel_mesh/rdel_test_bounds_3.inc +++ b/src/libcpp/rdel_mesh/rdel_test_bounds_3.inc @@ -35,7 +35,7 @@ * * Copyright 2013-2019 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- @@ -179,18 +179,16 @@ ++_epos ) { /*----------------- compute restricted surf. ball */ - char_type _hits; char_type _feat, _topo ; iptr_type _part; real_type _fbal[ +4] ; real_type _sbal[ +4] ; - if (!mesh_pred::edge_ball ( + if (!mesh_pred::edge_ball ( _geom, _mesh , _epos->_tadj , _epos->_eadj , _fbal, _sbal , - _hits, _feat , - _topo, _part ) ) + _feat, _topo , _part ) ) __assert( false && "_NEW-BNDS: edge-ball" ); @@ -254,7 +252,7 @@ iptr_type _part; real_type _fbal[ +4] ; real_type _sbal[ +4] ; - if (!mesh_pred::face_ball ( + if (!mesh_pred::face_ball ( _geom, _mesh , _fpos->_tadj , _fpos->_fadj , @@ -369,18 +367,16 @@ ++_epos ) { /*----------------- compute restricted surf. ball */ - char_type _hits; char_type _feat, _topo ; iptr_type _part; real_type _fbal[ +4] ; real_type _sbal[ +4] ; - if (!mesh_pred::edge_ball ( + if (!mesh_pred::edge_ball ( _geom, _mesh , _epos->_tadj , _epos->_eadj , _fbal, _sbal , - _hits, _feat , - _topo, _part ) ) + _feat, _topo , _part ) ) __assert( false && "_old_bnds: edge-ball" ); diff --git a/src/libcpp/rdel_mesh/rdel_timers.hpp b/src/libcpp/rdel_mesh/rdel_timers.hpp index 2c5c7b1..c7ca32a 100644 --- a/src/libcpp/rdel_mesh/rdel_timers.hpp +++ b/src/libcpp/rdel_mesh/rdel_timers.hpp @@ -35,7 +35,7 @@ * * Copyright 2013-2019 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- diff --git a/src/libcpp/rdel_mesh/rdel_update_face_2.inc b/src/libcpp/rdel_mesh/rdel_update_face_2.inc index 4b0a9c8..7e31b96 100644 --- a/src/libcpp/rdel_mesh/rdel_update_face_2.inc +++ b/src/libcpp/rdel_mesh/rdel_update_face_2.inc @@ -35,7 +35,7 @@ * * Copyright 2013-2019 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- diff --git a/src/libcpp/rdel_mesh/rdel_update_face_3.inc b/src/libcpp/rdel_mesh/rdel_update_face_3.inc index 1f9dda7..dfe7fe1 100644 --- a/src/libcpp/rdel_mesh/rdel_update_face_3.inc +++ b/src/libcpp/rdel_mesh/rdel_update_face_3.inc @@ -35,7 +35,7 @@ * * Copyright 2013-2019 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- @@ -287,7 +287,6 @@ (char_type) _fpos; /*--------------------------- call edge predicate */ - char_type _hits; real_type _fbal[ 4]; real_type _sbal[ 4]; mesh_pred::edge_cost ( @@ -297,7 +296,6 @@ _edat._eadj, _opts,_cdat, _edat._part, - _hits, _edat._feat, _edat._topo, _edat._kind, @@ -582,7 +580,7 @@ /*---------------------- calc. ball in floating-point */ real_type _tbal[4] ; - geometry::circ_ball_3d ( + geometry::perp_ball_3d ( _tbal , &_mesh._tria. node(_tnod[0])->pval(0) , diff --git a/src/libcpp/rdel_mesh/rdel_update_topo_2.inc b/src/libcpp/rdel_mesh/rdel_update_topo_2.inc index 9df2451..3249d4f 100644 --- a/src/libcpp/rdel_mesh/rdel_update_topo_2.inc +++ b/src/libcpp/rdel_mesh/rdel_update_topo_2.inc @@ -35,7 +35,7 @@ * * Copyright 2013-2019 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- diff --git a/src/libcpp/rdel_mesh/rdel_update_topo_3.inc b/src/libcpp/rdel_mesh/rdel_update_topo_3.inc index c4c51e8..a2dc264 100644 --- a/src/libcpp/rdel_mesh/rdel_update_topo_3.inc +++ b/src/libcpp/rdel_mesh/rdel_update_topo_3.inc @@ -35,7 +35,7 @@ * * Copyright 2013-2019 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- diff --git a/src/libcpp/rdel_mesh/rvor_mesh_2.hpp b/src/libcpp/rdel_mesh/rvor_mesh_2.hpp index 048e5b3..2f2cef7 100644 --- a/src/libcpp/rdel_mesh/rvor_mesh_2.hpp +++ b/src/libcpp/rdel_mesh/rvor_mesh_2.hpp @@ -35,7 +35,7 @@ * * Copyright 2013-2018 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- diff --git a/src/libcpp/rdel_mesh/rvor_mesh_3.hpp b/src/libcpp/rdel_mesh/rvor_mesh_3.hpp index 75e6ff1..df93aac 100644 --- a/src/libcpp/rdel_mesh/rvor_mesh_3.hpp +++ b/src/libcpp/rdel_mesh/rvor_mesh_3.hpp @@ -35,7 +35,7 @@ * * Copyright 2013-2018 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- diff --git a/src/libcpp/rdel_mesh/rvor_update_face_2.inc b/src/libcpp/rdel_mesh/rvor_update_face_2.inc index f6f9292..534038b 100644 --- a/src/libcpp/rdel_mesh/rvor_update_face_2.inc +++ b/src/libcpp/rdel_mesh/rvor_update_face_2.inc @@ -35,7 +35,7 @@ * * Copyright 2013-2018 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- diff --git a/src/libcpp/rdelmesh.hpp b/src/libcpp/rdelmesh.hpp index 9379fe2..1437ee6 100644 --- a/src/libcpp/rdelmesh.hpp +++ b/src/libcpp/rdelmesh.hpp @@ -35,7 +35,7 @@ * * Copyright 2013-2019 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * ------------------------------------------------------------ @@ -48,7 +48,7 @@ namespace mesh { -/*-------------------------- classification of mesh items */ +/*-------------------------- classification of mesh cells */ char_type constexpr null_item = 0 ; char_type constexpr void_item = 1 ; char_type constexpr ring_item = 2 ; diff --git a/src/libcpp/tessellate.hpp b/src/libcpp/tessellate.hpp index 8553ba8..b8dc28a 100644 --- a/src/libcpp/tessellate.hpp +++ b/src/libcpp/tessellate.hpp @@ -31,11 +31,11 @@ * ------------------------------------------------------------ * - * Last updated: 12 August, 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/ * ------------------------------------------------------------ @@ -54,11 +54,17 @@ # include "tessellate/delaunay_tri_type_2.hpp" # include "tessellate/delaunay_tri_type_3.hpp" +# include "tessellate/delaunay_tri_type_4.hpp" # include "tessellate/delaunay_tri_k.hpp" -# include "tessellate/del_tri_euclidean_2.hpp" -# include "tessellate/del_tri_euclidean_3.hpp" +# include "tessellate/delaunay_tri_pred_2.hpp" +# include "tessellate/delaunay_tri_pred_3.hpp" +# include "tessellate/delaunay_tri_pred_4.hpp" + +# include "tessellate/laguerre_tri_pred_2.hpp" +# include "tessellate/laguerre_tri_pred_3.hpp" +# include "tessellate/laguerre_tri_pred_4.hpp" # endif//__TESSELLATE__ diff --git a/src/libcpp/tessellate/delaunay_scan_tria.inc b/src/libcpp/tessellate/delaunay_scan_tria.inc index ac0d628..23e0b0b 100644 --- a/src/libcpp/tessellate/delaunay_scan_tria.inc +++ b/src/libcpp/tessellate/delaunay_scan_tria.inc @@ -35,7 +35,7 @@ * * Copyright 2013-2018 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- @@ -70,7 +70,7 @@ _iter != _list.count(); ++_iter) { /*--------- scan all faces within current element */ - for(iptr_type _fpos = tria_pred::_dims + 1; + for(iptr_type _fpos = tria_pred::topo_dims + 1; _fpos-- != +0 ; ) { /*--------- find neighbour about current edge */ diff --git a/src/libcpp/tessellate/delaunay_star_void.inc b/src/libcpp/tessellate/delaunay_star_void.inc index f57143f..94765e7 100644 --- a/src/libcpp/tessellate/delaunay_star_void.inc +++ b/src/libcpp/tessellate/delaunay_star_void.inc @@ -35,7 +35,7 @@ * * Copyright 2013-2019 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- @@ -71,10 +71,10 @@ /*---------------------- scan list of trias in cavity */ iptr_type static constexpr - FACE_SIZE = tria_pred::_dims+1; + FACE_SIZE = tria_pred::topo_dims + 1 ; this->_fset.set_slots ( - _vset.count()* tria_dims ) ; + _vset.count()* topo_dims ) ; __assert ( this->_fset.count() == +0 && @@ -87,48 +87,48 @@ if (__mark(*_iter)<_flag) continue ; /*-------------------------- scan for cavity face */ - for(iptr_type _fpos = tria_dims +1 ; + for(iptr_type _fpos = topo_dims +1 ; _fpos-- != +0 ; ) { iptr_type _tadj, _fadj, _fmrk ; find_pair(*_iter, _tadj, _fpos, _fadj, _fmrk) ; - /*--------------- continue if cavity face */ + /*------------------- continue if cavity face */ if (_tadj == this->null_flag() || __mark(_tadj) < _flag ) { iptr_type _tria = _get_tria () ; - /*--------------- push new tria onto list */ + /*------------------- push new tria onto list */ if (_tnew != nullptr) { _tnew->push_tail(_tria) ; } - /*------------------------- face indexing */ + /*----------------------------- face indexing */ iptr_type _tnod[FACE_SIZE]; tria_type::face_node( _tnod,_fpos , - tria_dims-0, tria_dims-1) ; + topo_dims-0, topo_dims-1) ; iptr_type _inod; - for(_inod = tria_dims + 0 ; + for(_inod = topo_dims + 0 ; _inod-- != +0 ; ) { _tnod[ _inod] = tria( *_iter)-> node(_tnod[ _inod]); } - _tnod[ tria_dims] = _npos ; + _tnod[ topo_dims] = _npos ; - /*------------------------- node indexing */ - for(_inod = tria_dims + 1 ; + /*----------------------------- node indexing */ + for(_inod = topo_dims + 1 ; _inod-- != +0 ; ) { node( _tnod[_inod])->next()=_tria ; } - for(_inod = tria_dims + 1 ; + for(_inod = topo_dims + 1 ; _inod-- != +0 ; ) { tria(_tria)-> @@ -140,16 +140,16 @@ _fadj, _fmrk) ; /*---------------- face indexing for new tria */ - for(iptr_type _posf = tria_dims + 1; + for(iptr_type _posf = topo_dims + 1; _posf-- != +1 ; ) { iptr_type _fnod[FACE_SIZE]; tria_type::face_node( _fnod,_posf , - tria_dims-0, tria_dims-1) ; + topo_dims-0, topo_dims-1) ; face_ptrs _fdat, _same ; - for(_inod = tria_dims + 0 ; + for(_inod = topo_dims + 0 ; _inod-- != +0 ; ) { _fdat._node[_inod] = @@ -191,12 +191,12 @@ if (_told != nullptr) { - /*------------------ push "old" tria list */ + /*---------------------- push "old" tria list */ _told->push_tail(*_iter) ; } else { - /*------------------ recycle cavity trias */ + /*---------------------- recycle cavity trias */ _put_tria(*_iter) ; } } diff --git a/src/libcpp/tessellate/delaunay_tri_k.hpp b/src/libcpp/tessellate/delaunay_tri_k.hpp index 0bc0a9a..0075cb4 100644 --- a/src/libcpp/tessellate/delaunay_tri_k.hpp +++ b/src/libcpp/tessellate/delaunay_tri_k.hpp @@ -31,11 +31,11 @@ * -------------------------------------------------------- * - * Last updated: 03 July, 2019 + * Last updated: 01 March, 2020 * - * Copyright 2013-2019 + * Copyright 2013-2020 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- @@ -110,11 +110,26 @@ typedef char_type fptr_type ; -/*------------------------- alternative to "static const" */ - iptr_type static constexpr null_mark = +0 ; - iptr_type static constexpr tria_dims = - tria_pred::_dims; + + iptr_type static constexpr geom_dims = + tria_pred::geom_dims; + iptr_type static constexpr real_dims = + tria_pred::real_dims; + iptr_type static constexpr topo_dims = + tria_pred::topo_dims; + + static_assert( node_type::geom_dims >= + tria_pred::geom_dims , + "DELAUNAY-TRI-K: Incompatible node vs pred dims!" ) ; + + static_assert( node_type::real_dims >= + tria_pred::real_dims , + "DELAUNAY-TRI-K: Incompatible node vs pred dims!" ) ; + + static_assert( tria_type::topo_dims >= + tria_pred::topo_dims , + "DELAUNAY-TRI-K: Incompatible tria vs pred dims!" ) ; __static_call __inline_call iptr_type null_flag ( @@ -250,13 +265,13 @@ iptr_type _ipos = -1; if (this->_npop.count() != +0 ) { - /*------------------------ recycle from free list */ + /*---------------------------- recycle from free list */ this-> _npop._pop_tail(_ipos) ; } else { - /*------------------------ alloc. from underlying */ + /*---------------------------- alloc. from underlying */ _ipos = (iptr_type) this->_nset.count() ; this->_nset.push_tail() ; @@ -279,13 +294,13 @@ iptr_type _ipos = -1; if (this->_tpop.count() != +0 ) { - /*------------------------ recycle from free list */ + /*---------------------------- recycle from free list */ this-> _tpop._pop_tail(_ipos) ; } else { - /*------------------------ alloc. from underlying */ + /*---------------------------- alloc. from underlying */ _ipos = (iptr_type) this->_tset.count() ; this->_tset.push_tail() ; @@ -310,7 +325,7 @@ iptr_type &_flag ) const { - /*---------------- unwind face adjacency pointers */ + /*-------------------- unwind face adjacency pointers */ _jfac = __unflip( tria(_ipos)->fpos(_ifac)) ; @@ -336,7 +351,7 @@ iptr_type _flag ) { - /*---------------- encode face adjacency pointers */ + /*-------------------- encode face adjacency pointers */ if (_itri != this->null_flag()) { if (_flag >= +0) @@ -400,7 +415,7 @@ -------------------------------------------------------- */ - __inline_call delaunay_tri_k ( + __inline_call delaunay_tri_k ( allocator const& _asrc = allocator () ) : _fpol(sizeof( typename hash_list::item_type)) , @@ -413,8 +428,12 @@ _tset( _asrc), _tpop( _asrc), _npop( _asrc), - _work( _asrc) - { tria_pred::exactinit() ; // init. predicates + _work( _asrc) {} + + __inline_call ~delaunay_tri_k ( + ) + { + clear (containers::tight_alloc); } /* @@ -450,17 +469,17 @@ __const_ptr(real_type) _pmax ) { - /*---------------------------- de-alloc. existing */ + /*-------------------------------- de-alloc. existing */ this->_nset.clear() ; this->_tset.clear() ; - /*---------------------------- scale initial tria */ + /*-------------------------------- scale initial tria */ real_type static constexpr _scal = - (real_type)+tria_pred::_dims ; + (real_type)tria_pred::geom_dims ; - real_type _pmid[tria_pred::_dims]; + real_type _pmid[real_dims] = {.0}; real_type _pdel = (real_type)+.0 ; - for (auto _idim = tria_pred::_dims + 0 ; + for (auto _idim = tria_pred::geom_dims + 0 ; _idim-- != + 0 ; ) { real_type _xdel=_pmax[_idim] - @@ -474,9 +493,9 @@ _pmin[_idim] *(real_type)+.5 ; } - /*---------------------------- push tria indexing */ + /*-------------------------------- push tria indexing */ iptr_type _itri = _get_tria() ; - for (auto _inod = tria_pred::_dims + 1 ; + for (auto _inod = tria_pred::topo_dims + 1 ; _inod-- != + 0 ; ) { tria(_itri)->node(_inod) =_inod; @@ -487,13 +506,15 @@ __doflip(this->null_flag()); } - /*------------------------- push node coordinates */ - for (auto _inod = tria_pred::_dims + 1 ; + /*----------------------------- push node coordinates */ + for (auto _inod = tria_pred::topo_dims + 1 ; _inod-- != + 0 ; ) { iptr_type _jnod = _get_node() ; + node(_jnod)->pval( + tria_pred::real_dims - 1) = (real_type)+ 0.; node(_jnod)->next() = _itri; - for (auto _idim = tria_pred::_dims + 0 ; + for (auto _idim = tria_pred::geom_dims + 0 ; _idim-- != + 0 ; ) { if (_idim != _jnod - 1 ) @@ -557,10 +578,10 @@ ) { this->_work.clear(); - /*--------------------------- find enclosing tria */ + /*------------------------------- find enclosing tria */ if (walk_mesh_node(_ppos, _elem, _hint)) { - /*------------------------------ bfs about cavity */ + /*---------------------------------- bfs about cavity */ typename tria_pred:: template circ_pred< self_type >_pred( _ppos) ; @@ -568,7 +589,7 @@ scan_tria_list (_elem, +1, _pred, _work) ; - /*------------------------------ push index lists */ + /*---------------------------------- push index lists */ _list.push_tail (_work.head(), _work.tend()) ; @@ -620,15 +641,15 @@ /*--------------------------- push new node onto list */ _node = _get_node() ; - for (auto _idim = tria_pred::_dims + 0 ; + for (auto _idim = tria_pred::real_dims + 0 ; _idim-- != +0 ; ) { node(_node)->pval(_idim) = _ppos[_idim]; } /*--------------------------- grab enclosing indexing */ - iptr_type _tnod[ +1 + tria_pred::_dims]; - for (auto _inod = tria_pred::_dims + 1 ; + iptr_type _tnod[1+tria_pred::topo_dims]; + for (auto _inod = tria_pred::topo_dims + 1 ; _inod-- != +0 ; ) { _tnod[_inod] = tria(_elem)->node(_inod); @@ -639,7 +660,7 @@ std::numeric_limits ::infinity() ; - for (auto _inod = tria_pred::_dims + 1 ; + for (auto _inod = tria_pred::topo_dims + 1 ; _inod-- != +0 ; ) { _dist = std::min(_dist, @@ -691,13 +712,12 @@ list_type &_told ) { - iptr_type _npos ; - iptr_type _fpos ; + iptr_type _npos, _fpos ; for (auto _tpos = _tnew.head(); _tpos != _tnew.tend(); ++_tpos ) { - for (_npos = tria_pred::_dims+1; + for (_npos = tria_pred::topo_dims + 1; _npos-- != +0 ; ) { node(tria(*_tpos ) @@ -710,7 +730,7 @@ _tpos != _told.tend(); ++_tpos ) { - for (_npos = tria_pred::_dims+1; + for (_npos = tria_pred::topo_dims + 1; _npos-- != +0 ; ) { node(tria(*_tpos ) @@ -718,7 +738,7 @@ ->next() = *_tpos ; } - for (_fpos = tria_pred::_dims+1; + for (_fpos = tria_pred::topo_dims + 1; _fpos-- != +0 ; ) { iptr_type _tadj; @@ -737,7 +757,7 @@ _tpos != _tnew.tend(); ++_tpos ) { - for (_npos = tria_pred::_dims+1; + for (_npos = tria_pred::topo_dims + 1; _npos-- != +0 ; ) { if (node(tria(*_tpos ) diff --git a/src/libcpp/tessellate/del_tri_euclidean_2.hpp b/src/libcpp/tessellate/delaunay_tri_pred_2.hpp similarity index 95% rename from src/libcpp/tessellate/del_tri_euclidean_2.hpp rename to src/libcpp/tessellate/delaunay_tri_pred_2.hpp index 30a2073..44c51ad 100644 --- a/src/libcpp/tessellate/del_tri_euclidean_2.hpp +++ b/src/libcpp/tessellate/delaunay_tri_pred_2.hpp @@ -1,7 +1,7 @@ /* ------------------------------------------------------------ - * DEL-TRI-EUCLIDEAN-2: kernel for 2-dim. delaunay tria. + * DEL-TRI-EUCLIDEAN-2: kernel for 2-dim. delaunay tri. ------------------------------------------------------------ * * This program may be freely redistributed under the @@ -31,11 +31,11 @@ * ------------------------------------------------------------ * - * Last updated: 18 February, 2019 + * Last updated: 01 March, 2019 * * Copyright 2013-2019 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * ------------------------------------------------------------ @@ -50,7 +50,7 @@ /* ------------------------------------------------------------ - * DELAUNAY-TRI-EUCLIDEAN-2: for del-tri. in R^2. + * DELAUNAY-TRI-EUCLIDEAN-2: for del.-tri. in R^2. ------------------------------------------------------------ * IPTR-TYPE - signed-integer typedef. * REAL-TYPE - floating-point typedef. @@ -68,16 +68,11 @@ typedef R real_type ; typedef I iptr_type ; - iptr_type static constexpr _dims = +2 ; + iptr_type static constexpr geom_dims = +2 ; + iptr_type static constexpr real_dims = +2 ; + iptr_type static constexpr topo_dims = +2 ; public : -/*----------------------- initialise geometric predicates */ - __static_call - __inline_call void_type exactinit ( - ) - { geompred::exactinit() ; - } - /*----------------------- (squared) node-to-node distance */ __static_call __inline_call real_type lensqr_kd ( @@ -241,7 +236,7 @@ } ; double _sign; - _sign = geompred::incircle ( + _sign = geompred::inball2d ( &_ipos[ 0] , &_jpos[ 0] , &_kpos[ 0] , diff --git a/src/libcpp/tessellate/del_tri_euclidean_3.hpp b/src/libcpp/tessellate/delaunay_tri_pred_3.hpp similarity index 95% rename from src/libcpp/tessellate/del_tri_euclidean_3.hpp rename to src/libcpp/tessellate/delaunay_tri_pred_3.hpp index 4f84503..7de9aad 100644 --- a/src/libcpp/tessellate/del_tri_euclidean_3.hpp +++ b/src/libcpp/tessellate/delaunay_tri_pred_3.hpp @@ -1,7 +1,7 @@ /* ------------------------------------------------------------ - * DEL-TRI-EUCLIDEAN-3: kernel for 3-dim. delaunay tria. + * DEL-TRI-EUCLIDEAN-3: kernel for 3-dim. delaunay tri. ------------------------------------------------------------ * * This program may be freely redistributed under the @@ -31,11 +31,11 @@ * ------------------------------------------------------------ * - * Last updated: 18 February, 2019 + * Last updated: 01 March, 2019 * * Copyright 2013-2019 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * ------------------------------------------------------------ @@ -63,21 +63,16 @@ > class delaunay_tri_euclidean_3 { -/*----------- predicate for delaunay triangulation in R^2 */ +/*----------- predicate for delaunay triangulation in R^3 */ public : typedef R real_type ; typedef I iptr_type ; - iptr_type static constexpr _dims = +3 ; + iptr_type static constexpr geom_dims = +3 ; + iptr_type static constexpr real_dims = +3 ; + iptr_type static constexpr topo_dims = +3 ; public : -/*----------------------- initialise geometric predicates */ - __static_call - __inline_call void_type exactinit ( - ) - { geompred::exactinit() ; - } - /*----------------------- (squared) node-to-node distance */ __static_call __inline_call real_type lensqr_kd ( @@ -264,7 +259,7 @@ } ; double _sign; - _sign = geompred::insphere ( + _sign = geompred::inball3d ( &_ipos[ 0] , &_jpos[ 0] , &_kpos[ 0] , diff --git a/src/libcpp/tessellate/delaunay_tri_pred_4.hpp b/src/libcpp/tessellate/delaunay_tri_pred_4.hpp new file mode 100644 index 0000000..fe5af0a --- /dev/null +++ b/src/libcpp/tessellate/delaunay_tri_pred_4.hpp @@ -0,0 +1,363 @@ + +/* +------------------------------------------------------------ + * DEL-TRI-EUCLIDEAN-4: kernel for 4-dim. delaunay tri. +------------------------------------------------------------ + * + * 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 2013-2020 + * Darren Engwirda + * d.engwirda@gmail.com + * https://github.com/dengwirda/ + * +------------------------------------------------------------ + */ + +# pragma once + +# ifndef __DELAUNAY_TRI_EUCLIDEAN_4__ +# define __DELAUNAY_TRI_EUCLIDEAN_4__ + + namespace mesh { + +/* +------------------------------------------------------------ + * DELAUNAY-TRI-EUCLIDEAN-4: for del.-tri. in R^4. +------------------------------------------------------------ + * IPTR-TYPE - signed-integer typedef. + * REAL-TYPE - floating-point typedef. +------------------------------------------------------------ + */ + + template < + typename I, + typename R + > + class delaunay_tri_euclidean_4 + { +/*----------- predicate for delaunay triangulation in R^4 */ + public : + typedef R real_type ; + typedef I iptr_type ; + + iptr_type static constexpr geom_dims = +4 ; + iptr_type static constexpr real_dims = +4 ; + iptr_type static constexpr topo_dims = +4 ; + + public : +/*----------------------- (squared) node-to-node distance */ + __static_call + __inline_call real_type lensqr_kd ( + __const_ptr ( real_type) _ipos, + __const_ptr ( real_type) _jpos + ) + { return ( geometry::lensqr_4d ( + _ipos, + _jpos) ) ; + } + + template class near_pred + { +/*------------------------------------ walk--simplex test */ + public : + __inline_call bool_type operator() ( + mesh_type &_mesh, + __const_ptr ( real_type) _ppos, + real_type &_dmin, + iptr_type &_nmin, + iptr_type _tpos, + iptr_type &_fmin + ) const + { + bool_type _done = true ; + iptr_type _fpos; + iptr_type _fadj; + iptr_type _tadj; + iptr_type _fnod[5] = {0}; + + for(_fpos = 5; _fpos-- != 0; ) + { + /*--------------- check dist. wrt. k-th face apex */ + _tadj = _mesh. + tria(_tpos)->next(_fpos) ; + _fadj = _mesh. + tria(_tpos)->fpos(_fpos) ; + + _tadj = __unflip(_tadj) ; + + if(_tadj == _mesh.null_flag()) + continue ; + + mesh_type::tria_type:: + face_node(_fnod, _fadj, 4, 3) ; + /* + _fnod[0] = _mesh. + tria(_tpos)->node(_fnod[0]); + _fnod[1] = _mesh. + tria(_tpos)->node(_fnod[1]); + _fnod[2] = _mesh. + tria(_tpos)->node(_fnod[2]); + _fnod[3] = _mesh. + tria(_tpos)->node(_fnod[3]); + */ + _fnod[4] = _mesh. + tria(_tadj)->node(_fnod[4]); + + iptr_type _apex = _fnod[4] ; + + real_type _dsqr = lensqr_kd ( + _ppos, + &_mesh.node(_fnod[4])->pval(0)); + + if (_dsqr < _dmin) + { + _done = false; + _dmin = _dsqr; + _nmin = _apex; + _fmin = _fpos; + } + } + + return _done ; + } + } ; + + template class walk_pred + { +/*------------------------------------ walk--simplex test */ + public : + __inline_call bool_type operator() ( + mesh_type &_mesh, + __const_ptr ( real_type) _ppos, + iptr_type _tpos, + iptr_type &_fpos + ) const + { + double _xpos[4]; + _xpos[0] = _ppos[0]; + _xpos[1] = _ppos[1]; + _xpos[2] = _ppos[2]; + _xpos[3] = _ppos[3]; + + for(_fpos = 5; _fpos-- != 0; ) + { + /*--------------- test orientation wrt. k-th face */ + iptr_type _fnod[ 5] ; + mesh_type::tria_type:: + face_node(_fnod, _fpos, 4, 3) ; + _fnod[0] = _mesh. + tria(_tpos)->node(_fnod[0]); + _fnod[1] = _mesh. + tria(_tpos)->node(_fnod[1]); + _fnod[2] = _mesh. + tria(_tpos)->node(_fnod[2]); + _fnod[3] = _mesh. + tria(_tpos)->node(_fnod[3]); + + double _ipos[4] = { + _mesh.node(_fnod[0])->pval(0) , + _mesh.node(_fnod[0])->pval(1) , + _mesh.node(_fnod[0])->pval(2) , + _mesh.node(_fnod[0])->pval(3) + } ; + double _jpos[4] = { + _mesh.node(_fnod[1])->pval(0) , + _mesh.node(_fnod[1])->pval(1) , + _mesh.node(_fnod[1])->pval(2) , + _mesh.node(_fnod[1])->pval(3) + } ; + double _kpos[4] = { + _mesh.node(_fnod[2])->pval(0) , + _mesh.node(_fnod[2])->pval(1) , + _mesh.node(_fnod[2])->pval(2) , + _mesh.node(_fnod[2])->pval(3) + } ; + double _lpos[4] = { + _mesh.node(_fnod[3])->pval(0) , + _mesh.node(_fnod[3])->pval(1) , + _mesh.node(_fnod[3])->pval(2) , + _mesh.node(_fnod[3])->pval(3) + } ; + + double _sign; + _sign = geompred::orient4d ( + &_ipos[ 0] , + &_jpos[ 0] , + &_kpos[ 0] , + &_lpos[ 0] , + &_xpos[ 0] ) ; + + if (_sign > (double) +0.00 ) + return false ; + } + + return true ; + } + } ; + + template class circ_pred + { +/*------------------------------------ in-circumball test */ + public : + __const_ptr ( real_type) _ppos ; + + public : + __inline_call circ_pred ( + __const_ptr ( real_type) _psrc + ) : _ppos( _psrc ) { ; } + + __inline_call bool_type operator()( + mesh_type &_mesh, + iptr_type _tpos, + iptr_type//_fpos + ) const + { + iptr_type _tnod[5] = { + _mesh.tria(_tpos )->node(0) , + _mesh.tria(_tpos )->node(1) , + _mesh.tria(_tpos )->node(2) , + _mesh.tria(_tpos )->node(3) , + _mesh.tria(_tpos )->node(4) + } ; + + double _xpos[4] ; + _xpos[0] = this->_ppos[0] ; + _xpos[1] = this->_ppos[1] ; + _xpos[2] = this->_ppos[2] ; + _xpos[3] = this->_ppos[3] ; + + double _ipos[4] = { + _mesh.node(_tnod[0])->pval(0) , + _mesh.node(_tnod[0])->pval(1) , + _mesh.node(_tnod[0])->pval(2) , + _mesh.node(_tnod[0])->pval(3) + } ; + double _jpos[4] = { + _mesh.node(_tnod[1])->pval(0) , + _mesh.node(_tnod[1])->pval(1) , + _mesh.node(_tnod[1])->pval(2) , + _mesh.node(_tnod[1])->pval(3) + } ; + double _kpos[4] = { + _mesh.node(_tnod[2])->pval(0) , + _mesh.node(_tnod[2])->pval(1) , + _mesh.node(_tnod[2])->pval(2) , + _mesh.node(_tnod[2])->pval(3) + } ; + double _lpos[4] = { + _mesh.node(_tnod[3])->pval(0) , + _mesh.node(_tnod[3])->pval(1) , + _mesh.node(_tnod[3])->pval(2) , + _mesh.node(_tnod[3])->pval(3) + } ; + double _mpos[4] = { + _mesh.node(_tnod[4])->pval(0) , + _mesh.node(_tnod[4])->pval(1) , + _mesh.node(_tnod[4])->pval(2) , + _mesh.node(_tnod[4])->pval(3) + } ; + + __unreferenced(_xpos); + __unreferenced(_ipos); + __unreferenced(_jpos); + __unreferenced(_kpos); + __unreferenced(_lpos); + __unreferenced(_mpos); + + double _sign = 0.; + /* + _sign = geompred::inball4d ( + &_ipos[ 0] , + &_jpos[ 0] , + &_kpos[ 0] , + &_lpos[ 0] , + &_mpos[ 0] , + &_xpos[ 0] ) ; + */ + return (_sign <= (double)0.0) ; + } + } ; + + class face_ptrs + { +/*------------------------------ face adjacency structure */ + public : + containers::fixed_array < + iptr_type, +4 > _node ; + + iptr_type _tadj ; + iptr_type _fadj ; + } ; + + class face_same + { +/*------------------------------ face indexing comparison */ + public : + __inline_call bool_type operator() ( + face_ptrs const&_fi, + face_ptrs const&_fj + ) const + { + return _fi._node[0] == + _fj._node[0] && + _fi._node[1] == + _fj._node[1] && + _fi._node[2] == + _fj._node[2] && + _fi._node[3] == + _fj._node[3] ; + } + } ; + + class face_hash + { +/*------------------------------ face indexing hash-value */ + public : + __inline_call uint32_t operator() ( + face_ptrs const&_ff + ) const + { + return hash::hashword ( + (uint32_t*)&_ff._node[ 0], + +4* sizeof(iptr_type) + / sizeof( uint32_t),13); + } + } ; + + } ; + + +} + +# endif //__DELAUNAY_TRI_EUCLIDEAN_4__ + + + diff --git a/src/libcpp/tessellate/delaunay_tri_type_2.hpp b/src/libcpp/tessellate/delaunay_tri_type_2.hpp index 3411f82..b95599e 100644 --- a/src/libcpp/tessellate/delaunay_tri_type_2.hpp +++ b/src/libcpp/tessellate/delaunay_tri_type_2.hpp @@ -1,45 +1,45 @@ - /* - -------------------------------------------------------- - * DEL-TRI-TYPE-2: datatypes for 2-dim. delaunay tria. - -------------------------------------------------------- - * - * 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: 12 May, 2017 - * - * Copyright 2013-2017 - * Darren Engwirda - * de2363@columbia.edu - * https://github.com/dengwirda/ - * - -------------------------------------------------------- - */ +/* +------------------------------------------------------------ + * DEL-TRI-TYPE-2: 2-dim. delaunay/laguerre tria. types +------------------------------------------------------------ + * + * 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: 22 February, 2020 + * + * Copyright 2013-2020 + * Darren Engwirda + * d.engwirda@gmail.com + * https://github.com/dengwirda/ + * +------------------------------------------------------------ + */ # pragma once @@ -48,14 +48,14 @@ namespace mesh { - /* - -------------------------------------------------------- - * DELAUNAY-TRI-NODE-2: node for delaunay tria. in R^2. - -------------------------------------------------------- - * IPTR-TYPE - signed-integer typedef. - * REAL-TYPE - floating-point typedef. - -------------------------------------------------------- - */ +/* +------------------------------------------------------------ + * DELAUNAY-TRI-NODE-2: node for delaunay tria. in R^2. +------------------------------------------------------------ + * IPTR-TYPE - signed-integer typedef. + * REAL-TYPE - floating-point typedef. +------------------------------------------------------------ + */ template < typename I, @@ -64,32 +64,97 @@ class delaunay_tri_node_2 { /*----------- node-type for delaunay triangulation in R^2 */ - public : - typedef R real_type ; - typedef I iptr_type ; + public: + typedef R real_type ; + typedef I iptr_type ; + + iptr_type static constexpr geom_dims = +2 ; + iptr_type static constexpr real_dims = +2 ; + +/*------------------------------------ local data members */ + containers:: + fixed_array _pval ; // node coord + + containers:: + fixed_array _flag ; // kind, mark + + iptr_type _next ; + +/*---------------------------------------- "write" access */ + __inline_call real_type & pval ( + iptr_type _ipos + ) + { return this->_pval [_ipos]; + } + __inline_call iptr_type & next ( + ) + { return this->_next; + } + __inline_call char_type & mark ( + ) + { return this->_flag [ +0]; + } + +/*---------------------------------------- "const" access */ + __inline_call real_type const& pval ( + iptr_type _ipos + ) const + { return this->_pval [_ipos]; + } + __inline_call iptr_type const& next ( + ) const + { return this->_next; + } + __inline_call char_type const& mark ( + ) const + { return this->_flag [ +0]; + } - iptr_type static constexpr _dims = +2 ; + } ; + +/* +------------------------------------------------------------ + * LAGUERRE-TRI-NODE-2: node for laguerre tria. in R^2. +------------------------------------------------------------ + * IPTR-TYPE - signed-integer typedef. + * REAL-TYPE - floating-point typedef. +------------------------------------------------------------ + */ + + template < + typename I, + typename R + > + class laguerre_tri_node_2 + { +/*----------- node-type for laguerre triangulation in R^2 */ + public: + typedef R real_type ; + typedef I iptr_type ; + + iptr_type static constexpr geom_dims = +2 ; + iptr_type static constexpr real_dims = +3 ; /*------------------------------------ local data members */ containers:: - fixed_array _pval ; // node coord + fixed_array _pval ; // node coord containers:: - fixed_array _flag ; // kind, mark + fixed_array _flag ; // kind, mark - iptr_type _next ; + iptr_type _next ; -/*---------------------------------------- "write access" */ - __inline_call real_type &pval ( +/*---------------------------------------- "write" access */ + __inline_call real_type & pval ( iptr_type _ipos ) { return this->_pval [_ipos]; } - __inline_call iptr_type &next ( + __inline_call iptr_type & next ( ) { return this->_next; } - __inline_call char_type &mark ( + __inline_call char_type & mark ( ) { return this->_flag [ +0]; } @@ -128,41 +193,41 @@ { /*----------- tria-type for delaunay triangulation in R^2 */ public : - typedef R real_type ; - typedef I iptr_type ; + typedef R real_type ; + typedef I iptr_type ; - iptr_type static constexpr _dims = +2 ; + iptr_type static constexpr topo_dims = +2 ; /*------------------------------------ local data members */ containers:: - fixed_array _ndat ; // node indexing + fixed_array _ndat ; // node indexing containers:: - fixed_array _edat ; // edge neighbour + fixed_array _edat ; // adjacent edge containers:: - fixed_array _epos ; // edge neighbour + fixed_array _epos ; // adjacent edge containers:: - fixed_array _flag ; // kind, mark + fixed_array _flag ; // kind, mark /*---------------------------------------- "write" access */ - __inline_call iptr_type &node ( + __inline_call iptr_type & node ( iptr_type _ipos ) { return this->_ndat [_ipos]; } - __inline_call iptr_type &next ( + __inline_call iptr_type & next ( iptr_type _ipos ) { return this->_edat [_ipos]; } - __inline_call char_type &fpos ( + __inline_call char_type & fpos ( iptr_type _ipos ) { return this->_epos [_ipos]; } - __inline_call char_type &mark ( + __inline_call char_type & mark ( ) { return this->_flag [ +0]; } @@ -195,6 +260,7 @@ iptr_type//_fpos ) { +/*-------------------------- return 2-cell local indexing */ _fnod[0] = 0 ; _fnod[1] = 1 ; _fnod[2] = 2 ; @@ -205,6 +271,7 @@ iptr_type//_fpos ) { +/*-------------------------- return 1-edge local indexing */ _fnod[0] = 0 ; _fnod[1] = 1 ; } @@ -214,6 +281,7 @@ iptr_type _fpos ) { +/*-------------------------- return 1-edge local indexing */ switch (_fpos) { case 0 : @@ -235,7 +303,7 @@ _fnod[2] = 1 ; break ; } default: - { // suppress compiler warnings + { // suppress compiler warnings _fnod[0] =-1 ; _fnod[1] =-1 ; _fnod[2] =-1 ; break ; @@ -250,15 +318,15 @@ iptr_type _into ) { - /* index FROM 2-dim faces */ + /*---------------------------- index FROM 2-dim faces */ if (_from == +2) { - /* index INTO 2-dim faces */ + /*---------------------------- index INTO 2-dim faces */ if (_into == +2) { faceind22(_fnod, _fpos); return ; } - /* index INTO 1-dim faces */ + /*---------------------------- index INTO 1-dim faces */ else if (_into == +1) { @@ -266,34 +334,49 @@ } else { - _fnod[0] = -1; // suppress compiler warnings + _fnod[0] = -1; // suppress compiler warnings _fnod[1] = -1; _fnod[2] = -1; return ; } } - /* index FROM 1-dim faces */ + /*---------------------------- index FROM 1-dim faces */ else if (_from == +1) { - /* index INTO 1-dim faces */ + /*---------------------------- index INTO 1-dim faces */ if (_into == +1) { faceind11(_fnod, _fpos); return ; } else { - _fnod[0] = -1; // suppress compiler warnings + _fnod[0] = -1; // suppress compiler warnings _fnod[1] = -1; return ; } } else { - _fnod[0] = -1; // suppress compiler warnings + _fnod[0] = -1; // suppress compiler warnings } } } ; +/* +------------------------------------------------------------ + * LAGUERRE-TRI-TRIA-2: tria for laguerre tria. in R^2. +------------------------------------------------------------ + * IPTR-TYPE - signed-integer typedef. + * REAL-TYPE - floating-point typedef. +------------------------------------------------------------ + */ + + template < + typename I, + typename R + > + using laguerre_tri_tria_2 = delaunay_tri_tria_2; + } diff --git a/src/libcpp/tessellate/delaunay_tri_type_3.hpp b/src/libcpp/tessellate/delaunay_tri_type_3.hpp index ebe855d..3f6a119 100644 --- a/src/libcpp/tessellate/delaunay_tri_type_3.hpp +++ b/src/libcpp/tessellate/delaunay_tri_type_3.hpp @@ -1,7 +1,7 @@ /* ------------------------------------------------------------ - * DEL-TRI-TYPE-3: data-types for 3-dim. delaunay tria. + * DEL-TRI-TYPE-3: 3-dim. delaunay/laguerre tria. types ------------------------------------------------------------ * * This program may be freely redistributed under the @@ -31,11 +31,11 @@ * ------------------------------------------------------------ * - * Last updated: 12 May, 2017 + * Last updated: 22 February, 2020 * - * Copyright 2013-2017 + * Copyright 2013-2020 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * ------------------------------------------------------------ @@ -65,31 +65,96 @@ { /*----------- node-type for delaunay triangulation in R^3 */ public: - typedef R real_type ; - typedef I iptr_type ; + typedef R real_type ; + typedef I iptr_type ; - iptr_type static constexpr _dims = +3 ; + iptr_type static constexpr geom_dims = +3 ; + iptr_type static constexpr real_dims = +3 ; /*------------------------------------ local data members */ containers:: - fixed_array _pval ; // node coord + fixed_array _pval ; // node coord containers:: - fixed_array _flag ; // kind, mark + fixed_array _flag ; // kind, mark - iptr_type _next ; + iptr_type _next ; /*---------------------------------------- "write" access */ - __inline_call real_type &pval ( + __inline_call real_type & pval ( iptr_type _ipos ) { return this->_pval [_ipos]; } - __inline_call iptr_type &next ( + __inline_call iptr_type & next ( ) { return this->_next; } - __inline_call char_type &mark ( + __inline_call char_type & mark ( + ) + { return this->_flag [ +0]; + } + +/*---------------------------------------- "const" access */ + __inline_call real_type const& pval ( + iptr_type _ipos + ) const + { return this->_pval [_ipos]; + } + __inline_call iptr_type const& next ( + ) const + { return this->_next; + } + __inline_call char_type const& mark ( + ) const + { return this->_flag [ +0]; + } + + } ; + +/* +------------------------------------------------------------ + * LAGUERRE-TRI-NODE-3: node for laguerre tria. in R^3. +------------------------------------------------------------ + * IPTR-TYPE - signed-integer typedef. + * REAL-TYPE - floating-point typedef. +------------------------------------------------------------ + */ + + template < + typename I, + typename R + > + class laguerre_tri_node_3 + { +/*----------- node-type for laguerre triangulation in R^3 */ + public: + typedef R real_type ; + typedef I iptr_type ; + + iptr_type static constexpr geom_dims = +3 ; + iptr_type static constexpr real_dims = +4 ; + +/*------------------------------------ local data members */ + containers:: + fixed_array _pval ; // node coord + + containers:: + fixed_array _flag ; // kind, mark + + iptr_type _next ; + +/*---------------------------------------- "write" access */ + __inline_call real_type & pval ( + iptr_type _ipos + ) + { return this->_pval [_ipos]; + } + __inline_call iptr_type & next ( + ) + { return this->_next; + } + __inline_call char_type & mark ( ) { return this->_flag [ +0]; } @@ -128,41 +193,41 @@ { /*----------- tria-type for delaunay triangulation in R^3 */ public: - typedef R real_type ; - typedef I iptr_type ; + typedef R real_type ; + typedef I iptr_type ; - iptr_type static constexpr _dims = +3 ; + iptr_type static constexpr topo_dims = +3 ; /*------------------------------------ local data members */ containers:: - fixed_array _ndat ; // node indexing + fixed_array _ndat ; // node indexing containers:: - fixed_array _fdat ; // edge neighbour + fixed_array _fdat ; // edge adjacent containers:: - fixed_array _fpos ; // edge neighbour + fixed_array _fpos ; // edge adjacent containers:: - fixed_array _flag ; // kind, mark + fixed_array _flag ; // kind, mark /*---------------------------------------- "write" access */ - __inline_call iptr_type &node ( + __inline_call iptr_type & node ( iptr_type _ipos ) { return this->_ndat [_ipos]; } - __inline_call iptr_type &next ( + __inline_call iptr_type & next ( iptr_type _ipos ) { return this->_fdat [_ipos]; } - __inline_call char_type &fpos ( + __inline_call char_type & fpos ( iptr_type _ipos ) { return this->_fpos [_ipos]; } - __inline_call char_type &mark ( + __inline_call char_type & mark ( ) { return this->_flag [ +0]; } @@ -195,6 +260,7 @@ iptr_type//_fpos ) { +/*-------------------------- return 3-cell local indexing */ _fnod[0] = 0 ; _fnod[1] = 1 ; _fnod[2] = 2 ; @@ -206,6 +272,7 @@ iptr_type//_fpos ) { +/*-------------------------- return 2-face local indexing */ _fnod[0] = 0 ; _fnod[1] = 1 ; _fnod[2] = 2 ; @@ -216,6 +283,7 @@ iptr_type//_fpos ) { +/*-------------------------- return 1-edge local indexing */ _fnod[0] = 0 ; _fnod[1] = 1 ; } @@ -225,6 +293,7 @@ iptr_type _fpos ) { +/*-------------------------- return 2-face local indexing */ switch (_fpos) { case 0 : @@ -256,7 +325,7 @@ _fnod[3] = 1 ; break ; } default: - { // suppress compiler warnings + { // suppress compiler warnings _fnod[0] =-1 ; _fnod[1] =-1 ; _fnod[2] =-1 ; @@ -270,6 +339,7 @@ iptr_type _fpos ) { +/*-------------------------- return 1-edge local indexing */ switch (_fpos) { case 0 : @@ -303,7 +373,7 @@ _fnod[1] = 3 ; break ; } default: - { // suppress compiler warnings + { // suppress compiler warnings _fnod[0] =-1 ; _fnod[1] =-1 ; break ; } @@ -315,6 +385,7 @@ iptr_type _fpos ) { +/*-------------------------- return 1-edge local indexing */ switch (_fpos) { case 0 : @@ -336,7 +407,7 @@ _fnod[2] = 1 ; break ; } default: - { // suppress compiler warnings + { // suppress compiler warnings _fnod[0] =-1 ; _fnod[1] =-1 ; _fnod[2] =-1 ; break ; @@ -352,21 +423,21 @@ iptr_type _into // "into" dims ) { - /* index FROM 3-dim faces */ + /*---------------------------- index FROM 3-dim faces */ if (_from == +3) { - /* index INTO 3-dim faces */ + /*---------------------------- index INTO 3-dim faces */ if (_into == +3) { faceind33(_fnod, _fpos); return ; } - /* index INTO 2-dim faces */ + /*---------------------------- index INTO 2-dim faces */ else if (_into == +2) { faceind32(_fnod, _fpos); return ; } - /* index INTO 1-dim faces */ + /*---------------------------- index INTO 1-dim faces */ else if (_into == +1) { @@ -374,22 +445,22 @@ } else { - _fnod[0] = -1; // suppress compiler warnings + _fnod[0] = -1; // suppress compiler warnings _fnod[1] = -1; _fnod[2] = -1; _fnod[3] = -1; return ; } } - /* index FROM 2-dim faces */ + /*---------------------------- index FROM 2-dim faces */ else if (_from == +2) { - /* index INTO 2-dim faces */ + /*---------------------------- index INTO 2-dim faces */ if (_into == +2) { faceind22(_fnod, _fpos); return ; } - /* index INTO 1-dim faces */ + /*---------------------------- index INTO 1-dim faces */ else if (_into == +1) { @@ -397,34 +468,49 @@ } else { - _fnod[0] = -1; // suppress compiler warnings + _fnod[0] = -1; // suppress compiler warnings _fnod[1] = -1; _fnod[2] = -1; return ; } } - /* index FROM 1-dim faces */ + /*---------------------------- index FROM 1-dim faces */ else if (_from == +1) { - /* index INTO 1-dim faces */ + /*---------------------------- index INTO 1-dim faces */ if (_into == +1) { faceind11(_fnod, _fpos); return ; } else { - _fnod[0] = -1; // suppress compiler warnings + _fnod[0] = -1; // suppress compiler warnings _fnod[1] = -1; return ; } } else { - _fnod[0] = -1; // suppress compiler warnings + _fnod[0] = -1; // suppress compiler warnings } } } ; +/* +------------------------------------------------------------ + * LAGUERRE-TRI-TRIA-3: tria for laguerre tria. in R^3. +------------------------------------------------------------ + * IPTR-TYPE - signed-integer typedef. + * REAL-TYPE - floating-point typedef. +------------------------------------------------------------ + */ + + template < + typename I, + typename R + > + using laguerre_tri_tria_3 = delaunay_tri_tria_3; + } diff --git a/src/libcpp/tessellate/delaunay_tri_type_4.hpp b/src/libcpp/tessellate/delaunay_tri_type_4.hpp new file mode 100644 index 0000000..9100065 --- /dev/null +++ b/src/libcpp/tessellate/delaunay_tri_type_4.hpp @@ -0,0 +1,533 @@ + +/* +------------------------------------------------------------ + * DEL-TRI-TYPE-4: 4-dim. delaunay/laguerre tria. types +------------------------------------------------------------ + * + * 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 2013-2020 + * Darren Engwirda + * d.engwirda@gmail.com + * https://github.com/dengwirda/ + * +------------------------------------------------------------ + */ + +# pragma once + +# ifndef __DELAUNAY_TRI_TYPE_4__ +# define __DELAUNAY_TRI_TYPE_4__ + + namespace mesh { + +/* +------------------------------------------------------------ + * DELAUNAY-TRI-NODE-4: node for delaunay tria. in R^4. +------------------------------------------------------------ + * IPTR-TYPE - signed-integer typedef. + * REAL-TYPE - floating-point typedef. +------------------------------------------------------------ + */ + + template < + typename I, + typename R + > + class delaunay_tri_node_4 + { +/*----------- node-type for delaunay triangulation in R^4 */ + public: + typedef R real_type ; + typedef I iptr_type ; + + iptr_type static constexpr geom_dims = +4 ; + iptr_type static constexpr real_dims = +4 ; + +/*------------------------------------ local data members */ + containers:: + fixed_array _pval ; // node coord + + containers:: + fixed_array _flag ; // kind, mark + + iptr_type _next ; + +/*---------------------------------------- "write" access */ + __inline_call real_type & pval ( + iptr_type _ipos + ) + { return this->_pval [_ipos]; + } + __inline_call iptr_type & next ( + ) + { return this->_next; + } + __inline_call char_type & mark ( + ) + { return this->_flag [ +0]; + } + +/*---------------------------------------- "const" access */ + __inline_call real_type const& pval ( + iptr_type _ipos + ) const + { return this->_pval [_ipos]; + } + __inline_call iptr_type const& next ( + ) const + { return this->_next; + } + __inline_call char_type const& mark ( + ) const + { return this->_flag [ +0]; + } + + } ; + +/* +------------------------------------------------------------ + * LAGUERRE-TRI-NODE-4: node for laguerre tria. in R^4. +------------------------------------------------------------ + * IPTR-TYPE - signed-integer typedef. + * REAL-TYPE - floating-point typedef. +------------------------------------------------------------ + */ + + template < + typename I, + typename R + > + class laguerre_tri_node_4 + { +/*----------- node-type for laguerre triangulation in R^4 */ + public: + typedef R real_type ; + typedef I iptr_type ; + + iptr_type static constexpr geom_dims = +4 ; + iptr_type static constexpr real_dims = +5 ; + +/*------------------------------------ local data members */ + containers:: + fixed_array _pval ; // node coord + + containers:: + fixed_array _flag ; // kind, mark + + iptr_type _next ; + +/*---------------------------------------- "write" access */ + __inline_call real_type & pval ( + iptr_type _ipos + ) + { return this->_pval [_ipos]; + } + __inline_call iptr_type & next ( + ) + { return this->_next; + } + __inline_call char_type & mark ( + ) + { return this->_flag [ +0]; + } + +/*---------------------------------------- "const" access */ + __inline_call real_type const& pval ( + iptr_type _ipos + ) const + { return this->_pval [_ipos]; + } + __inline_call iptr_type const& next ( + ) const + { return this->_next; + } + __inline_call char_type const& mark ( + ) const + { return this->_flag [ +0]; + } + + } ; + +/* +------------------------------------------------------------ + * DELAUNAY-TRI-TRIA-4: tria for delaunay tria. in R^4. +------------------------------------------------------------ + * IPTR-TYPE - signed-integer typedef. + * REAL-TYPE - floating-point typedef. +------------------------------------------------------------ + */ + + template < + typename I, + typename R + > + class delaunay_tri_tria_4 + { +/*----------- tria-type for delaunay triangulation in R^4 */ + public: + typedef R real_type ; + typedef I iptr_type ; + + iptr_type static constexpr topo_dims = +4 ; + +/*------------------------------------ local data members */ + containers:: + fixed_array _ndat ; // node indexing + + containers:: + fixed_array _fdat ; // face adjacent + + containers:: + fixed_array _fpos ; // face adjacent + + containers:: + fixed_array _flag ; // kind, mark + +/*---------------------------------------- "write" access */ + __inline_call iptr_type & node ( + iptr_type _ipos + ) + { return this->_ndat [_ipos]; + } + __inline_call iptr_type & next ( + iptr_type _ipos + ) + { return this->_fdat [_ipos]; + } + __inline_call char_type & fpos ( + iptr_type _ipos + ) + { return this->_fpos [_ipos]; + } + __inline_call char_type & mark ( + ) + { return this->_flag [ +0]; + } + +/*---------------------------------------- "const" access */ + __inline_call iptr_type const& node ( + iptr_type _ipos + ) const + { return this->_ndat [_ipos]; + } + __inline_call iptr_type const& next ( + iptr_type _ipos + ) const + { return this->_fdat [_ipos]; + } + __inline_call char_type const& fpos ( + iptr_type _ipos + ) const + { return this->_fpos [_ipos]; + } + __inline_call char_type const& mark ( + ) const + { return this->_flag [ +0]; + } + +/*---------------------------------------- local indexing */ + __static_call + __inline_call void_type faceind44 ( + iptr_type *_fnod, + iptr_type//_fpos + ) + { +/*-------------------------- return 4-cell local indexing */ + _fnod[0] = 0 ; + _fnod[1] = 1 ; + _fnod[2] = 2 ; + _fnod[3] = 3 ; + _fnod[4] = 4 ; + } + __static_call + __inline_call void_type faceind33 ( + iptr_type *_fnod, + iptr_type//_fpos + ) + { +/*-------------------------- return 3-cell local indexing */ + _fnod[0] = 0 ; + _fnod[1] = 1 ; + _fnod[2] = 2 ; + _fnod[3] = 3 ; + } + __static_call + __inline_call void_type faceind22 ( + iptr_type *_fnod, + iptr_type//_fpos + ) + { +/*-------------------------- return 2-face local indexing */ + _fnod[0] = 0 ; + _fnod[1] = 1 ; + _fnod[2] = 2 ; + } + __static_call + __inline_call void_type faceind11 ( + iptr_type *_fnod, + iptr_type//_fpos + ) + { +/*-------------------------- return 1-edge local indexing */ + _fnod[0] = 0 ; + _fnod[1] = 1 ; + } + __static_call + __inline_call void_type faceind32 ( + iptr_type *_fnod, + iptr_type _fpos + ) + { +/*-------------------------- return 2-face local indexing */ + switch (_fpos) + { + case 0 : + { + _fnod[0] = 0 ; + _fnod[1] = 1 ; + _fnod[2] = 2 ; + _fnod[3] = 3 ; break ; + } + case 1 : + { + _fnod[0] = 0 ; + _fnod[1] = 3 ; + _fnod[2] = 1 ; + _fnod[3] = 2 ; break ; + } + case 2 : + { + _fnod[0] = 1 ; + _fnod[1] = 3 ; + _fnod[2] = 2 ; + _fnod[3] = 0 ; break ; + } + case 3 : + { + _fnod[0] = 2 ; + _fnod[1] = 3 ; + _fnod[2] = 0 ; + _fnod[3] = 1 ; break ; + } + default: + { // suppress compiler warnings + _fnod[0] =-1 ; + _fnod[1] =-1 ; + _fnod[2] =-1 ; + _fnod[3] =-1 ; break ; + } + } + } + __static_call + __inline_call void_type faceind31 ( + iptr_type *_fnod, + iptr_type _fpos + ) + { +/*-------------------------- return 1-edge local indexing */ + switch (_fpos) + { + case 0 : + { + _fnod[0] = 0 ; + _fnod[1] = 1 ; break ; + } + case 1 : + { + _fnod[0] = 1 ; + _fnod[1] = 2 ; break ; + } + case 2 : + { + _fnod[0] = 2 ; + _fnod[1] = 0 ; break ; + } + case 3 : + { + _fnod[0] = 0 ; + _fnod[1] = 3 ; break ; + } + case 4 : + { + _fnod[0] = 1 ; + _fnod[1] = 3 ; break ; + } + case 5 : + { + _fnod[0] = 2 ; + _fnod[1] = 3 ; break ; + } + default: + { // suppress compiler warnings + _fnod[0] =-1 ; + _fnod[1] =-1 ; break ; + } + } + } + __static_call + __inline_call void_type faceind21 ( + iptr_type *_fnod, + iptr_type _fpos + ) + { +/*-------------------------- return 1-edge local indexing */ + switch (_fpos) + { + case 0 : + { + _fnod[0] = 0 ; + _fnod[1] = 1 ; + _fnod[2] = 2 ; break ; + } + case 1 : + { + _fnod[0] = 1 ; + _fnod[1] = 2 ; + _fnod[2] = 0 ; break ; + } + case 2 : + { + _fnod[0] = 2 ; + _fnod[1] = 0 ; + _fnod[2] = 1 ; break ; + } + default: + { // suppress compiler warnings + _fnod[0] =-1 ; + _fnod[1] =-1 ; + _fnod[2] =-1 ; break ; + } + } + } + + __static_call + __inline_call void_type face_node ( + iptr_type *_fnod, + iptr_type _fpos, + iptr_type _from, // "from" dims + iptr_type _into // "into" dims + ) + { + /*---------------------------- index FROM 3-dim faces */ + if (_from == +3) + { + /*---------------------------- index INTO 3-dim faces */ + if (_into == +3) + { + faceind33(_fnod, _fpos); return ; + } + /*---------------------------- index INTO 2-dim faces */ + else + if (_into == +2) + { + faceind32(_fnod, _fpos); return ; + } + /*---------------------------- index INTO 1-dim faces */ + else + if (_into == +1) + { + faceind31(_fnod, _fpos); return ; + } + else + { + _fnod[0] = -1; // suppress compiler warnings + _fnod[1] = -1; + _fnod[2] = -1; + _fnod[3] = -1; return ; + } + } + /*---------------------------- index FROM 2-dim faces */ + else + if (_from == +2) + { + /*---------------------------- index INTO 2-dim faces */ + if (_into == +2) + { + faceind22(_fnod, _fpos); return ; + } + /*---------------------------- index INTO 1-dim faces */ + else + if (_into == +1) + { + faceind21(_fnod, _fpos); return ; + } + else + { + _fnod[0] = -1; // suppress compiler warnings + _fnod[1] = -1; + _fnod[2] = -1; return ; + } + } + /*---------------------------- index FROM 1-dim faces */ + else + if (_from == +1) + { + /*---------------------------- index INTO 1-dim faces */ + if (_into == +1) + { + faceind11(_fnod, _fpos); return ; + } + else + { + _fnod[0] = -1; // suppress compiler warnings + _fnod[1] = -1; return ; + } + } + else + { + _fnod[0] = -1; // suppress compiler warnings + } + } + + } ; + +/* +------------------------------------------------------------ + * LAGUERRE-TRI-TRIA-4: tria for laguerre tria. in R^4. +------------------------------------------------------------ + * IPTR-TYPE - signed-integer typedef. + * REAL-TYPE - floating-point typedef. +------------------------------------------------------------ + */ + + template < + typename I, + typename R + > + using laguerre_tri_tria_4 = delaunay_tri_tria_4; + + + } + +# endif//__DELAUNAY_TRI_TYPE_4__ + + + diff --git a/src/libcpp/tessellate/delaunay_walk_mesh.inc b/src/libcpp/tessellate/delaunay_walk_mesh.inc index fc5d0b6..8d21e59 100644 --- a/src/libcpp/tessellate/delaunay_walk_mesh.inc +++ b/src/libcpp/tessellate/delaunay_walk_mesh.inc @@ -35,7 +35,7 @@ * * Copyright 2013-2019 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- @@ -96,7 +96,7 @@ /*--------------------- scale no. iter with dims. */ iptr_type _imax = (iptr_type) std::pow ((double) _ntri, - +1.0 / tria_pred::_dims) / 4 + 1 ; + 1. / tria_pred::geom_dims) / 4 + 1 ; for (auto _iter = _imax; _iter-- != +0; ) { @@ -212,7 +212,7 @@ real_type _dmin = +std :: numeric_limits::infinity () ; - for (auto _inod = tria_pred::_dims + 1 ; + for (auto _inod = tria_pred::topo_dims+1 ; _inod-- != +0 ; ) { auto _next = tria(_elem) diff --git a/src/libcpp/tessellate/laguerre_tri_pred_2.hpp b/src/libcpp/tessellate/laguerre_tri_pred_2.hpp new file mode 100644 index 0000000..36794d0 --- /dev/null +++ b/src/libcpp/tessellate/laguerre_tri_pred_2.hpp @@ -0,0 +1,303 @@ + +/* +------------------------------------------------------------ + * LAG-TRI-EUCLIDEAN-2: kernel for 2-dim. laguerre tri. +------------------------------------------------------------ + * + * 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 2013-2020 + * Darren Engwirda + * d.engwirda@gmail.com + * https://github.com/dengwirda/ + * +------------------------------------------------------------ + */ + +# pragma once + +# ifndef __LAGUERRE_TRI_EUCLIDEAN_2__ +# define __LAGUERRE_TRI_EUCLIDEAN_2__ + + namespace mesh { + +/* +------------------------------------------------------------ + * LAGUERRE-TRI-EUCLIDEAN-2: for lag.-tri. in R^2. +------------------------------------------------------------ + * IPTR-TYPE - signed-integer typedef. + * REAL-TYPE - floating-point typedef. +------------------------------------------------------------ + */ + + template < + typename I, + typename R + > + class laguerre_tri_euclidean_2 + { +/*----------- predicate for laguerre triangulation in R^2 */ + public : + typedef R real_type ; + typedef I iptr_type ; + + iptr_type static constexpr geom_dims = +2 ; + iptr_type static constexpr real_dims = +3 ; + iptr_type static constexpr topo_dims = +2 ; + + public : +/*----------------------- (squared) node-to-node distance */ + __static_call + __inline_call real_type lensqr_kd ( + __const_ptr ( real_type) _ipos, + __const_ptr ( real_type) _jpos + ) + { return ( geometry::lensqr_2d ( + _ipos, + _jpos) ) ; + } + + template class near_pred + { +/*------------------------------------ walk--simplex test */ + public : + __inline_call bool_type operator() ( + mesh_type &_mesh, + __const_ptr ( real_type) _ppos, + real_type &_dmin, + iptr_type &_nmin, + iptr_type _tpos, + iptr_type &_fmin + ) const + { + bool_type _done = true ; + iptr_type _fpos; + iptr_type _fadj; + iptr_type _tadj; + iptr_type _fnod[3] = {0}; + + for(_fpos = 3; _fpos-- != 0; ) + { + /*--------------- check dist. wrt. k-th face apex */ + _tadj = _mesh. + tria(_tpos)->next(_fpos) ; + _fadj = _mesh. + tria(_tpos)->fpos(_fpos) ; + + _tadj = __unflip(_tadj) ; + + if(_tadj == _mesh.null_flag()) + continue ; + + mesh_type::tria_type:: + face_node(_fnod, _fadj, 2, 1) ; + /* + _fnod[0] = _mesh. + tria(_tadj)->node(_fnod[0]); + _fnod[1] = _mesh. + tria(_tadj)->node(_fnod[1]); + */ + _fnod[2] = _mesh. + tria(_tadj)->node(_fnod[2]); + + iptr_type _apex = _fnod[2] ; + + real_type _dsqr = lensqr_kd ( + _ppos, + &_mesh.node(_fnod[2])->pval(0)); + + if (_dsqr < _dmin) + { + _done = false; + _dmin = _dsqr; + _nmin = _apex; + _fmin = _fpos; + } + } + + return _done ; + } + } ; + + template class walk_pred + { +/*------------------------------------ walk--simplex test */ + public : + __inline_call bool_type operator() ( + mesh_type &_mesh, + __const_ptr ( real_type) _ppos, + iptr_type _tpos, + iptr_type &_fpos + ) const + { + double _xpos[2]; + _xpos[0] = _ppos[0]; + _xpos[1] = _ppos[1]; + + for(_fpos = 3; _fpos-- != 0; ) + { + /*--------------- test orientation wrt. k-th face */ + iptr_type _fnod[ 3] ; + mesh_type::tria_type:: + face_node(_fnod, _fpos, 2, 1) ; + _fnod[0] = _mesh. + tria(_tpos)->node(_fnod[0]); + _fnod[1] = _mesh. + tria(_tpos)->node(_fnod[1]); + + double _ipos[2] = { + _mesh.node(_fnod[0])->pval(0) , + _mesh.node(_fnod[0])->pval(1) + } ; + double _jpos[2] = { + _mesh.node(_fnod[1])->pval(0) , + _mesh.node(_fnod[1])->pval(1) + } ; + + double _sign; + _sign = geompred::orient2d ( + &_ipos[ 0] , + &_jpos[ 0] , + &_xpos[ 0] ) ; + + if (_sign < (double) +0.00 ) + return false ; + } + + return true ; + } + } ; + + template class circ_pred + { +/*------------------------------------ in-circumball test */ + public : + __const_ptr ( real_type) _ppos ; + + public : + __inline_call circ_pred ( + __const_ptr ( real_type) _psrc + ) : _ppos( _psrc ) { ; } + + __inline_call bool_type operator()( + mesh_type &_mesh, + iptr_type _tpos, + iptr_type//_fpos + ) const + { + iptr_type _tnod[3] = { + _mesh.tria(_tpos )->node(0) , + _mesh.tria(_tpos )->node(1) , + _mesh.tria(_tpos )->node(2) + } ; + + double _xpos[3] ; + _xpos[0] = this->_ppos[0] ; + _xpos[1] = this->_ppos[1] ; + _xpos[2] = this->_ppos[2] ; + + double _ipos[3] = { + _mesh.node(_tnod[0])->pval(0) , + _mesh.node(_tnod[0])->pval(1) , + _mesh.node(_tnod[0])->pval(2) + } ; + double _jpos[3] = { + _mesh.node(_tnod[1])->pval(0) , + _mesh.node(_tnod[1])->pval(1) , + _mesh.node(_tnod[1])->pval(2) + } ; + double _kpos[3] = { + _mesh.node(_tnod[2])->pval(0) , + _mesh.node(_tnod[2])->pval(1) , + _mesh.node(_tnod[2])->pval(2) + } ; + + double _sign; + _sign = geompred::inball2w ( + &_ipos[ 0] , + &_jpos[ 0] , + &_kpos[ 0] , + &_xpos[ 0] ) ; + + return (_sign >= (double)+0.) ; + } + } ; + + class face_ptrs + { +/*------------------------------ face adjacency structure */ + public : + containers::fixed_array < + iptr_type, +2 > _node ; + + iptr_type _tadj ; + iptr_type _fadj ; + } ; + + class face_same + { +/*------------------------------ face indexing comparison */ + public : + __inline_call bool_type operator() ( + face_ptrs const&_fi, + face_ptrs const&_fj + ) const + { + return _fi._node[0] == + _fj._node[0] && + _fi._node[1] == + _fj._node[1] ; + } + } ; + + class face_hash + { +/*------------------------------ face indexing hash-value */ + public : + __inline_call uint32_t operator() ( + face_ptrs const&_ff + ) const + { + return hash::hashword ( + (uint32_t*)&_ff._node[ 0], + +2* sizeof(iptr_type) + / sizeof( uint32_t),13); + } + } ; + + } ; + + + } + +# endif //__LAGUERRE_TRI_EUCLIDEAN_2__ + + + diff --git a/src/libcpp/tessellate/laguerre_tri_pred_3.hpp b/src/libcpp/tessellate/laguerre_tri_pred_3.hpp new file mode 100644 index 0000000..68154bc --- /dev/null +++ b/src/libcpp/tessellate/laguerre_tri_pred_3.hpp @@ -0,0 +1,330 @@ + +/* +------------------------------------------------------------ + * LAG-TRI-EUCLIDEAN-3: kernel for 3-dim. laguerre tri. +------------------------------------------------------------ + * + * 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 2013-2020 + * Darren Engwirda + * d.engwirda@gmail.com + * https://github.com/dengwirda/ + * +------------------------------------------------------------ + */ + +# pragma once + +# ifndef __LAGUERRE_TRI_EUCLIDEAN_3__ +# define __LAGUERRE_TRI_EUCLIDEAN_3__ + + namespace mesh { + +/* +------------------------------------------------------------ + * LAGUERRE-TRI-EUCLIDEAN-3: for lag.-tri. in R^3. +------------------------------------------------------------ + * IPTR-TYPE - signed-integer typedef. + * REAL-TYPE - floating-point typedef. +------------------------------------------------------------ + */ + + template < + typename I, + typename R + > + class laguerre_tri_euclidean_3 + { +/*----------- predicate for laguerre triangulation in R^3 */ + public : + typedef R real_type ; + typedef I iptr_type ; + + iptr_type static constexpr geom_dims = +3 ; + iptr_type static constexpr real_dims = +4 ; + iptr_type static constexpr topo_dims = +3 ; + + public : +/*----------------------- (squared) node-to-node distance */ + __static_call + __inline_call real_type lensqr_kd ( + __const_ptr ( real_type) _ipos, + __const_ptr ( real_type) _jpos + ) + { return ( geometry::lensqr_3d ( + _ipos, + _jpos) ) ; + } + + template class near_pred + { +/*------------------------------------ walk--simplex test */ + public : + __inline_call bool_type operator() ( + mesh_type &_mesh, + __const_ptr ( real_type) _ppos, + real_type &_dmin, + iptr_type &_nmin, + iptr_type _tpos, + iptr_type &_fmin + ) const + { + bool_type _done = true ; + iptr_type _fpos; + iptr_type _fadj; + iptr_type _tadj; + iptr_type _fnod[4] = {0}; + + for(_fpos = 4; _fpos-- != 0; ) + { + /*--------------- check dist. wrt. k-th face apex */ + _tadj = _mesh. + tria(_tpos)->next(_fpos) ; + _fadj = _mesh. + tria(_tpos)->fpos(_fpos) ; + + _tadj = __unflip(_tadj) ; + + if(_tadj == _mesh.null_flag()) + continue ; + + mesh_type::tria_type:: + face_node(_fnod, _fadj, 3, 2) ; + /* + _fnod[0] = _mesh. + tria(_tpos)->node(_fnod[0]); + _fnod[1] = _mesh. + tria(_tpos)->node(_fnod[1]); + _fnod[2] = _mesh. + tria(_tpos)->node(_fnod[2]); + */ + _fnod[3] = _mesh. + tria(_tadj)->node(_fnod[3]); + + iptr_type _apex = _fnod[3] ; + + real_type _dsqr = lensqr_kd ( + _ppos, + &_mesh.node(_fnod[3])->pval(0)); + + if (_dsqr < _dmin) + { + _done = false; + _dmin = _dsqr; + _nmin = _apex; + _fmin = _fpos; + } + } + + return _done ; + } + } ; + + template class walk_pred + { +/*------------------------------------ walk--simplex test */ + public : + __inline_call bool_type operator() ( + mesh_type &_mesh, + __const_ptr ( real_type) _ppos, + iptr_type _tpos, + iptr_type &_fpos + ) const + { + double _xpos[3]; + _xpos[0] = _ppos[0]; + _xpos[1] = _ppos[1]; + _xpos[2] = _ppos[2]; + + for(_fpos = 4; _fpos-- != 0; ) + { + /*--------------- test orientation wrt. k-th face */ + iptr_type _fnod[ 4] ; + mesh_type::tria_type:: + face_node(_fnod, _fpos, 3, 2) ; + _fnod[0] = _mesh. + tria(_tpos)->node(_fnod[0]); + _fnod[1] = _mesh. + tria(_tpos)->node(_fnod[1]); + _fnod[2] = _mesh. + tria(_tpos)->node(_fnod[2]); + + double _ipos[3] = { + _mesh.node(_fnod[0])->pval(0) , + _mesh.node(_fnod[0])->pval(1) , + _mesh.node(_fnod[0])->pval(2) + } ; + double _jpos[3] = { + _mesh.node(_fnod[1])->pval(0) , + _mesh.node(_fnod[1])->pval(1) , + _mesh.node(_fnod[1])->pval(2) + } ; + double _kpos[3] = { + _mesh.node(_fnod[2])->pval(0) , + _mesh.node(_fnod[2])->pval(1) , + _mesh.node(_fnod[2])->pval(2) + } ; + + double _sign; + _sign = geompred::orient3d ( + &_ipos[ 0] , + &_jpos[ 0] , + &_kpos[ 0] , + &_xpos[ 0] ) ; + + if (_sign > (double) +0.00 ) + return false ; + } + + return true ; + } + } ; + + template class circ_pred + { +/*------------------------------------ in-circumball test */ + public : + __const_ptr ( real_type) _ppos ; + + public : + __inline_call circ_pred ( + __const_ptr ( real_type) _psrc + ) : _ppos( _psrc ) { ; } + + __inline_call bool_type operator()( + mesh_type &_mesh, + iptr_type _tpos, + iptr_type//_fpos + ) const + { + iptr_type _tnod[4] = { + _mesh.tria(_tpos )->node(0) , + _mesh.tria(_tpos )->node(1) , + _mesh.tria(_tpos )->node(2) , + _mesh.tria(_tpos )->node(3) + } ; + + double _xpos[4] ; + _xpos[0] = this->_ppos[0] ; + _xpos[1] = this->_ppos[1] ; + _xpos[2] = this->_ppos[2] ; + _xpos[3] = this->_ppos[3] ; + + double _ipos[4] = { + _mesh.node(_tnod[0])->pval(0) , + _mesh.node(_tnod[0])->pval(1) , + _mesh.node(_tnod[0])->pval(2) , + _mesh.node(_tnod[0])->pval(3) + } ; + double _jpos[4] = { + _mesh.node(_tnod[1])->pval(0) , + _mesh.node(_tnod[1])->pval(1) , + _mesh.node(_tnod[1])->pval(2) , + _mesh.node(_tnod[1])->pval(3) + } ; + double _kpos[4] = { + _mesh.node(_tnod[2])->pval(0) , + _mesh.node(_tnod[2])->pval(1) , + _mesh.node(_tnod[2])->pval(2) , + _mesh.node(_tnod[2])->pval(3) + } ; + double _lpos[4] = { + _mesh.node(_tnod[3])->pval(0) , + _mesh.node(_tnod[3])->pval(1) , + _mesh.node(_tnod[3])->pval(2) , + _mesh.node(_tnod[3])->pval(3) + } ; + + double _sign; + _sign = geompred::inball3w ( + &_ipos[ 0] , + &_jpos[ 0] , + &_kpos[ 0] , + &_lpos[ 0] , + &_xpos[ 0] ) ; + + return (_sign <= (double)0.0) ; + } + } ; + + class face_ptrs + { +/*------------------------------ face adjacency structure */ + public : + containers::fixed_array < + iptr_type, +3 > _node ; + + iptr_type _tadj ; + iptr_type _fadj ; + } ; + + class face_same + { +/*------------------------------ face indexing comparison */ + public : + __inline_call bool_type operator() ( + face_ptrs const&_fi, + face_ptrs const&_fj + ) const + { + return _fi._node[0] == + _fj._node[0] && + _fi._node[1] == + _fj._node[1] && + _fi._node[2] == + _fj._node[2] ; + } + } ; + + class face_hash + { +/*------------------------------ face indexing hash-value */ + public : + __inline_call uint32_t operator() ( + face_ptrs const&_ff + ) const + { + return hash::hashword ( + (uint32_t*)&_ff._node[ 0], + +3* sizeof(iptr_type) + / sizeof( uint32_t),13); + } + } ; + + } ; + + +} + +# endif //__LAGUERRE_TRI_EUCLIDEAN_3__ + + + diff --git a/src/libcpp/tessellate/laguerre_tri_pred_4.hpp b/src/libcpp/tessellate/laguerre_tri_pred_4.hpp new file mode 100644 index 0000000..51362b3 --- /dev/null +++ b/src/libcpp/tessellate/laguerre_tri_pred_4.hpp @@ -0,0 +1,363 @@ + +/* +------------------------------------------------------------ + * LAG-TRI-EUCLIDEAN-4: kernel for 4-dim. laguerre tri. +------------------------------------------------------------ + * + * 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 2013-2020 + * Darren Engwirda + * d.engwirda@gmail.com + * https://github.com/dengwirda/ + * +------------------------------------------------------------ + */ + +# pragma once + +# ifndef __LAGUERRE_TRI_EUCLIDEAN_4__ +# define __LAGUERRE_TRI_EUCLIDEAN_4__ + + namespace mesh { + +/* +------------------------------------------------------------ + * LAGUERRE-TRI-EUCLIDEAN-4: for lag.-tri. in R^4. +------------------------------------------------------------ + * IPTR-TYPE - signed-integer typedef. + * REAL-TYPE - floating-point typedef. +------------------------------------------------------------ + */ + + template < + typename I, + typename R + > + class laguerre_tri_euclidean_4 + { +/*----------- predicate for laguerre triangulation in R^4 */ + public : + typedef R real_type ; + typedef I iptr_type ; + + iptr_type static constexpr geom_dims = +4 ; + iptr_type static constexpr real_dims = +5 ; + iptr_type static constexpr topo_dims = +4 ; + + public : +/*----------------------- (squared) node-to-node distance */ + __static_call + __inline_call real_type lensqr_kd ( + __const_ptr ( real_type) _ipos, + __const_ptr ( real_type) _jpos + ) + { return ( geometry::lensqr_4d ( + _ipos, + _jpos) ) ; + } + + template class near_pred + { +/*------------------------------------ walk--simplex test */ + public : + __inline_call bool_type operator() ( + mesh_type &_mesh, + __const_ptr ( real_type) _ppos, + real_type &_dmin, + iptr_type &_nmin, + iptr_type _tpos, + iptr_type &_fmin + ) const + { + bool_type _done = true ; + iptr_type _fpos; + iptr_type _fadj; + iptr_type _tadj; + iptr_type _fnod[5] = {0}; + + for(_fpos = 5; _fpos-- != 0; ) + { + /*--------------- check dist. wrt. k-th face apex */ + _tadj = _mesh. + tria(_tpos)->next(_fpos) ; + _fadj = _mesh. + tria(_tpos)->fpos(_fpos) ; + + _tadj = __unflip(_tadj) ; + + if(_tadj == _mesh.null_flag()) + continue ; + + mesh_type::tria_type:: + face_node(_fnod, _fadj, 4, 3) ; + /* + _fnod[0] = _mesh. + tria(_tpos)->node(_fnod[0]); + _fnod[1] = _mesh. + tria(_tpos)->node(_fnod[1]); + _fnod[2] = _mesh. + tria(_tpos)->node(_fnod[2]); + _fnod[3] = _mesh. + tria(_tpos)->node(_fnod[3]); + */ + _fnod[4] = _mesh. + tria(_tadj)->node(_fnod[4]); + + iptr_type _apex = _fnod[4] ; + + real_type _dsqr = lensqr_kd ( + _ppos, + &_mesh.node(_fnod[4])->pval(0)); + + if (_dsqr < _dmin) + { + _done = false; + _dmin = _dsqr; + _nmin = _apex; + _fmin = _fpos; + } + } + + return _done ; + } + } ; + + template class walk_pred + { +/*------------------------------------ walk--simplex test */ + public : + __inline_call bool_type operator() ( + mesh_type &_mesh, + __const_ptr ( real_type) _ppos, + iptr_type _tpos, + iptr_type &_fpos + ) const + { + double _xpos[4]; + _xpos[0] = _ppos[0]; + _xpos[1] = _ppos[1]; + _xpos[2] = _ppos[2]; + _xpos[3] = _ppos[3]; + + for(_fpos = 5; _fpos-- != 0; ) + { + /*--------------- test orientation wrt. k-th face */ + iptr_type _fnod[ 5] ; + mesh_type::tria_type:: + face_node(_fnod, _fpos, 4, 3) ; + _fnod[0] = _mesh. + tria(_tpos)->node(_fnod[0]); + _fnod[1] = _mesh. + tria(_tpos)->node(_fnod[1]); + _fnod[2] = _mesh. + tria(_tpos)->node(_fnod[2]); + _fnod[3] = _mesh. + tria(_tpos)->node(_fnod[3]); + + double _ipos[4] = { + _mesh.node(_fnod[0])->pval(0) , + _mesh.node(_fnod[0])->pval(1) , + _mesh.node(_fnod[0])->pval(2) , + _mesh.node(_fnod[0])->pval(3) + } ; + double _jpos[4] = { + _mesh.node(_fnod[1])->pval(0) , + _mesh.node(_fnod[1])->pval(1) , + _mesh.node(_fnod[1])->pval(2) , + _mesh.node(_fnod[1])->pval(3) + } ; + double _kpos[4] = { + _mesh.node(_fnod[2])->pval(0) , + _mesh.node(_fnod[2])->pval(1) , + _mesh.node(_fnod[2])->pval(2) , + _mesh.node(_fnod[2])->pval(3) + } ; + double _lpos[4] = { + _mesh.node(_fnod[3])->pval(0) , + _mesh.node(_fnod[3])->pval(1) , + _mesh.node(_fnod[3])->pval(2) , + _mesh.node(_fnod[3])->pval(3) + } ; + + double _sign; + _sign = geompred::orient4d ( + &_ipos[ 0] , + &_jpos[ 0] , + &_kpos[ 0] , + &_lpos[ 0] , + &_xpos[ 0] ) ; + + if (_sign > (double) +0.00 ) + return false ; + } + + return true ; + } + } ; + + template class circ_pred + { +/*------------------------------------ in-circumball test */ + public : + __const_ptr ( real_type) _ppos ; + + public : + __inline_call circ_pred ( + __const_ptr ( real_type) _psrc + ) : _ppos( _psrc ) { ; } + + __inline_call bool_type operator()( + mesh_type &_mesh, + iptr_type _tpos, + iptr_type//_fpos + ) const + { + iptr_type _tnod[5] = { + _mesh.tria(_tpos )->node(0) , + _mesh.tria(_tpos )->node(1) , + _mesh.tria(_tpos )->node(2) , + _mesh.tria(_tpos )->node(3) , + _mesh.tria(_tpos )->node(4) + } ; + + double _xpos[4] ; + _xpos[0] = this->_ppos[0] ; + _xpos[1] = this->_ppos[1] ; + _xpos[2] = this->_ppos[2] ; + _xpos[3] = this->_ppos[3] ; + + double _ipos[4] = { + _mesh.node(_tnod[0])->pval(0) , + _mesh.node(_tnod[0])->pval(1) , + _mesh.node(_tnod[0])->pval(2) , + _mesh.node(_tnod[0])->pval(3) + } ; + double _jpos[4] = { + _mesh.node(_tnod[1])->pval(0) , + _mesh.node(_tnod[1])->pval(1) , + _mesh.node(_tnod[1])->pval(2) , + _mesh.node(_tnod[1])->pval(3) + } ; + double _kpos[4] = { + _mesh.node(_tnod[2])->pval(0) , + _mesh.node(_tnod[2])->pval(1) , + _mesh.node(_tnod[2])->pval(2) , + _mesh.node(_tnod[2])->pval(3) + } ; + double _lpos[4] = { + _mesh.node(_tnod[3])->pval(0) , + _mesh.node(_tnod[3])->pval(1) , + _mesh.node(_tnod[3])->pval(2) , + _mesh.node(_tnod[3])->pval(3) + } ; + double _mpos[4] = { + _mesh.node(_tnod[4])->pval(0) , + _mesh.node(_tnod[4])->pval(1) , + _mesh.node(_tnod[4])->pval(2) , + _mesh.node(_tnod[4])->pval(3) + } ; + + __unreferenced(_xpos); + __unreferenced(_ipos); + __unreferenced(_jpos); + __unreferenced(_kpos); + __unreferenced(_lpos); + __unreferenced(_mpos); + + double _sign = 0.; + /* + _sign = geompred::inball4w ( + &_ipos[ 0] , + &_jpos[ 0] , + &_kpos[ 0] , + &_lpos[ 0] , + &_mpos[ 0] , + &_xpos[ 0] ) ; + */ + return (_sign <= (double)0.0) ; + } + } ; + + class face_ptrs + { +/*------------------------------ face adjacency structure */ + public : + containers::fixed_array < + iptr_type, +4 > _node ; + + iptr_type _tadj ; + iptr_type _fadj ; + } ; + + class face_same + { +/*------------------------------ face indexing comparison */ + public : + __inline_call bool_type operator() ( + face_ptrs const&_fi, + face_ptrs const&_fj + ) const + { + return _fi._node[0] == + _fj._node[0] && + _fi._node[1] == + _fj._node[1] && + _fi._node[2] == + _fj._node[2] && + _fi._node[3] == + _fj._node[3] ; + } + } ; + + class face_hash + { +/*------------------------------ face indexing hash-value */ + public : + __inline_call uint32_t operator() ( + face_ptrs const&_ff + ) const + { + return hash::hashword ( + (uint32_t*)&_ff._node[ 0], + +4* sizeof(iptr_type) + / sizeof( uint32_t),13); + } + } ; + + } ; + + +} + +# endif //__LAGUERRE_TRI_EUCLIDEAN_4__ + + + diff --git a/src/libcpp/libparse.hpp b/src/libcpp/textutil.hpp similarity index 97% rename from src/libcpp/libparse.hpp rename to src/libcpp/textutil.hpp index 0d5a1ba..406a7e5 100644 --- a/src/libcpp/libparse.hpp +++ b/src/libcpp/textutil.hpp @@ -1,7 +1,7 @@ /* -------------------------------------------------------- - * LIBPARSE: utilities for string/file parsing. + * TEXTUTIL: utilities for string/file parsing. -------------------------------------------------------- * * This program may be freely redistributed under the @@ -35,7 +35,7 @@ * * Copyright 2013-2017 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- @@ -43,8 +43,8 @@ # pragma once -# ifndef __LIBPARSE__ -# define __LIBPARSE__ +# ifndef __TEXTUTIL__ +# define __TEXTUTIL__ /* -------------------------------------------------------- @@ -221,7 +221,7 @@ } -# endif//__LIBPARSE__ +# endif//__TEXTUTIL__ diff --git a/src/libcpp/tree_mesh/tree_mesh_2.hpp b/src/libcpp/tree_mesh/tree_mesh_2.hpp index 98592ee..1b399be 100644 --- a/src/libcpp/tree_mesh/tree_mesh_2.hpp +++ b/src/libcpp/tree_mesh/tree_mesh_2.hpp @@ -35,7 +35,7 @@ * * Copyright 2013-2019 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- @@ -138,6 +138,8 @@ tree_stat _tcpu ; + __unreferenced(_ttic) ; + __unreferenced(_ttoc) ; __unreferenced(_geom) ; __unreferenced(_init) ; diff --git a/src/libcpp/tree_mesh/tree_timers.hpp b/src/libcpp/tree_mesh/tree_timers.hpp index dbad604..2f53e19 100644 --- a/src/libcpp/tree_mesh/tree_timers.hpp +++ b/src/libcpp/tree_mesh/tree_timers.hpp @@ -35,7 +35,7 @@ * * Copyright 2013-2019 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- diff --git a/src/libcpp/treemesh.hpp b/src/libcpp/treemesh.hpp index e02bd24..f6deccf 100644 --- a/src/libcpp/treemesh.hpp +++ b/src/libcpp/treemesh.hpp @@ -35,7 +35,7 @@ * * Copyright 2013-2019 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * ------------------------------------------------------------ diff --git a/src/libcpp/useropts.hpp b/src/libcpp/useropts.hpp index 756ccb3..2801c2d 100644 --- a/src/libcpp/useropts.hpp +++ b/src/libcpp/useropts.hpp @@ -35,7 +35,7 @@ * * Copyright 2013-2019 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * ------------------------------------------------------------ diff --git a/src/liblib/init_jig_t.hpp b/src/liblib/init_jig_t.hpp index b94e7f7..82360cb 100644 --- a/src/liblib/init_jig_t.hpp +++ b/src/liblib/init_jig_t.hpp @@ -35,7 +35,7 @@ * * Copyright 2013-2019 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- diff --git a/src/liblib/init_msh_t.hpp b/src/liblib/init_msh_t.hpp index 2024ba2..4cdebb6 100644 --- a/src/liblib/init_msh_t.hpp +++ b/src/liblib/init_msh_t.hpp @@ -31,11 +31,11 @@ * -------------------------------------------------------- * - * Last updated: 28 June, 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/ * -------------------------------------------------------- @@ -98,6 +98,12 @@ _mesh->_bound._size = +0 ; _mesh->_bound._data = nullptr ; + _mesh->_seed2._size = +0 ; + _mesh->_seed2._data = nullptr ; + + _mesh->_seed3._size = +0 ; + _mesh->_seed3._data = nullptr ; + _mesh->_value._size = +0 ; _mesh->_value._data = nullptr ; @@ -135,47 +141,29 @@ { _mesh->_flags = JIGSAW_NULL_FLAG ; - jigsaw_free_vert2( - &_mesh->_vert2) ; - jigsaw_free_vert3( - &_mesh->_vert3) ; - jigsaw_free_reals( - &_mesh->_power) ; - - jigsaw_free_reals( - &_mesh->_radii) ; - - jigsaw_free_edge2( - &_mesh->_edge2) ; - - jigsaw_free_tria3( - &_mesh->_tria3) ; - jigsaw_free_quad4( - &_mesh->_quad4) ; - - jigsaw_free_tria4( - &_mesh->_tria4) ; - jigsaw_free_hexa8( - &_mesh->_hexa8) ; - jigsaw_free_wedg6( - &_mesh->_wedg6) ; - jigsaw_free_pyra5( - &_mesh->_pyra5) ; - - jigsaw_free_bound( - &_mesh->_bound) ; - - jigsaw_free_reals( - &_mesh->_xgrid) ; - jigsaw_free_reals( - &_mesh->_ygrid) ; - jigsaw_free_reals( - &_mesh->_zgrid) ; - - jigsaw_free_reals( - &_mesh->_value) ; - jigsaw_free_reals( - &_mesh->_slope) ; + jigsaw_free_vert2(&_mesh->_vert2); + jigsaw_free_vert3(&_mesh->_vert3); + jigsaw_free_reals(&_mesh->_power); + + jigsaw_free_reals(&_mesh->_radii); + + jigsaw_free_edge2(&_mesh->_edge2); + jigsaw_free_tria3(&_mesh->_tria3); + jigsaw_free_quad4(&_mesh->_quad4); + jigsaw_free_tria4(&_mesh->_tria4); + jigsaw_free_hexa8(&_mesh->_hexa8); + jigsaw_free_wedg6(&_mesh->_wedg6); + jigsaw_free_pyra5(&_mesh->_pyra5); + + jigsaw_free_bound(&_mesh->_bound); + + jigsaw_free_reals(&_mesh->_xgrid); + jigsaw_free_reals(&_mesh->_ygrid); + jigsaw_free_reals(&_mesh->_zgrid); + + jigsaw_free_reals(&_mesh->_value); + jigsaw_free_reals(&_mesh->_slope); + } } diff --git a/src/liblib/load_jig_t.hpp b/src/liblib/load_jig_t.hpp index e5d7f2f..bf74c5a 100644 --- a/src/liblib/load_jig_t.hpp +++ b/src/liblib/load_jig_t.hpp @@ -35,7 +35,7 @@ * * Copyright 2013-2019 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- diff --git a/src/liblib/load_msh_t.hpp b/src/liblib/load_msh_t.hpp index 31db039..381271b 100644 --- a/src/liblib/load_msh_t.hpp +++ b/src/liblib/load_msh_t.hpp @@ -31,11 +31,11 @@ * -------------------------------------------------------- * - * Last updated: 1 October, 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/ * -------------------------------------------------------- @@ -225,6 +225,88 @@ this->_errv =__invalid_argument ; } + } + } + /*-------------------------------- open SEEDS section */ + __normal_call void_type open_seeds ( + std:: size_t _nrow + ) + { + if (this->_kind == + jmsh_kind:: euclidean_mesh) + { + + if (this->_ndim == +2) + jigsaw_alloc_vert2 ( + &this->_jmsh->_seed2, _nrow) ; + else + if (this->_ndim == +3) + jigsaw_alloc_vert3 ( + &this->_jmsh->_seed3, _nrow) ; + + } + else + if (this->_kind == + jmsh_kind:: ellipsoid_mesh) + { + + if (this->_ndim == +2) + jigsaw_alloc_vert2 ( + &this->_jmsh->_seed2, _nrow) ; + else + if (this->_ndim == +3) + jigsaw_alloc_vert3 ( + &this->_jmsh->_seed3, _nrow) ; + + } + } + /*-------------------------------- read SEEDS section */ + __normal_call void_type push_seeds ( + std:: size_t _ipos , + double *_pval , + std::int32_t _itag + ) + { + if (this->_ndim == +2 ) + { + + if (_ipos < this->_jmsh->_seed2._size) + { + this->_jmsh->_seed2._data[_ipos]. + _ppos[0] = _pval[0] ; + this->_jmsh->_seed2._data[_ipos]. + _ppos[1] = _pval[1] ; + + this->_jmsh->_seed2. + _data[_ipos]._itag = _itag ; + } + else + { + this->_errv =__invalid_argument ; + } + + } + else + if (this->_ndim == +3 ) + { + + if (_ipos < this->_jmsh->_seed3._size) + { + this->_jmsh->_seed3._data[_ipos]. + _ppos[0] = _pval[0] ; + this->_jmsh->_seed3._data[_ipos]. + _ppos[1] = _pval[1] ; + this->_jmsh->_seed3._data[_ipos]. + _ppos[2] = _pval[2] ; + + this->_jmsh->_seed3. + _data[_ipos]._itag = _itag ; + } + else + { + this->_errv =__invalid_argument ; + } + } } /*-------------------------------- read POWER section */ diff --git a/src/liblib/save_jig_t.hpp b/src/liblib/save_jig_t.hpp index e9ac9f3..8c51609 100644 --- a/src/liblib/save_jig_t.hpp +++ b/src/liblib/save_jig_t.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/ * -------------------------------------------------------- @@ -190,6 +190,11 @@ JIGSAW_KERN_CVT_DQDX) _file << "OPTM_KERN = " << "CVT+DQDX\n" ; + else + if (_jcfg->_optm_kern == + JIGSAW_KERN_H95_DQDX) + _file << "OPTM_KERN = " + << "H95+DQDX\n" ; /*--------------------------------- OPTM keywords */ _file << "OPTM_ITER = " << diff --git a/src/liblib/save_msh_t.hpp b/src/liblib/save_msh_t.hpp index 6aa0b54..11a1470 100644 --- a/src/liblib/save_msh_t.hpp +++ b/src/liblib/save_msh_t.hpp @@ -35,7 +35,7 @@ * * Copyright 2013-2018 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- diff --git a/src/marche.hpp b/src/marche.hpp index c233c9a..291d0dd 100644 --- a/src/marche.hpp +++ b/src/marche.hpp @@ -14,11 +14,11 @@ * MARCHE: "fast-marching" eikonal equation solver. -------------------------------------------------------- * - * Last updated: 28 June, 2019 + * Last updated: 01 March, 2020 * - * Copyright 2013 -- 2019 + * Copyright 2013 -- 2020 * Darren Engwirda - * darren.engwirda@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda * -------------------------------------------------------- @@ -109,6 +109,9 @@ __unreferenced(_time) ; # endif//__use_timers + /*--------------------------------- init. geo. kernel */ + mp_float::exactinit() ; + /*--------------------------------- setup *.JLOG data */ if (_jjig != nullptr ) { @@ -293,6 +296,9 @@ __unreferenced(_time) ; # endif//__use_timers + /*--------------------------------- init. geo. kernel */ + mp_float::exactinit() ; + /*-------------------------- find *.JFCG file in args */ iptr_type _retv = -1 ; jcfg_data _jcfg ; @@ -327,9 +333,7 @@ break ; } - std::string _path ; - std::string _name ; - std::string _fext ; + std::string _path , _name , _fext ; file_part ( _ssrc , _path , _name , _fext ) ; diff --git a/src/msh_copy.hpp b/src/msh_copy.hpp index 2d2549d..a24d4ac 100644 --- a/src/msh_copy.hpp +++ b/src/msh_copy.hpp @@ -31,11 +31,11 @@ * -------------------------------------------------------- * - * Last updated: 05 July, 2019 + * Last updated: 10 Sept., 2020 * - * Copyright 2013-2019 + * Copyright 2013-2020 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- @@ -58,7 +58,6 @@ __normal_call iptr_type copy_mesh ( jcfg_data &_jcfg , jlog_data &_jlog , - rdel_data &_rdel , mesh_data &_mesh ) { @@ -67,20 +66,17 @@ __unreferenced(_jcfg) ; __unreferenced(_jlog) ; - if (_rdel._ndim == +2 && - _rdel._kind == + if (_mesh._ndim == +2 && + _mesh._kind == jmsh_kind::euclidean_mesh) { /*---------------------------------- copy 2-dim. mesh */ _mesh._euclidean_mesh_2d._mesh. - clear(containers::loose_alloc) ; - - _mesh._kind = _rdel._kind ; - _mesh._ndim = _rdel._ndim ; + clear(containers::tight_alloc) ; - for (auto _iter = _rdel. + for (auto _iter = _mesh. _euclidean_rdel_2d._tria._nset.head() ; - _iter != _rdel. + _iter != _mesh. _euclidean_rdel_2d._tria._nset.tend() ; ++_iter ) { @@ -96,6 +92,7 @@ _node.hidx () = _iter->idxh () ; + _node.itag () = (iptr_type)+0; _node.fdim () = _iter->fdim () ; _node.feat () = _iter->feat () ; @@ -104,12 +101,12 @@ } } - _rdel._euclidean_rdel_2d._tria. + _mesh._euclidean_rdel_2d._tria. clear(containers::tight_alloc) ; - for (auto _iter = _rdel. + for (auto _iter = _mesh. _euclidean_rdel_2d._eset._lptr.head() ; - _iter != _rdel. + _iter != _mesh. _euclidean_rdel_2d._eset._lptr.tend() ; ++_iter ) { @@ -136,12 +133,12 @@ } } - _rdel._euclidean_rdel_2d._eset. + _mesh._euclidean_rdel_2d._eset. clear(containers::tight_alloc) ; - for (auto _iter = _rdel. + for (auto _iter = _mesh. _euclidean_rdel_2d._tset._lptr.head() ; - _iter != _rdel. + _iter != _mesh. _euclidean_rdel_2d._tset._lptr.tend() ; ++_iter ) { @@ -170,10 +167,10 @@ } } - _rdel._euclidean_rdel_2d._tset. + _mesh._euclidean_rdel_2d._tset. clear(containers::tight_alloc) ; - _rdel._euclidean_rdel_2d. + _mesh._euclidean_rdel_2d. clear(containers::tight_alloc) ; _mesh._euclidean_mesh_2d. @@ -181,20 +178,17 @@ } else - if (_rdel._ndim == +3 && - _rdel._kind == + if (_mesh._ndim == +3 && + _mesh._kind == jmsh_kind::euclidean_mesh) { /*---------------------------------- copy 3-dim. mesh */ _mesh._euclidean_mesh_3d._mesh. - clear(containers::loose_alloc) ; - - _mesh._kind = _rdel._kind ; - _mesh._ndim = _rdel._ndim ; + clear(containers::tight_alloc) ; - for (auto _iter = _rdel. + for (auto _iter = _mesh. _euclidean_rdel_3d._tria._nset.head() ; - _iter != _rdel. + _iter != _mesh. _euclidean_rdel_3d._tria._nset.tend() ; ++_iter ) { @@ -211,6 +205,7 @@ _node.hidx () = _iter->idxh () ; + _node.itag () = (iptr_type)+0; _node.fdim () = _iter->fdim () ; _node.feat () = _iter->feat () ; @@ -219,12 +214,12 @@ } } - _rdel._euclidean_rdel_3d._tria. + _mesh._euclidean_rdel_3d._tria. clear(containers::tight_alloc) ; - for (auto _iter = _rdel. + for (auto _iter = _mesh. _euclidean_rdel_3d._eset._lptr.head() ; - _iter != _rdel. + _iter != _mesh. _euclidean_rdel_3d._eset._lptr.tend() ; ++_iter ) { @@ -251,12 +246,12 @@ } } - _rdel._euclidean_rdel_3d._eset. + _mesh._euclidean_rdel_3d._eset. clear(containers::tight_alloc) ; - for (auto _iter = _rdel. + for (auto _iter = _mesh. _euclidean_rdel_3d._fset._lptr.head() ; - _iter != _rdel. + _iter != _mesh. _euclidean_rdel_3d._fset._lptr.tend() ; ++_iter ) { @@ -285,12 +280,12 @@ } } - _rdel._euclidean_rdel_3d._fset. + _mesh._euclidean_rdel_3d._fset. clear(containers::tight_alloc) ; - for (auto _iter = _rdel. + for (auto _iter = _mesh. _euclidean_rdel_3d._tset._lptr.head() ; - _iter != _rdel. + _iter != _mesh. _euclidean_rdel_3d._tset._lptr.tend() ; ++_iter ) { @@ -321,10 +316,10 @@ } } - _rdel._euclidean_rdel_3d._tset. + _mesh._euclidean_rdel_3d._tset. clear(containers::tight_alloc) ; - _rdel._euclidean_rdel_3d. + _mesh._euclidean_rdel_3d. clear(containers::tight_alloc) ; _mesh._euclidean_mesh_3d. diff --git a/src/msh_init.hpp b/src/msh_init.hpp index 04d58fe..685a4cd 100644 --- a/src/msh_init.hpp +++ b/src/msh_init.hpp @@ -31,11 +31,11 @@ * -------------------------------------------------------- * - * Last updated: 21 August, 2018 + * Last updated: 27 July, 2020 * - * Copyright 2013-2018 + * Copyright 2013-2020 * Darren Engwirda - * de2363@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda/ * -------------------------------------------------------- @@ -58,6 +58,7 @@ __normal_call iptr_type init_mesh ( jcfg_data &_jcfg , jlog_data &_jlog , + geom_data &_geom , mesh_data &_mesh ) { @@ -72,13 +73,22 @@ { /*--------------------------------- euclidean-mesh-2d */ for (auto _iter = _mesh. - _euclidean_mesh_2d._mesh._set1.head() ; + _euclidean_mesh_2d._mesh.node().head() ; _iter != _mesh. - _euclidean_mesh_2d._mesh._set1.tend() ; + _euclidean_mesh_2d._mesh.node().tend() ; ++_iter ) { if (_iter->mark() < 0) continue ; + if (_iter->itag () > +0) + if (_geom._kind == + jmsh_kind::euclidean_mesh) + _geom. + _euclidean_mesh_2d.projector ( + &_iter->pval(0) , + _iter->itag () , + &_iter->pval(0) ) ; + if (_iter->feat() == mesh::null_feat) _iter->fdim() = 2 ; @@ -97,15 +107,41 @@ } for (auto _iter = _mesh. - _euclidean_mesh_2d._mesh._set3.head() ; + _euclidean_mesh_2d._mesh.tri3().head() ; + _iter != _mesh. + _euclidean_mesh_2d._mesh.tri3().tend() ; + ++_iter ) + { + if (_iter->mark() < 0) continue ; + + auto _head = _mesh. + _euclidean_mesh_2d._mesh.node().head() ; + + auto _inod = + _head+_iter->node( +0) ; + auto _jnod = + _head+_iter->node( +1) ; + auto _knod = + _head+_iter->node( +2) ; + + if (_inod->fdim() > 2) + _inod->fdim() = 2 ; + if (_jnod->fdim() > 2) + _jnod->fdim() = 2 ; + if (_knod->fdim() > 2) + _knod->fdim() = 2 ; + } + + for (auto _iter = _mesh. + _euclidean_mesh_2d._mesh.quad().head() ; _iter != _mesh. - _euclidean_mesh_2d._mesh._set3.tend() ; + _euclidean_mesh_2d._mesh.quad().tend() ; ++_iter ) { if (_iter->mark() < 0) continue ; auto _head = _mesh. - _euclidean_mesh_2d._mesh._set1.head() ; + _euclidean_mesh_2d._mesh.node().head() ; auto _inod = _head+_iter->node( +0) ; @@ -113,6 +149,8 @@ _head+_iter->node( +1) ; auto _knod = _head+_iter->node( +2) ; + auto _lnod = + _head+_iter->node( +3) ; if (_inod->fdim() > 2) _inod->fdim() = 2 ; @@ -120,18 +158,20 @@ _jnod->fdim() = 2 ; if (_knod->fdim() > 2) _knod->fdim() = 2 ; + if (_lnod->fdim() > 2) + _lnod->fdim() = 2 ; } for (auto _iter = _mesh. - _euclidean_mesh_2d._mesh._set2.head() ; + _euclidean_mesh_2d._mesh.edge().head() ; _iter != _mesh. - _euclidean_mesh_2d._mesh._set2.tend() ; + _euclidean_mesh_2d._mesh.edge().tend() ; ++_iter ) { if (_iter->mark() < 0) continue ; auto _head = _mesh. - _euclidean_mesh_2d._mesh._set1.head() ; + _euclidean_mesh_2d._mesh.node().head() ; auto _inod = _head+_iter->node( +0) ; @@ -151,13 +191,31 @@ { /*--------------------------------- euclidean-mesh-3d */ for (auto _iter = _mesh. - _euclidean_mesh_3d._mesh._set1.head() ; + _euclidean_mesh_3d._mesh.node().head() ; _iter != _mesh. - _euclidean_mesh_3d._mesh._set1.tend() ; + _euclidean_mesh_3d._mesh.node().tend() ; ++_iter ) { if (_iter->mark() < 0) continue ; + if (_iter->itag () > +0) + if (_geom._kind == + jmsh_kind::euclidean_mesh) + _geom. + _euclidean_mesh_3d.projector ( + &_iter->pval(0) , + _iter->itag () , + &_iter->pval(0) ) ; + + if (_iter->itag () > +0) + if (_geom._kind == + jmsh_kind::ellipsoid_mesh) + _geom. + _ellipsoid_mesh_3d.projector ( + &_iter->pval(0) , + _iter->itag () , + &_iter->pval(0) ) ; + if (_iter->feat() == mesh::null_feat) _iter->fdim() = 3 ; @@ -176,15 +234,15 @@ } for (auto _iter = _mesh. - _euclidean_mesh_3d._mesh._set4.head() ; + _euclidean_mesh_3d._mesh.tri4().head() ; _iter != _mesh. - _euclidean_mesh_3d._mesh._set4.tend() ; + _euclidean_mesh_3d._mesh.tri4().tend() ; ++_iter ) { if (_iter->mark() < 0) continue ; auto _head = _mesh. - _euclidean_mesh_3d._mesh._set1.head() ; + _euclidean_mesh_3d._mesh.node().head() ; auto _inod = _head+_iter->node( +0) ; @@ -206,15 +264,41 @@ } for (auto _iter = _mesh. - _euclidean_mesh_3d._mesh._set3.head() ; + _euclidean_mesh_3d._mesh.tri3().head() ; + _iter != _mesh. + _euclidean_mesh_3d._mesh.tri3().tend() ; + ++_iter ) + { + if (_iter->mark() < 0) continue ; + + auto _head = _mesh. + _euclidean_mesh_3d._mesh.node().head() ; + + auto _inod = + _head+_iter->node( +0) ; + auto _jnod = + _head+_iter->node( +1) ; + auto _knod = + _head+_iter->node( +2) ; + + if (_inod->fdim() > 2) + _inod->fdim() = 2 ; + if (_jnod->fdim() > 2) + _jnod->fdim() = 2 ; + if (_knod->fdim() > 2) + _knod->fdim() = 2 ; + } + + for (auto _iter = _mesh. + _euclidean_mesh_3d._mesh.quad().head() ; _iter != _mesh. - _euclidean_mesh_3d._mesh._set3.tend() ; + _euclidean_mesh_3d._mesh.quad().tend() ; ++_iter ) { if (_iter->mark() < 0) continue ; auto _head = _mesh. - _euclidean_mesh_3d._mesh._set1.head() ; + _euclidean_mesh_3d._mesh.node().head() ; auto _inod = _head+_iter->node( +0) ; @@ -222,6 +306,8 @@ _head+_iter->node( +1) ; auto _knod = _head+_iter->node( +2) ; + auto _lnod = + _head+_iter->node( +3) ; if (_inod->fdim() > 2) _inod->fdim() = 2 ; @@ -229,18 +315,20 @@ _jnod->fdim() = 2 ; if (_knod->fdim() > 2) _knod->fdim() = 2 ; + if (_lnod->fdim() > 2) + _lnod->fdim() = 2 ; } for (auto _iter = _mesh. - _euclidean_mesh_3d._mesh._set2.head() ; + _euclidean_mesh_3d._mesh.edge().head() ; _iter != _mesh. - _euclidean_mesh_3d._mesh._set2.tend() ; + _euclidean_mesh_3d._mesh.edge().tend() ; ++_iter ) { if (_iter->mark() < 0) continue ; auto _head = _mesh. - _euclidean_mesh_3d._mesh._set1.head() ; + _euclidean_mesh_3d._mesh.node().head() ; auto _inod = _head+_iter->node( +0) ; diff --git a/src/msh_read.hpp b/src/msh_read.hpp index 51f80e0..415ef0f 100644 --- a/src/msh_read.hpp +++ b/src/msh_read.hpp @@ -31,11 +31,11 @@ * -------------------------------------------------------- * - * Last updated: 28 June, 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/ * -------------------------------------------------------- @@ -68,6 +68,14 @@ double * /*_pval*/, std::int32_t /*_itag*/ ) { } + __normal_call void_type open_seeds ( + std:: size_t /*_nrow*/ + ) { } + __normal_call void_type push_seeds ( + std:: size_t /*_irow*/, + double * /*_pval*/, + std::int32_t /*_itag*/ + ) { } __normal_call void_type open_power ( std:: size_t /*_nrow*/, std:: size_t /*_npwr*/ @@ -424,6 +432,86 @@ } } + /* + -------------------------------------------------------- + * READ-SEEDS: read SEEDS data section + -------------------------------------------------------- + */ + + template < + typename dest_type + > + __normal_call void_type read_seeds ( + std::ifstream&_ffid , + string_tokens&_stok , + dest_type &_dest + ) + { + containers:: + array< std::string > _tstr ; + + /*----------------------------------------- read head */ + std:: size_t _nrow = +0; + std:: size_t _irow = +0; + if (_stok.count() == +2) + { + _nrow = std::stol(_stok[1]); + } + else + { + this->_errs. + push_tail("Invalid SEEDS!"); + } + + _dest.open_seeds(_nrow); + + /*----------------------------------------- read data */ + std::string _line; + while (std::getline(_ffid, _line)) + { + _tstr.clear(); + + try + { + find_toks (_line, ";", _tstr); + + if (_tstr.count() == this->_ndim+1) + { + std:: size_t static + constexpr _VMAX = +16; + + double _pval[_VMAX]; + std::int32_t _itag ; + for (auto _ipos = this->_ndim ; + _ipos-- != +0; ) + { + _pval[_ipos] = + std::stod(_tstr[_ipos]); + } + + _itag = std::stol( + _tstr[this->_ndim]); + + _dest.push_seeds ( + _irow, _pval, _itag); + } + else + { + this->_errs.push_tail(_line); + } + + } + catch (...) + { + this->_errs.push_tail(_line); + } + + _irow += +1 ; + + if (--_nrow == +0) break ; + } + } + /* -------------------------------------------------------- * READ-COORD: read COORD data section @@ -1406,6 +1494,12 @@ _dest) ; } else + if (_stok[0] == "SEEDS") + { + read_seeds(_ffid, _stok, + _dest) ; + } + else if (_stok[0] == "COORD") { read_coord(_ffid, _stok, diff --git a/src/msh_save.hpp b/src/msh_save.hpp index affdde1..2f4e38d 100644 --- a/src/msh_save.hpp +++ b/src/msh_save.hpp @@ -31,11 +31,11 @@ * -------------------------------------------------------- * - * Last updated: 1 October, 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/ * -------------------------------------------------------- @@ -58,7 +58,7 @@ __normal_call iptr_type save_rdel ( jcfg_data &_jcfg , jlog_data &_jlog , - rdel_data &_rdel + mesh_data &_rdel ) { iptr_type _errv = __no_error ; @@ -69,11 +69,9 @@ { containers::array _nmap; - std::ofstream _file ; + std::ofstream _file; - std::string _path ; - std::string _name ; - std::string _fext ; + std::string _path, _name, _fext; file_part( _jcfg._mesh_file, _path, _name, _fext); @@ -541,7 +539,7 @@ __normal_call iptr_type save_rdel ( jcfg_data &_jcfg , jlog_data &_jlog , - rdel_data &_rdel , + mesh_data &_rdel , jigsaw_msh_t &_mmsh ) { @@ -1008,7 +1006,7 @@ __normal_call iptr_type save_tria ( jcfg_data &_jcfg , jlog_data &_jlog , - rdel_data &_rdel + mesh_data &_rdel ) { iptr_type _errv = __no_error ; @@ -1019,11 +1017,9 @@ { containers::array _nmap; - std::ofstream _file ; + std::ofstream _file; - std::string _path ; - std::string _name ; - std::string _fext ; + std::string _path, _name, _fext; file_part( _jcfg._tria_file, _path, _name, _fext); @@ -1254,7 +1250,7 @@ __normal_call iptr_type save_tria ( jcfg_data &_jcfg , jlog_data &_jlog , - rdel_data &_rdel , + mesh_data &_rdel , jigsaw_msh_t &_mmsh ) { @@ -1547,11 +1543,9 @@ { containers::array _nmap; - std::ofstream _file ; + std::ofstream _file; - std::string _path ; - std::string _name ; - std::string _fext ; + std::string _path, _name, _fext; file_part( _jcfg._mesh_file, _path, _name, _fext); @@ -1579,17 +1573,33 @@ /*------------ index mapping for active nodes */ _nmap.set_count(_mesh. - _euclidean_mesh_2d._mesh._set1.count() , - containers::tight_alloc, -1) ; + _euclidean_mesh_2d._mesh.node().count() , + containers::tight_alloc, -1) ; - iptr_type _nnum = +0 ; - iptr_type _enum = +0 ; - iptr_type _tnum = +0 ; + iptr_type _nnN1 = +0 ; + iptr_type _nnE2 = +0 ; + iptr_type _nnT3 = +0 ; + iptr_type _nnQ4 = +0 ; + + for (auto _iter = _mesh. + _euclidean_mesh_2d._mesh.edge().head() ; + _iter != _mesh. + _euclidean_mesh_2d._mesh.edge().tend() ; + ++_iter ) + { + if (_iter->mark() >= +0 && + _iter->self() >= +1 ) + { + _nmap[_iter->node(0)] = +1 ; + _nmap[_iter->node(1)] = +1 ; + _nnE2 += +1 ; + } + } for (auto _iter = _mesh. - _euclidean_mesh_2d._mesh._set2.head() ; + _euclidean_mesh_2d._mesh.tri3().head() ; _iter != _mesh. - _euclidean_mesh_2d._mesh._set2.tend() ; + _euclidean_mesh_2d._mesh.tri3().tend() ; ++_iter ) { if (_iter->mark() >= +0 && @@ -1597,14 +1607,15 @@ { _nmap[_iter->node(0)] = +1 ; _nmap[_iter->node(1)] = +1 ; - _enum += +1 ; + _nmap[_iter->node(2)] = +1 ; + _nnT3 += +1 ; } } for (auto _iter = _mesh. - _euclidean_mesh_2d._mesh._set3.head() ; + _euclidean_mesh_2d._mesh.quad().head() ; _iter != _mesh. - _euclidean_mesh_2d._mesh._set3.tend() ; + _euclidean_mesh_2d._mesh.quad().tend() ; ++_iter ) { if (_iter->mark() >= +0 && @@ -1613,7 +1624,8 @@ _nmap[_iter->node(0)] = +1 ; _nmap[_iter->node(1)] = +1 ; _nmap[_iter->node(2)] = +1 ; - _tnum += +1 ; + _nmap[_iter->node(3)] = +1 ; + _nnQ4 += +1 ; } } @@ -1623,47 +1635,47 @@ { if ( *_iter >= +0) { - *_iter = _nnum ++ ; + *_iter = _nnN1 ++ ; } } - if (_nnum > +0) + if (_nnN1 > +0) { /*-------------------------- write POINT data */ - _file << "POINT=" << _nnum << "\n" ; + _file << "POINT=" << _nnN1 << "\n" ; iptr_type _npos = +0; for (auto _iter = _mesh. - _euclidean_mesh_2d._mesh._set1.head() ; + _euclidean_mesh_2d._mesh.node().head() ; _iter != _mesh. - _euclidean_mesh_2d._mesh._set1.tend() ; + _euclidean_mesh_2d._mesh.node().tend() ; ++_iter, ++_npos) { if (_iter->mark() >= 0 && - _nmap[_npos ] >= 0) + _nmap[_npos ] >= 0 ) { _file << _iter->pval(0) << ";" << _iter->pval(1) << ";" - << +0 << "\n" ; + << +0 << "\n" ; } } } - if (_nnum > +0) + if (_nnN1 > +0) { /*-------------------------- write POWER data */ if (_jcfg._iter_opts.dual() ) { _file << "POWER=" - << _nnum << ";1" << "\n" ; + << _nnN1 << ";1" << "\n" ; iptr_type _npos = +0; for (auto _iter = _mesh. - _euclidean_mesh_2d._mesh._set1.head() ; + _euclidean_mesh_2d._mesh.node().head() ; _iter != _mesh. - _euclidean_mesh_2d._mesh._set1.tend() ; + _euclidean_mesh_2d._mesh.node().tend() ; ++_iter, ++_npos) { if (_iter->mark() >= 0 && @@ -1675,15 +1687,15 @@ } } - if (_enum > +0) + if (_nnE2 > +0) { /*-------------------------- write EDGE2 data */ - _file << "EDGE2=" << _enum << "\n" ; + _file << "EDGE2=" << _nnE2 << "\n" ; for (auto _iter = _mesh. - _euclidean_mesh_2d._mesh._set2.head() ; + _euclidean_mesh_2d._mesh.edge().head() ; _iter != _mesh. - _euclidean_mesh_2d._mesh._set2.tend() ; + _euclidean_mesh_2d._mesh.edge().tend() ; ++_iter ) { if (_iter->mark() >= 0 && @@ -1699,15 +1711,41 @@ } } - if (_tnum > +0) + if (_nnT3 > +0) { /*-------------------------- write TRIA3 data */ - _file << "TRIA3=" << _tnum << "\n" ; + _file << "TRIA3=" << _nnT3 << "\n" ; + + for (auto _iter = _mesh. + _euclidean_mesh_2d._mesh.tri3().head() ; + _iter != _mesh. + _euclidean_mesh_2d._mesh.tri3().tend() ; + ++_iter ) + { + if (_iter->mark() >= 0 && + _iter->self() >= 1 ) + { + _file << + _nmap[_iter->node(0)] << ";" + << + _nmap[_iter->node(1)] << ";" + << + _nmap[_iter->node(2)] << ";" + << + _iter->itag() << "\n" ; + } + } + } + + if (_nnQ4 > +0) + { + /*-------------------------- write QUAD4 data */ + _file << "QUAD4=" << _nnQ4 << "\n" ; for (auto _iter = _mesh. - _euclidean_mesh_2d._mesh._set3.head() ; + _euclidean_mesh_2d._mesh.quad().head() ; _iter != _mesh. - _euclidean_mesh_2d._mesh._set3.tend() ; + _euclidean_mesh_2d._mesh.quad().tend() ; ++_iter ) { if (_iter->mark() >= 0 && @@ -1720,6 +1758,8 @@ << _nmap[_iter->node(2)] << ";" << + _nmap[_iter->node(3)] << ";" + << _iter->itag() << "\n" ; } } @@ -1744,18 +1784,34 @@ /*------------ index mapping for active nodes */ _nmap.set_count(_mesh. - _euclidean_mesh_3d._mesh._set1.count() , - containers::tight_alloc, -1) ; + _euclidean_mesh_3d._mesh.node().count() , + containers::tight_alloc, -1) ; - iptr_type _nnum = +0 ; - iptr_type _enum = +0 ; - iptr_type _fnum = +0 ; - iptr_type _tnum = +0 ; + iptr_type _nnN1 = +0 ; + iptr_type _nnE2 = +0 ; + iptr_type _nnT3 = +0 ; + iptr_type _nnQ4 = +0 ; + iptr_type _nnT4 = +0 ; + + for (auto _iter = _mesh. + _euclidean_mesh_3d._mesh.edge().head() ; + _iter != _mesh. + _euclidean_mesh_3d._mesh.edge().tend() ; + ++_iter ) + { + if (_iter->mark() >= +0 && + _iter->self() >= +1 ) + { + _nmap[_iter->node(0)] = +1 ; + _nmap[_iter->node(1)] = +1 ; + _nnE2 += +1 ; + } + } for (auto _iter = _mesh. - _euclidean_mesh_3d._mesh._set2.head() ; + _euclidean_mesh_3d._mesh.tri3().head() ; _iter != _mesh. - _euclidean_mesh_3d._mesh._set2.tend() ; + _euclidean_mesh_3d._mesh.tri3().tend() ; ++_iter ) { if (_iter->mark() >= +0 && @@ -1763,14 +1819,15 @@ { _nmap[_iter->node(0)] = +1 ; _nmap[_iter->node(1)] = +1 ; - _enum += +1 ; + _nmap[_iter->node(2)] = +1 ; + _nnT3 += +1 ; } } for (auto _iter = _mesh. - _euclidean_mesh_3d._mesh._set3.head() ; + _euclidean_mesh_3d._mesh.quad().head() ; _iter != _mesh. - _euclidean_mesh_3d._mesh._set3.tend() ; + _euclidean_mesh_3d._mesh.quad().tend() ; ++_iter ) { if (_iter->mark() >= +0 && @@ -1779,14 +1836,15 @@ _nmap[_iter->node(0)] = +1 ; _nmap[_iter->node(1)] = +1 ; _nmap[_iter->node(2)] = +1 ; - _fnum += +1 ; + _nmap[_iter->node(3)] = +1 ; + _nnQ4 += +1 ; } } for (auto _iter = _mesh. - _euclidean_mesh_3d._mesh._set4.head() ; + _euclidean_mesh_3d._mesh.tri4().head() ; _iter != _mesh. - _euclidean_mesh_3d._mesh._set4.tend() ; + _euclidean_mesh_3d._mesh.tri4().tend() ; ++_iter ) { if (_iter->mark() >= +0 && @@ -1796,7 +1854,7 @@ _nmap[_iter->node(1)] = +1 ; _nmap[_iter->node(2)] = +1 ; _nmap[_iter->node(3)] = +1 ; - _tnum += +1 ; + _nnT4 += +1 ; } } @@ -1806,48 +1864,48 @@ { if ( *_iter >= +0) { - *_iter = _nnum ++ ; + *_iter = _nnN1 ++ ; } } - if (_nnum > +0) + if (_nnN1 > +0) { /*-------------------------- write POINT data */ - _file << "POINT=" << _nnum << "\n" ; + _file << "POINT=" << _nnN1 << "\n" ; iptr_type _npos = +0; for (auto _iter = _mesh. - _euclidean_mesh_3d._mesh._set1.head() ; + _euclidean_mesh_3d._mesh.node().head() ; _iter != _mesh. - _euclidean_mesh_3d._mesh._set1.tend() ; + _euclidean_mesh_3d._mesh.node().tend() ; ++_iter, ++_npos) { if (_iter->mark() >= 0 && - _nmap[_npos ] >= 0) + _nmap[_npos ] >= 0 ) { _file << _iter->pval(0) << ";" << _iter->pval(1) << ";" << _iter->pval(2) << ";" - << +0 << "\n" ; + << +0 << "\n" ; } } } - if (_nnum > +0) + if (_nnN1 > +0) { /*-------------------------- write POWER data */ if (_jcfg._iter_opts.dual() ) { _file << "POWER=" - << _nnum << ";1" << "\n" ; + << _nnN1 << ";1" << "\n" ; iptr_type _npos = +0; for (auto _iter = _mesh. - _euclidean_mesh_3d._mesh._set1.head() ; + _euclidean_mesh_3d._mesh.node().head() ; _iter != _mesh. - _euclidean_mesh_3d._mesh._set1.tend() ; + _euclidean_mesh_3d._mesh.node().tend() ; ++_iter, ++_npos) { if (_iter->mark() >= 0 && @@ -1859,15 +1917,15 @@ } } - if (_enum > +0) + if (_nnE2 > +0) { /*-------------------------- write EDGE2 data */ - _file << "EDGE2=" << _enum << "\n" ; + _file << "EDGE2=" << _nnE2 << "\n" ; for (auto _iter = _mesh. - _euclidean_mesh_3d._mesh._set2.head() ; + _euclidean_mesh_3d._mesh.edge().head() ; _iter != _mesh. - _euclidean_mesh_3d._mesh._set2.tend() ; + _euclidean_mesh_3d._mesh.edge().tend() ; ++_iter ) { if (_iter->mark() >= 0 && @@ -1883,15 +1941,15 @@ } } - if (_fnum > +0) + if (_nnT3 > +0) { /*-------------------------- write TRIA3 data */ - _file << "TRIA3=" << _fnum << "\n" ; + _file << "TRIA3=" << _nnT3 << "\n" ; for (auto _iter = _mesh. - _euclidean_mesh_3d._mesh._set3.head() ; + _euclidean_mesh_3d._mesh.tri3().head() ; _iter != _mesh. - _euclidean_mesh_3d._mesh._set3.tend() ; + _euclidean_mesh_3d._mesh.tri3().tend() ; ++_iter ) { if (_iter->mark() >= 0 && @@ -1909,15 +1967,43 @@ } } - if (_tnum > +0) + if (_nnQ4 > +0) { - /*-------------------------- write TRIA3 data */ - _file << "TRIA4=" << _tnum << "\n" ; + /*-------------------------- write QUAD4 data */ + _file << "QUAD4=" << _nnQ4 << "\n" ; for (auto _iter = _mesh. - _euclidean_mesh_3d._mesh._set4.head() ; + _euclidean_mesh_3d._mesh.quad().head() ; _iter != _mesh. - _euclidean_mesh_3d._mesh._set4.tend() ; + _euclidean_mesh_3d._mesh.quad().tend() ; + ++_iter ) + { + if (_iter->mark() >= 0 && + _iter->self() >= 1 ) + { + _file << + _nmap[_iter->node(0)] << ";" + << + _nmap[_iter->node(1)] << ";" + << + _nmap[_iter->node(2)] << ";" + << + _nmap[_iter->node(3)] << ";" + << + _iter->itag() << "\n" ; + } + } + } + + if (_nnT4 > +0) + { + /*-------------------------- write TRIA4 data */ + _file << "TRIA4=" << _nnT4 << "\n" ; + + for (auto _iter = _mesh. + _euclidean_mesh_3d._mesh.tri4().head() ; + _iter != _mesh. + _euclidean_mesh_3d._mesh.tri4().tend() ; ++_iter ) { if (_iter->mark() >= 0 && @@ -1989,17 +2075,33 @@ /*------------ index mapping for active nodes */ _nmap.set_count(_mesh. - _euclidean_mesh_2d._mesh._set1.count() , - containers::tight_alloc, -1) ; + _euclidean_mesh_2d._mesh.node().count() , + containers::tight_alloc, -1) ; - iptr_type _nnum = +0 ; - iptr_type _enum = +0 ; - iptr_type _tnum = +0 ; + iptr_type _nnN1 = +0 ; + iptr_type _nnE2 = +0 ; + iptr_type _nnT3 = +0 ; + iptr_type _nnQ4 = +0 ; + + for (auto _iter = _mesh. + _euclidean_mesh_2d._mesh.edge().head() ; + _iter != _mesh. + _euclidean_mesh_2d._mesh.edge().tend() ; + ++_iter ) + { + if (_iter->mark() >= +0 && + _iter->self() >= +1 ) + { + _nmap[_iter->node(0)] = +1 ; + _nmap[_iter->node(1)] = +1 ; + _nnE2 += +1 ; + } + } for (auto _iter = _mesh. - _euclidean_mesh_2d._mesh._set2.head() ; + _euclidean_mesh_2d._mesh.tri3().head() ; _iter != _mesh. - _euclidean_mesh_2d._mesh._set2.tend() ; + _euclidean_mesh_2d._mesh.tri3().tend() ; ++_iter ) { if (_iter->mark() >= +0 && @@ -2007,14 +2109,15 @@ { _nmap[_iter->node(0)] = +1 ; _nmap[_iter->node(1)] = +1 ; - _enum += +1 ; + _nmap[_iter->node(2)] = +1 ; + _nnT3 += +1 ; } } for (auto _iter = _mesh. - _euclidean_mesh_2d._mesh._set3.head() ; + _euclidean_mesh_2d._mesh.quad().head() ; _iter != _mesh. - _euclidean_mesh_2d._mesh._set3.tend() ; + _euclidean_mesh_2d._mesh.quad().tend() ; ++_iter ) { if (_iter->mark() >= +0 && @@ -2023,7 +2126,8 @@ _nmap[_iter->node(0)] = +1 ; _nmap[_iter->node(1)] = +1 ; _nmap[_iter->node(2)] = +1 ; - _tnum += +1 ; + _nmap[_iter->node(3)] = +1 ; + _nnQ4 += +1 ; } } @@ -2033,26 +2137,26 @@ { if ( *_iter >= +0) { - *_iter = _nnum ++ ; + *_iter = _nnN1 ++ ; } } - if (_nnum > +0) + if (_nnN1 > +0) { /*-------------------------- write POINT data */ jigsaw_alloc_vert2 ( - &_mmsh._vert2, _nnum) ; + &_mmsh._vert2, _nnN1) ; jigsaw_alloc_reals ( - &_mmsh._power, _nnum) ; + &_mmsh._power, _nnN1) ; iptr_type _npos = +0 ; iptr_type _nout = +0 ; for (auto _iter = _mesh. - _euclidean_mesh_2d._mesh._set1.head() ; + _euclidean_mesh_2d._mesh.node().head() ; _iter != _mesh. - _euclidean_mesh_2d._mesh._set1.tend() ; + _euclidean_mesh_2d._mesh.node().tend() ; ++_iter, ++_npos) { if (_iter->mark() >= 0 && @@ -2073,25 +2177,25 @@ } } - _mesh._euclidean_mesh_2d._mesh._set1. + _mesh._euclidean_mesh_2d._mesh._llN1. clear(containers::tight_alloc); - _mesh._euclidean_mesh_2d._mesh._adj1. + _mesh._euclidean_mesh_2d._mesh._aaN1. clear(containers::tight_alloc); } - if (_enum > +0) + if (_nnE2 > +0) { /*-------------------------- write EDGE2 data */ jigsaw_alloc_edge2 ( - &_mmsh._edge2, _enum) ; + &_mmsh._edge2, _nnE2) ; iptr_type _eout = +0 ; for (auto _iter = _mesh. - _euclidean_mesh_2d._mesh._set2.head() ; + _euclidean_mesh_2d._mesh.edge().head() ; _iter != _mesh. - _euclidean_mesh_2d._mesh._set2.tend() ; + _euclidean_mesh_2d._mesh.edge().tend() ; ++_iter ) { if (_iter->mark() >= 0 && @@ -2112,28 +2216,28 @@ } } - _mesh._euclidean_mesh_2d._mesh._set2. + _mesh._euclidean_mesh_2d._mesh._llE2. clear(containers::tight_alloc); - _mesh._euclidean_mesh_2d._mesh._adj2. + _mesh._euclidean_mesh_2d._mesh._aaE2. clear(containers::tight_alloc); - _mesh._euclidean_mesh_2d._mesh._map2. + _mesh._euclidean_mesh_2d._mesh._mmE2. clear(containers::tight_alloc); } - if (_tnum > +0) + if (_nnT3 > +0) { /*-------------------------- write TRIA3 data */ jigsaw_alloc_tria3 ( - &_mmsh._tria3, _tnum) ; + &_mmsh._tria3, _nnT3) ; iptr_type _tout = +0 ; for (auto _iter = _mesh. - _euclidean_mesh_2d._mesh._set3.head() ; + _euclidean_mesh_2d._mesh.tri3().head() ; _iter != _mesh. - _euclidean_mesh_2d._mesh._set3.tend() ; + _euclidean_mesh_2d._mesh.tri3().tend() ; ++_iter ) { if (_iter->mark() >= 0 && @@ -2157,13 +2261,55 @@ } } - _mesh._euclidean_mesh_2d._mesh._set3. + _mesh._euclidean_mesh_2d._mesh._llT3. clear(containers::tight_alloc); - _mesh._euclidean_mesh_2d._mesh._adj3. + _mesh._euclidean_mesh_2d._mesh._mmT3. + clear(containers::tight_alloc); + + } + + if (_nnQ4 > +0) + { + /*-------------------------- write QUAD4 data */ + jigsaw_alloc_quad4 ( + &_mmsh._quad4, _nnQ4) ; + + iptr_type _qout = +0 ; + for (auto _iter = _mesh. + _euclidean_mesh_2d._mesh.quad().head() ; + _iter != _mesh. + _euclidean_mesh_2d._mesh.quad().tend() ; + ++_iter ) + { + if (_iter->mark() >= 0 && + _iter->self() >= 1 ) + { + _mmsh._quad4. + _data[_qout]._node[0] + = _nmap[_iter->node(0)] ; + _mmsh._quad4. + _data[_qout]._node[1] + = _nmap[_iter->node(1)] ; + _mmsh._quad4. + _data[_qout]._node[2] + = _nmap[_iter->node(2)] ; + _mmsh._quad4. + _data[_qout]._node[3] + = _nmap[_iter->node(3)] ; + + _mmsh._quad4. + _data[_qout]. + _itag = _iter->itag() ; + + _qout = _qout + 1 ; + } + } + + _mesh._euclidean_mesh_2d._mesh._llQ4. clear(containers::tight_alloc); - _mesh._euclidean_mesh_2d._mesh._map3. + _mesh._euclidean_mesh_2d._mesh._mmQ4. clear(containers::tight_alloc); } @@ -2178,18 +2324,19 @@ /*------------ index mapping for active nodes */ _nmap.set_count(_mesh. - _euclidean_mesh_3d._mesh._set1.count() , - containers::tight_alloc, -1) ; + _euclidean_mesh_3d._mesh.node().count() , + containers::tight_alloc, -1) ; - iptr_type _nnum = +0 ; - iptr_type _enum = +0 ; - iptr_type _fnum = +0 ; - iptr_type _tnum = +0 ; + iptr_type _nnN1 = +0 ; + iptr_type _nnE2 = +0 ; + iptr_type _nnT3 = +0 ; + iptr_type _nnQ4 = +0 ; + iptr_type _nnT4 = +0 ; for (auto _iter = _mesh. - _euclidean_mesh_3d._mesh._set2.head() ; + _euclidean_mesh_3d._mesh.edge().head() ; _iter != _mesh. - _euclidean_mesh_3d._mesh._set2.tend() ; + _euclidean_mesh_3d._mesh.edge().tend() ; ++_iter ) { if (_iter->mark() >= +0 && @@ -2197,14 +2344,14 @@ { _nmap[_iter->node(0)] = +1 ; _nmap[_iter->node(1)] = +1 ; - _enum += +1 ; + _nnE2 += +1 ; } } for (auto _iter = _mesh. - _euclidean_mesh_3d._mesh._set3.head() ; + _euclidean_mesh_3d._mesh.tri3().head() ; _iter != _mesh. - _euclidean_mesh_3d._mesh._set3.tend() ; + _euclidean_mesh_3d._mesh.tri3().tend() ; ++_iter ) { if (_iter->mark() >= +0 && @@ -2213,14 +2360,14 @@ _nmap[_iter->node(0)] = +1 ; _nmap[_iter->node(1)] = +1 ; _nmap[_iter->node(2)] = +1 ; - _fnum += +1 ; + _nnT3 += +1 ; } } for (auto _iter = _mesh. - _euclidean_mesh_3d._mesh._set4.head() ; + _euclidean_mesh_3d._mesh.quad().head() ; _iter != _mesh. - _euclidean_mesh_3d._mesh._set4.tend() ; + _euclidean_mesh_3d._mesh.quad().tend() ; ++_iter ) { if (_iter->mark() >= +0 && @@ -2230,7 +2377,24 @@ _nmap[_iter->node(1)] = +1 ; _nmap[_iter->node(2)] = +1 ; _nmap[_iter->node(3)] = +1 ; - _tnum += +1 ; + _nnQ4 += +1 ; + } + } + + for (auto _iter = _mesh. + _euclidean_mesh_3d._mesh.tri4().head() ; + _iter != _mesh. + _euclidean_mesh_3d._mesh.tri4().tend() ; + ++_iter ) + { + if (_iter->mark() >= +0 && + _iter->self() >= +1 ) + { + _nmap[_iter->node(0)] = +1 ; + _nmap[_iter->node(1)] = +1 ; + _nmap[_iter->node(2)] = +1 ; + _nmap[_iter->node(3)] = +1 ; + _nnT4 += +1 ; } } @@ -2240,26 +2404,26 @@ { if ( *_iter >= +0) { - *_iter = _nnum ++ ; + *_iter = _nnN1 ++ ; } } - if (_nnum > +0) + if (_nnN1 > +0) { /*-------------------------- write POINT data */ jigsaw_alloc_vert3 ( - &_mmsh._vert3, _nnum) ; + &_mmsh._vert3, _nnN1) ; jigsaw_alloc_reals ( - &_mmsh._power, _nnum) ; + &_mmsh._power, _nnN1) ; iptr_type _npos = +0 ; iptr_type _nout = +0 ; for (auto _iter = _mesh. - _euclidean_mesh_3d._mesh._set1.head() ; + _euclidean_mesh_3d._mesh.node().head() ; _iter != _mesh. - _euclidean_mesh_3d._mesh._set1.tend() ; + _euclidean_mesh_3d._mesh.node().tend() ; ++_iter, ++_npos) { if (_iter->mark() >= 0 && @@ -2282,25 +2446,25 @@ } } - _mesh._euclidean_mesh_3d._mesh._set1. + _mesh._euclidean_mesh_3d._mesh._llN1. clear(containers::tight_alloc); - _mesh._euclidean_mesh_3d._mesh._adj1. + _mesh._euclidean_mesh_3d._mesh._aaN1. clear(containers::tight_alloc); } - if (_enum > +0) + if (_nnE2 > +0) { /*-------------------------- write EDGE2 data */ jigsaw_alloc_edge2 ( - &_mmsh._edge2, _enum) ; + &_mmsh._edge2, _nnE2) ; iptr_type _eout = +0 ; for (auto _iter = _mesh. - _euclidean_mesh_3d._mesh._set2.head() ; + _euclidean_mesh_3d._mesh.edge().head() ; _iter != _mesh. - _euclidean_mesh_3d._mesh._set2.tend() ; + _euclidean_mesh_3d._mesh.edge().tend() ; ++_iter ) { if (_iter->mark() >= 0 && @@ -2321,28 +2485,28 @@ } } - _mesh._euclidean_mesh_3d._mesh._set2. + _mesh._euclidean_mesh_3d._mesh._llE2. clear(containers::tight_alloc); - _mesh._euclidean_mesh_3d._mesh._adj2. + _mesh._euclidean_mesh_3d._mesh._aaE2. clear(containers::tight_alloc); - _mesh._euclidean_mesh_3d._mesh._map2. + _mesh._euclidean_mesh_3d._mesh._mmE2. clear(containers::tight_alloc); } - if (_fnum > +0) + if (_nnT3 > +0) { /*-------------------------- write TRIA3 data */ jigsaw_alloc_tria3 ( - &_mmsh._tria3, _fnum) ; + &_mmsh._tria3, _nnT3) ; iptr_type _fout = +0 ; for (auto _iter = _mesh. - _euclidean_mesh_3d._mesh._set3.head() ; + _euclidean_mesh_3d._mesh.tri3().head() ; _iter != _mesh. - _euclidean_mesh_3d._mesh._set3.tend() ; + _euclidean_mesh_3d._mesh.tri3().tend() ; ++_iter ) { if (_iter->mark() >= 0 && @@ -2366,28 +2530,76 @@ } } - _mesh._euclidean_mesh_3d._mesh._set3. + _mesh._euclidean_mesh_3d._mesh._llT3. clear(containers::tight_alloc); - _mesh._euclidean_mesh_3d._mesh._adj3. + _mesh._euclidean_mesh_3d._mesh._aaT3. clear(containers::tight_alloc); - _mesh._euclidean_mesh_3d._mesh._map3. + _mesh._euclidean_mesh_3d._mesh._mmT3. clear(containers::tight_alloc); } - if (_tnum > +0) + if (_nnQ4 > +0) { - /*-------------------------- write TRIA3 data */ + /*-------------------------- write QUAD4 data */ + jigsaw_alloc_quad4 ( + &_mmsh._quad4, _nnQ4) ; + + iptr_type _fout = +0 ; + for (auto _iter = _mesh. + _euclidean_mesh_3d._mesh.quad().head() ; + _iter != _mesh. + _euclidean_mesh_3d._mesh.quad().tend() ; + ++_iter ) + { + if (_iter->mark() >= 0 && + _iter->self() >= 1 ) + { + _mmsh._quad4. + _data[_fout]._node[0] + = _nmap[_iter->node(0)] ; + _mmsh._quad4. + _data[_fout]._node[1] + = _nmap[_iter->node(1)] ; + _mmsh._quad4. + _data[_fout]._node[2] + = _nmap[_iter->node(2)] ; + _mmsh._quad4. + _data[_fout]._node[2] + = _nmap[_iter->node(2)] ; + + _mmsh._quad4. + _data[_fout]. + _itag = _iter->itag() ; + + _fout = _fout + 1 ; + } + } + + _mesh._euclidean_mesh_3d._mesh._llQ4. + clear(containers::tight_alloc); + + _mesh._euclidean_mesh_3d._mesh._aaQ4. + clear(containers::tight_alloc); + + _mesh._euclidean_mesh_3d._mesh._mmQ4. + clear(containers::tight_alloc); + + } + + if (_nnT4 > +0) + { + /*-------------------------- write TRIA4 data */ jigsaw_alloc_tria4 ( - &_mmsh._tria4, _tnum) ; + &_mmsh._tria4, _nnT4) ; iptr_type _tout = +0 ; for (auto _iter = _mesh. - _euclidean_mesh_3d._mesh._set4.head() ; + _euclidean_mesh_3d._mesh.tri4().head() ; _iter != _mesh. - _euclidean_mesh_3d._mesh._set4.tend() ; + _euclidean_mesh_3d._mesh.tri4().tend() ; ++_iter ) { if (_iter->mark() >= 0 && @@ -2414,13 +2626,10 @@ } } - _mesh._euclidean_mesh_3d._mesh._set4. - clear(containers::tight_alloc); - - _mesh._euclidean_mesh_3d._mesh._adj4. + _mesh._euclidean_mesh_3d._mesh._llT4. clear(containers::tight_alloc); - _mesh._euclidean_mesh_3d._mesh._map4. + _mesh._euclidean_mesh_3d._mesh._mmT4. clear(containers::tight_alloc); } @@ -2460,11 +2669,9 @@ try { - std::ofstream _file ; + std::ofstream _file; - std::string _path ; - std::string _name ; - std::string _fext ; + std::string _path, _name, _fext ; file_part( _jcfg._hfun_file, _path, _name, _fext); @@ -2495,9 +2702,9 @@ iptr_type _tnum = +0 ; for (auto _iter = _ffun. - _euclidean_mesh_2d._mesh._set1.head() ; + _euclidean_mesh_2d._mesh.node().head() ; _iter != _ffun. - _euclidean_mesh_2d._mesh._set1.tend() ; + _euclidean_mesh_2d._mesh.node().tend() ; ++_iter ) { if (_iter->mark() >= +0 && @@ -2508,9 +2715,9 @@ } for (auto _iter = _ffun. - _euclidean_mesh_2d._mesh._set3.head() ; + _euclidean_mesh_2d._mesh.tri3().head() ; _iter != _ffun. - _euclidean_mesh_2d._mesh._set3.tend() ; + _euclidean_mesh_2d._mesh.tri3().tend() ; ++_iter ) { if (_iter->mark() >= +0 && @@ -2528,16 +2735,16 @@ iptr_type _npos = +0; for (auto _iter = _ffun. - _euclidean_mesh_2d._mesh._set1.head() ; + _euclidean_mesh_2d._mesh.node().head() ; _iter != _ffun. - _euclidean_mesh_2d._mesh._set1.tend() ; + _euclidean_mesh_2d._mesh.node().tend() ; ++_iter, ++_npos) { - if (_iter->mark() >= 0) + if (_iter->mark() >= 0 ) { _file << _iter->pval(0) << ";" << _iter->pval(1) << ";" - << +0 << "\n" ; + << +0 << "\n" ; } } } @@ -2564,9 +2771,9 @@ _file << "TRIA3=" << _tnum << "\n" ; for (auto _iter = _ffun. - _euclidean_mesh_2d._mesh._set3.head() ; + _euclidean_mesh_2d._mesh.tri3().head() ; _iter != _ffun. - _euclidean_mesh_2d._mesh._set3.tend() ; + _euclidean_mesh_2d._mesh.tri3().tend() ; ++_iter ) { if (_iter->mark() >= 0 && @@ -2602,9 +2809,9 @@ iptr_type _tnum = +0 ; for (auto _iter = _ffun. - _euclidean_mesh_3d._mesh._set1.head() ; + _euclidean_mesh_3d._mesh.node().head() ; _iter != _ffun. - _euclidean_mesh_3d._mesh._set1.tend() ; + _euclidean_mesh_3d._mesh.node().tend() ; ++_iter ) { if (_iter->mark() >= +0 && @@ -2615,9 +2822,9 @@ } for (auto _iter = _ffun. - _euclidean_mesh_3d._mesh._set4.head() ; + _euclidean_mesh_3d._mesh.tri4().head() ; _iter != _ffun. - _euclidean_mesh_3d._mesh._set4.tend() ; + _euclidean_mesh_3d._mesh.tri4().tend() ; ++_iter ) { if (_iter->mark() >= +0 && @@ -2635,17 +2842,17 @@ iptr_type _npos = +0; for (auto _iter = _ffun. - _euclidean_mesh_3d._mesh._set1.head() ; + _euclidean_mesh_3d._mesh.node().head() ; _iter != _ffun. - _euclidean_mesh_3d._mesh._set1.tend() ; + _euclidean_mesh_3d._mesh.node().tend() ; ++_iter, ++_npos) { - if (_iter->mark() >= 0) + if (_iter->mark() >= 0 ) { _file << _iter->pval(0) << ";" << _iter->pval(1) << ";" << _iter->pval(2) << ";" - << +0 << "\n" ; + << +0 << "\n" ; } } } @@ -2672,9 +2879,9 @@ _file << "TRIA4=" << _tnum << "\n" ; for (auto _iter = _ffun. - _euclidean_mesh_3d._mesh._set4.head() ; + _euclidean_mesh_3d._mesh.tri4().head() ; _iter != _ffun. - _euclidean_mesh_3d._mesh._set4.tend() ; + _euclidean_mesh_3d._mesh.tri4().tend() ; ++_iter ) { if (_iter->mark() >= 0 && @@ -2721,9 +2928,9 @@ iptr_type _tnum = +0 ; for (auto _iter = _ffun. - _ellipsoid_mesh_3d._mesh._set1.head() ; + _ellipsoid_mesh_3d._mesh.node().head() ; _iter != _ffun. - _ellipsoid_mesh_3d._mesh._set1.tend() ; + _ellipsoid_mesh_3d._mesh.node().tend() ; ++_iter ) { if (_iter->mark() >= +0 && @@ -2734,9 +2941,9 @@ } for (auto _iter = _ffun. - _ellipsoid_mesh_3d._mesh._set3.head() ; + _ellipsoid_mesh_3d._mesh.tri3().head() ; _iter != _ffun. - _ellipsoid_mesh_3d._mesh._set3.tend() ; + _ellipsoid_mesh_3d._mesh.tri3().tend() ; ++_iter ) { if (_iter->mark() >= +0 && @@ -2757,9 +2964,9 @@ real_type _ppos[3] ; real_type _apos[2] ; for (auto _iter = _ffun. - _ellipsoid_mesh_3d._mesh._set1.head() ; + _ellipsoid_mesh_3d._mesh.node().head() ; _iter != _ffun. - _ellipsoid_mesh_3d._mesh._set1.tend() ; + _ellipsoid_mesh_3d._mesh.node().tend() ; ++_iter, ++_npos) { if (_iter->mark() >= +0) @@ -2800,9 +3007,9 @@ _file << "TRIA3=" << _tnum << "\n" ; for (auto _iter = _ffun. - _ellipsoid_mesh_3d._mesh._set3.head() ; + _ellipsoid_mesh_3d._mesh.tri3().head() ; _iter != _ffun. - _ellipsoid_mesh_3d._mesh._set3.tend() ; + _ellipsoid_mesh_3d._mesh.tri3().tend() ; ++_iter ) { if (_iter->mark() >= 0 && diff --git a/src/netcdf/COPYRIGHT.md b/src/netcdf/COPYRIGHT.md new file mode 100644 index 0000000..af669df --- /dev/null +++ b/src/netcdf/COPYRIGHT.md @@ -0,0 +1,11 @@ +Copyright 2018 Unidata + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/src/netcdf/README.md b/src/netcdf/README.md new file mode 100644 index 0000000..1cd691e --- /dev/null +++ b/src/netcdf/README.md @@ -0,0 +1,81 @@ +# Unidata NetCDF + +[![Build Status](https://travis-ci.org/Unidata/netcdf-c.svg?branch=master)](https://travis-ci.org/Unidata/netcdf-c) +[![Coverity Scan Build Status](https://scan.coverity.com/projects/157/badge.svg)](https://scan.coverity.com/projects/157) + +### About +The Unidata network Common Data Form (**netCDF**) is an interface for +scientific data access and a freely-distributed software library that +provides an implementation of the interface. The netCDF library also +defines a machine-independent format for representing scientific data. +Together, the interface, library, and format support the creation, +access, and sharing of scientific data. The current netCDF software +provides C interfaces for applications and data. Separate software +distributions available from Unidata provide Java, Fortran, Python, +and C++ interfaces. They have been tested on various common +platforms. + +#### Properties +NetCDF files are self-describing, network-transparent, directly +accessible, and extendible. `Self-describing` means that a netCDF file +includes information about the data it contains. `Network-transparent` +means that a netCDF file is represented in a form that can be accessed +by computers with different ways of storing integers, characters, and +floating-point numbers. `Direct-access` means that a small subset of a +large dataset may be accessed efficiently, without first reading through +all the preceding data. `Extendible` means that data can be appended to +a netCDF dataset without copying it or redefining its structure. + +#### Use +NetCDF is useful for supporting access to diverse kinds of scientific +data in heterogeneous networking environments and for writing +application software that does not depend on application-specific +formats. For information about a variety of analysis and display +packages that have been developed to analyze and display data in +netCDF form, see + +* [Software for Manipulating or Displaying NetCDF Data](http://www.unidata.ucar.edu/netcdf/software.html) + +##### More information +For more information about netCDF, see + +* [Unidata Network Common Data Form (NetCDF)](http://www.unidata.ucar.edu/netcdf/) + +### Latest releases +You can obtain a copy of the latest released version of netCDF +software for various languages: + +* [C library and utilities](http://github.com/Unidata/netcdf-c) +* [Fortran](http://github.com/Unidata/netcdf-fortran) +* [Java](http://www.unidata.ucar.edu/downloads/netcdf/netcdf-java-4/) +* [Python](http://github.com/Unidata/netcdf4-python) +* [C++](http://github.com/Unidata/netcdf-cxx4) + +### Copyright +Copyright and licensing information can be found [here](http://www.unidata.ucar.edu/software/netcdf/copyright.html), as well as in the COPYRIGHT file accompanying the software + +### Installation +To install the netCDF-C software, please see the file INSTALL in the +netCDF-C distribution, or the (usually more up-to-date) document: + +* [Building NetCDF](https://www.unidata.ucar.edu/software/netcdf/docs/winbin.html) + +### Documentation +A language-independent User's Guide for netCDF, and some other +language-specific user-level documents are available from: + +* [Language-independent User's Guide](http://www.unidata.ucar.edu/software/netcdf/docs/user_guide.html) +* [NetCDF-C Tutorial](http://www.unidata.ucar.edu/software/netcdf/docs/tutorial_8dox.html) +* [Fortran-90 User's Guide](http://www.unidata.ucar.edu/software/netcdf/documentation/historic/netcdf-f90/index.html#Top) +* [Fortran-77 User's Guide](http://www.unidata.ucar.edu/software/netcdf/documentation/historic/netcdf-f77/index.html#Top) +* [netCDF-Java/Common Data Model library](http://www.unidata.ucar.edu/software/thredds/current/netcdf-java/) +* [netCDF4-python](http://unidata.github.io/netcdf4-python/) + +A mailing list, netcdfgroup@unidata.ucar.edu, exists for discussion of +the netCDF interface and announcements about netCDF bugs, fixes, and +enhancements. For information about how to subscribe, see the URL + +* [Unidata netCDF Mailing-Lists](http://www.unidata.ucar.edu/netcdf/mailing-lists.html) + +### Feedback +We appreciate feedback from users of this package. Please send comments, suggestions, and bug reports to . diff --git a/src/netcdf/lib_netcdf.h b/src/netcdf/lib_netcdf.h new file mode 100644 index 0000000..67a8d61 --- /dev/null +++ b/src/netcdf/lib_netcdf.h @@ -0,0 +1,2001 @@ +/*! \file + +Main header file for the C API. + +Copyright 2018, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, +2015, 2016, 2017, 2018, 2019 +University Corporation for Atmospheric Research/Unidata. + +See \ref copyright file for more info. +*/ + +#ifndef _NETCDF_ +#define _NETCDF_ + +#include /* size_t, ptrdiff_t */ +#include /* netcdf functions sometimes return system errors */ + +/* Required for alloca on Windows */ +#if defined(_WIN32) || defined(_WIN64) +#include +#endif + +/*! The nc_type type is just an int. */ +typedef int nc_type; + +#if defined(__cplusplus) +extern "C" { +#endif + +/* + * The netcdf external data types + */ +#define NC_NAT 0 /**< Not A Type */ +#define NC_BYTE 1 /**< signed 1 byte integer */ +#define NC_CHAR 2 /**< ISO/ASCII character */ +#define NC_SHORT 3 /**< signed 2 byte integer */ +#define NC_INT 4 /**< signed 4 byte integer */ +#define NC_LONG NC_INT /**< \deprecated required for backward compatibility. */ +#define NC_FLOAT 5 /**< single precision floating point number */ +#define NC_DOUBLE 6 /**< double precision floating point number */ +#define NC_UBYTE 7 /**< unsigned 1 byte int */ +#define NC_USHORT 8 /**< unsigned 2-byte int */ +#define NC_UINT 9 /**< unsigned 4-byte int */ +#define NC_INT64 10 /**< signed 8-byte int */ +#define NC_UINT64 11 /**< unsigned 8-byte int */ +#define NC_STRING 12 /**< string */ + +#define NC_MAX_ATOMIC_TYPE NC_STRING /**< @internal Largest atomic type. */ + +/* The following are use internally in support of user-defines + * types. They are also the class returned by nc_inq_user_type. */ +#define NC_VLEN 13 /**< vlen (variable-length) types */ +#define NC_OPAQUE 14 /**< opaque types */ +#define NC_ENUM 15 /**< enum types */ +#define NC_COMPOUND 16 /**< compound types */ + +/** @internal Define the first user defined type id (leave some + * room) */ +#define NC_FIRSTUSERTYPEID 32 + +/** Default fill value. This is used unless _FillValue attribute + * is set. These values are stuffed into newly allocated space as + * appropriate. The hope is that one might use these to notice that a + * particular datum has not been set. */ +/**@{*/ +#define NC_FILL_BYTE ((signed char)-127) +#define NC_FILL_CHAR ((char)0) +#define NC_FILL_SHORT ((short)-32767) +#define NC_FILL_INT (-2147483647) +#define NC_FILL_FLOAT (9.9692099683868690e+36f) /* near 15 * 2^119 */ +#define NC_FILL_DOUBLE (9.9692099683868690e+36) +#define NC_FILL_UBYTE (255) +#define NC_FILL_USHORT (65535) +#define NC_FILL_UINT (4294967295U) +#define NC_FILL_INT64 ((long long)-9223372036854775806LL) +#define NC_FILL_UINT64 ((unsigned long long)18446744073709551614ULL) +#define NC_FILL_STRING ((char *)"") +/**@}*/ + +/*! Max or min values for a type. Nothing greater/smaller can be + * stored in a netCDF file for their associated types. Recall that a C + * compiler may define int to be any length it wants, but a NC_INT is + * *always* a 4 byte signed int. On a platform with 64 bit ints, + * there will be many ints which are outside the range supported by + * NC_INT. But since NC_INT is an external format, it has to mean the + * same thing everywhere. */ +/**@{*/ +#define NC_MAX_BYTE 127 +#define NC_MIN_BYTE (-NC_MAX_BYTE-1) +#define NC_MAX_CHAR 255 +#define NC_MAX_SHORT 32767 +#define NC_MIN_SHORT (-NC_MAX_SHORT - 1) +#define NC_MAX_INT 2147483647 +#define NC_MIN_INT (-NC_MAX_INT - 1) +#define NC_MAX_FLOAT 3.402823466e+38f +#define NC_MIN_FLOAT (-NC_MAX_FLOAT) +#define NC_MAX_DOUBLE 1.7976931348623157e+308 +#define NC_MIN_DOUBLE (-NC_MAX_DOUBLE) +#define NC_MAX_UBYTE NC_MAX_CHAR +#define NC_MAX_USHORT 65535U +#define NC_MAX_UINT 4294967295U +#define NC_MAX_INT64 (9223372036854775807LL) +#define NC_MIN_INT64 (-9223372036854775807LL-1) +#define NC_MAX_UINT64 (18446744073709551615ULL) +/**@}*/ + +/** Name of fill value attribute. If you wish a variable to use a + * different value than the above defaults, create an attribute with + * the same type as the variable and this reserved name. The value you + * give the attribute will be used as the fill value for that + * variable. */ +#define _FillValue "_FillValue" +#define NC_FILL 0 /**< Argument to nc_set_fill() to clear NC_NOFILL */ +#define NC_NOFILL 0x100 /**< Argument to nc_set_fill() to turn off filling of data. */ + +/* Define the ioflags bits for nc_create and nc_open. + currently unused: + 0x0002 + and the whole upper 16 bits +*/ + +#define NC_NOWRITE 0x0000 /**< Set read-only access for nc_open(). */ +#define NC_WRITE 0x0001 /**< Set read-write access for nc_open(). */ + +#define NC_CLOBBER 0x0000 /**< Destroy existing file. Mode flag for nc_create(). */ +#define NC_NOCLOBBER 0x0004 /**< Don't destroy existing file. Mode flag for nc_create(). */ + +#define NC_DISKLESS 0x0008 /**< Use diskless file. Mode flag for nc_open() or nc_create(). */ +#define NC_MMAP 0x0010 /**< \deprecated Use diskless file with mmap. Mode flag for nc_open() or nc_create()*/ + +#define NC_64BIT_DATA 0x0020 /**< CDF-5 format: classic model but 64 bit dimensions and sizes */ +#define NC_CDF5 NC_64BIT_DATA /**< Alias NC_CDF5 to NC_64BIT_DATA */ + +#define NC_UDF0 0x0040 /**< User-defined format 0. */ +#define NC_UDF1 0x0080 /**< User-defined format 1. */ + +#define NC_CLASSIC_MODEL 0x0100 /**< Enforce classic model on netCDF-4. Mode flag for nc_create(). */ +#define NC_64BIT_OFFSET 0x0200 /**< Use large (64-bit) file offsets. Mode flag for nc_create(). */ + +/** \deprecated The following flag currently is ignored, but use in + * nc_open() or nc_create() may someday support use of advisory + * locking to prevent multiple writers from clobbering a file + */ +#define NC_LOCK 0x0400 + +/** Share updates, limit caching. +Use this in mode flags for both nc_create() and nc_open(). */ +#define NC_SHARE 0x0800 + +#define NC_NETCDF4 0x1000 /**< Use netCDF-4/HDF5 format. Mode flag for nc_create(). */ + +/** The following 3 flags are deprecated as of 4.6.2. Parallel I/O is now + * initiated by calling nc_create_par and nc_open_par, no longer by flags. + */ +#define NC_MPIIO 0x2000 /**< \deprecated */ +#define NC_MPIPOSIX NC_MPIIO /**< \deprecated */ +#define NC_PNETCDF (NC_MPIIO) /**< \deprecated */ + +#define NC_PERSIST 0x4000 /**< Save diskless contents to disk. Mode flag for nc_open() or nc_create() */ +#define NC_INMEMORY 0x8000 /**< Read from memory. Mode flag for nc_open() or nc_create() */ + +#define NC_MAX_MAGIC_NUMBER_LEN 8 /**< Max len of user-defined format magic number. */ + +/** Format specifier for nc_set_default_format() and returned + * by nc_inq_format. This returns the format as provided by + * the API. See nc_inq_format_extended to see the true file format. + * Starting with version 3.6, there are different format netCDF files. + * 4.0 introduces the third one. \see netcdf_format + */ +/**@{*/ +#define NC_FORMAT_CLASSIC (1) +/* After adding CDF5 support, the NC_FORMAT_64BIT + flag is somewhat confusing. So, it is renamed. + Note that the name in the contributed code + NC_FORMAT_64BIT was renamed to NC_FORMAT_CDF2 +*/ +#define NC_FORMAT_64BIT_OFFSET (2) +#define NC_FORMAT_64BIT (NC_FORMAT_64BIT_OFFSET) /**< \deprecated Saved for compatibility. Use NC_FORMAT_64BIT_OFFSET or NC_FORMAT_64BIT_DATA, from netCDF 4.4.0 onwards. */ +#define NC_FORMAT_NETCDF4 (3) +#define NC_FORMAT_NETCDF4_CLASSIC (4) +#define NC_FORMAT_64BIT_DATA (5) + +/* Alias */ +#define NC_FORMAT_CDF5 NC_FORMAT_64BIT_DATA + +/* Define a mask covering format flags only */ +#define NC_FORMAT_ALL (NC_64BIT_OFFSET|NC_64BIT_DATA|NC_CLASSIC_MODEL|NC_NETCDF4|NC_UDF0|NC_UDF1) + +/**@}*/ + +/** Extended format specifier returned by nc_inq_format_extended() + * Added in version 4.3.1. This returns the true format of the + * underlying data. + * The function returns two values + * 1. a small integer indicating the underlying source type + * of the data. Note that this may differ from what the user + * sees from nc_inq_format() because this latter function + * returns what the user can expect to see thru the API. + * 2. A mode value indicating what mode flags are effectively + * set for this dataset. This usually will be a superset + * of the mode flags used as the argument to nc_open + * or nc_create. + * More or less, the #1 values track the set of dispatch tables. + * The #1 values are as follows. + * Note that CDF-5 returns NC_FORMAT_NC3, but sets the mode flag properly. + */ +/**@{*/ + +#define NC_FORMATX_NC3 (1) +#define NC_FORMATX_NC_HDF5 (2) /**< netCDF-4 subset of HDF5 */ +#define NC_FORMATX_NC4 NC_FORMATX_NC_HDF5 /**< alias */ +#define NC_FORMATX_NC_HDF4 (3) /**< netCDF-4 subset of HDF4 */ +#define NC_FORMATX_PNETCDF (4) +#define NC_FORMATX_DAP2 (5) +#define NC_FORMATX_DAP4 (6) +#define NC_FORMATX_UDF0 (8) +#define NC_FORMATX_UDF1 (9) +#define NC_FORMATX_ZARR (10) +#define NC_FORMATX_UNDEFINED (0) + + /* To avoid breaking compatibility (such as in the python library), + we need to retain the NC_FORMAT_xxx format as well. This may come + out eventually, as the NC_FORMATX is more clear that it's an extended + format specifier.*/ + +#define NC_FORMAT_NC3 NC_FORMATX_NC3 /**< \deprecated As of 4.4.0, use NC_FORMATX_NC3 */ +#define NC_FORMAT_NC_HDF5 NC_FORMATX_NC_HDF5 /**< \deprecated As of 4.4.0, use NC_FORMATX_NC_HDF5 */ +#define NC_FORMAT_NC4 NC_FORMATX_NC4 /**< \deprecated As of 4.4.0, use NC_FORMATX_NC4 */ +#define NC_FORMAT_NC_HDF4 NC_FORMATX_NC_HDF4 /**< \deprecated As of 4.4.0, use NC_FORMATX_HDF4 */ +#define NC_FORMAT_PNETCDF NC_FORMATX_PNETCDF /**< \deprecated As of 4.4.0, use NC_FORMATX_PNETCDF */ +#define NC_FORMAT_DAP2 NC_FORMATX_DAP2 /**< \deprecated As of 4.4.0, use NC_FORMATX_DAP2 */ +#define NC_FORMAT_DAP4 NC_FORMATX_DAP4 /**< \deprecated As of 4.4.0, use NC_FORMATX_DAP4 */ +#define NC_FORMAT_UNDEFINED NC_FORMATX_UNDEFINED /**< \deprecated As of 4.4.0, use NC_FORMATX_UNDEFINED */ + +/**@}*/ + +/** Let nc__create() or nc__open() figure out a suitable buffer size. */ +#define NC_SIZEHINT_DEFAULT 0 + +/** In nc__enddef(), align to the buffer size. */ +#define NC_ALIGN_CHUNK ((size_t)(-1)) + +/** Size argument to nc_def_dim() for an unlimited dimension. */ +#define NC_UNLIMITED 0L + +/** Attribute id to put/get a global attribute. */ +#define NC_GLOBAL -1 + +/** +Maximum for classic library. + +In the classic netCDF model there are maximum values for the number of +dimensions in the file (\ref NC_MAX_DIMS), the number of global or per +variable attributes (\ref NC_MAX_ATTRS), the number of variables in +the file (\ref NC_MAX_VARS), and the length of a name (\ref +NC_MAX_NAME). + +These maximums are enforced by the interface, to facilitate writing +applications and utilities. However, nothing is statically allocated +to these sizes internally. + +These maximums are not used for netCDF-4/HDF5 files unless they were +created with the ::NC_CLASSIC_MODEL flag. + +As a rule, NC_MAX_VAR_DIMS <= NC_MAX_DIMS. + +NOTE: The NC_MAX_DIMS, NC_MAX_ATTRS, and NC_MAX_VARS limits + are *not* enforced after version 4.5.0 +*/ +/**@{*/ +#define NC_MAX_DIMS 1024 /* not enforced after 4.5.0 */ +#define NC_MAX_ATTRS 8192 /* not enforced after 4.5.0 */ +#define NC_MAX_VARS 8192 /* not enforced after 4.5.0 */ +#define NC_MAX_NAME 256 +#define NC_MAX_VAR_DIMS 1024 /**< max per variable dimensions */ +/**@}*/ + +/** The max size of an SD dataset name in HDF4 (from HDF4 + * documentation) is 64. But in in the wild we have encountered longer + * names. As long as the HDF4 name is not greater than NC_MAX_NAME, + * our code will be OK. */ +#define NC_MAX_HDF4_NAME NC_MAX_NAME + +/** In HDF5 files you can set the endianness of variables with + nc_def_var_endian(). This define is used there. */ +/**@{*/ +#define NC_ENDIAN_NATIVE 0 +#define NC_ENDIAN_LITTLE 1 +#define NC_ENDIAN_BIG 2 +/**@}*/ + +/** In HDF5 files you can set storage for each variable to be either + * contiguous or chunked, with nc_def_var_chunking(). This define is + * used there. */ +/**@{*/ +#define NC_CHUNKED 0 +#define NC_CONTIGUOUS 1 +#define NC_COMPACT 2 +/**@}*/ + +/** In HDF5 files you can set check-summing for each variable. +Currently the only checksum available is Fletcher-32, which can be set +with the function nc_def_var_fletcher32. These defines are used +there. */ +/**@{*/ +#define NC_NOCHECKSUM 0 +#define NC_FLETCHER32 1 +/**@}*/ + +/**@{*/ +/** Control the HDF5 shuffle filter. In HDF5 files you can specify + * that a shuffle filter should be used on each chunk of a variable to + * improve compression for that variable. This per-variable shuffle + * property can be set with the function nc_def_var_deflate(). */ +#define NC_NOSHUFFLE 0 +#define NC_SHUFFLE 1 +/**@}*/ + +#define NC_MIN_DEFLATE_LEVEL 0 /**< Minimum deflate level. */ +#define NC_MAX_DEFLATE_LEVEL 9 /**< Maximum deflate level. */ + +/** The netcdf version 3 functions all return integer error status. + * These are the possible values, in addition to certain values from + * the system errno.h. + */ +#define NC_ISSYSERR(err) ((err) > 0) + +#define NC_NOERR 0 /**< No Error */ +#define NC2_ERR (-1) /**< Returned for all errors in the v2 API. */ + +/** Not a netcdf id. + +The specified netCDF ID does not refer to an +open netCDF dataset. */ +#define NC_EBADID (-33) +#define NC_ENFILE (-34) /**< Too many netcdfs open */ +#define NC_EEXIST (-35) /**< netcdf file exists && NC_NOCLOBBER */ +#define NC_EINVAL (-36) /**< Invalid Argument */ +#define NC_EPERM (-37) /**< Write to read only */ + +/** Operation not allowed in data mode. This is returned for netCDF +classic or 64-bit offset files, or for netCDF-4 files, when they were +been created with ::NC_CLASSIC_MODEL flag in nc_create(). */ +#define NC_ENOTINDEFINE (-38) + +/** Operation not allowed in define mode. + +The specified netCDF is in define mode rather than data mode. + +With netCDF-4/HDF5 files, this error will not occur, unless +::NC_CLASSIC_MODEL was used in nc_create(). + */ +#define NC_EINDEFINE (-39) + +/** Index exceeds dimension bound. + +The specified corner indices were out of range for the rank of the +specified variable. For example, a negative index or an index that is +larger than the corresponding dimension length will cause an error. */ +#define NC_EINVALCOORDS (-40) + +/** NC_MAX_DIMS exceeded. Max number of dimensions exceeded in a +classic or 64-bit offset file, or an netCDF-4 file with +::NC_CLASSIC_MODEL on. */ +#define NC_EMAXDIMS (-41) /* not enforced after 4.5.0 */ + +#define NC_ENAMEINUSE (-42) /**< String match to name in use */ +#define NC_ENOTATT (-43) /**< Attribute not found */ +#define NC_EMAXATTS (-44) /**< NC_MAX_ATTRS exceeded - not enforced after 4.5.0 */ +#define NC_EBADTYPE (-45) /**< Not a netcdf data type */ +#define NC_EBADDIM (-46) /**< Invalid dimension id or name */ +#define NC_EUNLIMPOS (-47) /**< NC_UNLIMITED in the wrong index */ + +/** NC_MAX_VARS exceeded. Max number of variables exceeded in a +classic or 64-bit offset file, or an netCDF-4 file with +::NC_CLASSIC_MODEL on. */ +#define NC_EMAXVARS (-48) /* not enforced after 4.5.0 */ + +/** Variable not found. + +The variable ID is invalid for the specified netCDF dataset. */ +#define NC_ENOTVAR (-49) +#define NC_EGLOBAL (-50) /**< Action prohibited on NC_GLOBAL varid */ +#define NC_ENOTNC (-51) /**< Not a netcdf file */ +#define NC_ESTS (-52) /**< In Fortran, string too short */ +#define NC_EMAXNAME (-53) /**< NC_MAX_NAME exceeded */ +#define NC_EUNLIMIT (-54) /**< NC_UNLIMITED size already in use */ +#define NC_ENORECVARS (-55) /**< nc_rec op when there are no record vars */ +#define NC_ECHAR (-56) /**< Attempt to convert between text & numbers */ + +/** Start+count exceeds dimension bound. + +The specified edge lengths added to the specified corner would have +referenced data out of range for the rank of the specified +variable. For example, an edge length that is larger than the +corresponding dimension length minus the corner index will cause an +error. */ +#define NC_EEDGE (-57) /**< Start+count exceeds dimension bound. */ +#define NC_ESTRIDE (-58) /**< Illegal stride */ +#define NC_EBADNAME (-59) /**< Attribute or variable name contains illegal characters */ +/* N.B. following must match value in ncx.h */ + +/** Math result not representable. + +One or more of the values are out of the range of values representable +by the desired type. */ +#define NC_ERANGE (-60) +#define NC_ENOMEM (-61) /**< Memory allocation (malloc) failure */ +#define NC_EVARSIZE (-62) /**< One or more variable sizes violate format constraints */ +#define NC_EDIMSIZE (-63) /**< Invalid dimension size */ +#define NC_ETRUNC (-64) /**< File likely truncated or possibly corrupted */ +#define NC_EAXISTYPE (-65) /**< Unknown axis type. */ + +/* Following errors are added for DAP */ +#define NC_EDAP (-66) /**< Generic DAP error */ +#define NC_ECURL (-67) /**< Generic libcurl error */ +#define NC_EIO (-68) /**< Generic IO error */ +#define NC_ENODATA (-69) /**< Attempt to access variable with no data */ +#define NC_EDAPSVC (-70) /**< DAP server error */ +#define NC_EDAS (-71) /**< Malformed or inaccessible DAS */ +#define NC_EDDS (-72) /**< Malformed or inaccessible DDS */ +#define NC_EDMR NC_EDDS /**< Dap4 alias */ +#define NC_EDATADDS (-73) /**< Malformed or inaccessible DATADDS */ +#define NC_EDATADAP NC_EDATADDS /**< Dap4 alias */ +#define NC_EDAPURL (-74) /**< Malformed DAP URL */ +#define NC_EDAPCONSTRAINT (-75) /**< Malformed DAP Constraint*/ +#define NC_ETRANSLATION (-76) /**< Untranslatable construct */ +#define NC_EACCESS (-77) /**< Access Failure */ +#define NC_EAUTH (-78) /**< Authorization Failure */ + +/* Misc. additional errors */ +#define NC_ENOTFOUND (-90) /**< No such file */ +#define NC_ECANTREMOVE (-91) /**< Can't remove file */ +#define NC_EINTERNAL (-92) /**< NetCDF Library Internal Error */ +#define NC_EPNETCDF (-93) /**< Error at PnetCDF layer */ + +/* The following was added in support of netcdf-4. Make all netcdf-4 + error codes < -100 so that errors can be added to netcdf-3 if + needed. */ +#define NC4_FIRST_ERROR (-100) /**< @internal All HDF5 errors < this. */ +#define NC_EHDFERR (-101) /**< Error at HDF5 layer. */ +#define NC_ECANTREAD (-102) /**< Can't read. */ +#define NC_ECANTWRITE (-103) /**< Can't write. */ +#define NC_ECANTCREATE (-104) /**< Can't create. */ +#define NC_EFILEMETA (-105) /**< Problem with file metadata. */ +#define NC_EDIMMETA (-106) /**< Problem with dimension metadata. */ +#define NC_EATTMETA (-107) /**< Problem with attribute metadata. */ +#define NC_EVARMETA (-108) /**< Problem with variable metadata. */ +#define NC_ENOCOMPOUND (-109) /**< Not a compound type. */ +#define NC_EATTEXISTS (-110) /**< Attribute already exists. */ +#define NC_ENOTNC4 (-111) /**< Attempting netcdf-4 operation on netcdf-3 file. */ +#define NC_ESTRICTNC3 (-112) /**< Attempting netcdf-4 operation on strict nc3 netcdf-4 file. */ +#define NC_ENOTNC3 (-113) /**< Attempting netcdf-3 operation on netcdf-4 file. */ +#define NC_ENOPAR (-114) /**< Parallel operation on file opened for non-parallel access. */ +#define NC_EPARINIT (-115) /**< Error initializing for parallel access. */ +#define NC_EBADGRPID (-116) /**< Bad group ID. */ +#define NC_EBADTYPID (-117) /**< Bad type ID. */ +#define NC_ETYPDEFINED (-118) /**< Type has already been defined and may not be edited. */ +#define NC_EBADFIELD (-119) /**< Bad field ID. */ +#define NC_EBADCLASS (-120) /**< Bad class. */ +#define NC_EMAPTYPE (-121) /**< Mapped access for atomic types only. */ +#define NC_ELATEFILL (-122) /**< Attempt to define fill value when data already exists. */ +#define NC_ELATEDEF (-123) /**< Attempt to define var properties, like deflate, after enddef. */ +#define NC_EDIMSCALE (-124) /**< Problem with HDF5 dimscales. */ +#define NC_ENOGRP (-125) /**< No group found. */ +#define NC_ESTORAGE (-126) /**< Can't specify both contiguous and chunking. */ +#define NC_EBADCHUNK (-127) /**< Bad chunksize. */ +#define NC_ENOTBUILT (-128) /**< Attempt to use feature that was not turned on when netCDF was built. */ +#define NC_EDISKLESS (-129) /**< Error in using diskless access. */ +#define NC_ECANTEXTEND (-130) /**< Attempt to extend dataset during ind. I/O operation. */ +#define NC_EMPI (-131) /**< MPI operation failed. */ + +#define NC_EFILTER (-132) /**< Filter operation failed. */ +#define NC_ERCFILE (-133) /**< RC file failure */ +#define NC_ENULLPAD (-134) /**< Header Bytes not Null-Byte padded */ +#define NC_EINMEMORY (-135) /**< In-memory file error */ +#define NC_ENOFILTER (-136) /**< Filter not defined on variable. */ + +#define NC4_LAST_ERROR (-137) /**< @internal All netCDF errors > this. */ + +/* Errors for all remote access methods(e.g. DAP and CDMREMOTE)*/ +#define NC_EURL (NC_EDAPURL) /**< Malformed URL */ +#define NC_ECONSTRAINT (NC_EDAPCONSTRAINT) /**< Malformed Constraint*/ + +/** @internal This is used in netCDF-4 files for dimensions without + * coordinate vars. */ +#define DIM_WITHOUT_VARIABLE "This is a netCDF dimension but not a netCDF variable." + +/** @internal This is here at the request of the NCO team to support + * our mistake of having chunksizes be first ints, then + * size_t. Doh! */ +#define NC_HAVE_NEW_CHUNKING_API 1 + +/* + * The Interface + */ + +/* Declaration modifiers for DLL support (MSC et al) */ +#if defined(DLL_NETCDF) /* define when library is a DLL */ +# if defined(DLL_EXPORT) /* define when building the library */ +# define MSC_EXTRA __declspec(dllexport) +# else +# define MSC_EXTRA __declspec(dllimport) +# endif +# include +#else +#define MSC_EXTRA /**< Needed for DLL build. */ +#endif /* defined(DLL_NETCDF) */ + +#define EXTERNL MSC_EXTRA extern /**< Needed for DLL build. */ + +#if defined(DLL_NETCDF) /* define when library is a DLL */ +EXTERNL int ncerr; +EXTERNL int ncopts; +#endif + +EXTERNL const char * +nc_inq_libvers(void); + +EXTERNL const char * +nc_strerror(int ncerr); + +/* Set up user-defined format. */ +typedef struct NC_Dispatch NC_Dispatch; +EXTERNL int +nc_def_user_format(int mode_flag, NC_Dispatch *dispatch_table, char *magic_number); + +EXTERNL int +nc_inq_user_format(int mode_flag, NC_Dispatch **dispatch_table, char *magic_number); + +EXTERNL int +nc__create(const char *path, int cmode, size_t initialsz, + size_t *chunksizehintp, int *ncidp); + +EXTERNL int +nc_create(const char *path, int cmode, int *ncidp); + +EXTERNL int +nc__open(const char *path, int mode, + size_t *chunksizehintp, int *ncidp); + +EXTERNL int +nc_open(const char *path, int mode, int *ncidp); + +/* Learn the path used to open/create the file. */ +EXTERNL int +nc_inq_path(int ncid, size_t *pathlen, char *path); + +/* Given an ncid and group name (NULL gets root group), return + * locid. */ +EXTERNL int +nc_inq_ncid(int ncid, const char *name, int *grp_ncid); + +/* Given a location id, return the number of groups it contains, and + * an array of their locids. */ +EXTERNL int +nc_inq_grps(int ncid, int *numgrps, int *ncids); + +/* Given locid, find name of group. (Root group is named "/".) */ +EXTERNL int +nc_inq_grpname(int ncid, char *name); + +/* Given ncid, find full name and len of full name. (Root group is + * named "/", with length 1.) */ +EXTERNL int +nc_inq_grpname_full(int ncid, size_t *lenp, char *full_name); + +/* Given ncid, find len of full name. */ +EXTERNL int +nc_inq_grpname_len(int ncid, size_t *lenp); + +/* Given an ncid, find the ncid of its parent group. */ +EXTERNL int +nc_inq_grp_parent(int ncid, int *parent_ncid); + +/* Given a name and parent ncid, find group ncid. */ +EXTERNL int +nc_inq_grp_ncid(int ncid, const char *grp_name, int *grp_ncid); + +/* Given a full name and ncid, find group ncid. */ +EXTERNL int +nc_inq_grp_full_ncid(int ncid, const char *full_name, int *grp_ncid); + +/* Get a list of ids for all the variables in a group. */ +EXTERNL int +nc_inq_varids(int ncid, int *nvars, int *varids); + +/* Find all dimids for a location. This finds all dimensions in a + * group, or any of its parents. */ +EXTERNL int +nc_inq_dimids(int ncid, int *ndims, int *dimids, int include_parents); + +/* Find all user-defined types for a location. This finds all + * user-defined types in a group. */ +EXTERNL int +nc_inq_typeids(int ncid, int *ntypes, int *typeids); + +/* Are two types equal? */ +EXTERNL int +nc_inq_type_equal(int ncid1, nc_type typeid1, int ncid2, + nc_type typeid2, int *equal); + +/* Create a group. its ncid is returned in the new_ncid pointer. */ +EXTERNL int +nc_def_grp(int parent_ncid, const char *name, int *new_ncid); + +/* Rename a group */ +EXTERNL int +nc_rename_grp(int grpid, const char *name); + +/* Here are functions for dealing with compound types. */ + +/* Create a compound type. */ +EXTERNL int +nc_def_compound(int ncid, size_t size, const char *name, nc_type *typeidp); + +/* Insert a named field into a compound type. */ +EXTERNL int +nc_insert_compound(int ncid, nc_type xtype, const char *name, + size_t offset, nc_type field_typeid); + +/* Insert a named array into a compound type. */ +EXTERNL int +nc_insert_array_compound(int ncid, nc_type xtype, const char *name, + size_t offset, nc_type field_typeid, + int ndims, const int *dim_sizes); + +/* Get the name and size of a type. */ +EXTERNL int +nc_inq_type(int ncid, nc_type xtype, char *name, size_t *size); + +/* Get the id of a type from the name. */ +EXTERNL int +nc_inq_typeid(int ncid, const char *name, nc_type *typeidp); + +/* Get the name, size, and number of fields in a compound type. */ +EXTERNL int +nc_inq_compound(int ncid, nc_type xtype, char *name, size_t *sizep, + size_t *nfieldsp); + +/* Get the name of a compound type. */ +EXTERNL int +nc_inq_compound_name(int ncid, nc_type xtype, char *name); + +/* Get the size of a compound type. */ +EXTERNL int +nc_inq_compound_size(int ncid, nc_type xtype, size_t *sizep); + +/* Get the number of fields in this compound type. */ +EXTERNL int +nc_inq_compound_nfields(int ncid, nc_type xtype, size_t *nfieldsp); + +/* Given the xtype and the fieldid, get all info about it. */ +EXTERNL int +nc_inq_compound_field(int ncid, nc_type xtype, int fieldid, char *name, + size_t *offsetp, nc_type *field_typeidp, int *ndimsp, + int *dim_sizesp); + +/* Given the typeid and the fieldid, get the name. */ +EXTERNL int +nc_inq_compound_fieldname(int ncid, nc_type xtype, int fieldid, + char *name); + +/* Given the xtype and the name, get the fieldid. */ +EXTERNL int +nc_inq_compound_fieldindex(int ncid, nc_type xtype, const char *name, + int *fieldidp); + +/* Given the xtype and fieldid, get the offset. */ +EXTERNL int +nc_inq_compound_fieldoffset(int ncid, nc_type xtype, int fieldid, + size_t *offsetp); + +/* Given the xtype and the fieldid, get the type of that field. */ +EXTERNL int +nc_inq_compound_fieldtype(int ncid, nc_type xtype, int fieldid, + nc_type *field_typeidp); + +/* Given the xtype and the fieldid, get the number of dimensions for + * that field (scalars are 0). */ +EXTERNL int +nc_inq_compound_fieldndims(int ncid, nc_type xtype, int fieldid, + int *ndimsp); + +/* Given the xtype and the fieldid, get the sizes of dimensions for + * that field. User must have allocated storage for the dim_sizes. */ +EXTERNL int +nc_inq_compound_fielddim_sizes(int ncid, nc_type xtype, int fieldid, + int *dim_sizes); + +/** This is the type of arrays of vlens. */ +typedef struct { + size_t len; /**< Length of VL data (in base type units) */ + void *p; /**< Pointer to VL data */ +} nc_vlen_t; + +/** Calculate an offset for creating a compound type. This calls a + * mysterious C macro which was found carved into one of the blocks of + * the Newgrange passage tomb in County Meath, Ireland. This code has + * been carbon dated to 3200 B.C.E. */ +#define NC_COMPOUND_OFFSET(S,M) (offsetof(S,M)) + +/* Create a variable length type. */ +EXTERNL int +nc_def_vlen(int ncid, const char *name, nc_type base_typeid, nc_type *xtypep); + +/* Find out about a vlen. */ +EXTERNL int +nc_inq_vlen(int ncid, nc_type xtype, char *name, size_t *datum_sizep, + nc_type *base_nc_typep); + +/* When you read VLEN type the library will actually allocate the + * storage space for the data. This storage space must be freed, so + * pass the pointer back to this function, when you're done with the + * data, and it will free the vlen memory. */ +EXTERNL int +nc_free_vlen(nc_vlen_t *vl); + +EXTERNL int +nc_free_vlens(size_t len, nc_vlen_t vlens[]); + +/* Put or get one element in a vlen array. */ +EXTERNL int +nc_put_vlen_element(int ncid, int typeid1, void *vlen_element, + size_t len, const void *data); + +EXTERNL int +nc_get_vlen_element(int ncid, int typeid1, const void *vlen_element, + size_t *len, void *data); + +/* When you read the string type the library will allocate the storage + * space for the data. This storage space must be freed, so pass the + * pointer back to this function, when you're done with the data, and + * it will free the string memory. */ +EXTERNL int +nc_free_string(size_t len, char **data); + +/* Find out about a user defined type. */ +EXTERNL int +nc_inq_user_type(int ncid, nc_type xtype, char *name, size_t *size, + nc_type *base_nc_typep, size_t *nfieldsp, int *classp); + +/* Write an attribute of any type. */ +EXTERNL int +nc_put_att(int ncid, int varid, const char *name, nc_type xtype, + size_t len, const void *op); + +/* Read an attribute of any type. */ +EXTERNL int +nc_get_att(int ncid, int varid, const char *name, void *ip); + +/* Enum type. */ + +/* Create an enum type. Provide a base type and a name. At the moment + * only ints are accepted as base types. */ +EXTERNL int +nc_def_enum(int ncid, nc_type base_typeid, const char *name, + nc_type *typeidp); + +/* Insert a named value into an enum type. The value must fit within + * the size of the enum type, the name size must be <= NC_MAX_NAME. */ +EXTERNL int +nc_insert_enum(int ncid, nc_type xtype, const char *name, + const void *value); + +/* Get information about an enum type: its name, base type and the + * number of members defined. */ +EXTERNL int +nc_inq_enum(int ncid, nc_type xtype, char *name, nc_type *base_nc_typep, + size_t *base_sizep, size_t *num_membersp); + +/* Get information about an enum member: a name and value. Name size + * will be <= NC_MAX_NAME. */ +EXTERNL int +nc_inq_enum_member(int ncid, nc_type xtype, int idx, char *name, + void *value); + + +/* Get enum name from enum value. Name size will be <= NC_MAX_NAME. */ +EXTERNL int +nc_inq_enum_ident(int ncid, nc_type xtype, long long value, char *identifier); + +/* Opaque type. */ + +/* Create an opaque type. Provide a size and a name. */ +EXTERNL int +nc_def_opaque(int ncid, size_t size, const char *name, nc_type *xtypep); + +/* Get information about an opaque type. */ +EXTERNL int +nc_inq_opaque(int ncid, nc_type xtype, char *name, size_t *sizep); + +/* Write entire var of any type. */ +EXTERNL int +nc_put_var(int ncid, int varid, const void *op); + +/* Read entire var of any type. */ +EXTERNL int +nc_get_var(int ncid, int varid, void *ip); + +/* Write one value. */ +EXTERNL int +nc_put_var1(int ncid, int varid, const size_t *indexp, + const void *op); + +/* Read one value. */ +EXTERNL int +nc_get_var1(int ncid, int varid, const size_t *indexp, void *ip); + +/* Write an array of values. */ +EXTERNL int +nc_put_vara(int ncid, int varid, const size_t *startp, + const size_t *countp, const void *op); + +/* Read an array of values. */ +EXTERNL int +nc_get_vara(int ncid, int varid, const size_t *startp, + const size_t *countp, void *ip); + +/* Write slices of an array of values. */ +EXTERNL int +nc_put_vars(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const void *op); + +/* Read slices of an array of values. */ +EXTERNL int +nc_get_vars(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + void *ip); + +/* Write mapped slices of an array of values. */ +EXTERNL int +nc_put_varm(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t *imapp, const void *op); + +/* Read mapped slices of an array of values. */ +EXTERNL int +nc_get_varm(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t *imapp, void *ip); + +/* Extra netcdf-4 stuff. */ + +/* Set compression settings for a variable. Lower is faster, higher is + * better. Must be called after nc_def_var and before nc_enddef. */ +EXTERNL int +nc_def_var_deflate(int ncid, int varid, int shuffle, int deflate, + int deflate_level); + +/* Find out compression settings of a var. */ +EXTERNL int +nc_inq_var_deflate(int ncid, int varid, int *shufflep, + int *deflatep, int *deflate_levelp); + +/* Set szip compression for a variable. */ +EXTERNL int nc_def_var_szip(int ncid, int varid, int options_mask, + int pixels_per_block); + +/* Find out szip settings of a var. */ +EXTERNL int +nc_inq_var_szip(int ncid, int varid, int *options_maskp, int *pixels_per_blockp); + +/* Set fletcher32 checksum for a var. This must be done after nc_def_var + and before nc_enddef. */ +EXTERNL int +nc_def_var_fletcher32(int ncid, int varid, int fletcher32); + +/* Inquire about fletcher32 checksum for a var. */ +EXTERNL int +nc_inq_var_fletcher32(int ncid, int varid, int *fletcher32p); + +/* Define chunking for a variable. This must be done after nc_def_var + and before nc_enddef. */ +EXTERNL int +nc_def_var_chunking(int ncid, int varid, int storage, const size_t *chunksizesp); + +/* Inq chunking stuff for a var. */ +EXTERNL int +nc_inq_var_chunking(int ncid, int varid, int *storagep, size_t *chunksizesp); + +/* Define fill value behavior for a variable. This must be done after + nc_def_var and before nc_enddef. */ +EXTERNL int +nc_def_var_fill(int ncid, int varid, int no_fill, const void *fill_value); + +/* Inq fill value setting for a var. */ +EXTERNL int +nc_inq_var_fill(int ncid, int varid, int *no_fill, void *fill_valuep); + +/* Define the endianness of a variable. */ +EXTERNL int +nc_def_var_endian(int ncid, int varid, int endian); + +/* Learn about the endianness of a variable. */ +EXTERNL int +nc_inq_var_endian(int ncid, int varid, int *endianp); + +/* Define a filter for a variable */ +EXTERNL int +nc_def_var_filter(int ncid, int varid, unsigned int id, size_t nparams, const unsigned int* parms); + +/* Learn about the first filter on a variable */ +EXTERNL int +nc_inq_var_filter(int ncid, int varid, unsigned int* idp, size_t* nparams, unsigned int* params); + +/* Set the fill mode (classic or 64-bit offset files only). */ +EXTERNL int +nc_set_fill(int ncid, int fillmode, int *old_modep); + +/* Set the default nc_create format to NC_FORMAT_CLASSIC, NC_FORMAT_64BIT, + * NC_FORMAT_CDF5, NC_FORMAT_NETCDF4, or NC_FORMAT_NETCDF4_CLASSIC */ +EXTERNL int +nc_set_default_format(int format, int *old_formatp); + +/* Set the cache size, nelems, and preemption policy. */ +EXTERNL int +nc_set_chunk_cache(size_t size, size_t nelems, float preemption); + +/* Get the cache size, nelems, and preemption policy. */ +EXTERNL int +nc_get_chunk_cache(size_t *sizep, size_t *nelemsp, float *preemptionp); + +/* Set the per-variable cache size, nelems, and preemption policy. */ +EXTERNL int +nc_set_var_chunk_cache(int ncid, int varid, size_t size, size_t nelems, + float preemption); + +/* Get the per-variable cache size, nelems, and preemption policy. */ +EXTERNL int +nc_get_var_chunk_cache(int ncid, int varid, size_t *sizep, size_t *nelemsp, + float *preemptionp); + +EXTERNL int +nc_redef(int ncid); + +/* Is this ever used? Convert to parameter form */ +EXTERNL int +nc__enddef(int ncid, size_t h_minfree, size_t v_align, + size_t v_minfree, size_t r_align); + +EXTERNL int +nc_enddef(int ncid); + +EXTERNL int +nc_sync(int ncid); + +EXTERNL int +nc_abort(int ncid); + +EXTERNL int +nc_close(int ncid); + +EXTERNL int +nc_inq(int ncid, int *ndimsp, int *nvarsp, int *nattsp, int *unlimdimidp); + +EXTERNL int +nc_inq_ndims(int ncid, int *ndimsp); + +EXTERNL int +nc_inq_nvars(int ncid, int *nvarsp); + +EXTERNL int +nc_inq_natts(int ncid, int *nattsp); + +EXTERNL int +nc_inq_unlimdim(int ncid, int *unlimdimidp); + +/* The next function is for NetCDF-4 only */ +EXTERNL int +nc_inq_unlimdims(int ncid, int *nunlimdimsp, int *unlimdimidsp); + +/* Added in 3.6.1 to return format of netCDF file. */ +EXTERNL int +nc_inq_format(int ncid, int *formatp); + +/* Added in 4.3.1 to return additional format info */ +EXTERNL int +nc_inq_format_extended(int ncid, int *formatp, int* modep); + +/* Begin _dim */ + +EXTERNL int +nc_def_dim(int ncid, const char *name, size_t len, int *idp); + +EXTERNL int +nc_inq_dimid(int ncid, const char *name, int *idp); + +EXTERNL int +nc_inq_dim(int ncid, int dimid, char *name, size_t *lenp); + +EXTERNL int +nc_inq_dimname(int ncid, int dimid, char *name); + +EXTERNL int +nc_inq_dimlen(int ncid, int dimid, size_t *lenp); + +EXTERNL int +nc_rename_dim(int ncid, int dimid, const char *name); + +/* End _dim */ +/* Begin _att */ + +EXTERNL int +nc_inq_att(int ncid, int varid, const char *name, + nc_type *xtypep, size_t *lenp); + +EXTERNL int +nc_inq_attid(int ncid, int varid, const char *name, int *idp); + +EXTERNL int +nc_inq_atttype(int ncid, int varid, const char *name, nc_type *xtypep); + +EXTERNL int +nc_inq_attlen(int ncid, int varid, const char *name, size_t *lenp); + +EXTERNL int +nc_inq_attname(int ncid, int varid, int attnum, char *name); + +EXTERNL int +nc_copy_att(int ncid_in, int varid_in, const char *name, int ncid_out, int varid_out); + +EXTERNL int +nc_rename_att(int ncid, int varid, const char *name, const char *newname); + +EXTERNL int +nc_del_att(int ncid, int varid, const char *name); + +/* End _att */ +/* Begin {put,get}_att */ +EXTERNL int +nc_put_att_text(int ncid, int varid, const char *name, + size_t len, const char *op); + +EXTERNL int +nc_get_att_text(int ncid, int varid, const char *name, char *ip); + +EXTERNL int +nc_put_att_string(int ncid, int varid, const char *name, + size_t len, const char **op); + +EXTERNL int +nc_get_att_string(int ncid, int varid, const char *name, char **ip); + +EXTERNL int +nc_put_att_uchar(int ncid, int varid, const char *name, nc_type xtype, + size_t len, const unsigned char *op); + +EXTERNL int +nc_get_att_uchar(int ncid, int varid, const char *name, unsigned char *ip); + +EXTERNL int +nc_put_att_schar(int ncid, int varid, const char *name, nc_type xtype, + size_t len, const signed char *op); + +EXTERNL int +nc_get_att_schar(int ncid, int varid, const char *name, signed char *ip); + +EXTERNL int +nc_put_att_short(int ncid, int varid, const char *name, nc_type xtype, + size_t len, const short *op); + +EXTERNL int +nc_get_att_short(int ncid, int varid, const char *name, short *ip); + +EXTERNL int +nc_put_att_int(int ncid, int varid, const char *name, nc_type xtype, + size_t len, const int *op); + +EXTERNL int +nc_get_att_int(int ncid, int varid, const char *name, int *ip); + +EXTERNL int +nc_put_att_long(int ncid, int varid, const char *name, nc_type xtype, + size_t len, const long *op); + +EXTERNL int +nc_get_att_long(int ncid, int varid, const char *name, long *ip); + +EXTERNL int +nc_put_att_float(int ncid, int varid, const char *name, nc_type xtype, + size_t len, const float *op); + +EXTERNL int +nc_get_att_float(int ncid, int varid, const char *name, float *ip); + +EXTERNL int +nc_put_att_double(int ncid, int varid, const char *name, nc_type xtype, + size_t len, const double *op); + +EXTERNL int +nc_get_att_double(int ncid, int varid, const char *name, double *ip); + +EXTERNL int +nc_put_att_ushort(int ncid, int varid, const char *name, nc_type xtype, + size_t len, const unsigned short *op); + +EXTERNL int +nc_get_att_ushort(int ncid, int varid, const char *name, unsigned short *ip); + +EXTERNL int +nc_put_att_uint(int ncid, int varid, const char *name, nc_type xtype, + size_t len, const unsigned int *op); + +EXTERNL int +nc_get_att_uint(int ncid, int varid, const char *name, unsigned int *ip); + +EXTERNL int +nc_put_att_longlong(int ncid, int varid, const char *name, nc_type xtype, + size_t len, const long long *op); + +EXTERNL int +nc_get_att_longlong(int ncid, int varid, const char *name, long long *ip); + +EXTERNL int +nc_put_att_ulonglong(int ncid, int varid, const char *name, nc_type xtype, + size_t len, const unsigned long long *op); + +EXTERNL int +nc_get_att_ulonglong(int ncid, int varid, const char *name, + unsigned long long *ip); + + +/* End {put,get}_att */ +/* Begin _var */ + +EXTERNL int +nc_def_var(int ncid, const char *name, nc_type xtype, int ndims, + const int *dimidsp, int *varidp); + +EXTERNL int +nc_inq_var(int ncid, int varid, char *name, nc_type *xtypep, + int *ndimsp, int *dimidsp, int *nattsp); + +EXTERNL int +nc_inq_varid(int ncid, const char *name, int *varidp); + +EXTERNL int +nc_inq_varname(int ncid, int varid, char *name); + +EXTERNL int +nc_inq_vartype(int ncid, int varid, nc_type *xtypep); + +EXTERNL int +nc_inq_varndims(int ncid, int varid, int *ndimsp); + +EXTERNL int +nc_inq_vardimid(int ncid, int varid, int *dimidsp); + +EXTERNL int +nc_inq_varnatts(int ncid, int varid, int *nattsp); + +EXTERNL int +nc_rename_var(int ncid, int varid, const char *name); + +EXTERNL int +nc_copy_var(int ncid_in, int varid, int ncid_out); + +#ifndef ncvarcpy +/* support the old name for now */ +#define ncvarcpy(ncid_in, varid, ncid_out) ncvarcopy((ncid_in), (varid), (ncid_out)) +#endif + +/* End _var */ +/* Begin {put,get}_var1 */ + +EXTERNL int +nc_put_var1_text(int ncid, int varid, const size_t *indexp, const char *op); + +EXTERNL int +nc_get_var1_text(int ncid, int varid, const size_t *indexp, char *ip); + +EXTERNL int +nc_put_var1_uchar(int ncid, int varid, const size_t *indexp, + const unsigned char *op); + +EXTERNL int +nc_get_var1_uchar(int ncid, int varid, const size_t *indexp, + unsigned char *ip); + +EXTERNL int +nc_put_var1_schar(int ncid, int varid, const size_t *indexp, + const signed char *op); + +EXTERNL int +nc_get_var1_schar(int ncid, int varid, const size_t *indexp, + signed char *ip); + +EXTERNL int +nc_put_var1_short(int ncid, int varid, const size_t *indexp, + const short *op); + +EXTERNL int +nc_get_var1_short(int ncid, int varid, const size_t *indexp, + short *ip); + +EXTERNL int +nc_put_var1_int(int ncid, int varid, const size_t *indexp, const int *op); + +EXTERNL int +nc_get_var1_int(int ncid, int varid, const size_t *indexp, int *ip); + +EXTERNL int +nc_put_var1_long(int ncid, int varid, const size_t *indexp, const long *op); + +EXTERNL int +nc_get_var1_long(int ncid, int varid, const size_t *indexp, long *ip); + +EXTERNL int +nc_put_var1_float(int ncid, int varid, const size_t *indexp, const float *op); + +EXTERNL int +nc_get_var1_float(int ncid, int varid, const size_t *indexp, float *ip); + +EXTERNL int +nc_put_var1_double(int ncid, int varid, const size_t *indexp, const double *op); + +EXTERNL int +nc_get_var1_double(int ncid, int varid, const size_t *indexp, double *ip); + +EXTERNL int +nc_put_var1_ushort(int ncid, int varid, const size_t *indexp, + const unsigned short *op); + +EXTERNL int +nc_get_var1_ushort(int ncid, int varid, const size_t *indexp, + unsigned short *ip); + +EXTERNL int +nc_put_var1_uint(int ncid, int varid, const size_t *indexp, + const unsigned int *op); + +EXTERNL int +nc_get_var1_uint(int ncid, int varid, const size_t *indexp, + unsigned int *ip); + +EXTERNL int +nc_put_var1_longlong(int ncid, int varid, const size_t *indexp, + const long long *op); + +EXTERNL int +nc_get_var1_longlong(int ncid, int varid, const size_t *indexp, + long long *ip); + +EXTERNL int +nc_put_var1_ulonglong(int ncid, int varid, const size_t *indexp, + const unsigned long long *op); + +EXTERNL int +nc_get_var1_ulonglong(int ncid, int varid, const size_t *indexp, + unsigned long long *ip); + +EXTERNL int +nc_put_var1_string(int ncid, int varid, const size_t *indexp, + const char **op); + +EXTERNL int +nc_get_var1_string(int ncid, int varid, const size_t *indexp, + char **ip); + +/* End {put,get}_var1 */ +/* Begin {put,get}_vara */ + +EXTERNL int +nc_put_vara_text(int ncid, int varid, const size_t *startp, + const size_t *countp, const char *op); + +EXTERNL int +nc_get_vara_text(int ncid, int varid, const size_t *startp, + const size_t *countp, char *ip); + +EXTERNL int +nc_put_vara_uchar(int ncid, int varid, const size_t *startp, + const size_t *countp, const unsigned char *op); + +EXTERNL int +nc_get_vara_uchar(int ncid, int varid, const size_t *startp, + const size_t *countp, unsigned char *ip); + +EXTERNL int +nc_put_vara_schar(int ncid, int varid, const size_t *startp, + const size_t *countp, const signed char *op); + +EXTERNL int +nc_get_vara_schar(int ncid, int varid, const size_t *startp, + const size_t *countp, signed char *ip); + +EXTERNL int +nc_put_vara_short(int ncid, int varid, const size_t *startp, + const size_t *countp, const short *op); + +EXTERNL int +nc_get_vara_short(int ncid, int varid, const size_t *startp, + const size_t *countp, short *ip); + +EXTERNL int +nc_put_vara_int(int ncid, int varid, const size_t *startp, + const size_t *countp, const int *op); + +EXTERNL int +nc_get_vara_int(int ncid, int varid, const size_t *startp, + const size_t *countp, int *ip); + +EXTERNL int +nc_put_vara_long(int ncid, int varid, const size_t *startp, + const size_t *countp, const long *op); + +EXTERNL int +nc_get_vara_long(int ncid, int varid, + const size_t *startp, const size_t *countp, long *ip); + +EXTERNL int +nc_put_vara_float(int ncid, int varid, + const size_t *startp, const size_t *countp, const float *op); + +EXTERNL int +nc_get_vara_float(int ncid, int varid, + const size_t *startp, const size_t *countp, float *ip); + +EXTERNL int +nc_put_vara_double(int ncid, int varid, const size_t *startp, + const size_t *countp, const double *op); + +EXTERNL int +nc_get_vara_double(int ncid, int varid, const size_t *startp, + const size_t *countp, double *ip); + +EXTERNL int +nc_put_vara_ushort(int ncid, int varid, const size_t *startp, + const size_t *countp, const unsigned short *op); + +EXTERNL int +nc_get_vara_ushort(int ncid, int varid, const size_t *startp, + const size_t *countp, unsigned short *ip); + +EXTERNL int +nc_put_vara_uint(int ncid, int varid, const size_t *startp, + const size_t *countp, const unsigned int *op); + +EXTERNL int +nc_get_vara_uint(int ncid, int varid, const size_t *startp, + const size_t *countp, unsigned int *ip); + +EXTERNL int +nc_put_vara_longlong(int ncid, int varid, const size_t *startp, + const size_t *countp, const long long *op); + +EXTERNL int +nc_get_vara_longlong(int ncid, int varid, const size_t *startp, + const size_t *countp, long long *ip); + +EXTERNL int +nc_put_vara_ulonglong(int ncid, int varid, const size_t *startp, + const size_t *countp, const unsigned long long *op); + +EXTERNL int +nc_get_vara_ulonglong(int ncid, int varid, const size_t *startp, + const size_t *countp, unsigned long long *ip); + +EXTERNL int +nc_put_vara_string(int ncid, int varid, const size_t *startp, + const size_t *countp, const char **op); + +EXTERNL int +nc_get_vara_string(int ncid, int varid, const size_t *startp, + const size_t *countp, char **ip); + +/* End {put,get}_vara */ +/* Begin {put,get}_vars */ + +EXTERNL int +nc_put_vars_text(int ncid, int varid, + const size_t *startp, const size_t *countp, const ptrdiff_t *stridep, + const char *op); + +EXTERNL int +nc_get_vars_text(int ncid, int varid, + const size_t *startp, const size_t *countp, const ptrdiff_t *stridep, + char *ip); + +EXTERNL int +nc_put_vars_uchar(int ncid, int varid, + const size_t *startp, const size_t *countp, const ptrdiff_t *stridep, + const unsigned char *op); + +EXTERNL int +nc_get_vars_uchar(int ncid, int varid, + const size_t *startp, const size_t *countp, const ptrdiff_t *stridep, + unsigned char *ip); + +EXTERNL int +nc_put_vars_schar(int ncid, int varid, + const size_t *startp, const size_t *countp, const ptrdiff_t *stridep, + const signed char *op); + +EXTERNL int +nc_get_vars_schar(int ncid, int varid, + const size_t *startp, const size_t *countp, const ptrdiff_t *stridep, + signed char *ip); + +EXTERNL int +nc_put_vars_short(int ncid, int varid, + const size_t *startp, const size_t *countp, const ptrdiff_t *stridep, + const short *op); + +EXTERNL int +nc_get_vars_short(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + short *ip); + +EXTERNL int +nc_put_vars_int(int ncid, int varid, + const size_t *startp, const size_t *countp, const ptrdiff_t *stridep, + const int *op); + +EXTERNL int +nc_get_vars_int(int ncid, int varid, + const size_t *startp, const size_t *countp, const ptrdiff_t *stridep, + int *ip); + +EXTERNL int +nc_put_vars_long(int ncid, int varid, + const size_t *startp, const size_t *countp, const ptrdiff_t *stridep, + const long *op); + +EXTERNL int +nc_get_vars_long(int ncid, int varid, + const size_t *startp, const size_t *countp, const ptrdiff_t *stridep, + long *ip); + +EXTERNL int +nc_put_vars_float(int ncid, int varid, + const size_t *startp, const size_t *countp, const ptrdiff_t *stridep, + const float *op); + +EXTERNL int +nc_get_vars_float(int ncid, int varid, + const size_t *startp, const size_t *countp, const ptrdiff_t *stridep, + float *ip); + +EXTERNL int +nc_put_vars_double(int ncid, int varid, + const size_t *startp, const size_t *countp, const ptrdiff_t *stridep, + const double *op); + +EXTERNL int +nc_get_vars_double(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + double *ip); + +EXTERNL int +nc_put_vars_ushort(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const unsigned short *op); + +EXTERNL int +nc_get_vars_ushort(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + unsigned short *ip); + +EXTERNL int +nc_put_vars_uint(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const unsigned int *op); + +EXTERNL int +nc_get_vars_uint(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + unsigned int *ip); + +EXTERNL int +nc_put_vars_longlong(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const long long *op); + +EXTERNL int +nc_get_vars_longlong(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + long long *ip); + +EXTERNL int +nc_put_vars_ulonglong(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const unsigned long long *op); + +EXTERNL int +nc_get_vars_ulonglong(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + unsigned long long *ip); + +EXTERNL int +nc_put_vars_string(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const char **op); + +EXTERNL int +nc_get_vars_string(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + char **ip); + +/* End {put,get}_vars */ +/* Begin {put,get}_varm */ + +EXTERNL int +nc_put_varm_text(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t *imapp, const char *op); + +EXTERNL int +nc_get_varm_text(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t *imapp, char *ip); + +EXTERNL int +nc_put_varm_uchar(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t *imapp, const unsigned char *op); + +EXTERNL int +nc_get_varm_uchar(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t *imapp, unsigned char *ip); + +EXTERNL int +nc_put_varm_schar(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t *imapp, const signed char *op); + +EXTERNL int +nc_get_varm_schar(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t *imapp, signed char *ip); + +EXTERNL int +nc_put_varm_short(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t *imapp, const short *op); + +EXTERNL int +nc_get_varm_short(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t *imapp, short *ip); + +EXTERNL int +nc_put_varm_int(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t *imapp, const int *op); + +EXTERNL int +nc_get_varm_int(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t *imapp, int *ip); + +EXTERNL int +nc_put_varm_long(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t *imapp, const long *op); + +EXTERNL int +nc_get_varm_long(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t *imapp, long *ip); + +EXTERNL int +nc_put_varm_float(int ncid, int varid,const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t *imapp, const float *op); + +EXTERNL int +nc_get_varm_float(int ncid, int varid,const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t *imapp, float *ip); + +EXTERNL int +nc_put_varm_double(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t *imapp, const double *op); + +EXTERNL int +nc_get_varm_double(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t * imapp, double *ip); + +EXTERNL int +nc_put_varm_ushort(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t * imapp, const unsigned short *op); + +EXTERNL int +nc_get_varm_ushort(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t * imapp, unsigned short *ip); + +EXTERNL int +nc_put_varm_uint(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t * imapp, const unsigned int *op); + +EXTERNL int +nc_get_varm_uint(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t * imapp, unsigned int *ip); + +EXTERNL int +nc_put_varm_longlong(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t * imapp, const long long *op); + +EXTERNL int +nc_get_varm_longlong(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t * imapp, long long *ip); + +EXTERNL int +nc_put_varm_ulonglong(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t * imapp, const unsigned long long *op); + +EXTERNL int +nc_get_varm_ulonglong(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t * imapp, unsigned long long *ip); + +EXTERNL int +nc_put_varm_string(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t * imapp, const char **op); + +EXTERNL int +nc_get_varm_string(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t * imapp, char **ip); + +/* End {put,get}_varm */ +/* Begin {put,get}_var */ + +EXTERNL int +nc_put_var_text(int ncid, int varid, const char *op); + +EXTERNL int +nc_get_var_text(int ncid, int varid, char *ip); + +EXTERNL int +nc_put_var_uchar(int ncid, int varid, const unsigned char *op); + +EXTERNL int +nc_get_var_uchar(int ncid, int varid, unsigned char *ip); + +EXTERNL int +nc_put_var_schar(int ncid, int varid, const signed char *op); + +EXTERNL int +nc_get_var_schar(int ncid, int varid, signed char *ip); + +EXTERNL int +nc_put_var_short(int ncid, int varid, const short *op); + +EXTERNL int +nc_get_var_short(int ncid, int varid, short *ip); + +EXTERNL int +nc_put_var_int(int ncid, int varid, const int *op); + +EXTERNL int +nc_get_var_int(int ncid, int varid, int *ip); + +EXTERNL int +nc_put_var_long(int ncid, int varid, const long *op); + +EXTERNL int +nc_get_var_long(int ncid, int varid, long *ip); + +EXTERNL int +nc_put_var_float(int ncid, int varid, const float *op); + +EXTERNL int +nc_get_var_float(int ncid, int varid, float *ip); + +EXTERNL int +nc_put_var_double(int ncid, int varid, const double *op); + +EXTERNL int +nc_get_var_double(int ncid, int varid, double *ip); + +EXTERNL int +nc_put_var_ushort(int ncid, int varid, const unsigned short *op); + +EXTERNL int +nc_get_var_ushort(int ncid, int varid, unsigned short *ip); + +EXTERNL int +nc_put_var_uint(int ncid, int varid, const unsigned int *op); + +EXTERNL int +nc_get_var_uint(int ncid, int varid, unsigned int *ip); + +EXTERNL int +nc_put_var_longlong(int ncid, int varid, const long long *op); + +EXTERNL int +nc_get_var_longlong(int ncid, int varid, long long *ip); + +EXTERNL int +nc_put_var_ulonglong(int ncid, int varid, const unsigned long long *op); + +EXTERNL int +nc_get_var_ulonglong(int ncid, int varid, unsigned long long *ip); + +EXTERNL int +nc_put_var_string(int ncid, int varid, const char **op); + +EXTERNL int +nc_get_var_string(int ncid, int varid, char **ip); + +/* Begin Deprecated, same as functions with "_ubyte" replaced by "_uchar" */ +EXTERNL int +nc_put_att_ubyte(int ncid, int varid, const char *name, nc_type xtype, + size_t len, const unsigned char *op); +EXTERNL int +nc_get_att_ubyte(int ncid, int varid, const char *name, + unsigned char *ip); +EXTERNL int +nc_put_var1_ubyte(int ncid, int varid, const size_t *indexp, + const unsigned char *op); +EXTERNL int +nc_get_var1_ubyte(int ncid, int varid, const size_t *indexp, + unsigned char *ip); +EXTERNL int +nc_put_vara_ubyte(int ncid, int varid, const size_t *startp, + const size_t *countp, const unsigned char *op); +EXTERNL int +nc_get_vara_ubyte(int ncid, int varid, const size_t *startp, + const size_t *countp, unsigned char *ip); +EXTERNL int +nc_put_vars_ubyte(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const unsigned char *op); +EXTERNL int +nc_get_vars_ubyte(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + unsigned char *ip); +EXTERNL int +nc_put_varm_ubyte(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t * imapp, const unsigned char *op); +EXTERNL int +nc_get_varm_ubyte(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t * imapp, unsigned char *ip); +EXTERNL int +nc_put_var_ubyte(int ncid, int varid, const unsigned char *op); +EXTERNL int +nc_get_var_ubyte(int ncid, int varid, unsigned char *ip); +/* End Deprecated */ + +/* Set the log level. 0 shows only errors, 1 only major messages, + * etc., to 5, which shows way too much information. */ +EXTERNL int +nc_set_log_level(int new_level); + +/* Use this to turn off logging by calling + nc_log_level(NC_TURN_OFF_LOGGING) */ +#define NC_TURN_OFF_LOGGING (-1) + +/* Show the netCDF library's in-memory metadata for a file. */ +EXTERNL int +nc_show_metadata(int ncid); + +/* End {put,get}_var */ + +/* Delete a file. */ +EXTERNL int +nc_delete(const char *path); + +/* + * The following functions were written to accommodate the old Cray + * systems. Modern HPC systems do not use these functions any more, + * but use the nc_open_par()/nc_create_par() functions instead. These + * functions are retained for backward compatibibility. These + * functions work as advertised, but you can only use "processor + * element" 0. + */ + +EXTERNL int +nc__create_mp(const char *path, int cmode, size_t initialsz, int basepe, + size_t *chunksizehintp, int *ncidp); + +EXTERNL int +nc__open_mp(const char *path, int mode, int basepe, + size_t *chunksizehintp, int *ncidp); + +EXTERNL int +nc_delete_mp(const char *path, int basepe); + +EXTERNL int +nc_set_base_pe(int ncid, int pe); + +EXTERNL int +nc_inq_base_pe(int ncid, int *pe); + +/* This v2 function is used in the nc_test program. */ +EXTERNL int +nctypelen(nc_type datatype); + +/* Begin v2.4 backward compatibility */ + +/** Backward compatible alias. */ +/**@{*/ +#define FILL_BYTE NC_FILL_BYTE +#define FILL_CHAR NC_FILL_CHAR +#define FILL_SHORT NC_FILL_SHORT +#define FILL_LONG NC_FILL_INT +#define FILL_FLOAT NC_FILL_FLOAT +#define FILL_DOUBLE NC_FILL_DOUBLE + +#define MAX_NC_DIMS NC_MAX_DIMS +#define MAX_NC_ATTRS NC_MAX_ATTRS +#define MAX_NC_VARS NC_MAX_VARS +#define MAX_NC_NAME NC_MAX_NAME +#define MAX_VAR_DIMS NC_MAX_VAR_DIMS +/**@}*/ + + +/* + * Global error status + */ +EXTERNL int ncerr; + +#define NC_ENTOOL NC_EMAXNAME /**< Backward compatibility */ +#define NC_EXDR (-32) /**< V2 API error. */ +#define NC_SYSERR (-31) /**< V2 API system error. */ + +/* + * Global options variable. + * Used to determine behavior of error handler. + */ +#define NC_FATAL 1 /**< For V2 API, exit on error. */ +#define NC_VERBOSE 2 /**< For V2 API, be verbose on error. */ + +/** V2 API error handling. Default is (NC_FATAL | NC_VERBOSE). */ +EXTERNL int ncopts; + +EXTERNL void +nc_advise(const char *cdf_routine_name, int err, const char *fmt,...); + +/** + * C data type corresponding to a netCDF NC_LONG argument, a signed 32 + * bit object. This is the only thing in this file which architecture + * dependent. + */ +typedef int nclong; + +EXTERNL int +nccreate(const char* path, int cmode); + +EXTERNL int +ncopen(const char* path, int mode); + +EXTERNL int +ncsetfill(int ncid, int fillmode); + +EXTERNL int +ncredef(int ncid); + +EXTERNL int +ncendef(int ncid); + +EXTERNL int +ncsync(int ncid); + +EXTERNL int +ncabort(int ncid); + +EXTERNL int +ncclose(int ncid); + +EXTERNL int +ncinquire(int ncid, int *ndimsp, int *nvarsp, int *nattsp, int *unlimdimp); + +EXTERNL int +ncdimdef(int ncid, const char *name, long len); + +EXTERNL int +ncdimid(int ncid, const char *name); + +EXTERNL int +ncdiminq(int ncid, int dimid, char *name, long *lenp); + +EXTERNL int +ncdimrename(int ncid, int dimid, const char *name); + +EXTERNL int +ncattput(int ncid, int varid, const char *name, nc_type xtype, + int len, const void *op); + +EXTERNL int +ncattinq(int ncid, int varid, const char *name, nc_type *xtypep, int *lenp); + +EXTERNL int +ncattget(int ncid, int varid, const char *name, void *ip); + +EXTERNL int +ncattcopy(int ncid_in, int varid_in, const char *name, int ncid_out, + int varid_out); + +EXTERNL int +ncattname(int ncid, int varid, int attnum, char *name); + +EXTERNL int +ncattrename(int ncid, int varid, const char *name, const char *newname); + +EXTERNL int +ncattdel(int ncid, int varid, const char *name); + +EXTERNL int +ncvardef(int ncid, const char *name, nc_type xtype, + int ndims, const int *dimidsp); + +EXTERNL int +ncvarid(int ncid, const char *name); + +EXTERNL int +ncvarinq(int ncid, int varid, char *name, nc_type *xtypep, + int *ndimsp, int *dimidsp, int *nattsp); + +EXTERNL int +ncvarput1(int ncid, int varid, const long *indexp, const void *op); + +EXTERNL int +ncvarget1(int ncid, int varid, const long *indexp, void *ip); + +EXTERNL int +ncvarput(int ncid, int varid, const long *startp, const long *countp, + const void *op); + +EXTERNL int +ncvarget(int ncid, int varid, const long *startp, const long *countp, + void *ip); + +EXTERNL int +ncvarputs(int ncid, int varid, const long *startp, const long *countp, + const long *stridep, const void *op); + +EXTERNL int +ncvargets(int ncid, int varid, const long *startp, const long *countp, + const long *stridep, void *ip); + +EXTERNL int +ncvarputg(int ncid, int varid, const long *startp, const long *countp, + const long *stridep, const long *imapp, const void *op); + +EXTERNL int +ncvargetg(int ncid, int varid, const long *startp, const long *countp, + const long *stridep, const long *imapp, void *ip); + +EXTERNL int +ncvarrename(int ncid, int varid, const char *name); + +EXTERNL int +ncrecinq(int ncid, int *nrecvarsp, int *recvaridsp, long *recsizesp); + +EXTERNL int +ncrecget(int ncid, long recnum, void **datap); + +EXTERNL int +ncrecput(int ncid, long recnum, void *const *datap); + +/* This function may be called to force the library to + initialize itself. It is not required, however. +*/ +EXTERNL int nc_initialize(void); + +/* This function may be called to force the library to + cleanup global memory so that memory checkers will not + report errors. It is not required, however. +*/ +EXTERNL int nc_finalize(void); + +#if defined(__cplusplus) +} +#endif + +/* Define two hard-coded functionality-related + (as requested by community developers) macros. + This is not going to be standard practice. + Don't remove without an in-place replacement of some sort, + the are now (for better or worse) used by downstream + software external to Unidata. */ +#ifndef NC_HAVE_RENAME_GRP +#define NC_HAVE_RENAME_GRP /*!< rename_grp() support. */ +#endif + +#ifndef NC_HAVE_INQ_FORMAT_EXTENDED +#define NC_HAVE_INQ_FORMAT_EXTENDED /*!< inq_format_extended() support. */ +#endif + +#define NC_HAVE_META_H + +#endif /* _NETCDF_ */ diff --git a/src/tripod.hpp b/src/tripod.hpp index 8551fb8..4574097 100644 --- a/src/tripod.hpp +++ b/src/tripod.hpp @@ -14,11 +14,11 @@ * TRIPOD: a "restricted" delaunay tessellator. -------------------------------------------------------- * - * Last updated: 02 July, 2019 + * Last updated: 01 March, 2020 * - * Copyright 2013 -- 2019 + * Copyright 2013 -- 2020 * Darren Engwirda - * darren.engwirda@columbia.edu + * d.engwirda@gmail.com * https://github.com/dengwirda * -------------------------------------------------------- @@ -83,7 +83,7 @@ typename rdel_type , typename jlog_data > - __normal_call void_type rdel_euclidean_2d ( + __normal_call void_type tria_euclidean_2d ( geom_type &_geom, init_type &_init, rdel_type &_rdel, @@ -92,7 +92,7 @@ ) { { - /*------------------------------ call rDEL kernel */ + /*---------------------------------- call rDEL kernel */ typedef mesh::rdel_make_2d < rdel_type , geom_type , @@ -101,12 +101,13 @@ typedef jcfg_data::mesh_opts rdel_opts ; - rdel_opts *_opts = + rdel_opts *_opts = &_args._mesh_opts ; rdel_func::rdel_make ( - _geom, _init , - _rdel, *_opts , _jlog ) ; + _geom, _init , + _rdel, + *_opts, _jlog ) ; } } @@ -122,7 +123,7 @@ typename rdel_type , typename jlog_data > - __normal_call void_type rdel_euclidean_3d ( + __normal_call void_type tria_euclidean_3d ( geom_type &_geom, init_type &_init, rdel_type &_rdel, @@ -131,7 +132,7 @@ ) { { - /*------------------------------ call rDEL kernel */ + /*---------------------------------- call rDEL kernel */ typedef mesh::rdel_make_3d < rdel_type , geom_type , @@ -140,12 +141,13 @@ typedef jcfg_data::mesh_opts rdel_opts ; - rdel_opts *_opts = + rdel_opts *_opts = &_args._mesh_opts ; rdel_func::rdel_make ( - _geom, _init , - _rdel, *_opts , _jlog ) ; + _geom, _init , + _rdel, + *_opts, _jlog ) ; } } @@ -158,12 +160,12 @@ template < typename jlog_data > - __normal_call iptr_type rdel_impl ( + __normal_call iptr_type tria_core ( jcfg_data &_args, jlog_data &_jlog, mesh_data &_init, geom_data &_geom, - rdel_data &_rdel + mesh_data &_mesh ) { iptr_type _errv = __no_error ; @@ -175,15 +177,15 @@ jmsh_kind::euclidean_mesh) { /*----------- have euclidean-mesh GEOM kernel */ - _rdel._kind = + _mesh._kind = jmsh_kind::euclidean_mesh; - _rdel._ndim = +2 ; + _mesh._ndim = +2 ; - rdel_euclidean_2d ( + tria_euclidean_2d ( _geom._euclidean_mesh_2d, _init._euclidean_mesh_2d, - _rdel._euclidean_rdel_2d, + _mesh._euclidean_rdel_2d, _args, _jlog) ; } else @@ -192,15 +194,15 @@ jmsh_kind::euclidean_mesh) { /*----------- have euclidean-mesh GEOM kernel */ - _rdel._kind = + _mesh._kind = jmsh_kind::euclidean_mesh; - _rdel._ndim = +3 ; + _mesh._ndim = +3 ; - rdel_euclidean_3d ( + tria_euclidean_3d ( _geom._euclidean_mesh_3d, _init._euclidean_mesh_3d, - _rdel._euclidean_rdel_3d, + _mesh._euclidean_rdel_3d, _args, _jlog) ; } else @@ -208,15 +210,15 @@ jmsh_kind::ellipsoid_mesh) { /*----------- have ellipsoid-mesh GEOM kernel */ - _rdel._kind = + _mesh._kind = jmsh_kind::euclidean_mesh; - _rdel._ndim = +3 ; + _mesh._ndim = +3 ; - rdel_euclidean_3d ( + tria_euclidean_3d ( _geom._ellipsoid_mesh_3d, _init._euclidean_mesh_3d, - _rdel._euclidean_rdel_3d, + _mesh._euclidean_rdel_3d, _args, _jlog) ; } } @@ -250,10 +252,9 @@ { iptr_type _retv = +0; - mesh_data _init ; // INIT data geom_data _geom ; // GEOM data - rdel_data _rdel ; // TRIA data - jcfg_data _jcfg ; + mesh_data _mesh ; // TRIA data + jcfg_data _jcfg ; // CFG. data # ifdef __use_timers typename std ::chrono:: @@ -268,6 +269,9 @@ __unreferenced(_time) ; # endif//__use_timers + /*--------------------------------- init. geo. kernel */ + mp_float::exactinit() ; + /*--------------------------------- init. output data */ jigsaw_init_msh_t(_mmsh) ; @@ -331,14 +335,14 @@ if ((_retv = copy_init ( _jcfg, _jlog, - _init,*_imsh)) != __no_error) + _mesh,*_imsh)) != __no_error) { return _retv ; } if ((_retv = test_init ( _jcfg, - _jlog, _init)) != __no_error) + _jlog, _mesh)) != __no_error) { return _retv ; } @@ -351,7 +355,7 @@ if (_imsh != nullptr ) { - /*--------------------------------- assemble init-con */ + /*--------------------------------- initialise i.c.'s */ _jlog.push ( __jloglndv "\n" ) ; _jlog.push ( " Forming INIT data...\n\n" ) ; @@ -360,11 +364,6 @@ _ttic = _time.now(); # endif//__use_timers - //_init._euclidean_mesh_2d. - // _mesh.make_link(); - //_init._euclidean_mesh_3d. - // _mesh.make_link(); - if (_jcfg._verbosity > 0 ) { @@ -373,7 +372,7 @@ if ((_retv = echo_init ( _jcfg, - _jlog, _init)) != __no_error) + _jlog, _mesh)) != __no_error) { return _retv ; } @@ -463,10 +462,10 @@ # endif//__use_timers if ((_retv = - TRIPOD ::rdel_impl ( + TRIPOD ::tria_core ( _jcfg, _jlog , - _init, - _geom, _rdel)) != __no_error) + _mesh, + _geom, _mesh)) != __no_error) { return _retv ; } @@ -493,7 +492,7 @@ if ((_retv = save_rdel ( _jcfg, _jlog , - _rdel,*_mmsh)) != __no_error) + _mesh,*_mmsh)) != __no_error) { return _retv ; } @@ -504,7 +503,7 @@ if ((_retv = save_tria ( _jcfg, _jlog , - _rdel,*_mmsh)) != __no_error) + _mesh,*_mmsh)) != __no_error) { return _retv ; } @@ -531,9 +530,8 @@ char **_argv ) { - mesh_data _init ; // INIT data geom_data _geom ; // GEOM data - rdel_data _rdel ; // TRIA data + mesh_data _mesh ; // TRIA data # ifdef __use_timers typename std ::chrono:: @@ -548,6 +546,9 @@ __unreferenced(_time) ; # endif//__use_timers + /*--------------------------------- init. geo. kernel */ + mp_float::exactinit() ; + /*-------------------------- find *.JFCG file in args */ iptr_type _retv = -1 ; jcfg_data _jcfg ; @@ -582,9 +583,7 @@ break ; } - std::string _path ; - std::string _name ; - std::string _fext ; + std::string _path , _name , _fext ; file_part ( _ssrc , _path , _name , _fext ) ; @@ -657,14 +656,14 @@ if ((_retv = read_init ( _jcfg, - _jlog, _init)) != __no_error) + _jlog, _mesh)) != __no_error) { return _retv ; } if ((_retv = test_init ( _jcfg, - _jlog, _init)) != __no_error) + _jlog, _mesh)) != __no_error) { return _retv ; } @@ -677,7 +676,7 @@ if(!_jcfg._init_file.empty()) { - /*--------------------------------- assemble init-con */ + /*--------------------------------- initialise i.c.'s */ _jlog.push ( __jloglndv "\n" ) ; _jlog.push ( " Forming INIT data...\n\n" ) ; @@ -686,11 +685,6 @@ _ttic = _time.now(); # endif//__use_timers - //_init._euclidean_mesh_2d. - // _mesh.make_link(); - //_init._euclidean_mesh_3d. - // _mesh.make_link(); - if (_jcfg._verbosity > 0 ) { @@ -699,7 +693,7 @@ if ((_retv = echo_init ( _jcfg, - _jlog, _init)) != __no_error) + _jlog, _mesh)) != __no_error) { return _retv ; } @@ -789,10 +783,10 @@ # endif//__use_timers if ((_retv = - TRIPOD ::rdel_impl ( + TRIPOD ::tria_core ( _jcfg, _jlog , - _init, - _geom, _rdel)) != __no_error) + _mesh, + _geom, _mesh)) != __no_error) { return _retv ; } @@ -816,7 +810,7 @@ if ((_retv = save_tria ( _jcfg, - _jlog, _rdel)) != __no_error) + _jlog, _mesh)) != __no_error) { return _retv ; } @@ -844,7 +838,7 @@ if ((_retv = save_rdel ( _jcfg, - _jlog, _rdel)) != __no_error) + _jlog, _mesh)) != __no_error) { return _retv ; } @@ -855,7 +849,7 @@ if ((_retv = save_tria ( _jcfg, - _jlog, _rdel)) != __no_error) + _jlog, _mesh)) != __no_error) { return _retv ; } diff --git a/uni/test_1.c b/uni/test_1.c index 0f1cde2..91214b0 100644 --- a/uni/test_1.c +++ b/uni/test_1.c @@ -1,33 +1,33 @@ -// gcc -Wall test_1.c -// -Xlinker -rpath=../lib +// gcc -Wall test_1.c +// -Xlinker -rpath=../lib // -L ../lib -ljigsaw -o test_1 // A simple example to start: use JIGSAW to mesh a square // domain. # include "../inc/lib_jigsaw.h" - + # include "stdio.h" - + int main ( - int _argc , + int _argc , char **_argv ) { int _retv = 0; - - /*-------------------------------- setup JIGSAW types */ + + /*-------------------------------- setup JIGSAW types */ jigsaw_jig_t _jjig ; - jigsaw_init_jig_t(&_jjig) ; + jigsaw_init_jig_t(&_jjig) ; jigsaw_msh_t _geom ; - jigsaw_init_msh_t(&_geom) ; + jigsaw_init_msh_t(&_geom) ; - jigsaw_msh_t _mesh ; + jigsaw_msh_t _mesh ; jigsaw_init_msh_t(&_mesh) ; - - /* + + /* -------------------------------------------------------- * JIGSAW's "mesh" is a piecewise linear complex: -------------------------------------------------------- @@ -46,53 +46,53 @@ * -------------------------------------------------------- */ - + jigsaw_VERT2_t _vert2[4] = { // setup geom. { {0., 0.}, +0 } , { {1., 0.}, +0 } , { {1., 1.}, +0 } , { {0., 1.}, +0 } } ; - + jigsaw_EDGE2_t _edge2[4] = { { {+0, +1}, +0 } , { {+1, +2}, +0 } , { {+2, +3}, +0 } , { {+3, +0}, +0 } } ; - - _geom._flags + + _geom._flags = JIGSAW_EUCLIDEAN_MESH; - + _geom._vert2._data = &_vert2[0] ; _geom._vert2._size = +4 ; - + _geom._edge2._data = &_edge2[0] ; - _geom._edge2._size = +4 ; - + _geom._edge2._size = +4 ; + /*-------------------------------- build JIGSAW tria. */ - + _jjig._verbosity = +1 ; - + _jjig._hfun_hmax = 0.25 ; - _jjig._hfun_scal = + _jjig._hfun_scal = JIGSAW_HFUN_RELATIVE; - + _jjig._mesh_dims = +2 ; - + _retv = jigsaw ( &_jjig , // the config. opts &_geom , // geom. data - NULL , // empty init. data + NULL , // empty init. data NULL , // empty hfun. data &_mesh ) ; - + /*-------------------------------- print JIGSAW tria. */ printf("\n VERT2: \n\n") ; - for (indx_t _ipos = +0; - _ipos != _mesh._vert2._size ; + for (indx_t _ipos = +0; + _ipos != _mesh._vert2._size ; ++_ipos ) { printf("%1.4f, %1.4f\n", @@ -102,11 +102,11 @@ _data[_ipos]._ppos[1] ) ; } - + printf("\n TRIA3: \n\n") ; - - for (indx_t _ipos = +0; - _ipos != _mesh._tria3._size ; + + for (indx_t _ipos = +0; + _ipos != _mesh._tria3._size ; ++_ipos ) { printf("%d, %d, %d\n", @@ -118,13 +118,13 @@ _data[_ipos]._node[2] ) ; } - + jigsaw_free_msh_t(&_mesh); - + printf ( "JIGSAW returned code : %d \n",_retv); - - + + return _retv ; } diff --git a/uni/test_2.c b/uni/test_2.c index 495416d..64dd21f 100644 --- a/uni/test_2.c +++ b/uni/test_2.c @@ -1,36 +1,36 @@ -// gcc -Wall test_2.c -// -Xlinker -rpath=../lib +// gcc -Wall test_2.c +// -Xlinker -rpath=../lib // -L ../lib -ljigsaw -o test_2 // Use JIGSAW to mesh a simple geometry with user-defined // mesh-spacing data defined on a "mesh". # include "../inc/lib_jigsaw.h" - + # include "stdio.h" - + int main ( - int _argc , + int _argc , char **_argv ) { int _retv = 0; - - /*-------------------------------- setup JIGSAW types */ + + /*-------------------------------- setup JIGSAW types */ jigsaw_jig_t _jjig ; - jigsaw_init_jig_t(&_jjig) ; + jigsaw_init_jig_t(&_jjig) ; jigsaw_msh_t _geom ; - jigsaw_init_msh_t(&_geom) ; + jigsaw_init_msh_t(&_geom) ; jigsaw_msh_t _hfun ; - jigsaw_init_msh_t(&_hfun) ; + jigsaw_init_msh_t(&_hfun) ; - jigsaw_msh_t _mesh ; + jigsaw_msh_t _mesh ; jigsaw_init_msh_t(&_mesh) ; - - /* + + /* -------------------------------------------------------- * JIGSAW's "mesh" is a piecewise linear complex: -------------------------------------------------------- @@ -49,31 +49,31 @@ * -------------------------------------------------------- */ - + jigsaw_VERT2_t _geom_vert2[4] = { // setup geom. { {0., 0.}, +0 } , { {1., 0.}, +0 } , { {1., 1.}, +0 } , { {0., 1.}, +0 } } ; - + jigsaw_EDGE2_t _geom_edge2[4] = { { {+0, +1}, +0 } , { {+1, +2}, +0 } , { {+2, +3}, +0 } , { {+3, +0}, +0 } } ; - - _geom._flags + + _geom._flags = JIGSAW_EUCLIDEAN_MESH; - + _geom._vert2._data = &_geom_vert2[0] ; _geom._vert2._size = +4 ; - + _geom._edge2._data = &_geom_edge2[0] ; _geom._edge2._size = +4 ; - - /* + + /* -------------------------------------------------------- * JIGSAW's "mesh" is a piecewise linear complex: -------------------------------------------------------- @@ -90,7 +90,7 @@ * -------------------------------------------------------- */ - + jigsaw_VERT2_t _hfun_vert2[5] = { // setup hfun. { {0., 0.}, +0 } , { {1., 0.}, +0 } , @@ -98,55 +98,55 @@ { {0., 1.}, +0 } , { {.5, .5}, +0 } } ; - + jigsaw_TRIA3_t _hfun_tria3[4] = { { {+0, +1, +4}, +0 } , { {+1, +2, +4}, +0 } , { {+2, +3, +4}, +4 } , { {+3, +0, +4}, +0 } } ; - + real_t _hfun_value[5] = { .2, .2, .2, .2, .5 } ; - - _hfun._flags + + _hfun._flags = JIGSAW_EUCLIDEAN_MESH; - + _hfun._vert2._data = &_hfun_vert2[0] ; _hfun._vert2._size = +5 ; - + _hfun._tria3._data = &_hfun_tria3[0] ; _hfun._tria3._size = +4 ; - + _hfun._value._data = &_hfun_value[0] ; _hfun._value._size = +5 ; - + /*-------------------------------- build JIGSAW tria. */ - + _jjig._verbosity = +1 ; - - _jjig._hfun_scal = + + _jjig._hfun_scal = JIGSAW_HFUN_ABSOLUTE ; - + _jjig._hfun_hmax = 1. ; _jjig._hfun_hmin = 0. ; - + _jjig._mesh_dims = +2 ; - + _retv = jigsaw ( &_jjig , // the config. opts &_geom , // geom. data - NULL , // empty init. data + NULL , // empty init. data &_hfun , // hfun. data &_mesh ) ; - + /*-------------------------------- print JIGSAW tria. */ printf("\n VERT2: \n\n") ; - for (indx_t _ipos = +0; - _ipos != _mesh._vert2._size ; + for (indx_t _ipos = +0; + _ipos != _mesh._vert2._size ; ++_ipos ) { printf("%1.4f, %1.4f\n", @@ -156,11 +156,11 @@ _data[_ipos]._ppos[1] ) ; } - + printf("\n TRIA3: \n\n") ; - - for (indx_t _ipos = +0; - _ipos != _mesh._tria3._size ; + + for (indx_t _ipos = +0; + _ipos != _mesh._tria3._size ; ++_ipos ) { printf("%i, %i, %i\n", @@ -172,13 +172,13 @@ _data[_ipos]._node[2] ) ; } - + jigsaw_free_msh_t(&_mesh); - + printf ( "JIGSAW returned code : %d \n",_retv); - - + + return _retv ; } diff --git a/uni/test_3.c b/uni/test_3.c index f42989a..f22955d 100644 --- a/uni/test_3.c +++ b/uni/test_3.c @@ -1,5 +1,5 @@ -// gcc -Wall test_3.c +// gcc -Wall test_3.c // -Xlinker -rpath=../lib // -L ../lib -ljigsaw -o test_3 @@ -7,30 +7,30 @@ // mesh-spacing data defined on a "grid". # include "../inc/lib_jigsaw.h" - + # include "stdio.h" - + int main ( - int _argc, + int _argc, char **_argv ) { int _retv = 0; - - /*-------------------------------- setup JIGSAW types */ + + /*-------------------------------- setup JIGSAW types */ jigsaw_jig_t _jjig ; - jigsaw_init_jig_t(&_jjig) ; + jigsaw_init_jig_t(&_jjig) ; jigsaw_msh_t _geom ; - jigsaw_init_msh_t(&_geom) ; + jigsaw_init_msh_t(&_geom) ; jigsaw_msh_t _hfun ; - jigsaw_init_msh_t(&_hfun) ; + jigsaw_init_msh_t(&_hfun) ; - jigsaw_msh_t _mesh ; + jigsaw_msh_t _mesh ; jigsaw_init_msh_t(&_mesh) ; - - /* + + /* -------------------------------------------------------- * JIGSAW's "mesh" is a piecewise linear complex: -------------------------------------------------------- @@ -56,29 +56,29 @@ { {1., 1.}, +0 } , { {0., 1.}, +0 } } ; - + jigsaw_EDGE2_t _geom_edge2[4] = { { {+0, +1}, +0 } , { {+1, +2}, +0 } , { {+2, +3}, +0 } , { {+3, +0}, +0 } } ; - - _geom._flags + + _geom._flags = JIGSAW_EUCLIDEAN_MESH; - + _geom._vert2._data = &_geom_vert2[0] ; _geom._vert2._size = +4 ; - + _geom._edge2._data = &_geom_edge2[0] ; _geom._edge2._size = +4 ; - - /* + + /* -------------------------------------------------------- * JIGSAW's "grid" uses a column-major numbering: -------------------------------------------------------- * - * v:5 + * v:5 * v:2 o-------o-------o v:8 * | | | * | | | @@ -91,58 +91,58 @@ * v:3 * -------------------------------------------------------- - */ - + */ + real_t _hfun_xgrid[3] = { // setup hfun. 0., .5, 1. } ; - + real_t _hfun_ygrid[3] = { 0., .5, 1. } ; - + real_t _hfun_value[9] = { - .3, .2, .3, .2, .1, .2, .3, + .3, .2, .3, .2, .1, .2, .3, .2, .3 } ; - - _hfun._flags + + _hfun._flags = JIGSAW_EUCLIDEAN_GRID; - + _hfun._xgrid._data = &_hfun_xgrid[0] ; _hfun._xgrid._size = +3 ; - + _hfun._ygrid._data = &_hfun_ygrid[0] ; _hfun._ygrid._size = +3 ; - + _hfun._value._data = &_hfun_value[0] ; _hfun._value._size = +9 ; - + /*-------------------------------- build JIGSAW tria. */ - + _jjig._verbosity = +1 ; - - _jjig._hfun_scal = + + _jjig._hfun_scal = JIGSAW_HFUN_ABSOLUTE ; - + _jjig._hfun_hmax = 1. ; _jjig._hfun_hmin = 0. ; - + _jjig._mesh_dims = +2 ; - + _retv = jigsaw ( &_jjig , // the config. opts &_geom , // geom. data - NULL , // empty init. data + NULL , // empty init. data &_hfun , // hfun. data &_mesh ) ; - + /*-------------------------------- print JIGSAW tria. */ printf("\n VERT2: \n\n") ; - for (indx_t _ipos = +0; - _ipos != _mesh._vert2._size ; + for (indx_t _ipos = +0; + _ipos != _mesh._vert2._size ; ++_ipos ) { printf("%1.4f, %1.4f\n", @@ -152,11 +152,11 @@ _data[_ipos]._ppos[1] ) ; } - + printf("\n TRIA3: \n\n") ; - - for (indx_t _ipos = +0; - _ipos != _mesh._tria3._size ; + + for (indx_t _ipos = +0; + _ipos != _mesh._tria3._size ; ++_ipos ) { printf("%i, %i, %i\n", @@ -168,12 +168,12 @@ _data[_ipos]._node[2] ) ; } - + jigsaw_free_msh_t(&_mesh); - + printf ( "JIGSAW returned code : %d \n",_retv); - + return _retv ; } diff --git a/uni/test_4.c b/uni/test_4.c index c206716..38b1661 100644 --- a/uni/test_4.c +++ b/uni/test_4.c @@ -1,33 +1,33 @@ -// gcc -Wall test_4.c -// -Xlinker -rpath=../lib +// gcc -Wall test_4.c +// -Xlinker -rpath=../lib // -L ../lib -ljigsaw -o test_4 -// An example that uses JIGSAW to mesh "multiply-connected" -// geometry. +// An example that uses JIGSAW to mesh "multiply-connected" +// geometry. # include "../inc/lib_jigsaw.h" - + # include "stdio.h" - + int main ( - int _argc , + int _argc , char **_argv ) { int _retv = 0; - - /*-------------------------------- setup JIGSAW types */ + + /*-------------------------------- setup JIGSAW types */ jigsaw_jig_t _jjig ; - jigsaw_init_jig_t(&_jjig) ; + jigsaw_init_jig_t(&_jjig) ; jigsaw_msh_t _geom ; - jigsaw_init_msh_t(&_geom) ; + jigsaw_init_msh_t(&_geom) ; - jigsaw_msh_t _mesh ; + jigsaw_msh_t _mesh ; jigsaw_init_msh_t(&_mesh) ; - - /* + + /* -------------------------------------------------------- * A domain with "interior" constraints -------------------------------------------------------- @@ -46,10 +46,10 @@ * -------------------------------------------------------- */ - - indx_t _ITAG = + + indx_t _ITAG = JIGSAW_EDGE2_TAG ; - + jigsaw_VERT2_t _vert2[8] = { // setup geom. { {0., 0.}, +0 } , { {3., 0.}, +0 } , @@ -60,7 +60,7 @@ { {2., 2.}, +0 } , { {1., 2.}, +0 } } ; - + jigsaw_EDGE2_t _edge2[8] = { { {+0, +1}, +0 } , // outer geom. { {+1, +2}, +0 } , @@ -71,49 +71,49 @@ { {+6, +7}, +0 } , { {+7, +4}, +0 } } ; - + jigsaw_BOUND_t _bound[4] = { { +0, +0, _ITAG}, { +0, +1, _ITAG}, { +0, +2, _ITAG}, - { +0, +3, _ITAG}, + { +0, +3, _ITAG}, } ; - - _geom._flags + + _geom._flags = JIGSAW_EUCLIDEAN_MESH ; - + _geom._vert2._data = &_vert2[0] ; _geom._vert2._size = +8 ; - + _geom._edge2._data = &_edge2[0] ; - _geom._edge2._size = +8 ; - + _geom._edge2._size = +8 ; + _geom._bound._data = &_bound[0] ; - _geom._bound._size = +4 ; - + _geom._bound._size = +4 ; + /*-------------------------------- build JIGSAW tria. */ - + _jjig._verbosity = +1 ; - + _jjig._hfun_hmax = 0.20 ; - _jjig._hfun_scal = + _jjig._hfun_scal = JIGSAW_HFUN_RELATIVE; - + _jjig._mesh_dims = +2 ; - + _retv = jigsaw ( &_jjig , // the config. opts &_geom , // geom. data - NULL , // empty init. data + NULL , // empty init. data NULL , // empty hfun. data &_mesh ) ; - + /*-------------------------------- print JIGSAW tria. */ printf("\n VERT2: \n\n") ; - for (indx_t _ipos = +0; - _ipos != _mesh._vert2._size ; + for (indx_t _ipos = +0; + _ipos != _mesh._vert2._size ; ++_ipos ) { printf("%1.4f, %1.4f\n", @@ -123,11 +123,11 @@ _data[_ipos]._ppos[1] ) ; } - + printf("\n TRIA3: \n\n") ; - - for (indx_t _ipos = +0; - _ipos != _mesh._tria3._size ; + + for (indx_t _ipos = +0; + _ipos != _mesh._tria3._size ; ++_ipos ) { printf("%d, %d, %d\n", @@ -139,13 +139,13 @@ _data[_ipos]._node[2] ) ; } - + jigsaw_free_msh_t(&_mesh); - + printf ( "JIGSAW returned code : %d \n",_retv); - - + + return _retv ; } diff --git a/uni/test_5.c b/uni/test_5.c index cb11685..a1d9efe 100644 --- a/uni/test_5.c +++ b/uni/test_5.c @@ -1,35 +1,35 @@ -// gcc -Wall test_5.c -// -Xlinker -rpath=../lib +// gcc -Wall test_5.c +// -Xlinker -rpath=../lib // -L ../lib -ljigsaw -o test_5 // An example that uses TRIPOD to build a "restricted" DT. # include "../inc/lib_jigsaw.h" - + # include "stdio.h" - + int main ( - int _argc , + int _argc , char **_argv ) { int _retv = 0; - - /*-------------------------------- setup JIGSAW types */ + + /*-------------------------------- setup JIGSAW types */ jigsaw_jig_t _jjig ; - jigsaw_init_jig_t(&_jjig) ; + jigsaw_init_jig_t(&_jjig) ; jigsaw_msh_t _geom ; - jigsaw_init_msh_t(&_geom) ; + jigsaw_init_msh_t(&_geom) ; jigsaw_msh_t _init ; - jigsaw_init_msh_t(&_init) ; + jigsaw_init_msh_t(&_init) ; - jigsaw_msh_t _tria ; + jigsaw_msh_t _tria ; jigsaw_init_msh_t(&_tria) ; - - /* + + /* -------------------------------------------------------- * JIGSAW's "mesh" is a piecewise linear complex: -------------------------------------------------------- @@ -48,30 +48,30 @@ * -------------------------------------------------------- */ - + jigsaw_VERT2_t _vert2[4] = { // setup geom. { {0., 0.}, +0 } , { {1., 0.}, +0 } , { {1., 1.}, +0 } , { {0., 1.}, +0 } } ; - + jigsaw_EDGE2_t _edge2[4] = { { {+0, +1}, +0 } , { {+1, +2}, +0 } , { {+2, +3}, +0 } , { {+3, +0}, +0 } } ; - - _geom._flags + + _geom._flags = JIGSAW_EUCLIDEAN_MESH; - + _geom._vert2._data = &_vert2[0] ; _geom._vert2._size = +4 ; - + _geom._edge2._data = &_edge2[0] ; - _geom._edge2._size = +4 ; - + _geom._edge2._size = +4 ; + /*-------------------------------- pts to triangulate */ jigsaw_VERT2_t _point[9] = { @@ -85,22 +85,22 @@ { {.0, .5}, +0 } , { {.3, .3}, +0 } } ; - + _init._flags = JIGSAW_EUCLIDEAN_MESH; - + _init._vert2._data = &_point[0] ; _init._vert2._size = +9 ; - + /*-------------------------------- build TRIPOD r-DT. */ - + _jjig._verbosity = +1 ; - + _jjig._mesh_dims = +2 ; - + _retv = tripod ( &_jjig , // the config. opts - &_init , // init. data + &_init , // init. data &_geom , // geom. data &_tria ) ; @@ -108,8 +108,8 @@ printf("\n VERT2: \n\n") ; - for (indx_t _ipos = +0; - _ipos != _tria._vert2._size ; + for (indx_t _ipos = +0; + _ipos != _tria._vert2._size ; ++_ipos ) { printf("%1.4f, %1.4f\n", @@ -119,11 +119,11 @@ _data[_ipos]._ppos[1] ) ; } - + printf("\n TRIA3: \n\n") ; - - for (indx_t _ipos = +0; - _ipos != _tria._tria3._size ; + + for (indx_t _ipos = +0; + _ipos != _tria._tria3._size ; ++_ipos ) { printf("%d, %d, %d\n", @@ -135,13 +135,13 @@ _data[_ipos]._node[2] ) ; } - + jigsaw_free_msh_t(&_tria); - + printf ( "TRIPOD returned code : %d \n",_retv); - - + + return _retv ; } diff --git a/uni/test_6.c b/uni/test_6.c index 488f573..b620ef3 100644 --- a/uni/test_6.c +++ b/uni/test_6.c @@ -1,36 +1,36 @@ -// gcc -Wall test_6.c -// -Xlinker -rpath=../lib +// gcc -Wall test_6.c +// -Xlinker -rpath=../lib // -L ../lib -ljigsaw -o test_6 // Use JIGSAW to mesh a simple domain, but starting from -// user-defined initial-conditions. +// user-defined initial-conditions. # include "../inc/lib_jigsaw.h" - + # include "stdio.h" - + int main ( - int _argc , + int _argc , char **_argv ) { int _retv = 0; - - /*-------------------------------- setup JIGSAW types */ + + /*-------------------------------- setup JIGSAW types */ jigsaw_jig_t _jjig ; - jigsaw_init_jig_t(&_jjig) ; + jigsaw_init_jig_t(&_jjig) ; jigsaw_msh_t _geom ; - jigsaw_init_msh_t(&_geom) ; + jigsaw_init_msh_t(&_geom) ; jigsaw_msh_t _init ; - jigsaw_init_msh_t(&_init) ; + jigsaw_init_msh_t(&_init) ; - jigsaw_msh_t _mesh ; + jigsaw_msh_t _mesh ; jigsaw_init_msh_t(&_mesh) ; - - /* + + /* -------------------------------------------------------- * JIGSAW's "mesh" is a piecewise linear complex: -------------------------------------------------------- @@ -49,39 +49,39 @@ * -------------------------------------------------------- */ - + jigsaw_VERT2_t _vert2[4] = { // setup geom. { {0., 0.}, +0 } , { {1., 0.}, +0 } , { {1., 1.}, +0 } , { {0., 1.}, +0 } } ; - + jigsaw_EDGE2_t _edge2[4] = { { {+0, +1}, +0 } , { {+1, +2}, +0 } , { {+2, +3}, +0 } , { {+3, +0}, +0 } } ; - - _geom._flags + + _geom._flags = JIGSAW_EUCLIDEAN_MESH; - + _geom._vert2._data = &_vert2[0] ; _geom._vert2._size = +4 ; - + _geom._edge2._data = &_edge2[0] ; - _geom._edge2._size = +4 ; - + _geom._edge2._size = +4 ; + /*-------------------------------- form init. config. */ - + jigsaw_VERT2_t _point[4] = { { {0., 0.}, +0 } , { {0., .5}, +0 } , { {0., 1.}, +0 } , { {.5, .5}, +0 } } ; - + jigsaw_EDGE2_t _edges[2] = { { {+0, +1}, -1 } , // -1 => "un-refinable" { {+1, +2}, -1 } @@ -89,40 +89,40 @@ _init._flags = JIGSAW_EUCLIDEAN_MESH; - + _init._vert2._data = &_point[0] ; _init._vert2._size = +4 ; _init._edge2._data = &_edges[0] ; - _init._edge2._size = +2 ; + _init._edge2._size = +2 ; /*-------------------------------- build JIGSAW tria. */ - + _jjig._verbosity = +1 ; - + _jjig._hfun_hmax = 0.33 ; - _jjig._hfun_scal = + _jjig._hfun_scal = JIGSAW_HFUN_RELATIVE; - + _jjig._mesh_dims = +2 ; _jjig._geom_feat = +1 ; _jjig._mesh_top1 = +1 ; - _jjig._optm_iter = +0 ; - + //_jjig._optm_iter = +0 ; + _retv = jigsaw ( &_jjig , // the config. opts &_geom , // geom. data - &_init , // init. data + &_init , // init. data NULL , // empty hfun. data &_mesh ) ; - + /*-------------------------------- print JIGSAW tria. */ printf("\n VERT2: \n\n") ; - for (indx_t _ipos = +0; - _ipos != _mesh._vert2._size ; + for (indx_t _ipos = +0; + _ipos != _mesh._vert2._size ; ++_ipos ) { printf("%1.4f, %1.4f\n", @@ -132,11 +132,11 @@ _data[_ipos]._ppos[1] ) ; } - + printf("\n TRIA3: \n\n") ; - - for (indx_t _ipos = +0; - _ipos != _mesh._tria3._size ; + + for (indx_t _ipos = +0; + _ipos != _mesh._tria3._size ; ++_ipos ) { printf("%d, %d, %d\n", @@ -148,13 +148,13 @@ _data[_ipos]._node[2] ) ; } - + jigsaw_free_msh_t(&_mesh); - + printf ( "JIGSAW returned code : %d \n",_retv); - - + + return _retv ; } diff --git a/uni/test_7.c b/uni/test_7.c index d5f99fa..b775fd9 100644 --- a/uni/test_7.c +++ b/uni/test_7.c @@ -1,29 +1,29 @@ -// gcc -Wall test_7.c -// -Xlinker -rpath=../lib +// gcc -Wall test_7.c +// -Xlinker -rpath=../lib // -L ../lib -ljigsaw -o test_7 -// Use MARCHE to set "gradient-limits" on mesh-spacing data +// Use MARCHE to set "gradient-limits" on mesh-spacing data # include "../inc/lib_jigsaw.h" - + # include "stdio.h" - + int main ( - int _argc , + int _argc , char **_argv ) { int _retv = 0; - - /*-------------------------------- setup JIGSAW types */ + + /*-------------------------------- setup JIGSAW types */ jigsaw_jig_t _jjig ; - jigsaw_init_jig_t(&_jjig) ; + jigsaw_init_jig_t(&_jjig) ; jigsaw_msh_t _hfun ; - jigsaw_init_msh_t(&_hfun) ; - - /* + jigsaw_init_msh_t(&_hfun) ; + + /* -------------------------------------------------------- * JIGSAW's "mesh" is a piecewise linear complex: -------------------------------------------------------- @@ -40,7 +40,7 @@ * -------------------------------------------------------- */ - + jigsaw_VERT2_t _hfun_vert2[5] = { // setup hfun. { {0., 0.}, +0 } , { {1., 0.}, +0 } , @@ -48,14 +48,14 @@ { {0., 1.}, +0 } , { {.5, .5}, +0 } } ; - + jigsaw_TRIA3_t _hfun_tria3[4] = { { {+0, +1, +4}, +0 } , { {+1, +2, +4}, +0 } , { {+2, +3, +4}, +4 } , { {+3, +0, +4}, +0 } } ; - + real_t _hfun_value[5] = { 2., 2., 2., 2., 1. } ; @@ -63,47 +63,47 @@ real_t _hfun_slope[1] = { .1 } ; - - _hfun._flags + + _hfun._flags = JIGSAW_EUCLIDEAN_MESH; _hfun._vert2._data = &_hfun_vert2[0] ; _hfun._vert2._size = +5 ; - + _hfun._tria3._data = &_hfun_tria3[0] ; _hfun._tria3._size = +4 ; - + _hfun._value._data = &_hfun_value[0] ; _hfun._value._size = +5 ; _hfun._slope._data = &_hfun_slope[0] ; _hfun._slope._size = +1 ; - + /*-------------------------------- build MARCHE hfun. */ - + _jjig._verbosity = +1 ; _retv = marche ( &_jjig , // the config. opts &_hfun ) ; // the spacing h(x) - + /*-------------------------------- print MARCHE hfun. */ printf("\n VALUE: \n\n") ; - for (indx_t _ipos = +0; - _ipos != _hfun._value._size ; + for (indx_t _ipos = +0; + _ipos != _hfun._value._size ; ++_ipos ) { printf("%1.4f\n", _hfun._value._data[_ipos] ) ; } - + printf ( "MARCHE returned code : %d \n",_retv); - - + + return _retv ; } diff --git a/uni/test_8.c b/uni/test_8.c index 343e5e6..3dafe4d 100644 --- a/uni/test_8.c +++ b/uni/test_8.c @@ -1,34 +1,34 @@ -// gcc -Wall test_8.c -// -Xlinker -rpath=../lib +// gcc -Wall test_8.c +// -Xlinker -rpath=../lib // -L ../lib -ljigsaw -o test_8 // Use MARCHE to set "gradient-limits" on mesh-spacing data # include "../inc/lib_jigsaw.h" - + # include "stdio.h" - + int main ( - int _argc , + int _argc , char **_argv ) { int _retv = 0; - - /*-------------------------------- setup JIGSAW types */ + + /*-------------------------------- setup JIGSAW types */ jigsaw_jig_t _jjig ; - jigsaw_init_jig_t(&_jjig) ; + jigsaw_init_jig_t(&_jjig) ; jigsaw_msh_t _hfun ; - jigsaw_init_msh_t(&_hfun) ; - - /* + jigsaw_init_msh_t(&_hfun) ; + + /* -------------------------------------------------------- * JIGSAW's "grid" uses a column-major numbering: -------------------------------------------------------- * - * v:5 + * v:5 * v:2 o-------o-------o v:8 * | | | * | | | @@ -41,66 +41,66 @@ * v:3 * -------------------------------------------------------- - */ - + */ + real_t _hfun_xgrid[3] = { // setup hfun. 0., .5, 1. } ; - + real_t _hfun_ygrid[3] = { 0., .5, 1. } ; - + real_t _hfun_value[9] = { - 2., 2., 2., 2., 1., 2., 2., + 2., 2., 2., 2., 1., 2., 2., 2., 2. } ; real_t _hfun_slope[9] = { - .4, .4, .4, .4, .1, .4, .4, + .4, .4, .4, .4, .1, .4, .4, .4, .4 } ; - - _hfun._flags + + _hfun._flags = JIGSAW_EUCLIDEAN_GRID; - + _hfun._xgrid._data = &_hfun_xgrid[0] ; _hfun._xgrid._size = +3 ; - + _hfun._ygrid._data = &_hfun_ygrid[0] ; _hfun._ygrid._size = +3 ; - + _hfun._value._data = &_hfun_value[0] ; _hfun._value._size = +9 ; _hfun._slope._data = &_hfun_slope[0] ; _hfun._slope._size = +9 ; - + /*-------------------------------- build MARCHE hfun. */ - + _jjig._verbosity = +1 ; _retv = marche ( &_jjig , // the config. opts &_hfun ) ; // the spacing h(x) - + /*-------------------------------- print MARCHE hfun. */ printf("\n VALUE: \n\n") ; - for (indx_t _ipos = +0; - _ipos != _hfun._value._size ; + for (indx_t _ipos = +0; + _ipos != _hfun._value._size ; ++_ipos ) { printf("%1.4f\n", _hfun._value._data[_ipos] ) ; } - + printf ( "MARCHE returned code : %d \n",_retv); - - + + return _retv ; } diff --git a/uni/test_9.c b/uni/test_9.c index e187ee2..d0c6e6d 100644 --- a/uni/test_9.c +++ b/uni/test_9.c @@ -1,66 +1,66 @@ -// gcc -Wall test_9.c -// -Xlinker -rpath=../lib +// gcc -Wall test_9.c +// -Xlinker -rpath=../lib // -L ../lib -ljigsaw -o test_9 -// Use JIGSAW to generate a uniform mesh for a spheroidal -// domain. +// Use JIGSAW to generate a uniform mesh for a spheroidal +// domain. # include "../inc/lib_jigsaw.h" - + # include "stdio.h" - + int main ( - int _argc , + int _argc , char **_argv ) { int _retv = 0; - - /*-------------------------------- setup JIGSAW types */ + + /*-------------------------------- setup JIGSAW types */ jigsaw_jig_t _jjig ; - jigsaw_init_jig_t(&_jjig) ; + jigsaw_init_jig_t(&_jjig) ; jigsaw_msh_t _geom ; jigsaw_init_msh_t(&_geom) ; jigsaw_msh_t _mesh ; - jigsaw_init_msh_t(&_mesh) ; - + jigsaw_init_msh_t(&_mesh) ; + /*-------------------------------- setup JIGSAW geom. */ real_t _radii[3] = {+1., +1., +1. } ; - _geom._flags = + _geom._flags = JIGSAW_ELLIPSOID_MESH ; _geom._radii._data = &_radii[0] ; _geom._radii._size = +3 ; /*-------------------------------- build JIGSAW tria. */ - + _jjig._verbosity = +1 ; - + _jjig._hfun_hmax = 0.80 ; - _jjig._hfun_scal = + _jjig._hfun_scal = JIGSAW_HFUN_ABSOLUTE; - + _jjig._mesh_dims = +2 ; - + _retv = jigsaw ( &_jjig , // the config. opts &_geom , // geom. data - NULL , // empty init. data + NULL , // empty init. data NULL , // empty hfun. data &_mesh ) ; - + /*-------------------------------- print JIGSAW tria. */ printf("\n VERT3: \n\n") ; - for (indx_t _ipos = +0; - _ipos != _mesh._vert3._size ; + for (indx_t _ipos = +0; + _ipos != _mesh._vert3._size ; ++_ipos ) { printf( @@ -73,11 +73,11 @@ _data[_ipos]._ppos[2] ) ; } - + printf("\n TRIA3: \n\n") ; - - for (indx_t _ipos = +0; - _ipos != _mesh._tria3._size ; + + for (indx_t _ipos = +0; + _ipos != _mesh._tria3._size ; ++_ipos ) { printf("%d, %d, %d\n", @@ -89,13 +89,13 @@ _data[_ipos]._node[2] ) ; } - + jigsaw_free_msh_t(&_mesh); - + printf ( "JIGSAW returned code : %d \n",_retv); - - + + return _retv ; } diff --git a/version.txt b/version.txt index 6898a84..10aa4d7 100644 --- a/version.txt +++ b/version.txt @@ -13,6 +13,17 @@ # JIGSAW: an unstructured mesh generation library #------------------------------------------------------------ + * Version 0.9.13: + -------------- + + - Better support for robust geometric computation + using multi-precision floating-point operators. + + - Initial support for "mixed-cell" mesh complexes + enabling (limited) processing of tria/quad/hexa + mesh formats. + + * Version 0.9.12: -------------- From 686ff8c197a7bebfc67c9f41bb6c5c354c820cb0 Mon Sep 17 00:00:00 2001 From: dengwirda Date: Sun, 13 Sep 2020 16:02:27 -0600 Subject: [PATCH 4/6] Update bindings for jigsaw-0.9.13.xx --- example.m | 113 +---------- jitter.m | 2 + loadmsh.m | 68 +++---- tetris.m | 6 +- tools/aabb_tree/exchange.m | 36 ++-- tools/aabb_tree/findpoly.m | 64 +++--- tools/ellipsoid/cubedsphere.m | 6 +- tools/ellipsoid/icosahedron.m | 10 +- tools/poly_sign/inpoly2.m | 366 +++++++++++++++++----------------- tools/poly_sign/inpoly2_mat.m | 72 +++---- 10 files changed, 319 insertions(+), 424 deletions(-) diff --git a/example.m b/example.m index c838153..208bcf1 100644 --- a/example.m +++ b/example.m @@ -80,33 +80,6 @@ function example(varargin) % construction of geometry + user-defined mesh-size const- % raints. - %{ - SEEDS=N - X;Y;Z;PART - - after rdel, before optm - project onto IDIM geometry closest feature - find intersecting cell, if any - bfs to all d-1 connected cells, stop at d-1 face that's a boundary - or external - - If there's no IDIM=k, just return the full k-DEL as now? - - Maybe we can worry about using this within rdel-mesh later? - - Are SEEDS part of the geometry definition? I think so... - - Build an aabb-tree for the mesh to facilitate the scan? - - Will TRIPOD do this too? Probably? - - What happens if you only pass input for optm? Prune the mesh passed? - Yes, I guess so. - So this is not so different from the mesh_func infrastructure... - Steal this and put somewhere common? - %} - - demo_A(); demo_B(); demo_C(); @@ -187,86 +160,12 @@ function example(varargin) opts.mesh_dims = +2 ; % 2-dim. simplexes opts.optm_qlim = +.95 ; - + opts.mesh_top1 = true ; % for sharp feat's opts.geom_feat = true ; - %opts.optm_kern = 'cvt+dqdx'; - - %opts.verbosity = +3 ; - mesh = jigsaw (opts) ; - - - %{ - for iter = 1:32 - - pmid = mesh.point.coord(mesh.tria3.index(:,1),1:2) ... - + mesh.point.coord(mesh.tria3.index(:,2),1:2) ... - + mesh.point.coord(mesh.tria3.index(:,3),1:2) ; - pmid = pmid / 3. ; - - move = zeros(size(mesh.point.coord,1),2); - wsum = zeros(size(mesh.point.coord,1),1); - nadj = zeros(size(mesh.point.coord,1),1); - ladj = zeros(size(mesh.point.coord,1),1); - - area = trivol2(mesh.point.coord(:,1:2), ... - mesh.tria3.index(:,1:3)) ; - - ball = tribal2(mesh.point.coord(:,1:2), ... - mesh.tria3.index(:,1:3)) ; - - pmid = (pmid + ball(:,1:2)) * .5 ; - - for cell = 1:size(mesh.tria3.index,1) - - inod = mesh.tria3.index(cell,1); - jnod = mesh.tria3.index(cell,2); - knod = mesh.tria3.index(cell,3); - - move(inod,:) = move(inod,:) + area(cell) * pmid(cell,1:2); - move(jnod,:) = move(jnod,:) + area(cell) * pmid(cell,1:2); - move(knod,:) = move(knod,:) + area(cell) * pmid(cell,1:2); - - wsum(inod,1) = wsum(inod,1) + area(cell,1); - wsum(jnod,1) = wsum(jnod,1) + area(cell,1); - wsum(knod,1) = wsum(knod,1) + area(cell,1); - - nadj(inod,1) = nadj(inod,1) + 1; - nadj(jnod,1) = nadj(jnod,1) + 1; - nadj(knod,1) = nadj(knod,1) + 1; - - ladj(inod,1) = ladj(inod,1) + ball(cell,3); - ladj(jnod,1) = ladj(jnod,1) + ball(cell,3); - ladj(knod,1) = ladj(knod,1) + ball(cell,3); - - end - - ladj = ladj ./ [nadj]; - move = move ./ [wsum,wsum]; - - ladj(mesh.edge2.index(:,1:2)) = inf ; - - lmov = sum((mesh.point.coord(:,1:2)-move).^2,2); - - ltol = 1.E-04; nmov = 0; - for node = 1:size(mesh.point.coord,1) - if (lmov(node) > ltol * ladj(node)) - nmov = nmov + 1; - mesh.point.coord(node,1:2) = move(node,:); - end - end - - disp(nmov); - - if (nmov <= 0), break; end - - end - %} - - figure('color','w'); patch ('faces',mesh.tria3.index(:,1:3), ... 'vertices',mesh.point.coord(:,1:2), ... @@ -285,7 +184,7 @@ function example(varargin) 'linewidth',1.5) ; drawcost(mesh) ; - + end function demo_B @@ -597,17 +496,13 @@ function example(varargin) %------------------------------------ make mesh using JIGSAW - opts.hfun_hmax = 0.02 ; % push HFUN limits + opts.hfun_hmax = 0.08 ; % push HFUN limits opts.mesh_dims = +3 ; % 3-dim. simplexes opts.mesh_top1 = true ; % for sharp feat's opts.geom_feat = true ; - %opts.mesh_iter = 1000 ; - - %opts.mesh_kern = 'delaunay'; - mesh = jigsaw (opts) ; mask = []; @@ -1228,7 +1123,7 @@ function example(varargin) opts.hfun_hmin = +0.0 ; %opts.optm_kern = 'cvt+dqdx'; - + mesh = jigsaw (opts) ; figure ; drawmesh(mesh) ; diff --git a/jitter.m b/jitter.m index a752e41..0d67c9c 100644 --- a/jitter.m +++ b/jitter.m @@ -107,6 +107,8 @@ cost = [] ; cnrm = +0.0 ; + if (isempty(mesh)), return ; end + if (inspect(mesh,'tria3')) %--------------------------------------- append TRIA3 scores COST = triscr2( ... diff --git a/loadmsh.m b/loadmsh.m index 6cd8874..2f693a4 100644 --- a/loadmsh.m +++ b/loadmsh.m @@ -156,12 +156,12 @@ nver = str2double(stag{1}) ; if (isnan(nver)) - + warning(['Invalid MSHID: ', lstr]); continue; - + end - + if (length(stag) >= +2) kind = ... strtrim(upper(stag{2})); @@ -188,12 +188,12 @@ ] ; if (any(isnan(mesh.radii))) - + warning(['Invalid RADII: ', lstr]); continue; - + end - + else warning(['Invalid RADII: ', lstr]); @@ -213,12 +213,12 @@ fscanf(ffid,[repmat(real,1,ndim),'%i'],numr); if (have ~= numr) - + warning('Invalid POINT! ') ; continue ; end - + if (ndim == +2) mesh.point.coord = [ ... data(1:3:end), ... @@ -245,12 +245,12 @@ fscanf(ffid,[repmat(real,1,ndim),'%i'],numr); if (have ~= numr) - + warning('Invalid SEEDS! ') ; continue ; end - + if (ndim == +2) mesh.seeds.coord = [ ... data(1:3:end), ... @@ -280,12 +280,12 @@ fscanf(ffid,'%f',cnum) ; if (have ~= cnum) - + warning('Invalid COORD! ') ; continue ; end - + mesh.point.coord{idim}= data ; case 'edge2' @@ -300,12 +300,12 @@ fscanf(ffid,[repmat(ints,1,2),'%i'],numr); if (have ~= numr) - + warning('Invalid EDGE2! ') ; continue ; end - + mesh.edge2.index = [ ... data(1:3:end), ... data(2:3:end), ... @@ -326,12 +326,12 @@ fscanf(ffid,[repmat(ints,1,3),'%i'],numr); if (have ~= numr) - + warning('Invalid TRIA3! ') ; continue ; end - + mesh.tria3.index = [ ... data(1:4:end), ... data(2:4:end), ... @@ -353,12 +353,12 @@ fscanf(ffid,[repmat(ints,1,4),'%i'],numr); if (have ~= numr) - + warning('Invalid QUAD4! ') ; continue ; end - + mesh.quad4.index = [ ... data(1:5:end), ... data(2:5:end), ... @@ -381,12 +381,12 @@ fscanf(ffid,[repmat(ints,1,4),'%i'],numr); if (have ~= numr) - + warning('Invalid TRIA4! ') ; continue ; end - + mesh.tria4.index = [ ... data(1:5:end), ... data(2:5:end), ... @@ -409,12 +409,12 @@ fscanf(ffid,[repmat(ints,1,8),'%i'],numr); if (have ~= numr) - + warning('Invalid HEXA8! ') ; continue ; end - + mesh.hexa8.index = [ ... data(1:9:end), ... data(2:9:end), ... @@ -441,12 +441,12 @@ fscanf(ffid,[repmat(ints,1,6),'%i'],numr); if (have ~= numr) - + warning('Invalid WEDG6! ') ; continue ; end - + mesh.wedg6.index = [ ... data(1:7:end), ... data(2:7:end), ... @@ -471,12 +471,12 @@ fscanf(ffid,[repmat(ints,1,5),'%i'],numr); if (have ~= numr) - + warning('Invalid PYRA5! ') ; continue ; end - + mesh.pyra5.index = [ ... data(1:6:end), ... data(2:6:end), ... @@ -500,12 +500,12 @@ fscanf(ffid,[repmat(ints,1,2),'%i'],numr); if (have ~= numr) - + warning('Invalid BOUND! ') ; continue ; end - + mesh.bound.index = [ ... data(1:3:end), ... data(2:3:end), ... @@ -540,12 +540,12 @@ ffid,fstr(1:end-1),numr) ; if (have ~= numr) - + warning(['Invalid VALUE: ', lstr]); continue ; end - + mesh.value = zeros(nnum, vnum); for vpos = +1 : vnum @@ -581,12 +581,12 @@ ffid,fstr(1:end-1),numr) ; if (have ~= numr) - + warning(['Invalid POWER: ', lstr]); continue ; end - + mesh.point.power = ... zeros(nnum, pnum) ; @@ -623,12 +623,12 @@ ffid,fstr(1:end-1),numr) ; if (have ~= numr) - + warning(['Invalid SLOPE: ', lstr]); continue ; end - + mesh.slope = ... zeros(nnum, vnum) ; diff --git a/tetris.m b/tetris.m index 78e8c1f..a651de6 100644 --- a/tetris.m +++ b/tetris.m @@ -34,9 +34,7 @@ end %---------------------------- call JIGSAW via inc. bisection - SCAL = +2. ^ nlev; - - OPTS = opts ; NLEV = nlev ; + SCAL = +2. ^ nlev; OPTS = opts; while (nlev >= +0) @@ -107,7 +105,7 @@ end if (mod(nlev, 2) ~= 0) - + %---------------------------- call JIGSAW kernel at this lev mesh = jitter ( ... OPTS, 3 + nlev * (nlev - 1), 2) ; diff --git a/tools/aabb_tree/exchange.m b/tools/aabb_tree/exchange.m index 31ed862..0f3af47 100644 --- a/tools/aabb_tree/exchange.m +++ b/tools/aabb_tree/exchange.m @@ -1,14 +1,14 @@ function [qp,qx] = exchange(pp,px) %EXCHANGE change the "associativity" of a sparse list set. -% [QP,QX] = EXCHANGE(PP,PX) returns a new set of sparse -% lists {QP,QX} as the "transpose" of the input collection +% [QP,QX] = EXCHANGE(PP,PX) returns a new set of sparse +% lists {QP,QX} as the "transpose" of the input collection % {PP,PX}. This operation can be used to form the inverse -% associations between two collections of objects. For -% example, given two collections A and B, if the input set -% {PP,PI} represents the indexing of A-into-B, the new set +% associations between two collections of objects. For +% example, given two collections A and B, if the input set +% {PP,PI} represents the indexing of A-into-B, the new set % {QP,QI} represents the indexing of B-into-A. % List sets are defined via a "compressed sparse" format, -% with the II-th list in a given collection {XP,XX} stored +% with the II-th list in a given collection {XP,XX} stored % as XX(XP(II,1):XP(II,2)). % % See also QUERYSET @@ -17,51 +17,51 @@ % Email : d.engwirda@gmail.com % Last updated : 05/06/2020 -%---------------------------------------------- basic checks +%---------------------------------------------- basic checks if ( ~isnumeric(pp) || ~isnumeric(px)) error('exchange:incorrectInputClass', ... 'Incorrect input class.') ; end - + if (size(pp,2) ~= 2 || size(px,2) ~= 1 ) error('exchange:incorrectDimensions', ... 'Incorrect input dimensions.') ; end - + if (min(px(:)) <= 0 || ... max(pp(:)) > length(px) ) error('exchange:invalidListIndexing', ... 'Invalid list indexing.') ; end - + %----------------------------------- compute list "tranpose" - qp = zeros(max(px),2); + qp = zeros(max(px),2); qx = zeros(length(px),1); - + for ip = 1:length(pp) % accumulate column count for ii = pp(ip,1):pp(ip,2) qp(px(ii),2) = qp(px(ii),2) + 1; end end - + Z = qp(:,2) == +0 ; % deal with "empty" lists - + qp(:,2) = cumsum(qp(:,2)); qp(:,1) = [+1;qp(1:end-1,2)+1]; - + for ip = 1:length(pp) % tranpose of items array for ii = pp(ip,1):pp(ip,2) qx(qp(px(ii),1)) = ip; qp(px(ii),1) = qp(px(ii),1) + 1; end end - + qp(:,1) = [+1;qp(1:end-1,2)+1]; - + qp(Z,1) = +0; % deal with "empty" lists qp(Z,2) = -1; - + end diff --git a/tools/aabb_tree/findpoly.m b/tools/aabb_tree/findpoly.m index f4dd261..c7cf073 100644 --- a/tools/aabb_tree/findpoly.m +++ b/tools/aabb_tree/findpoly.m @@ -1,21 +1,21 @@ function [ip,ix,tr] = findpoly(pp,ee,pj,varargin) %FINDPOLY point-in-polygon queries for polygon collections. % [IP,IX] = FINDPOLY(PP,EE,PJ) returns the set of polygons -% that enclose the points in the distribution PJ. Polygons +% that enclose the points in the distribution PJ. Polygons % are specified via the cell arrays: % % PP{kk} = [X11,Y11;X22,Y22;...;XNN,YNN]; % EE{kk} = [E11,E12;E21,E22;...;EM1;EM2]; % -% where PP{kk} defines the vertex coordinates of the KK-th -% polygon, and EE{kk} defines its edges. Each edge is -% specified as a pair of vertex indices, such that +% where PP{kk} defines the vertex coordinates of the KK-th +% polygon, and EE{kk} defines its edges. Each edge is +% specified as a pair of vertex indices, such that % PP{kk}(EE{kk}(II,1),:) and PP{kk}(EE{kk}(II,2),:) define % the endpoints of the II-th edge in the KK-th polygon. % -% A set of intersecting polygons is returned for each +% A set of intersecting polygons is returned for each % query point in PJ, such that the II-th point is associa- -% ted with the polygons IX(IP(II,1):IP(II,2)). Unenclosed +% ted with the polygons IX(IP(II,1):IP(II,2)). Unenclosed % points have IP(II,1) == +0. % % In general, query points may be matched to multiple pol- @@ -23,21 +23,21 @@ % % [IP,IX,TR] = FINDPOLY(PP,EE,PJ) additionally returns the % supporting aabb-tree used internally to compute the que- -% ry. If the underlying collection [PP,EE] is static, the -% tree TR may be passed to subsequent calls, via [...] = -% FINDPOLY(PP,EE,PJ,TR). This syntax may lead to improved -% performance, especially when the number of polygons -% is large w.r.t. the number of query points. Note that in -% such cases the underlying polygons are NOT permitted to +% ry. If the underlying collection [PP,EE] is static, the +% tree TR may be passed to subsequent calls, via [...] = +% FINDPOLY(PP,EE,PJ,TR). This syntax may lead to improved +% performance, especially when the number of polygons +% is large w.r.t. the number of query points. Note that in +% such cases the underlying polygons are NOT permitted to % change between calls, or erroneous results may be retur- -% ned. Additional parameters used to control the creation -% of the underlying aabb-tree may also be passed via [...] -% = FINDPOLY(PP,EE,PI,TR,OP). See MAKETREE for additional +% ned. Additional parameters used to control the creation +% of the underlying aabb-tree may also be passed via [...] +% = FINDPOLY(PP,EE,PI,TR,OP). See MAKETREE for additional % information. % % See also MAKETREE, EXCHANGE -% Given K polygons (each with M edges on average) the task +% Given K polygons (each with M edges on average) the task % is to find the enclosing polygons for a set of N points. % The (obvious) naive implementation is expensive, leading % to O(K*M*N) complexity (based on a simple loop over all @@ -45,13 +45,13 @@ % for each individually). This code aims to do better: % % * Employing a "fast" inpolygon routine, reducing the comp- -% lexity of each points-in-polygon test (based on spatial +% lexity of each points-in-polygon test (based on spatial % sorting) to approximately O((N+M)*log(N)). % -% * Employing a spatial tree (an aabb-tree) to localise each -% points-in-polygon query within a spatially local "tile". +% * Employing a spatial tree (an aabb-tree) to localise each +% points-in-polygon query within a spatially local "tile". % This typically gains another logarithmic factor, so is a -% big win for large K. +% big win for large K. % Darren Engwirda : 2020 -- % Email : d.engwirda@gmail.com @@ -71,14 +71,14 @@ %------------------------------- extract user-defined inputs if (nargin >= +4), tr = varargin{1}; end if (nargin >= +5), op = varargin{2}; end - -%---------------------------------------------- basic checks + +%---------------------------------------------- basic checks if (~iscell(pp) || ~iscell(ee) || ... ~isnumeric(pj) ) error('findpoly:incorrectInputClass', ... 'Incorrect input class.') ; end - + %---------------------------------------------- basic checks if (any(cellfun('ndims', pp) ~= +2) || ... any(cellfun('size', pp, 2) ~= +2)) @@ -90,12 +90,12 @@ error('findpoly:incorrectDimensions', ... 'Incorrect input dimensions.'); end - + %------------------------------- test query array for VERT's if (ndims(pj) ~= +2 || size(pj,2) ~= +2 ) error('findpoly:incorrectDimensions', ... 'Incorrect input dimensions.'); - end + end %---------------------------------------------- basic checks if (~isempty(tr) && ~isstruct(tr) ) @@ -115,13 +115,13 @@ xx = [xx{:}]; bb(:,1) = xx(1:2:end-1); bb(:,2) = xx(2:2:end-0); - + xx = cellfun( ... @max,pp,'uniformoutput',false) ; xx = [xx{:}]; bb(:,3) = xx(1:2:end-1); bb(:,4) = xx(2:2:end-0); - + %------------------------------ compute aabb-tree for aabb's if (isempty(op) || ... ~isfield(op,'nobj')) @@ -129,20 +129,20 @@ end tr = maketree(bb,op); % compute aabb-tree end - + %------------------------------ compute tree-to-vert mapping tm = mapvert(tr,pj) ; %------------------------------ compute vert-to-poly queries [ii,px,ix] = ... queryset(tr,tm,@polykern,pj,pp,ee) ; - -%------------------------------ re-index onto full obj. list + +%------------------------------ re-index onto full obj. list ip = zeros(size(pj,1),2); ip( :,2) = -1 ; - + if (isempty(ii)), return; end - + ip(ii,:) = px ; end diff --git a/tools/ellipsoid/cubedsphere.m b/tools/ellipsoid/cubedsphere.m index c50645f..f6ae028 100644 --- a/tools/ellipsoid/cubedsphere.m +++ b/tools/ellipsoid/cubedsphere.m @@ -1,6 +1,6 @@ function [mesh] = cubedsphere(opts,nlev) %CUBEDSPHERE an Nth-level cubedsphere mesh of the ellipsoid -%defined by GEOM.RADII. +%defined by GEOM.RADII. % % See also JIGSAW % @@ -65,7 +65,7 @@ savemsh(opts.init_file,mesh); mesh = refine(opts,nlev) ; - + end function [mesh] = refine (opts,nlev) @@ -89,7 +89,7 @@ mesh = jigsaw(opts) ; if (ilev >= +1) - + %---------------------------- create/write current INIT data [path,name,fext] = ... fileparts(opts.mesh_file) ; diff --git a/tools/ellipsoid/icosahedron.m b/tools/ellipsoid/icosahedron.m index 11bde9d..59a9d38 100644 --- a/tools/ellipsoid/icosahedron.m +++ b/tools/ellipsoid/icosahedron.m @@ -1,6 +1,6 @@ function [mesh] = icosahedron(opts,nlev) %ICOSAHEDRON an Nth-level icosahedral mesh of the ellipsoid -%defined by GEOM.RADII. +%defined by GEOM.RADII. % % See also JIGSAW % @@ -58,7 +58,7 @@ mesh.tria3.index = [ 1, 4, 6, 0 1, 6, 8, 0 - 1, 8, 10, 0 + 1, 8, 10, 0 1, 10, 12, 0 1, 12, 4, 0 2, 3, 5, 0 @@ -82,9 +82,9 @@ opts.init_file = opts.mesh_file; savemsh(opts.init_file,mesh); - + mesh = refine(opts,nlev) ; - + end function [mesh] = refine (opts,nlev) @@ -108,7 +108,7 @@ mesh = jigsaw(opts) ; if (ilev >= +1) - + %---------------------------- create/write current INIT data [path,name,fext] = ... fileparts(opts.mesh_file) ; diff --git a/tools/poly_sign/inpoly2.m b/tools/poly_sign/inpoly2.m index 7bfc98b..4fb42ad 100644 --- a/tools/poly_sign/inpoly2.m +++ b/tools/poly_sign/inpoly2.m @@ -1,183 +1,183 @@ -function [STAT,BNDS] = inpoly2(varargin) -%INPOLY2 compute "points-in-polygon" queries. -% [STAT] = INPOLY2(VERT,NODE,EDGE) returns the "inside/ou- -% tside" status for a set of vertices VERT and a polygon -% {NODE,EDGE} embedded in a two-dimensional plane. General -% non-convex and multiply-connected polygonal regions can -% be handled. VERT is an N-by-2 array of XY coordinates to -% be tested. STAT is an associated N-by-1 logical array, -% with STAT(II) = TRUE if VERT(II,:) is an interior point. -% The polygonal region is defined as a piecewise-straight- -% line-graph, where NODE is an M-by-2 array of polygon ve- -% rtices and EDGE is a P-by-2 array of edge indexing. Each -% row in EDGE represents an edge of the polygon, such that -% NODE(EDGE(KK,1),:) and NODE(EDGE(KK,2),:) are the coord- -% inates of the endpoints of the KK-TH edge. If the argum- -% ent EDGE is omitted it assumed that the vertices in NODE -% are connected in ascending order. -% -% [STAT,BNDS] = INPOLY2(..., FTOL) also returns an N-by-1 -% logical array BNDS, with BNDS(II) = TRUE if VERT(II,:) -% lies "on" a boundary segment, where FTOL is a floating- -% point tolerance for boundary comparisons. By default, -% FTOL = EPS ^ 0.85. -% -% See also INPOLYGON - -% This algorithm is based on a "crossing-number" test, co- -% unting the number of times a line extending from each -% point past the right-most region of the polygon interse- -% cts with the polygonal boundary. Points with odd counts -% are "inside". A simple implementation requires that each -% edge intersection be checked for each point, leading to -% O(N*M) complexity... -% -% This implementation seeks to improve these bounds: -% -% * Sorting the query points by y-value and determining can- -% didate edge intersection sets via binary-search. Given a -% configuration with N test points, M edges and an average -% point-edge "overlap" of H, the overall complexity scales -% like O(M*H + M*LOG(N) + N*LOG(N)), where O(N*LOG(N)) -% operations are required for sorting, O(M*LOG(N)) operat- -% ions required for the set of binary-searches, and O(M*H) -% operations required for the intersection tests, where H -% is typically small on average, such that H << N. -% -% * Carefully checking points against the bounding-box asso- -% ciated with each polygon edge. This minimises the number -% of calls to the (relatively) expensive edge intersection -% test. - -% Darren Engwirda : 2017 -- -% Email : d.engwirda@gmail.com -% Last updated : 31/03/2020 - -%---------------------------------------------- extract args - node = []; edge = []; vert = []; - - fTOL = eps ^ .85; - - if (nargin>=+1), vert = varargin{1}; end - if (nargin>=+2), node = varargin{2}; end - if (nargin>=+3), edge = varargin{3}; end - if (nargin>=+4), fTOL = varargin{4}; end - -%---------------------------------------------- default args - nnod = size(node,1) ; - nvrt = size(vert,1) ; - - if (isempty(edge)) - edge = [(1:nnod-1)',(2:nnod)'; nnod,1]; - end - -%---------------------------------------------- basic checks - if ( ~isnumeric(node) || ... - ~isnumeric(edge) || ... - ~isnumeric(vert) || ... - ~isnumeric(fTOL) ) - error('inpoly2:incorrectInputClass' , ... - 'Incorrect input class.') ; - end - -%---------------------------------------------- basic checks - if (ndims(node) ~= +2 || ... - ndims(edge) ~= +2 || ... - ndims(vert) ~= +2 || ... - numel(fTOL) ~= +1 ) - error('inpoly2:incorrectDimensions' , ... - 'Incorrect input dimensions.'); - end - if (size(node,2)~= +2 || ... - size(edge,2)~= +2 || ... - size(vert,2)~= +2 ) - error('inpoly2:incorrectDimensions' , ... - 'Incorrect input dimensions.'); - end - -%---------------------------------------------- basic checks - if (min([edge(:)]) < +1 || ... - max([edge(:)]) > nnod) - error('inpoly2:invalidInputs', ... - 'Invalid EDGE input array.') ; - end - - STAT = false(size(vert,1),1) ; - BNDS = false(size(vert,1),1) ; - -%----------------------------------- prune points using bbox - mask = ... - vert(:,1) >= min (node(:,1)) & ... - vert(:,1) <= max (node(:,1)) & ... - vert(:,2) >= min (node(:,2)) & ... - vert(:,2) <= max (node(:,2)) ; - - vert = vert(mask, :) ; - -%-------------- flip to ensure the y-axis is the "long" axis - vmin = min(vert,[],1); - vmax = max(vert,[],1); - ddxy = vmax - vmin ; - - lbar = sum(ddxy) / 2.; - - if (ddxy(1) > ddxy(2)) - vert = vert(:,[2,1]) ; - node = node(:,[2,1]) ; - end - -%----------------------------------- sort points via y-value - swap = ... - node(edge(:,2),2) ... - < node(edge(:,1),2) ; - - edge(swap,[1,2]) = ... - edge(swap,[2,1]) ; - - [~,ivec] = ... - sort(vert(:,+2)) ; - vert = vert (ivec,:) ; - - if (exist( ... - 'OCTAVE_VERSION','builtin') > +0) - - if (exist('inpoly2_oct','file') == +3) - - %-- delegate to the compiled version of the code if it's - %-- available - - [stat,bnds] = ... - inpoly2_oct( ... - vert,node,edge,fTOL,lbar) ; - - else - - %-- otherwise, just call the native m-code version - - [stat,bnds] = ... - inpoly2_mat( ... - vert,node,edge,fTOL,lbar) ; - - end - - else - - %-- MATLAB's JIT is generally smart enough these days to - %-- run this efficiently - - [stat,bnds] = ... - inpoly2_mat( ... - vert,node,edge,fTOL,lbar) ; - - end - - stat(ivec) = stat ; - bnds(ivec) = bnds ; - - STAT(mask) = stat ; - BNDS(mask) = bnds ; - -end - - - +function [STAT,BNDS] = inpoly2(varargin) +%INPOLY2 compute "points-in-polygon" queries. +% [STAT] = INPOLY2(VERT,NODE,EDGE) returns the "inside/ou- +% tside" status for a set of vertices VERT and a polygon +% {NODE,EDGE} embedded in a two-dimensional plane. General +% non-convex and multiply-connected polygonal regions can +% be handled. VERT is an N-by-2 array of XY coordinates to +% be tested. STAT is an associated N-by-1 logical array, +% with STAT(II) = TRUE if VERT(II,:) is an interior point. +% The polygonal region is defined as a piecewise-straight- +% line-graph, where NODE is an M-by-2 array of polygon ve- +% rtices and EDGE is a P-by-2 array of edge indexing. Each +% row in EDGE represents an edge of the polygon, such that +% NODE(EDGE(KK,1),:) and NODE(EDGE(KK,2),:) are the coord- +% inates of the endpoints of the KK-TH edge. If the argum- +% ent EDGE is omitted it assumed that the vertices in NODE +% are connected in ascending order. +% +% [STAT,BNDS] = INPOLY2(..., FTOL) also returns an N-by-1 +% logical array BNDS, with BNDS(II) = TRUE if VERT(II,:) +% lies "on" a boundary segment, where FTOL is a floating- +% point tolerance for boundary comparisons. By default, +% FTOL = EPS ^ 0.85. +% +% See also INPOLYGON + +% This algorithm is based on a "crossing-number" test, co- +% unting the number of times a line extending from each +% point past the right-most region of the polygon interse- +% cts with the polygonal boundary. Points with odd counts +% are "inside". A simple implementation requires that each +% edge intersection be checked for each point, leading to +% O(N*M) complexity... +% +% This implementation seeks to improve these bounds: +% +% * Sorting the query points by y-value and determining can- +% didate edge intersection sets via binary-search. Given a +% configuration with N test points, M edges and an average +% point-edge "overlap" of H, the overall complexity scales +% like O(M*H + M*LOG(N) + N*LOG(N)), where O(N*LOG(N)) +% operations are required for sorting, O(M*LOG(N)) operat- +% ions required for the set of binary-searches, and O(M*H) +% operations required for the intersection tests, where H +% is typically small on average, such that H << N. +% +% * Carefully checking points against the bounding-box asso- +% ciated with each polygon edge. This minimises the number +% of calls to the (relatively) expensive edge intersection +% test. + +% Darren Engwirda : 2017 -- +% Email : d.engwirda@gmail.com +% Last updated : 31/03/2020 + +%---------------------------------------------- extract args + node = []; edge = []; vert = []; + + fTOL = eps ^ .85; + + if (nargin>=+1), vert = varargin{1}; end + if (nargin>=+2), node = varargin{2}; end + if (nargin>=+3), edge = varargin{3}; end + if (nargin>=+4), fTOL = varargin{4}; end + +%---------------------------------------------- default args + nnod = size(node,1) ; + nvrt = size(vert,1) ; + + if (isempty(edge)) + edge = [(1:nnod-1)',(2:nnod)'; nnod,1]; + end + +%---------------------------------------------- basic checks + if ( ~isnumeric(node) || ... + ~isnumeric(edge) || ... + ~isnumeric(vert) || ... + ~isnumeric(fTOL) ) + error('inpoly2:incorrectInputClass' , ... + 'Incorrect input class.') ; + end + +%---------------------------------------------- basic checks + if (ndims(node) ~= +2 || ... + ndims(edge) ~= +2 || ... + ndims(vert) ~= +2 || ... + numel(fTOL) ~= +1 ) + error('inpoly2:incorrectDimensions' , ... + 'Incorrect input dimensions.'); + end + if (size(node,2)~= +2 || ... + size(edge,2)~= +2 || ... + size(vert,2)~= +2 ) + error('inpoly2:incorrectDimensions' , ... + 'Incorrect input dimensions.'); + end + +%---------------------------------------------- basic checks + if (min([edge(:)]) < +1 || ... + max([edge(:)]) > nnod) + error('inpoly2:invalidInputs', ... + 'Invalid EDGE input array.') ; + end + + STAT = false(size(vert,1),1) ; + BNDS = false(size(vert,1),1) ; + +%----------------------------------- prune points using bbox + mask = ... + vert(:,1) >= min (node(:,1)) & ... + vert(:,1) <= max (node(:,1)) & ... + vert(:,2) >= min (node(:,2)) & ... + vert(:,2) <= max (node(:,2)) ; + + vert = vert(mask, :) ; + +%-------------- flip to ensure the y-axis is the "long" axis + vmin = min(vert,[],1); + vmax = max(vert,[],1); + ddxy = vmax - vmin ; + + lbar = sum(ddxy) / 2.; + + if (ddxy(1) > ddxy(2)) + vert = vert(:,[2,1]) ; + node = node(:,[2,1]) ; + end + +%----------------------------------- sort points via y-value + swap = ... + node(edge(:,2),2) ... + < node(edge(:,1),2) ; + + edge(swap,[1,2]) = ... + edge(swap,[2,1]) ; + + [~,ivec] = ... + sort(vert(:,+2)) ; + vert = vert (ivec,:) ; + + if (exist( ... + 'OCTAVE_VERSION','builtin') > +0) + + if (exist('inpoly2_oct','file') == +3) + + %-- delegate to the compiled version of the code if it's + %-- available + + [stat,bnds] = ... + inpoly2_oct( ... + vert,node,edge,fTOL,lbar) ; + + else + + %-- otherwise, just call the native m-code version + + [stat,bnds] = ... + inpoly2_mat( ... + vert,node,edge,fTOL,lbar) ; + + end + + else + + %-- MATLAB's JIT is generally smart enough these days to + %-- run this efficiently + + [stat,bnds] = ... + inpoly2_mat( ... + vert,node,edge,fTOL,lbar) ; + + end + + stat(ivec) = stat ; + bnds(ivec) = bnds ; + + STAT(mask) = stat ; + BNDS(mask) = bnds ; + +end + + + diff --git a/tools/poly_sign/inpoly2_mat.m b/tools/poly_sign/inpoly2_mat.m index ee9bb06..2b20b37 100644 --- a/tools/poly_sign/inpoly2_mat.m +++ b/tools/poly_sign/inpoly2_mat.m @@ -18,10 +18,10 @@ stat = false(nvrt,1) ; bnds = false(nvrt,1) ; - + %----------------------------------- loop over polygon edges for epos = +1 : size(edge,1) - + inod = edge(epos,1) ; jnod = edge(epos,2) ; @@ -30,107 +30,107 @@ ytwo = node(jnod,2) ; xone = node(inod,1) ; xtwo = node(jnod,1) ; - + xmin = min(xone,xtwo) ; xmax = max(xone,xtwo) ; - - xmax = xmax + veps; - + + xmax = xmax + veps; + ymin = yone - veps; ymax = ytwo + veps; - + ydel = ytwo - yone; xdel = xtwo - xone; %------------------------------- find top VERT(:,2)= ymin) ilow = ilow - 1 ; end %------------------------------- calc. edge-intersection for jpos = ilow+1 : nvrt - + if (bnds(jpos)), continue ; end - + xpos = vert(jpos,1) ; ypos = vert(jpos,2) ; - + if (ypos <= ymax) if (xpos >= xmin) if (xpos <= xmax) - - %------------------- compute crossing number + + %------------------- compute crossing number mul1 = ... ydel * (xpos - xone) ; mul2 = ... xdel * (ypos - yone) ; - + if (feps >= ... abs(mul2 - mul1) ) - + %------------------- BNDS -- approx. on edge bnds(jpos)= true ; stat(jpos)= true ; - + elseif (ypos == yone ... && xpos == xone ) - + %------------------- BNDS -- match about ONE bnds(jpos)= true ; stat(jpos)= true ; - + elseif (ypos == ytwo ... && xpos == xtwo ) - + %------------------- BNDS -- match about TWO bnds(jpos)= true ; stat(jpos)= true ; - + elseif (mul1 < mul2) - + if (ypos >= yone ... && ypos < ytwo) - + %------------------- advance crossing number stat(jpos) = ... ~stat (jpos) ; - + end - + end - + end else - + if (ypos >= yone ... && ypos < ytwo) - + %------------------- advance crossing number stat(jpos) = ... ~stat (jpos) ; - + end - + end else - + break ; % done -- due to the sort - + end - + end end From ca8b4f38180026451edecf5c5712f86c102472fd Mon Sep 17 00:00:00 2001 From: Darren Engwirda Date: Sun, 13 Sep 2020 16:06:09 -0600 Subject: [PATCH 5/6] Update bindings for jigsaw-0.9.13.xx --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) 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. From c2110c551e58b6d20a7742433c06db0a1c0d67c7 Mon Sep 17 00:00:00 2001 From: dengwirda Date: Sun, 13 Sep 2020 20:15:23 -0600 Subject: [PATCH 6/6] Update bindings for jigsaw-0.9.13.xx --- jitter.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jitter.m b/jitter.m index 0d67c9c..b049bbd 100644 --- a/jitter.m +++ b/jitter.m @@ -75,7 +75,7 @@ %---------------------------------- keep nodes far from seam init.mshID = 'euclidean-mesh'; init.point.coord = ... - mesh.point.coord(keep,:) ; + next.point.coord(keep,:) ; done = all(keep);