From 51b5ec5904f2d631c1d665ce2a5da75d9f936de5 Mon Sep 17 00:00:00 2001 From: dengwirda Date: Sun, 27 Jul 2025 20:25:04 +1000 Subject: [PATCH 01/14] Add min/max limits for dual mesh weight optim. --- jigsawpy/jig_l.py | 10 ++++++++++ jigsawpy/jig_t.py | 9 +++++++++ jigsawpy/libsaw.py | 10 ++++++++++ jigsawpy/loadjig.py | 5 +++++ jigsawpy/savejig.py | 5 +++++ 5 files changed, 39 insertions(+) diff --git a/jigsawpy/jig_l.py b/jigsawpy/jig_l.py index c1287a8..4c1f73f 100644 --- a/jigsawpy/jig_l.py +++ b/jigsawpy/jig_l.py @@ -269,6 +269,16 @@ class libsaw_jig_t(ct.Structure): ("optm_qlim", real_t), + # OPTM_WMIN - {default=-7./8.} lower limit on dual + # mesh weights relative to cell radius. + + ("optm_wmin", real_t), + + # OPTM_WMAX - {default=+1./80} upper limit on dual + # mesh weights relative to cell radius. + + ("optm_wmax", real_t), + # OPTM_TRIA - {default= true} allow for optimisation # of TRIA grid geometry. diff --git a/jigsawpy/jig_t.py b/jigsawpy/jig_t.py index d61028e..a6f71f3 100644 --- a/jigsawpy/jig_t.py +++ b/jigsawpy/jig_t.py @@ -207,6 +207,12 @@ function above which gradient-based optimisation is attempted. + OPTS.OPTM_WMIN - {default=-7./8.} lower limit on dual + mesh weights relative to cell radius. + + OPTS.OPTM_WMAX - {default=+1./80} upper limit on dual + mesh weights relative to cell radius. + OPTS.OPTM_TRIA - {default= true} allow for optimisation of TRIA grid geometry. @@ -322,6 +328,9 @@ def __init__(self): self.optm_qtol = None self.optm_qlim = None + self.optm_wmin = None + self.optm_wmax = None + self.optm_zip_ = None self.optm_div_ = None self.optm_tria = None diff --git a/jigsawpy/libsaw.py b/jigsawpy/libsaw.py index ca6faec..e8f3245 100644 --- a/jigsawpy/libsaw.py +++ b/jigsawpy/libsaw.py @@ -317,6 +317,16 @@ def put_jig_t(jigt, jigl): elif (jigt.optm_qlim is not None): raise TypeError("OPTM-QLIM type") + if (is_type_t(jigt.optm_wmin, float)): + jigl.optm_wmin = real_t(jigt.optm_wmin) + elif (jigt.optm_wmin is not None): + raise TypeError("OPTM-WMIN type") + + if (is_type_t(jigt.optm_wmax, float)): + jigl.optm_wmax = real_t(jigt.optm_wmax) + elif (jigt.optm_wmax is not None): + raise TypeError("OPTM-WMAX type") + if (is_type_t(jigt.optm_tria, bool)): jigl.optm_tria = indx_t(jigt.optm_tria) elif (jigt.optm_tria is not None): diff --git a/jigsawpy/loadjig.py b/jigsawpy/loadjig.py index 3be3e03..dffdba2 100644 --- a/jigsawpy/loadjig.py +++ b/jigsawpy/loadjig.py @@ -160,6 +160,11 @@ def loadjig(name, opts): if (item == "OPTM_QLIM"): opts.optm_qlim = float(ltag[1]) + if (item == "OPTM_WMIN"): + opts.optm_wmin = float(ltag[1]) + if (item == "OPTM_WMAX"): + opts.optm_wmax = float(ltag[1]) + if (item == "OPTM_ZIP_"): opts.optm_zip_ = bool(ltag[1]) if (item == "OPTM_DIV_"): diff --git a/jigsawpy/savejig.py b/jigsawpy/savejig.py index 3cb9fef..2bd9948 100644 --- a/jigsawpy/savejig.py +++ b/jigsawpy/savejig.py @@ -203,6 +203,11 @@ def savejig(name, opts): if (opts.optm_qlim is not None): savereal(fptr, opts.optm_qlim, "OPTM_QLIM") + if (opts.optm_wmin is not None): + savereal(fptr, opts.optm_wmin, "OPTM_WMIN") + if (opts.optm_wmax is not None): + savereal(fptr, opts.optm_wmax, "OPTM_WMAX") + if (opts.optm_zip_ is not None): savebool(fptr, opts.optm_zip_, "OPTM_ZIP_") if (opts.optm_div_ is not None): From 2084cd62a896370c5133f10c464f4529061c72fc Mon Sep 17 00:00:00 2001 From: dengwirda Date: Sun, 27 Jul 2025 20:51:55 +1000 Subject: [PATCH 02/14] Adjust TETRIS iteration scheme --- jigsawpy/jigsaw.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/jigsawpy/jigsaw.py b/jigsawpy/jigsaw.py index 2fda9b7..f78fba1 100644 --- a/jigsawpy/jigsaw.py +++ b/jigsawpy/jigsaw.py @@ -253,6 +253,9 @@ def jitter(opts, imax, ibad, mesh=None): for iter in range(imax): + if (opts.optm_dual is not None): + OPTS.optm_dual = iter == imax - 1 + if (mesh.point is not None and mesh.point.size != +0): @@ -363,7 +366,7 @@ def tetris(opts, nlev, mesh=None): OPTS.hfun_hmin = \ opts.hfun_hmin * SCAL - if (opts.hfun_file is not None): + if (opts.hfun_file is not None and SCAL > 1.0): #------------------------ create/write current HFUN data path = Path(opts.hfun_file).parent name = Path(opts.hfun_file).stem @@ -384,7 +387,7 @@ def tetris(opts, nlev, mesh=None): savemsh(OPTS.hfun_file, HFUN) #------------------------ call JIGSAW kernel at this lev - jitter(OPTS, 4 + (nlev > 0) * 44, 3, mesh) + jitter(OPTS, 4 + (nlev > 0) *12, 3, mesh) nlev = nlev - 1 SCAL = SCAL / 2. From cf78c83beb8280c51602828f833d2e0e6564cd5a Mon Sep 17 00:00:00 2001 From: dengwirda Date: Tue, 12 Aug 2025 01:54:51 +1000 Subject: [PATCH 03/14] Ensure correct reshape for scaling --- jigsawpy/project.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/jigsawpy/project.py b/jigsawpy/project.py index e4c5a1c..ea247a9 100644 --- a/jigsawpy/project.py +++ b/jigsawpy/project.py @@ -98,14 +98,14 @@ def project(mesh, proj, sign): if (mesh.value is not None and mesh.value.size != +0): - mesh.value = mesh.value * SCAL + mesh.value*= SCAL.reshape(mesh.value.shape) if (mesh.power is not None and mesh.power.size != +0): SPOW = np.sqrt(SCAL) - mesh.power = mesh.power * SPOW + mesh.power*= SPOW.reshape(mesh.power.shape) elif (kind == "euclidean-grid" or kind == "ellipsoid-grid"): @@ -220,8 +220,7 @@ def project(mesh, proj, sign): tset.append(triaB) - mesh.tria3 = \ - np.concatenate(tset, axis=0) + mesh.tria3 = np.concatenate(tset, axis=0) #----------------------------------- setup proj.'d extras if (mesh.slope is not None and @@ -236,7 +235,7 @@ def project(mesh, proj, sign): mesh.value = np.reshape( mesh.value, mesh.value.size) - mesh.value = mesh.value * SCAL + mesh.value*= SCAL.reshape(mesh.value.shape) if (mesh.power is not None and mesh.power.size != +0): @@ -246,6 +245,6 @@ def project(mesh, proj, sign): SPOW = np.sqrt(SCAL) - mesh.power = mesh.power * SPOW + mesh.power*= SPOW.reshape(mesh.power.shape) return From e640170c070995d8303eb63e0b6bf43306f17079 Mon Sep 17 00:00:00 2001 From: dengwirda Date: Tue, 12 Aug 2025 02:04:45 +1000 Subject: [PATCH 04/14] Update bindings for jigsaw-1.1.0.xx --- jigsawpy/__init__.py | 6 ++++-- jigsawpy/jig_l.py | 16 ++++++++++++++++ jigsawpy/jig_t.py | 15 +++++++++++++++ jigsawpy/jigsaw.py | 15 +++++++++++---- jigsawpy/libsaw.py | 10 ++++++++++ jigsawpy/loadjig.py | 8 ++++++-- jigsawpy/savejig.py | 5 +++++ setup.py | 33 +++++++++++---------------------- 8 files changed, 78 insertions(+), 30 deletions(-) diff --git a/jigsawpy/__init__.py b/jigsawpy/__init__.py index 67f8f9b..884f8ea 100644 --- a/jigsawpy/__init__.py +++ b/jigsawpy/__init__.py @@ -13,9 +13,9 @@ * JIGSAW: Interface to the JIGSAW meshing library. ------------------------------------------------------------ * - * Last updated: 10 Jan., 2023 + * Last updated: 04 Aug., 2025 * - * Copyright 2019-2023 + * Copyright 2019-2025 * Darren Engwirda * d.engwirda@gmail.com * https://github.com/dengwirda @@ -65,6 +65,8 @@ from jigsawpy.savemsh import savemsh from jigsawpy.loadjig import loadjig from jigsawpy.savejig import savejig +from jigsawpy.loadprj import loadprj +from jigsawpy.saveprj import saveprj from jigsawpy.certify import certify diff --git a/jigsawpy/jig_l.py b/jigsawpy/jig_l.py index 4c1f73f..519ef66 100644 --- a/jigsawpy/jig_l.py +++ b/jigsawpy/jig_l.py @@ -107,6 +107,22 @@ class libsaw_jig_t(ct.Structure): ("mesh_iter", indx_t), + # MESH_ORPH - {default=true} allow "orphaned" facets + # to remain in the mesh. A K-1 dimensional subcell is + # orphaned if it does not appear in any K-dimensional + # cell, e.g. a surface triangle that is not the face + # of any interior tetrahedron. + + ("mesh_orph", indx_t), + + # MESH_LOCK - {default=false} prevent the refinement + # of subfaces during subsequent refinement. The + # refinement of a K-dimensional cell is deferred if + # doing so would cause any K-1 dimensional subfaces to + # be refined. + + ("mesh_lock", indx_t), + # MESH_TOP1 - {default=false} enforce 1-dim. topolog- # ical constraints. 1-dim. edges are refined until all # embedded nodes are "locally 1-manifold", i.e. nodes diff --git a/jigsawpy/jig_t.py b/jigsawpy/jig_t.py index a6f71f3..e0f6b47 100644 --- a/jigsawpy/jig_t.py +++ b/jigsawpy/jig_t.py @@ -96,6 +96,18 @@ inement iterations. Set ITER=N to see progress after N iterations. + OPTS.MESH_ORPH - {default=true} allow "orphaned" facets + to remain in the mesh. A K-1 dimensional subcell is + orphaned if it does not appear in any K-dimensional + cell, e.g. a surface triangle that is not the face + of any interior tetrahedron. + + OPTS.MESH_LOCK - {default=false} prevent the refinement + of subfaces during subsequent refinement. The + refinement of a K-dimensional cell is deferred if + doing so would cause any K-1 dimensional subfaces to + be refined. + OPTS.MESH_TOP1 - {default=false} enforce 1-dim. topolog- ical constraints. 1-dim. edges are refined until all embedded nodes are "locally 1-manifold", i.e. nodes @@ -292,6 +304,9 @@ def __init__(self): self.mesh_iter = None + self.mesh_orph = None + self.mesh_lock = None + self.mesh_dims = None self.mesh_top1 = None diff --git a/jigsawpy/jigsaw.py b/jigsawpy/jigsaw.py index f78fba1..378fee6 100644 --- a/jigsawpy/jigsaw.py +++ b/jigsawpy/jigsaw.py @@ -253,16 +253,19 @@ def jitter(opts, imax, ibad, mesh=None): for iter in range(imax): + npts = npwr = 0 + if (mesh.point is not None): npts = mesh.point.size + if (mesh.power is not None): npwr = mesh.power.size + if (opts.optm_dual is not None): - OPTS.optm_dual = iter == imax - 1 + OPTS.optm_dual = iter == imax-1 or npts == npwr if (mesh.point is not None and mesh.point.size != +0): nvrt = mesh.point.size - keep = np.full( - (nvrt), True, dtype=bool) + keep = np.full((nvrt), True, dtype=bool) #------------------------------ setup initial conditions path = Path(opts.mesh_file).parent @@ -304,11 +307,15 @@ def jitter(opts, imax, ibad, mesh=None): #------------------------------ keep nodes far from seam init = jigsaw_msh_t() - init.point = mesh.point[keep] + if (mesh.point is not None): + init.point = mesh.point[keep] + if (mesh.power is not None): + init.power = mesh.power[keep] savemsh(OPTS.init_file, init) #------------------------------ call JIGSAW with new ICs + print("optm_dual:", OPTS.optm_dual) jigsaw (OPTS, mesh) # noqa return diff --git a/jigsawpy/libsaw.py b/jigsawpy/libsaw.py index e8f3245..34c9f2d 100644 --- a/jigsawpy/libsaw.py +++ b/jigsawpy/libsaw.py @@ -221,6 +221,16 @@ def put_jig_t(jigt, jigl): elif (jigt.mesh_iter is not None): raise TypeError("MESH-ITER type") + if (is_type_t(jigt.mesh_orph, bool)): + jigl.mesh_orph = indx_t(jigt.mesh_orph) + elif (jigt.mesh_orph is not None): + raise TypeError("MESH-ORPH type") + + if (is_type_t(jigt.mesh_lock, bool)): + jigl.mesh_lock = indx_t(jigt.mesh_lock) + elif (jigt.mesh_lock is not None): + raise TypeError("MESH-LOCK type") + if (is_type_t(jigt.mesh_top1, bool)): jigl.mesh_top1 = indx_t(jigt.mesh_top1) elif (jigt.mesh_top1 is not None): diff --git a/jigsawpy/loadjig.py b/jigsawpy/loadjig.py index dffdba2..4507994 100644 --- a/jigsawpy/loadjig.py +++ b/jigsawpy/loadjig.py @@ -33,8 +33,7 @@ def loadjig(name, opts): #----------------------- parse next non-null section line = line.strip() - if (line[0] == "#"): - continue + if (line[0] == "#"): continue ltag = line.split("=") item = ltag[0].upper().strip() @@ -103,6 +102,11 @@ def loadjig(name, opts): if (item == "MESH_ITER"): opts.mesh_iter = int(ltag[1]) + if (item == "MESH_ORPH"): + opts.mesh_orph = bool(ltag[1]) + if (item == "MESH_LOCK"): + opts.mesh_lock = bool(ltag[1]) + if (item == "MESH_DIMS"): opts.mesh_dims = int(ltag[1]) diff --git a/jigsawpy/savejig.py b/jigsawpy/savejig.py index 2bd9948..2c41ccd 100644 --- a/jigsawpy/savejig.py +++ b/jigsawpy/savejig.py @@ -146,6 +146,11 @@ def savejig(name, opts): if (opts.mesh_iter is not None): saveints(fptr, opts.mesh_iter, "MESH_ITER") + if (opts.mesh_orph is not None): + savebool(fptr, opts.mesh_orph, "MESH_ORPH") + if (opts.mesh_lock is not None): + savebool(fptr, opts.mesh_lock, "MESH_LOCK") + if (opts.mesh_dims is not None): saveints(fptr, opts.mesh_dims, "MESH_DIMS") diff --git a/setup.py b/setup.py index 374404f..0992fa9 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,6 @@ import shutil from setuptools import setup, find_packages, Command -from packaging import version NAME = "jigsawpy" DESCRIPTION = \ @@ -13,7 +12,7 @@ AUTHOR = "Darren Engwirda" AUTHOR_EMAIL = "d.engwirda@gmail.com" URL = "https://github.com/dengwirda/" -VERSION = "1.0.0" +VERSION = "1.1.0" REQUIRES_PYTHON = ">=3.6.0" KEYWORDS = "Mesh-generation Delaunay Voronoi" @@ -45,18 +44,6 @@ LONG_DESCRIPTION = DESCRIPTION -def get_cmake_version(): - try: - out = subprocess.check_output( - ["cmake", "--version"]).decode("utf-8") - sln = out.splitlines()[0] - ver = sln.split()[2] - return ver - - except: - print("cmake not found!") - - class build_external(Command): description = "build external JIGSAW dependencies" @@ -114,22 +101,24 @@ def run(self): self.announce("cmake complie", level=3) - ver = get_cmake_version() - if version.parse(ver) < version.parse("3.12"): + try: compilecall = [ "cmake", "--build", ".", "--config", "Release", - "--target", "install" + "--target", "install", + "--parallel", "4" ] - else: + subprocess.run( + compilecall, check=True) + + except: compilecall = [ "cmake", "--build", ".", "--config", "Release", - "--target", "install", - "--parallel", "4" + "--target", "install" ] - - subprocess.run(compilecall, check=True) + subprocess.run( + compilecall, check=True) self.announce("cmake cleanup", level=3) From cf62b8646eedf7d0d6819236260907e4ab888350 Mon Sep 17 00:00:00 2001 From: dengwirda Date: Tue, 12 Aug 2025 02:06:26 +1000 Subject: [PATCH 05/14] Add load/save routines for projection obj. --- jigsawpy/loadprj.py | 58 ++++++++++++++++++++++++++ jigsawpy/saveprj.py | 99 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 157 insertions(+) create mode 100644 jigsawpy/loadprj.py create mode 100644 jigsawpy/saveprj.py diff --git a/jigsawpy/loadprj.py b/jigsawpy/loadprj.py new file mode 100644 index 0000000..a004b89 --- /dev/null +++ b/jigsawpy/loadprj.py @@ -0,0 +1,58 @@ + +from pathlib import Path +from jigsawpy.prj_t import jigsaw_prj_t + + +def loadprj(name, opts): + """ + LOADPRJ: load a PRJ config. obj. from file. + + LOADPRJ(NAME, OPTS) + + OPTS is a user-defined set of projection data. See PRJ_t + for details. + + Data in OPTS is loaded on-demand -- any objects included + in the file will be read. + + """ + + if (not isinstance(name, str)): + raise TypeError("Incorrect type: NAME.") + + if (not isinstance(opts, jigsaw_prj_t)): + raise TypeError("Incorrect type: OPTS.") + + with Path(name).open("r") as fptr: + while (True): + + #----------------------- get the next line from file + line = fptr.readline() + + if (len(line) != +0): + + #----------------------- parse next non-null section + line = line.strip() + if (line[0] == "#"): continue + + ltag = line.split("=") + item = ltag[0].upper().strip() + + #-------------------------------------- PROJ options + if (item == "PRJID"): + opts.prjID = ltag[1].strip() + + if (item == "RADII"): + opts.radii = float(ltag[1]) + + if (item == "X-MID"): + opts.xbase = float(ltag[1]) + + if (item == "Y-MID"): + opts.ybase = float(ltag[1]) + + else: + #----------------------- reached end-of-file: done!! + break + + return diff --git a/jigsawpy/saveprj.py b/jigsawpy/saveprj.py new file mode 100644 index 0000000..ada761f --- /dev/null +++ b/jigsawpy/saveprj.py @@ -0,0 +1,99 @@ + +from pathlib import Path +from jigsawpy.prj_t import jigsaw_prj_t + + +def savechar(fptr, sval, stag): + + if (isinstance(sval, str)): + fptr.write(" " + stag + "=" + sval + "\n") + else: + raise TypeError( + "Invalid [CHARA] data: OPTS." + stag) + + return + + +def saveints(fptr, ival, stag): + + if (isinstance(ival, int)): + fptr.write( + " " + stag + "=" + str(ival) + "\n") + else: + raise TypeError( + "Invalid [INDEX] data: OPTS." + stag) + + return + + +def savereal(fptr, fval, stag): + + if (isinstance(fval, float)): + fptr.write( + " " + stag + "=" + str(fval) + "\n") + else: + raise TypeError( + "Invalid [FLOAT] data: OPTS." + stag) + + return + + +def savebool(fptr, bval, stag): + + if (isinstance(bval, bool)): + if (bval is True): + fptr.write(" " + stag + "=TRUE \n") + else: + fptr.write(" " + stag + "=FALSE\n") + else: + raise TypeError( + "Invalid [BOOLS] data: OPTS." + stag) + + return + + +def saveprj(name, opts): + """ + SAVEPRJ: save a PRJ config. obj. to file. + + SAVEPRJ(NAME, OPTS) + + OPTS is a user-defined set of projection data. See PRJ_t + for details. + + Data in OPTS is written as-needed -- any objects defined + will be saved to file. + + """ + + if (not isinstance(name, str)): + raise TypeError("Incorrect type: NAME.") + + if (not isinstance(opts, jigsaw_prj_t)): + raise TypeError("Incorrect type: OPTS.") + + fext = Path(name).suffix + + if (fext.strip() != ".prj"): name = name + ".prj" + + with Path(name).open("w") as fptr: + + fptr.write( + "# " + Path(name).name + + " config. file;" + " created by JIGSAW's PYTHON interface \n") + + #------------------------------------------ MISC options + if (opts.prjID is not None): + savechar(fptr, opts.prjID, "PRJID") + + if (opts.radii is not None): + savereal(fptr, opts.radii, "RADII") + + if (opts.xbase is not None): + savereal(fptr, opts.xbase, "X-MID") + + if (opts.ybase is not None): + savereal(fptr, opts.ybase, "Y-MID") + + return From df1886f01a7ef13bb9d5136337c0db8a4bf122ec Mon Sep 17 00:00:00 2001 From: dengwirda Date: Tue, 12 Aug 2025 02:10:24 +1000 Subject: [PATCH 06/14] Simplify dependencies --- requirements.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index f1c7422..6bad103 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,2 @@ numpy scipy -packaging From 5a570519315135edfb69043f0120919bbbfbde59 Mon Sep 17 00:00:00 2001 From: dengwirda Date: Tue, 12 Aug 2025 02:51:07 +1000 Subject: [PATCH 07/14] Simplify README.md --- README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index bc667e6..c738055 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,9 @@

-`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. +`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 constructing new meshes, optimisation-driven techniques for improving existing grids, as well as routines to assemble (restricted) Delaunay tessellations, Voronoi complexes and Power diagrams. This package provides a `Python` based scripting interface to the underlying `JIGSAW` mesh generator, including a range of additional facilities for file I/O, mesh visualisation and post-processing operations. @@ -21,7 +23,7 @@ This package provides a `Python` based scrip python3 setup.py install python3 example.py --IDnumber=0 -Note: installation of `JIGSAW` requires a `c++` compiler and the `cmake` utility. `JIGSAW` may also be installed as a `conda` package. See here for details. +Note: installation of `JIGSAW` requires a `c++` compiler and the `cmake` utility. ### `Function Listing` @@ -75,7 +77,7 @@ This program may be freely redistributed under the condition that the copyright ### `References` -There are a number of publications that describe the algorithms used in `JIGSAW` in detail. If you make use of `JIGSAW` in your work, please consider including a reference to the following: +There are a number of publications that describe the algorithms used in `JIGSAW` in detail. If you make use of `JIGSAW` in your work, please include references as appropriate: `[1]` - Darren Engwirda: Generalised primal-dual grids for unstructured co-volume schemes, J. Comp. Phys., 375, pp. 155-176, https://doi.org/10.1016/j.jcp.2018.07.025, 2018. From 17b658e2d032769af7c9bc9ae85ddff98bd2e55d Mon Sep 17 00:00:00 2001 From: dengwirda Date: Tue, 12 Aug 2025 03:07:03 +1000 Subject: [PATCH 08/14] Squashed 'external/jigsaw/' changes from 595ff4b..a3afb93 a3afb93 Merge pull request #56 from dengwirda/dev-v1.1.0 125afa4 Update mesh optim. div/zip schedule 8db4b07 Add indexing hint for element-centred h(x) eval. 77f7a06 Update unit test config.'s eb99e86 Simplify README.md e29bcd7 Simplify README.md c2273db Update CI workflow 26120b1 Ensure R^d+1 weight is initialised 05e8951 Ensure rDT face counter is initialised dae33aa Force fast stdout for unit tests e9f8d67 Update API interface 47c877a Correct circumball array size 275d7db Update CI workflow 4c71306 Simplify README.md 36e4db6 Simplify README.md 4944f66 Update CI workflow ccb7894 Simplify README.md c048284 Squelch compiler warnings 00bb2f4 Simplify README.md e2eac64 Update CI workflow 5650f61 Add unit tests for MARCHE in E^3 1362b95 Remove discontinued conda build detail 14c170e Add min/max limits for dual mesh weight optim. d0f9f4c Add min/max limits for dual mesh weight optim. b5f81c7 Add min/max limits for dual mesh weight optim. 4c11b70 Adjust dual mesh weight optimisation 48593bd Update CI workflow 4047d6c Reduce error on -ve h(x) data to warning 930249c Squelch unused variables 304234f Fix spatially-variable initial point selection d563c1c Fix auto disambiguation of multiple types 22c1fdb Fix | vs || usage fa0cfef std:: functions are no longer constexpr 52306af 1.1.0 updates to documentation & examples 8614f9a 1.1.0 updates to mesh optim. strategies 1c95b5e 1.1.0 updates to rDT refinement schemes 74eddb5 Ensure constants are constexpr 2506397 Update geometry objects and utilities df5225a Update mesh complex objects 4e21aae Upgrade compiler + flags support dd7253c Fix buffer overflow in i/o routines bae0609 Update to v1.1.0 user-opt. defaults 7539007 Support for deferred refinement user-opts 2530527 WIP support for "in-ball" in E^4 3caddcd Add multi-prec. 6x6 determinant 3d191a3 Increase reserve alloc. for hashtable 98d0422 Fix rect-dist for nearest scheme 7b037a9 Add is-unique for general sequences 1a23384 Eikonal solve for mixed cell types in R^3 f99d8f4 Merge pull request #50 from dengwirda/dev d589b1b 1.0.0 updates: "spars(er)" refinement, thread-parallelism, etc 5c46d96 Merge pull request #48 from dengwirda/dev git-subtree-dir: external/jigsaw git-subtree-split: a3afb9397be1a3dc0b839ca289298321aa0114c7 --- .github/workflows/cmake.yml | 16 +- README.md | 89 +- example.jig | 32 + inc/jigsaw_jig_t.h | 52 +- inc/lib_jigsaw.h | 8 +- src/CMakeLists.txt | 17 +- src/geo_load.hpp | 7 + src/hfn_load.hpp | 116 +- src/hfn_save.inc | 27 +- src/ini_load.hpp | 10 + src/jig_load.hpp | 164 ++- src/jig_read.hpp | 37 +- src/jigsaw.cpp | 12 +- src/jigsaw.hpp | 13 +- src/libcpp/aabb_tree/aabb_tree_k.hpp | 22 +- src/libcpp/algorithms/find.hpp | 26 + src/libcpp/containers/hashtable.hpp | 21 +- src/libcpp/expansion/mp_float.hpp | 3 +- src/libcpp/expansion/mp_utils.hpp | 163 ++- src/libcpp/geom_base/cell_base_k.hpp | 18 +- src/libcpp/geom_base/intersect_k.hpp | 928 ++++++--------- src/libcpp/geom_reps/geom_base_2.hpp | 10 +- src/libcpp/geom_reps/geom_base_3.hpp | 10 +- .../geom_reps/geom_mesh_ellipsoid_3.hpp | 49 +- .../geom_reps/geom_mesh_euclidean_2.hpp | 51 +- .../geom_reps/geom_mesh_euclidean_3.hpp | 109 +- src/libcpp/interpolate/hfun_base_k.hpp | 19 +- src/libcpp/interpolate/hfun_clip_k.hpp | 626 ++++++++-- .../interpolate/hfun_constant_value_k.hpp | 9 + .../interpolate/hfun_grid_ellipsoid_3.hpp | 278 ++--- .../interpolate/hfun_grid_euclidean_2.hpp | 125 +- .../interpolate/hfun_grid_euclidean_3.hpp | 400 ++++++- .../interpolate/hfun_mesh_ellipsoid_3.hpp | 92 +- .../interpolate/hfun_mesh_euclidean_2.hpp | 95 +- .../interpolate/hfun_mesh_euclidean_3.hpp | 116 +- src/libcpp/iter_mesh/_zip_mesh_2.inc | 47 +- src/libcpp/iter_mesh/cost_mesh_2.inc | 68 +- src/libcpp/iter_mesh/iter_divs_2.inc | 47 +- src/libcpp/iter_mesh/iter_dual_2.inc | 17 +- src/libcpp/iter_mesh/iter_mesh_2.hpp | 158 +-- .../iter_mesh/iter_mesh_euclidean_2.hpp | 33 +- .../iter_mesh/iter_mesh_euclidean_3.hpp | 69 +- src/libcpp/iter_mesh/iter_node_2.inc | 183 ++- src/libcpp/iter_mesh/iter_zips_2.inc | 78 +- src/libcpp/iter_mesh/move_mesh_2.inc | 81 +- src/libcpp/mathutil.hpp | 2 +- src/libcpp/mesh_reps/base_complex_k.hpp | 161 +-- src/libcpp/parameters/iter_params.hpp | 30 +- src/libcpp/parameters/mesh_params.hpp | 36 +- src/libcpp/predicate/inball_k.hpp | 1048 ++++++++++++++++- src/libcpp/predicate/predicate_k.hpp | 111 +- src/libcpp/rdel_mesh/rdel_base_2.hpp | 4 +- src/libcpp/rdel_mesh/rdel_base_3.hpp | 8 +- src/libcpp/rdel_mesh/rdel_cost_delfront_3.inc | 6 +- src/libcpp/rdel_mesh/rdel_filt_k.hpp | 20 +- src/libcpp/rdel_mesh/rdel_make_2.hpp | 330 +++--- src/libcpp/rdel_mesh/rdel_make_3.hpp | 430 ++++--- src/libcpp/rdel_mesh/rdel_mesh_2.hpp | 486 ++++---- src/libcpp/rdel_mesh/rdel_mesh_3.hpp | 663 ++++++----- src/libcpp/rdel_mesh/rdel_offh_delfront_2.inc | 4 +- src/libcpp/rdel_mesh/rdel_offh_delfront_3.inc | 6 +- src/libcpp/rdel_mesh/rdel_pred_delfront_2.hpp | 42 +- src/libcpp/rdel_mesh/rdel_pred_delfront_3.hpp | 87 +- src/libcpp/rdel_mesh/rdel_refine_ball_2.inc | 91 +- src/libcpp/rdel_mesh/rdel_refine_base_2.inc | 54 +- src/libcpp/rdel_mesh/rdel_refine_base_3.inc | 54 +- src/libcpp/rdel_mesh/rdel_refine_face_2.inc | 12 +- src/libcpp/rdel_mesh/rdel_refine_face_3.inc | 18 +- src/libcpp/rdel_mesh/rdel_refine_topo_2.inc | 2 +- src/libcpp/rdel_mesh/rdel_refine_topo_3.inc | 6 +- src/libcpp/rdel_mesh/rdel_test_bounds_2.inc | 5 +- src/libcpp/rdel_mesh/rdel_test_bounds_3.inc | 7 +- src/libcpp/rdel_mesh/rdel_timers.hpp | 16 +- src/libcpp/rdel_mesh/rdel_update_face_2.inc | 210 ++-- src/libcpp/rdel_mesh/rdel_update_face_3.inc | 302 ++--- src/libcpp/rdel_mesh/rdel_update_topo_2.inc | 10 +- src/libcpp/tessellate/delaunay_tri_k.hpp | 66 ++ src/liblib/init_jig_t.hpp | 23 +- src/liblib/load_jig_t.hpp | 32 +- src/liblib/save_jig_t.hpp | 15 +- src/marche.hpp | 13 +- src/msh_save.inc | 23 +- src/rdt_save.inc | 23 +- src/tri_save.inc | 16 +- src/tripod.hpp | 13 +- uni/CMakeLists.txt | 10 + uni/test2d_a.c | 2 + uni/test2d_b.c | 2 + uni/test2d_c.c | 2 + uni/test2d_d.c | 2 + uni/test2d_e.c | 2 + uni/test2d_f.c | 2 + uni/test2d_g.c | 2 + uni/test2d_h.c | 2 + uni/test2d_i.c | 2 + uni/test2s_a.c | 2 + uni/test2s_b.c | 2 + uni/test2s_c.c | 2 + uni/test2s_e.c | 2 + uni/test2s_f.c | 2 + uni/test2s_g.c | 2 + uni/test2s_h.c | 2 + uni/test2s_i.c | 2 + uni/test3d_a.c | 2 + uni/test3d_b.c | 2 + uni/test3d_c.c | 2 + uni/test3d_d.c | 34 +- uni/test3d_e.c | 2 + uni/test3d_f.c | 2 + uni/test3d_g.c | 2 + uni/test3d_h.c | 109 ++ uni/test3d_i.c | 116 ++ uni/test_all.c | 12 +- version.txt | 8 + 114 files changed, 6048 insertions(+), 3323 deletions(-) create mode 100644 uni/test3d_h.c create mode 100644 uni/test3d_i.c diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index 92293f1..3548fdc 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -88,19 +88,14 @@ jobs: run: | cd ${{github.workspace}}/uni/build cmake --build . --config ${{env.BUILD_TYPE}} --target install - + - name: Prep. tests for jigsaw if: startsWith(matrix.config.os, 'windows') run: | cd ${{github.workspace}}/uni cp ../lib/jigsaw.dll . - - name: Eval. tests for jigsaw - run: | - cd ${{github.workspace}}/uni - ./test_all - - - name: Extra tests for jigsaw + - name: Tests for cmd-jigsaw run: | cd ${{github.workspace}} ./bin/jigsaw example.jig @@ -109,6 +104,11 @@ jobs: ./bin/jigsaw geo/parts.jig ./bin/jigsaw geo/earth.jig ./bin/jigsaw geo/lakes.jig - + + - name: Tests for lib-jigsaw + run: | + cd ${{github.workspace}}/uni + ./test_all + - name: Clean tests for jigsaw run: rm -r ${{github.workspace}}/uni/build diff --git a/README.md b/README.md index a59cf25..ab17904 100644 --- a/README.md +++ b/README.md @@ -7,15 +7,17 @@

-`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. +`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. -This package provides the underlying `c++` source for `JIGSAW`; defining a basic command-line interface and a `c`-format `API`. Higher-level scripting interfaces, supporting a range of additional facilities for file I/O, mesh visualisation and post-processing operations are also available, including for `MATLAB` / `OCTAVE` here and for `PYTHON` here. +`JIGSAW` includes refinement-based algorithms for constructing new meshes, optimisation-driven techniques for improving existing grids, as well as routines to assemble (restricted) Delaunay tessellations, Voronoi complexes and Power diagrams. -`JIGSAW` is compiled and tested on various `64-bit` `Linux`, `Windows` and `MacOS` platforms using the `g++`, `clang++` and `msvc` compilers. +This package provides the underlying `c++` source for `JIGSAW`; defining a basic command-line interface and a `c`-format `API`. Higher-level scripting interfaces, supporting additional facilities for file I/O, mesh visualisation and post-processing operations are also available, including for `MATLAB` / `OCTAVE` here and for `PYTHON` here. + +`JIGSAW` has been compiled and tested on various `64-bit` `Linux`, `Windows` and `MacOS` platforms using `>=c++17` versions of the `g++`, `clang++` and `msvc` compilers. ### `Code Structure` -`JIGSAW` is written as a `header-only` library in `c++`. Both a basic command-line interface and a `c`-format `API` are defined: +`JIGSAW` is a header-only `c++` library. Both a basic command-line interface and a `c`-format `API` are defined: JIGSAW:: ├── src -- JIGSAW src code @@ -28,59 +30,26 @@ This package provides the underlying `c++` source for `JIGSAW`; defining a basic ### `Getting Started` -The first step is to compile and configure the code! `JIGSAW` can either be built directly from src, or installed using the `conda` package manager. - -### `Building from src` - -The full `JIGSAW` src can be found in `../jigsaw/src/`. It has been built using various `c++17` conforming versions of the `g++`, `clang++` and `msvc` compilers. - -`JIGSAW` is a `header-only` package - the single main `jigsaw.cpp` file simply `#include`'s the rest of the library directly. `JIGSAW` does not currently dependent on any external packages or libraries. - -`JIGSAW` consists of several pieces: `(a)` a set of command-line utilities that read and write mesh data from/to file, and `(b)` a shared library, accessible via a `c`-format `API`. - -### `Using cmake` - -`JIGSAW` can be built using the `cmake` utility. To build, follow the steps below: - - * Clone or download this repository. - * Navigate to the root `../jigsaw/` directory. - * Make a new temporary directory BUILD. - * cd build - * cmake .. -DCMAKE_BUILD_TYPE=BUILD_MODE - * cmake --build . --config BUILD_MODE --target install EXTRAS - * Delete the temporary BUILD directory. +`JIGSAW` can be built using the `cmake` utility: -This process will build a series of executables and shared libraries: `jigsaw` itself - the main command-line meshing utility, `tripod` - `JIGSAW`'s tessellation infrastructure, `marche` - a fast-marching solver designed to optimise mesh-spacing configurations, as well as `libjigsaw` - `JIGSAW`'s shared `API`. + Navigate to the root ../jigsaw/ directory. + mkdir build && cd build + cmake .. -DCMAKE_BUILD_TYPE=BUILD_MODE + cmake --build . --config BUILD_MODE --target install EXTRAS + +A set of executables and shared libraries is built: `jigsaw` itself - the main command-line meshing utility, `tripod` - `JIGSAW`'s tessellation infrastructure, `marche` - a fast-marching solver designed to optimise mesh-spacing configurations, as well as `libjigsaw` - `JIGSAW`'s shared `API`. -`BUILD_MODE` can be used to select different compiler configurations and should generally either be `Release` or `Debug`. `EXTRAS` can be used to pass additional compile-time arguments, for example `-- -j 4` will build in parallel on supported architectures. +`BUILD_MODE` can be used to select different compiler configurations (either `Release` or `Debug`). `EXTRAS` can be used to pass additional compile-time arguments, for example `-- -j4` will build in parallel on supported architectures. -See `example.jig` for documentation on calling the command-line executables, and the headers in `../jigsaw/inc/` for details on the `API`. +See `example.jig` for documentation, as well as the headers in `../jigsaw/inc/` for details on the `API`. -### `Using conda` +### `cmd-line Examples` -`JIGSAW` is also available as a `conda` environment. To install and use, follow the steps below: +After compiling the code, try running the following command-line example: - * Ensure you have conda installed. If not, consider miniconda as a lightweight option. - * Add conda-forge as a channel: conda config --add channels conda-forge - * Create a jigsaw environment: conda create -n jigsaw jigsaw + /bin/jigsaw{.exe} example.jig -Each time you want to use `JIGSAW` simply activate the environment using: `conda activate jigsaw` - -Once activated, the various `JIGSAW` command-line utilities will be available in your run path, `JIGSAW`'s shared library (`libjigsaw`) will be available in your library path and its include files in your include path. - -### `CMD-line Examples` - -After compiling the code, try running the following command-line example to get started: -```` -On WIN platforms: - -\bin\jigsaw.exe example.jig - -On LNX platforms: - -/bin/jigsaw example.jig -```` -In this example, a high-quality tetrahedral mesh is generated for the 'stanford-bunny' geometry and the result written to file. The input geometry is specified as a triangulated surface, and is read from `../jigsaw/geo/bunny.msh`. The volume and surface mesh outputs are written to `../jigsaw/out/bunny.msh`. See the `example.jig` text-file for a description of `JIGSAW`'s configuration options. +In this example, a high-quality tetrahedral mesh is generated for the `stanford-bunny` geometry. The input geometry is specified as a triangulated surface, and is read from `../jigsaw/geo/bunny.msh`. The volume and surface mesh outputs are written to `../jigsaw/out/bunny.msh`. See the `example.jig` text-file for a description of `JIGSAW`'s configuration options. A repository of additional surface models generated using `JIGSAW` can be found here. A description of the `*.jig` and `*.msh` input file formats can be found in the wiki. @@ -88,20 +57,18 @@ A repository of additional surface models generated using `JIGSAW` can be found A set of unit-tests and `libjigsaw` example programs are contained in `../jigsaw/uni/`. The `JIGSAW-API` is documented via the header files in `../jigsaw/inc/`. -The unit-tests can be built using the `cmake` utility. To build, follow the steps below: - - * Navigate to the `../jigsaw/uni/` directory. - * Make a new temporary directory BUILD. - * cd build - * cmake .. -DCMAKE_BUILD_TYPE=BUILD_MODE - * cmake --build . --config BUILD_MODE --target install EXTRAS - * Delete the temporary BUILD directory. +The unit-tests can be built using the `cmake` utility: -This process will build the unit-tests as a series of executables in `../jigsaw/uni/`. `BUILD_MODE` is a compiler configuration flag: either `Release` or `Debug`. `EXTRAS` can be used to pass additional compile-time arguments. + Navigate to the ../jigsaw/uni/ directory. + mkdir build && cd build + cmake .. -DCMAKE_BUILD_TYPE=BUILD_MODE + cmake --build . --config BUILD_MODE --target install EXTRAS + +This process will build the unit-tests as a set of executables in `../jigsaw/uni/`. `BUILD_MODE` is a compiler configuration flag (either `Release` or `Debug`). `EXTRAS` can be used to pass additional compile-time arguments. ### `Contributors` -1. [@dengwirda](https://github.com/dengwirda) is `JIGSAW`'s developer and maintainer --- this work was originally the focus of my PhD at the University of Sydney. +1. [@dengwirda](https://github.com/dengwirda) is `JIGSAW`'s developer and maintainer. 2. [@xylar](https://github.com/xylar) contributed the `cmake` build system and `conda` environment. 3. [@tunnellm](https://github.com/tunnellm) extended the sequential optimisation algorithms to support thread-parallelism. @@ -120,7 +87,7 @@ This program may be freely redistributed under the condition that the copyright ### `References` -There are a number of publications that describe the algorithms used in `JIGSAW` in detail. If you make use of `JIGSAW` in your work, please consider including a reference to the following: +There are a number of publications that describe the algorithms used in `JIGSAW` in detail. If you make use of `JIGSAW` in your work, please include references as appropriate: `[1]` - Darren Engwirda: Generalised primal-dual grids for unstructured co-volume schemes, J. Comp. Phys., 375, pp. 155-176, https://doi.org/10.1016/j.jcp.2018.07.025, 2018. diff --git a/example.jig b/example.jig index 2507603..ddcddd2 100644 --- a/example.jig +++ b/example.jig @@ -184,6 +184,24 @@ # MESH_ITER = 10000 +# ---> MESH_ORPH - {default=true} allow "orphaned" facets +# to remain in the mesh. A K-1 dimensional subcell is +# orphaned if it does not appear in any K-dimensional +# cell, e.g. a surface triangle that is not the face +# of any interior tetrahedron. + +# MESH_ORPH = FALSE + + +# ---> MESH_LOCK - {default=false} prevent the refinement +# of subfaces during subsequent refinement. The +# refinement of a K-dimensional cell is deferred if +# doing so would cause any K-1 dimensional subfaces to +# be refined. + +# MESH_LOCK = TRUE + + # ---> MESH_TOP1 - {default=false} enforce 1-dim. topolog- # ical constraints. 1-dim. edges are refined until all # embedded nodes are "locally 1-manifold", i.e. nodes @@ -369,6 +387,20 @@ # OPTM_QLIM = 0.90 +# ---> OPTM_WMIN - {default=-7./8.} lower limit on dual +# mesh weights relative to cell radius. +# + +# OPTM_WMIN =-0.500 + + +# ---> OPTM_WMAX - {default=+1./80} upper limit on dual +# mesh weights relative to cell radius. +# + +# OPTM_WMAX = 0.125 + + # ---> OPTM_ZIP_ - {default= true} allow for "merge" oper- # ations on sub-faces. # diff --git a/inc/jigsaw_jig_t.h b/inc/jigsaw_jig_t.h index 4efce4f..076e50b 100644 --- a/inc/jigsaw_jig_t.h +++ b/inc/jigsaw_jig_t.h @@ -35,9 +35,9 @@ * -------------------------------------------------------- * - * Last updated: 12 Dec., 2022 + * Last updated: 27 Jul., 2025 * - * Copyright 2013-2022 + * Copyright 2013-2025 * Darren Engwirda * d.engwirda@gmail.com * https://github.com/dengwirda @@ -209,6 +209,30 @@ indx_t _mesh_iter ; + /* + -------------------------------------------------------- + * MESH_ORPH - {default=true} allow "orphaned" facets + * to remain in the mesh. A K-1 dimensional subcell is + * orphaned if it does not appear in any K-dimensional + * cell, e.g. a surface triangle that is not the face + * of any interior tetrahedron. + -------------------------------------------------------- + */ + + indx_t _mesh_orph ; + + /* + -------------------------------------------------------- + * MESH_LOCK - {default=false} prevent the refinement + * of subfaces during subsequent refinement. The + * refinement of a K-dimensional cell is deferred if + * doing so would cause any K-1 dimensional subfaces to + * be refined. + -------------------------------------------------------- + */ + + indx_t _mesh_lock ; + /* -------------------------------------------------------- * MESH_TOP1 - {default=false} enforce 1-dim. topolog- @@ -339,7 +363,7 @@ /* -------------------------------------------------------- - * MESH_EPS1 - {default=0.33} max. surface-discretisa- + * MESH_EPS1 - {default=5/12} max. surface-discretisa- * tion error multiplier for 1-edge elements. 1-edge * elements are refined until the surface-disc. error * is less-than EPS1 * HFUN(X). @@ -350,7 +374,7 @@ /* -------------------------------------------------------- - * MESH_EPS2 - {default=0.33} max. surface-discretisa- + * MESH_EPS2 - {default=5/12} max. surface-discretisa- * tion error multiplier for 2-tria elements. 2-tria * elements are refined until the surface-disc. error * is less-than EPS2 * HFUN(X). @@ -447,7 +471,7 @@ /* -------------------------------------------------------- - * OPTM_QLIM - {default=0.9333} threshold on mesh cost + * OPTM_QLIM - {default=.91667} threshold on mesh cost * function above which gradient-based optimisation is * attempted. -------------------------------------------------------- @@ -455,6 +479,24 @@ real_t _optm_qlim ; + /* + -------------------------------------------------------- + * OPTM_WMIN - {default=-7./8.} lower limit on dual + * mesh weights relative to cell radius. + -------------------------------------------------------- + */ + + real_t _optm_wmin ; + + /* + -------------------------------------------------------- + * OPTM_WMAX - {default=+1./80} upper limit on dual + * mesh weights relative to cell radius. + -------------------------------------------------------- + */ + + real_t _optm_wmax ; + /* -------------------------------------------------------- * OPTM_TRIA - {default= true} allow for optimisation diff --git a/inc/lib_jigsaw.h b/inc/lib_jigsaw.h index 2491e2f..e010e3b 100644 --- a/inc/lib_jigsaw.h +++ b/inc/lib_jigsaw.h @@ -14,9 +14,11 @@ * JIGSAW: Interface to the JIGSAW meshing library. -------------------------------------------------------- * - * Last updated: 08 Feb., 2021 + * JIGSAW release 1.1.0.x * - * Copyright 2013-2021 + * Last updated: 20 Oct., 2024 + * + * Copyright 2013-2024 * Darren Engwirda * d.engwirda@gmail.com * https://github.com/dengwirda @@ -64,7 +66,7 @@ extern "C" { # endif -# ifdef _WIN32 +# if defined(_WIN32) || defined(_WIN64) # ifdef __lib_jigsaw # define SHARED __declspec(dllexport) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 80208f3..16922f2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,4 +1,5 @@ function (cfg_compile_options OPT CFG) + # set OPT if compiling with CFG add_compile_options ("$<$:${OPT}>") endfunction () @@ -27,9 +28,10 @@ endif () if (DEFINED ICPC_LIKE) add_compile_options (-pedantic -Wall -Wextra -Wshadow -Wfloat-conversion) add_compile_options (-fp-model=precise) # needed for adapt-fp - add_compile_options (-fno-math-errno) # no errno checks - add_compile_options (-fno-trapping-math) # no fp exceptions - add_compile_options (-ffinite-math-only) # no explicit nans, etc + cfg_compile_options (-fno-math-errno RELEASE) # no errno checks + cfg_compile_options (-fno-trapping-math RELEASE) # no fp exceptions + cfg_compile_options (-fno-signed-zeros RELEASE) # -0.0 == +0.0 + cfg_compile_options (-ffinite-math-only RELEASE) # no explicit nans, etc endif () if (DEFINED MSVC_LIKE) @@ -37,14 +39,15 @@ if (DEFINED MSVC_LIKE) add_compile_options (/openmp:llvm) # needed for openmp > 2.0 add_compile_options (/fp:precise) # needed for adapt-fp cfg_compile_options (/GS- RELEASE) # disable buffer checks - cfg_compile_options (/Ot RELEASE) # favour "fast" code + cfg_compile_options (/Ot RELEASE) # favour "fast" code endif () if (DEFINED GCXX_LIKE) add_compile_options (-pedantic -Wall -Wextra -Wshadow -Wfloat-conversion) - add_compile_options (-fno-math-errno) # no errno checks - add_compile_options (-fno-trapping-math) # no fp exceptions - add_compile_options (-ffinite-math-only) # no explicit nans, etc + cfg_compile_options (-fno-math-errno RELEASE) # no errno checks + cfg_compile_options (-fno-trapping-math RELEASE) # no fp exceptions + cfg_compile_options (-fno-signed-zeros RELEASE) # -0.0 == +0.0 + cfg_compile_options (-ffinite-math-only RELEASE) # no explicit nans, etc endif () if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) diff --git a/src/geo_load.hpp b/src/geo_load.hpp index 3adba32..9e34aaa 100644 --- a/src/geo_load.hpp +++ b/src/geo_load.hpp @@ -1132,7 +1132,14 @@ return _errv ; } } + else + { + _jlog. push ( + "**input error: couldn't determine format of GEOM.\n") ; + return __invalid_argument ; + } + return ( _errv ) ; } diff --git a/src/hfn_load.hpp b/src/hfn_load.hpp index 78c543f..9bb4388 100644 --- a/src/hfn_load.hpp +++ b/src/hfn_load.hpp @@ -35,9 +35,9 @@ * -------------------------------------------------------- * - * Last updated: 28 Mar., 2022 + * Last updated: 27 Feb., 2025 * - * Copyright 2013-2022 + * Copyright 2013-2025 * Darren Engwirda * d.engwirda@gmail.com * https://github.com/dengwirda/ @@ -1141,6 +1141,7 @@ iptr_type _imax = std::numeric_limits::min() ; + fp32_type _zero = +0.; iptr_type _nmax = +0 ; for (auto _iter = _hfun. @@ -1150,6 +1151,8 @@ ++_iter ) { _hmin = std::min(_hmin, *_iter) ; + if (_nneg) + *_iter = std::max(_zero, *_iter) ; } for (auto _iter = _hfun. @@ -1159,6 +1162,8 @@ ++_iter ) { _smin = std::min(_smin, *_iter) ; + if (_nneg) + *_iter = std::max(_zero, *_iter) ; } for (auto _iter = _hfun. @@ -1214,17 +1219,21 @@ if (_hmin < (fp32_type)+0. && _nneg) { _jlog.push ( - "**input error: HFUN. values must be non-negative.\n") ; + "**input warn.: HFUN. values must be non-negative.\n") ; + _jlog.push ( + "**input warn.: HFUN. values clipped to zero.\n") ; - _errv = __invalid_argument ; + // _errv = __invalid_argument ; } if (_smin < (fp32_type)+0. && _nneg) { _jlog.push ( - "**input error: DHDX. values must be non-negative.\n") ; + "**input warn.: DHDX. values must be non-negative.\n") ; + _jlog.push ( + "**input warn.: DHDX. values clipped to zero.\n") ; - _errv = __invalid_argument ; + // _errv = __invalid_argument ; } if (_imin < +0 || _imax>=_nmax) @@ -1246,6 +1255,8 @@ fp32_type _smin = std::numeric_limits::infinity(); + fp32_type _zero = +0.; + for (auto _iter = _hfun. _euclidean_grid_2d._hmat.head(); _iter != _hfun. @@ -1253,6 +1264,8 @@ ++_iter ) { _hmin = std::min(_hmin, *_iter) ; + if (_nneg) + *_iter = std::max(_zero, *_iter) ; } for (auto _iter = _hfun. @@ -1262,6 +1275,8 @@ ++_iter ) { _smin = std::min(_smin, *_iter) ; + if (_nneg) + *_iter = std::max(_zero, *_iter) ; } bool_type _mono = true; @@ -1325,17 +1340,21 @@ if (_hmin < (fp32_type)+0. && _nneg) { _jlog.push ( - "**input error: HFUN. values must be non-negative.\n") ; + "**input warn.: HFUN. values must be non-negative.\n") ; + _jlog.push ( + "**input warn.: HFUN. values clipped to zero.\n") ; - _errv = __invalid_argument ; + // _errv = __invalid_argument ; } if (_smin < (fp32_type)+0. && _nneg) { _jlog.push ( - "**input error: DHDX. values must be non-negative.\n") ; + "**input warn.: DHDX. values must be non-negative.\n") ; + _jlog.push ( + "**input warn.: DHDX. values clipped to zero.\n") ; - _errv = __invalid_argument ; + // _errv = __invalid_argument ; } if (!_mono) @@ -1362,6 +1381,7 @@ iptr_type _imax = std::numeric_limits::min() ; + fp32_type _zero = +0.; iptr_type _nmax = +0 ; for (auto _iter = _hfun. @@ -1371,6 +1391,8 @@ ++_iter ) { _hmin = std::min(_hmin, *_iter) ; + if (_nneg) + *_iter = std::max(_zero, *_iter) ; } for (auto _iter = _hfun. @@ -1380,6 +1402,8 @@ ++_iter ) { _smin = std::min(_smin, *_iter) ; + if (_nneg) + *_iter = std::max(_zero, *_iter) ; } for (auto _iter = _hfun. @@ -1439,17 +1463,21 @@ if (_hmin < (fp32_type)+0. && _nneg) { _jlog.push ( - "**input error: HFUN. values must be non-negative.\n") ; + "**input warn.: HFUN. values must be non-negative.\n") ; + _jlog.push ( + "**input warn.: HFUN. values clipped to zero.\n") ; - _errv = __invalid_argument ; + // _errv = __invalid_argument ; } if (_smin < (fp32_type)+0. && _nneg) { _jlog.push ( - "**input error: DHDX. values must be non-negative.\n") ; + "**input warn.: DHDX. values must be non-negative.\n") ; + _jlog.push ( + "**input warn.: DHDX. values clipped to zero.\n") ; - _errv = __invalid_argument ; + // _errv = __invalid_argument ; } if (_imin < +0 || _imax>=_nmax) @@ -1471,6 +1499,8 @@ fp32_type _smin = std::numeric_limits::infinity(); + fp32_type _zero = +0.; + for (auto _iter = _hfun. _euclidean_grid_3d._hmat.head(); _iter != _hfun. @@ -1478,6 +1508,8 @@ ++_iter ) { _hmin = std::min(_hmin, *_iter) ; + if (_nneg) + *_iter = std::max(_zero, *_iter) ; } for (auto _iter = _hfun. @@ -1487,6 +1519,8 @@ ++_iter ) { _smin = std::min(_smin, *_iter) ; + if (_nneg) + *_iter = std::max(_zero, *_iter) ; } bool_type _mono = true; @@ -1566,17 +1600,21 @@ if (_hmin < (fp32_type)+0. && _nneg) { _jlog.push ( - "**input error: HFUN. values must be non-negative.\n") ; + "**input warn.: HFUN. values must be non-negative.\n") ; + _jlog.push ( + "**input warn.: HFUN. values clipped to zero.\n") ; - _errv = __invalid_argument ; + // _errv = __invalid_argument ; } if (_smin < (fp32_type)+0. && _nneg) { _jlog.push ( - "**input error: DHDX. values must be non-negative.\n") ; + "**input warn.: DHDX. values must be non-negative.\n") ; + _jlog.push ( + "**input warn.: DHDX. values clipped to zero.\n") ; - _errv = __invalid_argument ; + // _errv = __invalid_argument ; } if (!_mono) @@ -1637,6 +1675,7 @@ iptr_type _imax = std::numeric_limits::min() ; + fp32_type _zero = +0.; iptr_type _nmax = +0 ; for (auto _iter = _hfun. @@ -1646,6 +1685,8 @@ ++_iter ) { _hmin = std::min(_hmin, *_iter) ; + if (_nneg) + *_iter = std::max(_zero, *_iter) ; } for (auto _iter = _hfun. @@ -1655,6 +1696,8 @@ ++_iter ) { _smin = std::min(_smin, *_iter) ; + if (_nneg) + *_iter = std::max(_zero, *_iter) ; } for (auto _iter = _hfun. @@ -1738,17 +1781,21 @@ if (_hmin < (fp32_type)+0. && _nneg) { _jlog.push ( - "**input error: HFUN. values must be non-negative.\n") ; + "**input warn.: HFUN. values must be non-negative.\n") ; + _jlog.push ( + "**input warn.: HFUN. values clipped to zero.\n") ; - _errv = __invalid_argument ; + // _errv = __invalid_argument ; } if (_smin < (fp32_type)+0. && _nneg) { _jlog.push ( - "**input error: DHDX. values must be non-negative.\n") ; + "**input warn.: DHDX. values must be non-negative.\n") ; + _jlog.push ( + "**input warn.: DHDX. values clipped to zero.\n") ; - _errv = __invalid_argument ; + // _errv = __invalid_argument ; } if (_imin < +0 || _imax>=_nmax) @@ -1803,6 +1850,8 @@ real_type _ymin = _YMAX; real_type _ymax = _YMIN; + fp32_type _zero = +0.; + for (auto _iter = _hfun. _ellipsoid_grid_3d._hmat.head(); _iter != _hfun. @@ -1810,6 +1859,8 @@ ++_iter ) { _hmin = std::min(_hmin, *_iter) ; + if (_nneg) + *_iter = std::max(_zero, *_iter) ; } for (auto _iter = _hfun. @@ -1819,6 +1870,8 @@ ++_iter ) { _smin = std::min(_smin, *_iter) ; + if (_nneg) + *_iter = std::max(_zero, *_iter) ; } bool_type _mono = true; @@ -1910,17 +1963,21 @@ if (_hmin < (fp32_type)+0. && _nneg) { _jlog.push ( - "**input error: HFUN. values must be non-negative.\n") ; + "**input warn.: HFUN. values must be non-negative.\n") ; + _jlog.push ( + "**input warn.: HFUN. values clipped to zero.\n") ; - _errv = __invalid_argument ; + // _errv = __invalid_argument ; } if (_smin < (fp32_type)+0. && _nneg) { _jlog.push ( - "**input error: DHDX. values must be non-negative.\n") ; + "**input warn.: DHDX. values must be non-negative.\n") ; + _jlog.push ( + "**input warn.: DHDX. values clipped to zero.\n") ; - _errv = __invalid_argument ; + // _errv = __invalid_argument ; } if (!_mono) @@ -1931,6 +1988,13 @@ _errv = __invalid_argument ; } } + else + { + _jlog. push ( + "**input error: couldn't determine format of HFUN.\n") ; + + return __invalid_argument ; + } return ( _errv ) ; } diff --git a/src/hfn_save.inc b/src/hfn_save.inc index 678d7ed..78d4cae 100644 --- a/src/hfn_save.inc +++ b/src/hfn_save.inc @@ -35,9 +35,9 @@ * -------------------------------------------------------- * - * Last updated: 30 May, 2022 + * Last updated: 05 Dec, 2024 * - * Copyright 2013-2022 + * Copyright 2013-2024 * Darren Engwirda * d.engwirda@gmail.com * https://github.com/dengwirda/ @@ -80,7 +80,7 @@ { /*--------------------- (apparently) faster to unroll */ PRINTCHARS(snprintf(&_fbuf[_next] , - PRINTCHUNK, + PRINTCHUNK-_next, "%.9g\n%.9g\n%.9g\n%.9g\n" , *(_iter + 0) + _xoff, *(_iter + 1) + _xoff, @@ -93,9 +93,9 @@ _iter < _last; _iter += +1 ) { - /*--------------------- (apparently) faster to unroll */ + /*--------------------- trailing non-mod(4) remainder */ PRINTCHARS(snprintf(&_fbuf[_next] , - PRINTCHUNK, "%.9g\n", + PRINTCHUNK-_next, "%.9g\n", *(_iter + 0) + _xoff) , VALUECHUNK) } @@ -119,7 +119,8 @@ if (_iter->mark() >= 0 ) \ { \ PRINTCHARS(snprintf(&_fbuf[_next] , \ - PRINTCHUNK, "%.17g;%.17g;+0\n", \ + PRINTCHUNK- _next , \ + "%.17g;%.17g;+0\n", \ _iter->pval(0) + _xoff[0] , \ _iter->pval(1) + _xoff[1]), \ VERT2CHUNK) \ @@ -142,7 +143,8 @@ if (_iter->mark() >= 0 ) \ { \ PRINTCHARS(snprintf(&_fbuf[_next] , \ - PRINTCHUNK,"%.17g;%.17g;%.17g;+0\n", \ + PRINTCHUNK- _next , \ + "%.17g;%.17g;%.17g;+0\n", \ _iter->pval(0) + _xoff[0] , \ _iter->pval(1) + _xoff[1] , \ _iter->pval(2) + _xoff[2]), \ @@ -174,7 +176,8 @@ toS2( _ppos, _apos ); \ \ PRINTCHARS(snprintf(&_fbuf[_next] , \ - PRINTCHUNK ,"%.17g;%.17g;+0\n" , \ + PRINTCHUNK- _next , \ + "%.17g;%.17g;+0\n", \ _apos[ 0], _apos[ 1]) , VERT2CHUNK) \ } \ } \ @@ -195,7 +198,8 @@ _iter->self() >= 1 ) \ { \ PRINTCHARS(snprintf(&_fbuf[_next] , \ - PRINTCHUNK, "%u;%u;%u;+0\n" , \ + PRINTCHUNK- _next , \ + "%u;%u;%u;+0\n", \ _iter->node(0) , \ _iter->node(1) , \ _iter->node(2) ), TRIA3CHUNK) \ @@ -218,7 +222,8 @@ _iter->self() >= 1 ) \ { \ PRINTCHARS(snprintf(&_fbuf[_next] , \ - PRINTCHUNK, "%u;%u;%u;%u;+0\n" , \ + PRINTCHUNK- _next , \ + "%u;%u;%u;%u;+0\n", \ _iter->node(0) , \ _iter->node(1) , \ _iter->node(2) , \ @@ -362,7 +367,7 @@ if (_nnum > +0) { /*-------------------------- write POINT data */ - save_vert2( + save_vert3( _ffun._euclidean_mesh_3d._mesh); } diff --git a/src/ini_load.hpp b/src/ini_load.hpp index 0cb3f2b..4145a8b 100644 --- a/src/ini_load.hpp +++ b/src/ini_load.hpp @@ -469,6 +469,9 @@ { save_point () ; // lon-lat to R^3 save_power () ; // match to point + + this-> // pts now in R^3 + _init->_kind = jmsh_kind::euclidean_mesh ; } } ; @@ -1158,6 +1161,13 @@ _errv = __invalid_indexing ; } } + else + { + _jlog. push ( + "**input error: couldn't determine format of INIT.\n") ; + + return __invalid_argument ; + } return ( _errv ) ; } diff --git a/src/jig_load.hpp b/src/jig_load.hpp index bd63937..406e0f0 100644 --- a/src/jig_load.hpp +++ b/src/jig_load.hpp @@ -35,9 +35,9 @@ * -------------------------------------------------------- * - * Last updated: 12 Dec., 2022 + * Last updated: 27 Jul., 2025 * - * Copyright 2013-2022 + * Copyright 2013-2025 * Darren Engwirda * d.engwirda@gmail.com * https://github.com/dengwirda/ @@ -85,9 +85,9 @@ { this->_jjig->_verbosity = _verb ; this->_jjig-> - _mesh_opts.verb() = _verb; + _mesh_opts.verb() = _verb; this->_jjig-> - _iter_opts.verb() = _verb; + _iter_opts.verb() = _verb; } __normal_call void_type push_numthread ( std::int32_t _nprt @@ -102,9 +102,9 @@ this->_jjig->_numthread = _nprt ; this->_jjig-> - _mesh_opts.nprt() = _nprt; + _mesh_opts.nprt() = _nprt; this->_jjig-> - _iter_opts.nprt() = _nprt; + _iter_opts.nprt() = _nprt; } /*------------------------------------- GEOM keywords */ @@ -112,50 +112,49 @@ std::string _file ) { - this-> - _jjig->_geom_file = _file; + this->_jjig->_geom_file = _file; } __normal_call void_type push_geom_seed ( std::int32_t _seed ) { this->_jjig-> - _mesh_opts.seed() = _seed; + _mesh_opts.seed() = _seed; } __normal_call void_type push_geom_feat ( bool _feat ) { this->_jjig-> - _mesh_opts.feat() = _feat; + _mesh_opts.feat() = _feat; } __normal_call void_type push_geom_phi1 ( double _phi1 ) { this->_jjig-> - _mesh_opts.phi1() = _phi1; + _mesh_opts.phi1() = _phi1; } __normal_call void_type push_geom_phi2 ( double _phi2 ) { this->_jjig-> - _mesh_opts.phi2() = _phi2; + _mesh_opts.phi2() = _phi2; } __normal_call void_type push_geom_eta1 ( double _eta1 ) { this->_jjig-> - _mesh_opts.eta1() = _eta1; + _mesh_opts.eta1() = _eta1; } __normal_call void_type push_geom_eta2 ( double _eta2 ) { this->_jjig-> - _mesh_opts.eta2() = _eta2; + _mesh_opts.eta2() = _eta2; } /*------------------------------------- INIT keywords */ @@ -164,7 +163,7 @@ ) { this->_jjig-> - _mesh_opts.near() = _near; + _mesh_opts.near() = _near; } /*------------------------------------- HFUN keywords */ @@ -172,8 +171,7 @@ std::string _file ) { - this-> - _jjig->_hfun_file = _file; + this->_jjig->_hfun_file = _file; } __normal_call void_type push_hfun_scal ( std::int32_t _scal @@ -187,15 +185,13 @@ double _hmax ) { - this-> - _jjig->_hfun_hmax = _hmax; + this->_jjig->_hfun_hmax = _hmax; } __normal_call void_type push_hfun_hmin ( double _hmin ) { - this-> - _jjig->_hfun_hmin = _hmin; + this->_jjig->_hfun_hmin = _hmin; } /*------------------------------------- INIT keywords */ @@ -203,8 +199,7 @@ std::string _file ) { - this-> - _jjig->_init_file = _file; + this->_jjig->_init_file = _file; } /*------------------------------------- BNDS keywords */ @@ -229,22 +224,19 @@ std::string _file ) { - this-> - _jjig->_mesh_file = _file; + this->_jjig->_mesh_file = _file; } __normal_call void_type push_tria_file ( std::string _file ) { - this-> - _jjig->_tria_file = _file; + this->_jjig->_tria_file = _file; } __normal_call void_type push_bnds_file ( std::string _file ) { - this-> - _jjig->_bnds_file = _file; + this->_jjig->_bnds_file = _file; } __normal_call void_type push_mesh_dims ( @@ -252,119 +244,133 @@ ) { this->_jjig-> - _mesh_opts.dims() = _dims; + _mesh_opts.dims() = _dims; } __normal_call void_type push_mesh_iter ( std::int32_t _iter ) { this->_jjig-> - _mesh_opts.iter() = _iter; + _mesh_opts.iter() = _iter; } __normal_call void_type push_mesh_rule ( std::int32_t _rule ) { this->_jjig-> - _mesh_opts.rule() = _rule; + _mesh_opts.rule() = _rule; } __normal_call void_type push_mesh_siz1 ( double _siz1 ) { this->_jjig-> - _mesh_opts.siz1() = _siz1; + _mesh_opts.siz1() = _siz1; } __normal_call void_type push_mesh_siz2 ( double _siz2 ) { this->_jjig-> - _mesh_opts.siz2() = _siz2; + _mesh_opts.siz2() = _siz2; } __normal_call void_type push_mesh_siz3 ( double _siz3 ) { this->_jjig-> - _mesh_opts.siz3() = _siz3; + _mesh_opts.siz3() = _siz3; + } + __normal_call void_type push_mesh_orph ( + bool _orph + ) + { + this->_jjig-> + _mesh_opts.orph() = _orph; + } + __normal_call void_type push_mesh_lock ( + bool _lock + ) + { + this->_jjig-> + _mesh_opts.lock() = _lock; } __normal_call void_type push_mesh_top1 ( bool _top1 ) { this->_jjig-> - _mesh_opts.top1() = _top1; + _mesh_opts.top1() = _top1; } __normal_call void_type push_mesh_top2 ( bool _top2 ) { this->_jjig-> - _mesh_opts.top2() = _top2; + _mesh_opts.top2() = _top2; } __normal_call void_type push_mesh_rad2 ( double _rad2 ) { this->_jjig-> - _mesh_opts.rad2() = _rad2; + _mesh_opts.rad2() = _rad2; } __normal_call void_type push_mesh_rad3 ( double _rad3 ) { this->_jjig-> - _mesh_opts.rad3() = _rad3; + _mesh_opts.rad3() = _rad3; } __normal_call void_type push_mesh_off2 ( double _off2 ) { this->_jjig-> - _mesh_opts.off2() = _off2; + _mesh_opts.off2() = _off2; } __normal_call void_type push_mesh_off3 ( double _off3 ) { this->_jjig-> - _mesh_opts.off3() = _off3; + _mesh_opts.off3() = _off3; } __normal_call void_type push_mesh_snk2 ( double _snk2 ) { this->_jjig-> - _mesh_opts.snk2() = _snk2; + _mesh_opts.snk2() = _snk2; } __normal_call void_type push_mesh_snk3 ( double _snk3 ) { this->_jjig-> - _mesh_opts.snk3() = _snk3; + _mesh_opts.snk3() = _snk3; } __normal_call void_type push_mesh_eps1 ( double _eps1 ) { this->_jjig-> - _mesh_opts.eps1() = _eps1; + _mesh_opts.eps1() = _eps1; } __normal_call void_type push_mesh_eps2 ( double _eps2 ) { this->_jjig-> - _mesh_opts.eps2() = _eps2; + _mesh_opts.eps2() = _eps2; } __normal_call void_type push_mesh_vol3 ( double _vol3 ) { this->_jjig-> - _mesh_opts.vol3() = _vol3; + _mesh_opts.vol3() = _vol3; } /*------------------------------------- OPTM keywords */ @@ -389,63 +395,79 @@ ) { this->_jjig-> - _iter_opts.iter() = _iter; + _iter_opts.iter() = _iter; } __normal_call void_type push_optm_beta ( double _beta ) { this->_jjig-> - _iter_opts.beta() = _beta; + _iter_opts.beta() = _beta; } __normal_call void_type push_optm_zeta ( double _zeta ) { this->_jjig-> - _iter_opts.zeta() = _zeta; + _iter_opts.zeta() = _zeta; } __normal_call void_type push_optm_qtol ( double _qtol ) { this->_jjig-> - _iter_opts.qtol() = _qtol; + _iter_opts.qtol() = _qtol; } __normal_call void_type push_optm_qlim ( double _qlim ) { this->_jjig-> - _iter_opts.qlim() = _qlim; + _iter_opts.qlim() = _qlim; } + + __normal_call void_type push_optm_wmin ( + double _wmin + ) + { + this->_jjig-> + _iter_opts.wmin() = _wmin; + } + __normal_call void_type push_optm_wmax ( + double _wmax + ) + { + this->_jjig-> + _iter_opts.wmax() = _wmax; + } + __normal_call void_type push_optm_tria ( bool _flag ) { this->_jjig-> - _iter_opts.tria() = _flag; + _iter_opts.tria() = _flag; } __normal_call void_type push_optm_dual ( bool _flag ) { this->_jjig-> - _iter_opts.dual() = _flag; + _iter_opts.dual() = _flag; } __normal_call void_type push_optm_div_ ( bool _flag ) { this->_jjig-> - _iter_opts.div_() = _flag; + _iter_opts.div_() = _flag; } __normal_call void_type push_optm_zip_ ( bool _flag ) { this->_jjig-> - _iter_opts.zip_() = _flag; + _iter_opts.zip_() = _flag; } } ; @@ -613,6 +635,12 @@ _jcfg._mesh_opts. siz3() = _jjig._mesh_siz3 ; + _jcfg._mesh_opts. + orph() = _jjig._mesh_orph ; + + _jcfg._mesh_opts. + lock() = _jjig._mesh_lock ; + _jcfg._mesh_opts. top1() = _jjig._mesh_top1 ; _jcfg._mesh_opts. @@ -682,6 +710,11 @@ _jcfg._iter_opts. qlim() = _jjig._optm_qlim ; + _jcfg._iter_opts. + wmin() = _jjig._optm_wmin ; + _jcfg._iter_opts. + wmax() = _jjig._optm_wmax ; + _jcfg._iter_opts. tria() = _jjig._optm_tria ; _jcfg._iter_opts. @@ -903,12 +936,20 @@ _jcfg._iter_opts.qtol(), (real_type) 0., (real_type) 1.) - __testREAL("OPTM-QLIM", _jcfg._iter_opts.qlim(), (real_type) 0., (real_type) 1.) + __testREAL("OPTM-WMIN", + _jcfg._iter_opts.wmin(), + -std::numeric_limits::infinity(), + (real_type) 0.) + __testREAL("OPTM-WMAX", + _jcfg._iter_opts.wmax(), + (real_type) 0., + +std::numeric_limits::infinity()) + #undef __testINTS #undef __testREAL #undef __warnREAL @@ -1033,6 +1074,12 @@ jcfg_data::mesh_pred::bisector) _jlog.push(" MESH-KERN = BISECTOR \n") ; + _jlog.push(" MESH-ORPH = " + + __pushBVAL(_jcfg._mesh_opts.orph())); + + _jlog.push(" MESH-LOCK = " + + __pushBVAL(_jcfg._mesh_opts.lock())); + _jlog.push(" MESH-TOP1 = " + __pushBVAL(_jcfg._mesh_opts.top1())); _jlog.push(" MESH-TOP2 = " + @@ -1109,6 +1156,11 @@ _jlog.push(" OPTM-QLIM = " + __pushRVAL(_jcfg._iter_opts.qlim())); + _jlog.push(" OPTM-WMIN =" + // -ve + __pushRVAL(_jcfg._iter_opts.wmin())); + _jlog.push(" OPTM-WMAX = " + + __pushRVAL(_jcfg._iter_opts.wmax())); + _jlog.push(" OPTM-ZIP_ = " + __pushBVAL(_jcfg._iter_opts.zip_())); _jlog.push(" OPTM-DIV_ = " + diff --git a/src/jig_read.hpp b/src/jig_read.hpp index aa164d4..a14ccd6 100644 --- a/src/jig_read.hpp +++ b/src/jig_read.hpp @@ -35,9 +35,9 @@ * -------------------------------------------------------- * - * Last updated: 12 Dec., 2022 + * Last updated: 27 Jul., 2025 * - * Copyright 2013-2022 + * Copyright 2013-2025 * Darren Engwirda * d.engwirda@gmail.com * https://github.com/dengwirda/ @@ -137,6 +137,12 @@ __normal_call void_type push_mesh_siz3 ( double /*_siz3*/ ) { } + __normal_call void_type push_mesh_orph ( + bool /*_orph*/ + ) { } + __normal_call void_type push_mesh_lock ( + bool /*_lock*/ + ) { } __normal_call void_type push_mesh_top1 ( bool /*_top1*/ ) { } @@ -192,6 +198,12 @@ __normal_call void_type push_optm_qlim ( double /*_qlim*/ ) { } + __normal_call void_type push_optm_wmin ( + double /*_wmin*/ + ) { } + __normal_call void_type push_optm_wmax ( + double /*_wmax*/ + ) { } __normal_call void_type push_optm_tria ( bool /*_flag*/ ) { } @@ -601,6 +613,16 @@ __putREAL(push_mesh_vol3, _stok) ; } else + if (_stok[0] == "MESH_ORPH") + { + __putBOOL(push_mesh_orph, _stok) ; + } + else + if (_stok[0] == "MESH_LOCK") + { + __putBOOL(push_mesh_lock, _stok) ; + } + else if (_stok[0] == "MESH_TOP1") { __putBOOL(push_mesh_top1, _stok) ; @@ -651,11 +673,22 @@ { __putREAL(push_optm_qtol, _stok) ; } + else if (_stok[0] == "OPTM_QLIM") { __putREAL(push_optm_qlim, _stok) ; } else + if (_stok[0] == "OPTM_WMIN") + { + __putREAL(push_optm_wmin, _stok) ; + } + else + if (_stok[0] == "OPTM_WMAX") + { + __putREAL(push_optm_wmax, _stok) ; + } + else if (_stok[0] == "OPTM_ZIP_") { __putBOOL(push_optm_zip_, _stok) ; diff --git a/src/jigsaw.cpp b/src/jigsaw.cpp index 8d94db6..1e91b25 100644 --- a/src/jigsaw.cpp +++ b/src/jigsaw.cpp @@ -41,11 +41,11 @@ * JIGSAW: an unstructured mesh generation library. -------------------------------------------------------- * - * JIGSAW release 1.0.0.x + * JIGSAW release 1.1.0.x * - * Last updated: 11 Dec., 2022 + * Last updated: 20 Oct., 2024 * - * Copyright 2013 -- 2022 + * Copyright 2013 -- 2024 * Darren Engwirda * d.engwirda@gmail.com * https://github.com/dengwirda @@ -193,7 +193,7 @@ -------------------------------------------------------- */ -# define __JGSWVSTR "JIGSAW VERSION 1.0.0" +# define __JGSWVSTR "JIGSAW VERSION 1.1.0" # if defined( USE_NETCDF) # define __use_netcdf @@ -233,7 +233,7 @@ # endif # define __jloglndv \ -"#------------------------------------------------------------\n" +"#-----------------------------------------------------------------------\n" /*---------------------------------- for i/o on files */ @@ -907,7 +907,7 @@ std::stringstream _sstr; _sstr << " Done. (" << std::scientific - << std::setprecision(2) + << std::setprecision(3) << time_span(_ttic, _ttoc ) << "sec)\n\n" ; diff --git a/src/jigsaw.hpp b/src/jigsaw.hpp index ec541e5..b7dd22a 100644 --- a/src/jigsaw.hpp +++ b/src/jigsaw.hpp @@ -59,7 +59,7 @@ std::string asciibanner = " \n" - "#------------------------------------------------------------\n" + "#-----------------------------------------------------------------------\n" "#\n" "# ,o, ,o, / \n" "# ` ` e88~88e d88~\\ /~~~8e Y88b e / \n" @@ -69,9 +69,9 @@ "# 88P 888 Cb \\_88P \"8b_-888 Y Y \n" "# \\_8\" Y8\"\"8D \n" "#\n" - "#------------------------------------------------------------\n" + "#-----------------------------------------------------------------------\n" "# JIGSAW: an unstructured mesh generation library. \n" - "#------------------------------------------------------------\n" + "#-----------------------------------------------------------------------\n" " \n" " " __JGSWVSTR "\n\n" ; @@ -1629,7 +1629,7 @@ _retv = -2 ; std::cout << - "run jigsaw jigname.jig"; + "Usage: jigsaw user-opts.jig" ; std::cout << std::endl ; break ; @@ -1665,6 +1665,11 @@ break ; } } + if (_retv == -1) + { + std::cout << + "**parse error: *.jig file not found!" << std::endl; + } if (_retv != +0) return ( _retv ) ; /*--------------------------------- setup *.JLOG file */ diff --git a/src/libcpp/aabb_tree/aabb_tree_k.hpp b/src/libcpp/aabb_tree/aabb_tree_k.hpp index a7ece7a..1e4a352 100644 --- a/src/libcpp/aabb_tree/aabb_tree_k.hpp +++ b/src/libcpp/aabb_tree/aabb_tree_k.hpp @@ -35,9 +35,9 @@ * ------------------------------------------------------------ * - * Last updated: 30 Dec., 2022 + * Last updated: 20 Apr., 2023 * - * Copyright 2013-2022 + * Copyright 2013-2023 * Darren Engwirda * d.engwirda@gmail.com * https://github.com/dengwirda/ @@ -479,6 +479,8 @@ this->_root->_hptr = nullptr; /*------------------------------ push items onto root */ + init_aabb_node (this->_root); + { item_data *_hptr = nullptr; item_data *_idat = nullptr; @@ -492,12 +494,12 @@ this->_imax = std::max( this->_imax,_head->ipos ()) ; + + push_aabb_node(this->_root, _hptr ) ; } this->_root->_hptr = _hptr ; } - init_aabb_node (this->_root); - /*-------------------------- a list of un-split nodes */ this->_work.clear() ; this->_work. @@ -983,18 +985,14 @@ { real_type _dloc = _bmin[_idim] - _ppos[_idim]; - - _dist = - std::max (_dist, _dloc); + _dist += _dloc ; } else if (_ppos[_idim] > _bmax[_idim]) { real_type _dloc = _ppos[_idim] - _bmax[_idim]; - - _dist = - std::max (_dist, _dloc); + _dist += _dloc ; } } @@ -1124,9 +1122,7 @@ /*------------------------ descend if maybe close */ if (_ndat. - _node-> _hptr != nullptr || - _ndat. - _node->lower(0) == nullptr) + _node-> _hptr != nullptr) { /*------------------------ leaf: update item-dist */ _find = true ; diff --git a/src/libcpp/algorithms/find.hpp b/src/libcpp/algorithms/find.hpp index 1ba8944..ab86d7b 100644 --- a/src/libcpp/algorithms/find.hpp +++ b/src/libcpp/algorithms/find.hpp @@ -148,6 +148,32 @@ return _head ; } + /* + -------------------------------------------------------- + * IS-UNIQUE: returns TRUE if VAL disjoint to SEQ. + -------------------------------------------------------- + */ + + template < + typename iter_type , + typename data_type , + typename pred_type + > + __normal_call bool_type is_unique ( + iter_type _head , // head of sequence to search + iter_type _tend , // last of sequence to search + data_type _xval , // value to search for + pred_type _same // comparison predicate + ) + { + for (; _head != _tend; ++_head) + { + if (_same(*_head, _xval)) return false ; + } + + return true ; + } + } diff --git a/src/libcpp/containers/hashtable.hpp b/src/libcpp/containers/hashtable.hpp index a403e1b..0efa690 100644 --- a/src/libcpp/containers/hashtable.hpp +++ b/src/libcpp/containers/hashtable.hpp @@ -4,7 +4,7 @@ * a chained hash-table. ------------------------------------------------------------ * - * HASH-TABLE is a dynamically-sized, chained hash-table + * HASH-TABLE is a dynamically-sized, chained hashtable * implementation, essentially a linear array of singly- * linked hash buckets. * @@ -103,7 +103,7 @@ pred_type , allocator > self_type ; - size_type static constexpr _mini_count = +8 ; + size_type static constexpr _mini_count = 32 ; public : @@ -156,17 +156,11 @@ ) { /*------------------------------- round to next 2^pwr */ - _slots = next_pwr2 (_slots); + _slots = next_pwr2 (_slots * 1) ; /*------------------------------- 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) ; + this->_lptr.set_count(std::max( + _slots, this->_mini_count), _alloc, nullptr) ; /*------------------------------- re-hash all objects */ redo_hash() ; @@ -176,14 +170,13 @@ ) { /*------------------------------- increase table size */ - if (this->_lptr.count() < - this->_mini_count ) + 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, + this->_lptr.count()*2 , containers::tight_alloc, nullptr) ; /*------------------------------- re-hash all objects */ diff --git a/src/libcpp/expansion/mp_float.hpp b/src/libcpp/expansion/mp_float.hpp index 5610954..a38b452 100644 --- a/src/libcpp/expansion/mp_float.hpp +++ b/src/libcpp/expansion/mp_float.hpp @@ -1011,8 +1011,7 @@ expansion _qp ; expansion_mul(_qa, _qb, _qp); - expansion_add( - _xp, _yp, _zp, _qp, _dp); + expansion_add(_xp, _yp, _zp, _qp, _dp) ; } # undef REAL_TYPE diff --git a/src/libcpp/expansion/mp_utils.hpp b/src/libcpp/expansion/mp_utils.hpp index 5720a03..4f4e2aa 100644 --- a/src/libcpp/expansion/mp_utils.hpp +++ b/src/libcpp/expansion/mp_utils.hpp @@ -35,7 +35,7 @@ * -------------------------------------------------------- * - * Last updated: 03 Mar., 2020 + * Last updated: 11 May., 2024 * * Copyright 2020-- * Darren Engwirda @@ -288,8 +288,8 @@ } else { - expansion_sub(_det2p, _det1p, _sum_1); - expansion_sub(_det4p, _det3p, _sum_2); + expansion_sub(_det1p, _det2p, _sum_1); + expansion_sub(_det3p, _det4p, _sum_2); } expansion_add(_sum_1, _sum_2, _final); @@ -440,6 +440,163 @@ expansion_add(_sum_3, _sum_2, _final); } + /* + -------------------------------------------------------- + * + * Compute an exact 6 x 6 determinant. + * + * | a1 a2 a3 a4 a5 v1 | + * | b1 b2 b3 b4 b5 v2 | + * | c1 c2 c3 c4 c5 v3 | + * | d1 d2 d3 d4 d5 v4 | + * | e1 e2 e3 e4 e5 v5 | + * | f1 f2 f3 f4 f5 v6 | + * + * as the product of 5 x 5 minors about a pivot column + * P, shown here for P = 6. The entry V1 is associated + * with the minor + * + * | b1 b2 b3 b4 b5 | + * | c1 c2 c3 c4 c5 | + * | d1 d2 d3 d4 d5 | = D1 + * | e1 e2 e3 e4 e5 | + * | f1 f2 f3 f4 f5 | + * + * 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, size_t NL, + size_t NM + > + __inline_call void compute_det_6x6 ( + 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 const& _det6p , + expansion const& _val6p , + 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); + + INDX_TYPE + constexpr N6 = mul_alloc (NK, NL) ; + expansion _mul6p; + expansion_mul(_det6p, _val6p, _mul6p); + + /*---------------------------------- 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 (N5, N6) ; + expansion _sum_3; + + if (_pivot % 2 == +0) + { + expansion_sub(_mul2p, _mul1p, _sum_1); + expansion_sub(_mul4p, _mul3p, _sum_2); + expansion_sub(_mul6p, _mul5p, _sum_3); + } + else + { + expansion_sub(_mul1p, _mul2p, _sum_1); + expansion_sub(_mul3p, _mul4p, _sum_2); + expansion_sub(_mul5p, _mul6p, _sum_3); + } + + expansion_add(_sum_1, _sum_2, _sum_3, _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, + size_t NG + > + __inline_call void unitary_det_6x6 ( + expansion const& _det1p , + expansion const& _det2p , + expansion const& _det3p , + expansion const& _det4p , + expansion const& _det5p , + expansion const& _det6p , + 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 M3 = sub_alloc (NE, NF) ; + expansion _sum_3; + + if (_pivot % 2 == +0) + { + expansion_sub(_det2p, _det1p, _sum_1); + expansion_sub(_det4p, _det3p, _sum_2); + expansion_sub(_det6p, _det5p, _sum_3); + } + else + { + expansion_sub(_det1p, _det2p, _sum_1); + expansion_sub(_det3p, _det4p, _sum_2); + expansion_sub(_det5p, _det6p, _sum_3); + } + + expansion_add(_sum_1, _sum_2, _sum_3, _final); + } + # undef REAL_TYPE # undef INDX_TYPE diff --git a/src/libcpp/geom_base/cell_base_k.hpp b/src/libcpp/geom_base/cell_base_k.hpp index fd4ad37..0c77b7d 100644 --- a/src/libcpp/geom_base/cell_base_k.hpp +++ b/src/libcpp/geom_base/cell_base_k.hpp @@ -35,9 +35,9 @@ * -------------------------------------------------------- * - * Last updated: 12 Jul., 2022 + * Last updated: 24 Jul., 2025 * - * Copyright 2013-2022 + * Copyright 2013-2025 * Darren Engwirda * d.engwirda@gmail.com * https://github.com/dengwirda/ @@ -710,8 +710,11 @@ real_type _r2 = _m2[2] ; real_type _r3 = _m3[2] ; - real_type _rb = // chara.-length - std::pow( _r1 * _r2 * _r3, 1./3.) ; + //real_type _rb = // chara.-length + //std::pow( _r1 * _r2 * _r3, 1./3.) ; + + real_type _rb = + (_r1+_r2+_r3) / (real_type)+3. ; real_type _qb = _lb / _rb ; @@ -772,8 +775,11 @@ real_type _r2 = _m2[3] ; real_type _r3 = _m3[3] ; - real_type _rb = // chara.-length - std::pow( _r1 * _r2 * _r3, 1./3.) ; + //real_type _rb = // chara.-length + //std::pow( _r1 * _r2 * _r3, 1./3.) ; + + real_type _rb = + (_r1+_r2+_r3) / (real_type)+3. ; real_type _qb = _lb / _rb ; diff --git a/src/libcpp/geom_base/intersect_k.hpp b/src/libcpp/geom_base/intersect_k.hpp index c6b6442..071fe03 100644 --- a/src/libcpp/geom_base/intersect_k.hpp +++ b/src/libcpp/geom_base/intersect_k.hpp @@ -35,9 +35,9 @@ * -------------------------------------------------------- * - * Last updated: 12 Aug., 2019 + * Last updated: 10 Feb., 2024 * - * Copyright 2013-2019 + * Copyright 2013-2024 * Darren Engwirda * d.engwirda@gmail.com * https://github.com/dengwirda/ @@ -61,6 +61,78 @@ hits_type face_hits = +3 ; hits_type tria_hits = +4 ; + /* + -------------------------------------------------------- + * COPY-NODE-KD: node-node copy helpers. + -------------------------------------------------------- + */ + + template < + typename data_one_, + typename data_two_ + > + __inline_call void copy_node_2d ( + __write_ptr (data_one_) _pa, // copy: A := B + __const_ptr (data_two_) _pb + ) + { + _pa[0] = (data_one_) _pb[0] ; + _pa[1] = (data_one_) _pb[1] ; + } + + template < + typename data_one_, + typename data_two_ + > + __inline_call void copy_node_3d ( + __write_ptr (data_one_) _pa, // copy: A := B + __const_ptr (data_two_) _pb + ) + { + _pa[0] = (data_one_) _pb[0] ; + _pa[1] = (data_one_) _pb[1] ; + _pa[2] = (data_one_) _pb[2] ; + } + + template < + typename data_one_, + typename data_two_ + > + __inline_call void copy_node_xy ( + __write_ptr (data_one_) _pa, // copy: A := B + __const_ptr (data_two_) _pb + ) + { + _pa[0] = (data_one_) _pb[0] ; + _pa[1] = (data_one_) _pb[1] ; + } + + template < + typename data_one_, + typename data_two_ + > + __inline_call void copy_node_yz ( + __write_ptr (data_one_) _pa, // copy: A := B + __const_ptr (data_two_) _pb + ) + { + _pa[0] = (data_one_) _pb[1] ; + _pa[1] = (data_one_) _pb[2] ; + } + + template < + typename data_one_, + typename data_two_ + > + __inline_call void copy_node_xz ( + __write_ptr (data_one_) _pa, // copy: A := B + __const_ptr (data_two_) _pb + ) + { + _pa[0] = (data_one_) _pb[0] ; + _pa[1] = (data_one_) _pb[2] ; + } + /* -------------------------------------------------------- * BALL-LINE-KD: ball-line intersections @@ -98,81 +170,42 @@ size_t _nn = +0 ; real_type _tt[2] ; - if ( math:: - polyroots(_aa, _bb, _cc, _tt)) + if (math::polyroots(_aa, _bb, _cc, _tt)) { - if (_tt[0] >= (real_type)+0. && - _tt[0] <= (real_type)+1. ) + for (size_t _ii = 0; _ii < 2; ++_ii) { - /*----------------------- compute 1st-root intersect. */ - real_type _WB = - (real_type)+0.+_tt[0] ; - - real_type _WA = - (real_type)+1.-_tt[0] ; - - _nn += +1 ; - - dd_flt _PA[2] ; - _PA[0]=_pa[0] ; - _PA[1]=_pa[1] ; - - dd_flt _PB[2] ; - _PB[0]=_pb[0] ; - _PB[1]=_pb[1] ; - - dd_flt _QQ[2] ; - _QQ[0]=_PA[0] * _WA + - _PB[0] * _WB ; - _QQ[1]=_PA[1] * _WA + - _PB[1] * _WB ; - - if (_nn == 1) + if (_tt[_ii] >= (real_type)+0. && + _tt[_ii] <= (real_type)+1. ) { - _qa[0]=_QQ[0] ; - _qa[1]=_QQ[1] ; - } - else - { - _qb[0]=_QQ[0] ; - _qb[1]=_QQ[1] ; - } - } - if (_tt[1] >= (real_type)+0. && - _tt[1] <= (real_type)+1. ) - { - /*----------------------- compute 2nd-root intersect. */ - real_type _WB = - (real_type)+0.+_tt[1] ; + /*----------------------- compute ith-root intersect. */ + real_type _WB = + (real_type)+0.+_tt[_ii] ; - real_type _WA = - (real_type)+1.-_tt[1] ; + real_type _WA = + (real_type)+1.-_tt[_ii] ; - _nn += +1 ; + _nn += +1 ; - dd_flt _PA[2] ; - _PA[0]=_pa[0] ; - _PA[1]=_pa[1] ; + dd_flt _PA[2] ; + copy_node_2d(_PA, _pa) ; + + dd_flt _PB[2] ; + copy_node_2d(_PB, _pb) ; - dd_flt _PB[2] ; - _PB[0]=_pb[0] ; - _PB[1]=_pb[1] ; - - dd_flt _QQ[2] ; - _QQ[0]=_PA[0] * _WA + - _PB[0] * _WB ; - _QQ[1]=_PA[1] * _WA + - _PB[1] * _WB ; + dd_flt _QQ[2] ; + _QQ[0]=_PA[0] * _WA + + _PB[0] * _WB ; + _QQ[1]=_PA[1] * _WA + + _PB[1] * _WB ; - if (_nn == 1) - { - _qa[0]=_QQ[0] ; - _qa[1]=_QQ[1] ; - } - else - { - _qb[0]=_QQ[0] ; - _qb[1]=_QQ[1] ; + if (_nn == 1) + { + copy_node_2d(_qa, _QQ) ; + } + else + { + copy_node_2d(_qb, _QQ) ; + } } } } @@ -213,93 +246,44 @@ size_t _nn = +0 ; real_type _tt[2] ; - if ( math:: - polyroots(_aa, _bb, _cc, _tt)) + if (math::polyroots(_aa, _bb, _cc, _tt)) { - if (_tt[0] >= (real_type)+0. && - _tt[0] <= (real_type)+1. ) + for (size_t _ii = 0; _ii < 2; ++_ii) { - /*----------------------- compute 1st-root intersect. */ - real_type _WB = - (real_type)+0.+_tt[0] ; - - real_type _WA = - (real_type)+1.-_tt[0] ; - - _nn += +1 ; - - dd_flt _PA[3] ; - _PA[0]=_pa[0] ; - _PA[1]=_pa[1] ; - _PA[2]=_pa[2] ; - - dd_flt _PB[3] ; - _PB[0]=_pb[0] ; - _PB[1]=_pb[1] ; - _PB[2]=_pb[2] ; - - dd_flt _QQ[3] ; - _QQ[0]=_PA[0] * _WA + - _PB[0] * _WB ; - _QQ[1]=_PA[1] * _WA + - _PB[1] * _WB ; - _QQ[2]=_PA[2] * _WA + - _PB[2] * _WB ; - - if (_nn == 1) + if (_tt[_ii] >= (real_type)+0. && + _tt[_ii] <= (real_type)+1. ) { - _qa[0]=_QQ[0] ; - _qa[1]=_QQ[1] ; - _qa[2]=_QQ[2] ; - } - else - { - _qb[0]=_QQ[0] ; - _qb[1]=_QQ[1] ; - _qb[2]=_QQ[2] ; - } - } - if (_tt[1] >= (real_type)+0. && - _tt[1] <= (real_type)+1. ) - { - /*----------------------- compute 2nd-root intersect. */ - real_type _WB = - (real_type)+0.+_tt[1] ; + /*----------------------- compute ith-root intersect. */ + real_type _WB = + (real_type)+0.+_tt[_ii] ; - real_type _WA = - (real_type)+1.-_tt[1] ; + real_type _WA = + (real_type)+1.-_tt[_ii] ; - _nn += +1 ; + _nn += +1 ; - dd_flt _PA[3] ; - _PA[0]=_pa[0] ; - _PA[1]=_pa[1] ; - _PA[2]=_pa[2] ; + dd_flt _PA[3] ; + copy_node_3d(_PA, _pa) ; - dd_flt _PB[3] ; - _PB[0]=_pb[0] ; - _PB[1]=_pb[1] ; - _PB[2]=_pb[2] ; + dd_flt _PB[3] ; + copy_node_3d(_PB, _pb) ; - dd_flt _QQ[3] ; - _QQ[0]=_PA[0] * _WA + - _PB[0] * _WB ; - _QQ[1]=_PA[1] * _WA + - _PB[1] * _WB ; - _QQ[2]=_PA[2] * _WA + - _PB[2] * _WB ; + dd_flt _QQ[3] ; + _QQ[0]=_PA[0] * _WA + + _PB[0] * _WB ; + _QQ[1]=_PA[1] * _WA + + _PB[1] * _WB ; + _QQ[2]=_PA[2] * _WA + + _PB[2] * _WB ; - if (_nn == 1) - { - _qa[0]=_QQ[0] ; - _qa[1]=_QQ[1] ; - _qa[2]=_QQ[2] ; - } - else - { - _qb[0]=_QQ[0] ; - _qb[1]=_QQ[1] ; - _qb[2]=_QQ[2] ; + if (_nn == 1) + { + copy_node_3d(_qa, _QQ) ; + } + else + { + copy_node_3d(_qb, _QQ) ; + } } } } @@ -407,78 +391,6 @@ } } - /* - -------------------------------------------------------- - * COPY-NODE-KD: node-node copy helpers. - -------------------------------------------------------- - */ - - template < - typename data_one_, - typename data_two_ - > - __inline_call void copy_node_2d ( - __write_ptr (data_one_) _pa, // copy: A := B - __const_ptr (data_two_) _pb - ) - { - _pa[0] = (data_one_) _pb[0] ; - _pa[1] = (data_one_) _pb[1] ; - } - - template < - typename data_one_, - typename data_two_ - > - __inline_call void copy_node_3d ( - __write_ptr (data_one_) _pa, // copy: A := B - __const_ptr (data_two_) _pb - ) - { - _pa[0] = (data_one_) _pb[0] ; - _pa[1] = (data_one_) _pb[1] ; - _pa[2] = (data_one_) _pb[2] ; - } - - template < - typename data_one_, - typename data_two_ - > - __inline_call void copy_node_xy ( - __write_ptr (data_one_) _pa, // copy: A := B - __const_ptr (data_two_) _pb - ) - { - _pa[0] = (data_one_) _pb[0] ; - _pa[1] = (data_one_) _pb[1] ; - } - - template < - typename data_one_, - typename data_two_ - > - __inline_call void copy_node_yz ( - __write_ptr (data_one_) _pa, // copy: A := B - __const_ptr (data_two_) _pb - ) - { - _pa[0] = (data_one_) _pb[1] ; - _pa[1] = (data_one_) _pb[2] ; - } - - template < - typename data_one_, - typename data_two_ - > - __inline_call void copy_node_xz ( - __write_ptr (data_one_) _pa, // copy: A := B - __const_ptr (data_two_) _pb - ) - { - _pa[0] = (data_one_) _pb[0] ; - _pa[1] = (data_one_) _pb[2] ; - } - /* -------------------------------------------------------- * LINE-FLAT-KD: line-flat intersections @@ -501,8 +413,6 @@ _pa[1] == _pb[1] && _pa[2] == _pb[2] ) { - //std::cout << "node_flat_3d" << std::endl; - return ( false ) ; } else @@ -510,11 +420,8 @@ _pp[1] == _pa[1] && _pp[2] == _pa[2] ) { - - _qq[0] = _pa[0] ; - _qq[1] = _pa[1] ; - _qq[2] = _pa[2] ; - + copy_node_3d(_qq, _pa) ; + return ( true ) ; } else @@ -522,11 +429,8 @@ _pp[1] == _pb[1] && _pp[2] == _pb[2] ) { - - _qq[0] = _pb[0] ; - _qq[1] = _pb[1] ; - _qq[2] = _pb[2] ; - + copy_node_3d(_qq, _pb) ; + return ( true ) ; } else @@ -542,7 +446,7 @@ _ap[1] = _pp[1] - _pa[1] ; _ap[2] = _pp[2] - _pa[2] ; - real_type _ep = + 1.0 * + real_type constexpr _ep = +1. * std::numeric_limits::epsilon() ; real_type _d1 = @@ -565,38 +469,28 @@ if (_tt == (real_type)+0.) { - _qq[0] = _pa[0] ; - _qq[1] = _pa[1] ; - _qq[2] = _pa[2] ; + copy_node_3d(_qq, _pa) ; } else if (_tt == (real_type)+1.) { - _qq[0] = _pb[0] ; - _qq[1] = _pb[1] ; - _qq[2] = _pb[2] ; + copy_node_3d(_qq, _pb) ; } else { dd_flt _AB[3] ; - _AB[0] = _pb[0] ; - _AB[1] = _pb[1] ; - _AB[2] = _pb[2] ; + copy_node_3d(_AB, _pb) ; _AB[0]-= _pa[0] ; _AB[1]-= _pa[1] ; _AB[2]-= _pa[2] ; dd_flt _QQ[3] ; - _QQ[0] = _pa[0] ; - _QQ[1] = _pa[1] ; - _QQ[2] = _pa[2] ; - _QQ[0]+= _AB[0] * _tt ; - _QQ[1]+= _AB[1] * _tt ; - _QQ[2]+= _AB[2] * _tt ; + copy_node_3d(_QQ, _pa) ; + _QQ[0]+= _AB[0] * _tt; + _QQ[1]+= _AB[1] * _tt; + _QQ[2]+= _AB[2] * _tt; - _qq[0] = _QQ[0] ; - _qq[1] = _QQ[1] ; - _qq[2] = _QQ[2] ; + copy_node_3d(_qq, _QQ) ; } return ( true ) ; @@ -689,15 +583,13 @@ _vv[0] = _pb[0] - _pa[0] ; _vv[1] = _pb[1] - _pa[1] ; - if (proj_line_2d(_pp, _pa, - _vv, _tt) ) + if (proj_line_2d(_pp, _pa, _vv, _tt)) { if (_tt <= (real_type)+0.) { _ht = node_hits; - _qq[0] = _pa[0] ; - _qq[1] = _pa[1] ; + copy_node_2d(_qq, _pa) ; return ( true ) ; } @@ -706,8 +598,7 @@ { _ht = node_hits; - _qq[0] = _pb[0] ; - _qq[1] = _pb[1] ; + copy_node_2d(_qq, _pb) ; return ( true ) ; } @@ -715,10 +606,17 @@ { _ht = edge_hits; - _qq[0] = - _pa[0] + _tt*_vv[ 0] ; - _qq[1] = - _pa[1] + _tt*_vv[ 1] ; + dd_flt _VV[2] ; + copy_node_2d(_VV, _pb) ; + _VV[0]-= _pa[0] ; + _VV[1]-= _pa[1] ; + + dd_flt _QQ[2] ; + copy_node_2d(_QQ, _pa) ; + _QQ[0]+= _VV[0] * _tt; + _QQ[1]+= _VV[1] * _tt; + + copy_node_2d(_qq, _QQ) ; return ( true ) ; } @@ -770,16 +668,13 @@ _vv[1] = _pb[1] - _pa[1] ; _vv[2] = _pb[2] - _pa[2] ; - if (proj_line_3d(_pp, _pa, - _vv, _tt) ) + if (proj_line_3d(_pp, _pa, _vv, _tt)) { if (_tt <= (real_type)+0.) { _ht = node_hits; - _qq[0] = _pa[0] ; - _qq[1] = _pa[1] ; - _qq[2] = _pa[2] ; + copy_node_3d(_qq, _pa) ; return ( true ) ; } @@ -788,9 +683,7 @@ { _ht = node_hits; - _qq[0] = _pb[0] ; - _qq[1] = _pb[1] ; - _qq[2] = _pb[2] ; + copy_node_3d(_qq, _pb) ; return ( true ) ; } @@ -798,12 +691,19 @@ { _ht = edge_hits; - _qq[0] = - _pa[0] + _tt*_vv[ 0] ; - _qq[1] = - _pa[1] + _tt*_vv[ 1] ; - _qq[2] = - _pa[2] + _tt*_vv[ 2] ; + dd_flt _VV[3] ; + copy_node_3d(_VV, _pb) ; + _VV[0]-= _pa[0] ; + _VV[1]-= _pa[1] ; + _VV[2]-= _pa[2] ; + + dd_flt _QQ[3] ; + copy_node_3d(_QQ, _pa) ; + _QQ[0]+= _VV[0] * _tt; + _QQ[1]+= _VV[1] * _tt; + _QQ[2]+= _VV[2] * _tt; + + copy_node_3d(_qq, _QQ) ; return ( true ) ; } @@ -843,12 +743,16 @@ _tt = _d1/_d2 ; - _qq[0] = - _pi[0] + _tt * _nv[0] ; - _qq[1] = - _pi[1] + _tt * _nv[1] ; - _qq[2] = - _pi[2] + _tt * _nv[2] ; + dd_flt _VV[3] ; + copy_node_3d(_VV, _nv) ; + + dd_flt _QQ[3] ; + copy_node_3d(_QQ, _pi) ; + _QQ[0]+= _VV[0] * _tt; + _QQ[1]+= _VV[1] * _tt; + _QQ[2]+= _VV[2] * _tt; + + copy_node_3d(_qq, _QQ) ; return ( true ) ; } @@ -1277,11 +1181,7 @@ _ap[0] = _pp[0]-_pa[0] ; _ap[1] = _pp[1]-_pa[1] ; - double _dp = - _ab[0] * _ap[0] + - _ab[1] * _ap[1] ; - - return _dp ; + return geometry::dot_2d(_ab, _ap) ; } __normal_call double cleave3d ( @@ -1300,12 +1200,7 @@ _ap[1] = _pp[1]-_pa[1] ; _ap[2] = _pp[2]-_pa[2] ; - double _dp = - _ab[0] * _ap[0] + - _ab[1] * _ap[1] + - _ab[2] * _ap[2] ; - - return _dp ; + return geometry::dot_3d(_ab, _ap) ; } @@ -1328,8 +1223,7 @@ _pa[1] == _pb[1] ) { /*----------------------- have node-node intersection */ - _qq[0] = _pa[0] ; - _qq[1] = _pa[1] ; + copy_node_2d(_qq, _pa) ; return node_hits ; } @@ -1354,9 +1248,7 @@ _pa[2] == _pb[2] ) { /*----------------------- have node-node intersection */ - _qq[0] = _pa[0] ; - _qq[1] = _pa[1] ; - _qq[2] = _pa[2] ; + copy_node_3d(_qq, _pa) ; return node_hits ; } @@ -1395,17 +1287,14 @@ { /*----------------------- test node-line intersection */ double _PA[2] ; - _PA[0] = _pa[0] ; - _PA[1] = _pa[1] ; - + copy_node_2d(_PA, _pa) ; + double _PB[2] ; - _PB[0] = _pb[0] ; - _PB[1] = _pb[1] ; - + copy_node_2d(_PB, _pb) ; + double _PP[2] ; - _PP[0] = _pp[0] ; - _PP[1] = _pp[1] ; - + copy_node_2d(_PP, _pp) ; + double _ss = geompred::orient2d ( (double*)_PA , @@ -1428,8 +1317,7 @@ if (_sa*_sb > +0.0) { /*----------------------- have node-line intersection */ - _qq[0] = _pp[0] ; - _qq[1] = _pp[1] ; + copy_node_2d(_qq, _pp) ; return edge_hits ; } @@ -1437,27 +1325,24 @@ if (_sa == +0.0) { /*----------------------- have node-node intersection */ - _qq[0] = _pa[0] ; - _qq[1] = _pa[1] ; - + copy_node_2d(_qq, _pa) ; + return node_hits ; } else if (_sb == +0.0) { /*----------------------- have node-node intersection */ - _qq[0] = _pb[0] ; - _qq[1] = _pb[1] ; - + copy_node_2d(_qq, _pb) ; + return node_hits ; } else if ( !_bind ) { /*----------------------- is unconstrained: edge hits */ - _qq[0] = _pp[0] ; - _qq[1] = _pp[1] ; - + copy_node_2d(_qq, _pp) ; + return edge_hits ; } else @@ -1498,33 +1383,24 @@ { /*----------------------- test node-line intersection */ double _PA[3] ; - _PA[0] = _pa[0] ; - _PA[1] = _pa[1] ; - _PA[2] = _pa[2] ; - + copy_node_3d(_PA, _pa) ; + double _PB[3] ; - _PB[0] = _pb[0] ; - _PB[1] = _pb[1] ; - _PB[2] = _pb[2] ; - + copy_node_3d(_PB, _pb) ; + double _PP[3] ; - _PP[0] = _pp[0] ; - _PP[1] = _pp[1] ; - _PP[2] = _pp[2] ; - + copy_node_3d(_PP, _pp) ; + /*----------------------- get orientation in xy-plane */ double _A1[2] ; - _A1[0] = _PA[0] ; - _A1[1] = _PA[1] ; - + copy_node_xy(_A1, _PA) ; + double _B1[2] ; - _B1[0] = _PB[0] ; - _B1[1] = _PB[1] ; - + copy_node_xy(_B1, _PB) ; + double _P1[2] ; - _P1[0] = _PP[0] ; - _P1[1] = _PP[1] ; - + copy_node_xy(_P1, _PP) ; + double _s1 = geompred::orient2d ( (double*)_A1 , @@ -1533,17 +1409,14 @@ /*----------------------- get orientation in xz-plane */ double _A2[2] ; - _A2[0] = _PA[0] ; - _A2[1] = _PA[2] ; - + copy_node_xz(_A2, _PA) ; + double _B2[2] ; - _B2[0] = _PB[0] ; - _B2[1] = _PB[2] ; - + copy_node_xz(_B2, _PB) ; + double _P2[2] ; - _P2[0] = _PP[0] ; - _P2[1] = _PP[2] ; - + copy_node_xz(_P2, _PP) ; + double _s2 = geompred::orient2d ( (double*)_A2 , @@ -1552,17 +1425,14 @@ /*----------------------- get orientation in yz-plane */ double _A3[2] ; - _A3[0] = _PA[1] ; - _A3[1] = _PA[2] ; - + copy_node_yz(_A3, _PA) ; + double _B3[2] ; - _B3[0] = _PB[1] ; - _B3[1] = _PB[2] ; - + copy_node_yz(_B3, _PB) ; + double _P3[2] ; - _P3[0] = _PP[1] ; - _P3[1] = _PP[2] ; - + copy_node_yz(_P3, _PP) ; + double _s3 = geompred::orient2d ( (double*)_A3 , @@ -1588,40 +1458,32 @@ if (_sa*_sb > +0.0) { /*----------------------- have node-line intersection */ - _qq[0] = _pp[0] ; - _qq[1] = _pp[1] ; - _qq[2] = _pp[2] ; - + copy_node_3d(_qq, _pp) ; + return edge_hits ; } else if (_sa == +0.0) { /*----------------------- have node-node intersection */ - _qq[0] = _pa[0] ; - _qq[1] = _pa[1] ; - _qq[2] = _pa[2] ; - + copy_node_3d(_qq, _pa) ; + return node_hits ; } else if (_sb == +0.0) { /*----------------------- have node-node intersection */ - _qq[0] = _pb[0] ; - _qq[1] = _pb[1] ; - _qq[2] = _pb[2] ; - + copy_node_3d(_qq, _pb) ; + return node_hits ; } else if ( !_bind ) { /*----------------------- is unconstrained: edge hits */ - _qq[0] = _pp[0] ; - _qq[1] = _pp[1] ; - _qq[2] = _pp[2] ; - + copy_node_3d(_qq, _pp) ; + return edge_hits ; } else @@ -1677,20 +1539,16 @@ { /*----------------------- test line-line intersection */ double _PA[2] ; - _PA[0] = _pa[0] ; - _PA[1] = _pa[1] ; - + copy_node_2d(_PA, _pa) ; + double _PB[2] ; - _PB[0] = _pb[0] ; - _PB[1] = _pb[1] ; + copy_node_2d(_PB, _pb) ; double _PC[2] ; - _PC[0] = _pc[0] ; - _PC[1] = _pc[1] ; + copy_node_2d(_PC, _pc) ; double _PD[2] ; - _PD[0] = _pd[0] ; - _PD[1] = _pd[1] ; + copy_node_2d(_PD, _pd) ; /*----------------------- orient w.r.t. line endpoint */ double _sa = @@ -1745,8 +1603,7 @@ if (_sa == +0.0 ) { /*----------------------- have node-line intersection */ - _qq[0] = _pa[0] ; - _qq[1] = _pa[1] ; + copy_node_2d(_qq, _pa) ; return node_hits ; } @@ -1754,8 +1611,7 @@ if (_sb == +0.0 ) { /*----------------------- have node-line intersection */ - _qq[0] = _pb[0] ; - _qq[1] = _pb[1] ; + copy_node_2d(_qq, _pb) ; return node_hits ; } @@ -1763,8 +1619,7 @@ if (_sc == +0.0 ) { /*----------------------- have node-line intersection */ - _qq[0] = _pc[0] ; - _qq[1] = _pc[1] ; + copy_node_2d(_qq, _pc) ; return node_hits ; } @@ -1772,8 +1627,7 @@ if (_sd == +0.0 ) { /*----------------------- have node-line intersection */ - _qq[0] = _pd[0] ; - _qq[1] = _pd[1] ; + copy_node_2d(_qq, _pd) ; return node_hits ; } @@ -1822,21 +1676,18 @@ dd_flt _WB = 0. + _tu ; dd_flt _FA[2] ; - _FA[0] = _pa[0] ; - _FA[1] = _pa[1] ; - + copy_node_2d(_FA, _pa) ; + dd_flt _FB[2] ; - _FB[0] = _pb[0] ; - _FB[1] = _pb[1] ; - + copy_node_2d(_FB, _pb) ; + dd_flt _QQ[2] ; _QQ[0] = _FA[0] * _WA + _FB[0] * _WB ; _QQ[1] = _FA[1] * _WA + _FB[1] * _WB ; - _qq[0] = _QQ[0] ; - _qq[1] = _QQ[1] ; + copy_node_2d(_qq, _QQ) ; } else if (_part == +2) @@ -1846,21 +1697,18 @@ dd_flt _WD = 0. + _tv ; dd_flt _FC[2] ; - _FC[0] = _pc[0] ; - _FC[1] = _pc[1] ; - + copy_node_2d(_FC, _pc) ; + dd_flt _FD[2] ; - _FD[0] = _pd[0] ; - _FD[1] = _pd[1] ; - + copy_node_2d(_FD, _pd) ; + dd_flt _QQ[2] ; _QQ[0] = _FC[0] * _WC + _FD[0] * _WD ; _QQ[1] = _FC[1] * _WC + _FD[1] * _WD ; - _qq[0] = _QQ[0] ; - _qq[1] = _QQ[1] ; + copy_node_2d(_qq, _QQ) ; } else { @@ -1986,21 +1834,17 @@ { /*----------------------- test node-tria intersection */ double _PP[2] ; - _PP[0] = _pp[0] ; - _PP[1] = _pp[1] ; - + copy_node_2d(_PP, _pp) ; + double _P1[2] ; - _P1[0] = _p1[0] ; - _P1[1] = _p1[1] ; - + copy_node_2d(_P1, _p1) ; + double _P2[2] ; - _P2[0] = _p2[0] ; - _P2[1] = _p2[1] ; - + copy_node_2d(_P2, _p2) ; + double _P3[2] ; - _P3[0] = _p3[0] ; - _P3[1] = _p3[1] ; - + copy_node_2d(_P3, _p3) ; + /*----------------------- orient w.r.t. tria vertices */ double _s3 = geompred::orient2d ( @@ -2034,9 +1878,6 @@ _s3 == +0.0 ) { /*----------------------- degenerate tria: check line */ - - //!!std::cout << "node-tria-2d" << std::endl; - return null_hits ; } @@ -2045,9 +1886,8 @@ _s2 == +0.0 ) { /*----------------------- have node-node intersection */ - _qq[0] = _pp[0] ; - _qq[1] = _pp[1] ; - + copy_node_2d(_qq, _pp) ; + return node_hits ; } else @@ -2055,8 +1895,7 @@ _s3 == +0.0 ) { /*----------------------- have node-node intersection */ - _qq[0] = _pp[0] ; - _qq[1] = _pp[1] ; + copy_node_2d(_qq, _pp) ; return node_hits ; } @@ -2065,8 +1904,7 @@ _s1 == +0.0 ) { /*----------------------- have node-node intersection */ - _qq[0] = _pp[0] ; - _qq[1] = _pp[1] ; + copy_node_2d(_qq, _pp) ; return node_hits ; } @@ -2074,8 +1912,7 @@ if (_s1 == +0.0 ) { /*----------------------- have node-edge intersection */ - _qq[0] = _pp[0] ; - _qq[1] = _pp[1] ; + copy_node_2d(_qq, _pp) ; return edge_hits ; } @@ -2083,8 +1920,7 @@ if (_s2 == +0.0 ) { /*----------------------- have node-edge intersection */ - _qq[0] = _pp[0] ; - _qq[1] = _pp[1] ; + copy_node_2d(_qq, _pp) ; return edge_hits ; } @@ -2092,16 +1928,14 @@ if (_s3 == +0.0 ) { /*----------------------- have node-edge intersection */ - _qq[0] = _pp[0] ; - _qq[1] = _pp[1] ; + copy_node_2d(_qq, _pp) ; return edge_hits ; } else { /*----------------------- have node-tria intersection */ - _qq[0] = _pp[0] ; - _qq[1] = _pp[1] ; + copy_node_2d(_qq, _pp) ; return face_hits ; } @@ -2150,25 +1984,17 @@ { /*----------------------- test node-tria intersection */ double _PP[3] ; - _PP[0] = _pp[0] ; - _PP[1] = _pp[1] ; - _PP[2] = _pp[2] ; - + copy_node_3d(_PP, _pp) ; + double _P1[3] ; - _P1[0] = _p1[0] ; - _P1[1] = _p1[1] ; - _P1[2] = _p1[2] ; - + copy_node_3d(_P1, _p1) ; + double _P2[3] ; - _P2[0] = _p2[0] ; - _P2[1] = _p2[1] ; - _P2[2] = _p2[2] ; - + copy_node_3d(_P2, _p2) ; + double _P3[3] ; - _P3[0] = _p3[0] ; - _P3[1] = _p3[1] ; - _P3[2] = _p3[2] ; - + copy_node_3d(_P3, _p3) ; + double _ss = geompred::orient3d ( (double*)_P1 , @@ -2180,21 +2006,17 @@ { /*----------------------- get orientation in xy-plane */ double _TP[2] ; - _TP[0] = _PP[0] ; - _TP[1] = _PP[1] ; + copy_node_xy(_TP, _PP) ; double _T1[2] ; - _T1[0] = _P1[0] ; - _T1[1] = _P1[1] ; - + copy_node_xy(_T1, _P1) ; + double _T2[2] ; - _T2[0] = _P2[0] ; - _T2[1] = _P2[1] ; - + copy_node_xy(_T2, _P2) ; + double _T3[2] ; - _T3[0] = _P3[0] ; - _T3[1] = _P3[1] ; - + copy_node_xy(_T3, _P3) ; + double _s3[3] ; _s3[0] = geompred::orient2d ( (double*)_T1 , @@ -2222,17 +2044,13 @@ } /*----------------------- get orientation in xz-plane */ - _TP[0] = _PP[0] ; - _TP[1] = _PP[2] ; + copy_node_xz(_TP, _PP) ; - _T1[0] = _P1[0] ; - _T1[1] = _P1[2] ; + copy_node_xz(_T1, _P1) ; - _T2[0] = _P2[0] ; - _T2[1] = _P2[2] ; + copy_node_xz(_T2, _P2) ; - _T3[0] = _P3[0] ; - _T3[1] = _P3[2] ; + copy_node_xz(_T3, _P3) ; _s3[1] = geompred::orient2d ( (double*)_T1 , @@ -2258,17 +2076,13 @@ } /*----------------------- get orientation in yz-plane */ - _TP[0] = _PP[1] ; - _TP[1] = _PP[2] ; + copy_node_yz(_TP, _PP) ; - _T1[0] = _P1[1] ; - _T1[1] = _P1[2] ; + copy_node_yz(_T1, _P1) ; - _T2[0] = _P2[1] ; - _T2[1] = _P2[2] ; + copy_node_yz(_T2, _P2) ; - _T3[0] = _P3[1] ; - _T3[1] = _P3[2] ; + copy_node_yz(_T3, _P3) ; _s3[2] = geompred::orient2d ( (double*)_T1 , @@ -2312,19 +2126,13 @@ if (_z1 && _z2 && _z3 ) { /*----------------------- degenerate tria: check line */ - - //!!std::cout << "node-tria-3d" << std::endl; - return null_hits ; - } else if (_z1 && _z2 ) { /*----------------------- have node-node intersection */ - _qq[0] = _pp[0] ; - _qq[1] = _pp[1] ; - _qq[2] = _pp[2] ; + copy_node_3d(_qq, _pp) ; return edge_hits ; } @@ -2332,9 +2140,7 @@ if (_z2 && _z3 ) { /*----------------------- have node-node intersection */ - _qq[0] = _pp[0] ; - _qq[1] = _pp[1] ; - _qq[2] = _pp[2] ; + copy_node_3d(_qq, _pp) ; return node_hits ; } @@ -2342,9 +2148,7 @@ if (_z3 && _z1 ) { /*----------------------- have node-node intersection */ - _qq[0] = _pp[0] ; - _qq[1] = _pp[1] ; - _qq[2] = _pp[2] ; + copy_node_3d(_qq, _pp) ; return node_hits ; } @@ -2352,9 +2156,7 @@ if (_z1 ) { /*----------------------- have node-edge intersection */ - _qq[0] = _pp[0] ; - _qq[1] = _pp[1] ; - _qq[2] = _pp[2] ; + copy_node_3d(_qq, _pp) ; return edge_hits ; } @@ -2362,9 +2164,7 @@ if (_z2 ) { /*----------------------- have node-edge intersection */ - _qq[0] = _pp[0] ; - _qq[1] = _pp[1] ; - _qq[2] = _pp[2] ; + copy_node_3d(_qq, _pp) ; return edge_hits ; } @@ -2372,18 +2172,14 @@ if (_z3 ) { /*----------------------- have node-edge intersection */ - _qq[0] = _pp[0] ; - _qq[1] = _pp[1] ; - _qq[2] = _pp[2] ; + copy_node_3d(_qq, _pp) ; return edge_hits ; } else { /*----------------------- have node-tria intersection */ - _qq[0] = _pp[0] ; - _qq[1] = _pp[1] ; - _qq[2] = _pp[2] ; + copy_node_3d(_qq, _pp) ; return face_hits ; } @@ -2417,7 +2213,6 @@ char_type _part = +1 ) { - __unreferenced (_part); if (_pa[0] == _pb[0] && @@ -2426,7 +2221,7 @@ { /*----------------------- test node-tria intersection */ return node_tria_3d ( - _pa, _p1, _p2, _p3, _qq, _bind) ; + _pa, _p1, _p2, _p3, _qq, _bind) ; } else if (_p1[0] == _p2[0] && @@ -2459,30 +2254,20 @@ { /*----------------------- test line-tria intersection */ double _PA[3] ; - _PA[0] = _pa[0] ; - _PA[1] = _pa[1] ; - _PA[2] = _pa[2] ; - + copy_node_3d(_PA, _pa) ; + double _PB[3] ; - _PB[0] = _pb[0] ; - _PB[1] = _pb[1] ; - _PB[2] = _pb[2] ; - + copy_node_3d(_PB, _pb) ; + double _P1[3] ; - _P1[0] = _p1[0] ; - _P1[1] = _p1[1] ; - _P1[2] = _p1[2] ; - + copy_node_3d(_P1, _p1) ; + double _P2[3] ; - _P2[0] = _p2[0] ; - _P2[1] = _p2[1] ; - _P2[2] = _p2[2] ; - + copy_node_3d(_P2, _p2) ; + double _P3[3] ; - _P3[0] = _p3[0] ; - _P3[1] = _p3[1] ; - _P3[2] = _p3[2] ; - + copy_node_3d(_P3, _p3) ; + /*----------------------- test if line straddles tria */ double _sa = geompred::orient3d ( @@ -2543,10 +2328,7 @@ if (_sa == +0.0 && _sb == +0.0 ) { - // line + tria in same plane - - //!!std::cout << "line-tria-3d" << std::endl; - + // line + tria in same plane return null_hits ; } @@ -2555,9 +2337,7 @@ _s2 == +0.0 ) { /*----------------------- have line-node intersection */ - _qq[0] = _p2[0] ; - _qq[1] = _p2[1] ; - _qq[2] = _p2[2] ; + copy_node_3d(_qq, _p2) ; return node_hits ; } @@ -2566,9 +2346,7 @@ _s3 == +0.0 ) { /*----------------------- have line-node intersection */ - _qq[0] = _p3[0] ; - _qq[1] = _p3[1] ; - _qq[2] = _p3[2] ; + copy_node_3d(_qq, _p3) ; return node_hits ; } @@ -2577,9 +2355,7 @@ _s1 == +0.0 ) { /*----------------------- have line-node intersection */ - _qq[0] = _p1[0] ; - _qq[1] = _p1[1] ; - _qq[2] = _p1[2] ; + copy_node_3d(_qq, _p1) ; return node_hits ; } @@ -2592,15 +2368,11 @@ double _W2 = _s3 / _WS ; dd_flt _F1[3] ; - _F1[0] = _p1[0] ; - _F1[1] = _p1[1] ; - _F1[2] = _p1[2] ; - + copy_node_3d(_F1, _p1) ; + dd_flt _F2[3] ; - _F2[0] = _p2[0] ; - _F2[1] = _p2[1] ; - _F2[2] = _p2[2] ; - + copy_node_3d(_F2, _p2) ; + dd_flt _QQ[3] ; _QQ[0] = _F1[0] * _W1 + _F2[0] * _W2 ; @@ -2609,10 +2381,8 @@ _QQ[2] = _F1[2] * _W1 + _F2[2] * _W2 ; - _qq[0] = _QQ[0] ; - _qq[1] = _QQ[1] ; - _qq[2] = _QQ[2] ; - + copy_node_3d(_qq, _QQ) ; + return edge_hits ; } else @@ -2624,15 +2394,11 @@ double _W3 = _s1 / _WS ; dd_flt _F2[3] ; - _F2[0] = _p2[0] ; - _F2[1] = _p2[1] ; - _F2[2] = _p2[2] ; - + copy_node_3d(_F2, _p2) ; + dd_flt _F3[3] ; - _F3[0] = _p3[0] ; - _F3[1] = _p3[1] ; - _F3[2] = _p3[2] ; - + copy_node_3d(_F3, _p3) ; + dd_flt _QQ[3] ; _QQ[0] = _F2[0] * _W2 + _F3[0] * _W3 ; @@ -2641,10 +2407,8 @@ _QQ[2] = _F2[2] * _W2 + _F3[2] * _W3 ; - _qq[0] = _QQ[0] ; - _qq[1] = _QQ[1] ; - _qq[2] = _QQ[2] ; - + copy_node_3d(_qq, _QQ) ; + return edge_hits ; } else @@ -2656,15 +2420,11 @@ double _W1 = _s2 / _WS ; dd_flt _F3[3] ; - _F3[0] = _p3[0] ; - _F3[1] = _p3[1] ; - _F3[2] = _p3[2] ; - + copy_node_3d(_F3, _p3) ; + dd_flt _F1[3] ; - _F1[0] = _p1[0] ; - _F1[1] = _p1[1] ; - _F1[2] = _p1[2] ; - + copy_node_3d(_F1, _p1) ; + dd_flt _QQ[3] ; _QQ[0] = _F3[0] * _W3 + _F1[0] * _W1 ; @@ -2673,10 +2433,8 @@ _QQ[2] = _F3[2] * _W3 + _F1[2] * _W1 ; - _qq[0] = _QQ[0] ; - _qq[1] = _QQ[1] ; - _qq[2] = _QQ[2] ; - + copy_node_3d(_qq, _QQ) ; + return edge_hits ; } else @@ -2688,20 +2446,14 @@ double _W3 = _s1 / _WS ; dd_flt _F1[3] ; - _F1[0] = _p1[0] ; - _F1[1] = _p1[1] ; - _F1[2] = _p1[2] ; - + copy_node_3d(_F1, _p1) ; + dd_flt _F2[3] ; - _F2[0] = _p2[0] ; - _F2[1] = _p2[1] ; - _F2[2] = _p2[2] ; - + copy_node_3d(_F2, _p2) ; + dd_flt _F3[3] ; - _F3[0] = _p3[0] ; - _F3[1] = _p3[1] ; - _F3[2] = _p3[2] ; - + copy_node_3d(_F3, _p3) ; + dd_flt _QQ[3] ; _QQ[0] = _F1[0] * _W1 + _F2[0] * _W2 + @@ -2713,10 +2465,8 @@ _F2[2] * _W2 + _F3[2] * _W3 ; - _qq[0] = _QQ[0] ; - _qq[1] = _QQ[1] ; - _qq[2] = _QQ[2] ; - + copy_node_3d(_qq, _QQ) ; + return face_hits ; } } diff --git a/src/libcpp/geom_reps/geom_base_2.hpp b/src/libcpp/geom_reps/geom_base_2.hpp index 364c564..f246478 100644 --- a/src/libcpp/geom_reps/geom_base_2.hpp +++ b/src/libcpp/geom_reps/geom_base_2.hpp @@ -35,9 +35,9 @@ * -------------------------------------------------------- * - * Last updated: 01 Feb., 2021 + * Last updated: 21 Jan., 2024 * - * Copyright 2013-2021 + * Copyright 2013-2024 * Darren Engwirda * d.engwirda@gmail.com * https://github.com/dengwirda/ @@ -118,14 +118,17 @@ template < typename mesh_type , + typename hfun_type , typename user_opts > __normal_call void_type seed_mesh ( mesh_type &_mesh, + hfun_type &_hfun, user_opts &_opts ) { __unreferenced(_mesh) ; + __unreferenced(_hfun) ; __unreferenced(_opts) ; } @@ -137,14 +140,17 @@ template < typename mesh_type , + typename hfun_type , typename user_opts > __normal_call void_type seed_feat ( mesh_type &_mesh, + hfun_type &_hfun, user_opts &_opts ) { __unreferenced(_mesh) ; + __unreferenced(_hfun) ; __unreferenced(_opts) ; } diff --git a/src/libcpp/geom_reps/geom_base_3.hpp b/src/libcpp/geom_reps/geom_base_3.hpp index 116aadc..b7ae48c 100644 --- a/src/libcpp/geom_reps/geom_base_3.hpp +++ b/src/libcpp/geom_reps/geom_base_3.hpp @@ -35,9 +35,9 @@ * -------------------------------------------------------- * - * Last updated: 01 Feb., 2021 + * Last updated: 21 Jan., 2024 * - * Copyright 2013-2021 + * Copyright 2013-2024 * Darren Engwirda * d.engwirda@gmail.com * https://github.com/dengwirda/ @@ -135,14 +135,17 @@ template < typename mesh_type , + typename hfun_type , typename user_opts > __normal_call void_type seed_mesh ( mesh_type &_mesh, + hfun_type &_hfun, user_opts &_opts ) { __unreferenced(_mesh) ; + __unreferenced(_hfun) ; __unreferenced(_opts) ; } @@ -154,14 +157,17 @@ template < typename mesh_type , + typename hfun_type , typename user_opts > __normal_call void_type seed_feat ( mesh_type &_mesh, + hfun_type &_hfun, user_opts &_opts ) { __unreferenced(_mesh) ; + __unreferenced(_hfun) ; __unreferenced(_opts) ; } diff --git a/src/libcpp/geom_reps/geom_mesh_ellipsoid_3.hpp b/src/libcpp/geom_reps/geom_mesh_ellipsoid_3.hpp index b5b9e2c..2cc7d4f 100644 --- a/src/libcpp/geom_reps/geom_mesh_ellipsoid_3.hpp +++ b/src/libcpp/geom_reps/geom_mesh_ellipsoid_3.hpp @@ -35,9 +35,9 @@ * -------------------------------------------------------- * - * Last updated: 18 Aug., 2021 + * Last updated: 26 Feb., 2025 * - * Copyright 2013-2021 + * Copyright 2013-2025 * Darren Engwirda * d.engwirda@gmail.com * https://github.com/dengwirda/ @@ -328,7 +328,7 @@ ) { /*------------ "sharp" geometry//topology about node? */ - real_type _DtoR = + real_type constexpr _DtoR = (real_type)+3.141592653589793 / 180. ; real_type _ZERO = -1. + @@ -360,10 +360,19 @@ _jpos != _aset.tend() ; ++_jpos ) { - /*------------ find signed angle between edge vectors */ auto _iedg = _ipos->_cell ; auto _jedg = _jpos->_cell ; + /*------------ tag as soft feature if dissimilar tags */ + auto _itag = + this->_mesh.edge(_iedg).itag () ; + auto _jtag = + this->_mesh.edge(_jedg).itag () ; + + if (_itag != _jtag) + _feat = std::max(_feat, soft_feat) ; + + /*------------ find signed angle between edge vectors */ iptr_type _inod[2] = { this->_mesh.edge(_iedg).node(0) , this->_mesh.edge(_iedg).node(1) , @@ -416,10 +425,7 @@ } else { - if (_tbad >= + 1 ) - { - _topo -= _tbad-- ; - } + if (_tbad >= 1) _topo -= _tbad-- ; } } } @@ -697,14 +703,17 @@ template < typename mesh_type , + typename hfun_type , typename user_opts > __normal_call void_type seed_feat ( mesh_type &_rdel , + hfun_type &_hfun , user_opts &_opts ) { __unreferenced(_opts) ; + __unreferenced(_hfun) ; /*------------------------- push set of feature nodes */ for (auto _iter = @@ -1072,13 +1081,29 @@ template < typename mesh_type , + typename hfun_type , typename user_opts > __normal_call void_type seed_mesh ( mesh_type &_rdel , + hfun_type &_hfun , user_opts &_opts ) { + /*------------------------- eval. h(x) func. on nodes */ + containers::array _spac( + this->_mesh.node().count(), 0) ; + iptr_type _npos = 0 ; + for (auto _node = + this->_mesh.node().head() ; + _node != + this->_mesh.node().tend() ; + ++_node, ++_npos) + { + _spac[_npos] = + _hfun.eval(&_node->pval(+0)); + } + /*------------------------- well-distributed sampling */ while (_rdel._tria._nset.count() < (std::size_t)_opts.seed() + 5) @@ -1088,11 +1113,12 @@ node_list::_write_it _best ; real_type _dmax = (real_type) +.0 ; + iptr_type _inum = 0 ; for (auto _ipos = this->_mesh.node().head() ; _ipos != this->_mesh.node().tend() ; - ++_ipos ) + ++_ipos, ++_inum) { /*------------------------- get current furthest node */ if (_ipos->mark() >= 0) @@ -1101,16 +1127,19 @@ +std::numeric_limits ::infinity(); + iptr_type _jnum = 0 ; for (auto _jpos = _rdel._tria._nset.head() ; _jpos != _rdel._tria._nset.tend() ; - ++_jpos ) + ++_jpos, ++_jnum) { real_type _dist = geometry::lensqr_3d( &_ipos->pval(+0), &_jpos->pval(+0)) ; + + _dist/= _spac [_inum] ; _dmin = std::min(_dmin, _dist); } diff --git a/src/libcpp/geom_reps/geom_mesh_euclidean_2.hpp b/src/libcpp/geom_reps/geom_mesh_euclidean_2.hpp index ae17fff..1ffa69f 100644 --- a/src/libcpp/geom_reps/geom_mesh_euclidean_2.hpp +++ b/src/libcpp/geom_reps/geom_mesh_euclidean_2.hpp @@ -35,9 +35,9 @@ * -------------------------------------------------------- * - * Last updated: 18 Aug., 2021 + * Last updated: 26 Feb., 2025 * - * Copyright 2013-2021 + * Copyright 2013-2025 * Darren Engwirda * d.engwirda@gmail.com * https://github.com/dengwirda/ @@ -414,7 +414,7 @@ ) { /*------------ "sharp" geometry//topology about node? */ - real_type _DtoR = + real_type constexpr _DtoR = (real_type)+3.141592653589793 / 180. ; real_type _ZERO = -1. + @@ -446,10 +446,19 @@ _jpos != _aset.tend() ; ++_jpos ) { - /*------------ find signed angle between edge vectors */ auto _iedg = _ipos->_cell ; auto _jedg = _jpos->_cell ; + /*------------ tag as soft feature if dissimilar tags */ + auto _itag = + this->_tria.edge(_iedg).itag () ; + auto _jtag = + this->_tria.edge(_jedg).itag () ; + + if (_itag != _jtag) + _feat = std::max(_feat, soft_feat) ; + + /*------------ find signed angle between edge vectors */ iptr_type _inod[2] = { this->_tria.edge(_iedg).node(0) , this->_tria.edge(_iedg).node(1) , @@ -502,10 +511,7 @@ } else { - if (_tbad >= + 1 ) - { - _topo -= _tbad-- ; - } + if (_tbad >= 1) _topo -= _tbad-- ; } } } @@ -876,15 +882,18 @@ template < typename mesh_type , + typename hfun_type , typename user_opts > __normal_call void_type seed_feat ( mesh_type &_mesh , + hfun_type &_hfun , user_opts &_opts ) { + __unreferenced(_hfun) ; __unreferenced(_opts) ; - + /*------------------------- push set of feature nodes */ for (auto _iter = this->_tria.node().head() ; @@ -973,13 +982,29 @@ template < typename mesh_type , + typename hfun_type , typename user_opts > __normal_call void_type seed_mesh ( mesh_type &_mesh , + hfun_type &_hfun , user_opts &_opts ) { + /*------------------------- eval. h(x) func. on nodes */ + containers::array _spac( + this->_tria.node().count(), 0) ; + iptr_type _npos = 0 ; + for (auto _node = + this->_tria.node().head() ; + _node != + this->_tria.node().tend() ; + ++_node, ++_npos) + { + _spac[_npos] = + _hfun.eval(&_node->pval(+0)); + } + /*------------------------- well-distributed sampling */ while (_mesh._tria._nset.count() < (std::size_t)_opts.seed() + 3) @@ -993,11 +1018,12 @@ for (_fdim = 1; _fdim != 3; ++_fdim) { + iptr_type _inum = 0 ; for (auto _ipos = this->_tria.node().head() ; _ipos != this->_tria.node().tend() ; - ++_ipos ) + ++_ipos, ++_inum) { /*------------------------- get current furthest node */ if (_ipos->mark() >= 0 && @@ -1007,17 +1033,20 @@ +std::numeric_limits ::infinity(); + iptr_type _jnum = 0 ; for (auto _jpos = _mesh._tria._nset.head() ; _jpos != _mesh._tria._nset.tend() ; - ++_jpos ) + ++_jpos, ++_jnum) { real_type _dist = geometry::lensqr_2d( &_ipos->pval(+0), &_jpos->pval(+0)) ; + _dist/= _spac [_inum] ; + _dmin = std::min(_dmin, _dist); } diff --git a/src/libcpp/geom_reps/geom_mesh_euclidean_3.hpp b/src/libcpp/geom_reps/geom_mesh_euclidean_3.hpp index 202dcf3..5de30db 100644 --- a/src/libcpp/geom_reps/geom_mesh_euclidean_3.hpp +++ b/src/libcpp/geom_reps/geom_mesh_euclidean_3.hpp @@ -35,9 +35,9 @@ * -------------------------------------------------------- * - * Last updated: 18 Aug., 2021 + * Last updated: 26 Feb., 2025 * - * Copyright 2013-2021 + * Copyright 2013-2025 * Darren Engwirda * d.engwirda@gmail.com * https://github.com/dengwirda/ @@ -500,7 +500,7 @@ ) { /*------------ "sharp" geometry//topology about node? */ - real_type _DtoR = + real_type constexpr _DtoR = (real_type)+3.141592653589793 / 180. ; real_type _ZERO = -1. + @@ -532,10 +532,19 @@ _jpos != _aset.tend() ; ++_jpos ) { - /*------------ find signed angle between edge vectors */ auto _iedg = _ipos->_cell ; auto _jedg = _jpos->_cell ; + /*------------ tag as soft feature if dissimilar tags */ + auto _itag = + this->_tria.edge(_iedg).itag () ; + auto _jtag = + this->_tria.edge(_jedg).itag () ; + + if (_itag != _jtag) + _feat = std::max(_feat, soft_feat) ; + + /*------------ find signed angle between edge vectors */ iptr_type _inod[2] = { this->_tria.edge(_iedg).node(0) , this->_tria.edge(_iedg).node(1) , @@ -588,10 +597,7 @@ } else { - if (_tbad >= + 1 ) - { - _topo -= _tbad-- ; - } + if (_tbad >= 1) _topo -= _tbad-- ; } } } @@ -624,7 +630,7 @@ /*------------ "sharp" geometry//topology about node? */ char_type _feat = null_feat ; - real_type _DtoR = + real_type constexpr _DtoR = (real_type)+3.141592653589793 / 180. ; real_type _phi1 = @@ -733,7 +739,7 @@ ) { /*------------ "sharp" geometry//topology about edge? */ - real_type _DtoR = + real_type constexpr _DtoR = (real_type)+3.141592653589793 / 180. ; real_type _ZERO = -1. + @@ -763,32 +769,37 @@ _jpos != _aset.tend() ; ++_jpos ) { - /*------------ find signed angle between cell normals */ auto _itri = _ipos->_cell ; auto _jtri = _jpos->_cell ; + /*------------ tag as soft feature if dissimilar tags */ + auto _itag = + this->_tria.tri3(_itri).itag () ; + auto _jtag = + this->_tria.tri3(_jtri).itag () ; + + if (_itag != _jtag) + _feat = std::max (_feat, soft_feat) ; + + /*------------ find signed angle between cell normals */ iptr_type _inod[3], _iloc ; for (_iloc = 3; _iloc-- != 0; ) { tri3_type::face_node ( - _inod, _iloc, +2, +1) ; + _inod, _iloc, +2, +1) ; _inod[0] = this->_tria. - tri3(_itri).node(_inod[0]) ; + tri3(_itri).node(_inod[0]) ; _inod[1] = this->_tria. - tri3(_itri).node(_inod[1]) ; + tri3(_itri).node(_inod[1]) ; _inod[2] = this->_tria. - tri3(_itri).node(_inod[2]) ; + 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 (_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 ; } @@ -797,24 +808,20 @@ for (_jloc = 3; _jloc-- != 0; ) { tri3_type::face_node ( - _jnod, _jloc, +2, +1) ; + _jnod, _jloc, +2, +1) ; _jnod[0] = this->_tria. - tri3(_jtri).node(_jnod[0]) ; + tri3(_jtri).node(_jnod[0]) ; _jnod[1] = this->_tria. - tri3(_jtri).node(_jnod[1]) ; + tri3(_jtri).node(_jnod[1]) ; _jnod[2] = this->_tria. - tri3(_jtri).node(_jnod[2]) ; + 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 (_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 ; } @@ -865,10 +872,7 @@ } else { - if (_tbad >= + 1 ) - { - _topo -= _tbad-- ; - } + if (_tbad >= 1) _topo -= _tbad-- ; } } } @@ -1393,13 +1397,16 @@ template < typename mesh_type , + typename hfun_type , typename user_opts > __normal_call void_type seed_feat ( mesh_type &_mesh , + hfun_type &_hfun , user_opts &_opts ) { + __unreferenced(_hfun) ; __unreferenced(_opts) ; /*------------------------- push set of feature nodes */ @@ -1492,13 +1499,29 @@ template < typename mesh_type , + typename hfun_type , typename user_opts > __normal_call void_type seed_mesh ( mesh_type &_mesh , + hfun_type &_hfun , user_opts &_opts ) { + /*------------------------- eval. h(x) func. on nodes */ + containers::array _spac( + this->_tria.node().count(), 0) ; + iptr_type _npos = 0 ; + for (auto _node = + this->_tria.node().head() ; + _node != + this->_tria.node().tend() ; + ++_node, ++_npos) + { + _spac[_npos] = + _hfun.eval(&_node->pval(+0)); + } + /*------------------------- well-distributed sampling */ while (_mesh._tria._nset.count() < (std::size_t)_opts.seed() + 4) @@ -1512,11 +1535,12 @@ for (_fdim = 1; _fdim != 4; ++_fdim) { + iptr_type _inum = 0 ; for (auto _ipos = this->_tria.node().head() ; _ipos != this->_tria.node().tend() ; - ++_ipos ) + ++_ipos, ++_inum) { /*------------------------- get current furthest node */ if (_ipos->mark() >= 0 && @@ -1526,16 +1550,19 @@ +std::numeric_limits ::infinity(); + iptr_type _jnum = 0 ; for (auto _jpos = _mesh._tria._nset.head() ; _jpos != _mesh._tria._nset.tend() ; - ++_jpos ) + ++_jpos, ++_jnum) { real_type _dist = geometry::lensqr_3d( &_ipos->pval(+0), &_jpos->pval(+0)) ; + + _dist/= _spac [_inum] ; _dmin = std::min(_dmin, _dist); } diff --git a/src/libcpp/interpolate/hfun_base_k.hpp b/src/libcpp/interpolate/hfun_base_k.hpp index c637b18..f0360fe 100644 --- a/src/libcpp/interpolate/hfun_base_k.hpp +++ b/src/libcpp/interpolate/hfun_base_k.hpp @@ -35,9 +35,9 @@ * -------------------------------------------------------- * - * Last updated: 30 Jun., 2019 + * Last updated: 21 Jan., 2024 * - * Copyright 2013-2019 + * Copyright 2013-2024 * Darren Engwirda * d.engwirda@gmail.com * https://github.com/dengwirda/ @@ -83,16 +83,17 @@ __normal_call void_type clip ( ) {} - __normal_call void_type eval ( - real_type/*_ppos*/ , - hint_type/*_hint*/ - ) {} + __inline_call real_type eval ( + real_type * /*_ppos*/ + ) + { return ( (real_type) 0. ); + } __inline_call real_type eval ( - real_type *_ppos , - hint_type&&_hint = null_hint () + real_type * /*_ppos*/ , + hint_type & /*_hint*/ ) - { return eval(_ppos, _hint); + { return ( (real_type) 0. ); } } ; diff --git a/src/libcpp/interpolate/hfun_clip_k.hpp b/src/libcpp/interpolate/hfun_clip_k.hpp index 1772655..884155b 100644 --- a/src/libcpp/interpolate/hfun_clip_k.hpp +++ b/src/libcpp/interpolate/hfun_clip_k.hpp @@ -35,9 +35,9 @@ * -------------------------------------------------------- * - * Last updated: 29 Jun., 2022 + * Last updated: 20 Oct., 2024 * - * Copyright 2013-2022 + * Copyright 2013-2024 * Darren Engwirda * d.engwirda@gmail.com * https://github.com/dengwirda @@ -165,7 +165,7 @@ _p1, _h1, _g1, _p3, _h3, _g3) - | EIKONAL_edge_2d ( + || EIKONAL_edge_2d ( _p2, _h2, _g2, _p3, _h3, _g3) ; } @@ -271,7 +271,7 @@ _p1, _h1, _g1, _p3, _h3, _g3) - | EIKONAL_edge_3d ( + || EIKONAL_edge_3d ( _p2, _h2, _g2, _p3, _h3, _g3) ; } @@ -326,7 +326,186 @@ typename real_type , typename vals_type > - __normal_call bool_type eikonal_edge_2d ( + __normal_call bool_type EIKONAL_tria_3d ( + __const_ptr (real_type) _p1 , + vals_type _h1 , + vals_type _g1 , + __const_ptr (real_type) _p2 , + vals_type _h2 , + vals_type _g2 , + __const_ptr (real_type) _p3 , + vals_type _h3 , + vals_type _g3 , + __const_ptr (real_type) _p4 , + vals_type& _h4 , + vals_type _g4 + ) + { + vals_type _gg = + (_g1+_g2+_g3+_g4)/(vals_type)4. ; + + /*---------------------- form "limited" extrap. to P4 */ + real_type _pa[3]; + real_type _pb[3]; + real_type _pc[3]; + geometry:: + vector_3d (_p1, _p3, _pa) ; + geometry:: + vector_3d (_p2, _p3, _pb) ; + geometry:: + vector_3d (_p3, _p4, _pc) ; + + vals_type _ha =_h1- _h3; + vals_type _hb =_h2- _h3; + + real_type _aa = + geometry:: dot_3d(_pa, _pa) ; + real_type _ab = + geometry:: dot_3d(_pa, _pb) ; + real_type _ac = + geometry:: dot_3d(_pa, _pc) ; + real_type _bb = + geometry:: dot_3d(_pb, _pb) ; + real_type _bc = + geometry:: dot_3d(_pb, _pc) ; + real_type _cc = + geometry:: dot_3d(_pc, _pc) ; + + /*---------------------- local gradient descent soln. */ + vals_type _hm, _hn = + std::numeric_limits::infinity() ; + + real_type _ss = (real_type) .5; + real_type _uu = (real_type) 1. / 3. ; + real_type _vv = (real_type) 1. / 3. ; + real_type _ww = (real_type) 1. - _uu - _vv ; + + // init. from best of base midpoint, and adj. faces + real_type _pi[3] = { + _p1[0]*_uu+_p2[0]*_vv+_p3[0]*_ww , + _p1[1]*_uu+_p2[1]*_vv+_p3[1]*_ww , + _p1[2]*_uu+_p2[2]*_vv+_p3[2]*_ww + } ; + + _hn = (vals_type) ( + _h1*_uu + _h2*_vv + _h3*_ww + + _gg * geometry::length_3d(_pi, _p4) ) ; + + if (EIKONAL_tria_3d(_p1, _h1, _g1, + _p2, _h2, _g2, + _p4, _hn, _g4) ) + { + _uu = (real_type)0.; + _vv = (real_type).5; + } + + if (EIKONAL_tria_3d(_p2, _h2, _g2, + _p3, _h3, _g3, + _p4, _hn, _g4) ) + { + _uu = (real_type).5; + _vv = (real_type)0.; + } + + if (EIKONAL_tria_3d(_p3, _h3, _g3, + _p1, _h1, _g1, + _p4, _hn, _g4) ) + { + _uu = (real_type).5; + _vv = (real_type).5; + } + + for (auto _iter = 8; _iter-- != +0; ) + { + /*---------------------- analytical gradients + soln. */ + real_type _dd = _aa * _uu * _uu + + _bb * _vv * _vv + + 2. * _ab * _uu * _vv + + 2. * _ac * _uu + + 2. * _bc * _vv + _cc ; + + real_type _du = + 2. * _aa * _uu + + 2. * _ab * _vv + 2. *_ac ; + real_type _dv = + 2. * _bb * _vv + + 2. * _ab * _uu + 2. *_bc ; + + _dd = std::sqrt(_dd); + _du = _ha + .5* _gg * _du / _dd ; + _dv = _hb + .5* _gg * _dv / _dd ; + + /*---------------------- local line-search relaxation */ + bool _up = false; + for (auto _line = 4; _line-- != +0; ) + { + real_type _tt = +1. ; + real_type _un = _uu - _ss * _du ; + real_type _vn = _vv - _ss * _dv ; + + /*---------------------- keep [u,v] in base of tetra. */ + if (1. - _un - _vn < 0.) + _tt = std::min( + _tt, (_uu + _vv - 1.) / (_du + _dv) / _ss) ; + + if (_un < 0.) + _tt = std::min( + _tt, (0. + _uu) / (_uu - _un)); + + if (_un > 1.) + _tt = std::min( + _tt, (1. - _uu) / (_un - _uu)); + + if (_vn < 0.) + _tt = std::min( + _tt, (0. + _vv) / (_vv - _vn)); + + if (_vn > 1.) + _tt = std::min( + _tt, (1. - _vv) / (_vn - _vv)); + + _ss = _ss * std::max(0., _tt) ; + + /*---------------------- eval. extrap. from new [u,v] */ + real_type _um = _uu - _ss * _du ; + real_type _vm = _vv - _ss * _dv ; + + real_type _dm = _aa * _um * _um + + _bb * _vm * _vm + + 2. * _ab * _um * _vm + + 2. * _ac * _um + + 2. * _bc * _vm + _cc ; + + _hm = (vals_type)( + _ha * _um + _hb * _vm + _h3 + + _gg * std::sqrt(_dm)) ; + + if (_hm < _hn || _ss <= 0.) + { + /*---------------------- move on to new better optima */ + _uu = _um; _vv = _vm; _hn = _hm; + _up = true; break ; + } + else { _ss *= (real_type).5; } + } + /*---------------------- done if stuck or on boundary */ + if (!_up || _ss <= 0.) break ; + /*---------------------- update length for next outer */ + _ss *= (real_type)+2.; + } + /*---------------------- update if extrap. does limit */ + if (_hn < _h4) + { + _h4 = _hn; return true; + } + else/*no clip*/return false; + } + + template < + typename real_type , + typename vals_type + > + __inline_call bool_type eikonal_edge_2d ( __const_ptr (real_type) _p1 , __const_ptr (real_type) _p2 , vals_type _hb , // current anchor @@ -339,23 +518,23 @@ /*---------------------- limit h-values within EDGE-2 */ bool_type _clip = false ; - if (_h2 > _hb) + if (_h1 >=(vals_type)+0. && + _h2 >=(vals_type)+0. ) + { + if (_h2 > _hb) /*--------------------------------- 1st node ordering */ - if (_h1 >=(vals_type)+0. && - _h2 >=(vals_type)+0. ) if (EIKONAL_edge_2d ( _p1, _h1, _g1 , _p2, _h2, _g2 ) ) _clip = true ; - if (_h1 > _hb) + if (_h1 > _hb) /*--------------------------------- 2nd node ordering */ - if (_h1 >=(vals_type)+0. && - _h2 >=(vals_type)+0. ) if (EIKONAL_edge_2d ( _p2, _h2, _g2 , _p1, _h1, _g1 ) ) _clip = true ; + } return ( _clip ) ; } @@ -364,7 +543,7 @@ typename real_type , typename vals_type > - __normal_call bool_type eikonal_edge_3d ( + __inline_call bool_type eikonal_edge_3d ( __const_ptr (real_type) _p1 , __const_ptr (real_type) _p2 , vals_type _hb , // current anchor @@ -377,23 +556,23 @@ /*---------------------- limit h-values within EDGE-2 */ bool_type _clip = false ; - if (_h2 > _hb) + if (_h1 >=(vals_type)+0. && + _h2 >=(vals_type)+0. ) + { + if (_h2 > _hb) /*--------------------------------- 1st node ordering */ - if (_h1 >=(vals_type)+0. && - _h2 >=(vals_type)+0. ) if (EIKONAL_edge_3d ( _p1, _h1, _g1 , _p2, _h2, _g2 ) ) _clip = true ; - if (_h1 > _hb) + if (_h1 > _hb) /*--------------------------------- 2nd node ordering */ - if (_h1 >=(vals_type)+0. && - _h2 >=(vals_type)+0. ) if (EIKONAL_edge_3d ( _p2, _h2, _g2 , _p1, _h1, _g1 ) ) _clip = true ; + } return ( _clip ) ; } @@ -402,7 +581,7 @@ typename real_type , typename vals_type > - __normal_call bool_type eikonal_tria_2d ( + __inline_call bool_type eikonal_tria_2d ( __const_ptr (real_type) _p1 , __const_ptr (real_type) _p2 , __const_ptr (real_type) _p3 , @@ -418,38 +597,34 @@ /*---------------------- limit h-values within TRIA-3 */ bool_type _clip = false ; - if (_h3 > _hb) + if (_h1 >=(vals_type)+0. && + _h2 >=(vals_type)+0. && + _h3 >=(vals_type)+0. ) + { + if (_h3 > _hb) /*--------------------------------- 1st node ordering */ - if (_h1 >=(vals_type)+0. && - _h2 >=(vals_type)+0. && - _h3 >=(vals_type)+0. ) if (EIKONAL_tria_2d ( _p1, _h1, _g1 , _p2, _h2, _g2 , _p3, _h3, _g3 ) ) _clip = true ; - if (_h1 > _hb) + if (_h1 > _hb) /*--------------------------------- 2nd node ordering */ - if (_h1 >=(vals_type)+0. && - _h2 >=(vals_type)+0. && - _h3 >=(vals_type)+0. ) if (EIKONAL_tria_2d ( _p2, _h2, _g2 , _p3, _h3, _g3 , _p1, _h1, _g1 ) ) _clip = true ; - if (_h2 > _hb) + if (_h2 > _hb) /*--------------------------------- 3rd node ordering */ - if (_h1 >=(vals_type)+0. && - _h2 >=(vals_type)+0. && - _h3 >=(vals_type)+0. ) if (EIKONAL_tria_2d ( _p3, _h3, _g3 , _p1, _h1, _g1 , _p2, _h2, _g2 ) ) _clip = true ; + } return ( _clip ) ; } @@ -458,7 +633,7 @@ typename real_type , typename vals_type > - __normal_call bool_type eikonal_tria_3d ( + __inline_call bool_type eikonal_tria_3d ( __const_ptr (real_type) _p1 , __const_ptr (real_type) _p2 , __const_ptr (real_type) _p3 , @@ -474,39 +649,103 @@ /*---------------------- limit h-values within TRIA-3 */ bool_type _clip = false ; - if (_h3 > _hb) + if (_h1 >=(vals_type)+0. && + _h2 >=(vals_type)+0. && + _h3 >=(vals_type)+0. ) + { + if (_h3 > _hb) /*--------------------------------- 1st node ordering */ - if (_h1 >=(vals_type)+0. && - _h2 >=(vals_type)+0. && - _h3 >=(vals_type)+0. ) if (EIKONAL_tria_3d ( _p1, _h1, _g1 , _p2, _h2, _g2 , _p3, _h3, _g3 ) ) _clip = true ; - if (_h1 > _hb) + if (_h1 > _hb) /*--------------------------------- 2nd node ordering */ - if (_h1 >=(vals_type)+0. && - _h2 >=(vals_type)+0. && - _h3 >=(vals_type)+0. ) if (EIKONAL_tria_3d ( _p2, _h2, _g2 , _p3, _h3, _g3 , _p1, _h1, _g1 ) ) _clip = true ; - if (_h2 > _hb) + if (_h2 > _hb) /*--------------------------------- 3rd node ordering */ - if (_h1 >=(vals_type)+0. && - _h2 >=(vals_type)+0. && - _h3 >=(vals_type)+0. ) if (EIKONAL_tria_3d ( _p3, _h3, _g3 , _p1, _h1, _g1 , _p2, _h2, _g2 ) ) _clip = true ; + } + + return ( _clip ) ; + } + + template < + typename real_type , + typename vals_type + > + __inline_call bool_type eikonal_tria_3d ( + __const_ptr (real_type) _p1 , + __const_ptr (real_type) _p2 , + __const_ptr (real_type) _p3 , + __const_ptr (real_type) _p4 , + vals_type _hb , // current anchor + vals_type& _h1 , + vals_type& _h2 , + vals_type& _h3 , + vals_type& _h4 , + vals_type _g1 , + vals_type _g2 , + vals_type _g3 , + vals_type _g4 + ) + { + /*---------------------- limit h-values within TRIA-4 */ + bool_type _clip = false ; + + if (_h1 >=(vals_type)+0. && + _h2 >=(vals_type)+0. && + _h3 >=(vals_type)+0. && + _h4 >=(vals_type)+0. ) + { + if (_h4 > _hb) + /*--------------------------------- 1st node ordering */ + if (EIKONAL_tria_3d ( + _p1, _h1, _g1 , + _p2, _h2, _g2 , + _p3, _h3, _g3 , + _p4, _h4, _g4 ) ) + _clip = true ; + + if (_h1 > _hb) + /*--------------------------------- 2nd node ordering */ + if (EIKONAL_tria_3d ( + _p2, _h2, _g2 , + _p3, _h3, _g3 , + _p4, _h4, _g4 , + _p1, _h1, _g1 ) ) + _clip = true ; + if (_h2 > _hb) + /*--------------------------------- 3rd node ordering */ + if (EIKONAL_tria_3d ( + _p3, _h3, _g3 , + _p1, _h1, _g1 , + _p4, _h4, _g4 , + _p2, _h2, _g2 ) ) + _clip = true ; + + if (_h3 > _hb) + /*--------------------------------- 4th node ordering */ + if (EIKONAL_tria_3d ( + _p1, _h1, _g1 , + _p2, _h2, _g2 , + _p4, _h4, _g4 , + _p3, _h3, _g3 ) ) + _clip = true ; + } + return ( _clip ) ; } @@ -617,7 +856,7 @@ typename real_type , typename vals_type > - __normal_call bool_type eikonal_grid_2d ( + __inline_call bool_type eikonal_grid_2d ( __const_ptr (real_type) _p1 , __const_ptr (real_type) _p2 , __const_ptr (real_type) _p3 , @@ -635,8 +874,6 @@ { /*---------------------- limit h-values within GRID-4 */ bool_type _clip = false ; - - if (true) { /*--------------------------------- 1st tria ordering */ if (eikonal_tria_2d ( @@ -650,10 +887,7 @@ _h1, _h3, _h4 , _g1, _g3, _g4 ) ) _clip = true ; - } - - if (true) - { + /*--------------------------------- 2nd tria ordering */ if (eikonal_tria_2d ( _p1, _p2, _p4 , _hb, @@ -784,7 +1018,7 @@ typename real_type , typename vals_type > - __normal_call bool_type eikonal_grid_3d ( + __inline_call bool_type eikonal_grid_3d ( __const_ptr (real_type) _p1 , __const_ptr (real_type) _p2 , __const_ptr (real_type) _p3 , @@ -802,8 +1036,6 @@ { /*---------------------- limit h-values within GRID-4 */ bool_type _clip = false ; - - if (true) { /*--------------------------------- 1st tria ordering */ if (eikonal_tria_3d ( @@ -817,10 +1049,7 @@ _h1, _h3, _h4 , _g1, _g3, _g4 ) ) _clip = true ; - } - - if (true) - { + /*--------------------------------- 2nd tria ordering */ if (eikonal_tria_3d ( _p1, _p2, _p4 , _hb, @@ -842,23 +1071,274 @@ typename real_type , typename vals_type > - __normal_call bool_type eikonal_tria_3d ( - __const_ptr (real_type) /*_p1*/ , - __const_ptr (real_type) /*_p2*/ , - __const_ptr (real_type) /*_p3*/ , - __const_ptr (real_type) /*_p4*/ , - vals_type /*_hb*/ , // current anchor - vals_type& /*_h1*/ , - vals_type& /*_h2*/ , - vals_type& /*_h3*/ , - vals_type& /*_h4*/ , - vals_type /*_g1*/ , - vals_type /*_g2*/ , - vals_type /*_g3*/ , - vals_type /*_g4*/ + __inline_call bool_type eikonal_pyra_3d ( + __const_ptr (real_type) _p1 , + __const_ptr (real_type) _p2 , + __const_ptr (real_type) _p3 , + __const_ptr (real_type) _p4 , + __const_ptr (real_type) _p5 , + vals_type _hb , // current anchor + vals_type& _h1 , + vals_type& _h2 , + vals_type& _h3 , + vals_type& _h4 , + vals_type& _h5 , + vals_type _g1 , + vals_type _g2 , + vals_type _g3 , + vals_type _g4 , + vals_type _g5 ) { - return false ; + /*---------------------- limit h-values within PYRA-5 */ + bool_type _clip = false ; + { + /*--------------------------------- 1st base ordering */ + if (eikonal_tria_3d ( + _p1, _p2, _p3, _p5, _hb, + _h1, _h2, _h3, _h5, + _g1, _g2, _g3, _g5) ) + _clip = true ; + + if (eikonal_tria_3d ( + _p1, _p3, _p4, _p5, _hb, + _h1, _h3, _h4, _h5, + _g1, _g3, _g4, _g5) ) + _clip = true ; + + /*--------------------------------- 2nd base ordering */ + if (eikonal_tria_3d ( + _p1, _p2, _p4, _p5, _hb, + _h1, _h2, _h4, _h5, + _g1, _g2, _g4, _g5) ) + _clip = true ; + + if (eikonal_tria_3d ( + _p2, _p3, _p4, _p5, _hb, + _h2, _h3, _h4, _h5, + _g2, _g3, _g4, _g5) ) + _clip = true ; + } + + return ( _clip ) ; + } + + template < + typename real_type , + typename vals_type + > + __normal_call bool_type eikonal_wedg_3d ( + __const_ptr (real_type) _p1 , + __const_ptr (real_type) _p2 , + __const_ptr (real_type) _p3 , + __const_ptr (real_type) _p4 , + __const_ptr (real_type) _p5 , + __const_ptr (real_type) _p6 , + vals_type _hb , // current anchor + vals_type& _h1 , + vals_type& _h2 , + vals_type& _h3 , + vals_type& _h4 , + vals_type& _h5 , + vals_type& _h6 , + vals_type _g1 , + vals_type _g2 , + vals_type _g3 , + vals_type _g4 , + vals_type _g5 , + vals_type _g6 + ) + { + /*---------------------- limit h-values within WEDG-6 */ + bool_type _clip = false ; + + // Similiarly to the hexa case, iterate on a regular + // division about the cell centroid... + + real_type constexpr _6r = (real_type) +6. ; + real_type _pc[3] = { + (_p1[0] + _p2[0] + _p3[0] + _p4[0] + + _p5[0] + _p6[0] ) / _6r, + (_p1[1] + _p2[1] + _p3[1] + _p4[1] + + _p5[1] + _p6[1] ) / _6r, + (_p1[2] + _p2[2] + _p3[2] + _p4[2] + + _p5[2] + _p6[2] ) / _6r, + } ; + + vals_type constexpr _6v = (vals_type) +6. ; + vals_type _hc = ( + _h1 + _h2 + _h3 + _h4 + _h5 + _h6) / _6v ; + vals_type _gc = ( + _g1 + _g2 + _g3 + _g4 + _g5 + _g6) / _6v ; + + for (auto _iter = 4; _iter-- != 0; ) + { + bool_type _diff = false; + /*----------------------------- subcells about centre */ + if (eikonal_tria_3d ( + _p1, _p2, _p3, _pc, _hb, + _h1, _h2, _h3, _hc, + _g1, _g2, _g3, _gc) ) + { + _diff = true ; _clip = true ; + } + + if (eikonal_pyra_3d ( + _p1, _p2, _p5, _p4, _pc, _hb, + _h1, _h2, _h5, _h4, _hc, + _g1, _g2, _g5, _g4, _gc) ) + { + _diff = true ; _clip = true ; + } + + if (eikonal_pyra_3d ( + _p2, _p3, _p6, _p5, _pc, _hb, + _h2, _h3, _h6, _h5, _hc, + _g2, _g3, _g6, _g5, _gc) ) + { + _diff = true ; _clip = true ; + } + + if (eikonal_pyra_3d ( + _p3, _p1, _p4, _p6, _pc, _hb, + _h3, _h1, _h4, _h6, _hc, + _g3, _g1, _g4, _g6, _gc) ) + { + _diff = true ; _clip = true ; + } + + if (eikonal_tria_3d ( + _p6, _p5, _p4, _pc, _hb, + _h6, _h5, _h4, _hc, + _g6, _g5, _g4, _gc) ) + { + _diff = true ; _clip = true ; + } + + if (!_diff ) break; + } + + return ( _clip ) ; + } + + template < + typename real_type , + typename vals_type + > + __normal_call bool_type eikonal_hexa_3d ( + __const_ptr (real_type) _p1 , + __const_ptr (real_type) _p2 , + __const_ptr (real_type) _p3 , + __const_ptr (real_type) _p4 , + __const_ptr (real_type) _p5 , + __const_ptr (real_type) _p6 , + __const_ptr (real_type) _p7 , + __const_ptr (real_type) _p8 , + vals_type _hb , // current anchor + vals_type& _h1 , + vals_type& _h2 , + vals_type& _h3 , + vals_type& _h4 , + vals_type& _h5 , + vals_type& _h6 , + vals_type& _h7 , + vals_type& _h8 , + vals_type _g1 , + vals_type _g2 , + vals_type _g3 , + vals_type _g4 , + vals_type _g5 , + vals_type _g6 , + vals_type _g7 , + vals_type _g8 + ) + { + /*---------------------- limit h-values within HEXA-8 */ + bool_type _clip = false ; + + // There are a very large number of hexa => tet cases: + // J. Pellerin, K. Verhetsel, J.F. Remacle (2018): + // There are 174 Subdivisions of the Hexahedron + // into Tetrahedra. + // ACM Transactions on Graphics (TOG), 37(6), pp. 1-9. + + // Instead, do a few iterations on a regular division + // about the cell centroid... + + real_type constexpr _8r = (real_type)+8.; + real_type _pc[3] = { + (_p1[0] + _p2[0] + _p3[0] + _p4[0] + + _p5[0] + _p6[0] + _p7[0] + _p8[0] ) / _8r, + (_p1[1] + _p2[1] + _p3[1] + _p4[1] + + _p5[1] + _p6[1] + _p7[1] + _p8[1] ) / _8r, + (_p1[2] + _p2[2] + _p3[2] + _p4[2] + + _p5[2] + _p6[2] + _p7[2] + _p8[2] ) / _8r, + } ; + + vals_type constexpr _8v = (vals_type)+8.; + vals_type _hc = ( + _h1 + _h2 + _h3 + _h4 + _h5 + _h6 + _h7 + _h8 + ) / _8v ; + vals_type _gc = ( + _g1 + _g2 + _g3 + _g4 + _g5 + _g6 + _g7 + _g8 + ) / _8v ; + + for (auto _iter = 4; _iter-- != 0; ) + { + bool_type _diff = false; + /*----------------------------- subcells about centre */ + if (eikonal_pyra_3d ( + _p1, _p2, _p3, _p4, _pc, _hb, + _h1, _h2, _h3, _h4, _hc, + _g1, _g2, _g3, _g4, _gc) ) + { + _diff = true ; _clip = true ; + } + + if (eikonal_pyra_3d ( + _p1, _p2, _p6, _p5, _pc, _hb, + _h1, _h2, _h6, _h5, _hc, + _g1, _g2, _g6, _g5, _gc) ) + { + _diff = true ; _clip = true ; + } + + if (eikonal_pyra_3d ( + _p2, _p3, _p7, _p6, _pc, _hb, + _h2, _h3, _h7, _h6, _hc, + _g2, _g3, _g7, _g6, _gc) ) + { + _diff = true ; _clip = true ; + } + + if (eikonal_pyra_3d ( + _p3, _p4, _p8, _p7, _pc, _hb, + _h3, _h4, _h8, _h7, _hc, + _g3, _g4, _g8, _g7, _gc) ) + { + _diff = true ; _clip = true ; + } + + if (eikonal_pyra_3d ( + _p4, _p1, _p5, _p8, _pc, _hb, + _h4, _h1, _h5, _h8, _hc, + _g4, _g1, _g5, _g8, _gc) ) + { + _diff = true ; _clip = true ; + } + + if (eikonal_pyra_3d ( + _p8, _p7, _p6, _p5, _pc, _hb, + _h8, _h7, _h6, _h5, _hc, + _g8, _g7, _g6, _g5, _gc) ) + { + _diff = true ; _clip = true ; + } + + if (!_diff ) break; + } + + return ( _clip ) ; } diff --git a/src/libcpp/interpolate/hfun_constant_value_k.hpp b/src/libcpp/interpolate/hfun_constant_value_k.hpp index 0f557a6..2557273 100644 --- a/src/libcpp/interpolate/hfun_constant_value_k.hpp +++ b/src/libcpp/interpolate/hfun_constant_value_k.hpp @@ -82,6 +82,15 @@ /*--------------------------- simply return the value */ + __inline_call real_type eval ( + real_type *_ppos + ) + { + __unreferenced(_ppos) ; + + return this-> _hval ; + } + __inline_call real_type eval ( real_type *_ppos, hint_type &_hint diff --git a/src/libcpp/interpolate/hfun_grid_ellipsoid_3.hpp b/src/libcpp/interpolate/hfun_grid_ellipsoid_3.hpp index 7b3bd24..ac6f90f 100644 --- a/src/libcpp/interpolate/hfun_grid_ellipsoid_3.hpp +++ b/src/libcpp/interpolate/hfun_grid_ellipsoid_3.hpp @@ -35,9 +35,9 @@ * -------------------------------------------------------- * - * Last updated: 15 Jun., 2022 + * Last updated: 20 Oct., 2024 * - * Copyright 2013-2022 + * Copyright 2013-2024 * Darren Engwirda * d.engwirda@gmail.com * https://github.com/dengwirda/ @@ -114,12 +114,13 @@ vals_type _htop ; // mean at poles vals_type _hbot ; + + real_type _ivdx, _ivdy ; containers::array < vals_type, allocator> _dhdx ; - bool_type _xvar ; - bool_type _yvar ; + bool_type _xvar, _yvar ; bool_type _wrap ; @@ -148,8 +149,8 @@ iptr_type _ynum = (iptr_type)this->_ypos.count() ; - _ipos = _indx % _ynum ; - _jpos =(_indx - _ipos )/_ynum ; + _jpos = _indx / _ynum ; + _ipos = _indx - _jpos * _ynum ; } __inline_call void_type toR3 ( @@ -258,6 +259,9 @@ _yvar = true ; break ; } } + + this->_ivdx = +1. / _xbar ; + this->_ivdy = +1. / _ybar ; /*-------------------------- test for "x" periodicity */ real_type _xdel = @@ -352,11 +356,9 @@ if (this->_wrap) { iptr_type _inum = +0; - for (auto _iter = - this->_ypos.head() ; - _iter != - this->_ypos.tend() ; - ++_iter , ++_inum) + for (auto _iter = this->_ypos.head() ; + _iter != this->_ypos.tend() ; + ++_iter, ++_inum) { iptr_type _left, _pair ; indx_from_subs( @@ -376,11 +378,9 @@ /*-------------------- push nodes onto priority queue */ { iptr_type _inum = +0; - for (auto _iter = - this->_hmat.head() ; - _iter != - this->_hmat.tend() ; - ++_iter , ++_inum) + for (auto _iter = this->_hmat.head() ; + _iter != this->_hmat.tend() ; + ++_iter, ++_inum) { _sort.push(_inum, _inum ) ; } @@ -394,11 +394,9 @@ { iptr_type _inum = +0; - for (auto _iter = - this->_xpos.head() ; - _iter != - this->_xpos.tend() ; - ++_iter , ++_inum) + for (auto _iter = this->_xpos.head() ; + _iter != this->_xpos.tend() ; + ++_iter, ++_inum) { this->_sinx[_inum] = std::sin(this->_xpos[_inum]); @@ -414,11 +412,9 @@ { iptr_type _inum = +0; - for (auto _iter = - this->_ypos.head() ; - _iter != - this->_ypos.tend() ; - ++_iter , ++_inum) + for (auto _iter = this->_ypos.head() ; + _iter != this->_ypos.tend() ; + ++_iter, ++_inum) { this->_siny[_inum] = std::sin(this->_ypos[_inum]); @@ -438,6 +434,19 @@ # define UPDATED(__new, __old) \ std::abs(__new - __old) > _FTOL*std::abs(__new) + # define REQUEUE(__new, __old, __idx) \ + if(UPDATED(__new, __old)) { \ + if(ISALIVE(__idx)) \ + { \ + _hmat[__idx] = __new; \ + _sort.reduce(__idx , __idx) ; \ + } \ + else \ + { \ + _hmat[__idx] = __new; \ + _sort.push (__idx , __idx) ; \ + } } + for ( ; !_sort.empty() ; ) { iptr_type _base, _bidx; @@ -491,16 +500,19 @@ _lpii, _lpjj, _lnod); /*-------------------- skip cells due to sorted order */ + iptr_type _near = +0; if (_inod != _base && - !ISALIVE(_inod)) continue ; + ISALIVE(_inod)) _near++; if (_jnod != _base && - !ISALIVE(_jnod)) continue ; + ISALIVE(_jnod)) _near++; if (_knod != _base && - !ISALIVE(_knod)) continue ; + ISALIVE(_knod)) _near++; if (_lnod != _base && - !ISALIVE(_lnod)) continue ; + ISALIVE(_lnod)) _near++; + + if (_near == 0) continue ; - vals_type _hmax; + vals_type _hmax = .0; _hmax = this->_hmat[_inod] ; _hmax = std::max( _hmax , this->_hmat[_jnod]); @@ -571,7 +583,7 @@ vals_type _lnew = this->_hmat[_lnod] ; - if (this->_dhdx.count() >1) + if (this->_dhdx.count() > +1) { /*-------------------- update adj. set, g = g(x) case */ if (eikonal_grid_3d ( @@ -588,37 +600,10 @@ // push updates one-at-a-time to ensure heap // maintains its sorted order - if (_sort. - keys(_inod) != _sort.null()) - if ( UPDATED(_inew, _iold) ) - { - _hmat[_inod] = _inew; - _sort.reduce(_inod , _inod) ; - } - - if (_sort. - keys(_jnod) != _sort.null()) - if ( UPDATED(_jnew, _jold) ) - { - _hmat[_jnod] = _jnew; - _sort.reduce(_jnod , _jnod) ; - } - - if (_sort. - keys(_knod) != _sort.null()) - if ( UPDATED(_knew, _kold) ) - { - _hmat[_knod] = _knew; - _sort.reduce(_knod , _knod) ; - } - - if (_sort. - keys(_lnod) != _sort.null()) - if ( UPDATED(_lnew, _lold) ) - { - _hmat[_lnod] = _lnew; - _sort.reduce(_lnod , _lnod) ; - } + REQUEUE (_inew, _iold, _inod) + REQUEUE (_jnew, _jold, _jnod) + REQUEUE (_knew, _kold, _knod) + REQUEUE (_lnew, _lold, _lnod) if (this->_wrap) { @@ -627,67 +612,39 @@ { iptr_type _pair; indx_from_subs( - _ipii, JEND , _pair) ; - - this->_hmat [_pair] = - this->_hmat [_inod] ; - - if (_sort. - keys(_pair) != _sort.null()) - if (_hmat[_inod] != _iold) - _sort.reduce(_pair , _pair) ; + _ipii, JEND, _pair) ; + REQUEUE (_inew, _iold, _pair) } if (_jpjj==JEND) { iptr_type _pair; indx_from_subs( - _jpii, JBEG , _pair) ; - - this->_hmat [_pair] = - this->_hmat [_jnod] ; - - if (_sort. - keys(_pair) != _sort.null()) - if (_hmat[_jnod] != _jold) - _sort.reduce(_pair , _pair) ; + _jpii, JBEG, _pair) ; + REQUEUE (_jnew, _jold, _pair) } if (_kpjj==JEND) { iptr_type _pair; indx_from_subs( - _kpii, JBEG , _pair) ; - - this->_hmat [_pair] = - this->_hmat [_knod] ; - - if (_sort. - keys(_pair) != _sort.null()) - if (_hmat[_knod] != _kold) - _sort.reduce(_pair , _pair) ; + _kpii, JBEG, _pair) ; + REQUEUE (_knew, _kold, _pair) } if (_lpjj==JBEG) { iptr_type _pair; indx_from_subs( - _lpii, JEND , _pair) ; - - this->_hmat [_pair] = - this->_hmat [_lnod] ; - - if (_sort. - keys(_pair) != _sort.null()) - if (_hmat[_lnod] != _lold) - _sort.reduce(_pair , _pair) ; + _lpii, JEND, _pair) ; + REQUEUE (_lnew, _lold, _pair) } } } } else - if (this->_dhdx.count()==1) + if (this->_dhdx.count() == 1) { /*-------------------- update adj. set, const. g case */ if (eikonal_grid_3d ( @@ -704,37 +661,10 @@ // push updates one-at-a-time to ensure heap // maintains its sorted order - if (_sort. - keys(_inod) != _sort.null()) - if ( UPDATED(_inew, _iold) ) - { - _hmat[_inod] = _inew; - _sort.reduce(_inod , _inod) ; - } - - if (_sort. - keys(_jnod) != _sort.null()) - if ( UPDATED(_jnew, _jold) ) - { - _hmat[_jnod] = _jnew; - _sort.reduce(_jnod , _jnod) ; - } - - if (_sort. - keys(_knod) != _sort.null()) - if ( UPDATED(_knew, _kold) ) - { - _hmat[_knod] = _knew; - _sort.reduce(_knod , _knod) ; - } - - if (_sort. - keys(_lnod) != _sort.null()) - if ( UPDATED(_lnew, _lold) ) - { - _hmat[_lnod] = _lnew; - _sort.reduce(_lnod , _lnod) ; - } + REQUEUE (_inew, _iold, _inod) + REQUEUE (_jnew, _jold, _jnod) + REQUEUE (_knew, _kold, _knod) + REQUEUE (_lnew, _lold, _lnod) if (this->_wrap) { @@ -743,60 +673,32 @@ { iptr_type _pair; indx_from_subs( - _ipii, JEND , _pair) ; - - this->_hmat [_pair] = - this->_hmat [_inod] ; - - if (_sort. - keys(_pair) != _sort.null()) - if (_hmat[_inod] != _iold) - _sort.reduce(_pair , _pair) ; + _ipii, JEND, _pair) ; + REQUEUE (_inew, _iold, _pair) } if (_jpjj==JEND) { iptr_type _pair; indx_from_subs( - _jpii, JBEG , _pair) ; - - this->_hmat [_pair] = - this->_hmat [_jnod] ; - - if (_sort. - keys(_pair) != _sort.null()) - if (_hmat[_jnod] != _jold) - _sort.reduce(_pair , _pair) ; + _jpii, JBEG, _pair) ; + REQUEUE (_jnew, _jold, _pair) } if (_kpjj==JEND) { iptr_type _pair; indx_from_subs( - _kpii, JBEG , _pair) ; - - this->_hmat [_pair] = - this->_hmat [_knod] ; - - if (_sort. - keys(_pair) != _sort.null()) - if (_hmat[_knod] != _kold) - _sort.reduce(_pair , _pair) ; + _kpii, JBEG, _pair) ; + REQUEUE (_knew, _kold, _pair) } if (_lpjj==JBEG) { iptr_type _pair; indx_from_subs( - _lpii, JEND , _pair) ; - - this->_hmat [_pair] = - this->_hmat [_lnod] ; - - if (_sort. - keys(_pair) != _sort.null()) - if (_hmat[_lnod] != _lold) - _sort.reduce(_pair , _pair) ; + _lpii, JEND, _pair) ; + REQUEUE (_lnew, _lold, _pair) } } @@ -809,6 +711,7 @@ # undef ISALIVE # undef UPDATED + # undef REQUEUE } /* @@ -817,6 +720,14 @@ -------------------------------------------------------- */ + __inline_call real_type eval ( + real_type *_ppos + ) + { + auto _hint = this->null_hint(); + return eval(_ppos, _hint); + } + __normal_call real_type eval ( real_type *_ppos , hint_type &_hint @@ -932,15 +843,8 @@ } else { - real_type _xmin, _xmax, _xdel; - _xmin = *this->_xpos.head(); - _xmax = *this->_xpos.tail(); - - _xdel = (_xmax - _xmin) / - (this->_xpos.count () - 1) ; - - _jpos = (iptr_type) - ((_alon-_xmin)/_xdel) ; + _jpos = (iptr_type) ( + (_alon -*this->_xpos.head()) * this->_ivdx) ; } /*---------------------------- find enclosing y-range */ @@ -957,15 +861,8 @@ } else { - real_type _ymin, _ymax, _ydel; - _ymin = *this->_ypos.head(); - _ymax = *this->_ypos.tail(); - - _ydel = (_ymax - _ymin) / - (this->_ypos.count () - 1) ; - - _ipos = (iptr_type) - ((_alat-_ymin)/_ydel) ; + _ipos = (iptr_type) ( + (_alat -*this->_ypos.head()) * this->_ivdy) ; } if (_ipos == @@ -987,17 +884,14 @@ real_type _yp22 = this->_ypos[_ipos + 1] ; - real_type _xval = _alon ; - real_type _yval = _alat ; - real_type _aa22 = - (_yval-_yp11) * (_xval-_xp11) ; + (_alat-_yp11) * (_alon-_xp11) ; real_type _aa21 = - (_yval-_yp11) * (_xp22-_xval) ; + (_alat-_yp11) * (_xp22-_alon) ; real_type _aa12 = - (_yp22-_yval) * (_xval-_xp11) ; + (_yp22-_alat) * (_alon-_xp11) ; real_type _aa11 = - (_yp22-_yval) * (_xp22-_xval) ; + (_yp22-_alat) * (_xp22-_alon) ; iptr_type _kk11 ; indx_from_subs( diff --git a/src/libcpp/interpolate/hfun_grid_euclidean_2.hpp b/src/libcpp/interpolate/hfun_grid_euclidean_2.hpp index 0619b53..a2ff415 100644 --- a/src/libcpp/interpolate/hfun_grid_euclidean_2.hpp +++ b/src/libcpp/interpolate/hfun_grid_euclidean_2.hpp @@ -35,9 +35,9 @@ * -------------------------------------------------------- * - * Last updated: 15 Jun., 2022 + * Last updated: 20 Oct., 2024 * - * Copyright 2013-2022 + * Copyright 2013-2024 * Darren Engwirda * d.engwirda@gmail.com * https://github.com/dengwirda/ @@ -127,8 +127,8 @@ iptr_type _ynum = (iptr_type)this->_ypos.count() ; - _ipos = _indx % _ynum ; - _jpos =(_indx - _ipos )/_ynum ; + _jpos = _indx / _ynum ; + _ipos = _indx - _jpos * _ynum ; } /* @@ -170,11 +170,9 @@ /*-------------------- push nodes onto priority queue */ iptr_type _inum = +0; - for (auto _iter = - this->_hmat.head() ; - _iter != - this->_hmat.tend() ; - ++_iter , ++_inum) + for (auto _iter = this->_hmat.head() ; + _iter != this->_hmat.tend() ; + ++_iter, ++_inum) { _sort.push(_inum, _inum ) ; } @@ -198,6 +196,19 @@ # define UPDATED(__new, __old) \ std::abs(__new - __old) > _FTOL*std::abs(__new) + # define REQUEUE(__new, __old, __idx) \ + if(UPDATED(__new, __old)) { \ + if(ISALIVE(__idx)) \ + { \ + _hmat[__idx] = __new; \ + _sort.reduce(__idx , __idx) ; \ + } \ + else \ + { \ + _hmat[__idx] = __new; \ + _sort.push (__idx , __idx) ; \ + } } + for ( ; !_sort.empty() ; ) { iptr_type _base, _bidx; @@ -249,16 +260,19 @@ _lpii, _lpjj, _lnod); /*-------------------- skip cells due to sorted order */ + iptr_type _near = +0; if (_inod != _base && - !ISALIVE(_inod)) continue ; + ISALIVE(_inod)) _near++; if (_jnod != _base && - !ISALIVE(_jnod)) continue ; + ISALIVE(_jnod)) _near++; if (_knod != _base && - !ISALIVE(_knod)) continue ; + ISALIVE(_knod)) _near++; if (_lnod != _base && - !ISALIVE(_lnod)) continue ; + ISALIVE(_lnod)) _near++; + + if (_near == 0) continue ; - vals_type _hmax; + vals_type _hmax = .0; _hmax = this->_hmat[_inod] ; _hmax = std::max( _hmax , this->_hmat[_jnod]); @@ -305,7 +319,7 @@ vals_type _lnew = this->_hmat[_lnod] ; - if (this->_dhdx.count() >1) + if (this->_dhdx.count() > +1) { /*-------------------- update adj. set, g = g(x) case */ if (eikonal_grid_2d ( @@ -322,42 +336,15 @@ // push updates one-at-a-time to ensure heap // maintains its sorted order - if (_sort. - keys(_inod) != _sort.null()) - if ( UPDATED(_inew, _iold) ) - { - _hmat[_inod] = _inew; - _sort.reduce(_inod , _inod) ; - } - - if (_sort. - keys(_jnod) != _sort.null()) - if ( UPDATED(_jnew, _jold) ) - { - _hmat[_jnod] = _jnew; - _sort.reduce(_jnod , _jnod) ; - } - - if (_sort. - keys(_knod) != _sort.null()) - if ( UPDATED(_knew, _kold) ) - { - _hmat[_knod] = _knew; - _sort.reduce(_knod , _knod) ; - } - - if (_sort. - keys(_lnod) != _sort.null()) - if ( UPDATED(_lnew, _lold) ) - { - _hmat[_lnod] = _lnew; - _sort.reduce(_lnod , _lnod) ; - } + REQUEUE (_inew, _iold, _inod) + REQUEUE (_jnew, _jold, _jnod) + REQUEUE (_knew, _kold, _knod) + REQUEUE (_lnew, _lold, _lnod) } } else - if (this->_dhdx.count()==1) + if (this->_dhdx.count() == 1) { /*-------------------- update adj. set, const. g case */ if (eikonal_grid_2d ( @@ -374,37 +361,10 @@ // push updates one-at-a-time to ensure heap // maintains its sorted order - if (_sort. - keys(_inod) != _sort.null()) - if ( UPDATED(_inew, _iold) ) - { - _hmat[_inod] = _inew; - _sort.reduce(_inod , _inod) ; - } - - if (_sort. - keys(_jnod) != _sort.null()) - if ( UPDATED(_jnew, _jold) ) - { - _hmat[_jnod] = _jnew; - _sort.reduce(_jnod , _jnod) ; - } - - if (_sort. - keys(_knod) != _sort.null()) - if ( UPDATED(_knew, _kold) ) - { - _hmat[_knod] = _knew; - _sort.reduce(_knod , _knod) ; - } - - if (_sort. - keys(_lnod) != _sort.null()) - if ( UPDATED(_lnew, _lold) ) - { - _hmat[_lnod] = _lnew; - _sort.reduce(_lnod , _lnod) ; - } + REQUEUE (_inew, _iold, _inod) + REQUEUE (_jnew, _jold, _jnod) + REQUEUE (_knew, _kold, _knod) + REQUEUE (_lnew, _lold, _lnod) } } @@ -415,6 +375,7 @@ # undef ISALIVE # undef UPDATED + # undef REQUEUE } /* @@ -511,6 +472,14 @@ -------------------------------------------------------- */ + __inline_call real_type eval ( + real_type *_ppos + ) + { + auto _hint = this->null_hint(); + return eval(_ppos, _hint); + } + __inline_call real_type eval ( real_type *_ppos, hint_type &_hint diff --git a/src/libcpp/interpolate/hfun_grid_euclidean_3.hpp b/src/libcpp/interpolate/hfun_grid_euclidean_3.hpp index c56f854..e7a5c2d 100644 --- a/src/libcpp/interpolate/hfun_grid_euclidean_3.hpp +++ b/src/libcpp/interpolate/hfun_grid_euclidean_3.hpp @@ -35,9 +35,9 @@ * -------------------------------------------------------- * - * Last updated: 15 Jun., 2022 + * Last updated: 20 Oct., 2024 * - * Copyright 2013-2022 + * Copyright 2013-2024 * Darren Engwirda * d.engwirda@gmail.com * https://github.com/dengwirda/ @@ -112,7 +112,7 @@ iptr_type _jpos, iptr_type _kpos, iptr_type&_indx - ) + ) const { /*------------ helper: convert into "un-rolled" index */ iptr_type _ynum = @@ -124,6 +124,391 @@ _indx = _kpos * _xnum * _ynum + _jpos * _ynum + _ipos ; } + + __inline_call void_type subs_from_indx ( + iptr_type _indx, + iptr_type&_ipos, + iptr_type&_jpos, + iptr_type&_kpos + ) const + { + /*------------ helper: convert from "un-rolled" index */ + iptr_type _ynum = + (iptr_type)this->_ypos.count() ; + + iptr_type _xnum = + (iptr_type)this->_xpos.count() ; + + _kpos = _indx /(_xnum * _ynum); + _indx-= _kpos * _xnum * _ynum ; + _jpos = _indx / _ynum ; + _ipos = _indx - _jpos * _ynum ; + } + + /* + -------------------------------------------------------- + * CLIP-HFUN: impose |dh/dx| limits. + -------------------------------------------------------- + */ + + __normal_call void_type clip ( + ) + { + class less_than + { + /*-------------------- "LESS-THAN" operator for queue */ + public : + typename vals_list::_write_it _hptr ; + + public : + __inline_call less_than ( + typename vals_list::_write_it _hsrc + ) : _hptr(_hsrc) {} + + __inline_call + bool_type operator() ( + iptr_type _ipos, + iptr_type _jpos + ) + { return *(this->_hptr+_ipos) < + *(this->_hptr+_jpos) ; + } + } ; + + containers::priorityidx < + iptr_type , + iptr_type , + less_than , + allocator > + _sort((less_than(this->_hmat.head()))); + + /*-------------------- push nodes onto priority queue */ + iptr_type _inum = +0; + for (auto _iter = this->_hmat.head() ; + _iter != this->_hmat.tend() ; + ++_iter, ++_inum) + { + _sort.push(_inum, _inum ) ; + } + + /*-------------------- compute h(x) via fast-marching */ + vals_type static _FTOL = + (vals_type)std::pow( + std::numeric_limits::epsilon(), .75) ; + + iptr_type IBEG = +0; + iptr_type IEND = + (iptr_type)this->_ypos.count() - 1 ; + + iptr_type JBEG = +0; + iptr_type JEND = + (iptr_type)this->_xpos.count() - 1 ; + + iptr_type KBEG = +0; + iptr_type KEND = + (iptr_type)this->_zpos.count() - 1 ; + + # define ISALIVE(__idx) \ + (_sort.keys(__idx) != _sort.null()) + + # define UPDATED(__new, __old) \ + std::abs(__new - __old) > _FTOL*std::abs(__new) + + # define REQUEUE(__new, __old, __idx) \ + if(UPDATED(__new, __old)) { \ + if(ISALIVE(__idx)) \ + { \ + _hmat[__idx] = __new; \ + _sort.reduce(__idx , __idx) ; \ + } \ + else \ + { \ + _hmat[__idx] = __new; \ + _sort.push (__idx , __idx) ; \ + } } + + for ( ; !_sort.empty() ; ) + { + iptr_type _base, _bidx; + _sort._pop_root ( _bidx, _base) ; + + iptr_type _ipos, _jpos, _kpos; + subs_from_indx( + _base, _ipos, _jpos, _kpos) ; + + vals_type _hnow = _hmat [_base] ; + + for (auto _IPOS = _ipos - 1 ; + _IPOS < _ipos + 1 ; + ++_IPOS ) + for (auto _JPOS = _jpos - 1 ; + _JPOS < _jpos + 1 ; + ++_JPOS ) + for (auto _KPOS = _kpos - 1 ; + _KPOS < _kpos + 1 ; + ++_KPOS ) + { + if (_IPOS >= IBEG && _IPOS < IEND) + if (_JPOS >= JBEG && _JPOS < JEND) + if (_KPOS >= KBEG && _KPOS < KEND) + { + /*-------------------- un-pack implicit cell indexing */ + auto _ipii = _IPOS + 0 ; + auto _ipjj = _JPOS + 0 ; + auto _ipkk = _KPOS + 0 ; + + iptr_type _inod; + indx_from_subs( + _ipii, _ipjj, _ipkk, _inod); + + auto _jpii = _IPOS + 1 ; + auto _jpjj = _JPOS + 0 ; + auto _jpkk = _KPOS + 0 ; + + iptr_type _jnod; + indx_from_subs( + _jpii, _jpjj, _jpkk, _jnod); + + auto _kpii = _IPOS + 1 ; + auto _kpjj = _JPOS + 1 ; + auto _kpkk = _KPOS + 0 ; + + iptr_type _knod; + indx_from_subs( + _kpii, _kpjj, _kpkk, _knod); + + auto _lpii = _IPOS + 0 ; + auto _lpjj = _JPOS + 1 ; + auto _lpkk = _KPOS + 0 ; + + iptr_type _lnod; + indx_from_subs( + _lpii, _lpjj, _lpkk, _lnod); + + auto _mpii = _IPOS + 0 ; + auto _mpjj = _JPOS + 0 ; + auto _mpkk = _KPOS + 1 ; + + iptr_type _mnod; + indx_from_subs( + _mpii, _mpjj, _mpkk, _mnod); + + auto _npii = _IPOS + 1 ; + auto _npjj = _JPOS + 0 ; + auto _npkk = _KPOS + 1 ; + + iptr_type _nnod; + indx_from_subs( + _npii, _npjj, _npkk, _nnod); + + auto _opii = _IPOS + 1 ; + auto _opjj = _JPOS + 1 ; + auto _opkk = _KPOS + 1 ; + + iptr_type _onod; + indx_from_subs( + _opii, _opjj, _opkk, _onod); + + auto _ppii = _IPOS + 0 ; + auto _ppjj = _JPOS + 1 ; + auto _ppkk = _KPOS + 1 ; + + iptr_type _pnod; + indx_from_subs( + _ppii, _ppjj, _ppkk, _pnod); + + /*-------------------- skip cells due to sorted order */ + iptr_type _near = +0; + if (_inod != _base && + ISALIVE(_inod)) _near++; + if (_jnod != _base && + ISALIVE(_jnod)) _near++; + if (_knod != _base && + ISALIVE(_knod)) _near++; + if (_lnod != _base && + ISALIVE(_lnod)) _near++; + if (_mnod != _base && + ISALIVE(_mnod)) _near++; + if (_nnod != _base && + ISALIVE(_nnod)) _near++; + if (_onod != _base && + ISALIVE(_onod)) _near++; + if (_pnod != _base && + ISALIVE(_pnod)) _near++; + + if (_near == 0) continue ; + + vals_type _hmax = .0; + _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]); + _hmax = std::max( + _hmax , this->_hmat[_mnod]); + _hmax = std::max( + _hmax , this->_hmat[_nnod]); + _hmax = std::max( + _hmax , this->_hmat[_onod]); + _hmax = std::max( + _hmax , this->_hmat[_pnod]); + + if (_hmax <= _hnow) continue ; + + /*-------------------- set-up cell vertex coordinates */ + real_type _IXYZ[3]; + _IXYZ[0] = this->_xpos[_ipjj]; + _IXYZ[1] = this->_ypos[_ipii]; + _IXYZ[2] = this->_zpos[_ipkk]; + + real_type _JXYZ[3]; + _JXYZ[0] = this->_xpos[_jpjj]; + _JXYZ[1] = this->_ypos[_jpii]; + _JXYZ[2] = this->_zpos[_jpkk]; + + real_type _KXYZ[3]; + _KXYZ[0] = this->_xpos[_kpjj]; + _KXYZ[1] = this->_ypos[_kpii]; + _KXYZ[2] = this->_zpos[_kpkk]; + + real_type _LXYZ[3]; + _LXYZ[0] = this->_xpos[_lpjj]; + _LXYZ[1] = this->_ypos[_lpii]; + _LXYZ[2] = this->_zpos[_lpkk]; + + real_type _MXYZ[3]; + _MXYZ[0] = this->_xpos[_mpjj]; + _MXYZ[1] = this->_ypos[_mpii]; + _MXYZ[2] = this->_zpos[_mpkk]; + + real_type _NXYZ[3]; + _NXYZ[0] = this->_xpos[_npjj]; + _NXYZ[1] = this->_ypos[_npii]; + _NXYZ[2] = this->_zpos[_npkk]; + + real_type _OXYZ[3]; + _OXYZ[0] = this->_xpos[_opjj]; + _OXYZ[1] = this->_ypos[_opii]; + _OXYZ[2] = this->_zpos[_opkk]; + + real_type _PXYZ[3]; + _PXYZ[0] = this->_xpos[_ppjj]; + _PXYZ[1] = this->_ypos[_ppii]; + _PXYZ[2] = this->_zpos[_ppkk]; + + /*-------------------- solve for local |dh/dx| limits */ + vals_type _iold = + this->_hmat[_inod] ; + vals_type _jold = + this->_hmat[_jnod] ; + vals_type _kold = + this->_hmat[_knod] ; + vals_type _lold = + this->_hmat[_lnod] ; + vals_type _mold = + this->_hmat[_mnod] ; + vals_type _nold = + this->_hmat[_nnod] ; + vals_type _oold = + this->_hmat[_onod] ; + vals_type _pold = + this->_hmat[_pnod] ; + + vals_type _inew = + this->_hmat[_inod] ; + vals_type _jnew = + this->_hmat[_jnod] ; + vals_type _knew = + this->_hmat[_knod] ; + vals_type _lnew = + this->_hmat[_lnod] ; + vals_type _mnew = + this->_hmat[_mnod] ; + vals_type _nnew = + this->_hmat[_nnod] ; + vals_type _onew = + this->_hmat[_onod] ; + vals_type _pnew = + this->_hmat[_pnod] ; + + if (this->_dhdx.count() > +1) + { + /*-------------------- update adj. set, g = g(x) case */ + if (eikonal_hexa_3d ( + _IXYZ , _JXYZ , _KXYZ , _LXYZ , + _MXYZ , _NXYZ , _OXYZ , _PXYZ , + _hnow , + _inew , _jnew , _knew , _lnew , + _mnew , _nnew , _onew , _pnew , + this->_dhdx[_inod], + this->_dhdx[_jnod], + this->_dhdx[_knod], + this->_dhdx[_lnod], + this->_dhdx[_mnod], + this->_dhdx[_nnod], + this->_dhdx[_onod], + this->_dhdx[_pnod]) ) + { + + // push updates one-at-a-time to ensure heap + // maintains its sorted order + + REQUEUE (_inew, _iold, _inod) + REQUEUE (_jnew, _jold, _jnod) + REQUEUE (_knew, _kold, _knod) + REQUEUE (_lnew, _lold, _lnod) + REQUEUE (_mnew, _mold, _mnod) + REQUEUE (_nnew, _nold, _nnod) + REQUEUE (_onew, _oold, _onod) + REQUEUE (_pnew, _pold, _pnod) + + } + } + else + if (this->_dhdx.count() == 1) + { + /*-------------------- update adj. set, const. g case */ + if (eikonal_hexa_3d ( + _IXYZ , _JXYZ , _KXYZ , _LXYZ , + _MXYZ , _NXYZ , _OXYZ , _PXYZ , + _hnow , + _inew , _jnew , _knew , _lnew , + _mnew , _nnew , _onew , _pnew , + this->_dhdx[ +0 ], + this->_dhdx[ +0 ], + this->_dhdx[ +0 ], + this->_dhdx[ +0 ], + this->_dhdx[ +0 ], + this->_dhdx[ +0 ], + this->_dhdx[ +0 ], + this->_dhdx[ +0 ]) ) + { + + // push updates one-at-a-time to ensure heap + // maintains its sorted order + + REQUEUE (_inew, _iold, _inod) + REQUEUE (_jnew, _jold, _jnod) + REQUEUE (_knew, _kold, _knod) + REQUEUE (_lnew, _lold, _lnod) + REQUEUE (_mnew, _mold, _mnod) + REQUEUE (_nnew, _nold, _nnod) + REQUEUE (_onew, _oold, _onod) + REQUEUE (_pnew, _pold, _pnod) + + } + } + + } + } + } + + # undef ISALIVE + # undef UPDATED + # undef REQUEUE + } /* -------------------------------------------------------- @@ -255,6 +640,14 @@ */ __inline_call real_type eval ( + real_type *_ppos + ) + { + auto _hint = this->null_hint(); + return eval(_ppos, _hint); + } + + __normal_call real_type eval ( real_type *_ppos, hint_type &_hint ) @@ -455,7 +848,6 @@ return ( _hBAR ) ; } - } ; diff --git a/src/libcpp/interpolate/hfun_mesh_ellipsoid_3.hpp b/src/libcpp/interpolate/hfun_mesh_ellipsoid_3.hpp index 36c3a5a..0e11686 100644 --- a/src/libcpp/interpolate/hfun_mesh_ellipsoid_3.hpp +++ b/src/libcpp/interpolate/hfun_mesh_ellipsoid_3.hpp @@ -35,9 +35,9 @@ * -------------------------------------------------------- * - * Last updated: 15 Jun., 2022 + * Last updated: 23 Oct., 2024 * - * Copyright 2013-2022 + * Copyright 2013-2024 * Darren Engwirda * d.engwirda@gmail.com * https://github.com/dengwirda/ @@ -362,6 +362,19 @@ # define UPDATED(__new, __old) \ std::abs(__new - __old) > _FTOL*std::abs(__new) + # define REQUEUE(__new, __old, __idx) \ + if(UPDATED(__new, __old)) { \ + if(ISALIVE(__idx)) \ + { \ + _hval[__idx] = __new; \ + _sort.reduce(__idx , __idx) ; \ + } \ + else \ + { \ + _hval[__idx] = __new; \ + _sort.push (__idx , __idx) ; \ + } } + for ( ; !_sort.empty() ; ) { iptr_type _base, _bidx ; @@ -390,14 +403,17 @@ _mesh. tri3( _cell).node(2); /*-------------------- skip cells due to sorted order */ + iptr_type _near = +0; if (_inod != _base && - !ISALIVE(_inod)) continue ; + ISALIVE(_inod)) _near++; if (_jnod != _base && - !ISALIVE(_jnod)) continue ; + ISALIVE(_jnod)) _near++; if (_knod != _base && - !ISALIVE(_knod)) continue ; + ISALIVE(_knod)) _near++; + + if (_near == 0) continue ; - vals_type _hmax; + vals_type _hmax = .0; _hmax = this->_hval[_inod] ; _hmax = std::max( _hmax , this->_hval[_jnod]); @@ -441,29 +457,9 @@ // push updates one-at-a-time to ensure heap // maintains its sorted order - if (_sort. - keys(_inod) != _sort.null()) - if ( UPDATED(_inew, _iold) ) - { - _hval[_inod] = _inew; - _sort.reduce(_inod , _inod) ; - } - - if (_sort. - keys(_jnod) != _sort.null()) - if ( UPDATED(_jnew, _jold) ) - { - _hval[_jnod] = _jnew; - _sort.reduce(_jnod , _jnod) ; - } - - if (_sort. - keys(_knod) != _sort.null()) - if ( UPDATED(_knew, _kold) ) - { - _hval[_knod] = _knew; - _sort.reduce(_knod , _knod) ; - } + REQUEUE (_inew, _iold, _inod) + REQUEUE (_jnew, _jold, _jnod) + REQUEUE (_knew, _kold, _knod) } } @@ -488,29 +484,9 @@ // push updates one-at-a-time to ensure heap // maintains its sorted order - if (_sort. - keys(_inod) != _sort.null()) - if ( UPDATED(_inew, _iold) ) - { - _hval[_inod] = _inew; - _sort.reduce(_inod , _inod) ; - } - - if (_sort. - keys(_jnod) != _sort.null()) - if ( UPDATED(_jnew, _jold) ) - { - _hval[_jnod] = _jnew; - _sort.reduce(_jnod , _jnod) ; - } - - if (_sort. - keys(_knod) != _sort.null()) - if ( UPDATED(_knew, _kold) ) - { - _hval[_knod] = _knew; - _sort.reduce(_knod , _knod) ; - } + REQUEUE (_inew, _iold, _inod) + REQUEUE (_jnew, _jold, _jnod) + REQUEUE (_knew, _kold, _knod) } } @@ -529,6 +505,7 @@ # undef ISALIVE # undef UPDATED + # undef REQUEUE } /* @@ -632,11 +609,12 @@ if (this->_find) return +0. ; __unreferenced(_lptr); + + real_type _qtmp[3] = {0,0,0}; for ( ; _iptr != nullptr; _iptr = _iptr->_next) { - real_type _qtmp[+3]; iptr_type _TPOS = _iptr->_data.ipos() ; @@ -746,6 +724,14 @@ -------------------------------------------------------- */ + __inline_call real_type eval ( + real_type *_ppos + ) + { + auto _hint = this->null_hint(); + return eval(_ppos, _hint); + } + __normal_call real_type eval ( real_type *_ppos , hint_type &_hint diff --git a/src/libcpp/interpolate/hfun_mesh_euclidean_2.hpp b/src/libcpp/interpolate/hfun_mesh_euclidean_2.hpp index b7c0e56..f59c93e 100644 --- a/src/libcpp/interpolate/hfun_mesh_euclidean_2.hpp +++ b/src/libcpp/interpolate/hfun_mesh_euclidean_2.hpp @@ -35,9 +35,9 @@ * -------------------------------------------------------- * - * Last updated: 15 Jun., 2022 + * Last updated: 23 Oct., 2024 * - * Copyright 2013-2022 + * Copyright 2013-2024 * Darren Engwirda * d.engwirda@gmail.com * https://github.com/dengwirda/ @@ -290,6 +290,19 @@ # define UPDATED(__new, __old) \ std::abs(__new - __old) > _FTOL*std::abs(__new) + # define REQUEUE(__new, __old, __idx) \ + if(UPDATED(__new, __old)) { \ + if(ISALIVE(__idx)) \ + { \ + _hval[__idx] = __new; \ + _sort.reduce(__idx , __idx) ; \ + } \ + else \ + { \ + _hval[__idx] = __new; \ + _sort.push (__idx , __idx) ; \ + } } + for ( ; !_sort.empty() ; ) { iptr_type _base, _bidx ; @@ -318,14 +331,17 @@ _mesh. tri3( _cell).node(2); /*-------------------- skip cells due to sorted order */ + iptr_type _near = +0; if (_inod != _base && - !ISALIVE(_inod)) continue ; + ISALIVE(_inod)) _near++; if (_jnod != _base && - !ISALIVE(_jnod)) continue ; + ISALIVE(_jnod)) _near++; if (_knod != _base && - !ISALIVE(_knod)) continue ; + ISALIVE(_knod)) _near++; + + if (_near == 0) continue ; - vals_type _hmax; + vals_type _hmax = .0; _hmax = this->_hval[_inod] ; _hmax = std::max( _hmax , this->_hval[_jnod]); @@ -349,7 +365,7 @@ vals_type _knew = this->_hval[_knod] ; - if (this->_dhdx.count() >1) + if (this->_dhdx.count() > +1) { /*-------------------- update adj. set, g = g(x) case */ if (eikonal_tria_2d ( @@ -369,34 +385,14 @@ // push updates one-at-a-time to ensure heap // maintains its sorted order - if (_sort. - keys(_inod) != _sort.null()) - if ( UPDATED(_inew, _iold) ) - { - _hval[_inod] = _inew; - _sort.reduce(_inod , _inod) ; - } - - if (_sort. - keys(_jnod) != _sort.null()) - if ( UPDATED(_jnew, _jold) ) - { - _hval[_jnod] = _jnew; - _sort.reduce(_jnod , _jnod) ; - } - - if (_sort. - keys(_knod) != _sort.null()) - if ( UPDATED(_knew, _kold) ) - { - _hval[_knod] = _knew; - _sort.reduce(_knod , _knod) ; - } + REQUEUE (_inew, _iold, _inod) + REQUEUE (_jnew, _jold, _jnod) + REQUEUE (_knew, _kold, _knod) } } else - if (this->_dhdx.count()==1) + if (this->_dhdx.count() == 1) { /*-------------------- update adj. set, const. g case */ if (eikonal_tria_2d ( @@ -416,29 +412,9 @@ // push updates one-at-a-time to ensure heap // maintains its sorted order - if (_sort. - keys(_inod) != _sort.null()) - if ( UPDATED(_inew, _iold) ) - { - _hval[_inod] = _inew; - _sort.reduce(_inod , _inod) ; - } - - if (_sort. - keys(_jnod) != _sort.null()) - if ( UPDATED(_jnew, _jold) ) - { - _hval[_jnod] = _jnew; - _sort.reduce(_jnod , _jnod) ; - } - - if (_sort. - keys(_knod) != _sort.null()) - if ( UPDATED(_knew, _kold) ) - { - _hval[_knod] = _knew; - _sort.reduce(_knod , _knod) ; - } + REQUEUE (_inew, _iold, _inod) + REQUEUE (_jnew, _jold, _jnod) + REQUEUE (_knew, _kold, _knod) } } @@ -561,10 +537,11 @@ __unreferenced(_lptr); + real_type _qtmp[2] = {0, 0} ; + for ( ; _iptr != nullptr; _iptr = _iptr->_next) { - real_type _qtmp[+2]; iptr_type _TPOS = _iptr->_data.ipos() ; @@ -671,6 +648,14 @@ -------------------------------------------------------- */ + __inline_call real_type eval ( + real_type *_ppos + ) + { + auto _hint = this->null_hint(); + return eval(_ppos, _hint); + } + __normal_call real_type eval ( real_type *_ppos , hint_type &_hint diff --git a/src/libcpp/interpolate/hfun_mesh_euclidean_3.hpp b/src/libcpp/interpolate/hfun_mesh_euclidean_3.hpp index 2b5f3e3..49bc69e 100644 --- a/src/libcpp/interpolate/hfun_mesh_euclidean_3.hpp +++ b/src/libcpp/interpolate/hfun_mesh_euclidean_3.hpp @@ -35,9 +35,9 @@ * -------------------------------------------------------- * - * Last updated: 15 Jun., 2022 + * Last updated: 23 Oct., 2024 * - * Copyright 2013-2022 + * Copyright 2013-2024 * Darren Engwirda * d.engwirda@gmail.com * https://github.com/dengwirda/ @@ -308,6 +308,19 @@ # define UPDATED(__new, __old) \ std::abs(__new - __old) > _FTOL*std::abs(__new) + # define REQUEUE(__new, __old, __idx) \ + if(UPDATED(__new, __old)) { \ + if(ISALIVE(__idx)) \ + { \ + _hval[__idx] = __new; \ + _sort.reduce(__idx , __idx) ; \ + } \ + else \ + { \ + _hval[__idx] = __new; \ + _sort.push (__idx , __idx) ; \ + } } + for ( ; !_sort.empty() ; ) { iptr_type _base, _bidx ; @@ -338,16 +351,19 @@ _mesh. tri4( _cell).node(3); /*-------------------- skip cells due to sorted order */ + iptr_type _near = +0; if (_inod != _base && - !ISALIVE(_inod)) continue ; + ISALIVE(_inod)) _near++; if (_jnod != _base && - !ISALIVE(_jnod)) continue ; + ISALIVE(_jnod)) _near++; if (_knod != _base && - !ISALIVE(_knod)) continue ; + ISALIVE(_knod)) _near++; if (_lnod != _base && - !ISALIVE(_lnod)) continue ; + ISALIVE(_lnod)) _near++; + + if (_near == 0) continue ; - vals_type _hmax; + vals_type _hmax = .0; _hmax = this->_hval[_inod] ; _hmax = std::max( _hmax , this->_hval[_jnod]); @@ -377,7 +393,7 @@ vals_type _lnew = this->_hval[_lnod] ; - if (this->_dhdx.count() >1) + if (this->_dhdx.count() > +1) { /*-------------------- update adj. set, g = g(x) case */ if (eikonal_tria_3d ( @@ -400,42 +416,15 @@ // push updates one-at-a-time to ensure heap // maintains its sorted order - if (_sort. - keys(_inod) != _sort.null()) - if ( UPDATED(_inew, _iold) ) - { - _hval[_inod] = _inew; - _sort.reduce(_inod , _inod) ; - } - - if (_sort. - keys(_jnod) != _sort.null()) - if ( UPDATED(_jnew, _jold) ) - { - _hval[_jnod] = _jnew; - _sort.reduce(_jnod , _jnod) ; - } - - if (_sort. - keys(_knod) != _sort.null()) - if ( UPDATED(_knew, _kold) ) - { - _hval[_knod] = _knew; - _sort.reduce(_knod , _knod) ; - } - - if (_sort. - keys(_lnod) != _sort.null()) - if ( UPDATED(_lnew, _lold) ) - { - _hval[_lnod] = _lnew; - _sort.reduce(_lnod , _lnod) ; - } + REQUEUE (_inew, _iold, _inod) + REQUEUE (_jnew, _jold, _jnod) + REQUEUE (_knew, _kold, _knod) + REQUEUE (_lnew, _lold, _lnod) } } else - if (this->_dhdx.count()==1) + if (this->_dhdx.count() == 1) { /*-------------------- update adj. set, const. g case */ if (eikonal_tria_3d ( @@ -458,37 +447,10 @@ // push updates one-at-a-time to ensure heap // maintains its sorted order - if (_sort. - keys(_inod) != _sort.null()) - if ( UPDATED(_inew, _iold) ) - { - _hval[_inod] = _inew; - _sort.reduce(_inod , _inod) ; - } - - if (_sort. - keys(_jnod) != _sort.null()) - if ( UPDATED(_jnew, _jold) ) - { - _hval[_jnod] = _jnew; - _sort.reduce(_jnod , _jnod) ; - } - - if (_sort. - keys(_knod) != _sort.null()) - if ( UPDATED(_knew, _kold) ) - { - _hval[_knod] = _knew; - _sort.reduce(_knod , _knod) ; - } - - if (_sort. - keys(_lnod) != _sort.null()) - if ( UPDATED(_lnew, _lold) ) - { - _hval[_lnod] = _lnew; - _sort.reduce(_lnod , _lnod) ; - } + REQUEUE (_inew, _iold, _inod) + REQUEUE (_jnew, _jold, _jnod) + REQUEUE (_knew, _kold, _knod) + REQUEUE (_lnew, _lold, _lnod) } } @@ -507,6 +469,7 @@ # undef ISALIVE # undef UPDATED + # undef REQUEUE } /* @@ -611,10 +574,11 @@ __unreferenced(_lptr); + real_type _qtmp[3] = {0,0,0}; + for ( ; _iptr != nullptr; _iptr = _iptr->_next) { - real_type _qtmp[+3]; iptr_type _TPOS = _iptr->_data.ipos() ; @@ -726,6 +690,14 @@ -------------------------------------------------------- */ + __inline_call real_type eval ( + real_type *_ppos + ) + { + auto _hint = this->null_hint(); + return eval(_ppos, _hint); + } + __normal_call real_type eval ( real_type *_ppos , hint_type &_hint diff --git a/src/libcpp/iter_mesh/_zip_mesh_2.inc b/src/libcpp/iter_mesh/_zip_mesh_2.inc index ebaad39..b8f6551 100644 --- a/src/libcpp/iter_mesh/_zip_mesh_2.inc +++ b/src/libcpp/iter_mesh/_zip_mesh_2.inc @@ -35,9 +35,9 @@ * -------------------------------------------------------- * - * Last updated: 11 Dec., 2022 + * Last updated: 21 Jan., 2025 * - * Copyright 2013-2022 + * Copyright 2013-2025 * Darren Engwirda * d.engwirda@gmail.com * https://github.com/dengwirda/ @@ -69,7 +69,9 @@ iptr_type _imrk , // outer iteration marker iter_opts &_opts , // user options real_type _QLIM , // cell quality threshold + real_type _QMOV , // cell quality tolerance real_type _DLIM , // dual quality threshold + real_type _DMOV , // dual quality tolerance size_t &_nzip , // number of successful zip's size_t &_ndiv , // number of successful div's iter_stat &_tcpu // CPU timers/info @@ -139,13 +141,16 @@ typedef containers:: array sort_list ; + __unreferenced ( _QLIM ); + __unreferenced ( _QMOV ); __unreferenced ( _DLIM ); + __unreferenced ( _DMOV ); sort_list _sort ; conn_list _iadj , _jadj, _kadj ; conn_list _conn , _cset; conn_list _iset , _jset, _kset ; - real_list _qold , _qnew, _qtmp ; + fp32_list _qold , _qnew, _qtmp ; _nzip = +0 ; _ndiv = +0 ; @@ -300,9 +305,10 @@ _imrk, _tadj, _kern, _move, _nnew, _iset, _jset, _kset, - _iadj, _jadj, _kadj, - _cset, _qold, _qnew, - _qtmp, _QLIM, _tcpu) ; + _iadj, _jadj, + _kadj, _cset, + _qold, _qnew, _qtmp, + _QLIM, _QMOV, _tcpu) ; if (_move) { @@ -332,7 +338,9 @@ iptr_type _imrk , // outer iteration marker iter_opts &_opts , // user options real_type _QLIM , // cell quality threshold + real_type _QMOV , // cell quality tolerance real_type _DLIM , // dual quality threshold + real_type _DMOV , // dual quality tolerance size_t &_nzip , // number of successful zip's size_t &_ndiv , // number of successful div's iter_stat &_tcpu // CPU timers/info @@ -400,12 +408,15 @@ typedef containers:: array sort_list ; + __unreferenced ( _QLIM ); + __unreferenced ( _QMOV ); __unreferenced ( _DLIM ); + __unreferenced ( _DMOV ); sort_list _sort ; conn_list _aset , _bset, _cset ; conn_list _conn , _iset, _jset ; - real_list _qold , _qnew, _qtmp ; + fp32_list _qold , _qnew, _qtmp ; _nzip = +0 ; _ndiv = +0 ; @@ -501,8 +512,8 @@ _kern, _move, _nnew, _iset, _jset, _aset, _bset, - _qold, _qnew, - _qtmp, _QLIM, _tcpu) ; + _qold, _qnew, _qtmp, + _QLIM, _QMOV, _tcpu) ; if (_move) { @@ -554,8 +565,8 @@ _kern, _move, _nnew, _iset, _jset, _aset, _bset, _cset, - _qold, _qnew, - _qtmp, _QLIM, _tcpu) ; + _qold, _qnew, _qtmp, + _QLIM, _QMOV, _tcpu) ; if (_move) { @@ -585,7 +596,9 @@ iptr_type _imrk , // outer iteration marker iter_opts &_opts , // user options real_type _QLIM , // cell quality threshold + real_type _QMOV , // cell quality tolerance real_type _DLIM , // dual quality threshold + real_type _DMOV , // dual quality tolerance size_t &_nzip , // number of successful zip's size_t &_ndiv , // number of successful div's iter_stat &_tcpu // CPU timers/info @@ -604,15 +617,15 @@ /*--------------------- zip//div topo. cell hierarchy */ _zip_fcel( _geom, _mesh, _hfun, - _kern, _hval, - _nset, _mark, _imrk, - _opts, _QLIM, _DLIM, + _kern, _hval, _nset, _mark, + _imrk, _opts, + _QLIM, _QMOV, _DLIM, _DMOV, _nzip, _ndiv, _tcpu) ; _zip_ecel( _geom, _mesh, _hfun, - _kern, _hval, - _nset, _mark, _imrk, - _opts, _QLIM, _DLIM, + _kern, _hval, _nset, _mark, + _imrk, _opts, + _QLIM, _QMOV, _DLIM, _DMOV, _nzip, _ndiv, _tcpu) ; # ifdef __use_timers diff --git a/src/libcpp/iter_mesh/cost_mesh_2.inc b/src/libcpp/iter_mesh/cost_mesh_2.inc index 6e49f3f..e585171 100644 --- a/src/libcpp/iter_mesh/cost_mesh_2.inc +++ b/src/libcpp/iter_mesh/cost_mesh_2.inc @@ -35,9 +35,9 @@ * -------------------------------------------------------- * - * Last updated: 10 Jun., 2022 + * Last updated: 07 Apr., 2024 * - * Copyright 2013-2022 + * Copyright 2013-2024 * Darren Engwirda * d.engwirda@gmail.com * https://github.com/dengwirda/ @@ -56,8 +56,8 @@ __static_call __normal_call void_type move_okay ( - real_list &_cdst , // list of new adj. costs - real_list &_csrc , // list of old adj. costs + fp32_list &_cdst , // list of new adj. costs + fp32_list &_csrc , // list of old adj. costs iptr_type &_move , // > +0 if move acceptable real_type _good = +9.25E-01, real_type _qtol = +1.00E-04, @@ -72,55 +72,55 @@ 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(); + double _zero = + +std::numeric_limits::epsilon (); + double _0src = + +std::numeric_limits::infinity(); + double _0dst = + +std::numeric_limits::infinity(); /*--------------------- compute harmonic averages */ _good = std::pow(_good, +7./8.); - real_type _msrc, _mdst; - _msrc = (real_type) +0. ; - _mdst = (real_type) +0. ; + double _msrc = (double)+0.; + double _mdst = (double)+0.; for (auto _iter = _csrc.head(), _tend = _csrc.tend(); _iter != _tend; ++_iter ) { + double _cost = (double)*_iter; + _0src = - std::min(_0src, *_iter) ; + std::min(_0src, _cost ) ; - _msrc += std::pow( - (real_type)1. / *_iter, +8); + _msrc += std::pow ( + (double)(1. / _cost), 8 ) ; } for (auto _iter = _cdst.head(), _tend = _cdst.tend(); _iter != _tend; ++_iter ) { + double _cost = (double)*_iter; + _0dst = - std::min(_0dst, *_iter) ; - + std::min(_0dst, _cost ) ; + _mdst += std::pow ( - (real_type)1. / *_iter, +8); + (double)(1. / _cost), 8 ) ; } _msrc = std::pow( - _csrc.count() / _msrc, +1./8.0); + _csrc.count() / _msrc, 1/8.) ; _mdst = std::pow( - _cdst.count() / _mdst, +1./8.0); + _cdst.count() / _mdst, 1/8.) ; _qtol /= - std::pow(_csrc.count(), 1./8.0); + std::pow(_csrc.count(),1/8.) ; _qtol /= - std::pow(_cdst.count(), 1./8.0); + std::pow(_cdst.count(),1/8.) ; /*---------------------------- test move = "okay" */ if (_0dst >= _good) @@ -142,9 +142,9 @@ if (_move > +0) return ; } - } + /* -------------------------------------------------------- * LOOP-COST: cost vector for 1-neighbourhood. @@ -155,7 +155,7 @@ __normal_call real_type loop_cost ( mesh_type &_mesh , // mesh object conn_list &_cset , // list of adj. cells - real_list &_cost , // list of adj. costs + fp32_list &_cost , // list of adj. costs cell_kind const& // cell costs on CSET ) { @@ -211,10 +211,9 @@ } } - _qmin = - std::min (_qmin, _cscr) ; + _qmin = std::min(_qmin, _cscr) ; - _cost.push_tail (_cscr) ; + _cost.push_tail ((float)_cscr) ; } return ( _qmin ) ; @@ -224,7 +223,7 @@ __normal_call real_type loop_cost ( mesh_type &_mesh , // mesh object conn_list &_cset , // list of adj. cells - real_list &_cost , // list of adj. costs + fp32_list &_cost , // list of adj. costs dual_kind const& // dual costs on CSET ) { @@ -280,10 +279,9 @@ } } - _qmin = - std::min (_qmin, _cscr) ; + _qmin = std::min(_qmin, _cscr) ; - _cost.push_tail (_cscr) ; + _cost.push_tail ((float)_cscr) ; } return ( _qmin ) ; diff --git a/src/libcpp/iter_mesh/iter_divs_2.inc b/src/libcpp/iter_mesh/iter_divs_2.inc index 843aa1c..1564500 100644 --- a/src/libcpp/iter_mesh/iter_divs_2.inc +++ b/src/libcpp/iter_mesh/iter_divs_2.inc @@ -35,9 +35,9 @@ * -------------------------------------------------------- * - * Last updated: 11 Jun., 2022 + * Last updated: 04 Aug., 2025 * - * Copyright 2013-2022 + * Copyright 2013-2025 * Darren Engwirda * d.engwirda@gmail.com * https://github.com/dengwirda/ @@ -70,15 +70,16 @@ conn_list &_cnew , // space for adj. cells conn_list &_iset , // space for adj. cells conn_list &_jset , // space for adj. cells - real_list &_qsrc , // space for adj. costs - real_list &_qdst , // space for adj. costs - real_list &_qtmp , // space for adj. costs + fp32_list &_qsrc , // space for adj. costs + fp32_list &_qdst , // space for adj. costs + fp32_list &_qtmp , // space for adj. costs real_type _QLIM , // cell quality threshold + real_type _QMOV , // cell quality tolerance iter_stat &_tcpu , // cpu timers/info real_type _lmin // div. spacing threshold - = (real_type) +1.000E+00 , + = (real_type) +1.11111E+00 , real_type _qinc // div. quality threshold - = (real_type) +3.333E-03 + = (real_type) +3.33333E-03 ) { iptr_type static constexpr @@ -126,9 +127,13 @@ if (_cset.count()<=1) return ; /*--------------------------------- get edge h-sizing */ - real_type _ball[_last + 1] ; + real_type _ball[_last + 1] = + {(real_type) 0.} ; + real_type _prev[_last + 1] = + {(real_type)+0.} ; + for (auto _idim = - pred_type::real_dims; _idim-- != 0; ) + pred_type::geom_dims; _idim-- != 0; ) { _ball[_idim] = (real_type) +0. ; _ball[_idim] += @@ -187,7 +192,7 @@ _hbar * _lmax ) { // if more regular geom. is constructed via the edge - // div, make it easier to do so! + // div, make it easier to do so _qinc = (real_type)(1./2. * (_hbar / std::sqrt(_lsqr) - 1.0)) ; @@ -198,22 +203,22 @@ { // try to reduce large vertex valence via refinement - real_type _qerr = (real_type) -1./16. ; + real_type _qerr = -std::min(1./12., 1. - _QMOV) ; _qerr*= std::max (_ierr, _jerr ) ; - _qerr/= std::pow (_iout, +1./2.) ; // stop oscl. + _qerr/= std::pow (_iout, +1./4.) ; // stop oscl. _qinc = std::min (_qinc, _qinc + _qerr) ; } else if ( _ierr > 0 && _jerr > 0 && - (_ierr + _jerr) >= 3 ) + (_ierr + _jerr) >= 2 ) { // try to reduce large vertex valence via refinement - real_type _qerr = (real_type) -1./16. ; + real_type _qerr = -std::min(1./12., 1. - _QMOV) ; _qerr*= std::max (_ierr, _jerr ) ; - _qerr/= std::pow (_iout, +1./2.) ; // stop oscl. + _qerr/= std::pow (_iout, +1./4.) ; // stop oscl. _qinc = std::min (_qinc, _qinc + _qerr) ; @@ -370,9 +375,6 @@ iptr_type static constexpr _INUM = (iptr_type) +4; - real_type _prev[_last + 1] = - {(real_type)+0.}; - iptr_type _move = -1; for (auto _iloc = +0; _iloc != _INUM; ++_iloc ) @@ -390,7 +392,7 @@ _opts, _nptr, _prev, _kern, _move, _cnew, _qtmp, _qdst, - _minC, _QLIM, _QLIM, + _minC, _QLIM, _QMOV, _tcpu) ; if (_move <= +0 ) break; @@ -405,11 +407,10 @@ _cnew, _qdst, cell_kind()) ; move_okay( _qdst, _qsrc, _move, - std::sqrt( _QLIM) , - _qinc) ; + +1.0 , _qinc) ; - if((_okay = _move > 0 && - _QMIN >= _qmin+_qinc)) + if((_okay = (_move > 0) && + _QMIN >= (_qmin + _qinc))) { /*--------------------------------- delete old cavity */ for (auto _cell = _cset.head() ; diff --git a/src/libcpp/iter_mesh/iter_dual_2.inc b/src/libcpp/iter_mesh/iter_dual_2.inc index 833eebb..3d9196c 100644 --- a/src/libcpp/iter_mesh/iter_dual_2.inc +++ b/src/libcpp/iter_mesh/iter_dual_2.inc @@ -35,9 +35,9 @@ * -------------------------------------------------------- * - * Last updated: 11 Jun., 2022 + * Last updated: 25 Feb., 2025 * - * Copyright 2013-2022 + * Copyright 2013-2025 * Darren Engwirda * d.engwirda@gmail.com * https://github.com/dengwirda/ @@ -124,7 +124,7 @@ _ppos [_last] = _SAVE ; /*------------------ finalise gradient and accumulate */ - if (_dsup * _dsdn > (real_type)0.) + // if (_dsup * _dsdn > (real_type)0.) { _dqdw = +.5 * (_dsup + _dsdn) ; @@ -215,7 +215,7 @@ _ppos [_last] = _SAVE ; /*------------------ finalise gradient and accumulate */ - if (_dsup * _dsdn > (real_type)0.) + // if (_dsup * _dsdn > (real_type)0.) { _dqdw = +.5 * (_dsup + _dsdn) ; @@ -244,7 +244,7 @@ mesh_type &_mesh , conn_list &_conn , node_iter _node , - real_list &_cost , + fp32_list &_cost , real_type &_step , real_type &_wadj ) @@ -260,8 +260,8 @@ _wadj = (real_type) 0. ; /*------------------ calc. local characteristic scale */ - real_type _qmin = - +std::numeric_limits::infinity(); + float _qmin = + +std::numeric_limits::infinity(); real_type _bmin[_last] = { +std::numeric_limits::infinity() @@ -300,8 +300,7 @@ _wadj = _wadj / _cnum ; /*------------------ adj. gradients wrt. pos: dQ / dx */ - real_type _qlim = _qmin + - (real_type)+1.0E-002 ; + float _qlim = _qmin + (float)+1.0E-002 ; real_type _dmax = -std::numeric_limits::infinity() ; diff --git a/src/libcpp/iter_mesh/iter_mesh_2.hpp b/src/libcpp/iter_mesh/iter_mesh_2.hpp index 268af63..0b3e68e 100644 --- a/src/libcpp/iter_mesh/iter_mesh_2.hpp +++ b/src/libcpp/iter_mesh/iter_mesh_2.hpp @@ -35,9 +35,9 @@ * -------------------------------------------------------- * - * Last updated: 12 Dec., 2022 + * Last updated: 04 Dec., 2024 * - * Copyright 2013-2022 + * Copyright 2013-2024 * Darren Engwirda, * Marc Tunnell * d.engwirda@gmail.com @@ -121,6 +121,9 @@ ::array< iptr_type > iptr_list ; typedef containers ::array< size_t > uint_list ; + + typedef containers + ::array< fp32_t > fp32_list ; typedef containers ::array< real_type > real_list ; @@ -449,9 +452,9 @@ if (_opts.verb() >= 0 ) { _dump.push( - "#------------------------------------------------------------\n" - "# |MOVE.| |FLIP.| |MERGE| |SPLIT| \n" - "#------------------------------------------------------------\n" +"#-----------------------------------------------------------------------\n" +"# |MOVE.| |FLIP.| |MERGE| |SPLIT| \n" +"#-----------------------------------------------------------------------\n" ) ; } @@ -488,9 +491,9 @@ static constexpr ITER_MAX_ = max_subit ; real_type _QMIN = init_cost (_mesh, _opts) ; - real_type _QMOV = +0. ; - real_type _DMOV = +0. ; - + real_type _QMOV = 0.0; + real_type _DMOV = 0.0; + real_list _hval ; // cache h(x) node val. _hval.set_count( _mesh. node().count(), @@ -501,7 +504,7 @@ { /*------------------------------ set-up current iter. */ init_mark(_mesh , - _mark,std::max(_iter - 1, +0)) ; + _mark, std::max(_iter - 1, 0)) ; _nset.set_count( +0); @@ -511,29 +514,25 @@ size_t _ndiv = +0 ; /*------------------------------ scale quality limits */ - iptr_type _nsub = _iter +1 ; + iptr_type _nsub = _iter + 1 ; - _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 _RMIN = _QMIN * - (real_type)(0.90 + 1./20 * (_iter - 1)) ; - real_type _RMAX = _QMIN * - (real_type)(0.90 + 1./30 * (_iter - 1)) ; + real_type _QLOW = _QMIN * // hill climbing + (real_type)(.875 + .05 * (_iter - 1)) ; + real_type _QLIM = + std::min (_opts.qlim(), _QLOW) ; real_type _DLIM = - (real_type)+1.-_opts.qtol() ; + (real_type) +1.0 - _opts.qtol() ; - _DMOV = std::max(_DMOV, _DLIM) ; - _DMOV = std::min(_DMOV, _RMAX) ; + real_type constexpr _TINY = 1.E-02 ; - real_type _QLIM = std::min ( - _opts.qlim(),_RMIN) ; - - _QMOV = std::max(_QMOV, _QLIM) ; - _QMOV = std::min(_QMOV, _RMAX) ; + _QMOV = std::max(_QMOV, std::min( + 1., _QLIM + _TINY * (_iter - 1))); + _DMOV = std::max(_DMOV, std::min( + 1., _DLIM + _TINY * (_iter - 1))); /*------------------------------ 1. CELL GEOM. PASSES */ @@ -700,7 +699,7 @@ _zip_mesh( _geom, _mesh , _hfun , _kern, _hval, _nset , _mark, _iter, _opts , - _QLIM, _DLIM, + _QLIM, _QMOV, _DLIM , _DMOV , _nzip, _ndiv, _tcpu ) ; } @@ -742,27 +741,26 @@ if (_opts.verb() >= 0) { std::stringstream _sstr ; - _sstr << std::setw(11) << _nmov - << std::setw(13) << _nflp - << std::setw(13) << _nzip - << std::setw(13) << _ndiv + _sstr << std::setw(12) << _nmov + << std::setw(14) << _nflp + << std::setw(14) << _nzip + << std::setw(14) << _ndiv << "\n" ; _dump.push(_sstr.str()) ; } - /*------------------------------ has iter. converged? */ - _QMOV = std::max(_QLIM, 1. - + /*------------------------------ stop non-convergence */ + _QMOV = std::max(_QMOV, 1. - ((real_type) _nmov) / _mesh.node().count()) ; - _DMOV = std::max(_DLIM, 1. - + _DMOV = std::max(_DMOV, 1. - ((real_type) _nmov) / _mesh.node().count()) ; - // if (_nset.count() == 0) break ; - if (_nmov == +0 && - _nzip == +0 && - _ndiv == +0 && + /*------------------------------ has iter. converged? */ + if (_nmov == +0 && + // _nzip == +0 && _ndiv == +0 && _nflp == +0 ) break ; } @@ -773,120 +771,92 @@ _dump.push("**TIMING statistics...\n") ; _dump.push(" MOVE-NODE: "); - _dump.push( - std::to_string(_tcpu._move_node)) ; + _dump.push(std::to_string(_tcpu._move_node)); _dump.push("\n"); _dump.push(" *init-node: "); - _dump.push( - std::to_string(_tcpu._init_node)) ; + _dump.push(std::to_string(_tcpu._init_node)); _dump.push("\n"); _dump.push(" *part-node: "); - _dump.push( - std::to_string(_tcpu._part_node)) ; + _dump.push(std::to_string(_tcpu._part_node)); _dump.push("\n"); _dump.push(" *core-node: "); - _dump.push( - std::to_string(_tcpu._core_node)) ; + _dump.push(std::to_string(_tcpu._core_node)); _dump.push("\n"); _dump.push(" *seqs-node: "); - _dump.push( - std::to_string(_tcpu._seqs_node)) ; + _dump.push(std::to_string(_tcpu._seqs_node)); _dump.push("\n"); _dump.push(" *para-node: "); - _dump.push( - std::to_string(_tcpu._para_node)) ; + _dump.push(std::to_string(_tcpu._para_node)); // _dump.push("\n"); // _dump.push(" *xDIR-node: "); - // _dump.push( - // std::to_string(_tcpu._ldir_node)) ; + // _dump.push(std::to_string(_tcpu._ldir_node)); // _dump.push("\n"); // _dump.push(" *xOPT-node: "); - // _dump.push( - // std::to_string(_tcpu._lopt_node)) ; + // _dump.push(std::to_string(_tcpu._lopt_node)); _dump.push("\n\n"); _dump.push(" MOVE-DUAL: "); - _dump.push( - std::to_string(_tcpu._move_dual)) ; + _dump.push(std::to_string(_tcpu._move_dual)); _dump.push("\n"); _dump.push(" *init-dual: "); - _dump.push( - std::to_string(_tcpu._init_dual)) ; + _dump.push(std::to_string(_tcpu._init_dual)); _dump.push("\n"); _dump.push(" *part-dual: "); - _dump.push( - std::to_string(_tcpu._part_dual)) ; + _dump.push(std::to_string(_tcpu._part_dual)); _dump.push("\n"); _dump.push(" *core-dual: "); - _dump.push( - std::to_string(_tcpu._core_dual)) ; + _dump.push(std::to_string(_tcpu._core_dual)); _dump.push("\n"); _dump.push(" *seqs-dual: "); - _dump.push( - std::to_string(_tcpu._seqs_dual)) ; + _dump.push(std::to_string(_tcpu._seqs_dual)); _dump.push("\n"); _dump.push(" *para-dual: "); - _dump.push( - std::to_string(_tcpu._para_dual)) ; + _dump.push(std::to_string(_tcpu._para_dual)); // _dump.push("\n"); // _dump.push(" *xDIR-dual: "); - // _dump.push( - // std::to_string(_tcpu._ldir_dual)) ; + // _dump.push(std::to_string(_tcpu._ldir_dual)); // _dump.push("\n"); // _dump.push(" *xOPT-dual: "); - // _dump.push( - // std::to_string(_tcpu._lopt_dual)) ; + // _dump.push(std::to_string(_tcpu._lopt_dual)); _dump.push("\n\n"); _dump.push(" TOPO-FLIP: "); - _dump.push( - std::to_string(_tcpu._topo_flip)) ; + _dump.push(std::to_string(_tcpu._topo_flip)); _dump.push("\n"); _dump.push(" *init-flip: "); - _dump.push( - std::to_string(_tcpu._init_flip)) ; + _dump.push(std::to_string(_tcpu._init_flip)); _dump.push("\n"); _dump.push(" *core-flip: "); - _dump.push( - std::to_string(_tcpu._core_flip)) ; + _dump.push(std::to_string(_tcpu._core_flip)); _dump.push("\n\n"); _dump.push(" TOPO-ZIPS: "); - _dump.push( - std::to_string(_tcpu._topo_zips)) ; + _dump.push(std::to_string(_tcpu._topo_zips)); _dump.push("\n"); _dump.push(" *init-zips: "); - _dump.push( - std::to_string(_tcpu._init_zips)) ; + _dump.push(std::to_string(_tcpu._init_zips)); _dump.push("\n"); _dump.push(" *core-divs: "); - _dump.push( - std::to_string(_tcpu._core_divs)) ; + _dump.push(std::to_string(_tcpu._core_divs)); _dump.push("\n"); _dump.push(" *core-zips: "); - _dump.push( - std::to_string(_tcpu._core_zips)) ; + _dump.push(std::to_string(_tcpu._core_zips)); _dump.push("\n\n"); _dump.push(" PARTITION: "); - _dump.push( - std::to_string(_tcpu._full_part)) ; + _dump.push(std::to_string(_tcpu._full_part)); _dump.push("\n"); _dump.push(" *tree-part: "); - _dump.push( - std::to_string(_tcpu._tree_part)) ; + _dump.push(std::to_string(_tcpu._tree_part)); // _dump.push("\n"); // _dump.push(" *redo-part: "); - // _dump.push( - // std::to_string(_tcpu._redo_part)) ; + // _dump.push(std::to_string(_tcpu._redo_part)); _dump.push("\n"); _dump.push(" *part-part: "); - _dump.push( - std::to_string(_tcpu._part_part)) ; + _dump.push(std::to_string(_tcpu._part_part)); _dump.push("\n"); _dump.push(" *seqs-part: "); - _dump.push( - std::to_string(_tcpu._seqs_part)) ; + _dump.push(std::to_string(_tcpu._seqs_part)); _dump.push("\n"); _dump.push("\n"); diff --git a/src/libcpp/iter_mesh/iter_mesh_euclidean_2.hpp b/src/libcpp/iter_mesh/iter_mesh_euclidean_2.hpp index d70b6f2..04af6f6 100644 --- a/src/libcpp/iter_mesh/iter_mesh_euclidean_2.hpp +++ b/src/libcpp/iter_mesh/iter_mesh_euclidean_2.hpp @@ -35,9 +35,9 @@ * -------------------------------------------------------- * - * Last updated: 15 Jul., 2021 + * Last updated: 08 Aug., 2025 * - * Copyright 2013-2021 + * Copyright 2013-2025 * Darren Engwirda * d.engwirda@gmail.com * https://github.com/dengwirda/ @@ -82,7 +82,7 @@ /*------------------------- node type for ITER-MESH-2 */ public : - iptr_type _hidx = 0 ; + iptr_type _hidx =-1 ; iptr_type _itag = 0 ; char_type _fdim = 0 ; @@ -130,6 +130,7 @@ public : iptr_type _itag = 0 ; + iptr_type _hidx =-1 ; public : @@ -141,6 +142,14 @@ ) const { return this->_itag ; } + __inline_call iptr_type & hidx ( + ) + { return this->_hidx ; + } + __inline_call iptr_type const& hidx ( + ) const + { return this->_hidx ; + } } ; class tri3_type : public tri3_base @@ -149,6 +158,7 @@ public : iptr_type _itag = 0 ; + iptr_type _hidx =-1 ; public : @@ -160,6 +170,14 @@ ) const { return this->_itag ; } + __inline_call iptr_type & hidx ( + ) + { return this->_hidx ; + } + __inline_call iptr_type const& hidx ( + ) const + { return this->_hidx ; + } } ; class quad_type : public quad_base @@ -168,6 +186,7 @@ public : iptr_type _itag = 0 ; + iptr_type _hidx =-1 ; public : @@ -179,6 +198,14 @@ ) const { return this->_itag ; } + __inline_call iptr_type & hidx ( + ) + { return this->_hidx ; + } + __inline_call iptr_type const& hidx ( + ) const + { return this->_hidx ; + } } ; typedef mesh::mesh_complex_2 < diff --git a/src/libcpp/iter_mesh/iter_mesh_euclidean_3.hpp b/src/libcpp/iter_mesh/iter_mesh_euclidean_3.hpp index 30fd6cf..f592dec 100644 --- a/src/libcpp/iter_mesh/iter_mesh_euclidean_3.hpp +++ b/src/libcpp/iter_mesh/iter_mesh_euclidean_3.hpp @@ -35,9 +35,9 @@ * -------------------------------------------------------- * - * Last updated: 15 Jul., 2021 + * Last updated: 08 Aug., 2025 * - * Copyright 2013-2021 + * Copyright 2013-2025 * Darren Engwirda * d.engwirda@gmail.com * https://github.com/dengwirda/ @@ -91,7 +91,7 @@ template < /*------------------------- node type for ITER-MESH-3 */ public : - iptr_type _hidx = 0 ; + iptr_type _hidx =-1 ; iptr_type _itag = 0 ; char_type _fdim = 0 ; @@ -139,6 +139,7 @@ template < public : iptr_type _itag = 0 ; + iptr_type _hidx =-1 ; public : @@ -150,6 +151,14 @@ template < ) const { return this->_itag ; } + __inline_call iptr_type & hidx ( + ) + { return this->_hidx ; + } + __inline_call iptr_type const& hidx ( + ) const + { return this->_hidx ; + } } ; class tri3_type : public tri3_base @@ -158,6 +167,7 @@ template < public : iptr_type _itag = 0 ; + iptr_type _hidx =-1 ; public : @@ -169,6 +179,14 @@ template < ) const { return this->_itag ; } + __inline_call iptr_type & hidx ( + ) + { return this->_hidx ; + } + __inline_call iptr_type const& hidx ( + ) const + { return this->_hidx ; + } } ; class quad_type : public quad_base @@ -177,6 +195,7 @@ template < public : iptr_type _itag = 0 ; + iptr_type _hidx =-1 ; public : @@ -188,6 +207,14 @@ template < ) const { return this->_itag ; } + __inline_call iptr_type & hidx ( + ) + { return this->_hidx ; + } + __inline_call iptr_type const& hidx ( + ) const + { return this->_hidx ; + } } ; class tri4_type : public tri4_base @@ -196,6 +223,7 @@ template < public : iptr_type _itag = 0 ; + iptr_type _hidx =-1 ; public : @@ -207,6 +235,14 @@ template < ) const { return this->_itag ; } + __inline_call iptr_type & hidx ( + ) + { return this->_hidx ; + } + __inline_call iptr_type const& hidx ( + ) const + { return this->_hidx ; + } } ; class hexa_type : public hexa_base @@ -215,6 +251,7 @@ template < public : iptr_type _itag = 0 ; + iptr_type _hidx =-1 ; public : @@ -226,6 +263,14 @@ template < ) const { return this->_itag ; } + __inline_call iptr_type & hidx ( + ) + { return this->_hidx ; + } + __inline_call iptr_type const& hidx ( + ) const + { return this->_hidx ; + } } ; class wedg_type : public wedg_base @@ -234,6 +279,7 @@ template < public : iptr_type _itag = 0 ; + iptr_type _hidx =-1 ; public : @@ -245,6 +291,14 @@ template < ) const { return this->_itag ; } + __inline_call iptr_type & hidx ( + ) + { return this->_hidx ; + } + __inline_call iptr_type const& hidx ( + ) const + { return this->_hidx ; + } } ; class pyra_type : public pyra_base @@ -253,6 +307,7 @@ template < public : iptr_type _itag = 0 ; + iptr_type _hidx =-1 ; public : @@ -264,6 +319,14 @@ template < ) const { return this->_itag ; } + __inline_call iptr_type & hidx ( + ) + { return this->_hidx ; + } + __inline_call iptr_type const& hidx ( + ) const + { return this->_hidx ; + } } ; typedef mesh::mesh_complex_3 < diff --git a/src/libcpp/iter_mesh/iter_node_2.inc b/src/libcpp/iter_mesh/iter_node_2.inc index 3d44a8b..2f6ffd3 100644 --- a/src/libcpp/iter_mesh/iter_node_2.inc +++ b/src/libcpp/iter_mesh/iter_node_2.inc @@ -35,9 +35,9 @@ * -------------------------------------------------------- * - * Last updated: 30 Dec., 2022 + * Last updated: 08 Aug., 2025 * - * Copyright 2013-2022 + * Copyright 2013-2025 * Darren Engwirda * d.engwirda@gmail.com * https://github.com/dengwirda/ @@ -114,7 +114,8 @@ &_jptr->pval(+0), &_kptr->pval(+0)) ; - _tmag = std::abs(_tmag) ; + _tmag = std::max( + (real_type)+0.0, _tmag) ; /*------------------------------------- odt weighting */ pred_type::proj_node( @@ -129,7 +130,7 @@ EVALHFUN( _knod , _kptr ) real_type _hbal = _hfun.eval( - &_ball[0], _node->hidx()) ; + &_ball[0], _tptr->hidx()) ; real_type _irho = _hval[_imid] / _hval[_inod] ; @@ -234,7 +235,8 @@ &_kptr->pval(+0), &_lptr->pval(+0)) ; - _qmag = std::abs(_qmag) ; + _qmag = std::max( + (real_type)+0.0, _qmag) ; /*------------------------------------- odt weighting */ pred_type::proj_node( @@ -250,7 +252,7 @@ EVALHFUN( _lnod , _lptr ) real_type _hbal = _hfun.eval( - &_ball[0], _node->hidx()) ; + &_ball[0], _qptr->hidx()) ; real_type _irho = _hval[_imid] / _hval[_inod] ; @@ -319,10 +321,9 @@ _last = pred_type::geom_dims + 0; real_type _move[_last + 0] = { - (real_type) +0.0} ; + (real_type) +0.0}; - _ladj = - (real_type) +0.0 ; + _ladj = (real_type) +0.0 ; real_type _wsum = +std::numeric_limits::epsilon(); @@ -446,17 +447,17 @@ &_iptr->pval(+0), &_kptr->pval(+0), true) ; - real_type _1mag = - std::abs(pred_type::tri3_mass ( + real_type _1mag = std::max( + pred_type::tri3_mass( &_iptr->pval(+0), &_1bal [+0] , - &_0bal [+0] ) ) ; + &_0bal [+0]), (real_type)+0.0); - real_type _2mag = - std::abs(pred_type::tri3_mass ( + real_type _2mag = std::max( + pred_type::tri3_mass( &_iptr->pval(+0), &_0bal [+0] , - &_2bal [+0] ) ) ; + &_2bal [+0]), (real_type)+0.0); /*------------------------------------- cvt weighting */ pred_type::proj_node( @@ -478,7 +479,6 @@ EVALHFUN( _jnod , _jptr ) EVALHFUN( _knod , _kptr ) - real_type _irho = (real_type)1. ; real_type _0rho = _hval[_inod] * (real_type)1./3. + _hval[_jnod] * (real_type)1./3. + @@ -493,15 +493,9 @@ _hval[_knod] * (real_type)1./2. ; real_type _0val = _hfun.eval( // eval. on dual - &_0bal[0], _node->hidx()) ; - real_type _1val = _hfun.eval( - &_1bal[0], _node->hidx()) ; - real_type _2val = _hfun.eval( - &_2bal[0], _node->hidx()) ; + &_0bal[0], _tptr->hidx()) ; _0rho = +.5 * (_0rho + _0val) ; - _1rho = +.5 * (_1rho + _1val) ; - _2rho = +.5 * (_2rho + _2val) ; _0rho = std::pow( _hval[_inod] / _0rho, +3) ; @@ -518,19 +512,17 @@ _1mag * ( _0rho * _0bal[_idim] + _1rho * _1bal[_idim] + - _irho * _iptr->pval(_idim) - ) + + _iptr-> pval(_idim) ) + // 2nd sub-tria in voro. cell _2mag * ( _0rho * _0bal[_idim] + _2rho * _2bal[_idim] + - _irho * _iptr->pval(_idim) - ) ; + _iptr-> pval(_idim) ) ; } - _wsum += _1mag * (_0rho+_1rho+_irho); - _wsum += _2mag * (_0rho+_2rho+_irho); + _wsum += _1mag * (_0rho + _1rho + 1.) ; + _wsum += _2mag * (_0rho + _2rho + 1.) ; _ladj += _lsqr ; @@ -632,17 +624,17 @@ &_iptr->pval(+0), &_lptr->pval(+0), true) ; - real_type _1mag = - std::abs(pred_type::tri3_mass ( + real_type _1mag = std::max( + pred_type::tri3_mass( &_iptr->pval(+0), &_1bal [+0] , - &_0bal [+0] ) ) ; + &_0bal [+0]), (real_type)+0.0); - real_type _2mag = - std::abs(pred_type::tri3_mass ( + real_type _2mag = std::max( + pred_type::tri3_mass( &_iptr->pval(+0), &_0bal [+0] , - &_2bal [+0] ) ) ; + &_2bal [+0]), (real_type)+0.0); /*------------------------------------- cvt weighting */ pred_type::proj_node( @@ -665,7 +657,6 @@ EVALHFUN( _knod , _kptr ) EVALHFUN( _lnod , _lptr ) - real_type _irho = (real_type)1. ; real_type _0rho = _hval[_inod] * (real_type)1./4. + _hval[_jnod] * (real_type)1./4. + @@ -681,15 +672,9 @@ _hval[_lnod] * (real_type)1./2. ; real_type _0val = _hfun.eval( // eval. on dual - &_0bal[0], _node->hidx()) ; - real_type _1val = _hfun.eval( - &_1bal[0], _node->hidx()) ; - real_type _2val = _hfun.eval( - &_2bal[0], _node->hidx()) ; + &_0bal[0], _qptr->hidx()) ; _0rho = +.5 * (_0rho + _0val) ; - _1rho = +.5 * (_1rho + _1val) ; - _2rho = +.5 * (_2rho + _2val) ; _0rho = std::pow( _hval[_inod] / _0rho, +3) ; @@ -706,19 +691,19 @@ _1mag * ( _0rho * _0bal[_idim] + _1rho * _1bal[_idim] + - _irho * _iptr->pval(_idim) + _iptr-> pval(_idim) ) + // 2nd sub-tria in voro. cell _2mag * ( _0rho * _0bal[_idim] + _2rho * _2bal[_idim] + - _irho * _iptr->pval(_idim) + _iptr-> pval(_idim) ) ; } - _wsum += _1mag * (_0rho+_1rho+_irho); - _wsum += _2mag * (_0rho+_2rho+_irho); + _wsum += _1mag * (_0rho + _1rho + 1.) ; + _wsum += _2mag * (_0rho + _2rho + 1.) ; _ladj += _lsqr ; @@ -755,10 +740,9 @@ _last = pred_type::geom_dims + 0; real_type _move[_last + 0] = { - (real_type) +0.0} ; + (real_type) +0.0}; - _ladj = - (real_type) +0.0 ; + _ladj = (real_type) +0.0 ; real_type _wsum = +std::numeric_limits::epsilon(); @@ -822,7 +806,7 @@ ) { iptr_type static constexpr - _last = pred_type::geom_dims + 0; + _last = pred_type::geom_dims + 0 ; /*------------------------------------- cell indexing */ auto _tptr = @@ -842,40 +826,26 @@ /*------------------------------------- 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. ; - } - + for (auto _idim = pred_type::geom_dims; _idim-- != +0; ) { + _pmid[_idim] = (real_type) 1./3. * ( + _iptr->pval(_idim) + + _jptr->pval(_idim) + + _kptr->pval(_idim) ) ; + _bmin[_idim] = std::min( - _bmin[_idim], - _pmid[_idim]) ; + _bmin[_idim], _pmid[_idim]) ; _bmax[_idim] = std::max( - _bmax[_idim], - _pmid[_idim]) ; + _bmax[_idim], _pmid[_idim]) ; } - + /*------------------------------------- cell "length" */ real_type _lsqr = pred_type::length_sq ( - _pmid, &_node->pval(0)) ; + _pmid, &_node->pval(0)) ; _ladj += _lsqr ; } @@ -897,7 +867,7 @@ { real_type static const _HINC = std::pow(std::numeric_limits - ::epsilon(), .50) ; + ::epsilon(), +0.75) ; /*------------------------------------- cell indexing */ auto _ppos = &_node->pval(0); @@ -954,9 +924,9 @@ _ppos[_idim] = _SAVE [_idim] ; /*------------------ finalise gradient and accumulate */ - if (_dsup * _dsdn > (real_type)0.) + //if (_dsup * _dsdn >= (real_type)+0.) _DQDX [ _idim ] += - (real_type)+.5 * (_dsup + _dsdn) ; + (real_type) +0.50 * (_dsup + _dsdn) ; } } @@ -981,7 +951,7 @@ ) { iptr_type static constexpr - _last = pred_type::geom_dims + 0; + _last = pred_type::geom_dims + 0 ; /*------------------------------------- cell indexing */ auto _qptr = @@ -1008,38 +978,23 @@ 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; ) - { + _pmid[_idim] = (real_type) 1./4. * ( + _iptr->pval(_idim) + + _jptr->pval(_idim) + + _kptr->pval(_idim) + + _lptr->pval(_idim) ) ; + _bmin[_idim] = std::min( - _bmin[_idim], - _pmid[_idim]) ; + _bmin[_idim], _pmid[_idim]) ; _bmax[_idim] = std::max( - _bmax[_idim], - _pmid[_idim]) ; + _bmax[_idim], _pmid[_idim]) ; } /*------------------------------------- cell "length" */ real_type _lsqr = pred_type::length_sq ( - _pmid, &_node->pval(0)) ; + _pmid, &_node->pval(0)) ; _ladj += _lsqr ; } @@ -1061,7 +1016,7 @@ { real_type static const _HINC = std::pow(std::numeric_limits - ::epsilon(), .50) ; + ::epsilon(), +0.75) ; /*------------------------------------- cell indexing */ auto _ppos = &_node->pval(0); @@ -1122,9 +1077,9 @@ _ppos[_idim] = _SAVE [_idim] ; /*------------------ finalise gradient and accumulate */ - if (_dsup * _dsdn > (real_type)0.) + //if (_dsup * _dsdn >= (real_type)+0.) _DQDX [ _idim ] += - (real_type)+.5 * (_dsup + _dsdn) ; + (real_type) +0.50 * (_dsup + _dsdn) ; } } @@ -1147,7 +1102,7 @@ mesh_type &_mesh , conn_list &_conn , node_iter _node , - real_list &_cost , + fp32_list &_cost , real_type *_line , real_type &_ladj ) @@ -1162,8 +1117,8 @@ _ladj = (real_type) 0. ; /*------------------ calc. local characteristic scale */ - real_type _qmin = - +std::numeric_limits::infinity(); + float _qmin = + +std::numeric_limits::infinity(); real_type _bmin[_last] = { +std::numeric_limits::infinity() @@ -1202,8 +1157,8 @@ _ladj = std::sqrt (_ladj / _cnum) ; /*------------------ adj. gradients wrt. pos: dQ / dx */ - real_type _qlim = _qmin + - (real_type) +1.0E-002 ; + float _qlim = _qmin + + (float ) +1.0E-002 ; real_type _DQDX[_last] = { (real_type) +0.0E+000} ; @@ -1215,8 +1170,7 @@ for (auto _idim = pred_type::geom_dims; _idim-- != +0; ) { - _SAVE[_idim] = - _node->pval(_idim) ; + _SAVE[_idim] = _node->pval(_idim); } iptr_type _lnum = 0, _hnum = 1, _nnum = 0; @@ -1275,8 +1229,7 @@ for (auto _idim = pred_type::geom_dims; _idim-- != +0; ) { - _line[_idim] - = (real_type) +0. ; + _line[_idim] = (real_type)+0.; } } else diff --git a/src/libcpp/iter_mesh/iter_zips_2.inc b/src/libcpp/iter_mesh/iter_zips_2.inc index 2c494fd..87b752b 100644 --- a/src/libcpp/iter_mesh/iter_zips_2.inc +++ b/src/libcpp/iter_mesh/iter_zips_2.inc @@ -35,9 +35,9 @@ * -------------------------------------------------------- * - * Last updated: 11 Dec., 2022 + * Last updated: 04 Aug., 2025 * - * Copyright 2013-2022 + * Copyright 2013-2025 * Darren Engwirda * d.engwirda@gmail.com * https://github.com/dengwirda/ @@ -324,15 +324,16 @@ conn_list &_iadj , // space for adj. cells conn_list &_jadj , // space for adj. cells conn_list &_cset , // space for adj. cells - real_list &_qsrc , // space for adj. costs - real_list &_qdst , // space for adj. costs - real_list &_qtmp , // space for adj. costs + fp32_list &_qsrc , // space for adj. costs + fp32_list &_qdst , // space for adj. costs + fp32_list &_qtmp , // space for adj. costs real_type _QLIM , // cell quality threshold + real_type _QMOV , // cell quality tolerance iter_stat &_tcpu , // cpu timers/info real_type _lmax // zip. spacing threshold - = (real_type) +8.888E-01 , + = (real_type) +8.91667E-01 , real_type _qinc // zip. quality threshold - = (real_type) +3.333E-03 + = (real_type) +3.33333E-03 ) { iptr_type static constexpr @@ -466,16 +467,19 @@ // bail-out early if the topological defect would be // made worse if the zip is done - if (_dnew > _dnow + 1) return; + if (_dnew > _dnow + 0) return; // if more regular topo. is constructed via the edge // zip, make it easier to do so! + real_type _qtol = + std::min( +1./24., +1. - _QMOV) ; + real_type _qerr = (real_type) - -1./16.*std::max (_ierr, _jerr) ; + -_qtol *std::max(0, _dnow-_dnew) ; real_type _lerr = (real_type) - +1./16.*std::max (_ierr, _jerr) ; + +_qtol *std::max(0, _dnow-_dnew) ; if (_dnew < _dnow - 0) { // no oscl. wrt. div @@ -638,7 +642,7 @@ _opts, _nptr, _prev, _kern, _move, _cset, _qtmp, _qdst, - _minC, _QLIM, _QLIM, + _minC, _QLIM, _QMOV, _tcpu) ; if (_move <= +0 ) break; @@ -653,11 +657,10 @@ _cset, _qdst, cell_kind()) ; move_okay( _qdst, _qsrc, _move, - std::sqrt( _QLIM) , - _qinc) ; + +1.0 , _qinc) ; - if((_okay = _move > 0 && - _QMIN >= _qmin+_qinc)) + if((_okay = (_move > 0) && + _QMIN >= (_qmin + _qinc))) { /*--------------------------------- delete old cavity */ _pop_sets( _mesh , _iset ); @@ -704,15 +707,16 @@ conn_list &_jadj , // space for adj. cells conn_list &_kadj , // space for adj. cells conn_list &_cset , // space for adj. cells - real_list &_qsrc , // space for adj. costs - real_list &_qdst , // space for adj. costs - real_list &_qtmp , // space for adj. costs + fp32_list &_qsrc , // space for adj. costs + fp32_list &_qdst , // space for adj. costs + fp32_list &_qtmp , // space for adj. costs real_type _QLIM , // cell quality threshold + real_type _QMOV , // cell quality tolerance iter_stat &_tcpu , // cpu timers/info real_type _lmax // zip. spacing threshold - = (real_type) +8.666E-01 , + = (real_type) +8.91667E-01 , real_type _qinc // zip. quality threshold - = (real_type) +3.333E-03 + = (real_type) +3.33333E-03 ) { iptr_type static constexpr @@ -801,7 +805,7 @@ auto _nerr = (iptr_type)(_DEG_TRIA3-_ndeg) ; - auto _dnew = std::abs(_nerr) ; + auto _dnew =(std::abs(_nerr) * 3) / 2 ; auto _dnow = std::abs(_ierr) + std::abs(_jerr) + std::abs(_kerr) ; @@ -811,6 +815,29 @@ if (_dnew > _dnow + 0) return ; + // if more regular topo. is constructed via the edge + // zip, make it easier to do so! + + real_type _qtol = + std::min( +1./36., +1. - _QMOV) ; + + real_type _qerr = (real_type) + -_qtol *std::max(0, _dnow-_dnew) ; + + real_type _lerr = (real_type) + +_qtol *std::max(0, _dnow-_dnew) ; + + if (_dnew < _dnow - 0) + { // no oscl. wrt. div + _qerr/= std::pow ( _iout, +1./4.) ; + _qinc = std::min ( _qinc, + _qinc + _qerr) ; + + _lerr/= std::pow ( _iout, +1./4.) ; + _lmax = std::max ( _lmax, + _lmax + _lerr) ; + } + /*--------------------------------- get face h-sizing */ real_type _pbal[ _last + 1 ] ; pred_type::tri3_ball ( _pbal , @@ -964,7 +991,7 @@ _opts, _nptr, _prev, _kern, _move, _cset, _qtmp, _qdst, - _minC, _QLIM, _QLIM, + _minC, _QLIM, _QMOV, _tcpu) ; if (_move <= +0 ) break; @@ -979,11 +1006,10 @@ _cset, _qdst, cell_kind()) ; move_okay( _qdst, _qsrc, _move, - std::sqrt( _QLIM) , - _qinc) ; + +1.0 , _qinc) ; - if((_okay = _move > 0 && - _QMIN >= _qmin+_qinc)) + if((_okay = (_move > 0) && + _QMIN >= (_qmin + _qinc))) { /*--------------------------------- delete old cavity */ _pop_sets( _mesh , _iset ); diff --git a/src/libcpp/iter_mesh/move_mesh_2.inc b/src/libcpp/iter_mesh/move_mesh_2.inc index 97f1289..cfc6f41 100644 --- a/src/libcpp/iter_mesh/move_mesh_2.inc +++ b/src/libcpp/iter_mesh/move_mesh_2.inc @@ -35,9 +35,9 @@ * -------------------------------------------------------- * - * Last updated: 11 Dec., 2022 + * Last updated: 27 Jul., 2025 * - * Copyright 2013-2022 + * Copyright 2013-2025 * Darren Engwirda, * Marc Tunnell * d.engwirda@gmail.com @@ -72,8 +72,8 @@ kern_kind _kern , // optim. kernel selector iptr_type &_move , // > 0 if move successful conn_list &_conn , // list of adj. cells - real_list &_qold , // list of old adj. costs - real_list &_qnew , // list of new adj. costs + fp32_list &_qold , // list of old adj. costs + fp32_list &_qnew , // list of new adj. costs real_type _QMIN , // minimum adj. old costs real_type _QLIM , // cell quality threshold real_type _QMOV , @@ -114,8 +114,8 @@ kern_kind _kern , // optim. kernel selector iptr_type &_move , // > 0 if move successful conn_list &_conn , // list of adj. cells - real_list &_qold , // list of old adj. costs - real_list &_qnew , // list of new adj. costs + fp32_list &_qold , // list of old adj. costs + fp32_list &_qnew , // list of new adj. costs real_type _QMIN , // minimum adj. old costs real_type _QLIM , // cell quality threshold real_type _QMOV , @@ -207,13 +207,8 @@ _xeps = std::pow(_xeps, 2) ; _xtol = std::pow(_xtol, 2) ; - real_type _SCAL[_ITER] = { // overrelaxation - (real_type) std::sqrt( 2.0 ) , - (real_type) +1.00, - (real_type) +0.50, - (real_type) +0.25, - (real_type) +.125 } ; - + real_type _SCAL = 4. / 3.; // overrelaxation + /*---------------- do backtracking line search iter's */ // ifdef __use_timers @@ -236,8 +231,7 @@ _iter != _ITER; ++_iter ) { /*---------------- push update along search direction */ - real_type _scal = _SCAL[_iter]; - + real_type _scal = _SCAL; real_type _zeta = _opts._zeta * std::min ((real_type)1.,_scal) ; @@ -277,6 +271,8 @@ if (_lmov <= _XEPS * _lsqr) break; //_move = +1 ; return ; + + _SCAL *= (real_type) 0.5 ; /*---------------- test quasi-monotonicity w.r.t. Q^T */ _qnew.set_count(0) ; @@ -341,8 +337,8 @@ real_type _last , // lagged line direction iptr_type &_move , // > 0 if move successful conn_list &_conn , // list of adj. cells - real_list &_dold , // list of old adj. costs - real_list &_dnew , // list of new adj. costs + fp32_list &_dold , // list of old adj. costs + fp32_list &_dnew , // list of new adj. costs real_type _DMIN , // minimum adj. old costs real_type _DLIM , // dual quality threshold real_type _DMOV , @@ -400,13 +396,8 @@ _node->pval( pred_type::real_dims - 1); - real_type _SCAL[_ITER] = { // overrelaxation - (real_type) std::sqrt( 2.0 ) , - (real_type) +1.00, - (real_type) +0.50, - (real_type) +0.25, - (real_type) +.125 } ; - + real_type _SCAL = 4. / 3.; // overrelaxation + /*---------------- do backtracking line search iter's */ // ifdef __use_timers @@ -419,8 +410,8 @@ for (auto _iter = +0 ; _iter != _ITER; ++_iter ) { - real_type _scal = _SCAL[_iter]; - + real_type _wmov; + real_type _scal = _SCAL; real_type _zeta = _opts._zeta * (real_type)3./4. * std::min((real_type)1.,_scal) ; @@ -437,22 +428,24 @@ _step * ((real_type)0.+_zeta) + _line * ((real_type)1.-_zeta)); - _node->pval(real_dims-1) = - std::max(-_wadj , + // set upper/lower limits on weights + _node->pval(real_dims-1) = std::max( + _wadj * _opts.wmin(), _node->pval(real_dims-1)); - _node->pval(real_dims-1) = - std::min(+_wadj , + _node->pval(real_dims-1) = std::min( + _wadj * _opts.wmax(), _node->pval(real_dims-1)); - real_type _wmov = - std::abs (_save - + _wmov = std::abs (_save - _node->pval(real_dims-1)); real_type _wtol = _weps * _wadj * std::min ((real_type)1.0, _scal); if (_wmov <= _wtol) break; + + _SCAL *= (real_type) 0.5 ; /*---------------- test quasi-monotonicity w.r.t. Q^D */ _dnew.set_count(0) ; @@ -533,8 +526,8 @@ iptr_type _iout , // outer iteration marker iter_opts &_opts , // user options conn_list &_conn , // space for connectivity - real_list &_qold , // space for adj. costs - real_list &_qnew , // space for adj. costs + fp32_list &_qold , // space for adj. costs + fp32_list &_qnew , // space for adj. costs real_type _QLIM , // cell quality threshold real_type _QMOV , iter_stat &_tcpu // CPU timers/info @@ -625,7 +618,7 @@ iptr_type _pful, _pbnd; conn_list _conn; - real_list _qold, _qnew; + fp32_list _qold, _qnew; # ifdef __use_timers typename std ::chrono:: @@ -774,7 +767,7 @@ _QLIM, _QMOV, _tcpu) { conn_list _CSET; // thread-local arrays - real_list _QOLD, _QNEW; + fp32_list _QOLD, _QNEW; iptr_list _NSET; iptr_type _pass = 0u ; iptr_type _anum; @@ -832,7 +825,7 @@ _QLIM, _QMOV, _tcpu) { conn_list _CSET; // thread-local arrays - real_list _QOLD, _QNEW; + fp32_list _QOLD, _QNEW; iptr_list _NSET; iptr_type _anum; # pragma omp for nowait schedule(static,1) @@ -890,7 +883,7 @@ _QLIM, _QMOV, _tcpu) { conn_list _CSET; // thread-local arrays - real_list _QOLD, _QNEW; + fp32_list _QOLD, _QNEW; iptr_list _NSET; iptr_type _pass = 1u ; iptr_type _anum; @@ -1023,8 +1016,8 @@ iptr_type _iout , // outer iteration marker iter_opts &_opts , // user options conn_list &_conn , // space for connectivity - real_list &_dold , // space for adj. costs - real_list &_dnew , // space for adj. costs + fp32_list &_dold , // space for adj. costs + fp32_list &_dnew , // space for adj. costs real_type _DLIM , // dual quality threshold real_type _DMOV , iter_stat &_tcpu // CPU timers/info @@ -1110,7 +1103,7 @@ iptr_type _pful, _pbnd; conn_list _conn; - real_list _dold, _dnew; + fp32_list _dold, _dnew; # ifdef __use_timers typename std ::chrono:: @@ -1259,7 +1252,7 @@ _DLIM, _DMOV, _tcpu) { conn_list _CSET; // thread-local arrays - real_list _DOLD, _DNEW; + fp32_list _DOLD, _DNEW; iptr_list _NSET; iptr_type _pass = 0u ; iptr_type _anum; @@ -1317,7 +1310,7 @@ _DLIM, _DMOV, _tcpu) { conn_list _CSET; // thread-local arrays - real_list _DOLD, _DNEW; + fp32_list _DOLD, _DNEW; iptr_list _NSET; iptr_type _anum; # pragma omp for nowait schedule(static,1) @@ -1375,7 +1368,7 @@ _DLIM, _DMOV, _tcpu) { conn_list _CSET; // thread-local arrays - real_list _DOLD, _DNEW; + fp32_list _DOLD, _DNEW; iptr_list _NSET; iptr_type _pass = 1u ; iptr_type _anum; diff --git a/src/libcpp/mathutil.hpp b/src/libcpp/mathutil.hpp index 4e717dc..f46c5e2 100644 --- a/src/libcpp/mathutil.hpp +++ b/src/libcpp/mathutil.hpp @@ -69,7 +69,7 @@ __write_ptr (real_type) _xx ) { - real_type _rt = + real_type constexpr _rt = std::numeric_limits ::epsilon() ; diff --git a/src/libcpp/mesh_reps/base_complex_k.hpp b/src/libcpp/mesh_reps/base_complex_k.hpp index a14be4a..189bfef 100644 --- a/src/libcpp/mesh_reps/base_complex_k.hpp +++ b/src/libcpp/mesh_reps/base_complex_k.hpp @@ -115,6 +115,18 @@ char_type _ksrc = +0 ) : _cell(_csrc), _kind(_ksrc) {} } ; + + class conn_same + { + public : + __inline_call bool_type operator() ( + conn_pair const& _xx, + conn_pair const& _yy + ) const + { return _xx._cell == _yy._cell && + _xx._kind == _yy._kind ; + } + } ; /* -------------------------------------------------------- @@ -570,7 +582,7 @@ "mesh-complex: non-top node!" ) ; /*------------------------ init. external d-face data */ - _ipos = (IPTR_TYPE)_get_node(_mesh) ; + _ipos = (IPTR_TYPE)_get_node(_mesh) ; _mesh._llN1[_ipos] = _ndat ; _mesh._llN1[_ipos].null() ; @@ -591,7 +603,7 @@ if (_itop == -1) { /*------------------------ init. external d-face data */ - _ipos = (IPTR_TYPE)_get_node(_mesh) ; + _ipos = (IPTR_TYPE)_get_node(_mesh) ; _mesh._llN1[_ipos] = _ndat ; _mesh._llN1[_ipos].null() ; @@ -2766,88 +2778,7 @@ tria_cell const & ) { - _mesh._tmp1.set_count( +0 ) ; - _mesh._tmp2.set_count( +0 ) ; - - auto _ioff = _conn.count () ; - - 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 ) - { - // 1-adj. list is disjoint, guaranteed - // 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()+_ioff ; - _iter != _conn.tend() ; - ++_iter ) - { - if(_iter->_kind == TRIA3_tag) - { - _mesh. _llT3[ - _iter->_cell].mark() = 0 ; - } - } + connect_2(_mesh, _ipos, _kind, _conn, mesh_cell()); } template < @@ -2862,32 +2793,30 @@ mesh_cell const & ) { - _mesh._tmp1.set_count( +0 ) ; - _mesh._tmp2.set_count( +0 ) ; - - auto _ioff = _conn.count () ; + connector _tmp1, _tmp2; + auto _ioff = _conn.count () ; switch ( _kind ) { /*-------------------------- init. "source" adj. list */ case POINT_tag: { - _mesh._tmp1.push_tail( + _tmp1.push_tail ( conn_pair (_ipos, _kind)) ; break ; } case EDGE2_tag: { - _mesh._tmp2.push_tail( + _tmp2.push_tail ( conn_pair (_ipos, _kind)) ; break ; } } /*-------------------------- find set of adj. 1-cells */ - for (auto _iter = _mesh._tmp1.head(); - _iter != _mesh._tmp1.tend(); + for (auto _iter = _tmp1.head(); + _iter != _tmp1.tend(); ++_iter ) { if (_iter->_kind == POINT_tag) @@ -2898,21 +2827,13 @@ ++_iadj ) { // 1-adj. list is disjoint, guaranteed - // 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(); + for (auto _iter = _tmp2.head(); + _iter != _tmp2.tend(); ++_iter ) { if (_iter->_kind == EDGE2_tag) @@ -2922,41 +2843,13 @@ _mesh._aaE2.tend(_iter->_cell); ++_iadj ) { - if(_iadj->_kind == TRIA3_tag && - _mesh. _llT3[ - _iadj->_cell].mark() == 0) + if(algorithms::is_unique ( + _conn.head()+ _ioff, + _conn.tend(),*_iadj, + conn_same()) ) { _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()+_ioff ; - _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 ; } } } diff --git a/src/libcpp/parameters/iter_params.hpp b/src/libcpp/parameters/iter_params.hpp index 65bffab..b8320dd 100644 --- a/src/libcpp/parameters/iter_params.hpp +++ b/src/libcpp/parameters/iter_params.hpp @@ -35,9 +35,9 @@ * -------------------------------------------------------- * - * Last updated: 12 Dec., 2022 + * Last updated: 27 Jul., 2025 * - * Copyright 2013-2022 + * Copyright 2013-2025 * Darren Engwirda * d.engwirda@gmail.com * https://github.com/dengwirda/ @@ -84,6 +84,9 @@ real_type _qtol ; // convergence tolerance real_type _qlim ; // fallback score threshold + real_type _wmin ; // up/lo limits on weights + real_type _wmax ; + bool_type _zip_ ; // do cell merge operations bool_type _div_ ; // do cell split operations bool_type _tria ; // mesh cell optimisation @@ -116,6 +119,11 @@ this->_qlim = real_type(_jjig._optm_qlim) ; + this->_wmin = + real_type(_jjig._optm_wmin) ; + this->_wmax = + real_type(_jjig._optm_wmax) ; + this->_zip_ = bool_type(_jjig._optm_zip_) ; this->_div_ = @@ -159,6 +167,15 @@ { return this->_qlim ; } + __inline_call real_type & wmin ( + ) + { return this->_wmin ; + } + __inline_call real_type & wmax ( + ) + { return this->_wmax ; + } + __inline_call bool_type & zip_ ( ) { return this->_zip_ ; @@ -209,6 +226,15 @@ { return this->_qlim ; } + __inline_call real_type const& wmin ( + ) const + { return this->_wmin ; + } + __inline_call real_type const& wmax ( + ) const + { return this->_wmax ; + } + __inline_call bool_type const& zip_ ( ) const { return this->_zip_ ; diff --git a/src/libcpp/parameters/mesh_params.hpp b/src/libcpp/parameters/mesh_params.hpp index a1ffa5e..6bbca47 100644 --- a/src/libcpp/parameters/mesh_params.hpp +++ b/src/libcpp/parameters/mesh_params.hpp @@ -35,9 +35,9 @@ * -------------------------------------------------------- * - * Last updated: 12 Dec., 2022 + * Last updated: 21 Apr., 2024 * - * Copyright 2013-2022 + * Copyright 2013-2024 * Darren Engwirda * d.engwirda@gmail.com * https://github.com/dengwirda/ @@ -123,6 +123,10 @@ real_type _vol3 ; // volume-length ratio + bool_type _orph ; // allow "orphaned" facets + + bool_type _lock ; // stop subface refinement + bool_type _top1 ; // impose 1-"manifold-ness" bool_type _top2 ; // impose 2-"manifold-ness" @@ -135,7 +139,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 ; @@ -210,6 +214,12 @@ this->_vol3 = real_type(_jjig._mesh_vol3) ; + this->_orph = + bool_type(_jjig._mesh_orph) ; + + this->_lock = + bool_type(_jjig._mesh_lock) ; + this->_top1 = bool_type(_jjig._mesh_top1) ; this->_top2 = @@ -328,6 +338,16 @@ { return this->_vol3 ; } + __inline_call bool_type & orph ( + ) + { return this->_orph ; + } + + __inline_call bool_type & lock ( + ) + { return this->_lock ; + } + __inline_call bool_type & top1 ( ) { return this->_top1 ; @@ -449,6 +469,16 @@ { return this->_vol3 ; } + __inline_call bool_type const& orph ( + ) const + { return this->_orph ; + } + + __inline_call bool_type const& lock ( + ) const + { return this->_lock ; + } + __inline_call bool_type const& top1 ( ) const { return this->_top1 ; diff --git a/src/libcpp/predicate/inball_k.hpp b/src/libcpp/predicate/inball_k.hpp index fbc7dfe..3878afb 100644 --- a/src/libcpp/predicate/inball_k.hpp +++ b/src/libcpp/predicate/inball_k.hpp @@ -35,7 +35,7 @@ * -------------------------------------------------------- * - * Last updated: 30 Apr., 2020 + * Last updated: 11 May., 2024 * * Copyright 2020-- * Darren Engwirda @@ -1570,56 +1570,1016 @@ return ( _d44 ) ; } + /* + -------------------------------------------------------- + * + * Compute an exact determinant using multi-precision + * expansions, a'la shewchuk + * + * | ax ay az aq dot(a, a) +1. | + * | bx by bz bq dot(b, b) +1. | + * | cx cy cz cq dot(c, c) +1. | + * | dx dy dz dq dot(d, d) +1. | + * | ex ey ez eq dot(e, e) +1. | + * | fx fy fz fq dot(f, f) +1. | + * + * This is the unweighted "in-ball" predicate in E^4. + * + -------------------------------------------------------- + */ + + __normal_call REAL_TYPE inball4d_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 , + __const_ptr(REAL_TYPE) _pf , + bool_type &_OK + ) + { + /*--------------- inball4d predicate, "exact" version */ + mp::expansion< 8 > _a_lift, _b_lift, + _c_lift, _d_lift, + _e_lift, _f_lift; + mp::expansion< 4 > _d2_ab_, _d2_ac_, + _d2_ad_, _d2_ae_, + _d2_af_, + _d2_bc_, _d2_bd_, + _d2_be_, _d2_bf_, + _d2_cd_, _d2_ce_, + _d2_cf_, + _d2_de_, _d2_df_, + _d2_ef_; + mp::expansion< 24> _d3_abc, _d3_abd, + _d3_abe, _d3_abf, + _d3_acd, _d3_ace, + _d3_acf, + _d3_ade, _d3_adf, + _d3_aef, + _d3_bcd, _d3_bce, + _d3_bcf, + _d3_bde, _d3_bdf, + _d3_bef, + _d3_cde, _d3_cdf, + _d3_cef, _d3_def; + mp::expansion<192> _d4abcd, _d4abce, + _d4abcf, + _d4abde, _d4abdf, + _d4abef, + _d4acde, _d4acdf, + _d4acef, _d4adef, + _d4bcde, _d4bcdf, + _d4bcef, _d4bdef, + _d4cdef; + mp::expansion<960> _5bcdef, _5acdef, + _5abdef, _5abcef, + _5abcdf, _5abcde; + // try not to blow the stack... + auto _d6full = new mp::expansion<92160>() ; + _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 > _pf_zz_(_pf[ 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]); + mp::expansion< 1 > _pf_qq_(_pf[ 3]); + /*-------------------------------------- lifted terms */ + mp::expansion_add( + mp::expansion_from_sqr(_pa[ 0]), + mp::expansion_from_sqr(_pa[ 1]), + mp::expansion_from_sqr(_pa[ 2]), + mp::expansion_from_sqr(_pa[ 3]), + _a_lift ) ; - #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 ; \ - } + mp::expansion_add( + mp::expansion_from_sqr(_pb[ 0]), + mp::expansion_from_sqr(_pb[ 1]), + mp::expansion_from_sqr(_pb[ 2]), + mp::expansion_from_sqr(_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]), + mp::expansion_from_sqr(_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]), + mp::expansion_from_sqr(_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]), + mp::expansion_from_sqr(_pe[ 3]), + _e_lift ) ; + + mp::expansion_add( + mp::expansion_from_sqr(_pf[ 0]), + mp::expansion_from_sqr(_pf[ 1]), + mp::expansion_from_sqr(_pf[ 2]), + mp::expansion_from_sqr(_pf[ 3]), + _f_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(_pa[ 0], _pa[ 1], + _pf[ 0], _pf[ 1], + _d2_af_ ) ; + + 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(_pb[ 0], _pb[ 1], + _pf[ 0], _pf[ 1], + _d2_bf_ ) ; + + 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(_pc[ 0], _pc[ 1], + _pf[ 0], _pf[ 1], + _d2_cf_ ) ; + + compute_det_2x2(_pd[ 0], _pd[ 1], + _pe[ 0], _pe[ 1], + _d2_de_ ) ; + + compute_det_2x2(_pd[ 0], _pd[ 1], + _pf[ 0], _pf[ 1], + _d2_df_ ) ; + + compute_det_2x2(_pe[ 0], _pe[ 1], + _pf[ 0], _pf[ 1], + _d2_ef_ ) ; + + /*-------------------------------------- 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_bf_, _pa_zz_, + _d2_af_, _pb_zz_, + _d2_ab_, _pf_zz_, + _d3_abf, +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_cf_, _pa_zz_, + _d2_af_, _pc_zz_, + _d2_ac_, _pf_zz_, + _d3_acf, +3) ; + + compute_det_3x3(_d2_de_, _pa_zz_, + _d2_ae_, _pd_zz_, + _d2_ad_, _pe_zz_, + _d3_ade, +3) ; + + compute_det_3x3(_d2_df_, _pa_zz_, + _d2_af_, _pd_zz_, + _d2_ad_, _pf_zz_, + _d3_adf, +3) ; + + compute_det_3x3(_d2_ef_, _pa_zz_, + _d2_af_, _pe_zz_, + _d2_ae_, _pf_zz_, + _d3_aef, +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_cf_, _pb_zz_, + _d2_bf_, _pc_zz_, + _d2_bc_, _pf_zz_, + _d3_bcf, +3) ; + + compute_det_3x3(_d2_de_, _pb_zz_, + _d2_be_, _pd_zz_, + _d2_bd_, _pe_zz_, + _d3_bde, +3) ; + + compute_det_3x3(_d2_df_, _pb_zz_, + _d2_bf_, _pd_zz_, + _d2_bd_, _pf_zz_, + _d3_bdf, +3) ; + + compute_det_3x3(_d2_ef_, _pb_zz_, + _d2_bf_, _pe_zz_, + _d2_be_, _pf_zz_, + _d3_bef, +3) ; + + compute_det_3x3(_d2_de_, _pc_zz_, + _d2_ce_, _pd_zz_, + _d2_cd_, _pe_zz_, + _d3_cde, +3) ; + + compute_det_3x3(_d2_df_, _pc_zz_, + _d2_cf_, _pd_zz_, + _d2_cd_, _pf_zz_, + _d3_cdf, +3) ; + + compute_det_3x3(_d2_ef_, _pc_zz_, + _d2_cf_, _pe_zz_, + _d2_ce_, _pf_zz_, + _d3_cef, +3) ; + + compute_det_3x3(_d2_ef_, _pd_zz_, + _d2_df_, _pe_zz_, + _d2_de_, _pf_zz_, + _d3_def, +3) ; + + /*-------------------------------------- 4 x 4 minors */ + compute_det_4x4(_d3_bcd, _pa_qq_, + _d3_acd, _pb_qq_, + _d3_abd, _pc_qq_, + _d3_abc, _pd_qq_, + _d4abcd, +4) ; + + compute_det_4x4(_d3_bce, _pa_qq_, + _d3_ace, _pb_qq_, + _d3_abe, _pc_qq_, + _d3_abc, _pe_qq_, + _d4abce, +4) ; + + compute_det_4x4(_d3_bcf, _pa_qq_, + _d3_acf, _pb_qq_, + _d3_abf, _pc_qq_, + _d3_abc, _pf_qq_, + _d4abcf, +4) ; + + compute_det_4x4(_d3_bde, _pa_qq_, + _d3_ade, _pb_qq_, + _d3_abe, _pd_qq_, + _d3_abd, _pe_qq_, + _d4abde, +4) ; + + compute_det_4x4(_d3_bdf, _pa_qq_, + _d3_adf, _pb_qq_, + _d3_abf, _pd_qq_, + _d3_abd, _pf_qq_, + _d4abdf, +4) ; + + compute_det_4x4(_d3_bef, _pa_qq_, + _d3_aef, _pb_qq_, + _d3_abf, _pe_qq_, + _d3_abe, _pf_qq_, + _d4abef, +4) ; + + compute_det_4x4(_d3_cde, _pa_qq_, + _d3_ade, _pc_qq_, + _d3_ace, _pd_qq_, + _d3_acd, _pe_qq_, + _d4acde, +4) ; + + compute_det_4x4(_d3_cdf, _pa_qq_, + _d3_adf, _pc_qq_, + _d3_acf, _pd_qq_, + _d3_acd, _pf_qq_, + _d4acdf, +4) ; + + compute_det_4x4(_d3_cef, _pa_qq_, + _d3_aef, _pc_qq_, + _d3_acf, _pe_qq_, + _d3_ace, _pf_qq_, + _d4acef, +4) ; + + compute_det_4x4(_d3_def, _pa_qq_, + _d3_aef, _pd_qq_, + _d3_adf, _pe_qq_, + _d3_ade, _pf_qq_, + _d4adef, +4) ; + + compute_det_4x4(_d3_cde, _pb_qq_, + _d3_bde, _pc_qq_, + _d3_bce, _pd_qq_, + _d3_bcd, _pe_qq_, + _d4bcde, +4) ; + + compute_det_4x4(_d3_cdf, _pb_qq_, + _d3_bdf, _pc_qq_, + _d3_bcf, _pd_qq_, + _d3_bcd, _pf_qq_, + _d4bcdf, +4) ; + + compute_det_4x4(_d3_cef, _pb_qq_, + _d3_bef, _pc_qq_, + _d3_bcf, _pe_qq_, + _d3_bce, _pf_qq_, + _d4bcef, +4) ; + + compute_det_4x4(_d3_def, _pb_qq_, + _d3_bef, _pd_qq_, + _d3_bdf, _pe_qq_, + _d3_bde, _pf_qq_, + _d4bdef, +4) ; + + compute_det_4x4(_d3_def, _pc_qq_, + _d3_cef, _pd_qq_, + _d3_cdf, _pe_qq_, + _d3_cde, _pf_qq_, + _d4cdef, +4) ; + + /*-------------------------------------- 5 x 5 minors */ + unitary_det_5x5(_d4bcde, _d4acde, + _d4abde, _d4abce, + _d4abcd, + _5abcde, +5) ; + + unitary_det_5x5(_d4bcdf, _d4acdf, + _d4abdf, _d4abcf, + _d4abcd, + _5abcdf, +5) ; + + unitary_det_5x5(_d4bcef, _d4acef, + _d4abef, _d4abcf, + _d4abce, + _5abcef, +5) ; + + unitary_det_5x5(_d4bdef, _d4adef, + _d4abef, _d4abdf, + _d4abde, + _5abdef, +5) ; + + unitary_det_5x5(_d4cdef, _d4adef, + _d4acef, _d4acdf, + _d4acde, + _5acdef, +5) ; + + unitary_det_5x5(_d4cdef, _d4bdef, + _d4bcef, _d4bcdf, + _d4bcde, + _5bcdef, +5) ; + + /*-------------------------------------- 6 x 6 result */ + compute_det_6x6(_5bcdef, _a_lift, + _5acdef, _b_lift, + _5abdef, _c_lift, + _5abcef, _d_lift, + _5abcdf, _e_lift, + _5abcde, _f_lift, + *_d6full, +5) ; + + /*-------------------------------------- leading det. */ + REAL_TYPE _d66 = mp::expansion_est(*_d6full) ; + + delete _d6full ; return _d66 ; + } + + __normal_call REAL_TYPE inball4d_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 , + __const_ptr(REAL_TYPE) _pf , + bool_type &_OK + ) + { + /*--------------- inball4d predicate, "bound" version */ + ia_flt _afx, _afy, _afz , + _afq, _ali, + _bfx, _bfy, _bfz , + _bfq, _bli, + _cfx, _cfy, _cfz , + _cfq, _cli, + _dfx, _dfy, _dfz , + _dfq, _dli, + _efx, _efy, _efz , + _efq, _eli; + + ia_flt _afxbfy, _bfxafy , + _afxcfy, _cfxafy , + _bfxcfy, _cfxbfy , + _cfxdfy, _dfxcfy , + _dfxafy, _afxdfy , + _bfxdfy, _dfxbfy ; + + ia_flt _ab_, _bc_, _cd_, _da_, + _ac_, _bd_; + + + ia_flt _abc, _bcd, _cda, _dab; + + + ia_flt _d55; + + ia_rnd _rnd; // up rounding! + + _afx.from_sub(_pa[0], _pf[0]) ; // coord. diff. + _afy.from_sub(_pa[1], _pf[1]) ; + _afz.from_sub(_pa[2], _pf[2]) ; + _afq.from_sub(_pa[3], _pf[3]) ; + + _bfx.from_sub(_pb[0], _pf[0]) ; + _bfy.from_sub(_pb[1], _pf[1]) ; + _bfz.from_sub(_pb[2], _pf[2]) ; + _bfq.from_sub(_pb[3], _pf[3]) ; + + _cfx.from_sub(_pc[0], _pf[0]) ; + _cfy.from_sub(_pc[1], _pf[1]) ; + _cfz.from_sub(_pc[2], _pf[2]) ; + _cfq.from_sub(_pc[3], _pf[3]) ; + + _dfx.from_sub(_pd[0], _pf[0]) ; + _dfy.from_sub(_pd[1], _pf[1]) ; + _dfz.from_sub(_pd[2], _pf[2]) ; + _dfq.from_sub(_pd[3], _pf[3]) ; + + _efx.from_sub(_pe[0], _pf[0]) ; + _efy.from_sub(_pe[1], _pf[1]) ; + _efz.from_sub(_pe[2], _pf[2]) ; + _efq.from_sub(_pe[3], _pf[3]) ; + + _ali = sqr (_afx) + sqr (_afy) // lifted terms + + sqr (_afz) + sqr (_afq) ; + + _bli = sqr (_bfx) + sqr (_bfy) + + sqr (_bfz) + sqr (_bfq) ; + + _cli = sqr (_cfx) + sqr (_cfy) + + sqr (_cfz) + sqr (_cfq) ; + + _dli = sqr (_dfx) + sqr (_dfy) + + sqr (_dfz) + sqr (_dfq) ; + + _eli = sqr (_efx) + sqr (_efy) + + sqr (_efz) + sqr (_efq) ; + + + /* + _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 = // 5 x 5 result + _eli * _abcd + + _dli * _abce + - _cli * _deab + + _bli * _cdea + - _ali * _bcde ; + */ + + _OK = + _d55.lo() >= (REAL_TYPE)0. + ||_d55.up() <= (REAL_TYPE)0.; + + return ( _d55.mid() ) ; + } + + + + + + + /* + -------------------------------------------------------- + * + * Compute an exact determinant using multi-precision + * expansions, a'la shewchuk + * + * | ax ay az aq dot(a, a) - aw +1. | + * | bx by bz bq dot(b, b) - bw +1. | + * | cx cy cz cq dot(c, c) - cw +1. | + * | dx dy dz dq dot(d, d) - dw +1. | + * | ex ey ez eq dot(e, e) - ew +1. | + * | fx fy fz fq dot(f, f) - fw +1. | + * + * This is the weighted "in-ball" predicate in E^4. + * + -------------------------------------------------------- + */ + + __normal_call REAL_TYPE inball4w_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 , + __const_ptr(REAL_TYPE) _pf , + bool_type &_OK + ) + { + /*--------------- inball4w predicate, "exact" version */ + mp::expansion< 9 > _a_lift, _b_lift, + _c_lift, _d_lift, + _e_lift, _f_lift; + mp::expansion< 8 > _t_lift; + mp::expansion< 4 > _d2_ab_, _d2_ac_, + _d2_ad_, _d2_ae_, + _d2_af_, + _d2_bc_, _d2_bd_, + _d2_be_, _d2_bf_, + _d2_cd_, _d2_ce_, + _d2_cf_, + _d2_de_, _d2_df_, + _d2_ef_; + mp::expansion< 24> _d3_abc, _d3_abd, + _d3_abe, _d3_abf, + _d3_acd, _d3_ace, + _d3_acf, + _d3_ade, _d3_adf, + _d3_aef, + _d3_bcd, _d3_bce, + _d3_bcf, + _d3_bde, _d3_bdf, + _d3_bef, + _d3_cde, _d3_cdf, + _d3_cef, _d3_def; + mp::expansion<192> _d4abcd, _d4abce, + _d4abcf, + _d4abde, _d4abdf, + _d4abef, + _d4acde, _d4acdf, + _d4acef, _d4adef, + _d4bcde, _d4bcdf, + _d4bcef, _d4bdef, + _d4cdef; + mp::expansion<960> _5bcdef, _5acdef, + _5abdef, _5abcef, + _5abcdf, _5abcde; + // try not to blow the stack... + auto _d6full = new mp::expansion<103680>(); + + _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 > _pf_zz_(_pf[ 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]); + mp::expansion< 1 > _pf_qq_(_pf[ 3]); + + /*-------------------------------------- lifted terms */ + mp::expansion_add( + mp::expansion_from_sqr(_pa[ 0]), + mp::expansion_from_sqr(_pa[ 1]), + mp::expansion_from_sqr(_pa[ 2]), + mp::expansion_from_sqr(_pa[ 3]), + _t_lift ) ; + mp::expansion_sub( + _t_lift , _pa[ 4] , _a_lift); + + mp::expansion_add( + mp::expansion_from_sqr(_pb[ 0]), + mp::expansion_from_sqr(_pb[ 1]), + mp::expansion_from_sqr(_pb[ 2]), + mp::expansion_from_sqr(_pb[ 3]), + _t_lift ) ; + mp::expansion_sub( + _t_lift , _pb[ 4] , _b_lift); + + mp::expansion_add( + mp::expansion_from_sqr(_pc[ 0]), + mp::expansion_from_sqr(_pc[ 1]), + mp::expansion_from_sqr(_pc[ 2]), + mp::expansion_from_sqr(_pc[ 3]), + _t_lift ) ; + mp::expansion_sub( + _t_lift , _pc[ 4] , _c_lift); + + mp::expansion_add( + mp::expansion_from_sqr(_pd[ 0]), + mp::expansion_from_sqr(_pd[ 1]), + mp::expansion_from_sqr(_pd[ 2]), + mp::expansion_from_sqr(_pd[ 3]), + _t_lift ) ; + mp::expansion_sub( + _t_lift , _pd[ 4] , _d_lift); + + mp::expansion_add( + mp::expansion_from_sqr(_pe[ 0]), + mp::expansion_from_sqr(_pe[ 1]), + mp::expansion_from_sqr(_pe[ 2]), + mp::expansion_from_sqr(_pe[ 3]), + _t_lift ) ; + mp::expansion_sub( + _t_lift , _pe[ 4] , _e_lift); + + mp::expansion_add( + mp::expansion_from_sqr(_pf[ 0]), + mp::expansion_from_sqr(_pf[ 1]), + mp::expansion_from_sqr(_pf[ 2]), + mp::expansion_from_sqr(_pf[ 3]), + _t_lift ) ; + mp::expansion_sub( + _t_lift , _pf[ 4] , _f_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(_pa[ 0], _pa[ 1], + _pf[ 0], _pf[ 1], + _d2_af_ ) ; + + 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(_pb[ 0], _pb[ 1], + _pf[ 0], _pf[ 1], + _d2_bf_ ) ; + + 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(_pc[ 0], _pc[ 1], + _pf[ 0], _pf[ 1], + _d2_cf_ ) ; + + compute_det_2x2(_pd[ 0], _pd[ 1], + _pe[ 0], _pe[ 1], + _d2_de_ ) ; + + compute_det_2x2(_pd[ 0], _pd[ 1], + _pf[ 0], _pf[ 1], + _d2_df_ ) ; + + compute_det_2x2(_pe[ 0], _pe[ 1], + _pf[ 0], _pf[ 1], + _d2_ef_ ) ; + + /*-------------------------------------- 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_bf_, _pa_zz_, + _d2_af_, _pb_zz_, + _d2_ab_, _pf_zz_, + _d3_abf, +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_cf_, _pa_zz_, + _d2_af_, _pc_zz_, + _d2_ac_, _pf_zz_, + _d3_acf, +3) ; + + compute_det_3x3(_d2_de_, _pa_zz_, + _d2_ae_, _pd_zz_, + _d2_ad_, _pe_zz_, + _d3_ade, +3) ; + + compute_det_3x3(_d2_df_, _pa_zz_, + _d2_af_, _pd_zz_, + _d2_ad_, _pf_zz_, + _d3_adf, +3) ; + + compute_det_3x3(_d2_ef_, _pa_zz_, + _d2_af_, _pe_zz_, + _d2_ae_, _pf_zz_, + _d3_aef, +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_cf_, _pb_zz_, + _d2_bf_, _pc_zz_, + _d2_bc_, _pf_zz_, + _d3_bcf, +3) ; + + compute_det_3x3(_d2_de_, _pb_zz_, + _d2_be_, _pd_zz_, + _d2_bd_, _pe_zz_, + _d3_bde, +3) ; + + compute_det_3x3(_d2_df_, _pb_zz_, + _d2_bf_, _pd_zz_, + _d2_bd_, _pf_zz_, + _d3_bdf, +3) ; + + compute_det_3x3(_d2_ef_, _pb_zz_, + _d2_bf_, _pe_zz_, + _d2_be_, _pf_zz_, + _d3_bef, +3) ; + + compute_det_3x3(_d2_de_, _pc_zz_, + _d2_ce_, _pd_zz_, + _d2_cd_, _pe_zz_, + _d3_cde, +3) ; + + compute_det_3x3(_d2_df_, _pc_zz_, + _d2_cf_, _pd_zz_, + _d2_cd_, _pf_zz_, + _d3_cdf, +3) ; + + compute_det_3x3(_d2_ef_, _pc_zz_, + _d2_cf_, _pe_zz_, + _d2_ce_, _pf_zz_, + _d3_cef, +3) ; + + compute_det_3x3(_d2_ef_, _pd_zz_, + _d2_df_, _pe_zz_, + _d2_de_, _pf_zz_, + _d3_def, +3) ; + + /*-------------------------------------- 4 x 4 minors */ + compute_det_4x4(_d3_bcd, _pa_qq_, + _d3_acd, _pb_qq_, + _d3_abd, _pc_qq_, + _d3_abc, _pd_qq_, + _d4abcd, +4) ; + + compute_det_4x4(_d3_bce, _pa_qq_, + _d3_ace, _pb_qq_, + _d3_abe, _pc_qq_, + _d3_abc, _pe_qq_, + _d4abce, +4) ; + + compute_det_4x4(_d3_bcf, _pa_qq_, + _d3_acf, _pb_qq_, + _d3_abf, _pc_qq_, + _d3_abc, _pf_qq_, + _d4abcf, +4) ; + + compute_det_4x4(_d3_bde, _pa_qq_, + _d3_ade, _pb_qq_, + _d3_abe, _pd_qq_, + _d3_abd, _pe_qq_, + _d4abde, +4) ; + + compute_det_4x4(_d3_bdf, _pa_qq_, + _d3_adf, _pb_qq_, + _d3_abf, _pd_qq_, + _d3_abd, _pf_qq_, + _d4abdf, +4) ; + + compute_det_4x4(_d3_bef, _pa_qq_, + _d3_aef, _pb_qq_, + _d3_abf, _pe_qq_, + _d3_abe, _pf_qq_, + _d4abef, +4) ; + + compute_det_4x4(_d3_cde, _pa_qq_, + _d3_ade, _pc_qq_, + _d3_ace, _pd_qq_, + _d3_acd, _pe_qq_, + _d4acde, +4) ; + + compute_det_4x4(_d3_cdf, _pa_qq_, + _d3_adf, _pc_qq_, + _d3_acf, _pd_qq_, + _d3_acd, _pf_qq_, + _d4acdf, +4) ; + + compute_det_4x4(_d3_cef, _pa_qq_, + _d3_aef, _pc_qq_, + _d3_acf, _pe_qq_, + _d3_ace, _pf_qq_, + _d4acef, +4) ; + + compute_det_4x4(_d3_def, _pa_qq_, + _d3_aef, _pd_qq_, + _d3_adf, _pe_qq_, + _d3_ade, _pf_qq_, + _d4adef, +4) ; + + compute_det_4x4(_d3_cde, _pb_qq_, + _d3_bde, _pc_qq_, + _d3_bce, _pd_qq_, + _d3_bcd, _pe_qq_, + _d4bcde, +4) ; + + compute_det_4x4(_d3_cdf, _pb_qq_, + _d3_bdf, _pc_qq_, + _d3_bcf, _pd_qq_, + _d3_bcd, _pf_qq_, + _d4bcdf, +4) ; + + compute_det_4x4(_d3_cef, _pb_qq_, + _d3_bef, _pc_qq_, + _d3_bcf, _pe_qq_, + _d3_bce, _pf_qq_, + _d4bcef, +4) ; + + compute_det_4x4(_d3_def, _pb_qq_, + _d3_bef, _pd_qq_, + _d3_bdf, _pe_qq_, + _d3_bde, _pf_qq_, + _d4bdef, +4) ; + + compute_det_4x4(_d3_def, _pc_qq_, + _d3_cef, _pd_qq_, + _d3_cdf, _pe_qq_, + _d3_cde, _pf_qq_, + _d4cdef, +4) ; + + /*-------------------------------------- 5 x 5 minors */ + unitary_det_5x5(_d4bcde, _d4acde, + _d4abde, _d4abce, + _d4abcd, + _5abcde, +5) ; + + unitary_det_5x5(_d4bcdf, _d4acdf, + _d4abdf, _d4abcf, + _d4abcd, + _5abcdf, +5) ; + + unitary_det_5x5(_d4bcef, _d4acef, + _d4abef, _d4abcf, + _d4abce, + _5abcef, +5) ; + + unitary_det_5x5(_d4bdef, _d4adef, + _d4abef, _d4abdf, + _d4abde, + _5abdef, +5) ; + + unitary_det_5x5(_d4cdef, _d4adef, + _d4acef, _d4acdf, + _d4acde, + _5acdef, +5) ; + + unitary_det_5x5(_d4cdef, _d4bdef, + _d4bcef, _d4bcdf, + _d4bcde, + _5bcdef, +5) ; + + /*-------------------------------------- 6 x 6 result */ + compute_det_6x6(_5bcdef, _a_lift, + _5acdef, _b_lift, + _5abdef, _c_lift, + _5abcef, _d_lift, + _5abcdf, _e_lift, + _5abcde, _f_lift, + *_d6full, +5) ; + + /*-------------------------------------- leading det. */ + REAL_TYPE _d66 = mp::expansion_est(*_d6full) ; + + delete _d6full ; return _d66 ; + } diff --git a/src/libcpp/predicate/predicate_k.hpp b/src/libcpp/predicate/predicate_k.hpp index dfb2b05..70fc15c 100644 --- a/src/libcpp/predicate/predicate_k.hpp +++ b/src/libcpp/predicate/predicate_k.hpp @@ -60,7 +60,7 @@ * -------------------------------------------------------- * - * Last updated: 30 Apr., 2020 + * Last updated: 11 May., 2024 * * Copyright 2020-- * Darren Engwirda @@ -76,7 +76,7 @@ # define __PREDICATE_K__ # define USE_KERNEL_FLTPOINT -// define USE_KERNEL_INTERVAL +# define USE_KERNEL_INTERVAL namespace geompred { @@ -709,6 +709,113 @@ } } + __inline_call REAL_TYPE inball4d ( + __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 , + __const_ptr(REAL_TYPE) _pf + ) + { + /*------------ inball4d predicate, "filtered" version */ + REAL_TYPE _rr; + bool_type _OK; + + /* + # ifdef USE_KERNEL_FLTPOINT + _nn_calls[INBALL4D_f] += +1; + + _rr = inball4d_f( // "float" kernel + _pa, _pb, _pc, _pd, _pe, _pf, _OK + ) ; + + if (_OK && std::isnormal(_rr)) + return _rr ; + # endif + + # ifdef USE_KERNEL_INTERVAL + _nn_calls[INBALL4D_i] += +1; + + _rr = inball4d_i( // "bound" kernel + _pa, _pb, _pc, _pd, _pe, _pf, _OK + ) ; + + if (_OK) return _rr ; + # endif + */ + + _nn_calls[INBALL4D_e] += +1; + + _rr = inball4d_e( // "exact" kernel + _pa, _pb, _pc, _pd, _pe, _pf, _OK + ) ; + + if (_OK) return _rr ; + + return (REAL_TYPE) +0.0E+00; + } + + __inline_call REAL_TYPE inball4w ( + __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 , + __const_ptr(REAL_TYPE) _pf + ) + { + /*------------ inball3w predicate, "filtered" version */ + if (_pa [ 4] == _pb [ 4] && + _pb [ 4] == _pc [ 4] && + _pc [ 4] == _pd [ 4] && + _pd [ 4] == _pe [ 4] && + _pe [ 4] == _pf [ 4] ) + { + return inball4d ( // equal weights, do inball4d + _pa, _pb, _pc, _pd, _pe, _pf + ) ; + } + else + { + REAL_TYPE _rr; // given weights, full kernel + bool_type _OK; + + /* + # ifdef USE_KERNEL_FLTPOINT + _nn_calls[INBALL4W_f] += +1; + + _rr = inball4w_f( // "float" kernal + _pa, _pb, _pc, _pd, _pe, _pf, _OK + ) ; + + if (_OK && std::isnormal(_rr)) + return _rr ; + # endif + + # ifdef USE_KERNEL_INTERVAL + _nn_calls[INBALL4D_i] += +1; + + _rr = inball4w_i( // "bound" kernel + _pa, _pb, _pc, _pd, _pe, _pf, _OK + ) ; + + if (_OK) return _rr ; + # endif + */ + + _nn_calls[INBALL4W_e] += +1; + + _rr = inball4w_e( // "exact" kernel + _pa, _pb, _pc, _pd, _pe, _pf, _OK + ) ; + + if (_OK) return _rr ; + + return (REAL_TYPE) +0.0E+00; + } + } + # undef REAL_TYPE # undef INDX_TYPE diff --git a/src/libcpp/rdel_mesh/rdel_base_2.hpp b/src/libcpp/rdel_mesh/rdel_base_2.hpp index bc38cb3..09167a6 100644 --- a/src/libcpp/rdel_mesh/rdel_base_2.hpp +++ b/src/libcpp/rdel_mesh/rdel_base_2.hpp @@ -555,9 +555,7 @@ // nudge away from orthoball, to sanitise degenerate // cases adj. to sharp boundaries - real_type static const _bump = - std::pow(std::numeric_limits - ::epsilon(), +0.5) ; + real_type constexpr _bump = 0.01 ; real_type _test[2] ; _test[0] = (real_type)1./3. * ( diff --git a/src/libcpp/rdel_mesh/rdel_base_3.hpp b/src/libcpp/rdel_mesh/rdel_base_3.hpp index 06799d6..01a5724 100644 --- a/src/libcpp/rdel_mesh/rdel_base_3.hpp +++ b/src/libcpp/rdel_mesh/rdel_base_3.hpp @@ -367,8 +367,8 @@ containers::array _hset ; _tset. set_alloc(+32); _hset. set_alloc(+32); - edge_loop( _mesh, _enod, - _tadj, _fadj, _tset) ; + edge_loop ( + _mesh, _enod, _tadj, _fadj, _tset) ; if (_tset.count()<+3) return false ; @@ -1032,9 +1032,7 @@ // nudge away from orthoball, to sanitise degenerate // cases adj. to sharp boundaries - real_type static const _bump = - std::pow(std::numeric_limits - ::epsilon(), +0.5) ; + real_type constexpr _bump = 0.01 ; real_type _test[3] ; _test[0] = (real_type)1./4. * ( diff --git a/src/libcpp/rdel_mesh/rdel_cost_delfront_3.inc b/src/libcpp/rdel_mesh/rdel_cost_delfront_3.inc index db3c8a4..236234a 100644 --- a/src/libcpp/rdel_mesh/rdel_cost_delfront_3.inc +++ b/src/libcpp/rdel_mesh/rdel_cost_delfront_3.inc @@ -441,15 +441,15 @@ tria(_tpos)->node(_fnod[ 2]); real_type _fbal [ +4]; - geometry::circ_ball_3d(_fbal , + 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)) ; + node(_fnod[2])->pval(0) ) ; - _frad[_fnum] = _fbal[3]; + _frad[_fnum] = _fbal[3] ; } /*--------------------------------- find min/max edge */ diff --git a/src/libcpp/rdel_mesh/rdel_filt_k.hpp b/src/libcpp/rdel_mesh/rdel_filt_k.hpp index 0b79f8d..938cab4 100644 --- a/src/libcpp/rdel_mesh/rdel_filt_k.hpp +++ b/src/libcpp/rdel_mesh/rdel_filt_k.hpp @@ -216,11 +216,15 @@ typedef keep_base_2d < real_type , iptr_type > pred_base ; + + typedef typename + pred_base::node_data node_type ; + + typedef containers::array < + node_type > list_type ; public : - containers::array < - typename pred_base::node_data> _list ; - + list_type _list ; iptr_type _inum ; bool_type _find ; @@ -291,10 +295,14 @@ real_type , iptr_type > pred_base ; - public : - containers::array < - typename pred_base::node_data> _list ; + typedef typename + pred_base::node_data node_type ; + + typedef containers::array < + node_type > list_type ; + public : + list_type _list ; iptr_type _inum ; bool_type _find ; diff --git a/src/libcpp/rdel_mesh/rdel_make_2.hpp b/src/libcpp/rdel_mesh/rdel_make_2.hpp index 1bba337..e69489b 100644 --- a/src/libcpp/rdel_mesh/rdel_make_2.hpp +++ b/src/libcpp/rdel_mesh/rdel_make_2.hpp @@ -35,9 +35,9 @@ * -------------------------------------------------------- * - * Last updated: 10 Jul., 2021 + * Last updated: 12 Nov., 2024 * - * Copyright 2013-2021 + * Copyright 2013-2024 * Darren Engwirda * d.engwirda@gmail.com * https://github.com/dengwirda/ @@ -139,7 +139,7 @@ */ __static_call - __normal_call void_type test_edge ( + __normal_call void_type push_edge ( mesh_type &_mesh , geom_type &_geom , iptr_type _tpos , @@ -147,62 +147,78 @@ mesh_type::edge_list & _edge_test , iptr_type &_nedg , iptr_type &_ndup , + iptr_type _pass , rdel_opts &_opts ) { + /*-------------------------------- correct node dims? */ + iptr_type _fdim =+0; + for (auto _node =+3; _node-- != +0; ) + { + if (_mesh._tria.node ( + _mesh._tria.tria ( + _tpos)->node(_node))->fdim() <= +1) + _fdim += +1 ; + } + /*-------------------------------- quick break if not */ + if (_fdim < +2 ) return ; + /*-------------------------------- check "restricted" */ for (auto _fpos =+3; _fpos-- != +0; ) { - /*---------------------------- extract face nodes */ + /*---------------------------- extract edge nodes */ iptr_type _tnod[ +3] ; mesh_type::tria_type:: tria_type:: face_node(_tnod, _fpos, +2, +1) ; - _tnod[0] = _mesh._tria. tria(_tpos)->node(_tnod[0]); _tnod[1] = _mesh._tria. tria(_tpos)->node(_tnod[1]); - /*--------------- face contains higher dim. nodes */ if (_mesh._tria.node( - _tnod[0])->fdim() > 1 || + _tnod[0])->fdim() < 2 && _mesh._tria.node( - _tnod[1])->fdim() > 1 ) - continue ; - + _tnod[1])->fdim() < 2 ) + { + /*--------------- face contains correct k^d nodes */ algorithms::isort ( &_tnod[0], &_tnod[2], std::less()) ; - edge_data _fdat; - _fdat._node[0] = _tnod[ 0] ; - _fdat._node[1] = _tnod[ 1] ; + edge_data _edat; + _edat._node[0] = _tnod[ 0] ; + _edat._node[1] = _tnod[ 1] ; + bool_type _test = true; typename mesh_type:: edge_list:: item_type *_mptr = nullptr ; + // pragma omp critical(update_face_edg2) if(_edge_test. - find( _fdat, _mptr) ) + find( _edat, _mptr) ) { /*--------------------------- count bnd. repeats! */ _ndup += _mptr->_data._dups; /*--------------------------- don't test repeats! */ - continue ; + _test = false ; } - _fdat._tadj = _tpos; - _fdat._eadj = + _edat._pass = _pass; + + _edat._tadj = _tpos; + _edat._eadj = (char_type) _fpos; - _fdat._pass = 0 ; - _fdat._dups = 0 ; // count num. dup's + _edat._dups = +0; // count num. dup's // only in hash-set - /*--------------------------- call face predicate */ + if (_test) + { + /*--------------------------- call edge predicate */ char_type _topo[ 2], _feat; - real_type _fbal[ 3]; + real_type _ebal[ 3]; real_type _sbal[ 3]; __unreferenced(_opts); @@ -210,23 +226,28 @@ bool_type _rBND = rdel_pred::edge_ball ( _geom,_mesh, - _fdat._tadj, - _fdat._eadj, - _fbal,_sbal, + _edat._tadj, + _edat._eadj, + _ebal,_sbal, _feat,_topo, - _fdat._part) ; - + _edat._part) ; + /*--------------------------- push edge onto mesh */ + // pragma omp critical(update_face_edg2) + { if (_rBND) _nedg += +1 ; if (_rBND) - _fdat._dups = +1 ; + _edat._dups = +1 ; if (_rBND) - _mesh.push_edge(_fdat) ; + _mesh.push_edge(_edat) ; - _edge_test.push(_fdat) ; + _edge_test.push(_edat) ; + } + } + } } // for (auto _fpos = +3; _fpos-- != +0; ) } @@ -237,7 +258,7 @@ */ __static_call - __normal_call void_type test_tria ( + __normal_call void_type push_tria ( mesh_type &_mesh , geom_type &_geom , iptr_type _tpos , @@ -245,6 +266,7 @@ /* typename mesh_type::tria_list & _tria_test , */ iptr_type &_ntri , + iptr_type _pass , rdel_opts &_opts ) { @@ -258,32 +280,30 @@ _tnod[2] = _mesh. _tria.tria(_tpos)->node(2); - /*--------------- face contains higher dim. nodes */ if (_mesh._tria.node( - _tnod[0])->fdim() > 2 || + _tnod[0])->fdim() < 3 && _mesh._tria.node( - _tnod[1])->fdim() > 2 || + _tnod[1])->fdim() < 3 && _mesh._tria.node( - _tnod[2])->fdim() > 2 ) - return ; - + _tnod[2])->fdim() < 3 ) + { + /*--------------- face contains correct k^d nodes */ tria_data _tdat; _tdat._node[0] = _tnod[ 0] ; _tdat._node[1] = _tnod[ 1] ; _tdat._node[2] = _tnod[ 2] ; - _tdat._tadj = _tpos; + _tdat._tadj = _tpos ; - //!!_tria_test.push (_tdat) ; won't have repeats! + // _tria_test.push( _tdat) ; guarantee no repeats! /*--------------------------- call tria predicate */ _tdat._part = _sign ; - _tdat._pass = +0 ; - - real_type _tbal[ +3] ; + _tdat._pass = _pass ; __unreferenced(_opts); + real_type _tbal[ +3] ; bool_type _rBND = rdel_pred::tria_ball ( _geom,_mesh, @@ -294,11 +314,15 @@ _sign = _tdat._part ; /*--------------------------- push tria onto mesh */ + // pragma omp critical(update_face_tri3) + { if (_rBND) _ntri += +1 ; if (_rBND) _mesh.push_tria(_tdat) ; + } + } } } @@ -312,52 +336,36 @@ __normal_call void_type push_tria ( mesh_type &_mesh , iptr_type _tpos , - iptr_type &_ntri , rdel_opts &_opts ) { /*-------------------------------- check "restricted" */ { - iptr_type _tnod[ +3] ; - _tnod[0] = _mesh. - _tria.tria(_tpos)->node(0); - _tnod[1] = _mesh. - _tria.tria(_tpos)->node(1); - _tnod[2] = _mesh. - _tria.tria(_tpos)->node(2); - - /*--------------- face contains higher dim. nodes */ + tria_data _tdat; + _tdat._node[0] = _mesh. + _tria.tria(_tpos)->node(0) ; + _tdat._node[1] = _mesh. + _tria.tria(_tpos)->node(1) ; + _tdat._node[2] = _mesh. + _tria.tria(_tpos)->node(2) ; + if (_mesh._tria.node( - _tnod[0])->fdim() > 2 || + _tdat._node[0])->fdim() < 3 && _mesh._tria.node( - _tnod[1])->fdim() > 2 || + _tdat._node[1])->fdim() < 3 && _mesh._tria.node( - _tnod[2])->fdim() > 2 ) - return ; - - tria_data _tdat; - _tdat._node[0] = _tnod[ 0] ; - _tdat._node[1] = _tnod[ 1] ; - _tdat._node[2] = _tnod[ 2] ; - - _tdat._tadj = _tpos; - - //!!_tria_test.push (_tdat) ; won't have repeats! - + _tdat._node[2])->fdim() < 3 ) + { /*--------------------------- call tria predicate */ + _tdat._tadj = _tpos ; _tdat._part = +0 ; _tdat._pass = +0 ; __unreferenced (_opts) ; - bool_type _rBND = true ; - /*--------------------------- push tria onto mesh */ - if (_rBND) _ntri += +1 ; - - if (_rBND) _mesh.push_tria(_tdat) ; - + } } } @@ -720,6 +728,14 @@ __unreferenced(_time) ; // why does MSVC need this?? # endif//__use_timers + iptr_type _ncpu = +1 ; //!! sequential for now... + + # ifdef __use_openmp + omp_set_num_threads(_ncpu); + # else + __unreferenced (_ncpu) ; + # endif//__use_openmp + /*------------------------------ initialise mesh obj. */ # ifdef __use_timers _ttic = _time.now() ; @@ -734,18 +750,23 @@ _tcpu.time_span(_ttic,_ttoc) ; # endif//__use_timers - iptr_type _nedg = +0 ; - iptr_type _ntri = +0 ; + iptr_type _pass = +0 ; + iptr_type _sign = -1 ; - iptr_type _ndup = +0 ; + iptr_type _nedg = +0 ; + iptr_type _ntri = +0 ; + iptr_type _ndup = +0 ; /*------------------------- DT cells to check for rDT */ + # ifdef __use_timers + _ttic = _time.now() ; + # endif//__use_timers + iptr_list _tnew ; _tnew.set_alloc ( _mesh._tria._tset.count()) ; iptr_type _tpos = +0 ; - for (auto _iter = _mesh._tria._tset.head() ; _iter != @@ -761,6 +782,9 @@ if (_geom.have_feat(1) ) { /*------------------------- calc. voronoi-dual points */ + // pragma omp parallel default(shared) + { + // pragma omp for schedule(static) for( auto _iter = _tnew.head(); _iter != _tnew.tend(); ++_iter ) @@ -768,119 +792,118 @@ tria_circ(_mesh, *_iter) ; } } + } else { /*------------------------- prune scaffolding tria.'s */ + _mesh._tset.set_slots(_tnew.count()* 1) ; + for( auto _iter = _tnew.head(); _iter != _tnew.tend(); ++_iter ) { - push_tria( _mesh, - *_iter, _ntri, _args) ; + push_tria(_mesh, *_iter, _args + ) ; } } + # ifdef __use_timers + _ttoc = _time.now() ; + _tcpu._mesh_seed += + _tcpu.time_span(_ttic,_ttoc) ; + # endif//__use_timers /*------------------------- test for restricted edges */ - if (_args.dims() >= 1 && - _geom.have_feat(1) ) - { - - typename - mesh_type::edge_list _eset ( - typename mesh_type::edge_hash(), - typename mesh_type::edge_pred(), - +.8, _mesh._eset.get_alloc(), - _tnew.count()*3) ; - # ifdef __use_timers _ttic = _time.now() ; # endif//__use_timers - for( auto _iter = _tnew.head(); - _iter != _tnew.tend(); - ++_iter ) + if (_args.dims() >= 1 && _geom.have_feat( 1) ) { - test_edge( _mesh, _geom,*_iter, - _eset, _nedg, _ndup, _args - ) ; - } + _mesh._eset.set_slots(_tnew.count() * 3) ; + _mesh._etwo.clear(); + _mesh._etwo.set_slots(_tnew.count() * 3) ; + + // pragma omp parallel default(shared) + { + // pragma omp for schedule(static) + for( auto _iter = _tnew.head(); + _iter != _tnew.tend(); + ++_iter ) + { + push_edge( _mesh, _geom,*_iter, + _mesh. _etwo, + _nedg, _ndup, _pass, _args) ; + } + } + } # ifdef __use_timers _ttoc = _time.now() ; _tcpu._edge_init += _tcpu.time_span(_ttic,_ttoc) ; # endif//__use_timers - } - /*------------------------- test for restricted cells */ - if (_args.dims() >= 2 && - _geom.have_feat(1) ) - { - bool_type _safe = true ; - iptr_type _sign = -1 ; - - //if (_nedg >= +1) _safe = false ; - if (_ndup >= +1) _safe = false ; - - //typename - // mesh_type::tria_list _tset ( - //typename mesh_type::tria_hash(), - //typename mesh_type::tria_pred(), - // +.8, _mesh._tset.get_alloc(), - // _tnew.count()*1) ; - # ifdef __use_timers _ttic = _time.now() ; # endif//__use_timers - for( auto _iter = _tnew.head(); - _iter != _tnew.tend(); - ++_iter ) + if (_args.dims() >= 2 && _geom.have_feat( 1) ) { - _sign = _safe ? _sign : -1 ; + // _mesh._tset.set_slots(_tnew.count() * 1) ; - test_tria( _mesh, _geom, - *_iter, _sign, _ntri, _args - ) ; - } + // _mesh._ttwo.clear(); + // _mesh._ttwo.set_slots(_tnew.count() * 1) ; + bool_type _safe = true ; + // if (_dim0 > +0) _safe = false ; + // if (_nfac >= +1) _safe = false ; + if (_ndup >= +1) _safe = false ; + + // pragma omp parallel default(shared) + { + // pragma omp for schedule(static) + for( auto _iter = _tnew.head(); + _iter != _tnew.tend(); + ++_iter ) + { + _sign = (!_safe) ? -1 : _sign; + + push_tria( _mesh, _geom,*_iter, + _sign, _ntri, _pass, _args) ; + } + } + } # ifdef __use_timers _ttoc = _time.now() ; _tcpu._tria_init += _tcpu.time_span(_ttic,_ttoc) ; # endif//__use_timers - } - if (_args.verb() >= +2 ) { - /*------------------------- push rDEL scheme metrics */ - + /*------------------------- push rDT scheme's metrics */ _dump.push("\n") ; _dump.push("**TIMING statistics...\n") ; _dump.push(" *mesh-seed = ") ; - _dump.push( - std::to_string (_tcpu._mesh_seed)); + _dump.push(std::to_string (_tcpu._mesh_seed)); _dump.push("\n") ; _dump.push(" *edge-init = ") ; - _dump.push( - std::to_string (_tcpu._edge_init)); + _dump.push(std::to_string (_tcpu._edge_init)); _dump.push("\n") ; _dump.push(" *tria-init = ") ; - _dump.push( - std::to_string (_tcpu._tria_init)); + _dump.push(std::to_string (_tcpu._tria_init)); _dump.push("\n") ; _dump.push("\n") ; _dump.push("**rDT(x) statistics...\n") ; _dump.push(" *rDEL-edge = "); - _dump.push(std::to_string (_nedg)); + _dump.push(std::to_string (_mesh._eset.count())) ; _dump.push("\n") ; _dump.push(" *rDEL-tria = "); - _dump.push(std::to_string (_ntri)); + _dump.push(std::to_string (_mesh._tset.count())) ; _dump.push("\n") ; _dump.push("\n") ; @@ -888,61 +911,54 @@ if (_args.verb() >= +2 ) { - /*------------------------- more rDEL scheme metrics */ - + /*------------------------- more rDT scheme's metrics */ _dump.push("\n") ; _dump.push("**MEMORY statistics...\n") ; _dump.push(" xDEL-type:\n") ; _dump.push(" *node-byte = ") ; - _dump.push(std::to_string( - sizeof(typename mesh_type:: - tria_type:: node_type)) ) ; + _dump.push(std::to_string(sizeof( + typename mesh_type::tria_type::node_type))); _dump.push("\n") ; _dump.push(" *nset-size = ") ; _dump.push(std::to_string( _mesh._tria._nset.alloc())) ; _dump.push("\n") ; _dump.push(" *tria-byte = ") ; - _dump.push(std::to_string( - sizeof(typename mesh_type:: - tria_type:: tria_type)) ) ; + _dump.push(std::to_string(sizeof( + typename mesh_type::tria_type::tria_type))); _dump.push("\n") ; _dump.push(" *tset-size = ") ; - _dump.push(std::to_string( - _mesh._tria._tset.alloc())) ; + _dump.push( + std::to_string(_mesh._tria._tset.alloc())) ; _dump.push("\n") ; _dump.push(" *pool-byte = ") ; - _dump.push(std::to_string( - _mesh._tria._fpol.bytes())) ; + _dump.push( + std::to_string(_mesh._tria._fpol.bytes())) ; _dump.push("\n") ; _dump.push(" rDEL-type:\n") ; _dump.push(" *edge-byte = ") ; _dump.push(std::to_string( - sizeof( - typename mesh_type::edge_item)) ) ; + sizeof(typename mesh_type::edge_item))) ; _dump.push("\n") ; _dump.push(" *eset-size = ") ; - _dump.push(std::to_string( - _mesh._eset._lptr.alloc())) ; + _dump.push( + std::to_string(_mesh._eset._lptr.alloc())) ; _dump.push("\n") ; _dump.push(" *pool-byte = ") ; - _dump.push( - std::to_string(_mesh._epol.bytes())) ; + _dump.push(std::to_string(_mesh._epol.bytes())); _dump.push("\n") ; _dump.push(" *tria-byte = ") ; _dump.push(std::to_string( - sizeof( - typename mesh_type::tria_item)) ) ; + sizeof(typename mesh_type::tria_item))) ; _dump.push("\n") ; _dump.push(" *tset-size = ") ; - _dump.push(std::to_string( - _mesh._tset._lptr.alloc())) ; + _dump.push( + std::to_string(_mesh._tset._lptr.alloc())) ; _dump.push("\n") ; _dump.push(" *pool-byte = ") ; - _dump.push( - std::to_string(_mesh._tpol.bytes())) ; + _dump.push(std::to_string(_mesh._tpol.bytes())); _dump.push("\n") ; _dump.push("\n") ; diff --git a/src/libcpp/rdel_mesh/rdel_make_3.hpp b/src/libcpp/rdel_mesh/rdel_make_3.hpp index 9f5fe4e..a45481f 100644 --- a/src/libcpp/rdel_mesh/rdel_make_3.hpp +++ b/src/libcpp/rdel_mesh/rdel_make_3.hpp @@ -35,9 +35,9 @@ * -------------------------------------------------------- * - * Last updated: 12 Jul., 2021 + * Last updated: 12 Nov., 2024 * - * Copyright 2013-2021 + * Copyright 2013-2024 * Darren Engwirda * d.engwirda@gmail.com * https://github.com/dengwirda/ @@ -126,6 +126,13 @@ typedef containers::array < iptr_type > iptr_list ; + typedef containers::array < + edge_data > edat_list ; + typedef containers::array < + face_data > fdat_list ; + typedef containers::array < + tria_data > tdat_list ; + typedef mesh::rdel_pred_base_3 < geom_type, mesh_type > rdel_pred ; @@ -141,16 +148,29 @@ */ __static_call - __normal_call void_type test_edge ( + __normal_call void_type push_edge ( mesh_type &_mesh , geom_type &_geom , iptr_type _tpos , typename mesh_type::edge_list & _edge_test , iptr_type &_nedg , + iptr_type _pass , rdel_opts &_opts ) { + /*-------------------------------- correct node dims? */ + iptr_type _fdim =+0; + for (auto _node =+4; _node-- != +0; ) + { + if (_mesh._tria.node ( + _mesh._tria.tria ( + _tpos)->node(_node))->fdim() <= +1) + _fdim += +1 ; + } + /*-------------------------------- quick break if not */ + if (_fdim < +2 ) return ; + /*-------------------------------- check "restricted" */ for (auto _fpos =+6; _fpos-- != +0; ) { @@ -164,13 +184,12 @@ _tnod[1] = _mesh._tria. tria(_tpos)->node(_tnod[1]); - /*--------------- face contains higher dim. nodes */ if (_mesh._tria.node( - _tnod[0])->fdim() > 1 || + _tnod[0])->fdim() < 2 && _mesh._tria.node( - _tnod[1])->fdim() > 1 ) - continue ; - + _tnod[1])->fdim() < 2 ) + { + /*--------------- face contains correct k^d nodes */ algorithms::isort ( &_tnod[0], &_tnod[2], std::less()) ; @@ -179,45 +198,55 @@ _edat._node[0] = _tnod[ 0] ; _edat._node[1] = _tnod[ 1] ; + bool_type _test = true; typename mesh_type:: edge_list:: item_type *_mptr = nullptr ; + // pragma omp critical(update_face_edg2) if(_edge_test. find( _edat, _mptr) ) { /*--------------------------- don't test repeats! */ - continue ; + _test = false; } + _edat._pass = _pass; + _edat._tadj = _tpos; _edat._eadj = (char_type) _fpos; - _edat._pass = +0 ; + if (_test) + { /*--------------------------- call edge predicate */ - real_type _fbal[ 4]; + char_type _topo[ 2], _feat; + real_type _ebal[ 4]; real_type _sbal[ 4]; __unreferenced(_opts); - bool_type _rBND = + bool_type _rBND = rdel_pred::edge_ball ( _geom,_mesh, _edat._tadj, _edat._eadj, - _fbal,_sbal, - _edat._feat, - _edat._topo, + _ebal,_sbal, + _feat,_topo, _edat._part) ; - + /*--------------------------- push edge onto mesh */ + // pragma omp critical(update_face_edg2) + { if (_rBND) _nedg += +1 ; if (_rBND) - _mesh.push_edge(_edat) ; + _mesh.push_edge (_edat) ; - _edge_test.push(_edat) ; + _edge_test.push (_edat) ; + } + } + } } // for (auto _fpos = +6; _fpos-- != +0; ) } @@ -228,7 +257,7 @@ */ __static_call - __normal_call void_type test_face ( + __normal_call void_type push_face ( mesh_type &_mesh , geom_type &_geom , iptr_type _tpos , @@ -236,9 +265,22 @@ mesh_type::face_list & _face_test , iptr_type &_nfac , iptr_type &_ndup , + iptr_type _pass , rdel_opts &_opts ) { + /*-------------------------------- correct node dims? */ + iptr_type _fdim =+0; + for (auto _node =+4; _node-- != +0; ) + { + if (_mesh._tria.node ( + _mesh._tria.tria ( + _tpos)->node(_node))->fdim() <= +2) + _fdim += +1 ; + } + /*-------------------------------- quick break if not */ + if (_fdim < +3 ) return ; + /*-------------------------------- check "restricted" */ for (auto _fpos =+4; _fpos-- != +0; ) { @@ -254,15 +296,14 @@ _tnod[2] = _mesh._tria. tria(_tpos)->node(_tnod[2]); - /*--------------- face contains higher dim. nodes */ if (_mesh._tria.node( - _tnod[0])->fdim() > 2 || + _tnod[0])->fdim() < 3 && _mesh._tria.node( - _tnod[1])->fdim() > 2 || + _tnod[1])->fdim() < 3 && _mesh._tria.node( - _tnod[2])->fdim() > 2 ) - continue ; - + _tnod[2])->fdim() < 3 ) + { + /*--------------- face contains correct k^d nodes */ algorithms::isort ( &_tnod[0], &_tnod[3], std::less()) ; @@ -272,9 +313,11 @@ _fdat._node[1] = _tnod[ 1] ; _fdat._node[2] = _tnod[ 2] ; + bool_type _test = true; typename mesh_type:: face_list:: item_type *_mptr = nullptr ; + // pragma omp critical(update_face_tri3) if(_face_test. find( _fdat, _mptr) ) { @@ -283,16 +326,19 @@ _mptr->_data._dups; /*--------------------------- don't test repeats! */ - continue ; + _test = false ; } + _fdat._pass = _pass; + _fdat._tadj = _tpos; _fdat._fadj = (char_type) _fpos; - _fdat._pass = 0 ; - _fdat._dups = 0 ; // count num. dup's + _fdat._dups = +0; // count num. dup's // only in hash-set + if (_test) + { /*--------------------------- call face predicate */ char_type _topo[ 2], _feat; real_type _fbal[ 4]; @@ -308,8 +354,10 @@ _fbal,_sbal, _feat,_topo, _fdat._part) ; - + /*--------------------------- push face onto mesh */ + // pragma omp critical(update_face_tri3) + { if (_rBND) _nfac += +1 ; if (_rBND) @@ -319,7 +367,10 @@ _mesh.push_face(_fdat) ; _face_test.push(_fdat) ; + } + } + } } // for (auto _fpos = +4; _fpos-- != +0; ) } @@ -330,7 +381,7 @@ */ __static_call - __normal_call void_type test_tria ( + __normal_call void_type push_tria ( mesh_type &_mesh , geom_type &_geom , iptr_type _tpos , @@ -338,11 +389,12 @@ /* typename mesh_type::tria_list & _tria_test , */ iptr_type &_ntri , + iptr_type _pass , rdel_opts &_opts ) { - /*-------------------------------- check "restricted" */ { + /*---------------------------- check "restricted" */ iptr_type _tnod[ +4] ; _tnod[0] = _mesh. _tria.tria(_tpos)->node(0); @@ -353,35 +405,33 @@ _tnod[3] = _mesh. _tria.tria(_tpos)->node(3); - /*--------------- face contains higher dim. nodes */ if (_mesh._tria.node( - _tnod[0])->fdim() > 3 || + _tnod[0])->fdim() < 4 && _mesh._tria.node( - _tnod[1])->fdim() > 3 || + _tnod[1])->fdim() < 4 && _mesh._tria.node( - _tnod[2])->fdim() > 3 || + _tnod[2])->fdim() < 4 && _mesh._tria.node( - _tnod[3])->fdim() > 3 ) - return ; - + _tnod[3])->fdim() < 4 ) + { + /*--------------- face contains correct k^d nodes */ tria_data _tdat; _tdat._node[0] = _tnod[ 0] ; _tdat._node[1] = _tnod[ 1] ; _tdat._node[2] = _tnod[ 2] ; _tdat._node[3] = _tnod[ 3] ; - _tdat._tadj = _tpos; + _tdat._tadj = _tpos ; - //!!_tria_test.push (_tdat) ; won't have repeats! + // _tria_test.push( _tdat) ; guarantee no repeats! - /*--------------------------- call tria predicate */ + /*--------------------------- calc tria cost/kind */ _tdat._part = _sign ; - _tdat._pass = +0 ; - - real_type _tbal[ +4] ; + _tdat._pass = _pass ; __unreferenced(_opts); + real_type _tbal[ +4] ; bool_type _rBND = rdel_pred::tria_ball ( _geom,_mesh, @@ -389,14 +439,18 @@ _tbal, _tdat._part) ; - _sign = _tdat._part ; + _sign = _tdat. _part ; /*--------------------------- push tria onto mesh */ + // pragma omp critical(update_face_tri4) + { if (_rBND) _ntri += +1 ; if (_rBND) _mesh.push_tria(_tdat) ; + } + } } } @@ -410,55 +464,40 @@ __normal_call void_type push_tria ( mesh_type &_mesh , iptr_type _tpos , - iptr_type &_ntri , rdel_opts &_opts ) { /*-------------------------------- check "restricted" */ { - iptr_type _tnod[ +4] ; - _tnod[0] = _mesh. - _tria.tria(_tpos)->node(0); - _tnod[1] = _mesh. - _tria.tria(_tpos)->node(1); - _tnod[2] = _mesh. - _tria.tria(_tpos)->node(2); - _tnod[3] = _mesh. - _tria.tria(_tpos)->node(3); + tria_data _tdat; + _tdat._node[0] = _mesh. + _tria.tria(_tpos)->node(0) ; + _tdat._node[1] = _mesh. + _tria.tria(_tpos)->node(1) ; + _tdat._node[2] = _mesh. + _tria.tria(_tpos)->node(2) ; + _tdat._node[3] = _mesh. + _tria.tria(_tpos)->node(3) ; - /*--------------- face contains higher dim. nodes */ if (_mesh._tria.node( - _tnod[0])->fdim() > 3 || + _tdat._node[0])->fdim() < 4 && _mesh._tria.node( - _tnod[1])->fdim() > 3 || + _tdat._node[1])->fdim() < 4 && _mesh._tria.node( - _tnod[2])->fdim() > 3 || + _tdat._node[2])->fdim() < 4 && _mesh._tria.node( - _tnod[3])->fdim() > 3 ) - return ; - - tria_data _tdat; - _tdat._node[0] = _tnod[ 0] ; - _tdat._node[1] = _tnod[ 1] ; - _tdat._node[2] = _tnod[ 2] ; - _tdat._node[3] = _tnod[ 3] ; - - _tdat._tadj = _tpos ; - + _tdat._node[3])->fdim() < 4 ) + { /*--------------------------- call tria predicate */ + _tdat._tadj = _tpos ; _tdat._part = +0 ; _tdat._pass = +0 ; __unreferenced (_opts) ; - bool_type _rBND = true ; - /*--------------------------- push tria onto mesh */ - if (_rBND) _ntri += +1 ; - - if (_rBND) _mesh.push_tria(_tdat) ; - + } } } @@ -850,6 +889,14 @@ __unreferenced(_time) ; // why does MSVC need this?? # endif//__use_timers + iptr_type _ncpu = +1 ; //!! sequential for now... + + # ifdef __use_openmp + omp_set_num_threads(_ncpu); + # else + __unreferenced (_ncpu) ; + # endif//__use_openmp + /*------------------------------ initialise mesh obj. */ # ifdef __use_timers _ttic = _time.now() ; @@ -864,19 +911,24 @@ _tcpu.time_span(_ttic,_ttoc) ; # endif//__use_timers - iptr_type _nedg = +0 ; - iptr_type _nfac = +0 ; - iptr_type _ntri = +0 ; + iptr_type _pass = +0 ; + iptr_type _sign = -1 ; - iptr_type _ndup = +0 ; + iptr_type _nedg = +0 ; + iptr_type _nfac = +0 ; + iptr_type _ntri = +0 ; + iptr_type _ndup = +0 ; /*------------------------- DT cells to check for rDT */ + # ifdef __use_timers + _ttic = _time.now() ; + # endif//__use_timers + iptr_list _tnew ; _tnew.set_alloc ( _mesh._tria._tset.count()) ; iptr_type _tpos = +0 ; - for (auto _iter = _mesh._tria._tset.head() ; _iter != @@ -893,6 +945,9 @@ _geom.have_feat(2) ) { /*------------------------- calc. voronoi-dual points */ + // pragma omp parallel default(shared) + { + // pragma omp for schedule(static) for( auto _iter = _tnew.head(); _iter != _tnew.tend(); ++_iter ) @@ -900,234 +955,225 @@ tria_circ(_mesh, *_iter) ; } } + } else { /*------------------------- prune scaffolding tria.'s */ + _mesh._tset.set_slots(_tnew.count()* 1) ; + for( auto _iter = _tnew.head(); _iter != _tnew.tend(); ++_iter ) { - push_tria( _mesh, - *_iter, _ntri, _args) ; + push_tria(_mesh, *_iter, _args + ) ; } } + # ifdef __use_timers + _ttoc = _time.now() ; + _tcpu._mesh_seed += + _tcpu.time_span(_ttic,_ttoc) ; + # endif//__use_timers /*------------------------- test for restricted edges */ - if (_args.dims() >= 1 && - _geom.have_feat(1) ) - { - - typename - mesh_type::edge_list _eset ( - typename mesh_type::edge_hash(), - typename mesh_type::edge_pred(), - +.8, _mesh._eset.get_alloc(), - _tnew.count()*6) ; - # ifdef __use_timers _ttic = _time.now() ; # endif//__use_timers - for( auto _iter = _tnew.head(); - _iter != _tnew.tend(); - ++_iter ) + if (_args.dims() >= 1 && _geom.have_feat( 1) ) { - test_edge( _mesh, _geom, - *_iter, _eset, _nedg, _args - ) ; - } + _mesh._eset.set_slots(_tnew.count() * 6) ; + _mesh._etwo.clear(); + _mesh._etwo.set_slots(_tnew.count() * 6) ; + + // pragma omp parallel default(shared) + { + // pragma omp for schedule(static) + for( auto _iter = _tnew.head(); + _iter != _tnew.tend(); + ++_iter ) + { + push_edge( _mesh, _geom,*_iter, + _mesh. _etwo, + _nedg, _pass, _args) ; + } + } + } # ifdef __use_timers _ttoc = _time.now() ; _tcpu._edge_init += _tcpu.time_span(_ttic,_ttoc) ; # endif//__use_timers - } - /*------------------------- test for restricted faces */ - if (_args.dims() >= 2 && - _geom.have_feat(2) ) - { - - typename - mesh_type::face_list _fset ( - typename mesh_type::face_hash(), - typename mesh_type::face_pred(), - +.8, _mesh._fset.get_alloc(), - _tnew.count()*4) ; - # ifdef __use_timers _ttic = _time.now() ; # endif//__use_timers - for( auto _iter = _tnew.head(); - _iter != _tnew.tend(); - ++_iter ) + if (_args.dims() >= 2 && _geom.have_feat( 2) ) { - test_face( _mesh, _geom,*_iter, - _fset, _nfac, _ndup, _args - ) ; - } + _mesh._fset.set_slots(_tnew.count() * 4) ; + + _mesh._ftwo.clear(); + _mesh._ftwo.set_slots(_tnew.count() * 4) ; + // pragma omp parallel default(shared) + { + // pragma omp for schedule(static) + for( auto _iter = _tnew.head(); + _iter != _tnew.tend(); + ++_iter ) + { + push_face( _mesh, _geom,*_iter, + _mesh. _ftwo, + _nfac, _ndup, _pass, _args) ; + } + } + } # ifdef __use_timers _ttoc = _time.now() ; _tcpu._face_init += _tcpu.time_span(_ttic,_ttoc) ; # endif//__use_timers - } - /*------------------------- test for restricted cells */ - if (_args.dims() >= 3 && - _geom.have_feat(2) ) - { - bool_type _safe = true ; - iptr_type _sign = -1 ; - - //if (_nfac >= +1) _safe = false ; - if (_ndup >= +1) _safe = false ; - - //typename - // mesh_type::tria_list _tset ( - //typename mesh_type::tria_hash(), - //typename mesh_type::tria_pred(), - // +.8, _mesh._tset.get_alloc(), - // _tnew.count()*1) ; - # ifdef __use_timers _ttic = _time.now() ; # endif//__use_timers - for( auto _iter = _tnew.head(); - _iter != _tnew.tend(); - ++_iter ) + if (_args.dims() >= 3 && _geom.have_feat( 2) ) { - _sign = _safe ? _sign : -1 ; + // _mesh._tset.set_slots(_tnew.count() * 1) ; - test_tria( _mesh, _geom, - *_iter, _sign, _ntri, _args - ) ; - } + // _mesh._ttwo.clear(); + // _mesh._ttwo.set_slots(_tnew.count() * 1) ; + + bool_type _safe = true ; + // if (_dim0 > +0) _safe = false ; + // if (_nfac >= +1) _safe = false ; + if (_ndup >= +1) _safe = false ; + + // pragma omp parallel default(shared) + { + // pragma omp for schedule(static) + for( auto _iter = _tnew.head(); + _iter != _tnew.tend(); + ++_iter ) + { + _sign = (!_safe) ? -1 : _sign; + push_tria( _mesh, _geom,*_iter, + _sign, _ntri, _pass, _args) ; + } + } + } # ifdef __use_timers _ttoc = _time.now() ; _tcpu._tria_init += _tcpu.time_span(_ttic,_ttoc) ; # endif//__use_timers - } - if (_args.verb() >= +2 ) { - /*------------------------- push rDEL scheme metrics */ + /*------------------------- push rDT scheme's metrics */ _dump.push("\n") ; _dump.push("**TIMING statistics...\n") ; _dump.push(" *mesh-seed = ") ; - _dump.push( - std::to_string (_tcpu._mesh_seed)); + _dump.push(std::to_string (_tcpu._mesh_seed)); _dump.push("\n") ; _dump.push(" *edge-init = ") ; - _dump.push( - std::to_string (_tcpu._edge_init)); + _dump.push(std::to_string (_tcpu._edge_init)); _dump.push("\n") ; _dump.push(" *face-init = ") ; - _dump.push( - std::to_string (_tcpu._face_init)); + _dump.push(std::to_string (_tcpu._face_init)); _dump.push("\n") ; _dump.push(" *tria-init = ") ; - _dump.push( - std::to_string (_tcpu._tria_init)); + _dump.push(std::to_string (_tcpu._tria_init)); _dump.push("\n") ; _dump.push("\n") ; _dump.push("**rDT(x) statistics...\n") ; _dump.push(" *rDEL-edge = "); - _dump.push(std::to_string (_nedg)); + _dump.push(std::to_string (_mesh._eset.count())) ; _dump.push("\n") ; _dump.push(" *rDEL-face = "); - _dump.push(std::to_string (_nfac)); + _dump.push(std::to_string (_mesh._fset.count())) ; _dump.push("\n") ; _dump.push(" *rDEL-tria = "); - _dump.push(std::to_string (_ntri)); + _dump.push(std::to_string (_mesh._tset.count())) ; _dump.push("\n") ; + _dump.push("\n") ; } if (_args.verb() >= +2 ) { - /*------------------------- more rDEL scheme metrics */ + /*------------------------- more rDT scheme's metrics */ _dump.push("\n") ; _dump.push("**MEMORY statistics...\n") ; _dump.push(" xDEL-type:\n") ; _dump.push(" *node-byte = ") ; - _dump.push(std::to_string( - sizeof(typename mesh_type:: - tria_type:: node_type)) ) ; + _dump.push(std::to_string(sizeof( + typename mesh_type::tria_type::node_type))); _dump.push("\n") ; _dump.push(" *nset-size = ") ; - _dump.push(std::to_string( - _mesh._tria._nset.alloc())) ; + _dump.push( + std::to_string(_mesh._tria._nset.alloc())) ; _dump.push("\n") ; _dump.push(" *tria-byte = ") ; - _dump.push(std::to_string( - sizeof(typename mesh_type:: - tria_type:: tria_type)) ) ; + _dump.push(std::to_string(sizeof( + typename mesh_type::tria_type::tria_type))); _dump.push("\n") ; _dump.push(" *tset-size = ") ; - _dump.push(std::to_string( - _mesh._tria._tset.alloc())) ; + _dump.push( + std::to_string(_mesh._tria._tset.alloc())) ; _dump.push("\n") ; _dump.push(" *pool-byte = ") ; - _dump.push(std::to_string( - _mesh._tria._fpol.bytes())) ; + _dump.push( + std::to_string(_mesh._tria._fpol.bytes())) ; _dump.push("\n") ; _dump.push("\n") ; _dump.push(" rDEL-type:\n") ; _dump.push(" *edge-byte = ") ; _dump.push(std::to_string( - sizeof( - typename mesh_type::edge_item)) ) ; + sizeof(typename mesh_type::edge_item))) ; _dump.push("\n") ; _dump.push(" *eset-size = ") ; - _dump.push(std::to_string( - _mesh._eset._lptr.alloc())) ; + _dump.push( + std::to_string(_mesh._eset._lptr.alloc())) ; _dump.push("\n") ; _dump.push(" *pool-byte = ") ; - _dump.push( - std::to_string(_mesh._epol.bytes())) ; + _dump.push(std::to_string(_mesh._epol.bytes())); _dump.push("\n") ; _dump.push(" *face-byte = ") ; _dump.push(std::to_string( - sizeof( - typename mesh_type::face_item)) ) ; + sizeof(typename mesh_type::face_item))) ; _dump.push("\n") ; _dump.push(" *fset-size = ") ; - _dump.push(std::to_string( - _mesh._fset._lptr.alloc())) ; + _dump.push( + std::to_string(_mesh._fset._lptr.alloc())) ; _dump.push("\n") ; _dump.push(" *pool-byte = ") ; - _dump.push( - std::to_string(_mesh._fpol.bytes())) ; + _dump.push(std::to_string(_mesh._fpol.bytes())); _dump.push("\n") ; _dump.push(" *tria-byte = ") ; _dump.push(std::to_string( - sizeof( - typename mesh_type::tria_item)) ) ; + sizeof(typename mesh_type::tria_item))) ; _dump.push("\n") ; _dump.push(" *tset-size = ") ; - _dump.push(std::to_string( - _mesh._tset._lptr.alloc())) ; + _dump.push( + std::to_string(_mesh._tset._lptr.alloc())) ; _dump.push("\n") ; _dump.push(" *pool-byte = ") ; - _dump.push( - std::to_string(_mesh._tpol.bytes())) ; + _dump.push(std::to_string(_mesh._tpol.bytes())); _dump.push("\n") ; + _dump.push("\n") ; } } diff --git a/src/libcpp/rdel_mesh/rdel_mesh_2.hpp b/src/libcpp/rdel_mesh/rdel_mesh_2.hpp index f7e5831..9bdfecb 100644 --- a/src/libcpp/rdel_mesh/rdel_mesh_2.hpp +++ b/src/libcpp/rdel_mesh/rdel_mesh_2.hpp @@ -35,9 +35,9 @@ * -------------------------------------------------------- * - * Last updated: 12 Jul., 2021 + * Last updated: 21 Apr., 2024 * - * Copyright 2013-2021 + * Copyright 2013-2024 * Darren Engwirda * d.engwirda@gmail.com * https://github.com/dengwirda/ @@ -149,6 +149,8 @@ char_type static constexpr edge_mode = +2 ; char_type static constexpr etop_mode = +3 ; char_type static constexpr tria_mode = +4 ; + + mesh::rdel_timers static inline _tcpu ; class node_pred ; class ball_pred ; class edge_pred ; class tria_pred ; @@ -180,8 +182,6 @@ typedef typename mesh_type::tria_list tria_hash ; - typedef mesh::rdel_timers rdel_stat ; - typedef mesh::mesh_params < real_type, iptr_type > rdel_opts ; @@ -192,13 +192,10 @@ /*------------------------------------------ cavity lists */ typedef containers::array < edge_data > edat_list ; - typedef containers::array < edge_cost > escr_list ; - typedef containers::array < tria_data > tdat_list ; - typedef containers::array < tria_cost > tscr_list ; @@ -206,11 +203,9 @@ typedef containers::priorityset < node_data, node_pred > node_heap ; - typedef containers::priorityset < edge_cost, edge_pred > edge_heap ; - typedef containers::priorityset < tria_cost, tria_pred > tria_heap ; @@ -218,7 +213,6 @@ /*------------------------------------------ collar lists */ typedef containers::array < ball_data > ball_list ; - typedef containers::priorityset < ball_data, ball_pred > ball_heap ; @@ -328,18 +322,16 @@ ) { typedef typename - list_type:: - size_type size_type; + list_type::size_type size_type; - size_type _amin = +512; - size_type _alim = +256; + size_type constexpr _amin = 512 ; + size_type constexpr _alim = 256 ; size_type _amax = - (size_type)+3 * _list.count() ; + (size_type)+3 * _list.count() ; size_type _anew = - (size_type)+2 * _list.count() ; + (size_type)+2 * _list.count() ; - _anew = - std::max(_alim, _anew) ; + _anew = std::max (_alim, _anew) ; if (_list.alloc() > _amin) if (_list.alloc() > _amax) @@ -360,9 +352,7 @@ { if(!_eepq.empty()) { - - iptr_type _dead = +0, _okay = +0 ; - + iptr_type _dead = +0, _okay = +0; for (auto _hpos = _eepq.count() - 1 ; _hpos > +0 ; --_hpos ) @@ -372,6 +362,7 @@ iptr_type _pass; edge_data _edat; + // from PQ so already sorted for hash _edat._node[0] = _eepq. peek(_hpos)._node[0]; _edat._node[1] = @@ -386,14 +377,12 @@ if(!_mesh.find_edge(_edat,_eptr)) { _eepq._pop(_hpos) ; - _dead += +1 ; } else if (_eptr->_data._pass != _pass ) { _eepq._pop(_hpos) ; - _dead += +1 ; } else @@ -420,9 +409,7 @@ { if(!_ttpq.empty()) { - - iptr_type _dead = +0, _okay = +0 ; - + iptr_type _dead = +0, _okay = +0; for (auto _hpos = _ttpq.count() - 1 ; _hpos > +0 ; --_hpos ) @@ -432,6 +419,7 @@ iptr_type _pass; tria_data _tdat; + // from PQ so already sorted for hash _tdat._node[0] = _ttpq. peek(_hpos)._node[0]; _tdat._node[1] = @@ -448,14 +436,12 @@ if(!_mesh.find_tria(_tdat,_tptr)) { _ttpq._pop(_hpos); - _dead += +1 ; } else if (_tptr->_data._pass != _pass ) { _ttpq._pop(_hpos); - _dead += +1 ; } else @@ -468,6 +454,45 @@ trim_list ( _ttpq ) ; } + /* + -------------------------------------------------------- + * LOCK-MESH: add faces to protected sets. + -------------------------------------------------------- + */ + + __static_call + __normal_call void_type lock_edge ( + mesh_type &_mesh, + typename + mesh_type:: edge_list & _epro , + rdel_opts &_opts + ) + { + if (!_opts.lock()) return ; + + __unreferenced( _opts ) ; + for (auto _iter = + _mesh._eset._lptr.head () ; + _iter != + _mesh._eset._lptr.tend () ; + ++_iter ) + { + // protect all restricted edges from refinement + for (auto _item = *_iter ; + _item != nullptr; + _item = _item->_next ) + { + edge_data _edat(_item->_data) ; + algorithms::isort ( + _edat._node.head(), + _edat._node.tend(), + std::less()) ; + + _epro.push( _edat ) ; + } + } + } + /* -------------------------------------------------------- * INIT-RDEL: init. face-set in rDT. @@ -490,7 +515,7 @@ ball_list &_bscr , iptr_type _pass , mode_type _fdim , - rdel_opts &_args + rdel_opts &_opts ) { /*-------------------- mark all existing elem. as new */ @@ -525,7 +550,7 @@ _tscr, _tcav, _bscr, _bcav, -1, _pass, - _fdim, _fdim, _args) ; + _fdim, _fdim, _opts) ; } /* @@ -541,9 +566,9 @@ hfun_type &_hfun, mesh_type &_mesh, typename - mesh_type::edge_list & _epro, + mesh_type:: edge_list & _epro , typename - mesh_type::edge_list & _ebad, + mesh_type:: edge_list & _ebad , rdel_opts &_opts ) { @@ -581,12 +606,9 @@ _pmax[ 0] - _pmin[ 0] , _pmax[ 1] - _pmin[ 1] } ; - real_type _scal = - (real_type)+0.0 ; - _scal = std::max( - _scal , _plen[ 0]); - _scal = std::max( - _scal , _plen[ 1]); + real_type _scal = (real_type) +0.0 ; + _scal = std::max(_scal, _plen[ 0]) ; + _scal = std::max(_scal, _plen[ 1]) ; _plen[ 0]*= (real_type)+8.0 ; _plen[ 1]*= (real_type)+8.0 ; @@ -623,7 +645,7 @@ /*------------------------------ seed feat from geom. */ _geom.seed_root(_mesh, _opts) ; - _geom.seed_feat(_mesh, _opts) ; + _geom.seed_feat(_mesh, _hfun, _opts) ; /*------------------------------ seed mesh from init. */ real_type _NEAR = @@ -636,7 +658,7 @@ _NEAR) ; /*------------------------------ seed mesh from geom. */ - _geom.seed_mesh(_mesh, _opts) ; + _geom.seed_mesh(_mesh, _hfun, _opts) ; } /* @@ -654,19 +676,19 @@ init_type &_init , hfun_type &_hfun , mesh_type &_mesh , - rdel_opts &_args , + rdel_opts &_opts , jlog_file &_dump ) { mode_type _mode = null_mode ; /*------------------------------ push log-file header */ - if (_args.verb() >= 0 ) + if (_opts.verb() >= 0 ) { _dump.push( - "#------------------------------------------------------------\n" - "# |ITER.| |DEL-1| |DEL-2| \n" - "#------------------------------------------------------------\n" +"#-----------------------------------------------------------------------\n" +"# |ITER.| |DEL-1| |DEL-2| \n" +"#-----------------------------------------------------------------------\n" ) ; } @@ -684,8 +706,6 @@ /*------------------------------ ensure deterministic */ std::srand( +1 ) ; - rdel_stat _tcpu ; - /*------------------------------ init. list workspace */ iptr_list _nnew, _nold ; iptr_list _tnew, _told ; @@ -746,7 +766,7 @@ init_mesh( _geom , _init, _hfun, _mesh, _epro , - _ebad, _args ) ; + _ebad, _opts ) ; if (_ebad.count() > +0) { @@ -784,9 +804,9 @@ for(bool_type _done=false; !_done ; ) { - iptr_type _trim_freq = +10000 ; + iptr_type constexpr _trim_freq = +10000 ; # ifdef _DEBUG - iptr_type _jlog_freq = +250 ; + iptr_type constexpr _jlog_freq = +250 ; # else iptr_type _jlog_tens = (iptr_type) std::log10(_pass) ; @@ -797,7 +817,7 @@ (iptr_type)std::pow(10, _jlog_tens))) / 2)) ; # endif - if(++_pass>_args.iter()) break; + if(++_pass>_opts.iter()) break; /*------------------------- init. array workspace */ @@ -843,7 +863,7 @@ _edat, _escr, _tdat, _tscr, _bdat, _bscr, _pass, - _mode, _args) ; + _mode, _opts) ; # ifdef __use_timers _ttoc = _time.now() ; @@ -870,7 +890,7 @@ { init_ball( _geom, _hfun, _mesh, _epro, _pass, - _mode, _args) ; + _mode, _opts) ; init_rdel( _geom, _hfun, _mesh, true,// init. circum. for rDT @@ -878,7 +898,7 @@ _edat, _escr, _tdat, _tscr, _bdat, _bscr, _pass, - _mode, _args) ; + _mode, _opts) ; } # ifdef __use_timers @@ -919,9 +939,11 @@ _edat, _escr, _tdat, _tscr, _bdat, _bscr, _pass, - _mode, _args) ; + _mode, _opts) ; } + lock_edge( _mesh, _epro, _opts) ; + # ifdef __use_timers _ttoc = _time.now() ; _tcpu._tria_init += @@ -952,7 +974,7 @@ _eprv, _edat, _escr, _tdat, _tscr, _bdat, _bscr, _tdim, - _pass, _args) ; + _pass, _opts) ; # ifdef __use_timers _ttoc = _time.now() ; @@ -975,7 +997,7 @@ _eprv, _edat, _escr, _tdat, _tscr, _bdat, _bscr, _tdim, - _pass, _args) ; + _pass, _opts) ; # ifdef __use_timers _ttoc = _time.now() ; @@ -999,7 +1021,7 @@ _eprv, _edat, _escr, _tdat, _tscr, _bdat, _bscr, _tdim, - _pass, _args) ; + _pass, _opts) ; # ifdef __use_timers _ttoc = _time.now() ; @@ -1022,7 +1044,7 @@ _eprv, _edat, _escr, _tdat, _tscr, _bdat, _bscr, _tdim, - _pass, _args) ; + _pass, _opts) ; # ifdef __use_timers _ttoc = _time.now() ; @@ -1036,15 +1058,14 @@ if (_pass%_jlog_freq==+0 || _done) { /*----------------------------- output to logfile */ - if (_args.verb() >= +0) + if (_opts.verb() >= +0) { std::stringstream _sstr; - _sstr << std::setw(+11) << - _pass << std::setw(+13) << + _sstr << std::setw(+12) << + _pass << std::setw(+14) << _mesh._eset.count () - << std::setw(+13) << - _mesh._tset.count () - << "\n" ; + << std::setw(+14) << + _mesh._tset.count () << "\n" ; _dump.push(_sstr.str()); } } @@ -1073,10 +1094,8 @@ # endif//__use_timers trim_list( _nbpq ) ; - trim_eepq( _mesh , - _eepq ) ; - trim_ttpq( _mesh , - _ttpq ) ; + trim_eepq( _mesh , _eepq ) ; + trim_ttpq( _mesh , _ttpq ) ; trim_list( _etpq ) ; trim_list( _nnew ) ; @@ -1107,262 +1126,266 @@ fill_topo( _mesh, _pass, _etpq, _emrk, - _edat, _eprv, _args) ; + _edat, _eprv, _opts) ; # ifdef __use_timers _ttoc = _time.now() ; - _tcpu._topo_init += + _tcpu._topo_init += _tcpu.time_span(_ttic,_ttoc) ; # endif//__use_timers } /*--------------- update restricted triangulation */ - - for (auto _npos = _nold.head() ; - _npos != _nold.tend() ; - ++_npos ) { - ball_data _ball, _same; - _ball._node[0] = *_npos; - _ball._kind = feat_ball; - _mesh. - _pop_ball( _ball, _same) ; - } + # ifdef __use_timers + _ttic = _time.now() ; + # endif//__use_timers - for (auto _tpos = _told.head() ; - _tpos != _told.tend() ; - ++_tpos ) - { - _pop_edge(_mesh, *_tpos) ; - _pop_tria(_mesh, *_tpos) ; - } - for (auto _tpos = _told.head() ; - _tpos != _told.tend() ; - ++_tpos ) - { - _mesh. - _tria._put_tria( *_tpos) ; - } + for (auto _npos = _nold.head() ; + _npos != _nold.tend() ; + ++_npos ) + { + ball_data _ball, _same; + _ball._node[0] = *_npos; + _ball._kind = feat_ball; + _mesh. + _pop_ball( _ball, _same) ; + } - for (auto _iter = _bscr.head() ; - _iter != _bscr.tend() ; - ++_iter ) - { - _nbpq .push( *_iter ) ; - } - for (auto _iter = _escr.head() ; - _iter != _escr.tend() ; - ++_iter ) - { - _eepq .push( *_iter ) ; - } - for (auto _iter = _tscr.head() ; - _iter != _tscr.tend() ; - ++_iter ) - { - _ttpq .push( *_iter ) ; - } + for (auto _tpos = _told.head() ; + _tpos != _told.tend() ; + ++_tpos ) + { + _pop_edge(_mesh, *_tpos) ; + _pop_tria(_mesh, *_tpos) ; + } + for (auto _tpos = _told.head() ; + _tpos != _told.tend() ; + ++_tpos ) + { + _mesh. + _tria._put_tria( *_tpos) ; + } - for (auto _iter = _bdat.head() ; - _iter != _bdat.tend() ; - ++_iter ) - { - _mesh.push_ball( *_iter) ; - } - for (auto _iter = _edat.head() ; - _iter != _edat.tend() ; - ++_iter ) - { - _mesh.push_edge( *_iter) ; - } - for (auto _iter = _tdat.head() ; - _iter != _tdat.tend() ; - ++_iter ) - { - _mesh.push_tria( *_iter) ; - } + for (auto _iter = _bscr.head() ; + _iter != _bscr.tend() ; + ++_iter ) + { + _nbpq .push( *_iter ) ; + } + for (auto _iter = _escr.head() ; + _iter != _escr.tend() ; + ++_iter ) + { + _eepq .push( *_iter ) ; + } + for (auto _iter = _tscr.head() ; + _iter != _tscr.tend() ; + ++_iter ) + { + _ttpq .push( *_iter ) ; + } + for (auto _iter = _bdat.head() ; + _iter != _bdat.tend() ; + ++_iter ) + { + _mesh.push_ball( *_iter) ; + } + for (auto _iter = _edat.head() ; + _iter != _edat.tend() ; + ++_iter ) + { + _mesh.push_edge( *_iter) ; + } + for (auto _iter = _tdat.head() ; + _iter != _tdat.tend() ; + ++_iter ) + { + _mesh.push_tria( *_iter) ; + } + + # ifdef __use_timers + _tcpu._list_push += + _tcpu.nano_span(_ttic,_ttoc) ; + # endif//__use_timers + } } - if (_args.verb() >= +2 ) + if (_opts.verb() >= +2 ) { /*-------------------- push refinement scheme metrics */ - _dump.push("\n") ; _dump.push("**TIMING statistics...\n") ; _dump.push(" *mesh-seed = ") ; - _dump.push( - std::to_string (_tcpu._mesh_seed)); + _dump.push(std::to_string(_tcpu._mesh_seed)); _dump.push("\n") ; _dump.push(" *node-init = ") ; - _dump.push( - std::to_string (_tcpu._node_init)); + _dump.push(std::to_string(_tcpu._node_init)); _dump.push("\n") ; _dump.push(" *node-rule = ") ; - _dump.push( - std::to_string (_tcpu._node_rule)); + _dump.push(std::to_string(_tcpu._node_rule)); + _dump.push("\n") ; _dump.push(" *edge-init = ") ; - _dump.push( - std::to_string (_tcpu._edge_init)); + _dump.push(std::to_string(_tcpu._edge_init)); _dump.push("\n") ; _dump.push(" *edge-rule = ") ; - _dump.push( - std::to_string (_tcpu._edge_rule)); + _dump.push(std::to_string(_tcpu._edge_rule)); + _dump.push("\n") ; _dump.push(" *tria-init = ") ; - _dump.push( - std::to_string (_tcpu._tria_init)); + _dump.push(std::to_string(_tcpu._tria_init)); _dump.push("\n") ; _dump.push(" *tria-rule = ") ; - _dump.push( - std::to_string (_tcpu._tria_rule)); + _dump.push(std::to_string(_tcpu._tria_rule)); + + _dump.push("\n") ; + _dump.push(" *dt-update = ") ; + _dump.push(std::to_string(_tcpu._dt_update)); + _dump.push("\n") ; + _dump.push(" *rdel-find = ") ; + _dump.push(std::to_string(_tcpu._rdel_find)); + _dump.push("\n") ; + _dump.push(" *rdel-push = ") ; + _dump.push(std::to_string(_tcpu._rdel_push)); + _dump.push("\n") ; + _dump.push(" *rdel-bnds = ") ; + _dump.push(std::to_string(_tcpu._rdel_bnds)); + _dump.push("\n") ; _dump.push(" *list-init = ") ; - _dump.push( - std::to_string (_tcpu._list_trim)); + _dump.push(std::to_string(_tcpu._list_trim)); + _dump.push("\n") ; + _dump.push(" *list-push = ") ; + _dump.push(std::to_string(_tcpu._list_push)); _dump.push("\n") ; _dump.push(" *topo-init = ") ; - _dump.push( - std::to_string (_tcpu._topo_init)); + _dump.push(std::to_string(_tcpu._topo_init)); _dump.push("\n\n"); _dump.push("**REFINE statistics...\n") ; _dump.push(" *edge-circ = ") ; - _dump.push(std::to_string( - _enod[rdel_opts::circ_kind])); + _dump.push( + std::to_string(_enod[rdel_opts::circ_kind])); _dump.push("\n") ; _dump.push(" *edge-offH = ") ; - _dump.push(std::to_string( - _enod[rdel_opts::offH_kind])); + _dump.push( + std::to_string(_enod[rdel_opts::offH_kind])); _dump.push("\n") ; _dump.push(" *edge-offT = ") ; - _dump.push(std::to_string( - _enod[rdel_opts::offT_kind])); + _dump.push( + std::to_string(_enod[rdel_opts::offT_kind])); _dump.push("\n") ; _dump.push(" *tria-circ = ") ; - _dump.push(std::to_string( - _tnod[rdel_opts::circ_kind])); + _dump.push( + std::to_string(_tnod[rdel_opts::circ_kind])); _dump.push("\n") ; _dump.push(" *tria-sink = ") ; - _dump.push(std::to_string( - _tnod[rdel_opts::sink_kind])); + _dump.push( + std::to_string(_tnod[rdel_opts::sink_kind])); _dump.push("\n") ; _dump.push(" *tria-offH = ") ; - _dump.push(std::to_string( - _tnod[rdel_opts::offH_kind])); + _dump.push( + std::to_string(_tnod[rdel_opts::offH_kind])); _dump.push("\n") ; _dump.push(" *tria-offC = ") ; - _dump.push(std::to_string( - _tnod[rdel_opts::offC_kind])); + _dump.push( + std::to_string(_tnod[rdel_opts::offC_kind])); _dump.push("\n") ; } - if (_args.verb() >= +2 ) + if (_opts.verb() >= +2 ) { /*-------------------- more refinement scheme metrics */ - _dump.push("\n") ; _dump.push("**MEMORY statistics...\n") ; _dump.push(" xDEL-type:\n") ; _dump.push(" *node-byte = ") ; - _dump.push(std::to_string( - sizeof(typename mesh_type:: - tria_type:: node_type)) ) ; + _dump.push(std::to_string(sizeof( + typename mesh_type::tria_type::node_type))); _dump.push("\n") ; _dump.push(" *nset-size = ") ; - _dump.push(std::to_string( - _mesh._tria._nset.alloc())) ; + _dump.push( + std::to_string(_mesh._tria._nset.alloc())) ; _dump.push("\n") ; _dump.push(" *tria-byte = ") ; - _dump.push(std::to_string( - sizeof(typename mesh_type:: - tria_type:: tria_type)) ) ; + _dump.push(std::to_string(sizeof( + typename mesh_type::tria_type::tria_type))); _dump.push("\n") ; _dump.push(" *tset-size = ") ; - _dump.push(std::to_string( - _mesh._tria._tset.alloc())) ; + _dump.push( + std::to_string(_mesh._tria._tset.alloc())) ; _dump.push("\n") ; _dump.push(" *pool-byte = ") ; - _dump.push(std::to_string( - _mesh._tria._fpol.bytes())) ; + _dump.push( + std::to_string(_mesh._tria._fpol.bytes())) ; _dump.push("\n") ; _dump.push(" rDEL-type:\n") ; _dump.push(" *ball-byte = ") ; _dump.push(std::to_string( - sizeof( - typename mesh_type::ball_item)) ) ; + sizeof(typename mesh_type::ball_item))); _dump.push("\n") ; _dump.push(" *bset-size = ") ; - _dump.push(std::to_string( - _mesh._bset._lptr.alloc())) ; + _dump.push( + std::to_string(_mesh._bset._lptr.alloc())) ; _dump.push("\n") ; _dump.push(" *pool-byte = ") ; - _dump.push( - std::to_string(_mesh._bpol.bytes())) ; + _dump.push(std::to_string(_mesh._bpol.bytes())); _dump.push("\n") ; _dump.push(" *node-byte = ") ; _dump.push(std::to_string( - sizeof( - typename mesh_type::node_item)) ) ; + sizeof(typename mesh_type::node_item))); _dump.push("\n") ; _dump.push(" *nset-size = ") ; - _dump.push(std::to_string( - _mesh._nset._lptr.alloc())) ; + _dump.push( + std::to_string(_mesh._nset._lptr.alloc())) ; _dump.push("\n") ; _dump.push(" *pool-byte = ") ; - _dump.push( - std::to_string(_mesh._npol.bytes())) ; + _dump.push(std::to_string(_mesh._npol.bytes())); _dump.push("\n") ; _dump.push(" *edge-byte = ") ; _dump.push(std::to_string( - sizeof( - typename mesh_type::edge_item)) ) ; + sizeof(typename mesh_type::edge_item))); _dump.push("\n") ; _dump.push(" *eset-size = ") ; - _dump.push(std::to_string( - _mesh._eset._lptr.alloc())) ; + _dump.push( + std::to_string(_mesh._eset._lptr.alloc())) ; _dump.push("\n") ; _dump.push(" *pool-byte = ") ; - _dump.push( - std::to_string(_mesh._epol.bytes())) ; + _dump.push(std::to_string(_mesh._epol.bytes())); _dump.push("\n") ; _dump.push(" *tria-byte = ") ; _dump.push(std::to_string( - sizeof( - typename mesh_type::tria_item)) ) ; + sizeof(typename mesh_type::tria_item))); _dump.push("\n") ; _dump.push(" *tset-size = ") ; - _dump.push(std::to_string( - _mesh._tset._lptr.alloc())) ; + _dump.push( + std::to_string(_mesh._tset._lptr.alloc())) ; _dump.push("\n") ; _dump.push(" *pool-byte = ") ; - _dump.push( - std::to_string(_mesh._tpol.bytes())) ; + _dump.push(std::to_string(_mesh._tpol.bytes())); _dump.push("\n") ; _dump.push(" xxPQ-type:\n") ; _dump.push(" *bscr-byte = ") ; - _dump.push( - std::to_string(sizeof(ball_data))); + _dump.push(std::to_string(sizeof(ball_data))); _dump.push("\n") ; _dump.push(" *bset-peak = ") ; _dump.push(std::to_string(_Nbpq)) ; _dump.push("\n") ; _dump.push(" *escr-byte = ") ; - _dump.push( - std::to_string(sizeof(edge_cost))); + _dump.push(std::to_string(sizeof(edge_cost))); _dump.push("\n") ; _dump.push(" *eset-peak = ") ; _dump.push(std::to_string(_Nepq)) ; _dump.push("\n") ; _dump.push(" *tscr-byte = ") ; - _dump.push( - std::to_string(sizeof(tria_cost))); + _dump.push(std::to_string(sizeof(tria_cost))); _dump.push("\n") ; _dump.push(" *tset-peak = ") ; _dump.push(std::to_string(_Ntpq)) ; @@ -1373,80 +1396,65 @@ _dump.push(" *orient2Df = ") ; _dump.push(std::to_string( - geompred::_nn_calls [ - geompred::ORIENT2D_f])) ; + geompred::_nn_calls[geompred::ORIENT2D_f])) ; _dump.push("\n") ; _dump.push(" *orient2Di = ") ; _dump.push(std::to_string( - geompred::_nn_calls [ - geompred::ORIENT2D_i])) ; + geompred::_nn_calls[geompred::ORIENT2D_i])) ; _dump.push("\n") ; _dump.push(" *orient2De = ") ; _dump.push(std::to_string( - geompred::_nn_calls [ - geompred::ORIENT2D_e])) ; + geompred::_nn_calls[geompred::ORIENT2D_e])) ; _dump.push("\n") ; _dump.push(" *bisect2Df = ") ; _dump.push(std::to_string( - geompred::_nn_calls [ - geompred::BISECT2D_f])) ; + geompred::_nn_calls[geompred::BISECT2D_f])) ; _dump.push("\n") ; _dump.push(" *bisect2Di = ") ; _dump.push(std::to_string( - geompred::_nn_calls [ - geompred::BISECT2D_i])) ; + geompred::_nn_calls[geompred::BISECT2D_i])) ; _dump.push("\n") ; _dump.push(" *bisect2De = ") ; _dump.push(std::to_string( - geompred::_nn_calls [ - geompred::BISECT2D_e])) ; + geompred::_nn_calls[geompred::BISECT2D_e])) ; _dump.push("\n") ; _dump.push(" *bisect2Wf = ") ; _dump.push(std::to_string( - geompred::_nn_calls [ - geompred::BISECT2W_f])) ; + geompred::_nn_calls[geompred::BISECT2W_f])) ; _dump.push("\n") ; _dump.push(" *bisect2Wi = ") ; _dump.push(std::to_string( - geompred::_nn_calls [ - geompred::BISECT2W_i])) ; + geompred::_nn_calls[geompred::BISECT2W_i])) ; _dump.push("\n") ; _dump.push(" *bisect2We = ") ; _dump.push(std::to_string( - geompred::_nn_calls [ - geompred::BISECT2W_e])) ; + geompred::_nn_calls[geompred::BISECT2W_e])) ; _dump.push("\n") ; _dump.push(" *inball2Df = ") ; _dump.push(std::to_string( - geompred::_nn_calls [ - geompred::INBALL2D_f])) ; + geompred::_nn_calls[geompred::INBALL2D_f])) ; _dump.push("\n") ; _dump.push(" *inball2Di = ") ; _dump.push(std::to_string( - geompred::_nn_calls [ - geompred::INBALL2D_i])) ; + geompred::_nn_calls[geompred::INBALL2D_i])) ; _dump.push("\n") ; _dump.push(" *inball2De = ") ; _dump.push(std::to_string( - geompred::_nn_calls [ - geompred::INBALL2D_e])) ; + geompred::_nn_calls[geompred::INBALL2D_e])) ; _dump.push("\n") ; _dump.push(" *inball2Wf = ") ; _dump.push(std::to_string( - geompred::_nn_calls [ - geompred::INBALL2W_f])) ; + geompred::_nn_calls[geompred::INBALL2W_f])) ; _dump.push("\n") ; _dump.push(" *inball2Wi = ") ; _dump.push(std::to_string( - geompred::_nn_calls [ - geompred::INBALL2W_i])) ; + geompred::_nn_calls[geompred::INBALL2W_i])) ; _dump.push("\n") ; _dump.push(" *inball2We = ") ; _dump.push(std::to_string( - geompred::_nn_calls [ - geompred::INBALL2W_e])) ; + geompred::_nn_calls[geompred::INBALL2W_e])) ; _dump.push("\n") ; } diff --git a/src/libcpp/rdel_mesh/rdel_mesh_3.hpp b/src/libcpp/rdel_mesh/rdel_mesh_3.hpp index bfb2bd2..c6a9032 100644 --- a/src/libcpp/rdel_mesh/rdel_mesh_3.hpp +++ b/src/libcpp/rdel_mesh/rdel_mesh_3.hpp @@ -35,9 +35,9 @@ * -------------------------------------------------------- * - * Last updated: 12 Jul., 2021 + * Last updated: 21 Apr., 2024 * - * Copyright 2013-2021 + * Copyright 2013-2024 * Darren Engwirda * d.engwirda@gmail.com * https://github.com/dengwirda/ @@ -151,6 +151,8 @@ char_type static constexpr face_mode = +4 ; char_type static constexpr ftop_mode = +5 ; char_type static constexpr tria_mode = +6 ; + + mesh::rdel_timers static inline _tcpu ; class node_pred ; class ball_pred ; class edge_pred ; class face_pred ; @@ -186,12 +188,12 @@ typedef typename mesh_type::tria_data tria_data ; - typedef mesh::rdel_timers rdel_stat ; - typedef mesh::mesh_params < real_type, iptr_type > rdel_opts ; + typedef containers::array < + real_type > real_list ; typedef containers::array < iptr_type > iptr_list ; @@ -356,18 +358,16 @@ ) { typedef typename - list_type:: - size_type size_type; + list_type::size_type size_type; - size_type _amin = +512; - size_type _alim = +256; + size_type constexpr _amin = 512 ; + size_type constexpr _alim = 256 ; size_type _amax = - (size_type)+3 * _list.count() ; + (size_type)+3 * _list.count() ; size_type _anew = - (size_type)+2 * _list.count() ; + (size_type)+2 * _list.count() ; - _anew = - std::max(_alim, _anew) ; + _anew = std::max (_alim, _anew) ; if (_list.alloc() > _amin) if (_list.alloc() > _amax) @@ -388,9 +388,7 @@ { if(!_eepq.empty()) { - - iptr_type _dead = +0, _okay = +0 ; - + iptr_type _dead = +0, _okay = +0; for (auto _hpos = _eepq.count() - 1 ; _hpos > +0 ; --_hpos ) @@ -400,6 +398,7 @@ iptr_type _pass; edge_data _edat; + // from PQ so already sorted for hash _edat._node[0] = _eepq. peek(_hpos)._node[0]; _edat._node[1] = @@ -414,14 +413,12 @@ if(!_mesh.find_edge(_edat,_eptr)) { _eepq._pop(_hpos); - _dead += +1 ; } else if (_eptr->_data._pass != _pass ) { _eepq._pop(_hpos); - _dead += +1 ; } else @@ -448,9 +445,7 @@ { if(!_ffpq.empty()) { - - iptr_type _dead = +0, _okay = +0 ; - + iptr_type _dead = +0, _okay = +0; for (auto _hpos = _ffpq.count() - 1 ; _hpos > +0 ; --_hpos ) @@ -460,6 +455,7 @@ iptr_type _pass ; face_data _fdat; + // from PQ so already sorted for hash _fdat._node[0] = _ffpq. peek(_hpos)._node[0]; _fdat._node[1] = @@ -476,14 +472,12 @@ if(!_mesh.find_face(_fdat,_fptr)) { _ffpq._pop(_hpos); - _dead += +1 ; } else if (_fptr->_data._pass != _pass ) { _ffpq._pop(_hpos); - _dead += +1 ; } else @@ -510,9 +504,7 @@ { if(!_ttpq.empty()) { - - iptr_type _dead = +0, _okay = +0 ; - + iptr_type _dead = +0, _okay = +0; for (auto _hpos = _ttpq.count() - 1 ; _hpos > +0 ; --_hpos ) @@ -522,6 +514,7 @@ iptr_type _pass; tria_data _tdat; + // from PQ so already sorted for hash _tdat._node[0] = _ttpq. peek(_hpos)._node[0]; _tdat._node[1] = @@ -540,14 +533,12 @@ if(!_mesh.find_tria(_tdat,_tptr)) { _ttpq._pop(_hpos); - _dead += +1 ; } else if (_tptr->_data._pass != _pass ) { _ttpq._pop(_hpos); - _dead += +1 ; } else @@ -560,6 +551,78 @@ trim_list ( _ttpq ) ; } + /* + -------------------------------------------------------- + * LOCK-MESH: add faces to protected sets. + -------------------------------------------------------- + */ + + __static_call + __normal_call void_type lock_edge ( + mesh_type &_mesh, + typename + mesh_type:: edge_list & _epro , + rdel_opts &_opts + ) + { + if (!_opts.lock()) return ; + + __unreferenced( _opts ) ; + for (auto _iter = + _mesh._eset._lptr.head () ; + _iter != + _mesh._eset._lptr.tend () ; + ++_iter ) + { + // protect all restricted edges from refinement + for (auto _item = *_iter ; + _item != nullptr; + _item = _item->_next ) + { + edge_data _edat(_item->_data) ; + algorithms::isort ( + _edat._node.head(), + _edat._node.tend(), + std::less()) ; + + _epro.push( _edat ) ; + } + } + } + + __static_call + __normal_call void_type lock_face ( + mesh_type &_mesh, + typename + mesh_type:: face_list & _fpro , + rdel_opts &_opts + ) + { + if (!_opts.lock()) return ; + + __unreferenced( _opts ) ; + for (auto _iter = + _mesh._fset._lptr.head () ; + _iter != + _mesh._fset._lptr.tend () ; + ++_iter ) + { + // protect all restricted faces from refinement + for (auto _item = *_iter ; + _item != nullptr; + _item = _item->_next ) + { + face_data _fdat(_item->_data) ; + algorithms::isort ( + _fdat._node.head(), + _fdat._node.tend(), + std::less()) ; + + _fpro.push( _fdat ) ; + } + } + } + /* -------------------------------------------------------- * INIT-RDEL: init. face-set in rDT. @@ -584,7 +647,7 @@ ball_list &_bscr , iptr_type _pass , mode_type _fdim , - rdel_opts &_args + rdel_opts &_opts ) { /*-------------------- mark all existing elem. as new */ @@ -620,7 +683,7 @@ _tscr, _tcav, _bscr, _bcav, -1, _pass, - _fdim, _fdim, _args) ; + _fdim, _fdim, _opts) ; } /* @@ -636,13 +699,13 @@ hfun_type &_hfun, mesh_type &_mesh, typename - mesh_type::edge_list & _epro, + mesh_type:: edge_list & _epro , typename - mesh_type::edge_list & _ebad, + mesh_type:: edge_list & _ebad , typename - mesh_type::face_list & _fpro, + mesh_type:: face_list & _fpro , typename - mesh_type::face_list & _fbad, + mesh_type:: face_list & _fbad , rdel_opts &_opts ) { @@ -688,14 +751,10 @@ _pmax[ 1] - _pmin[ 1] , _pmax[ 2] - _pmin[ 2] } ; - real_type _scal = - (real_type)+0.0 ; - _scal = std::max( - _scal , _plen[ 0]); - _scal = std::max( - _scal , _plen[ 1]); - _scal = std::max( - _scal , _plen[ 2]); + real_type _scal = (real_type) +0.0 ; + _scal = std::max(_scal, _plen[ 0]); + _scal = std::max(_scal, _plen[ 1]); + _scal = std::max(_scal, _plen[ 2]); _plen[ 0]*= (real_type)+8.0 ; _plen[ 1]*= (real_type)+8.0 ; @@ -741,7 +800,7 @@ /*------------------------------ seed feat from geom. */ _geom.seed_root(_mesh, _opts) ; - _geom.seed_feat(_mesh, _opts) ; + _geom.seed_feat(_mesh, _hfun, _opts) ; /*------------------------------ seed node from init. */ real_type _NEAR = @@ -755,7 +814,7 @@ _NEAR) ; /*------------------------------ seed mesh from geom. */ - _geom.seed_mesh(_mesh, _opts) ; + _geom.seed_mesh(_mesh, _hfun, _opts) ; } @@ -766,11 +825,13 @@ mesh_type &_mesh ) { - iptr_list _nsum; - _nsum.set_count( - _mesh._tria._nset.count(), - containers::tight_alloc, +0) ; + return; + real_list _npwr(_mesh._tria._nset.count(), + std::numeric_limits::infinity()); + + iptr_list _topo(_mesh._tria._nset.count(), +0) ; + for (auto _iter = _mesh._eset._lptr.head() ; _iter != @@ -783,7 +844,10 @@ _item != nullptr; _item = _item->_next ) { - if (_item->_data._feat == mesh::hard_feat) + auto _feat = _item->_data._feat ; + if (_feat == mesh::hard_feat || + _feat == mesh::soft_feat || + _feat == mesh::user_feat) { auto _inod = _item->_data._node[0] ; auto _jnod = _item->_data._node[1] ; @@ -797,31 +861,39 @@ & _iptr->pval( 0), & _jptr->pval( 0)) ; - _lsqr *= (real_type) std::pow(2./3., +2) ; + _lsqr*= std::pow(2./3., 2) ; - _iptr->pval(3) += _lsqr ; - _nsum[_inod] += +1 ; + _npwr[_inod] = + std::min(_lsqr, _npwr[_inod]) ; + _topo[_inod] += 1 ; - _jptr->pval(3) += _lsqr ; - _nsum[_jnod] += +1 ; + _npwr[_jnod] = + std::min(_lsqr, _npwr[_jnod]) ; + _topo[_jnod] += 1 ; } } } - for (auto _iter = _nsum.head() , - _npos = +0 ; - _iter != _nsum.tend() ; + iptr_type _npos = +0 ; + for (auto _iter = _topo.head() ; + _iter != _topo.tend() ; ++_iter, ++_npos) { if ( *_iter != +0 ) - _mesh._tria._nset[_npos].pval(3) /= *_iter ; + { + real_type _ppos[4] = { + _mesh._tria.node(_npos)->pval(0), + _mesh._tria.node(_npos)->pval(1), + _mesh._tria.node(_npos)->pval(2), + _npwr[_npos] } ; + + _mesh._tria.update(_ppos, _npos); + } } } - - /* -------------------------------------------------------- * RDEL-MESH: build an rDT mesh in R^3. @@ -837,19 +909,19 @@ init_type &_init , hfun_type &_hfun , mesh_type &_mesh , - rdel_opts &_args , + rdel_opts &_opts , jlog_file &_dump ) { mode_type _mode = null_mode ; /*------------------------------ push log-file header */ - if (_args.verb() >= 0 ) + if (_opts.verb() >= 0 ) { _dump.push( - "#------------------------------------------------------------\n" - "# |ITER.| |DEL-1| |DEL-2| |DEL-3| \n" - "#------------------------------------------------------------\n" +"#-----------------------------------------------------------------------\n" +"# |ITER.| |DEL-1| |DEL-2| |DEL-3| \n" +"#-----------------------------------------------------------------------\n" ) ; } @@ -867,8 +939,6 @@ /*------------------------------ ensure deterministic */ std::srand( +1 ) ; - rdel_stat _tcpu ; - /*------------------------------ init. list workspace */ iptr_list _nnew, _nold ; iptr_list _tnew, _told ; @@ -955,7 +1025,7 @@ init_mesh( _geom , _init, _hfun, _mesh, _epro , _ebad, _fpro , - _fbad, _args ) ; + _fbad, _opts ) ; if (_ebad.count() > +0) { @@ -1001,9 +1071,9 @@ for(bool_type _done=false; !_done ; ) { - iptr_type _trim_freq = +10000 ; + iptr_type constexpr _trim_freq = +10000 ; # ifdef _DEBUG - iptr_type _jlog_freq = +250 ; + iptr_type constexpr _jlog_freq = +250 ; # else iptr_type _jlog_tens = (iptr_type) std::log10(_pass) ; @@ -1014,7 +1084,7 @@ (iptr_type)std::pow(10, _jlog_tens))) / 2)) ; # endif - if(++_pass>_args.iter()) break; + if(++_pass>_opts.iter()) break; /*------------------------- init. array workspace */ @@ -1066,7 +1136,7 @@ _fdat, _fscr, _tdat, _tscr, _bdat, _bscr, _pass, - _mode, _args) ; + _mode, _opts) ; # ifdef __use_timers _ttoc = _time.now() ; @@ -1094,7 +1164,7 @@ init_ball( _geom, _hfun, _mesh, _epro, _fpro, _pass, - _mode, _args) ; + _mode, _opts) ; init_rdel( _geom, _hfun, _mesh, true,// init. circum. for rDT @@ -1103,7 +1173,7 @@ _fdat, _fscr, _tdat, _tscr, _bdat, _bscr, _pass, - _mode, _args) ; + _mode, _opts) ; } # ifdef __use_timers @@ -1137,14 +1207,7 @@ { _irDT = true; // init. new face in rDT - /* - init_disc( _geom, _hfun, - _mesh, - _epro, _fpro, _pass, - _mode, _args) ; - init_dual( _mesh) ; - */ init_rdel( _geom, _hfun, _mesh, true, @@ -1153,9 +1216,11 @@ _fdat, _fscr, _tdat, _tscr, _bdat, _bscr, _pass, - _mode, _args) ; + _mode, _opts) ; } + lock_edge( _mesh, _epro, _opts) ; + # ifdef __use_timers _ttoc = _time.now() ; _tcpu._face_init += @@ -1195,9 +1260,11 @@ _fdat, _fscr, _tdat, _tscr, _bdat, _bscr, _pass, - _mode, _args) ; + _mode, _opts) ; } + lock_face( _mesh, _fpro, _opts) ; + # ifdef __use_timers _ttoc = _time.now() ; _tcpu._tria_init += @@ -1229,7 +1296,7 @@ _fprv, _fdat, _fscr, _tdat, _tscr, _bdat, _bscr, - _tdim, _pass, _args) ; + _tdim, _pass, _opts) ; # ifdef __use_timers _ttoc = _time.now() ; @@ -1254,7 +1321,7 @@ _fprv, _fdat, _fscr, _tdat, _tscr, _bdat, _bscr, - _tdim, _pass, _args) ; + _tdim, _pass, _opts) ; # ifdef __use_timers _ttoc = _time.now() ; @@ -1280,7 +1347,7 @@ _fprv, _fdat, _fscr, _tdat, _tscr, _bdat, _bscr, - _tdim, _pass, _args) ; + _tdim, _pass, _opts) ; # ifdef __use_timers _ttoc = _time.now() ; @@ -1305,7 +1372,7 @@ _fprv, _fdat, _fscr, _tdat, _tscr, _bdat, _bscr, - _tdim, _pass, _args) ; + _tdim, _pass, _opts) ; # ifdef __use_timers _ttoc = _time.now() ; @@ -1331,7 +1398,7 @@ _fprv, _fdat, _fscr, _tdat, _tscr, _bdat, _bscr, - _tdim, _pass, _args) ; + _tdim, _pass, _opts) ; # ifdef __use_timers _ttoc = _time.now() ; @@ -1356,7 +1423,7 @@ _fprv, _fdat, _fscr, _tdat, _tscr, _bdat, _bscr, - _tdim, _pass, _args) ; + _tdim, _pass, _opts) ; # ifdef __use_timers _ttoc = _time.now() ; @@ -1370,17 +1437,16 @@ if (_pass%_jlog_freq==+0 || _done) { /*----------------------------- output to logfile */ - if (_args.verb() >= +0) + if (_opts.verb() >= +0) { std::stringstream _sstr; - _sstr << std::setw(+11) << - _pass << std::setw(+13) << + _sstr << std::setw(+12) << + _pass << std::setw(+14) << _mesh._eset.count () - << std::setw(+13) << + << std::setw(+14) << _mesh._fset.count () - << std::setw(+13) << - _mesh._tset.count () - << "\n" ; + << std::setw(+14) << + _mesh._tset.count () << "\n" ; _dump.push(_sstr.str()); } } @@ -1414,12 +1480,9 @@ # endif//__use_timers trim_list( _nbpq ) ; - trim_eepq( _mesh , - _eepq ) ; - trim_ffpq( _mesh , - _ffpq ) ; - trim_ttpq( _mesh , - _ttpq ) ; + trim_eepq( _mesh , _eepq ) ; + trim_ffpq( _mesh , _ffpq ) ; + trim_ttpq( _mesh , _ttpq ) ; trim_list( _etpq ) ; trim_list( _ftpq ) ; @@ -1442,7 +1505,7 @@ # ifdef __use_timers _ttoc = _time.now() ; _tcpu._list_trim += - _tcpu.time_span(_ttic,_ttoc) ; + _tcpu.nano_span(_ttic,_ttoc) ; # endif//__use_timers } @@ -1456,323 +1519,324 @@ _etpq, _emrk, _ftpq, _fmrk, _edat, _eprv, - _fdat, _fprv, _args) ; + _fdat, _fprv, _opts) ; # ifdef __use_timers _ttoc = _time.now() ; _tcpu._topo_init += - _tcpu.time_span(_ttic,_ttoc) ; + _tcpu.nano_span(_ttic,_ttoc) ; # endif//__use_timers } /*--------------- update restricted triangulation */ - - for (auto _npos = _nold.head() ; - _npos != _nold.tend() ; - ++_npos ) { - ball_data _ball, _same; - _ball._node[0] = *_npos; - _ball._kind = feat_ball; - _mesh. - _pop_ball( _ball, _same) ; - } + # ifdef __use_timers + _ttic = _time.now() ; + # endif//__use_timers - for (auto _tpos = _told.head() ; - _tpos != _told.tend() ; - ++_tpos ) - { - _pop_edge(_mesh, *_tpos) ; - _pop_face(_mesh, *_tpos) ; - _pop_tria(_mesh, *_tpos) ; - } - for (auto _tpos = _told.head() ; - _tpos != _told.tend() ; - ++_tpos ) - { - _mesh. - _tria._put_tria( *_tpos) ; - } + for (auto _npos = _nold.head() ; + _npos != _nold.tend() ; + ++_npos ) + { + ball_data _ball, _same; + _ball._node[0] = *_npos; + _ball._kind = feat_ball; + _mesh. + _pop_ball( _ball, _same) ; + } - for (auto _iter = _bscr.head() ; - _iter != _bscr.tend() ; - ++_iter ) - { - _nbpq .push( *_iter ) ; - } - for (auto _iter = _escr.head() ; - _iter != _escr.tend() ; - ++_iter ) - { - _eepq .push( *_iter ) ; - } - for (auto _iter = _fscr.head() ; - _iter != _fscr.tend() ; - ++_iter ) - { - _ffpq .push( *_iter ) ; - } - for (auto _iter = _tscr.head() ; - _iter != _tscr.tend() ; - ++_iter ) - { - _ttpq .push( *_iter ) ; - } + for (auto _tpos = _told.head() ; + _tpos != _told.tend() ; + ++_tpos ) + { + _pop_edge(_mesh, *_tpos) ; + _pop_face(_mesh, *_tpos) ; + _pop_tria(_mesh, *_tpos) ; + } + for (auto _tpos = _told.head() ; + _tpos != _told.tend() ; + ++_tpos ) + { + _mesh. + _tria._put_tria( *_tpos) ; + } - for (auto _iter = _bdat.head() ; - _iter != _bdat.tend() ; - ++_iter ) - { - _mesh.push_ball( *_iter) ; - } - for (auto _iter = _edat.head() ; - _iter != _edat.tend() ; - ++_iter ) - { - _mesh.push_edge( *_iter) ; - } - for (auto _iter = _fdat.head() ; - _iter != _fdat.tend() ; - ++_iter ) - { - _mesh.push_face( *_iter) ; - } - for (auto _iter = _tdat.head() ; - _iter != _tdat.tend() ; - ++_iter ) - { - _mesh.push_tria( *_iter) ; - } + for (auto _iter = _bscr.head() ; + _iter != _bscr.tend() ; + ++_iter ) + { + _nbpq .push( *_iter ) ; + } + for (auto _iter = _escr.head() ; + _iter != _escr.tend() ; + ++_iter ) + { + _eepq .push( *_iter ) ; + } + for (auto _iter = _fscr.head() ; + _iter != _fscr.tend() ; + ++_iter ) + { + _ffpq .push( *_iter ) ; + } + for (auto _iter = _tscr.head() ; + _iter != _tscr.tend() ; + ++_iter ) + { + _ttpq .push( *_iter ) ; + } + + for (auto _iter = _bdat.head() ; + _iter != _bdat.tend() ; + ++_iter ) + { + _mesh.push_ball( *_iter) ; + } + for (auto _iter = _edat.head() ; + _iter != _edat.tend() ; + ++_iter ) + { + _mesh.push_edge( *_iter) ; + } + for (auto _iter = _fdat.head() ; + _iter != _fdat.tend() ; + ++_iter ) + { + _mesh.push_face( *_iter) ; + } + for (auto _iter = _tdat.head() ; + _iter != _tdat.tend() ; + ++_iter ) + { + _mesh.push_tria( *_iter) ; + } + # ifdef __use_timers + _ttoc = _time.now() ; + _tcpu._list_push += + _tcpu.nano_span(_ttic,_ttoc) ; + # endif//__use_timers + } } - if (_args.verb() >= +2 ) + if (_opts.verb() >= +2 ) { /*-------------------- push refinement scheme metrics */ - _dump.push("\n") ; _dump.push("**TIMING statistics...\n") ; _dump.push(" *mesh-seed = ") ; - _dump.push( - std::to_string (_tcpu._mesh_seed)); + _dump.push(std::to_string(_tcpu._mesh_seed)); _dump.push("\n") ; _dump.push(" *node-init = ") ; - _dump.push( - std::to_string (_tcpu._node_init)); + _dump.push(std::to_string(_tcpu._node_init)); _dump.push("\n") ; _dump.push(" *node-rule = ") ; - _dump.push( - std::to_string (_tcpu._node_rule)); + _dump.push(std::to_string(_tcpu._node_rule)); + _dump.push("\n") ; _dump.push(" *edge-init = ") ; - _dump.push( - std::to_string (_tcpu._edge_init)); + _dump.push(std::to_string(_tcpu._edge_init)); _dump.push("\n") ; _dump.push(" *edge-rule = ") ; - _dump.push( - std::to_string (_tcpu._edge_rule)); + _dump.push(std::to_string(_tcpu._edge_rule)); + _dump.push("\n") ; _dump.push(" *face-init = ") ; - _dump.push( - std::to_string (_tcpu._face_init)); + _dump.push(std::to_string(_tcpu._face_init)); _dump.push("\n") ; _dump.push(" *face-rule = ") ; - _dump.push( - std::to_string (_tcpu._face_rule)); + _dump.push(std::to_string(_tcpu._face_rule)); + _dump.push("\n") ; _dump.push(" *tria-init = ") ; - _dump.push( - std::to_string (_tcpu._tria_init)); + _dump.push(std::to_string(_tcpu._tria_init)); _dump.push("\n") ; _dump.push(" *tria-rule = ") ; - _dump.push( - std::to_string (_tcpu._tria_rule)); + _dump.push(std::to_string(_tcpu._tria_rule)); + + _dump.push("\n") ; + _dump.push(" *dt-update = ") ; + _dump.push(std::to_string(_tcpu._dt_update)); + _dump.push("\n") ; + _dump.push(" *rdel-find = ") ; + _dump.push(std::to_string(_tcpu._rdel_find)); + _dump.push("\n") ; + _dump.push(" *rdel-push = ") ; + _dump.push(std::to_string(_tcpu._rdel_push)); + _dump.push("\n") ; + _dump.push(" *rdel-bnds = ") ; + _dump.push(std::to_string(_tcpu._rdel_bnds)); + _dump.push("\n") ; _dump.push(" *list-init = ") ; - _dump.push( - std::to_string (_tcpu._list_trim)); + _dump.push(std::to_string(_tcpu._list_trim)); + _dump.push("\n") ; + _dump.push(" *list-push = ") ; + _dump.push(std::to_string(_tcpu._list_push)); _dump.push("\n") ; _dump.push(" *topo-init = ") ; - _dump.push( - std::to_string (_tcpu._topo_init)); + _dump.push(std::to_string(_tcpu._topo_init)); _dump.push("\n\n"); _dump.push("**REFINE statistics...\n") ; _dump.push(" *edge-circ = ") ; - _dump.push(std::to_string( - _enod[rdel_opts::circ_kind])); + _dump.push( + std::to_string(_enod[rdel_opts::circ_kind])); _dump.push("\n") ; _dump.push(" *edge-offH = ") ; - _dump.push(std::to_string( - _enod[rdel_opts::offH_kind])); + _dump.push( + std::to_string(_enod[rdel_opts::offH_kind])); _dump.push("\n") ; _dump.push(" *edge-offT = ") ; - _dump.push(std::to_string( - _enod[rdel_opts::offT_kind])); + _dump.push( + std::to_string(_enod[rdel_opts::offT_kind])); _dump.push("\n") ; _dump.push(" *face-circ = ") ; - _dump.push(std::to_string( - _fnod[rdel_opts::circ_kind])); + _dump.push( + std::to_string(_fnod[rdel_opts::circ_kind])); _dump.push("\n") ; _dump.push(" *face-sink = ") ; - _dump.push(std::to_string( - _fnod[rdel_opts::sink_kind])); + _dump.push( + std::to_string(_fnod[rdel_opts::sink_kind])); _dump.push("\n") ; _dump.push(" *face-offH = ") ; - _dump.push(std::to_string( - _fnod[rdel_opts::offH_kind])); + _dump.push( + std::to_string(_fnod[rdel_opts::offH_kind])); _dump.push("\n") ; _dump.push(" *face-offC = ") ; - _dump.push(std::to_string( - _fnod[rdel_opts::offC_kind])); + _dump.push( + std::to_string(_fnod[rdel_opts::offC_kind])); _dump.push("\n") ; _dump.push(" *face-offT = ") ; - _dump.push(std::to_string( - _fnod[rdel_opts::offT_kind])); + _dump.push( + std::to_string(_fnod[rdel_opts::offT_kind])); _dump.push("\n") ; _dump.push(" *tria-circ = ") ; - _dump.push(std::to_string( - _tnod[rdel_opts::circ_kind])); + _dump.push( + std::to_string(_tnod[rdel_opts::circ_kind])); _dump.push("\n") ; _dump.push(" *tria-sink = ") ; - _dump.push(std::to_string( - _tnod[rdel_opts::sink_kind])); + _dump.push( + std::to_string(_tnod[rdel_opts::sink_kind])); _dump.push("\n") ; _dump.push(" *tria-offH = ") ; - _dump.push(std::to_string( - _tnod[rdel_opts::offH_kind])); + _dump.push( + std::to_string(_tnod[rdel_opts::offH_kind])); _dump.push("\n") ; _dump.push(" *tria-offC = ") ; - _dump.push(std::to_string( - _tnod[rdel_opts::offC_kind])); + _dump.push( + std::to_string(_tnod[rdel_opts::offC_kind])); _dump.push("\n") ; } - if (_args.verb() >= +2 ) + if (_opts.verb() >= +2 ) { /*-------------------- more refinement scheme metrics */ - _dump.push("\n") ; _dump.push("**MEMORY statistics...\n") ; _dump.push(" xDEL-type:\n") ; _dump.push(" *node-byte = ") ; - _dump.push(std::to_string( - sizeof(typename mesh_type:: - tria_type:: node_type)) ) ; + _dump.push(std::to_string(sizeof( + typename mesh_type::tria_type::node_type))); _dump.push("\n") ; _dump.push(" *nset-size = ") ; - _dump.push(std::to_string( - _mesh._tria._nset.alloc())) ; + _dump.push( + std::to_string(_mesh._tria._nset.alloc())) ; _dump.push("\n") ; _dump.push(" *tria-byte = ") ; - _dump.push(std::to_string( - sizeof(typename mesh_type:: - tria_type:: tria_type)) ) ; + _dump.push(std::to_string(sizeof( + typename mesh_type::tria_type::tria_type))); _dump.push("\n") ; _dump.push(" *tset-size = ") ; - _dump.push(std::to_string( - _mesh._tria._tset.alloc())) ; + _dump.push( + std::to_string(_mesh._tria._tset.alloc())) ; _dump.push("\n") ; _dump.push(" *pool-byte = ") ; - _dump.push(std::to_string( - _mesh._tria._fpol.bytes())) ; + _dump.push( + std::to_string(_mesh._tria._fpol.bytes())) ; _dump.push("\n") ; _dump.push(" rDEL-type:\n") ; _dump.push(" *ball-byte = ") ; _dump.push(std::to_string( - sizeof( - typename mesh_type::ball_item)) ) ; + sizeof(typename mesh_type::ball_item))); _dump.push("\n") ; _dump.push(" *bset-size = ") ; - _dump.push(std::to_string( - _mesh._bset._lptr.alloc())) ; + _dump.push( + std::to_string(_mesh._bset._lptr.alloc())) ; _dump.push("\n") ; _dump.push(" *pool-byte = ") ; - _dump.push( - std::to_string(_mesh._bpol.bytes())) ; + _dump.push(std::to_string(_mesh._bpol.bytes())); _dump.push("\n") ; _dump.push(" *node-byte = ") ; _dump.push(std::to_string( - sizeof( - typename mesh_type::node_item)) ) ; + sizeof(typename mesh_type::node_item))); _dump.push("\n") ; _dump.push(" *nset-size = ") ; - _dump.push(std::to_string( - _mesh._nset._lptr.alloc())) ; + _dump.push( + std::to_string(_mesh._nset._lptr.alloc())) ; _dump.push("\n") ; _dump.push(" *pool-byte = ") ; - _dump.push(std::to_string( - _mesh._npol.bytes () ) ) ; + _dump.push(std::to_string(_mesh._npol.bytes())); _dump.push("\n") ; _dump.push(" *edge-byte = ") ; _dump.push(std::to_string( - sizeof( - typename mesh_type::edge_item)) ) ; + sizeof(typename mesh_type::edge_item))); _dump.push("\n") ; _dump.push(" *eset-size = ") ; - _dump.push(std::to_string( - _mesh._eset._lptr.alloc())) ; + _dump.push( + std::to_string(_mesh._eset._lptr.alloc())) ; _dump.push("\n") ; _dump.push(" *pool-byte = ") ; - _dump.push( - std::to_string(_mesh._epol.bytes())) ; + _dump.push(std::to_string(_mesh._epol.bytes())); _dump.push("\n") ; _dump.push(" *face-byte = ") ; _dump.push(std::to_string( - sizeof( - typename mesh_type::face_item)) ) ; + sizeof(typename mesh_type::face_item))); _dump.push("\n") ; _dump.push(" *fset-size = ") ; - _dump.push(std::to_string( - _mesh._fset._lptr.alloc())) ; + _dump.push( + std::to_string(_mesh._fset._lptr.alloc())) ; _dump.push("\n") ; _dump.push(" *pool-byte = ") ; - _dump.push( - std::to_string(_mesh._fpol.bytes())) ; + _dump.push(std::to_string(_mesh._fpol.bytes())); _dump.push("\n") ; _dump.push(" *tria-byte = ") ; _dump.push(std::to_string( - sizeof( - typename mesh_type::tria_item)) ) ; + sizeof(typename mesh_type::tria_item))); _dump.push("\n") ; _dump.push(" *tset-size = ") ; - _dump.push(std::to_string( - _mesh._tset._lptr.alloc())) ; + _dump.push( + std::to_string(_mesh._tset._lptr.alloc())) ; _dump.push("\n") ; _dump.push(" *pool-byte = ") ; - _dump.push( - std::to_string(_mesh._tpol.bytes())) ; + _dump.push(std::to_string(_mesh._tpol.bytes())); _dump.push("\n") ; _dump.push(" xxPQ-type:\n") ; _dump.push(" *bscr-byte = ") ; - _dump.push( - std::to_string(sizeof(ball_data))); + _dump.push(std::to_string(sizeof(ball_data))); _dump.push("\n") ; _dump.push(" *bset-peak = ") ; _dump.push(std::to_string(_Nbpq)) ; _dump.push("\n") ; _dump.push(" *escr-byte = ") ; - _dump.push( - std::to_string(sizeof(edge_cost))); + _dump.push(std::to_string(sizeof(edge_cost))); _dump.push("\n") ; _dump.push(" *eset-peak = ") ; _dump.push(std::to_string(_Nepq)) ; _dump.push("\n") ; _dump.push(" *fscr-byte = ") ; - _dump.push( - std::to_string(sizeof(face_cost))); + _dump.push(std::to_string(sizeof(face_cost))); _dump.push("\n") ; _dump.push(" *fset-peak = ") ; _dump.push(std::to_string(_Nfpq)) ; _dump.push("\n") ; _dump.push(" *tscr-byte = ") ; - _dump.push( - std::to_string(sizeof(tria_cost))); + _dump.push(std::to_string(sizeof(tria_cost))); _dump.push("\n") ; _dump.push(" *tset-peak = ") ; _dump.push(std::to_string(_Ntpq)) ; @@ -1783,80 +1847,65 @@ _dump.push(" *orient3Df = ") ; _dump.push(std::to_string( - geompred::_nn_calls [ - geompred::ORIENT3D_f])) ; + geompred::_nn_calls[geompred::ORIENT3D_f])) ; _dump.push("\n") ; _dump.push(" *orient3Di = ") ; _dump.push(std::to_string( - geompred::_nn_calls [ - geompred::ORIENT3D_i])) ; + geompred::_nn_calls[geompred::ORIENT3D_i])) ; _dump.push("\n") ; _dump.push(" *orient3De = ") ; _dump.push(std::to_string( - geompred::_nn_calls [ - geompred::ORIENT3D_e])) ; + geompred::_nn_calls[geompred::ORIENT3D_e])) ; _dump.push("\n") ; _dump.push(" *bisect3Df = ") ; _dump.push(std::to_string( - geompred::_nn_calls [ - geompred::BISECT3D_f])) ; + geompred::_nn_calls[geompred::BISECT3D_f])) ; _dump.push("\n") ; _dump.push(" *bisect3Di = ") ; _dump.push(std::to_string( - geompred::_nn_calls [ - geompred::BISECT3D_i])) ; + geompred::_nn_calls[geompred::BISECT3D_i])) ; _dump.push("\n") ; _dump.push(" *bisect3De = ") ; _dump.push(std::to_string( - geompred::_nn_calls [ - geompred::BISECT3D_e])) ; + geompred::_nn_calls[geompred::BISECT3D_e])) ; _dump.push("\n") ; _dump.push(" *bisect3Wf = ") ; _dump.push(std::to_string( - geompred::_nn_calls [ - geompred::BISECT3W_f])) ; + geompred::_nn_calls[geompred::BISECT3W_f])) ; _dump.push("\n") ; _dump.push(" *bisect3Wi = ") ; _dump.push(std::to_string( - geompred::_nn_calls [ - geompred::BISECT3W_i])) ; + geompred::_nn_calls[geompred::BISECT3W_i])) ; _dump.push("\n") ; _dump.push(" *bisect3We = ") ; _dump.push(std::to_string( - geompred::_nn_calls [ - geompred::BISECT3W_e])) ; + geompred::_nn_calls[geompred::BISECT3W_e])) ; _dump.push("\n") ; _dump.push(" *inball3Df = ") ; _dump.push(std::to_string( - geompred::_nn_calls [ - geompred::INBALL3D_f])) ; + geompred::_nn_calls[geompred::INBALL3D_f])) ; _dump.push("\n") ; _dump.push(" *inball3Di = ") ; _dump.push(std::to_string( - geompred::_nn_calls [ - geompred::INBALL3D_i])) ; + geompred::_nn_calls[geompred::INBALL3D_i])) ; _dump.push("\n") ; _dump.push(" *inball3De = ") ; _dump.push(std::to_string( - geompred::_nn_calls [ - geompred::INBALL3D_e])) ; + geompred::_nn_calls[geompred::INBALL3D_e])) ; _dump.push("\n") ; _dump.push(" *inball3Wf = ") ; _dump.push(std::to_string( - geompred::_nn_calls [ - geompred::INBALL3W_f])) ; + geompred::_nn_calls[geompred::INBALL3W_f])) ; _dump.push("\n") ; _dump.push(" *inball3Wi = ") ; _dump.push(std::to_string( - geompred::_nn_calls [ - geompred::INBALL3W_i])) ; + geompred::_nn_calls[geompred::INBALL3W_i])) ; _dump.push("\n") ; _dump.push(" *inball3We = ") ; _dump.push(std::to_string( - geompred::_nn_calls [ - geompred::INBALL3W_e])) ; + geompred::_nn_calls[geompred::INBALL3W_e])) ; _dump.push("\n") ; } diff --git a/src/libcpp/rdel_mesh/rdel_offh_delfront_2.inc b/src/libcpp/rdel_mesh/rdel_offh_delfront_2.inc index 37ffab6..18778ce 100644 --- a/src/libcpp/rdel_mesh/rdel_offh_delfront_2.inc +++ b/src/libcpp/rdel_mesh/rdel_offh_delfront_2.inc @@ -139,7 +139,7 @@ _pert += + 1 ; _pert *= _seps ; - for (auto _iter = +0; _iter++ != +4 ; ) + for (auto _iter = +0; _iter++ != +5 ; ) { _hsiz[2] = _hfun.eval(_ppos, _hint) ; @@ -304,7 +304,7 @@ _pert += + 1 ; _pert *= _seps ; - for (auto _iter = +0; _iter++ != +4 ; ) + for (auto _iter = +0; _iter++ != +5 ; ) { _hsiz[2] = _hfun.eval(_ppos, _hint) ; diff --git a/src/libcpp/rdel_mesh/rdel_offh_delfront_3.inc b/src/libcpp/rdel_mesh/rdel_offh_delfront_3.inc index 99072a4..1e0d015 100644 --- a/src/libcpp/rdel_mesh/rdel_offh_delfront_3.inc +++ b/src/libcpp/rdel_mesh/rdel_offh_delfront_3.inc @@ -145,7 +145,7 @@ _pert += + 1 ; _pert *= _seps ; - for (auto _iter = +0; _iter++ != +4 ; ) + for (auto _iter = +0; _iter++ != +5 ; ) { _hsiz[2] = _hfun.eval(_ppos, _hint) ; @@ -335,7 +335,7 @@ _pert += + 1 ; _pert *= _seps ; - for (auto _iter = +0; _iter++ != +4 ; ) + for (auto _iter = +0; _iter++ != +5 ; ) { _hsiz[2] = _hfun.eval(_ppos, _hint) ; @@ -529,7 +529,7 @@ _pert += + 1 ; _pert *= _seps ; - for (auto _iter = +0; _iter++ != +4 ; ) + for (auto _iter = +0; _iter++ != +5 ; ) { _hsiz[3] = _hfun.eval(_ppos, _hint) ; diff --git a/src/libcpp/rdel_mesh/rdel_pred_delfront_2.hpp b/src/libcpp/rdel_mesh/rdel_pred_delfront_2.hpp index 5fea2e6..03f4697 100644 --- a/src/libcpp/rdel_mesh/rdel_pred_delfront_2.hpp +++ b/src/libcpp/rdel_mesh/rdel_pred_delfront_2.hpp @@ -154,7 +154,7 @@ /*------------------------ max. frontal "redo" steps */ iptr_type static constexpr _REDO = 32 ; - iptr_type static constexpr _STEP = 8 ; + iptr_type static constexpr _STEP = 8 ; real_type static constexpr _OKAY = (real_type) +5./6. ; @@ -388,9 +388,8 @@ if (_kind == rdel_opts::null_kind ) { /*----------------------- attempt offcentre placement */ - if(__chkbit(_args.rule(), - rdel_opts - ::offH_kind) ) + if(__chkbit(_args.rule(), + rdel_opts::offH_kind) ) _kind = edge_offh( _geom, _size, _mesh , _enod, _pmax, _ppos , _args) ; @@ -454,27 +453,24 @@ /*--------------------------------- calc. 3-tria ball */ real_type _tbal[3]; - _tbal[0] = _mesh. - _tria.tria(_tpos)->circ(0); - _tbal[1] = _mesh. - _tria.tria(_tpos)->circ(1); + _tbal[0] = + _mesh._tria.tria(_tpos)->circ(0) ; + _tbal[1] = + _mesh._tria.tria(_tpos)->circ(1) ; _tbal[2] = (real_type)+0. ; auto _hash = _mesh._tria._nset.count(); _tbal[2]+= - geometry::lensqr_2d (_tbal, - &_mesh._tria.node( - _tnod[0])->pval( 0)) ; + geometry::lensqr_2d (_tbal, + &_mesh._tria.node(_tnod[0])->pval(0)) ; _tbal[2]+= - geometry::lensqr_2d (_tbal, - &_mesh._tria.node( - _tnod[1])->pval( 0)) ; + geometry::lensqr_2d (_tbal, + &_mesh._tria.node(_tnod[1])->pval(0)) ; _tbal[2]+= - geometry::lensqr_2d (_tbal, - &_mesh._tria.node( - _tnod[2])->pval( 0)) ; + geometry::lensqr_2d (_tbal, + &_mesh._tria.node(_tnod[2])->pval(0)) ; _tbal[2]/= (real_type)+3. ; @@ -586,20 +582,18 @@ { /*----------------------- attempt offcentre placement */ if(__chkbit(_args.rule(), - rdel_opts - ::offH_kind) ) + rdel_opts::offH_kind) ) _kind = tria_offh( _geom, - _size , _mesh, _enod, - _ebal , _tbal, _dvec, - _ppos , _args) ; + _size , _mesh, + _enod , _ebal, _tbal, + _dvec , _ppos, _args) ; } if (_kind == rdel_opts::null_kind || _kind == rdel_opts::circ_kind ) { /*----------------------- attempt sink-type placement */ if(__chkbit(_args.rule(), - rdel_opts - ::sink_kind) ) + rdel_opts::sink_kind) ) _kind = tria_sink( _geom, _size , _mesh, _tpos , _tnod, _tbal, diff --git a/src/libcpp/rdel_mesh/rdel_pred_delfront_3.hpp b/src/libcpp/rdel_mesh/rdel_pred_delfront_3.hpp index ed14380..269400e 100644 --- a/src/libcpp/rdel_mesh/rdel_pred_delfront_3.hpp +++ b/src/libcpp/rdel_mesh/rdel_pred_delfront_3.hpp @@ -291,8 +291,7 @@ ) { containers::array _tset; - - _tset.set_alloc(8) ; + _tset.set_alloc(32); iptr_type _epos; for (_epos = +3; _epos-- != +0; ) @@ -305,10 +304,8 @@ _enod[1] = _FNOD[_enod[ 1]]; _tset.set_count(0) ; - - base_type::edge_loop (_mesh , - _enod, _tadj , - _fadj, _tset ) ; + base_type::edge_loop ( + _mesh, _enod, _tadj, _fadj, _tset); algorithms::isort ( &_enod[0], &_enod[2], @@ -532,8 +529,7 @@ { /*----------------------- attempt offcentre placement */ if(__chkbit(_args.rule(), - rdel_opts - ::offH_kind) ) + rdel_opts::offH_kind) ) _kind = edge_offh( _geom, _size , _mesh, _enod, _pmax , _ppos, _args) ; @@ -746,24 +742,22 @@ { /*----------------------- attempt offcentre placement */ if(__chkbit(_args.rule(), - rdel_opts - ::offH_kind) ) + rdel_opts::offH_kind) ) _kind = face_offh( _geom, _size , _mesh, _enod, - _evec , _dvec, _pmax, - _ppos , _args) ; + _evec , _dvec, + _pmax , _ppos, _args) ; } if (_kind == rdel_opts::null_kind || _kind == rdel_opts::circ_kind ) { /*----------------------- attempt sink-type placement */ if(__chkbit(_args.rule(), - rdel_opts - ::sink_kind) ) + rdel_opts::sink_kind) ) _kind = face_sink( _geom, - _size , _mesh, _tadj, - _enod , _pmax, - _ppos , _args) ; + _size , _mesh, + _tadj , _enod, + _pmax , _ppos, _args) ; } if (_kind == rdel_opts::null_kind || _kind == rdel_opts::circ_kind ) @@ -832,44 +826,40 @@ /*--------------------------------- pop tria indexing */ iptr_type _tnod[4] = { _mesh. - _tria.tria(_tpos)->node( +0), + _tria.tria(_tpos)->node(+0), _mesh. - _tria.tria(_tpos)->node( +1), + _tria.tria(_tpos)->node(+1), _mesh. - _tria.tria(_tpos)->node( +2), + _tria.tria(_tpos)->node(+2), _mesh. - _tria.tria(_tpos)->node( +3) + _tria.tria(_tpos)->node(+3) } ; /*--------------------------------- calc. 3-tria ball */ real_type _tbal[4]; - _tbal[0] = _mesh. - _tria.tria(_tpos)->circ(0); - _tbal[1] = _mesh. - _tria.tria(_tpos)->circ(1); - _tbal[2] = _mesh. - _tria.tria(_tpos)->circ(2); + _tbal[0] = + _mesh._tria.tria(_tpos)->circ(0) ; + _tbal[1] = + _mesh._tria.tria(_tpos)->circ(1) ; + _tbal[2] = + _mesh._tria.tria(_tpos)->circ(2) ; _tbal[3] = (real_type)+0. ; - auto _hash = + auto _hash = _mesh._tria._nset.count(); _tbal[3]+= - geometry::lensqr_3d (_tbal, - &_mesh._tria.node( - _tnod[0])->pval( 0)) ; + geometry::lensqr_3d (_tbal, + &_mesh._tria.node(_tnod[0])->pval(0)) ; _tbal[3]+= - geometry::lensqr_3d (_tbal, - &_mesh._tria.node( - _tnod[1])->pval( 0)) ; + geometry::lensqr_3d (_tbal, + &_mesh._tria.node(_tnod[1])->pval(0)) ; _tbal[3]+= - geometry::lensqr_3d (_tbal, - &_mesh._tria.node( - _tnod[2])->pval( 0)) ; + geometry::lensqr_3d (_tbal, + &_mesh._tria.node(_tnod[2])->pval(0)) ; _tbal[3]+= - geometry::lensqr_3d (_tbal, - &_mesh._tria.node( - _tnod[3])->pval( 0)) ; + geometry::lensqr_3d (_tbal, + &_mesh._tria.node(_tnod[3])->pval(0)) ; _tbal[3]/= (real_type)+4. ; @@ -935,7 +925,7 @@ tria(_tpos)->node(_fnod[ 2]); real_type _fbal [ +4]; - geometry::circ_ball_3d(_fbal , + geometry::perp_ball_3d(_fbal , &_mesh._tria. node(_fnod[0])->pval(0), &_mesh._tria. @@ -1015,14 +1005,13 @@ /*----------------------------------- calc. face-ball */ real_type _fbal [ +4]; - geometry::circ_ball_3d(_fbal, + 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) - ) ; + _tria.node(_fnod[2])->pval(0) ) ; /*------------------------- assemble "frontal" vector */ real_type _dvec[5] ; @@ -1051,20 +1040,18 @@ { /*----------------------- attempt offcentre placement */ if(__chkbit(_args.rule(), - rdel_opts - ::offH_kind) ) + rdel_opts::offH_kind) ) _kind = tria_offh( _geom, _size , _mesh, _fnod, - _fbal , _tbal, _dvec, - _ppos , _args) ; + _fbal , _tbal, + _dvec , _ppos, _args) ; } if (_kind == rdel_opts::null_kind || _kind == rdel_opts::circ_kind ) { /*----------------------- attempt sink-type placement */ if(__chkbit(_args.rule(), - rdel_opts - ::sink_kind) ) + rdel_opts::sink_kind) ) _kind = tria_sink( _geom, _size , _mesh, _tpos , _tnod, _tbal, diff --git a/src/libcpp/rdel_mesh/rdel_refine_ball_2.inc b/src/libcpp/rdel_mesh/rdel_refine_ball_2.inc index a420c1d..fcf5d78 100644 --- a/src/libcpp/rdel_mesh/rdel_refine_ball_2.inc +++ b/src/libcpp/rdel_mesh/rdel_refine_ball_2.inc @@ -147,6 +147,73 @@ } } ; + typedef mesh::keep_all_2d + halo_pred; + + class feat_pred + { + public : + __static_call + __inline_call char_type feat_kind ( + real_type *_apex, + typename halo_pred::list_type & _list, + rdel_opts &_args + ) + { + char_type _feat = null_feat ; + + real_type constexpr _DtoR = + (real_type)+3.141592653589793 / 180. ; + + real_type _phi1 = + (real_type)+180. - _args.phi1() ; + real_type _eta1 = + (real_type)+ 0. + _args.eta1() ; + + real_type _hard = + std::cos( _phi1 * _DtoR) ; + real_type _soft = + std::cos( _eta1 * _DtoR) ; + + for(auto _ipos = _list.head() ; + _ipos != _list.tend() ; + ++_ipos ) + { + for(auto _jpos = _ipos+1 ; + _jpos != _list.tend() ; + ++_jpos ) + { + real_type _ivec[2] ; + geometry::vector_2d( + &_apex[0], &_ipos->pval(0), + _ivec) ; + + real_type _jvec[2] ; + geometry::vector_2d( + &_apex[0], &_jpos->pval(0), + _jvec) ; + + real_type _acos = geometry:: + cosine_2d(_ivec, _jvec) ; + + /*------------ 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) ; + } + } + } + return _feat; + } + } ; + /*--------------------- refine next "protecting ball" */ typename rdel_opts::node_kind _kind = rdel_opts::null_kind ; @@ -199,7 +266,7 @@ (real_type) +3./8. * +3./8. ; real_type static constexpr _STOL = - (real_type) +1./2. * +1./2. ; + (real_type) +4./9. * +4./9. ; iptr_type _base = _ball._node[0]; real_type _rmax = _ball._ball[2]; @@ -267,11 +334,7 @@ _hdat._pmid[0] = _ball._ball[0] ; _hdat._pmid[1] = _ball._ball[1] ; - mesh::keep_all_2d < - real_type, iptr_type> _pred ; - mesh::keep_all_2d < - real_type, iptr_type> _halo ; - + halo_pred _pred, _halo ; for(auto _iter = 96; _iter-- != +0 ; ) { bool_type _okay = true; @@ -305,7 +368,7 @@ (real_type) +.67 ; continue ; } - + _okay = _okay & _geom.intersect ( _hdat, _halo) ; // bracket @@ -322,7 +385,19 @@ (real_type) +.67 ; continue ; } - else break ; + + /* + if (feat_pred::feat_kind ( + &_pdat._pmid[0], + _pred._list, _args) != hard_feat) + { + _ball._ball[2] *= // reduce R for FEAT. + (real_type) +.67 ; + continue ; + } + else */ + + break ; } return ( _kind ) ; diff --git a/src/libcpp/rdel_mesh/rdel_refine_base_2.inc b/src/libcpp/rdel_mesh/rdel_refine_base_2.inc index b2a4768..be40086 100644 --- a/src/libcpp/rdel_mesh/rdel_refine_base_2.inc +++ b/src/libcpp/rdel_mesh/rdel_refine_base_2.inc @@ -120,11 +120,26 @@ typename rdel_opts::node_kind _kout = _kind; + # ifdef __use_timers + typename std ::chrono:: + high_resolution_clock::time_point _ttic ; + typename std ::chrono:: + high_resolution_clock::time_point _ttoc ; + typename std ::chrono:: + high_resolution_clock _time ; + + __unreferenced(_time) ; // why does MSVC need this?? + # endif//__use_timers + /*---------------- try lower-dim. faces until success */ for (_tdim = _topo; _tdim > 0 ; ) { _eold.set_count( +0) ; + # ifdef __use_timers + _ttic = _time.now() ; + # endif//__use_timers + real_type _PPOS[3] ; _PPOS[0] = _ppos[0] ; _PPOS[1] = _ppos[1] ; @@ -151,9 +166,14 @@ _tcav.set_count(+0) ; _bscr.set_count(+0) ; _bcav.set_count(+0) ; - + break ; } + + # ifdef __use_timers + _ttoc = _time.now() ; + _tcpu._dt_update+=_tcpu.nano_span(_ttic,_ttoc); + # endif//__use_timers /*------------------------- config. new node data */ _mesh._tria. @@ -179,11 +199,24 @@ } /*------------------------- keep "old" rDT cavity */ + # ifdef __use_timers + _ttic = _time.now() ; + # endif//__use_timers + find_rdel( _geom, _mesh, _told, _eold ) ; + + # ifdef __use_timers + _ttoc = _time.now() ; + _tcpu._rdel_find+=_tcpu.nano_span(_ttic,_ttoc); + # endif//__use_timers /*------------------------- form "new" rDT cavity */ + # ifdef __use_timers + _ttic = _time.now() ; + # endif//__use_timers + push_rdel( _geom, _hfun, _mesh, true, _nnew, _tnew , _escr, _ecav, @@ -194,8 +227,18 @@ _mesh._tria.node( _node)->fdim() = _tdim ; + + # ifdef __use_timers + _ttoc = _time.now() ; + _tcpu._rdel_push+=_tcpu.nano_span(_ttic,_ttoc); + # endif//__use_timers /*------------------------- test "new" rDT cavity */ + # ifdef __use_timers + _ttic = _time.now() ; + # endif//__use_timers + + bool_type _done = false; real_type _pnow[2] ; _pnow[0] = _ppos[0] ; _pnow[1] = _ppos[1] ; @@ -257,7 +300,14 @@ _bcav.set_count(+0) ; } /*------------------- new node acceptable "as-is" */ - else break ; + else _done = true ; + + # ifdef __use_timers + _ttoc = _time.now() ; + _tcpu._rdel_bnds+=_tcpu.nano_span(_ttic,_ttoc); + # endif//__use_timers + + if ( _done) break ; } return _kout ; diff --git a/src/libcpp/rdel_mesh/rdel_refine_base_3.inc b/src/libcpp/rdel_mesh/rdel_refine_base_3.inc index 2c3f743..ceb90d0 100644 --- a/src/libcpp/rdel_mesh/rdel_refine_base_3.inc +++ b/src/libcpp/rdel_mesh/rdel_refine_base_3.inc @@ -54,7 +54,7 @@ -------------------------------------------------------- */ - __static_call + __static_call __normal_call iptr_type tria_sign ( mesh_type &_mesh, iptr_type _tpos @@ -127,12 +127,27 @@ typename rdel_opts::node_kind _kout = _kind; + # ifdef __use_timers + typename std ::chrono:: + high_resolution_clock::time_point _ttic ; + typename std ::chrono:: + high_resolution_clock::time_point _ttoc ; + typename std ::chrono:: + high_resolution_clock _time ; + + __unreferenced(_time) ; // why does MSVC need this?? + # endif//__use_timers + /*---------------- try lower-dim. faces until success */ for (_tdim = _topo; _tdim > 0 ; ) { _eold.set_count( +0) ; _fold.set_count( +0) ; + # ifdef __use_timers + _ttic = _time.now() ; + # endif//__use_timers + real_type _PPOS[4] ; _PPOS[0] = _ppos[0] ; _PPOS[1] = _ppos[1] ; @@ -168,6 +183,11 @@ break ; } + # ifdef __use_timers + _ttoc = _time.now() ; + _tcpu._dt_update+=_tcpu.nano_span(_ttic,_ttoc); + # endif//__use_timers + /*------------------------- config. new node data */ _mesh._tria. node(_node)->idxh() = @@ -192,11 +212,24 @@ } /*------------------------- keep "old" rDT cavity */ + # ifdef __use_timers + _ttic = _time.now() ; + # endif//__use_timers + find_rdel( _geom, _mesh, _told, _eold, _fold ) ; + + # ifdef __use_timers + _ttoc = _time.now() ; + _tcpu._rdel_find+=_tcpu.nano_span(_ttic,_ttoc); + # endif//__use_timers /*------------------------- form "new" rDT cavity */ + # ifdef __use_timers + _ttic = _time.now() ; + # endif//__use_timers + push_rdel( _geom, _hfun, _mesh, true, _nnew, _tnew , _escr, _ecav, @@ -209,7 +242,17 @@ _mesh._tria.node( _node)->fdim() = _tdim; + # ifdef __use_timers + _ttoc = _time.now() ; + _tcpu._rdel_push+=_tcpu.nano_span(_ttic,_ttoc); + # endif//__use_timers + /*------------------------- test "new" rDT cavity */ + # ifdef __use_timers + _ttic = _time.now() ; + # endif//__use_timers + + bool_type _done = false; real_type _pnow[3] ; _pnow[0] = _ppos[0] ; _pnow[1] = _ppos[1] ; @@ -281,7 +324,14 @@ _bcav.set_count(+0) ; } /*------------------- new node acceptable "as-is" */ - else break ; + else _done = true ; + + # ifdef __use_timers + _ttoc = _time.now() ; + _tcpu._rdel_bnds+=_tcpu.nano_span(_ttic,_ttoc); + # endif//__use_timers + + if ( _done) break ; } return _kout ; diff --git a/src/libcpp/rdel_mesh/rdel_refine_face_2.inc b/src/libcpp/rdel_mesh/rdel_refine_face_2.inc index 8fb39f3..328b1b4 100644 --- a/src/libcpp/rdel_mesh/rdel_refine_face_2.inc +++ b/src/libcpp/rdel_mesh/rdel_refine_face_2.inc @@ -118,16 +118,14 @@ _qdat. _pass ) { /*----------------- new steiner vertex coords */ - _kind = - mesh_pred::edge_node ( + _kind = mesh_pred::edge_node( _geom, _hfun , _mesh, _qdat , _eptr->_data._tadj, _eptr->_data._eadj, _ppos, _args ) ; - _hint = - _eptr->_data._tadj ; + _hint = _eptr->_data._tadj; if (_kind == rdel_opts:: fail_kind) @@ -271,15 +269,13 @@ _qdat. _pass ) { /*----------------- new steiner vertex coords */ - _kind = - mesh_pred::tria_node ( + _kind = mesh_pred::tria_node( _geom, _hfun , _mesh, _qdat , _tptr->_data._tadj , _ppos, _args ) ; - _hint = - _tptr->_data._tadj ; + _hint = _tptr->_data._tadj; if (_kind == rdel_opts:: fail_kind) diff --git a/src/libcpp/rdel_mesh/rdel_refine_face_3.inc b/src/libcpp/rdel_mesh/rdel_refine_face_3.inc index d4676d1..0b0152a 100644 --- a/src/libcpp/rdel_mesh/rdel_refine_face_3.inc +++ b/src/libcpp/rdel_mesh/rdel_refine_face_3.inc @@ -127,16 +127,14 @@ _qdat. _pass ) { /*----------------- new steiner vertex coords */ - _kind = - mesh_pred::edge_node ( + _kind = mesh_pred::edge_node( _geom, _hfun , _mesh, _qdat , _eptr->_data._tadj , _eptr->_data._eadj , _ppos, _args ) ; - _hint = - _eptr->_data._tadj ; + _hint = _eptr->_data._tadj; if (_kind == rdel_opts:: fail_kind) @@ -294,16 +292,14 @@ _qdat. _pass ) { /*----------------- new steiner vertex coords */ - _kind = - mesh_pred::face_node ( + _kind = mesh_pred::face_node( _geom, _hfun , _mesh, _qdat , _fptr->_data._tadj , _fptr->_data._fadj , _ppos, _args ) ; - _hint = - _fptr->_data._tadj ; + _hint = _fptr->_data._tadj; if (_kind == rdel_opts:: fail_kind) @@ -461,15 +457,13 @@ _qdat. _pass ) { /*----------------- new steiner vertex coords */ - _kind = - mesh_pred::tria_node ( + _kind = mesh_pred::tria_node( _geom, _hfun , _mesh, _qdat , _tptr->_data._tadj , _ppos, _args ) ; - _hint = - _tptr->_data._tadj ; + _hint = _tptr->_data._tadj; if (_kind == rdel_opts:: fail_kind) diff --git a/src/libcpp/rdel_mesh/rdel_refine_topo_2.inc b/src/libcpp/rdel_mesh/rdel_refine_topo_2.inc index 2ee2b59..b593554 100644 --- a/src/libcpp/rdel_mesh/rdel_refine_topo_2.inc +++ b/src/libcpp/rdel_mesh/rdel_refine_topo_2.inc @@ -508,7 +508,7 @@ _tcav , _tscr, _bcav , _bscr, _hint, _tdim , _pass, _args) ; - + return ( _kind ) ; } diff --git a/src/libcpp/rdel_mesh/rdel_refine_topo_3.inc b/src/libcpp/rdel_mesh/rdel_refine_topo_3.inc index 69dcba4..4c0fadc 100644 --- a/src/libcpp/rdel_mesh/rdel_refine_topo_3.inc +++ b/src/libcpp/rdel_mesh/rdel_refine_topo_3.inc @@ -35,9 +35,9 @@ * -------------------------------------------------------- * - * Last updated: 15 Jul., 2021 + * Last updated: 21 Apr., 2024 * - * Copyright 2013-2021 + * Copyright 2013-2024 * Darren Engwirda * d.engwirda@gmail.com * https://github.com/dengwirda/ @@ -598,7 +598,7 @@ _geom.intersect( _fdat , _halo ) ; - if (_halo._list.count() <= +2) + //!!if (_halo._list.count() <= +2) { /*--------------------- keep "best" intersections */ auto _ioff = _halo._list.tend(); diff --git a/src/libcpp/rdel_mesh/rdel_test_bounds_2.inc b/src/libcpp/rdel_mesh/rdel_test_bounds_2.inc index cec0044..87e4b4b 100644 --- a/src/libcpp/rdel_mesh/rdel_test_bounds_2.inc +++ b/src/libcpp/rdel_mesh/rdel_test_bounds_2.inc @@ -48,6 +48,7 @@ // from rdel_mesh_2.hpp + // consider geometrical as well as topol. encroachment # define __GEOMBNDS /* @@ -131,7 +132,7 @@ real_type static const _pert = std::pow( std::numeric_limits - ::epsilon(),(real_type)+.8); + ::epsilon(),(real_type)+.5); _pmax[2] = (real_type) +.0 ; @@ -226,7 +227,7 @@ real_type static const _pert = std::pow( std::numeric_limits - ::epsilon(),(real_type)+.80) ; + ::epsilon(),(real_type)+.5); bool_type _bnds = false; diff --git a/src/libcpp/rdel_mesh/rdel_test_bounds_3.inc b/src/libcpp/rdel_mesh/rdel_test_bounds_3.inc index 59b3c63..2b391d7 100644 --- a/src/libcpp/rdel_mesh/rdel_test_bounds_3.inc +++ b/src/libcpp/rdel_mesh/rdel_test_bounds_3.inc @@ -48,6 +48,7 @@ // from rdel_mesh_3.hpp + // consider geometrical as well as topol. encroachment # define __GEOMBNDS /* @@ -171,9 +172,9 @@ real_type static const _pert = std::pow( std::numeric_limits - ::epsilon(),(real_type)+.80) ; + ::epsilon(),(real_type)+.5); - _pmax[ 3] = (real_type)+.00 ; + _pmax[ 3] = (real_type)+.0 ; if (_mode > +1) { @@ -341,7 +342,7 @@ real_type static const _pert = std::pow( std::numeric_limits - ::epsilon(),(real_type)+.80) ; + ::epsilon(),(real_type)+.5); bool_type _bnds = false; diff --git a/src/libcpp/rdel_mesh/rdel_timers.hpp b/src/libcpp/rdel_mesh/rdel_timers.hpp index e2a3928..0401dea 100644 --- a/src/libcpp/rdel_mesh/rdel_timers.hpp +++ b/src/libcpp/rdel_mesh/rdel_timers.hpp @@ -35,9 +35,9 @@ * -------------------------------------------------------- * - * Last updated: 20 Jul., 2022 + * Last updated: 29 Apr., 2023 * - * Copyright 2013-2022 + * Copyright 2013-2023 * Darren Engwirda * d.engwirda@gmail.com * https://github.com/dengwirda/ @@ -65,14 +65,26 @@ double _node_init = (double ) +0. ; double _node_rule = (double ) +0. ; + double _edge_init = (double ) +0. ; double _edge_rule = (double ) +0. ; + double _edge_node = (double ) +0. ; + double _face_init = (double ) +0. ; double _face_rule = (double ) +0. ; + double _face_node = (double ) +0. ; + double _tria_init = (double ) +0. ; double _tria_rule = (double ) +0. ; + double _tria_node = (double ) +0. ; + + double _dt_update = (double ) +0. ; + double _rdel_find = (double ) +0. ; + double _rdel_push = (double ) +0. ; + double _rdel_bnds = (double ) +0. ; double _list_trim = (double ) +0. ; + double _list_push = (double ) +0. ; double _topo_init = (double ) +0. ; diff --git a/src/libcpp/rdel_mesh/rdel_update_face_2.inc b/src/libcpp/rdel_mesh/rdel_update_face_2.inc index 767c3c0..1f77949 100644 --- a/src/libcpp/rdel_mesh/rdel_update_face_2.inc +++ b/src/libcpp/rdel_mesh/rdel_update_face_2.inc @@ -35,9 +35,9 @@ * -------------------------------------------------------- * - * Last updated: 02 Aug., 2022 + * Last updated: 11 Nov., 2024 * - * Copyright 2013-2022 + * Copyright 2013-2024 * Darren Engwirda * d.engwirda@gmail.com * https://github.com/dengwirda/ @@ -215,13 +215,12 @@ _tnod[1] = _mesh._tria. tria(_tpos)->node(_tnod[1]); - /*--------------- face contains higher dim. nodes */ if (_mesh._tria.node( - _tnod[0])->fdim() > 1 || + _tnod[0])->fdim() < 2 && _mesh._tria.node( - _tnod[1])->fdim() > 1 ) - continue ; - + _tnod[1])->fdim() < 2 ) + { + /*--------------- face contains correct k^d nodes */ algorithms::isort ( &_tnod[0], &_tnod[2], std::less()) ; @@ -234,9 +233,11 @@ _cdat._node[0] = _tnod[ 0] ; _cdat._node[1] = _tnod[ 1] ; + bool_type _test = true; typename mesh_type:: edge_list:: item_type *_mptr = nullptr ; + // pragma omp critical(update_face_edg2) if(_edge_test. find( _fdat, _mptr) ) { @@ -245,9 +246,9 @@ _mptr->_data._dups; /*--------------------------- don't test repeats! */ - continue ; + _test = false; } - + _cdat._pass = _pass; _fdat._pass = _pass; @@ -257,42 +258,42 @@ _fdat._dups = +0; // count num. dup's // only in hash-set + if (_test) + { /*--------------------------- call face predicate */ - char_type _topo[ 2], _feat; - real_type _fbal[ 3]; - real_type _sbal[ 3]; + char_type _topo[ 2] , _feat; + real_type _fbal[ 3] ; + real_type _sbal[ 3] ; mesh_pred::edge_cost ( - _geom,_hfun, - _mesh, - _fdat._tadj, - _fdat._eadj, - _opts,_cdat, - _fdat._part, - _feat,_topo, - _fdat._kind, - _fbal,_sbal) ; + _geom, _hfun, _mesh, + _fdat. _tadj, + _fdat. _eadj, + _opts, _cdat, + _fdat. _part, + _feat, _topo, + _fdat. _kind, + _fbal, _sbal) ; /*--------------------------- push edge onto mesh */ - if (_fdat._kind - == mesh::ring_item) + // pragma omp critical(update_face_edg2) + { + if (_fdat._kind == mesh::ring_item) _escr. push_tail(_cdat) ; - if (_fdat._kind - != mesh::null_item) + if (_fdat._kind != mesh::null_item) _nedg += +1 ; - if (_fdat._kind - != mesh::null_item) - _fdat. - _dups = +1 ; + if (_fdat._kind != mesh::null_item) + _fdat._dups = +1 ; - if (_fdat._kind - != mesh::null_item) + if (_fdat._kind != mesh::null_item) _eset. push_tail(_fdat) ; - _edge_test.push (_fdat) ; + } + } + } } // for (auto _fpos = +3; _fpos-- != +0; ) } @@ -330,14 +331,14 @@ _tnod[2] = _mesh. _tria.tria(_tpos)->node(2); - /*--------------- face contains higher dim. nodes */ if (_mesh._tria.node( - _tnod[0])->fdim() > 2 || + _tnod[0])->fdim() < 3 && _mesh._tria.node( - _tnod[1])->fdim() > 2 || + _tnod[1])->fdim() < 3 && _mesh._tria.node( - _tnod[2])->fdim() > 2 ) - return ; + _tnod[2])->fdim() < 3 ) + { + /*--------------- face contains correct k^d nodes */ tria_data _tdat; _tdat._node[0] = _tnod[ 0] ; @@ -351,8 +352,7 @@ _cdat._node[1] = _tnod[ 1] ; _cdat._node[2] = _tnod[ 2] ; - - //!!_tria_test.push( _tdat) ; won't have repeats! + // _tria_test.push( _tdat) ; guarantee no repeat /*--------------------------- call tria predicate */ _tdat._part = _sign ; @@ -361,27 +361,28 @@ _tdat._pass = _pass ; mesh_pred::tria_cost ( - _geom,_hfun, - _mesh, - _tdat._tadj, - _opts,_cdat, - _tdat._part, - _tdat._kind) ; + _geom, _hfun, _mesh, + _tdat. _tadj, + _opts, _cdat, + _tdat. _part, + _tdat. _kind); _sign = _tdat. _part ; /*--------------------------- push edge onto mesh */ - if (_tdat._kind - == mesh::ring_item) + // pragma omp critical(update_face_tri3) + { + if (_tdat._kind == mesh::ring_item) _tscr. push_tail(_cdat) ; - if (_tdat._kind - != mesh::null_item) + if (_tdat._kind != mesh::null_item) _ntri += +1 ; - if (_tdat._kind - != mesh::null_item) + if (_tdat._kind != mesh::null_item) _tset. push_tail(_tdat) ; + } + + } } } @@ -460,77 +461,88 @@ iptr_type _ntri = +0 ; iptr_type _ndup = +0 ; + // iptr_type _ncpu = +1 ; //!! sequential for now... + + // ifdef __use_openmp + // omp_set_num_threads(_ncpu); + // else + // __unreferenced (_ncpu) ; + // endif//__use_openmp + /*------------------------- calc. voronoi-dual points */ - for( auto _iter = _tnew.head(); - _iter != _tnew.tend(); - ++_iter ) + // pragma omp parallel default(shared) { - if (_init) - tria_circ(_mesh,*_iter) ; + // pragma omp for schedule(static) + for( auto _iter = _tnew.head(); + _iter != _tnew.tend(); + ++_iter ) + { + if (_init) tria_circ(_mesh, *_iter) ; + } } /*------------- push any new protecting balls created */ if (_dim0 <= node_mode && _dim1 >= node_mode ) { - for( auto _iter = _nnew.head(); - _iter != _nnew.tend(); - ++_iter ) - { - char_type _kind = feat_ball; + for( auto _iter = _nnew.head(); + _iter != _nnew.tend(); + ++_iter ) + { + char_type _kind = feat_ball; - init_ball(_mesh, _geom , - _hfun,*_iter , - _bdat, _bscr , - _kind, - _pass, _opts) ; - } + init_ball( _mesh, _geom, _hfun, + *_iter, _bdat, _bscr, + _kind, _pass, _opts) ; + } } /*------------- push any new restricted edges created */ if (_dim0 <= edge_mode && _dim1 >= edge_mode ) { - _mesh._etwo.clear(); - _mesh._etwo.set_slots(_tnew.count() * +3) ; + _mesh._etwo.clear(); + _mesh._etwo.set_slots(_tnew.count() * +3) ; - for( auto _iter = _tnew.head(); - _iter != _tnew.tend(); - ++_iter ) - { - push_edge(_mesh, _geom , - _hfun,*_iter , - _edat, _escr , - _mesh. _etwo , - _nedg, _ndup , - _pass, _opts) ; - } + // pragma omp parallel default(shared) + { + // pragma omp for schedule(static) + for( auto _iter = _tnew.head(); + _iter != _tnew.tend(); + ++_iter ) + { + push_edge( _mesh, _geom, _hfun, + *_iter, _edat, _escr, + _mesh. _etwo, + _nedg, _ndup, _pass, _opts) ; + } + } } /*------------- push any new restricted trias created */ if (_dim0 <= tria_mode && _dim1 >= tria_mode ) { - // _mesh._ttwo.clear(); - // _mesh._ttwo.set_slots(_tnew.count() * +1) ; - - bool_type _safe = true ; - - if (_dim0 > +0) _safe = false ; + // _mesh._ttwo.clear(); + // _mesh._ttwo.set_slots(_tnew.count() * +1) ; - // if (_nedg >= +1) _safe = false ; - if (_ndup >= +1) _safe = false ; + bool_type _safe = true ; + if (_dim0 > +0) _safe = false ; + // if (_nedg >= +1) _safe = false ; + if (_ndup >= +1) _safe = false ; - for( auto _iter = _tnew.head(); - _iter != _tnew.tend(); - ++_iter ) - { - _sign = (!_safe) ? -1 : _sign ; + // pragma omp parallel default(shared) + { + // pragma omp for schedule(static) + for( auto _iter = _tnew.head(); + _iter != _tnew.tend(); + ++_iter ) + { + _sign = (!_safe) ? -1 : _sign; - push_tria(_mesh, _geom , - _hfun,*_iter , - _sign, _tdat , - _tscr, _ntri , - _pass, _opts) ; - } + push_tria( _mesh, _geom, _hfun, + *_iter, _sign, _tdat, + _tscr, _ntri, _pass, _opts) ; + } + } } } diff --git a/src/libcpp/rdel_mesh/rdel_update_face_3.inc b/src/libcpp/rdel_mesh/rdel_update_face_3.inc index 766598f..42be782 100644 --- a/src/libcpp/rdel_mesh/rdel_update_face_3.inc +++ b/src/libcpp/rdel_mesh/rdel_update_face_3.inc @@ -35,9 +35,9 @@ * -------------------------------------------------------- * - * Last updated: 02 Aug., 2022 + * Last updated: 11 Nov., 2024 * - * Copyright 2013-2022 + * Copyright 2013-2024 * Darren Engwirda * d.engwirda@gmail.com * https://github.com/dengwirda/ @@ -260,13 +260,12 @@ _tnod[1] = _mesh._tria. tria(_tpos)->node(_tnod[1]); - /*--------------- face contains higher dim. nodes */ if (_mesh._tria.node( - _tnod[0])->fdim() > 1 || + _tnod[0])->fdim() < 2 && _mesh._tria.node( - _tnod[1])->fdim() > 1 ) - continue ; - + _tnod[1])->fdim() < 2 ) + { + /*--------------- face contains correct k^d nodes */ algorithms::isort ( &_tnod[0], &_tnod[2], std::less()) ; @@ -279,14 +278,16 @@ _cdat._node[0] = _tnod[ 0] ; _cdat._node[1] = _tnod[ 1] ; + bool_type _test = true; typename mesh_type:: edge_list:: item_type *_mptr = nullptr ; + // pragma omp critical(update_face_edg2) if(_edge_test. find( _edat, _mptr) ) { /*--------------------------- don't test repeats! */ - continue ; + _test = false; } _cdat._pass = _pass; @@ -296,37 +297,39 @@ _edat._eadj = (char_type) _fpos; + if (_test) + { /*--------------------------- call edge predicate */ - real_type _fbal[ 4]; - real_type _sbal[ 4]; + real_type _fbal[ 4] ; + real_type _sbal[ 4] ; mesh_pred::edge_cost ( - _geom,_hfun, - _mesh, - _edat._tadj, - _edat._eadj, - _opts,_cdat, - _edat._part, - _edat._feat, - _edat._topo, - _edat._kind, - _fbal,_sbal) ; - + _geom, _hfun, _mesh, + _edat. _tadj, + _edat. _eadj, + _opts, _cdat, + _edat. _part, + _edat. _feat, + _edat. _topo, + _edat. _kind, + _fbal, _sbal) ; + /*--------------------------- push edge onto mesh */ - if (_edat._kind - == mesh::ring_item) + // pragma omp critical(update_face_edg2) + { + if (_edat._kind == mesh::ring_item) _escr. push_tail(_cdat) ; - if (_edat._kind - != mesh::null_item) + if (_edat._kind != mesh::null_item) _nedg += +1 ; - if (_edat._kind - != mesh::null_item) + if (_edat._kind != mesh::null_item) _eset. push_tail(_edat) ; + _edge_test.push (_edat) ; + } + } - _edge_test.push( _edat) ; - + } } // for (auto _fpos = +6; _fpos-- != +0; ) } @@ -381,15 +384,14 @@ _tnod[2] = _mesh._tria. tria(_tpos)->node(_tnod[2]); - /*--------------- face contains higher dim. nodes */ if (_mesh._tria.node( - _tnod[0])->fdim() > 2 || + _tnod[0])->fdim() < 3 && _mesh._tria.node( - _tnod[1])->fdim() > 2 || + _tnod[1])->fdim() < 3 && _mesh._tria.node( - _tnod[2])->fdim() > 2 ) - continue ; - + _tnod[2])->fdim() < 3 ) + { + /*--------------- face contains correct k^d nodes */ algorithms::isort ( &_tnod[0], &_tnod[3], std::less()) ; @@ -404,9 +406,11 @@ _cdat._node[1] = _tnod[ 1] ; _cdat._node[2] = _tnod[ 2] ; + bool_type _test = true; typename mesh_type:: face_list:: item_type *_mptr = nullptr ; + // pragma omp critical(update_face_tri3) if(_face_test. find( _fdat, _mptr) ) { @@ -415,7 +419,7 @@ _mptr->_data._dups; /*--------------------------- don't test repeats! */ - continue ; + _test = false ; } _cdat._pass = _pass; @@ -427,42 +431,42 @@ _fdat._dups = +0; // count num. dup's // only in hash-set + if (_test) + { /*--------------------------- call face predicate */ - char_type _topo[ 2], _feat; - real_type _fbal[ 4]; - real_type _sbal[ 4]; + char_type _topo[ 2] , _feat; + real_type _fbal[ 4] ; + real_type _sbal[ 4] ; mesh_pred::face_cost ( - _geom,_hfun, - _mesh, - _fdat._tadj, - _fdat._fadj, - _opts,_cdat, - _fdat._part, - _feat,_topo, - _fdat._kind, - _fbal,_sbal) ; - + _geom, _hfun, _mesh, + _fdat. _tadj, + _fdat. _fadj, + _opts, _cdat, + _fdat. _part, + _feat, _topo, + _fdat. _kind, + _fbal, _sbal) ; + /*--------------------------- push face onto mesh */ - if (_fdat._kind - == mesh::ring_item) + // pragma omp critical(update_face_tri3) + { + if (_fdat._kind == mesh::ring_item) _fscr. push_tail(_cdat) ; - if (_fdat._kind - != mesh::null_item) + if (_fdat._kind != mesh::null_item) _nfac += +1 ; - if (_fdat._kind - != mesh::null_item) - _fdat. - _dups = +1 ; + if (_fdat._kind != mesh::null_item) + _fdat._dups = +1 ; - if (_fdat._kind - != mesh::null_item) + if (_fdat._kind != mesh::null_item) _fset. push_tail(_fdat) ; + _face_test.push (_fdat) ; + } + } - _face_test.push( _fdat) ; - + } } // for (auto _fpos = +4; _fpos-- != +0; ) } @@ -502,17 +506,16 @@ _tnod[3] = _mesh. _tria.tria(_tpos)->node(3); - /*--------------- face contains higher dim. nodes */ if (_mesh._tria.node( - _tnod[0])->fdim() > 3 || + _tnod[0])->fdim() < 4 && _mesh._tria.node( - _tnod[1])->fdim() > 3 || + _tnod[1])->fdim() < 4 && _mesh._tria.node( - _tnod[2])->fdim() > 3 || + _tnod[2])->fdim() < 4 && _mesh._tria.node( - _tnod[3])->fdim() > 3 ) - return ; - + _tnod[3])->fdim() < 4 ) + { + /*--------------- face contains correct k^d nodes */ tria_data _tdat; _tdat._node[0] = _tnod[ 0] ; _tdat._node[1] = _tnod[ 1] ; @@ -527,8 +530,7 @@ _cdat._node[2] = _tnod[ 2] ; _cdat._node[3] = _tnod[ 3] ; - - //!!_tria_test.push( _tdat) ; won't have repeats! + // _tria_test.push( _tdat) ; guarantee no repeats! /*--------------------------- calc tria cost/kind */ _tdat._part = _sign ; @@ -537,27 +539,28 @@ _tdat._pass = _pass ; mesh_pred::tria_cost ( - _geom,_hfun, - _mesh, - _tdat._tadj, - _opts,_cdat, - _tdat._part, - _tdat._kind) ; + _geom, _hfun, _mesh, + _tdat. _tadj, + _opts, _cdat, + _tdat. _part, + _tdat. _kind); _sign = _tdat. _part ; /*--------------------------- push tria onto mesh */ - if (_tdat._kind - == mesh::ring_item) + // pragma omp critical(update_face_tri4) + { + if (_tdat._kind == mesh::ring_item) _tscr. push_tail(_cdat) ; - if (_tdat._kind - != mesh::null_item) + if (_tdat._kind != mesh::null_item) _ntri += +1 ; - if (_tdat._kind - != mesh::null_item) + if (_tdat._kind != mesh::null_item) _tset. push_tail(_tdat) ; + } + + } } } @@ -645,96 +648,109 @@ iptr_type _ntri = +0 ; iptr_type _ndup = +0 ; + // iptr_type _ncpu = +1 ; //!! sequential for now... + + // ifdef __use_openmp + // omp_set_num_threads(_ncpu); + // else + // __unreferenced (_ncpu) ; + // endif//__use_openmp + /*------------------------- calc. voronoi-dual points */ - for( auto _iter = _tnew.head(); - _iter != _tnew.tend(); - ++_iter ) + // pragma omp parallel default(shared) { - if (_init) - tria_circ(_mesh,*_iter) ; + // pragma omp for schedule(static) + for( auto _iter = _tnew.head(); + _iter != _tnew.tend(); + ++_iter ) + { + if (_init) tria_circ(_mesh, *_iter) ; + } } /*------------- push any new protecting balls created */ if (_dim0 <= node_mode && _dim1 >= node_mode ) { - for( auto _iter = _nnew.head(); - _iter != _nnew.tend(); - ++_iter ) - { - char_type _kind = feat_ball; + for( auto _iter = _nnew.head(); + _iter != _nnew.tend(); + ++_iter ) + { + char_type _kind = feat_ball; - init_ball(_mesh, _geom , - _hfun,*_iter , - _bdat, _bscr , - _kind, - _pass, _opts) ; - } + init_ball( _mesh, _geom, _hfun, + *_iter, _bdat, _bscr, + _kind, _pass, _opts) ; + } } /*------------- push any new restricted edges created */ if (_dim0 <= edge_mode && _dim1 >= edge_mode ) { - _mesh._etwo.clear(); - _mesh._etwo.set_slots(_tnew.count() * +6) ; + _mesh._etwo.clear(); + _mesh._etwo.set_slots(_tnew.count() * +6) ; - for( auto _iter = _tnew.head(); - _iter != _tnew.tend(); - ++_iter ) - { - push_edge(_mesh, _geom , - _hfun,*_iter , - _edat, _escr , - _mesh. _etwo , - _nedg, - _pass, _opts) ; - } + // pragma omp parallel default(shared) + { + // pragma omp for schedule(static) + for( auto _iter = _tnew.head(); + _iter != _tnew.tend(); + ++_iter ) + { + push_edge( _mesh, _geom, _hfun, + *_iter, _edat, _escr, + _mesh. _etwo, + _nedg, _pass, _opts) ; + } + } } /*------------- push any new restricted faces created */ if (_dim0 <= face_mode && _dim1 >= face_mode ) { - _mesh._ftwo.clear(); - _mesh._ftwo.set_slots(_tnew.count() * +4) ; + _mesh._ftwo.clear(); + _mesh._ftwo.set_slots(_tnew.count() * +4) ; - for( auto _iter = _tnew.head(); - _iter != _tnew.tend(); - ++_iter ) - { - push_face(_mesh, _geom , - _hfun,*_iter , - _fdat, _fscr , - _mesh. _ftwo , - _nfac, _ndup , - _pass, _opts) ; - } + // pragma omp parallel default(shared) + { + // pragma omp for schedule(static) + for( auto _iter = _tnew.head(); + _iter != _tnew.tend(); + ++_iter ) + { + push_face( _mesh, _geom, _hfun, + *_iter, _fdat, _fscr, + _mesh. _ftwo, + _nfac, _ndup, _pass, _opts) ; + } + } } /*------------- push any new restricted trias created */ if (_dim0 <= tria_mode && _dim1 >= tria_mode ) { - // _mesh._ttwo.clear(); - // _mesh._ttwo.set_slots(_tnew.count() * +1) ; - - bool_type _safe = true ; - - if (_dim0 > +0) _safe = false ; + // _mesh._ttwo.clear(); + // _mesh._ttwo.set_slots(_tnew.count() * +1) ; - // if (_nfac >= +1) _safe = false ; - if (_ndup >= +1) _safe = false ; + bool_type _safe = true ; + if (_dim0 > +0) _safe = false ; + // if (_nfac >= +1) _safe = false ; + if (_ndup >= +1) _safe = false ; - for( auto _iter = _tnew.head(); - _iter != _tnew.tend(); - ++_iter ) - { - _sign = (!_safe) ? -1 : _sign ; + // pragma omp parallel default(shared) + { + // pragma omp for schedule(static) + for( auto _iter = _tnew.head(); + _iter != _tnew.tend(); + ++_iter ) + { + _sign = (!_safe) ? -1 : _sign; - push_tria(_mesh, _geom , - _hfun,*_iter , - _sign, _tdat , - _tscr, _ntri, - _pass, _opts) ; - } + push_tria( _mesh, _geom, _hfun, + *_iter, _sign, _tdat, + _tscr, _ntri, _pass, _opts) ; + } + } } } diff --git a/src/libcpp/rdel_mesh/rdel_update_topo_2.inc b/src/libcpp/rdel_mesh/rdel_update_topo_2.inc index 557d71b..de44dfe 100644 --- a/src/libcpp/rdel_mesh/rdel_update_topo_2.inc +++ b/src/libcpp/rdel_mesh/rdel_update_topo_2.inc @@ -73,7 +73,7 @@ _mesh._tria._nset.count(), containers::loose_alloc , -1) ; - /*------------------------- add all: everything "new" */ + /*------------------------- add all: everything "new" */ node_data _ndat ; for (auto _iter = _enew.head(); _iter != _enew.tend(); @@ -109,14 +109,14 @@ containers::loose_alloc , -1) ; { - /*------------------------- init. for local hash obj. */ + /*------------------------- init. for local hash obj. */ _mesh._etwo.clear(); _mesh._etwo. set_slots(_enew.count() * 2) ; auto& _eset = _mesh. _etwo; - /*------------------------- add "old" absent in "new" */ + /*------------------------- add "old" absent in "new" */ node_data _ndat ; for (auto _iter = _enew.head(); _iter != _enew.tend(); @@ -158,14 +158,14 @@ } { - /*------------------------- init. for local hash obj. */ + /*------------------------- init. for local hash obj. */ _mesh._etwo.clear(); _mesh._etwo. set_slots(_eold.count() * 2) ; auto& _eset = _mesh. _etwo; - /*------------------------- add "new" absent in "old" */ + /*------------------------- add "new" absent in "old" */ node_data _ndat ; for (auto _iter = _eold.head(); _iter != _eold.tend(); diff --git a/src/libcpp/tessellate/delaunay_tri_k.hpp b/src/libcpp/tessellate/delaunay_tri_k.hpp index fb498a5..5079718 100644 --- a/src/libcpp/tessellate/delaunay_tri_k.hpp +++ b/src/libcpp/tessellate/delaunay_tri_k.hpp @@ -789,6 +789,72 @@ return ( false ) ; } + + + + __inline_call bool_type update ( + __const_ptr(real_type) _ppos, + iptr_type _node + ) + { + bool_type _pass = update ( + _ppos, _node, + (iptr_list*)nullptr, + (iptr_list*)nullptr, + (iptr_list*)nullptr) ; + + return ( _pass ) ; + } + + template < + typename list_type + > + __normal_call bool_type update ( + __const_ptr(real_type) _ppos, + iptr_type _node, + list_type *_tnew = nullptr , + list_type *_told = nullptr , + list_type *_circ = nullptr + ) + { + if (node(_node)-> + next() != this->null_flag()) + { + this->_work.clear (); + + /*--------------------------- find containing element */ + auto _elem = node(_node)->next() ; + + /*--------------------------- push new node onto list */ + for (auto _idim = tria_pred::real_dims + 0 ; + _idim-- != +0 ; ) + { + node(_node)->pval(_idim) = _ppos[_idim]; + } + + /*-------------------- retriangulate enclosing cavity */ + typename tria_pred:: + template circ_pred< + self_type> _pred( _ppos) ; + + if (_circ == nullptr) + scan_tria_list(_elem, +1 , + _pred, _work) ; + else + _work.push_tail(_circ->head() , + _circ->tend() + ) ; + + star_tria_void(_work, _node, + +1, _tnew, _told) ; + + /*-------------------- delaunay topology is recovered */ + return ( true ) ; + } + + return ( false ) ; + } + /* -------------------------------------------------------- * ROLL-BACK: "roll-back" an update. diff --git a/src/liblib/init_jig_t.hpp b/src/liblib/init_jig_t.hpp index 0337732..fc9e2ae 100644 --- a/src/liblib/init_jig_t.hpp +++ b/src/liblib/init_jig_t.hpp @@ -35,9 +35,9 @@ * -------------------------------------------------------- * - * Last updated: 12 Dec., 2022 + * Last updated: 26 Jul., 2025 * - * Copyright 2013-2022 + * Copyright 2013-2025 * Darren Engwirda * d.engwirda@gmail.com * https://github.com/dengwirda/ @@ -99,6 +99,10 @@ _jcfg->_mesh_iter = (indx_t) std::numeric_limits< indx_t >::max() ; + _jcfg->_mesh_orph = (indx_t) +1 ; + + _jcfg->_mesh_lock = (indx_t) +0 ; + _jcfg->_mesh_top1 = (indx_t) +0 ; _jcfg->_mesh_top2 = (indx_t) +0 ; @@ -108,12 +112,12 @@ _jcfg->_mesh_off2 = (real_t) +0.90 ; _jcfg->_mesh_off3 = (real_t) +1.10 ; - real_t _SIZ1 = +1./1. * 4./3. ; + real_t const _SIZ1 = 1./1. * 4./3. ; - real_t _SIZ2 = +5./8. * 4./3. + + real_t const _SIZ2 = 5./8. * 4./3. + 3./8. * 2. / (1. + std::sqrt(1./3.)) ; - real_t _SIZ3 = +5./8. * 4./3. + + real_t const _SIZ3 = 5./8. * 4./3. + 3./8. * 2. / (1. + std::sqrt(3./8.)) ; _jcfg->_mesh_siz1 = (real_t) _SIZ1 ; @@ -123,8 +127,8 @@ _jcfg->_mesh_snk2 = (real_t) + 1./5. ; _jcfg->_mesh_snk3 = (real_t) + 1./3. ; - _jcfg->_mesh_eps1 = (real_t) + 1./3. ; - _jcfg->_mesh_eps2 = (real_t) + 1./3. ; + _jcfg->_mesh_eps1 = (real_t) + 5./12.; // .41667... + _jcfg->_mesh_eps2 = (real_t) + 5./12.; _jcfg->_mesh_vol3 = (real_t) + 0./1. ; @@ -139,7 +143,10 @@ _jcfg->_optm_zeta = (real_t) +0.8250 ; _jcfg->_optm_qtol = (real_t) +1.E-04 ; - _jcfg->_optm_qlim = (real_t) +14./15.; // .9333... + _jcfg->_optm_qlim = (real_t) +11./12.; // .91667... + + _jcfg->_optm_wmin = (real_t) -7. / 8.; // .87500 + _jcfg->_optm_wmax = (real_t) +1. /80.; // .01250 _jcfg->_optm_tria = (indx_t) +1 ; _jcfg->_optm_dual = (indx_t) +0 ; diff --git a/src/liblib/load_jig_t.hpp b/src/liblib/load_jig_t.hpp index 5f60912..de7d300 100644 --- a/src/liblib/load_jig_t.hpp +++ b/src/liblib/load_jig_t.hpp @@ -35,9 +35,9 @@ * -------------------------------------------------------- * - * Last updated: 12 Dec., 2022 + * Last updated: 26 Jul., 2025 * - * Copyright 2013-2022 + * Copyright 2013-2025 * Darren Engwirda * d.engwirda@gmail.com * https://github.com/dengwirda/ @@ -208,6 +208,20 @@ this-> _jjig->_mesh_siz3 = _siz3; } + __normal_call void_type push_mesh_orph ( + bool _orph + ) + { + this-> + _jjig->_mesh_orph = _orph; + } + __normal_call void_type push_mesh_lock ( + bool _lock + ) + { + this-> + _jjig->_mesh_lock = _lock; + } __normal_call void_type push_mesh_top1 ( bool _top1 ) @@ -336,6 +350,20 @@ this-> _jjig->_optm_qlim = _qlim; } + __normal_call void_type push_optm_wmin ( + double _wmin + ) + { + this-> + _jjig->_optm_wmin = _wmin; + } + __normal_call void_type push_optm_wmax ( + double _wmax + ) + { + this-> + _jjig->_optm_wmax = _wmax; + } __normal_call void_type push_optm_tria ( bool _flag ) diff --git a/src/liblib/save_jig_t.hpp b/src/liblib/save_jig_t.hpp index 7e6ab55..5e40fd5 100644 --- a/src/liblib/save_jig_t.hpp +++ b/src/liblib/save_jig_t.hpp @@ -35,9 +35,9 @@ * -------------------------------------------------------- * - * Last updated: 12 Dec., 2022 + * Last updated: 26 Jul., 2025 * - * Copyright 2013-2022 + * Copyright 2013-2025 * Darren Engwirda * d.engwirda@gmail.com * https://github.com/dengwirda/ @@ -159,6 +159,12 @@ _file << "MESH_SIZ3 = " << _jcfg->_mesh_siz3 << "\n" ; + _file << "MESH_ORPH = " << + _jcfg->_mesh_orph << "\n" ; + + _file << "MESH_LOCK = " << + _jcfg->_mesh_lock << "\n" ; + _file << "MESH_TOP1 = " << _jcfg->_mesh_top1 << "\n" ; _file << "MESH_TOP2 = " << @@ -227,6 +233,11 @@ _file << "OPTM_QLIM = " << _jcfg->_optm_qlim << "\n" ; + _file << "OPTM_WMIN = " << + _jcfg->_optm_wmin << "\n" ; + _file << "OPTM_WMAX = " << + _jcfg->_optm_wmax << "\n" ; + _file << "OPTM_TRIA = " << _jcfg->_optm_tria << "\n" ; _file << "OPTM_DUAL = " << diff --git a/src/marche.hpp b/src/marche.hpp index 9110168..d380c8e 100644 --- a/src/marche.hpp +++ b/src/marche.hpp @@ -59,7 +59,7 @@ std::string asciibanner = " \n" - "#------------------------------------------------------------\n" + "#-----------------------------------------------------------------------\n" "#\n" "# ,o, ,o, / \n" "# ` ` e88~88e d88~\\ /~~~8e Y88b e / \n" @@ -69,9 +69,9 @@ "# 88P 888 Cb \\_88P \"8b_-888 Y Y \n" "# \\_8\" Y8\"\"8D \n" "#\n" - "#------------------------------------------------------------\n" + "#-----------------------------------------------------------------------\n" "# MARCHE: \"fast-marching\" eikonal equation solver. \n" - "#------------------------------------------------------------\n" + "#-----------------------------------------------------------------------\n" " \n" " " __JGSWVSTR "\n\n" ; @@ -326,7 +326,7 @@ _retv = -2 ; std::cout << - "run marche jigname.jig"; + "Usage: marche user-opts.jig" ; std::cout << std::endl ; break ; @@ -362,6 +362,11 @@ break ; } } + if (_retv == -1) + { + std::cout << + "**parse error: *.jig file not found!" << std::endl; + } if (_retv != +0) return ( _retv ) ; /*--------------------------------- setup *.JLOG file */ diff --git a/src/msh_save.inc b/src/msh_save.inc index f879dd8..3d840c2 100644 --- a/src/msh_save.inc +++ b/src/msh_save.inc @@ -35,9 +35,9 @@ * -------------------------------------------------------- * - * Last updated: 30 May, 2022 + * Last updated: 05 Dec, 2024 * - * Copyright 2013-2022 + * Copyright 2013-2024 * Darren Engwirda * d.engwirda@gmail.com * https://github.com/dengwirda/ @@ -69,8 +69,8 @@ _nmap[_npos ] >= 0 ) \ { \ PRINTCHARS(snprintf(&_fbuf[_next] , \ - PRINTCHUNK, \ - "%.17g;%.17g;%d\n" , \ + PRINTCHUNK- _next , \ + "%.17g;%.17g;%d\n", \ _iter->pval(0) + _xoff[0] , \ _iter->pval(1) + _xoff[1] , \ _iter->itag()) , VERT2CHUNK ) \ @@ -94,7 +94,7 @@ _nmap[_npos ] >= 0 ) \ { \ PRINTCHARS(snprintf(&_fbuf[_next] , \ - PRINTCHUNK, \ + PRINTCHUNK- _next , \ "%.17g;%.17g;%.17g;%d\n", \ _iter->pval(0) + _xoff[0] , \ _iter->pval(1) + _xoff[1] , \ @@ -120,7 +120,8 @@ _nmap[_npos ] >= 0) \ { \ PRINTCHARS(snprintf(&_fbuf[_next] , \ - PRINTCHUNK, "%.17g\n" , \ + PRINTCHUNK- _next , \ + "%.17g\n" , \ _iter->pval(_koff) ), VALUECHUNK) \ } \ } \ @@ -141,7 +142,8 @@ _iter->self() >= 1 ) \ { \ PRINTCHARS(snprintf(&_fbuf[_next] , \ - PRINTCHUNK, "%u;%u;%d\n", \ + PRINTCHUNK- _next , \ + "%u;%u;%d\n", \ _nmap[_iter->node(0)] , \ _nmap[_iter->node(1)] , \ _iter->itag()), EDGE2CHUNK) \ @@ -164,7 +166,8 @@ _iter->self() >= 1 ) \ { \ PRINTCHARS(snprintf(&_fbuf[_next] , \ - PRINTCHUNK, "%u;%u;%u;%d\n", \ + PRINTCHUNK- _next , \ + "%u;%u;%u;%d\n", \ _nmap[_iter->node(0)] , \ _nmap[_iter->node(1)] , \ _nmap[_iter->node(2)] , \ @@ -188,7 +191,7 @@ _iter->self() >= 1 ) \ { \ PRINTCHARS(snprintf(&_fbuf[_next] , \ - PRINTCHUNK, \ + PRINTCHUNK- _next , \ "%u;%u;%u;%u;%d\n", \ _nmap[_iter->node(0)] , \ _nmap[_iter->node(1)] , \ @@ -214,7 +217,7 @@ _iter->self() >= 1 ) \ { \ PRINTCHARS(snprintf(&_fbuf[_next] , \ - PRINTCHUNK, \ + PRINTCHUNK- _next , \ "%u;%u;%u;%u;%d\n", \ _nmap[_iter->node(0)] , \ _nmap[_iter->node(1)] , \ diff --git a/src/rdt_save.inc b/src/rdt_save.inc index 32e4f24..e6f5965 100644 --- a/src/rdt_save.inc +++ b/src/rdt_save.inc @@ -35,9 +35,9 @@ * -------------------------------------------------------- * - * Last updated: 30 May, 2022 + * Last updated: 05 Dec, 2024 * - * Copyright 2013-2022 + * Copyright 2013-2024 * Darren Engwirda * d.engwirda@gmail.com * https://github.com/dengwirda/ @@ -69,7 +69,7 @@ _nmap[_npos ] >= 0) \ { \ PRINTCHARS(snprintf(&_fbuf[_next], \ - PRINTCHUNK, \ + PRINTCHUNK- _next , \ "%.17g;%.17g;%d\n", \ _iter->pval(0) + _xoff[0] , \ _iter->pval(1) + _xoff[1] , \ @@ -94,7 +94,7 @@ _nmap[_npos ] >= 0) \ { \ PRINTCHARS(snprintf(&_fbuf[_next], \ - PRINTCHUNK, \ + PRINTCHUNK- _next , \ "%.17g;%.17g;%.17g;%d\n", \ _iter->pval(0) + _xoff[0] , \ _iter->pval(1) + _xoff[1] , \ @@ -120,7 +120,8 @@ _nmap[_npos ] >= 0) \ { \ PRINTCHARS(snprintf(&_fbuf[_next], \ - PRINTCHUNK, "%.17g\n" , \ + PRINTCHUNK- _next , \ + "%.17g\n" , \ _iter->pval(_koff) ), VALUECHUNK) \ } \ } \ @@ -144,7 +145,8 @@ _item = _item->_next ) \ { \ PRINTCHARS(snprintf(&_fbuf[_next], \ - PRINTCHUNK, "%u;%u;%d\n", \ + PRINTCHUNK- _next , \ + "%u;%u;%d\n", \ _nmap[_item->_data._node[0]], \ _nmap[_item->_data._node[1]], \ _item->_data._part ), EDGE2CHUNK) \ @@ -170,7 +172,8 @@ _item = _item->_next ) \ { \ PRINTCHARS(snprintf(&_fbuf[_next], \ - PRINTCHUNK, "%u;%u;%u;%d\n", \ + PRINTCHUNK- _next , \ + "%u;%u;%u;%d\n", \ _nmap[_item->_data._node[0]], \ _nmap[_item->_data._node[1]], \ _nmap[_item->_data._node[2]], \ @@ -197,7 +200,7 @@ _item = _item->_next ) \ { \ PRINTCHARS(snprintf(&_fbuf[_next], \ - PRINTCHUNK, \ + PRINTCHUNK- _next , \ "%u;%u;%u;%u;%d\n", \ _nmap[_item->_data._node[0]], \ _nmap[_item->_data._node[1]], \ @@ -484,11 +487,11 @@ {"vert2_row", "vert2_col"} ) ; \ ncutil::def_var( \ _jcfg._mesh_file, "vert2_tag", NC_INT, \ - "2-vertex id-tags" , \ + "2-vertex ID integers" , \ {"vert2_row", "singleton"} ) ; \ ncutil::def_var( \ _jcfg._mesh_file, "power_val", NC_DOUBLE, \ - "vertex power values" , \ + "vertex power weights" , \ {"vert2_row", "singleton"} ) ; \ \ _pos.clear(); _pos.set_alloc(_last * 2); \ diff --git a/src/tri_save.inc b/src/tri_save.inc index 0f6a81b..54c994a 100644 --- a/src/tri_save.inc +++ b/src/tri_save.inc @@ -35,9 +35,9 @@ * -------------------------------------------------------- * - * Last updated: 30 May, 2022 + * Last updated: 05 Dec, 2024 * - * Copyright 2013-2022 + * Copyright 2013-2024 * Darren Engwirda * d.engwirda@gmail.com * https://github.com/dengwirda/ @@ -69,7 +69,7 @@ _nmap[_npos ] >= 0) \ { \ PRINTCHARS(snprintf(&_fbuf[_next], \ - PRINTCHUNK, \ + PRINTCHUNK- _next , \ "%.17g;%.17g;+0\n", \ _iter->pval(0) + _xoff[0] , \ _iter->pval(1) + _xoff[1]), \ @@ -94,7 +94,7 @@ _nmap[_npos ] >= 0) \ { \ PRINTCHARS(snprintf(&_fbuf[_next], \ - PRINTCHUNK, \ + PRINTCHUNK- _next , \ "%.17g;%.17g;%.17g;+0\n", \ _iter->pval(0) + _xoff[0] , \ _iter->pval(1) + _xoff[1] , \ @@ -120,7 +120,8 @@ _nmap[_npos ] >= 0) \ { \ PRINTCHARS(snprintf(&_fbuf[_next] , \ - PRINTCHUNK, "%.17g\n" , \ + PRINTCHUNK- _next , \ + "%.17g\n" , \ _iter->pval(_koff) ), VALUECHUNK) \ } \ } \ @@ -140,7 +141,8 @@ if (_iter->mark() < +0) continue ; \ \ PRINTCHARS(snprintf(&_fbuf[_next], \ - PRINTCHUNK, "%u;%u;%u;+0\n", \ + PRINTCHUNK- _next , \ + "%u;%u;%u;+0\n", \ _nmap[_iter->node(0)] , \ _nmap[_iter->node(1)] , \ _nmap[_iter->node(2)]),TRIA3CHUNK) \ @@ -161,7 +163,7 @@ if (_iter->mark() < +0) continue ; \ \ PRINTCHARS(snprintf(&_fbuf[_next], \ - PRINTCHUNK, \ + PRINTCHUNK- _next , \ "%u;%u;%u;%u;+0\n", \ _nmap[_iter->node(0)] , \ _nmap[_iter->node(1)] , \ diff --git a/src/tripod.hpp b/src/tripod.hpp index 608bc9a..2d76e5b 100644 --- a/src/tripod.hpp +++ b/src/tripod.hpp @@ -59,7 +59,7 @@ std::string asciibanner = " \n" - "#------------------------------------------------------------\n" + "#-----------------------------------------------------------------------\n" "#\n" "# ,o, ,o, / \n" "# ` ` e88~88e d88~\\ /~~~8e Y88b e / \n" @@ -69,9 +69,9 @@ "# 88P 888 Cb \\_88P \"8b_-888 Y Y \n" "# \\_8\" Y8\"\"8D \n" "#\n" - "#------------------------------------------------------------\n" + "#-----------------------------------------------------------------------\n" "# TRIPOD: a \"restricted\" delaunay tessellator. \n" - "#------------------------------------------------------------\n" + "#-----------------------------------------------------------------------\n" " \n" " " __JGSWVSTR "\n\n" ; @@ -619,7 +619,7 @@ _retv = -2 ; std::cout << - "run tripod jigname.jig"; + "Usage: tripod user-opts.jig" ; std::cout << std::endl ; break ; @@ -655,6 +655,11 @@ break ; } } + if (_retv == -1) + { + std::cout << + "**parse error: *.jig file not found!" << std::endl; + } if (_retv != +0) return ( _retv ) ; /*--------------------------------- setup *.JLOG file */ diff --git a/uni/CMakeLists.txt b/uni/CMakeLists.txt index 01f2a1b..d29307e 100644 --- a/uni/CMakeLists.txt +++ b/uni/CMakeLists.txt @@ -126,6 +126,11 @@ target_link_libraries (test2d_h ${LIBJIGSAW}) set_target_properties(test2d_h PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE) install (TARGETS test2d_h DESTINATION "${PROJECT_SOURCE_DIR}") +add_executable (test3d_h test3d_h.c) +target_link_libraries (test3d_h ${LIBJIGSAW}) +set_target_properties(test3d_h PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE) +install (TARGETS test3d_h DESTINATION "${PROJECT_SOURCE_DIR}") + add_executable (test2s_h test2s_h.c) target_link_libraries (test2s_h ${LIBJIGSAW}) set_target_properties(test2s_h PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE) @@ -136,6 +141,11 @@ target_link_libraries (test2d_i ${LIBJIGSAW}) set_target_properties(test2d_i PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE) install (TARGETS test2d_i DESTINATION "${PROJECT_SOURCE_DIR}") +add_executable (test3d_i test3d_i.c) +target_link_libraries (test3d_i ${LIBJIGSAW}) +set_target_properties(test3d_i PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE) +install (TARGETS test3d_i DESTINATION "${PROJECT_SOURCE_DIR}") + add_executable (test2s_i test2s_i.c) target_link_libraries (test2s_i ${LIBJIGSAW}) set_target_properties(test2s_i PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE) diff --git a/uni/test2d_a.c b/uni/test2d_a.c index 4ab02c4..4e4c7c1 100644 --- a/uni/test2d_a.c +++ b/uni/test2d_a.c @@ -94,6 +94,8 @@ printf ( "[2d_a] JIGSAW returned code : %d \n", _retv) ; + fflush (stdout) ; + return _retv ; } diff --git a/uni/test2d_b.c b/uni/test2d_b.c index 4bb2860..11a94a5 100644 --- a/uni/test2d_b.c +++ b/uni/test2d_b.c @@ -147,6 +147,8 @@ printf ( "[2d_b] JIGSAW returned code : %d \n", _retv) ; + fflush (stdout) ; + return _retv ; } diff --git a/uni/test2d_c.c b/uni/test2d_c.c index d825b8e..f8a2cbd 100644 --- a/uni/test2d_c.c +++ b/uni/test2d_c.c @@ -158,6 +158,8 @@ printf ( "[2d_c] JIGSAW returned code : %d \n", _retv) ; + fflush (stdout) ; + return _retv ; } diff --git a/uni/test2d_d.c b/uni/test2d_d.c index fb8872a..5c9912d 100644 --- a/uni/test2d_d.c +++ b/uni/test2d_d.c @@ -123,6 +123,8 @@ printf ( "[2d_d] JIGSAW returned code : %d \n", _retv) ; + fflush (stdout) ; + return _retv ; } diff --git a/uni/test2d_e.c b/uni/test2d_e.c index 5055250..b6d7981 100644 --- a/uni/test2d_e.c +++ b/uni/test2d_e.c @@ -122,6 +122,8 @@ printf ( "[2d_e] JIGSAW returned code : %d \n", _retv) ; + fflush (stdout) ; + return _retv ; } diff --git a/uni/test2d_f.c b/uni/test2d_f.c index 7c4d8f7..d59995d 100644 --- a/uni/test2d_f.c +++ b/uni/test2d_f.c @@ -115,6 +115,8 @@ printf ( "[2d_f] TRIPOD returned code : %d \n", _retv) ; + fflush (stdout) ; + return _retv ; } diff --git a/uni/test2d_g.c b/uni/test2d_g.c index b4634b0..ed3612b 100644 --- a/uni/test2d_g.c +++ b/uni/test2d_g.c @@ -67,6 +67,8 @@ printf ( "[2d_g] TRIPOD returned code : %d \n", _retv) ; + fflush (stdout) ; + return _retv ; } diff --git a/uni/test2d_h.c b/uni/test2d_h.c index efff8f2..a6a2f4a 100644 --- a/uni/test2d_h.c +++ b/uni/test2d_h.c @@ -104,6 +104,8 @@ printf ( "[2d_h] MARCHE returned code : %d \n", _retv) ; + fflush (stdout) ; + return _retv ; } diff --git a/uni/test2d_i.c b/uni/test2d_i.c index fad73b9..de7f000 100644 --- a/uni/test2d_i.c +++ b/uni/test2d_i.c @@ -107,6 +107,8 @@ printf ( "[2d_i] MARCHE returned code : %d \n", _retv) ; + fflush (stdout) ; + return _retv ; } diff --git a/uni/test2s_a.c b/uni/test2s_a.c index 9df3b39..3e16587 100644 --- a/uni/test2s_a.c +++ b/uni/test2s_a.c @@ -62,6 +62,8 @@ printf ( "[2s_a] JIGSAW returned code : %d \n", _retv) ; + fflush (stdout) ; + return _retv ; } diff --git a/uni/test2s_b.c b/uni/test2s_b.c index 0e0446e..760742c 100644 --- a/uni/test2s_b.c +++ b/uni/test2s_b.c @@ -121,6 +121,8 @@ printf ( "[2s_b] JIGSAW returned code : %d \n", _retv) ; + fflush (stdout) ; + return _retv ; } diff --git a/uni/test2s_c.c b/uni/test2s_c.c index 46b5753..27b0a65 100644 --- a/uni/test2s_c.c +++ b/uni/test2s_c.c @@ -114,6 +114,8 @@ printf ( "[2s_c] JIGSAW returned code : %d \n", _retv) ; + fflush (stdout) ; + return _retv ; } diff --git a/uni/test2s_e.c b/uni/test2s_e.c index 3907110..98ce7ff 100644 --- a/uni/test2s_e.c +++ b/uni/test2s_e.c @@ -96,6 +96,8 @@ printf ( "[2s_e] JIGSAW returned code : %d \n", _retv) ; + fflush (stdout) ; + return _retv ; } diff --git a/uni/test2s_f.c b/uni/test2s_f.c index 1215547..aa85fa8 100644 --- a/uni/test2s_f.c +++ b/uni/test2s_f.c @@ -98,6 +98,8 @@ printf ( "[2s_f] TRIPOD returned code : %d \n", _retv) ; + fflush (stdout) ; + return _retv ; } diff --git a/uni/test2s_g.c b/uni/test2s_g.c index f374848..7e7587f 100644 --- a/uni/test2s_g.c +++ b/uni/test2s_g.c @@ -90,6 +90,8 @@ printf ( "[2s_g] TRIPOD returned code : %d \n", _retv) ; + fflush (stdout) ; + return _retv ; } diff --git a/uni/test2s_h.c b/uni/test2s_h.c index 04cd9a4..e605aa0 100644 --- a/uni/test2s_h.c +++ b/uni/test2s_h.c @@ -94,6 +94,8 @@ printf ( "[2s_h] MARCHE returned code : %d \n", _retv) ; + fflush (stdout) ; + return _retv ; } diff --git a/uni/test2s_i.c b/uni/test2s_i.c index 3fd6921..bb56424 100644 --- a/uni/test2s_i.c +++ b/uni/test2s_i.c @@ -103,6 +103,8 @@ printf ( "[2s_i] MARCHE returned code : %d \n", _retv) ; + fflush (stdout) ; + return _retv ; } diff --git a/uni/test3d_a.c b/uni/test3d_a.c index 74c9858..74c8409 100644 --- a/uni/test3d_a.c +++ b/uni/test3d_a.c @@ -91,6 +91,8 @@ printf ( "[3d_a] JIGSAW returned code : %d \n", _retv) ; + fflush (stdout) ; + return _retv ; } diff --git a/uni/test3d_b.c b/uni/test3d_b.c index 5778858..70cdb24 100644 --- a/uni/test3d_b.c +++ b/uni/test3d_b.c @@ -130,6 +130,8 @@ printf ( "[3d_b] JIGSAW returned code : %d \n", _retv) ; + fflush (stdout) ; + return _retv ; } diff --git a/uni/test3d_c.c b/uni/test3d_c.c index df498b8..9ae3d82 100644 --- a/uni/test3d_c.c +++ b/uni/test3d_c.c @@ -147,6 +147,8 @@ printf ( "[3d_c] JIGSAW returned code : %d \n", _retv) ; + fflush (stdout) ; + return _retv ; } diff --git a/uni/test3d_d.c b/uni/test3d_d.c index d60a87d..6716cef 100644 --- a/uni/test3d_d.c +++ b/uni/test3d_d.c @@ -31,21 +31,21 @@ jigsaw_VERT3_t _geom_vert3[16] = { // setup geom. { {0., 0., 0.}, +0 } , // outer cube - { {3., 0., 0.}, +0 } , - { {3., 3., 0.}, +0 } , - { {0., 3., 0.}, +0 } , - { {0., 0., 3.}, +0 } , - { {3., 0., 3.}, +0 } , + { {5., 0., 0.}, +0 } , + { {5., 5., 0.}, +0 } , + { {0., 5., 0.}, +0 } , + { {0., 0., 5.}, +0 } , + { {5., 0., 5.}, +0 } , + { {5., 5., 5.}, +0 } , + { {0., 5., 5.}, +0 } , + { {2., 2., 2.}, +0 } , // inner cube + { {3., 2., 2.}, +0 } , + { {3., 3., 2.}, +0 } , + { {2., 3., 2.}, +0 } , + { {2., 2., 3.}, +0 } , + { {3., 2., 3.}, +0 } , { {3., 3., 3.}, +0 } , - { {0., 3., 3.}, +0 } , - { {1., 1., 1.}, +0 } , // inner cube - { {2., 1., 1.}, +0 } , - { {2., 2., 1.}, +0 } , - { {1., 2., 1.}, +0 } , - { {1., 1., 2.}, +0 } , - { {2., 1., 2.}, +0 } , - { {2., 2., 2.}, +0 } , - { {1., 2., 2.}, +0 } , + { {2., 3., 3.}, +0 } , } ; jigsaw_TRIA3_t _geom_tria3[24] = { @@ -130,12 +130,12 @@ _jjig._verbosity = _verb; - _jjig._hfun_hmax = 3./3.; + _jjig._hfun_hmax = 1./2.; _jjig._hfun_scal = JIGSAW_HFUN_RELATIVE; _jjig._mesh_rad2 = 1.50 ; - _jjig._mesh_rad3 = 2.50 ; + _jjig._mesh_rad3 = 4.00 ; _jjig._geom_feat = +1 ; // do "sharp" geom. _jjig._mesh_top1 = +1 ; @@ -162,6 +162,8 @@ printf ( "[3d_d] JIGSAW returned code : %d \n", _retv) ; + fflush (stdout) ; + return _retv ; } diff --git a/uni/test3d_e.c b/uni/test3d_e.c index 9581b57..f8e685f 100644 --- a/uni/test3d_e.c +++ b/uni/test3d_e.c @@ -117,6 +117,8 @@ printf ( "[3d_e] JIGSAW returned code : %d \n", _retv) ; + fflush (stdout) ; + return _retv ; } diff --git a/uni/test3d_f.c b/uni/test3d_f.c index ed44b6f..09d372b 100644 --- a/uni/test3d_f.c +++ b/uni/test3d_f.c @@ -109,6 +109,8 @@ printf ( "[3d_f] TRIPOD returned code : %d \n", _retv) ; + fflush (stdout) ; + return _retv ; } diff --git a/uni/test3d_g.c b/uni/test3d_g.c index 559ce54..649006d 100644 --- a/uni/test3d_g.c +++ b/uni/test3d_g.c @@ -67,6 +67,8 @@ printf ( "[3d_g] TRIPOD returned code : %d \n", _retv) ; + fflush (stdout) ; + return _retv ; } diff --git a/uni/test3d_h.c b/uni/test3d_h.c new file mode 100644 index 0000000..931ef1b --- /dev/null +++ b/uni/test3d_h.c @@ -0,0 +1,109 @@ + +// gcc -Wall -Wextra test3d_h.c -Xlinker -rpath=../lib +// -L ../lib -ljigsaw -o test3d_h + +// Use MARCHE to set "gradient-limits" on mesh-spacing data +// +// ensures: |GRAD(h)| <= slope_limit(x), +// +// via a "fast-marching" solver for the Hamilton-Jacobi eq. + +# include "../inc/lib_jigsaw.h" + +# include "print.h" +# include "stdio.h" + + int test3d_h (int _verb) + { + int _retv = 0; + + /*-------------------------------- setup JIGSAW types */ + jigsaw_jig_t _jjig ; + jigsaw_init_jig_t(&_jjig) ; + + jigsaw_msh_t _hfun ; + jigsaw_init_msh_t(&_hfun) ; + + /*-------------------------------- setup JIGSAW hfun. */ + + real_t _hfun_xgrid[3] = { // setup hfun. + 0., .5, 1. + } ; + + real_t _hfun_ygrid[3] = { + 0., .5, 1. + } ; + + real_t _hfun_zgrid[3] = { + 0., .5, 1. + } ; + + fp32_t _hfun_value[27]= { + 2.f, 2.f, 2.f, 2.f, 1.f, 2.f, 2.f, 2.f, 2.f, + 2.f, 2.f, 2.f, 2.f, 1.f, 2.f, 2.f, 2.f, 2.f, + 2.f, 2.f, 2.f, 2.f, 1.f, 2.f, 2.f, 2.f, 2.f + } ; + + fp32_t _hfun_slope[27]= { + .4f, .4f, .4f, .4f, .1f, .4f, .4f, .4f, .4f, + .4f, .4f, .4f, .4f, .1f, .4f, .4f, .4f, .4f, + .4f, .4f, .4f, .4f, .1f, .4f, .4f, .4f, .4f + } ; + + _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._zgrid._data = &_hfun_zgrid[0] ; + _hfun._zgrid._size = +3 ; + + _hfun._value._data = &_hfun_value[0] ; + _hfun._value._size = +27; + + _hfun._slope._data = &_hfun_slope[0] ; + _hfun._slope._size = +27; + + /*-------------------------------- build MARCHE hfun. */ + + _jjig._verbosity = _verb; + + _retv = marche ( + & _jjig , // the config. opts + & _hfun ) ; // the spacing h(x) + + /*-------------------------------- print MARCHE hfun. */ + + if (_verb > 0 ) + { + printf("\n VALUE: \n\n") ; + + for (size_t _ipos = +0; + _ipos != _hfun._value._size ; + ++_ipos ) + { + printf("%1.4f\n", + _hfun._value._data[_ipos] + ) ; + } + } + + printf ( + "[3d_h] MARCHE returned code : %d \n", _retv) ; + + fflush (stdout) ; + + + return _retv ; + } + +# ifndef __SKIP_MAIN__ + int main () { return test3d_h(1) ; } +# endif//__SKIP_MAIN__ + + + diff --git a/uni/test3d_i.c b/uni/test3d_i.c new file mode 100644 index 0000000..94ec2f2 --- /dev/null +++ b/uni/test3d_i.c @@ -0,0 +1,116 @@ + +// gcc -Wall -Wextra test3d_i.c -Xlinker -rpath=../lib +// -L ../lib -ljigsaw -o test3d_i + +// Use MARCHE to set "gradient-limits" on mesh-spacing data +// +// ensures: |GRAD(h)| <= slope_limit(x), +// +// via a "fast-marching" solver for the Hamilton-Jacobi eq. + +# include "../inc/lib_jigsaw.h" + +# include "print.h" +# include "stdio.h" + + int test3d_i (int _verb) + { + int _retv = 0; + + /*-------------------------------- setup JIGSAW types */ + jigsaw_jig_t _jjig ; + jigsaw_init_jig_t(&_jjig) ; + + jigsaw_msh_t _hfun ; + jigsaw_init_msh_t(&_hfun) ; + + /*-------------------------------- setup JIGSAW hfun. */ + + jigsaw_VERT3_t _hfun_vert3[9] = { // setup hfun. + { {.5, .5, 0.}, +0 } , + { {0., 0., 0.}, +0 } , + { {1., 0., 0.}, +0 } , + { {1., 1., 0.}, +0 } , + { {0., 1., 0.}, +0 } , + { {0., 0., 1.}, +0 } , + { {1., 0., 1.}, +0 } , + { {1., 1., 1.}, +0 } , + { {0., 1., 1.}, +0 } , + } ; + + jigsaw_TRIA4_t _hfun_tria4[10] = { + { {0, 5, 2, 1}, +0 } , + { {0, 6, 5, 2}, +0 } , + { {7, 0, 6, 2}, +0 } , + { {7, 0, 3, 2}, +0 } , + { {8, 0, 5, 1}, +0 } , + { {8, 0, 4, 1}, +0 } , + { {8, 0, 6, 5}, +0 } , + { {8, 7, 0, 6}, +0 } , + { {8, 0, 4, 3}, +0 } , + { {8, 7, 0, 3}, +0 } , + } ; + + fp32_t _hfun_value[9]= { + .5f, .5f, .5f, .5f, .5f, + 1.f, 1.f, 1.f, 1.f + } ; + + fp32_t _hfun_slope[1] = { + .1f + } ; + + _hfun._flags + = JIGSAW_EUCLIDEAN_MESH; + + _hfun._vert3._data = &_hfun_vert3[0] ; + _hfun._vert3._size = +9 ; + + _hfun._tria4._data = &_hfun_tria4[0] ; + _hfun._tria4._size = +10; + + _hfun._value._data = &_hfun_value[0] ; + _hfun._value._size = +9 ; + + _hfun._slope._data = &_hfun_slope[0] ; + _hfun._slope._size = +1 ; + + /*-------------------------------- build MARCHE hfun. */ + + _jjig._verbosity = _verb; + + _retv = marche ( + & _jjig , // the config. opts + & _hfun ) ; // the spacing h(x) + + /*-------------------------------- print MARCHE hfun. */ + + if (_verb > 0 ) + { + printf("\n VALUE: \n\n") ; + + for (size_t _ipos = +0; + _ipos != _hfun._value._size ; + ++_ipos ) + { + printf("%1.4f\n", + _hfun._value._data[_ipos] + ) ; + } + } + + printf ( + "[3d_i] MARCHE returned code : %d \n", _retv) ; + + fflush (stdout) ; + + + return _retv ; + } + +# ifndef __SKIP_MAIN__ + int main () { return test3d_i(1) ; } +# endif//__SKIP_MAIN__ + + + diff --git a/uni/test_all.c b/uni/test_all.c index fbbce67..cda5c26 100644 --- a/uni/test_all.c +++ b/uni/test_all.c @@ -33,8 +33,8 @@ # include "test3d_e.c" # include "test3d_f.c" # include "test3d_g.c" -// include "test3d_h.c" -// include "test3d_i.c" +# include "test3d_h.c" +# include "test3d_i.c" int main () { @@ -96,10 +96,10 @@ return _retv ; if ((_retv = test3d_g(_verb)) != 0) return _retv ; - // if ((_retv = test3d_h(_verb)) != 0) - // return _retv ; - // if ((_retv = test3d_i(_verb)) != 0) - // return _retv ; + if ((_retv = test3d_h(_verb)) != 0) + return _retv ; + if ((_retv = test3d_i(_verb)) != 0) + return _retv ; return _retv ; } diff --git a/version.txt b/version.txt index 7934a70..89e5d4e 100644 --- a/version.txt +++ b/version.txt @@ -13,7 +13,15 @@ # JIGSAW: an unstructured mesh generation library #------------------------------------------------------------ + * Version 1.1.0: + ------------- + + - Eikonal solver support for mixed elem. types in + E^2, S^2 and E^3. + + * Version 1.0.0: + ------------- - Initial support for thread-parallelism in optim. phase. From 005bef18b21c0280356ae5f7865dc270633b7d18 Mon Sep 17 00:00:00 2001 From: dengwirda Date: Tue, 12 Aug 2025 18:31:44 +1000 Subject: [PATCH 09/14] Initial pyproject.toml workflow --- build.py | 82 +++++++++++++++++++++++++++++++++++++++++++++++++ pyproject.toml | 36 ++++++++++++++++++++++ setup.py | 83 ++++---------------------------------------------- 3 files changed, 124 insertions(+), 77 deletions(-) create mode 100644 build.py create mode 100644 pyproject.toml diff --git a/build.py b/build.py new file mode 100644 index 0000000..2131bfc --- /dev/null +++ b/build.py @@ -0,0 +1,82 @@ + +import os +import subprocess +import shutil + +HERE = os.path.abspath(os.path.dirname(__file__)) + +def build_external(): +#-- The actual cmake-based build steps for JIGSAW + + cwd_pointer = os.getcwd() + + try: + print("cmake config. for jigsaw...") + + source_path = os.path.join( + HERE, "external", "jigsaw") + + builds_path = \ + os.path.join(source_path, "tmp") + + os.makedirs(builds_path, exist_ok=True) + + exesrc_path = \ + os.path.join(source_path, "bin") + + libsrc_path = \ + os.path.join(source_path, "lib") + + exedst_path = os.path.join( + HERE, "jigsawpy", "_bin") + + libdst_path = os.path.join( + HERE, "jigsawpy", "_lib") + + shutil.rmtree( + exedst_path, ignore_errors=True) + shutil.rmtree( + libdst_path, ignore_errors=True) + + os.chdir(builds_path) + + config_call = [ + "cmake", + "..", "-DCMAKE_BUILD_TYPE=Release"] + + subprocess.run(config_call, check=True) + + print("cmake compile for jigsaw...") + + try: + compilecall = [ + "cmake", "--build", ".", + "--config", "Release", + "--target", "install", + "--parallel", "4" + ] + subprocess.run( + compilecall, check=True) + + except: + compilecall = [ + "cmake", "--build", ".", + "--config", "Release", + "--target", "install" + ] + subprocess.run( + compilecall, check=True) + + print("cmake cleanup for jigsaw...") + + shutil.copytree(exesrc_path, exedst_path) + shutil.copytree(libsrc_path, libdst_path) + + finally: + os.chdir(cwd_pointer) + + shutil.rmtree(builds_path) + + +if (__name__ == "__main__"): build_external() + diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..bda84de --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,36 @@ +[build-system] +requires = ["setuptools"] +build-backend = "setuptools.build_meta" + +[project] +name = "jigsawpy" +version = "1.1.0" +description = "Python interface for the JIGSAW meshing library." +readme = "README.md" +authors = [ + { name = "Darren Engwirda", email = "d.engwirda@gmail.com" }, +] +requires-python = ">=3.6.0" +keywords = ["Mesh-generation", "Delaunay", "Voronoi"] +license-files = ["LICENSE.md"] +dependencies = ["numpy", "scipy"] +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Operating System :: OS Independent", + "Intended Audience :: Science/Research", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: C++", + "Topic :: Scientific/Engineering", + "Topic :: Scientific/Engineering :: Mathematics", + "Topic :: Scientific/Engineering :: Physics", + "Topic :: Scientific/Engineering :: Visualization" +] + +[project.urls] +homepage = "https://dengwirda.github.io/" +source = "https://github.com/dengwirda/jigsaw-python/" + +[tool.setuptools.package-data] +"jigsawpy" = ["_bin/*", "_lib/*"] + diff --git a/setup.py b/setup.py index 0992fa9..0bc53fd 100644 --- a/setup.py +++ b/setup.py @@ -1,11 +1,12 @@ import io import os -import subprocess -import shutil - from setuptools import setup, find_packages, Command +#-- old setup.py workflow for backwards compatibility +#-- python setup.py build_external +#-- python setup.py install + NAME = "jigsawpy" DESCRIPTION = \ "Python interface for the JIGSAW meshing library." @@ -55,80 +56,8 @@ def initialize_options(self): pass def finalize_options(self): pass def run(self): - """ - The actual cmake-based build steps for JIGSAW - - """ if (self.dry_run): return - - cwd_pointer = os.getcwd() - - try: - self.announce("cmake config.", level=3) - - source_path = os.path.join( - HERE, "external", "jigsaw") - - builds_path = \ - os.path.join(source_path, "tmp") - - os.makedirs(builds_path, exist_ok=True) - - exesrc_path = \ - os.path.join(source_path, "bin") - - libsrc_path = \ - os.path.join(source_path, "lib") - - exedst_path = os.path.join( - HERE, "jigsawpy", "_bin") - - libdst_path = os.path.join( - HERE, "jigsawpy", "_lib") - - shutil.rmtree( - exedst_path, ignore_errors=True) - shutil.rmtree( - libdst_path, ignore_errors=True) - - os.chdir(builds_path) - - config_call = [ - "cmake", - "..", "-DCMAKE_BUILD_TYPE=Release"] - - subprocess.run(config_call, check=True) - - self.announce("cmake complie", level=3) - - try: - compilecall = [ - "cmake", "--build", ".", - "--config", "Release", - "--target", "install", - "--parallel", "4" - ] - subprocess.run( - compilecall, check=True) - - except: - compilecall = [ - "cmake", "--build", ".", - "--config", "Release", - "--target", "install" - ] - subprocess.run( - compilecall, check=True) - - self.announce("cmake cleanup", level=3) - - shutil.copytree(exesrc_path, exedst_path) - shutil.copytree(libsrc_path, libdst_path) - - finally: - os.chdir(cwd_pointer) - - shutil.rmtree(builds_path) + import build; build.build_external() setup( @@ -137,7 +66,6 @@ def run(self): description=DESCRIPTION, long_description=LONG_DESCRIPTION, long_description_content_type="text/markdown", - license="custom", author=AUTHOR, author_email=AUTHOR_EMAIL, python_requires=REQUIRES_PYTHON, @@ -149,3 +77,4 @@ def run(self): install_requires=REQUIRED, classifiers=CLASSIFY ) + From 51e1ae5e1aa42c05e0abfe4ae2d4ccf9d6c61e6f Mon Sep 17 00:00:00 2001 From: dengwirda Date: Tue, 12 Aug 2025 18:33:25 +1000 Subject: [PATCH 10/14] Initial pyproject.toml workflow --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c738055..03f1411 100644 --- a/README.md +++ b/README.md @@ -19,8 +19,8 @@ This package provides a `Python` based scrip Ensure you have a c++ compiler and the cmake utility installed. Clone/download + unpack this repository. - python3 setup.py build_external - python3 setup.py install + python3 build.py + pip3 install . python3 example.py --IDnumber=0 Note: installation of `JIGSAW` requires a `c++` compiler and the `cmake` utility. @@ -29,7 +29,7 @@ Note: installation of `JIGSAW` requires a `c++` compiler and the `cmake` utility See `jigsawpy` for a description of the various functions available. - setup.py - compile and install JIGSAW's c++ backend using cmake. + build.py - compile and install JIGSAW's c++ backend using cmake. example.py - a list of demo programs. jigsaw.py - cmd-line interface to JIGSAW's backend From 0d1b1a9bda2ee7a5889889683811c2b6bc999422 Mon Sep 17 00:00:00 2001 From: dengwirda Date: Tue, 12 Aug 2025 18:35:23 +1000 Subject: [PATCH 11/14] Initial pyproject.toml workflow --- .github/workflows/setup.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/setup.yml b/.github/workflows/setup.yml index c48ef93..432c3fd 100644 --- a/.github/workflows/setup.yml +++ b/.github/workflows/setup.yml @@ -57,7 +57,9 @@ jobs: pip install -r requirements.txt - name: Build jigsaw-python - run: python setup.py build_external install + run: | + python build.py + pip install . - name: Eval. jigsaw-python run: python example.py --IDnumber=-1 From 1c4635928231af46fab8118dd303f2d269ac0f1b Mon Sep 17 00:00:00 2001 From: dengwirda Date: Tue, 12 Aug 2025 18:41:13 +1000 Subject: [PATCH 12/14] Update multigrid refinement --- jigsawpy/jigsaw.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/jigsawpy/jigsaw.py b/jigsawpy/jigsaw.py index 378fee6..d44acfa 100644 --- a/jigsawpy/jigsaw.py +++ b/jigsawpy/jigsaw.py @@ -309,13 +309,15 @@ def jitter(opts, imax, ibad, mesh=None): init = jigsaw_msh_t() if (mesh.point is not None): init.point = mesh.point[keep] - if (mesh.power is not None): + + if (mesh.power is not None and + mesh.power.size == + mesh.point.size): init.power = mesh.power[keep] savemsh(OPTS.init_file, init) #------------------------------ call JIGSAW with new ICs - print("optm_dual:", OPTS.optm_dual) jigsaw (OPTS, mesh) # noqa return From 0de05275a0134d72268e461a1b58ba03230a1e95 Mon Sep 17 00:00:00 2001 From: dengwirda Date: Tue, 12 Aug 2025 19:03:58 +1000 Subject: [PATCH 13/14] Defer libjigsaw init., to isolate loadlibrary issues --- jigsawpy/__init__.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/jigsawpy/__init__.py b/jigsawpy/__init__.py index 884f8ea..4fb3d5d 100644 --- a/jigsawpy/__init__.py +++ b/jigsawpy/__init__.py @@ -13,7 +13,7 @@ * JIGSAW: Interface to the JIGSAW meshing library. ------------------------------------------------------------ * - * Last updated: 04 Aug., 2025 + * Last updated: 10 Aug., 2025 * * Copyright 2019-2025 * Darren Engwirda @@ -59,7 +59,7 @@ from jigsawpy.def_t import jigsaw_def_t from jigsawpy.prj_t import jigsaw_prj_t -from jigsawpy import jigsaw, libsaw +from jigsawpy import jigsaw from jigsawpy.loadmsh import loadmsh from jigsawpy.savemsh import savemsh @@ -135,18 +135,18 @@ class lib: @staticmethod def jigsaw(opts, geom, mesh, init=None, hfun=None): - + from jigsawpy import libsaw return libsaw.jigsaw(opts, geom, mesh, init, hfun) @staticmethod def tripod(opts, init, tria, geom=None): - + from jigsawpy import libsaw return libsaw.tripod(opts, init, tria, geom) @staticmethod def marche(opts, ffun): - + from jigsawpy import libsaw return libsaw.marche(opts, ffun) From e4b2c370077fb8e5dac69b8d0995b166c987e837 Mon Sep 17 00:00:00 2001 From: dengwirda Date: Tue, 12 Aug 2025 19:20:59 +1000 Subject: [PATCH 14/14] Bump python=3.12 in CI workflows --- .github/workflows/setup.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/setup.yml b/.github/workflows/setup.yml index 432c3fd..2a1e522 100644 --- a/.github/workflows/setup.yml +++ b/.github/workflows/setup.yml @@ -12,7 +12,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, macos-latest, windows-latest] - python-version: ["3.10"] + python-version: ["3.12"] steps: - uses: actions/checkout@v3