diff --git a/README.md b/README.md index ac187e7..ce2b43c 100644 --- a/README.md +++ b/README.md @@ -7,15 +7,15 @@

-`JIGSAW` is a computational library for unstructured mesh generation and tessellation; 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 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. -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. +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` has been compiled and tested on various `64-bit` `Linux`, `Windows` and `MacOS` based platforms. ### `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 written as a `header-only` library in `c++`. Both a basic command-line interface and a `c`-format `API` are defined: JIGSAW:: ├── src -- JIGSAW src code @@ -32,26 +32,25 @@ The first step is to compile and configure the code! `JIGSAW` can either be buil ### `Building from src` -The full `JIGSAW` src can be found in `../jigsaw/src/`. It has been built using various `C++11` conforming versions of the `g++`, `clang++` and `msvc` compilers. +The full `JIGSAW` src can be found in `../jigsaw/src/`. It has been built using various `c++11` 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`. +`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: - * Ensure you have the cmake utility installed. * Clone or download this repository. * Navigate to the root `../jigsaw/` directory. * Make a new temporary directory BUILD. * cd build - * cmake .. -D CMAKE_BUILD_TYPE=BUILD_MODE + * cmake .. -DCMAKE_BUILD_TYPE=BUILD_MODE * cmake --build . --config BUILD_MODE --target install * Delete the temporary BUILD directory. -This process will build a series of executables and shared libraries: `jigsaw` itself - the main command-line meshing utility, `tripod` - `JIGSAW`'s tessellation infrastructure, 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`. +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`. `BUILD_MODE` can be used to select different compiler configurations and should generally either be `Release` or `Debug`. See `example.jig` for documentation on calling the command-line executables, and the headers in `../jigsaw/inc/` for details on the `API`. @@ -92,7 +91,7 @@ The unit-tests can be built using the `cmake` u * Navigate to the `../jigsaw/uni/` directory. * Make a new temporary directory BUILD. * cd build - * cmake .. -D CMAKE_BUILD_TYPE=BUILD_MODE + * cmake .. -DCMAKE_BUILD_TYPE=BUILD_MODE * cmake --build . --config BUILD_MODE --target install * Delete the temporary BUILD directory. diff --git a/example.jig b/example.jig index 50bd164..d168a19 100644 --- a/example.jig +++ b/example.jig @@ -298,6 +298,17 @@ # ---------------------- # +# ---> OPTM_KERN - {default='odt+dqdx'} mesh optimisation +# kernel, choice of an Optimal Delaunay Tessellation +# strategy (KERN='odt+dqdx') or a Centroidal Voronoi +# Tessellation method (KERN='cvt+dqdx'). In both +# cases a hybrid formulation is employed, using a +# "blend" of the ODT/CVT updates, and gradients of a +# "fall-back" mesh quality function Q. + +# OPTM_KERN = CVT+DQDX + + # ---> OPTM_ITER - {default=16} max. number of mesh optim- # isation iterations. Set ITER=N to see progress after # N iterations. diff --git a/geo/fandisk.msh b/geo/fandisk.msh deleted file mode 100644 index 29e29c2..0000000 --- a/geo/fandisk.msh +++ /dev/null @@ -1,19426 +0,0 @@ -# fandisk.msh geometry file -mshid=1 -ndims=3 -point=6475 -0.1696;0.04095;-0.0471;0 -0.1809;0.03455;-0.046;0 -0.1628;0.03455;-0.046;0 -0.1539;0.04355;-0.0475;0 -0.1651;0.05375;-0.0494;0 -0.1811;0.05105;-0.0489;0 -0.1952;0.04725;-0.0482;0 -0.1949;0.05065;-0.0275;0 -0.1813;0.03875;-0.0237;0 -0.1666;0.02125;-0.0389;0 -0.1585;0.02595;-0.0412;0 -0.1446;0.03455;-0.046;0 -0.1367;0.04495;-0.0478;0 -0.148;0.05595;-0.0497;0 -0.1604;0.06725;-0.0517;0 -0.1778;0.06475;-0.0513;0 -0.1944;0.06205;-0.0508;0 -0.2101;0.05925;-0.0503;0 -0.2105;0.06304999999999999;-0.0313;0 -0.2093;0.06565;-0.011;0 -0.1945;0.05355;-0.0089;0 -0.1814;0.04205;-0.0057;0 -0.1668;0.02495;-0.0191;0 -0.1527;0.00675;-0.033;0 -0.142;0.02155;-0.039;0 -0.1264;0.03455;-0.046;0 -0.119;0.04605;-0.048;0 -0.1304;0.05785;-0.0501;0 -0.1427;0.06965;-0.0522;0 -0.1557;0.08144999999999999;-0.0542;0 -0.1737;0.07865;-0.0537;0 -0.1915;0.07585;-0.0532;0 -0.2089;0.07305;-0.0528;0 -0.2255;0.07055;-0.0523;0 -0.2256;0.07405;-0.0334;0 -0.2248;0.07695;-0.013;0 -0.2247;0.08035;0.006;0 -0.2093;0.06895;0.008;0 -0.1945;0.05685;0.0101;0 -0.1802;0.04415;0.0124;0 -0.1673;0.02835;-0.003;0 -0.1528;0.01005;-0.0147;0 -0.1396;-0.008750000000000001;-0.0287;0 -0.1156;-0.00185;-0.0304;0 -0.1199;0.02535;-0.0409;0 -0.1082;0.03455;-0.046;0 -0.1011;0.04715;-0.0482;0 -0.1126;0.05975;-0.0504;0 -0.1248;0.07224999999999999;-0.0526;0 -0.1376;0.08434999999999999;-0.0547;0 -0.1509;0.09615;-0.0568;0 -0.1693;0.09285;-0.0562;0 -0.1878;0.08964999999999999;-0.0557;0 -0.2061;0.08665;-0.0551;0 -0.2241;0.08375;-0.0546;0 -0.2415;0.08125;-0.0542;0 -0.2415;0.08455;-0.0353;0 -0.2407;0.08765000000000001;-0.0149;0 -0.2407;0.09095;0.0041;0 -0.2358;0.06555;0.0086;0 -0.221;0.05475;0.0105;0 -0.2068;0.04315;0.0125;0 -0.1932;0.03095;0.0147;0 -0.1801;0.01815;0.017;0 -0.1665;0.03065;0.0147;0 -0.1534;0.01375;0.0015;0 -0.141;-0.00105;0.0045;0 -0.1398;-0.00535;-0.0115;0 -0.1274;-0.02215;-0.0092;0 -0.127;-0.02565;-0.0261;0 -0.1081;-0.02565;-0.0261;0 -0.0866;-0.00565;-0.0294;0 -0.1038;0.01495;-0.036;0 -0.11;0.02835;-0.0424;0 -0.0965;0.02515;-0.0407;0 -0.09;0.03455;-0.046;0 -0.083;0.04855;-0.0484;0 -0.09470000000000001;0.06195;-0.0508;0 -0.1068;0.07505000000000001;-0.0531;0 -0.1194;0.08765000000000001;-0.0553;0 -0.1325;0.09975000000000001;-0.0575;0 -0.146;0.11145;-0.0595;0 -0.1647;0.10745;-0.0588;0 -0.1835;0.10375;-0.0582;0 -0.2024;0.10035;-0.0575;0 -0.2213;0.09694999999999999;-0.057;0 -0.2398;0.09375;-0.0564;0 -0.258;0.09105000000000001;-0.0559;0 -0.258;0.09435;-0.037;0 -0.2572;0.09755;-0.0167;0 -0.2572;0.10085;0.0024;0 -0.251;0.07575;0.0068;0 -0.2467;0.05075;0.0112;0 -0.2327;0.04045;0.013;0 -0.2191;0.02945;0.015;0 -0.2061;0.01785;0.017;0 -0.1937;0.00565;0.0192;0 -0.1819;-0.00715;0.0214;0 -0.1677;0.00475;0.0193;0 -0.1535;0.01655;0.0172;0 -0.1412;0.00185;0.0198;0 -0.1296;-0.01335;0.0225;0 -0.1283;-0.01805;0.0061;0 -0.1176;-0.03395;0.008200000000000001;0 -0.1168;-0.03795;-0.0072;0 -0.1166;-0.04135;-0.0245;0 -0.09859999999999999;-0.04185;-0.0245;0 -0.0891;-0.02565;-0.0261;0 -0.0702;-0.02565;-0.0261;0 -0.0693;-0.00485;-0.0296;0 -0.0819;0.009350000000000001;-0.0339;0 -0.0793;0.02165;-0.039;0 -0.07190000000000001;0.03455;-0.046;0 -0.0827;0.04705;-0.0544;0 -0.0867;0.05215;-0.053;0 -0.09619999999999999;0.06235;-0.0584;0 -0.1059;0.07215000000000001;-0.0641;0 -0.1173;0.08265;-0.0717;0 -0.1331;0.09575;-0.0834;0 -0.1485;0.10995;-0.0798;0 -0.16;0.12255;-0.0615;0 -0.179;0.11825;-0.0607;0 -0.1982;0.11425;-0.06;0 -0.2176;0.11045;-0.0593;0 -0.237;0.10665;-0.0587;0 -0.2561;0.10315;-0.0581;0 -0.2749;0.10015;-0.0575;0 -0.2749;0.10345;-0.0386;0 -0.2741;0.10665;-0.0183;0 -0.2741;0.10995;0.0008;0 -0.2668;0.08515;0.0051;0 -0.2612;0.06045;0.0095;0 -0.2575;0.03585;0.0138;0 -0.2442;0.02605;0.0156;0 -0.2313;0.01565;0.0174;0 -0.219;0.00455;0.0193;0 -0.2072;-0.00695;0.0214;0 -0.196;-0.01915;0.0235;0 -0.1853;-0.03175;0.0258;0 -0.1707;-0.02045;0.0238;0 -0.156;-0.00925;0.0218;0 -0.1449;-0.02385;0.0244;0 -0.1345;-0.03885;0.027;0 -0.1188;-0.02915;0.0253;0 -0.1087;-0.04545;0.0282;0 -0.1078;-0.05015;0.0106;0 -0.1071;-0.05415;-0.0052;0 -0.1069;-0.05755;-0.0228;0 -0.0896;-0.05825;-0.0227;0 -0.0803;-0.04205;-0.0244;0 -0.0619;-0.04225;-0.0244;0 -0.0512;-0.02565;-0.0261;0 -0.0516;-0.00295;-0.0301;0 -0.06950000000000001;0.00915;-0.0339;0 -0.0703;0.01785;-0.0373;0 -0.0612;0.02365;-0.04;0 -0.058;0.04425;-0.0524;0 -0.0678;0.05475;-0.0607;0 -0.0785;0.06494999999999999;-0.0706;0 -0.0935;0.05825;-0.0639;0 -0.1042;0.06845;-0.07439999999999999;0 -0.1149;0.07754999999999999;-0.0861;0 -0.1252;0.08555;-0.0988;0 -0.1426;0.10095;-0.1024;0 -0.1505;0.10905;-0.095;0 -0.1619;0.12065;-0.08069999999999999;0 -0.1743;0.13325;-0.0633;0 -0.1937;0.12855;-0.0625;0 -0.2133;0.12415;-0.0617;0 -0.2332;0.11995;-0.061;0 -0.2531;0.11575;-0.0603;0 -0.2728;0.11175;-0.0596;0 -0.2921;0.10835;-0.059;0 -0.2921;0.11165;-0.0401;0 -0.2915;0.11495;-0.0198;0 -0.2915;0.11835;-0.0007;0 -0.283;0.09385;0.0036;0 -0.2762;0.06934999999999999;0.007900000000000001;0 -0.2713;0.04505;0.0122;0 -0.2812;0.02955;0.0149;0 -0.2682;0.02085;0.0165;0 -0.2555;0.01155;0.0181;0 -0.2434;0.00165;0.0199;0 -0.2317;-0.008750000000000001;0.0217;0 -0.2205;-0.01975;0.0236;0 -0.2099;-0.03125;0.0257;0 -0.1998;-0.04325;0.0278;0 -0.1753;-0.04485;0.0281;0 -0.1602;-0.03425;0.0262;0 -0.1503;-0.04865;0.0287;0 -0.1411;-0.06335;0.0313;0 -0.1249;-0.05435;0.0297;0 -0.1161;-0.07035;0.0326;0 -0.0994;-0.06215;0.0311;0 -0.09859999999999999;-0.06685000000000001;0.0132;0 -0.0975;-0.07185;-0.0021;0 -0.098;-0.07425;-0.021;0 -0.08110000000000001;-0.07505000000000001;-0.0209;0 -0.07190000000000001;-0.05865;-0.0227;0 -0.0539;-0.05885;-0.0227;0 -0.0433;-0.04225;-0.0244;0 -0.0323;-0.02565;-0.0261;0 -0.028;0.00185;-0.0315;0 -0.0368;0.01995;-0.0383;0 -0.0553;0.01275;-0.0352;0 -0.0467;0.03255;-0.0448;0 -0.0425;0.05105;-0.0576;0 -0.0546;0.06165;-0.06710000000000001;0 -0.06569999999999999;0.07095;-0.07729999999999999;0 -0.0755;0.07775;-0.0863;0 -0.089;0.07405;-0.0813;0 -0.097;0.08094999999999999;-0.0911;0 -0.1062;0.08845;-0.1043;0 -0.1183;0.09685000000000001;-0.1248;0 -0.135;0.09235;-0.1126;0 -0.1521;0.10645;-0.117;0 -0.1623;0.11735;-0.102;0 -0.1768;0.12855;-0.1002;0 -0.1743;0.13015;-0.08110000000000001;0 -0.189;0.14335;-0.06510000000000001;0 -0.2088;0.13825;-0.06419999999999999;0 -0.2288;0.13345;-0.0634;0 -0.2492;0.12875;-0.0626;0 -0.2696;0.12415;-0.0617;0 -0.2899;0.11975;-0.061;0 -0.3098;0.11575;-0.0603;0 -0.3098;0.11905;-0.0413;0 -0.3093;0.12245;-0.0211;0 -0.3093;0.12585;-0.002;0 -0.2995;0.10175;0.0022;0 -0.2916;0.07765;0.0064;0 -0.2855;0.05355;0.0107;0 -0.2947;0.03765;0.0135;0 -0.3037;0.02165;0.0164;0 -0.291;0.01395;0.0177;0 -0.2786;0.00575;0.0191;0 -0.2667;-0.00305;0.0207;0 -0.2552;-0.01235;0.0223;0 -0.2442;-0.02225;0.0241;0 -0.2337;-0.03265;0.0259;0 -0.2237;-0.04345;0.0278;0 -0.2142;-0.05485;0.0298;0 -0.1903;-0.05565;0.03;0 -0.1659;-0.05855;0.0305;0 -0.1572;-0.07245;0.0329;0 -0.1492;-0.08695;0.0355;0 -0.1327;-0.07854999999999999;0.034;0 -0.125;-0.09404999999999999;0.0368;0 -0.108;-0.08665;0.0354;0 -0.091;-0.07925;0.0341;0 -0.0902;-0.08415;0.0158;0 -0.08939999999999999;-0.08885;-0.0002;0 -0.0898;-0.09125;-0.019;0 -0.07340000000000001;-0.09205000000000001;-0.0189;0 -0.0639;-0.07545;-0.0209;0 -0.0463;-0.07575;-0.0208;0 -0.0357;-0.05895;-0.0227;0 -0.0248;-0.04235;-0.0244;0 -0.0133;-0.02565;-0.0261;0 -0.0106;-0.00485;-0.0296;0 -0.0134;0.01495;-0.0361;0 -0.022;0.02755;-0.042;0 -0.032;0.04025;-0.0496;0 -0.0255;0.05775;-0.0634;0 -0.0384;0.07145;-0.078;0 -0.0571;0.07685;-0.0851;0 -0.0677;0.08044999999999999;-0.0902;0 -0.0801;0.08355;-0.09520000000000001;0 -0.08500000000000001;0.09005000000000001;-0.1075;0 -0.0902;0.09694999999999999;-0.1252;0 -0.1131;0.10145;-0.1436;0 -0.1324;0.09915;-0.1327;0 -0.144;0.09775;-0.1275;0 -0.1607;0.11045;-0.1334;0 -0.1717;0.12105;-0.1214;0 -0.1798;0.12855;-0.1127;0 -0.1891;0.13715;-0.1005;0 -0.1891;0.14025;-0.0828;0 -0.2042;0.15295;-0.0668;0 -0.2242;0.14735;-0.0659;0 -0.2447;0.14215;-0.0649;0 -0.2655;0.13695;-0.064;0 -0.2865;0.13185;-0.0631;0 -0.3074;0.12685;-0.0622;0 -0.3278;0.12235;-0.0614;0 -0.3278;0.12565;-0.0425;0 -0.3274;0.12915;-0.0223;0 -0.3274;0.13245;-0.0032;0 -0.3164;0.10895;0.0009;0 -0.3074;0.08515;0.0051;0 -0.3001;0.06135;0.009299999999999999;0 -0.3085;0.04505;0.0122;0 -0.3168;0.02865;0.0151;0 -0.3055;0.02605;0.0355;0 -0.2928;0.01855;0.0368;0 -0.2805;0.01045;0.0383;0 -0.2687;0.00185;0.0398;0 -0.2575;-0.00705;0.0414;0 -0.2476;-0.01575;0.0429;0 -0.2404;-0.02245;0.0441;0 -0.2312;-0.03175;0.0457;0 -0.2217;-0.04225;0.0476;0 -0.2126;-0.05345;0.0496;0 -0.2053;-0.06655;0.0319;0 -0.1815;-0.06855;0.0322;0 -0.1733;-0.08175;0.0346;0 -0.1657;-0.09544999999999999;0.037;0 -0.1419;-0.10165;0.0381;0 -0.1353;-0.11685;0.0408;0 -0.118;-0.11005;0.0396;0 -0.1007;-0.10345;0.0384;0 -0.0834;-0.09675;0.0372;0 -0.0834;-0.10015;0.0182;0 -0.0828;-0.10455;0.0013;0 -0.0825;-0.10865;-0.0169;0 -0.0663;-0.10945;-0.0168;0 -0.0565;-0.09254999999999999;-0.0189;0 -0.0392;-0.09285;-0.0188;0 -0.0284;-0.07585;-0.0208;0 -0.0174;-0.05905;-0.0227;0 -0.0061;-0.04235;-0.0244;0 --0.0056;-0.02565;-0.0261;0 --0.0056;-0.00605;-0.0293;0 -0.0059;0.00555;-0.0326;0 --0.0025;0.02095;-0.0387;0 -0.0064;0.03465;-0.046;0 -0.0162;0.04645;-0.054;0 -0.0075;0.06325;-0.0688;0 -0.0125;0.07285;-0.07969999999999999;0 -0.0373;0.08155;-0.092;0 -0.0543;0.08355;-0.09520000000000001;0 -0.0682;0.08465;-0.09710000000000001;0 -0.0701;0.09075;-0.109;0 -0.0726;0.09715;-0.1256;0 -0.0743;0.10145;-0.1436;0 -0.09370000000000001;0.10145;-0.1436;0 -0.0921;0.10525;-0.1646;0 -0.1117;0.10635;-0.1713;0 -0.1324;0.10145;-0.1436;0 -0.1518;0.10145;-0.1436;0 -0.1704;0.11485;-0.1511;0 -0.1867;0.12935;-0.1351;0 -0.1899;0.13485;-0.1166;0 -0.2042;0.14665;-0.1022;0 -0.2042;0.14985;-0.08450000000000001;0 -0.2196;0.16195;-0.0684;0 -0.24;0.15585;-0.0674;0 -0.2609;0.15015;-0.0663;0 -0.2822;0.14455;-0.0653;0 -0.3037;0.13875;-0.0643;0 -0.3251;0.13315;-0.0633;0 -0.3462;0.12815;-0.0625;0 -0.3461;0.13145;-0.0435;0 -0.3458;0.13495;-0.0233;0 -0.3458;0.13825;-0.0042;0 -0.3337;0.11525;-0.0002;0 -0.3235;0.09195;0.0039;0 -0.3151;0.06855;0.0081;0 -0.3227;0.05185;0.011;0 -0.3302;0.03505;0.014;0 -0.3185;0.03295;0.0343;0 -0.3069;0.03025;0.0548;0 -0.2943;0.02285;0.0561;0 -0.282;0.01495;0.0575;0 -0.2701;0.00635;0.059;0 -0.2588;-0.00255;0.0606;0 -0.2483;-0.01165;0.0621;0 -0.239;-0.02045;0.06370000000000001;0 -0.2295;-0.03025;0.0654;0 -0.2201;-0.04085;0.0673;0 -0.211;-0.05205;0.0693;0 -0.2038;-0.06515;0.0516;0 -0.1969;-0.07875;0.0341;0 -0.1891;-0.09125;0.0362;0 -0.182;-0.10415;0.0385;0 -0.1587;-0.10945;0.0395;0 -0.1525;-0.12375;0.042;0 -0.1294;-0.13225;0.0435;0 -0.1119;-0.12625;0.0424;0 -0.09429999999999999;-0.12045;0.0414;0 -0.0766;-0.11465;0.0404;0 -0.0766;-0.11795;0.0213;0 -0.0762;-0.12235;0.0033;0 -0.0759;-0.12645;-0.0146;0 -0.0601;-0.12705;-0.0145;0 -0.0497;-0.10985;-0.0167;0 -0.0327;-0.11015;-0.0167;0 -0.0217;-0.09304999999999999;-0.0188;0 -0.0105;-0.07595;-0.0208;0 --0.0009;-0.05915;-0.0226;0 --0.0125;-0.04235;-0.0244;0 --0.0245;-0.02565;-0.0261;0 --0.0245;-0.00645;-0.0292;0 --0.0233;0.008449999999999999;-0.0336;0 --0.0058;0.00675;-0.033;0 --0.0179;0.02615;-0.0413;0 --0.0092;0.04275;-0.0513;0 -0.0004;0.05475;-0.0607;0 --0.0028;0.06575;-0.07140000000000001;0 --0.0047;0.07275;-0.0796;0 --0.0052;0.08144999999999999;-0.0919;0 -0.0148;0.08175;-0.0924;0 -0.0355;0.08975;-0.1069;0 -0.0549;0.09095;-0.1095;0 -0.0549;0.09685000000000001;-0.1248;0 -0.0549;0.10145;-0.1436;0 -0.0565;0.10505;-0.1639;0 -0.0759;0.10515;-0.1644;0 -0.0893;0.10735;-0.1766;0 -0.0987;0.10885;-0.1853;0 -0.1293;0.11045;-0.1945;0 -0.1404;0.10535;-0.1653;0 -0.1594;0.10455;-0.1611;0 -0.1801;0.11875;-0.1693;0 -0.1957;0.13095;-0.1607;0 -0.2083;0.14315;-0.1369;0 -0.2059;0.14485;-0.1186;0 -0.2197;0.15575;-0.1038;0 -0.2197;0.15885;-0.0861;0 -0.2354;0.17045;-0.0699;0 -0.2561;0.16385;-0.0688;0 -0.2774;0.15755;-0.06759999999999999;0 -0.2992;0.15135;-0.06660000000000001;0 -0.3212;0.14495;-0.0654;0 -0.3431;0.13875;-0.0643;0 -0.3648;0.13305;-0.0633;0 -0.3647;0.13635;-0.0444;0 -0.3645;0.13985;-0.0242;0 -0.3645;0.14325;-0.0051;0 -0.3512;0.12075;-0.0011;0 -0.3399;0.09795;0.0029;0 -0.3304;0.07495;0.0069;0 -0.3372;0.05795;0.009900000000000001;0 -0.3439;0.04085;0.013;0 -0.3318;0.03925;0.0332;0 -0.3198;0.03705;0.0536;0 -0.3077;0.03405;0.074;0 -0.2951;0.02685;0.07530000000000001;0 -0.2829;0.01895;0.0767;0 -0.271;0.01045;0.07820000000000001;0 -0.2596;0.00145;0.0798;0 -0.2487;-0.007849999999999999;0.0814;0 -0.2385;-0.01755;0.08309999999999999;0 -0.2287;-0.02765;0.0849;0 -0.2192;-0.03845;0.0868;0 -0.2102;-0.04975;0.0888;0 -0.2024;-0.06365;0.0713;0 -0.1957;-0.07715;0.0537;0 -0.1881;-0.08964999999999999;0.0559;0 -0.1811;-0.10245;0.0582;0 -0.1755;-0.11735;0.0409;0 -0.1696;-0.13085;0.0432;0 -0.147;-0.13835;0.0445;0 -0.1243;-0.14785;0.0462;0 -0.1065;-0.14275;0.0453;0 -0.0886;-0.13775;0.0444;0 -0.0707;-0.13275;0.0436;0 -0.0707;-0.13605;0.0245;0 -0.07000000000000001;-0.14185;0.0066;0 -0.0702;-0.14445;-0.0122;0 -0.0546;-0.14505;-0.0121;0 -0.0437;-0.12755;-0.0145;0 -0.0269;-0.12775;-0.0144;0 -0.0155;-0.11035;-0.0167;0 -0.004;-0.09315;-0.0188;0 --0.0075;-0.07605000000000001;-0.0208;0 --0.0192;-0.05915;-0.0226;0 --0.0312;-0.04235;-0.0244;0 --0.0435;-0.02565;-0.0261;0 --0.0435;-0.00665;-0.0292;0 --0.0439;0.009849999999999999;-0.0341;0 --0.0403;0.03355;-0.0454;0 --0.0258;0.04765;-0.0549;0 --0.0115;0.06035;-0.0659;0 --0.0231;0.06825000000000001;-0.0742;0 --0.0233;0.08105;-0.0912;0 --0.0227;0.09005000000000001;-0.1076;0 --0.0033;0.08995;-0.1072;0 -0.0161;0.08985;-0.107;0 -0.0356;0.09685000000000001;-0.1248;0 -0.0356;0.10145;-0.1436;0 -0.0341;0.10485;-0.1625;0 -0.0527;0.10925;-0.1877;0 -0.078;0.10795;-0.1803;0 -0.0868;0.11055;-0.1949;0 -0.0958;0.11325;-0.2099;0 -0.1112;0.11195;-0.2031;0 -0.1226;0.11505;-0.2203;0 -0.1403;0.11335;-0.2109;0 -0.1498;0.10895;-0.1857;0 -0.167;0.10755;-0.178;0 -0.1879;0.12125;-0.1859;0 -0.202;0.13205;-0.1774;0 -0.2117;0.14175;-0.1564;0 -0.2221;0.15125;-0.1374;0 -0.221;0.15355;-0.1207;0 -0.2354;0.16415;-0.1053;0 -0.2354;0.16725;-0.0876;0 -0.2515;0.17825;-0.0713;0 -0.2725;0.17115;-0.07000000000000001;0 -0.2941;0.16435;-0.0688;0 -0.3164;0.15755;-0.06759999999999999;0 -0.3388;0.15055;-0.0664;0 -0.3612;0.14365;-0.06519999999999999;0 -0.3836;0.13705;-0.064;0 -0.3836;0.14035;-0.0451;0 -0.3834;0.14395;-0.0249;0 -0.3834;0.14725;-0.0058;0 -0.369;0.12545;-0.002;0 -0.3565;0.10325;0.002;0 -0.346;0.08065;0.0059;0 -0.3519;0.06335;0.008999999999999999;0 -0.3578;0.04595;0.012;0 -0.3454;0.04485;0.0322;0 -0.333;0.04315;0.0525;0 -0.3206;0.04075;0.07290000000000001;0 -0.308;0.03765;0.0934;0 -0.2954;0.03045;0.09470000000000001;0 -0.2832;0.02255;0.096;0 -0.2714;0.01415;0.0975;0 -0.2599;0.00515;0.09909999999999999;0 -0.2489;-0.00425;0.1008;0 -0.2385;-0.01415;0.1025;0 -0.2285;-0.02445;0.1043;0 -0.219;-0.03535;0.1063;0 -0.2099;-0.04665;0.1082;0 -0.2017;-0.06145;0.09089999999999999;0 -0.1944;-0.07575;0.07340000000000001;0 -0.187;-0.08815000000000001;0.0756;0 -0.1802;-0.10085;0.0779;0 -0.1748;-0.11555;0.0605;0 -0.1691;-0.12885;0.0629;0 -0.1644;-0.14465;0.0457;0 -0.1421;-0.15315;0.0472;0 -0.12;-0.16383;0.0491;0 -0.1019;-0.15951;0.0483;0 -0.0838;-0.15525;0.0475;0 -0.06569999999999999;-0.15115;0.0468;0 -0.06569999999999999;-0.15445;0.0277;0 -0.06519999999999999;-0.15992;0.0091;0 -0.0654;-0.16264;-0.0097;0 -0.0498;-0.16313;-0.009599999999999999;0 -0.0383;-0.14535;-0.0121;0 -0.0217;-0.14565;-0.0121;0 -0.009900000000000001;-0.12795;-0.0144;0 --0.0019;-0.11045;-0.0167;0 --0.0137;-0.09325;-0.0188;0 --0.0256;-0.07615;-0.0208;0 --0.0376;-0.05915;-0.0226;0 --0.0498;-0.04235;-0.0244;0 --0.0624;-0.02565;-0.0261;0 --0.0624;-0.00685;-0.0292;0 --0.06370000000000001;0.009849999999999999;-0.0341;0 --0.0606;0.03115;-0.044;0 --0.047;0.04285;-0.0514;0 --0.04;0.05155;-0.058;0 --0.048;0.07045;-0.0767;0 --0.0447;0.08185000000000001;-0.0925;0 --0.0422;0.09035;-0.1082;0 --0.0226;0.09694999999999999;-0.125;0 --0.0032;0.09694999999999999;-0.1249;0 -0.0162;0.09685000000000001;-0.1248;0 -0.0162;0.10145;-0.1436;0 -0.015;0.10485;-0.1629;0 -0.0293;0.10845;-0.1832;0 -0.0374;0.11245;-0.2054;0 -0.067;0.11225;-0.2045;0 -0.0771;0.11525;-0.2215;0 -0.105;0.11685;-0.2308;0 -0.1312;0.11815;-0.2381;0 -0.1487;0.11645;-0.2283;0 -0.1661;0.11495;-0.2196;0 -0.1578;0.11195;-0.2027;0 -0.1749;0.11055;-0.1947;0 -0.196;0.12385;-0.2023;0 -0.2098;0.13395;-0.1937;0 -0.2169;0.14205;-0.1723;0 -0.2252;0.14995;-0.1542;0 -0.2369;0.15905;-0.1387;0 -0.2355;0.16105;-0.123;0 -0.2515;0.16895;-0.1243;0 -0.2515;0.17205;-0.1067;0 -0.2515;0.17515;-0.089;0 -0.2679;0.18555;-0.0726;0 -0.289;0.17795;-0.0713;0 -0.3108;0.17065;-0.07000000000000001;0 -0.3332;0.16345;-0.0687;0 -0.3559;0.15585;-0.0673;0 -0.3791;0.14795;-0.0659;0 -0.4025;0.14015;-0.0646;0 -0.4025;0.14355;-0.0456;0 -0.4025;0.14705;-0.0255;0 -0.4025;0.15045;-0.0064;0 -0.387;0.12935;-0.0026;0 -0.3735;0.10765;0.0012;0 -0.3778;0.08985;0.0043;0 -0.3618;0.08565;0.0051;0 -0.3669;0.06805;0.008200000000000001;0 -0.372;0.05045;0.0113;0 -0.3592;0.04985;0.0313;0 -0.3465;0.04875;0.0515;0 -0.3337;0.04685;0.0718;0 -0.3208;0.04435;0.0922;0 -0.3208;0.04775;0.1116;0 -0.308;0.04105;0.1128;0 -0.2954;0.03385;0.114;0 -0.2832;0.02595;0.1154;0 -0.2714;0.01765;0.1169;0 -0.26;0.00865;0.1185;0 -0.249;-0.00075;0.1201;0 -0.2385;-0.01065;0.1219;0 -0.2285;-0.02105;0.1237;0 -0.219;-0.03185;0.1256;0 -0.21;-0.04315;0.1276;0 -0.2015;-0.05485;0.1296;0 -0.2014;-0.05835;0.1103;0 -0.1937;-0.07345;0.093;0 -0.1864;-0.08585;0.09520000000000001;0 -0.1797;-0.09845;0.0974;0 -0.174;-0.11385;0.08019999999999999;0 -0.1684;-0.12715;0.0825;0 -0.164;-0.14255;0.0653;0 -0.1599;-0.15858;0.0481;0 -0.1381;-0.16822;0.0498;0 -0.1165;-0.17977;0.0519;0 -0.0982;-0.17626;0.0512;0 -0.0799;-0.17292;0.0507;0 -0.0616;-0.1697;0.0501;0 -0.0616;-0.17304;0.031;0 -0.0613;-0.17819;0.0118;0 -0.0614;-0.18101;-0.007;0 -0.0458;-0.18142;-0.0069;0 -0.0336;-0.16343;-0.0095;0 -0.017;-0.16364;-0.0095;0 -0.0048;-0.14575;-0.012;0 --0.0074;-0.12805;-0.0144;0 --0.0195;-0.11055;-0.0167;0 --0.0315;-0.09325;-0.0188;0 --0.0437;-0.07615;-0.0208;0 --0.056;-0.05925;-0.0226;0 --0.06850000000000001;-0.04245;-0.0244;0 --0.0814;-0.02565;-0.0261;0 --0.0814;-0.00685;-0.0291;0 --0.08169999999999999;0.01025;-0.0343;0 --0.0808;0.03045;-0.0436;0 --0.08;0.04295;-0.0515;0 --0.0591;0.04305;-0.0515;0 --0.0561;0.05465;-0.0606;0 --0.0701;0.07305;-0.08;0 --0.0645;0.08305;-0.0945;0 --0.0609;0.09075;-0.109;0 --0.0419;0.09694999999999999;-0.1252;0 --0.0226;0.10145;-0.1436;0 --0.0032;0.10145;-0.1436;0 --0.0049;0.10485;-0.1629;0 -0.0136;0.10815;-0.1813;0 -0.0241;0.11125;-0.1986;0 -0.0204;0.11295;-0.2085;0 -0.0267;0.11425;-0.216;0 -0.0492;0.11455;-0.2176;0 -0.059;0.11745;-0.234;0 -0.0873;0.11885;-0.2418;0 -0.1137;0.12005;-0.249;0 -0.1401;0.12135;-0.2559;0 -0.1574;0.11945;-0.2456;0 -0.1747;0.11785;-0.2364;0 -0.1916;0.11635;-0.2279;0 -0.1831;0.11345;-0.2114;0 -0.2044;0.12635;-0.2185;0 -0.218;0.13605;-0.2098;0 -0.2234;0.14335;-0.186;0 -0.2293;0.14975;-0.168;0 -0.2382;0.15725;-0.1528;0 -0.2511;0.16385;-0.1516;0 -0.2511;0.16605;-0.1394;0 -0.268;0.17395;-0.1387;0 -0.2679;0.17625;-0.1255;0 -0.2679;0.17935;-0.1079;0 -0.2679;0.18245;-0.09030000000000001;0 -0.2845;0.19225;-0.0738;0 -0.3054;0.18435;-0.07240000000000001;0 -0.3269;0.17685;-0.07099999999999999;0 -0.3491;0.16925;-0.0697;0 -0.3723;0.16105;-0.0683;0 -0.3965;0.15195;-0.0667;0 -0.4216;0.14245;-0.065;0 -0.4216;0.14575;-0.0461;0 -0.4216;0.14935;-0.0259;0 -0.4216;0.15265;-0.0068;0 -0.4051;0.13235;-0.0032;0 -0.3906;0.11135;0.0005;0 -0.3941;0.09335;0.0037;0 -0.3976;0.07535;0.0069;0 -0.3822;0.07205;0.0074;0 -0.3865;0.05425;0.0106;0 -0.3733;0.05425;0.0306;0 -0.3603;0.05365;0.0506;0 -0.3472;0.05235;0.0708;0 -0.3339;0.05035;0.0911;0 -0.3339;0.05375;0.1105;0 -0.3338;0.05715;0.1299;0 -0.3207;0.05115;0.1309;0 -0.3079;0.04445;0.1321;0 -0.2954;0.03725;0.1334;0 -0.2832;0.02935;0.1348;0 -0.2714;0.02105;0.1362;0 -0.26;0.01205;0.1378;0 -0.2491;0.00265;0.1395;0 -0.2386;-0.00715;0.1412;0 -0.2286;-0.01755;0.1431;0 -0.2191;-0.02835;0.145;0 -0.2101;-0.03965;0.147;0 -0.2016;-0.05125;0.149;0 -0.1937;-0.06335;0.1511;0 -0.1936;-0.06685000000000001;0.1318;0 -0.1935;-0.07035;0.1124;0 -0.1862;-0.08275;0.1146;0 -0.1795;-0.09535;0.1168;0 -0.1735;-0.11145;0.0997;0 -0.168;-0.12475;0.102;0 -0.1634;-0.14075;0.0849;0 -0.1596;-0.15635;0.0677;0 -0.1561;-0.17274;0.0506;0 -0.1347;-0.18339;0.0525;0 -0.1137;-0.19622;0.0548;0 -0.09520000000000001;-0.19358;0.0543;0 -0.07679999999999999;-0.19097;0.0538;0 -0.0584;-0.18841;0.0534;0 -0.0584;-0.19175;0.0344;0 -0.0582;-0.19659;0.0147;0 -0.0583;-0.19953;-0.0041;0 -0.0424;-0.19985;-0.0041;0 -0.0295;-0.18168;-0.0069;0 -0.0129;-0.18185;-0.0068;0 -0.0002;-0.1638;-0.0095;0 --0.0123;-0.14585;-0.012;0 --0.0247;-0.12815;-0.0144;0 --0.037;-0.11065;-0.0167;0 --0.0494;-0.09335;-0.0188;0 --0.0618;-0.07625;-0.0208;0 --0.0743;-0.05925;-0.0226;0 --0.0871;-0.04245;-0.0244;0 --0.1003;-0.02565;-0.0261;0 --0.1003;-0.00695;-0.0291;0 --0.1004;0.01055;-0.0344;0 --0.1001;0.02845;-0.0425;0 --0.1004;0.04265;-0.0512;0 --0.0794;0.05635;-0.0621;0 --0.0893;0.07535;-0.083;0 --0.08409999999999999;0.08415;-0.09619999999999999;0 --0.0813;0.09125;-0.1101;0 --0.0613;0.09715;-0.1255;0 --0.0419;0.10145;-0.1436;0 --0.0235;0.10535;-0.1656;0 --0.0062;0.10815;-0.1813;0 -0.0113;0.11075;-0.1959;0 -0.0109;0.11335;-0.2107;0 -0.017;0.11565;-0.2238;0 -0.0357;0.11675;-0.2299;0 -0.0442;0.11965;-0.2465;0 -0.07000000000000001;0.12085;-0.2535;0 -0.0964;0.12215;-0.2607;0 -0.1229;0.12335;-0.2673;0 -0.1495;0.12445;-0.2736;0 -0.1665;0.12255;-0.2627;0 -0.1837;0.12085;-0.2531;0 -0.2004;0.11925;-0.2442;0 -0.2131;0.12885;-0.2345;0 -0.2265;0.13815;-0.2256;0 -0.2315;0.14505;-0.2018;0 -0.2349;0.15065;-0.1806;0 -0.2413;0.15675;-0.1645;0 -0.2493;0.16125;-0.1617;0 -0.2571;0.16375;-0.1688;0 -0.2683;0.17135;-0.1542;0 -0.2835;0.17905;-0.1461;0 -0.2834;0.18075;-0.1367;0 -0.2845;0.18315;-0.1249;0 -0.2846;0.18595;-0.1091;0 -0.2846;0.18915;-0.0915;0 -0.3014;0.19835;-0.07480000000000001;0 -0.3214;0.19045;-0.07340000000000001;0 -0.3421;0.18305;-0.0721;0 -0.364;0.17545;-0.0708;0 -0.3874;0.16675;-0.0693;0 -0.4129;0.15625;-0.0674;0 -0.4408;0.14375;-0.06519999999999999;0 -0.4407;0.14715;-0.0462;0 -0.4409;0.15065;-0.0263;0 -0.4409;0.15405;-0.007;0 -0.4234;0.13445;-0.0036;0 -0.4078;0.11415;0;0 -0.4105;0.09605;0.0032;0 -0.4131;0.07795000000000001;0.0064;0 -0.4157;0.05985;0.009599999999999999;0 -0.401;0.05735;0.01;0 -0.3876;0.05795;0.0299;0 -0.3743;0.05795;0.0499;0 -0.3609;0.05725;0.07000000000000001;0 -0.3473;0.05585;0.0902;0 -0.3473;0.05925;0.1096;0 -0.3472;0.06265;0.1289;0 -0.3471;0.06605;0.1483;0 -0.3338;0.06055;0.1493;0 -0.3207;0.05445;0.1503;0 -0.3078;0.04785;0.1515;0 -0.2953;0.04055;0.1528;0 -0.2832;0.03275;0.1542;0 -0.2714;0.02445;0.1556;0 -0.26;0.01555;0.1572;0 -0.2491;0.00615;0.1588;0 -0.2387;-0.00375;0.1606;0 -0.2287;-0.01405;0.1624;0 -0.2191;-0.02485;0.1643;0 -0.2102;-0.03605;0.1663;0 -0.2017;-0.04775;0.1683;0 -0.1938;-0.05975;0.1705;0 -0.1865;-0.07205;0.1726;0 -0.1864;-0.07565;0.1533;0 -0.1863;-0.07925;0.134;0 -0.1796;-0.09185;0.1362;0 -0.1735;-0.10475;0.1385;0 -0.1734;-0.10835;0.1191;0 -0.1679;-0.12155;0.1215;0 -0.1631;-0.13825;0.1044;0 -0.1591;-0.15445;0.0873;0 -0.1558;-0.17034;0.0702;0 -0.1529;-0.18707;0.0532;0 -0.132;-0.19888;0.0552;0 -0.1117;-0.21255;0.0576;0 -0.09320000000000001;-0.21078;0.0573;0 -0.0747;-0.20903;0.057;0 -0.0562;-0.20729;0.0567;0 -0.0562;-0.21061;0.0377;0 -0.0561;-0.21507;0.0178;0 -0.0561;-0.21815;-0.0012;0 -0.0397;-0.21839;-0.0011;0 -0.026;-0.20005;-0.0041;0 -0.0091;-0.20019;-0.004;0 --0.0041;-0.18197;-0.0068;0 --0.0169;-0.1639;-0.0095;0 --0.0295;-0.14595;-0.012;0 --0.0421;-0.12825;-0.0144;0 --0.0547;-0.11065;-0.0166;0 --0.0672;-0.09335;-0.0188;0 --0.0799;-0.07625;-0.0208;0 --0.0927;-0.05925;-0.0226;0 --0.1058;-0.04245;-0.0244;0 --0.1193;-0.02565;-0.0261;0 --0.1193;-0.00695;-0.0291;0 --0.1193;0.01085;-0.0345;0 --0.1191;0.02845;-0.0425;0 --0.1181;0.04235;-0.051;0 --0.1171;0.05215;-0.0584;0 --0.1027;0.05785;-0.0635;0 --0.1173;0.06825000000000001;-0.0742;0 --0.1069;0.07905;-0.0881;0 --0.1017;0.08585;-0.0993;0 --0.09859999999999999;0.09145;-0.1106;0 --0.08069999999999999;0.09725;-0.1261;0 --0.0613;0.10145;-0.1436;0 --0.0641;0.10485;-0.1625;0 --0.047;0.10605;-0.1692;0 --0.0383;0.10885;-0.1854;0 --0.0245;0.10845;-0.183;0 --0.0076;0.11045;-0.1946;0 --0.009299999999999999;0.11425;-0.2158;0 -0.0028;0.11775;-0.236;0 -0.0253;0.11835;-0.2389;0 -0.0339;0.12105;-0.2547;0 -0.039;0.12285;-0.2646;0 -0.0515;0.12295;-0.2652;0 -0.0692;0.12625;-0.2838;0 -0.0823;0.12425;-0.2727;0 -0.106;0.12545;-0.2792;0 -0.1326;0.12655;-0.2855;0 -0.1593;0.12755;-0.2912;0 -0.176;0.12555;-0.2798;0 -0.193;0.12375;-0.2696;0 -0.2095;0.12205;-0.2603;0 -0.2222;0.13135;-0.2504;0 -0.2355;0.14025;-0.2411;0 -0.2399;0.14675;-0.2173;0 -0.2442;0.15275;-0.1953;0 -0.2466;0.15755;-0.1752;0 -0.2554;0.15945;-0.1886;0 -0.2672;0.16625;-0.1802;0 -0.282;0.17495;-0.1661;0 -0.2933;0.18175;-0.152;0 -0.2967;0.18515;-0.1401;0 -0.299;0.18845;-0.1258;0 -0.3014;0.19205;-0.1101;0 -0.3014;0.19515;-0.0925;0 -0.3186;0.20065;-0.0935;0 -0.3186;0.20375;-0.07580000000000001;0 -0.337;0.19625;-0.0745;0 -0.3564;0.18945;-0.0733;0 -0.3773;0.18235;-0.07199999999999999;0 -0.4003;0.17395;-0.07049999999999999;0 -0.4268;0.16245;-0.06850000000000001;0 -0.4603;0.14425;-0.0653;0 -0.4603;0.14765;-0.0459;0 -0.4603;0.15105;-0.0265;0 -0.4603;0.15445;-0.0071;0 -0.4418;0.13575;-0.0038;0 -0.4252;0.11625;-0.0003;0 -0.427;0.09805;0.0029;0 -0.4288;0.07975;0.0061;0 -0.4305;0.06155;0.009299999999999999;0 -0.4166;0.06335;0.029;0 -0.4021;0.06095;0.0294;0 -0.3886;0.06155;0.0492;0 -0.3749;0.06155;0.0692;0 -0.3611;0.06075;0.0893;0 -0.361;0.06415;0.1087;0 -0.3609;0.06745;0.128;0 -0.3608;0.07085;0.1474;0 -0.3608;0.07425;0.1668;0 -0.3472;0.06945;0.1677;0 -0.3338;0.06395000000000001;0.1686;0 -0.3207;0.05795;0.1697;0 -0.3079;0.05125;0.1708;0 -0.2954;0.04405;0.1721;0 -0.2833;0.03625;0.1735;0 -0.2716;0.02795;0.175;0 -0.2602;0.01915;0.1765;0 -0.2493;0.00975;0.1782;0 -0.2389;-5e-05;0.1799;0 -0.2289;-0.01035;0.1817;0 -0.2194;-0.02115;0.1836;0 -0.2104;-0.03235;0.1856;0 -0.202;-0.04385;0.1876;0 -0.1941;-0.05585;0.1897;0 -0.1868;-0.06815;0.1919;0 -0.18;-0.08075;0.1941;0 -0.1797;-0.08465;0.1749;0 -0.1796;-0.08825;0.1555;0 -0.1735;-0.10115;0.1578;0 -0.1681;-0.11435;0.1601;0 -0.168;-0.11795;0.1408;0 -0.1631;-0.13145;0.1432;0 -0.163;-0.13505;0.1238;0 -0.1589;-0.15185;0.1069;0 -0.1555;-0.16831;0.0898;0 -0.1527;-0.18446;0.0726;0 -0.1504;-0.20156;0.0557;0 -0.1302;-0.21434;0.058;0 -0.1105;-0.22895;0.0605;0 -0.0919;-0.22805;0.0604;0 -0.0733;-0.22715;0.0602;0 -0.0548;-0.22622;0.06;0 -0.0548;-0.22958;0.0409;0 -0.0548;-0.23361;0.0211;0 -0.0548;-0.23686;0.002;0 -0.0376;-0.23696;0.002;0 -0.0228;-0.21852;-0.0011;0 -0.0056;-0.21861;-0.0011;0 --0.008;-0.20028;-0.004;0 --0.0212;-0.18206;-0.0068;0 --0.034;-0.16397;-0.0095;0 --0.0468;-0.14605;-0.012;0 --0.0595;-0.12825;-0.0144;0 --0.0723;-0.11075;-0.0166;0 --0.0851;-0.09345000000000001;-0.0187;0 --0.098;-0.07625;-0.0208;0 --0.1111;-0.05935;-0.0226;0 --0.1244;-0.04245;-0.0244;0 --0.1382;-0.02565;-0.0261;0 --0.1382;-0.00695;-0.0291;0 --0.1382;0.01095;-0.0345;0 --0.1381;0.02845;-0.0425;0 --0.1348;0.04635;-0.0539;0 --0.1272;0.05785;-0.0635;0 --0.1414;0.06525;-0.0709;0 --0.1289;0.07535;-0.0829;0 --0.1198;0.08284999999999999;-0.0941;0 --0.1158;0.08774999999999999;-0.1028;0 --0.1148;0.09215;-0.1122;0 --0.0989;0.09744999999999999;-0.1266;0 --0.08069999999999999;0.10145;-0.1436;0 --0.0799;0.10475;-0.162;0 --0.06660000000000001;0.10675;-0.1735;0 --0.0587;0.10805;-0.1806;0 --0.0487;0.10995;-0.1916;0 --0.0349;0.11025;-0.1934;0 --0.0258;0.11055;-0.1947;0 --0.0297;0.11275;-0.2073;0 --0.0256;0.11765;-0.2353;0 --0.0122;0.12015;-0.2494;0 -0.0123;0.12045;-0.2513;0 -0.0238;0.12265;-0.2635;0 -0.033;0.12425;-0.2728;0 -0.0427;0.12585;-0.2814;0 -0.0588;0.12855;-0.2968;0 -0.08110000000000001;0.12875;-0.2982;0 -0.0921;0.12725;-0.2896;0 -0.0988;0.12955;-0.3025;0 -0.1164;0.12815;-0.2949;0 -0.1263;0.13105;-0.311;0 -0.1427;0.12965;-0.3034;0 -0.1695;0.13065;-0.3087;0 -0.186;0.12845;-0.2967;0 -0.2026;0.12655;-0.2859;0 -0.219;0.12495;-0.2763;0 -0.2317;0.13385;-0.266;0 -0.2449;0.14235;-0.2565;0 -0.2488;0.14855;-0.2325;0 -0.2538;0.15475;-0.2111;0 -0.2672;0.16205;-0.2041;0 -0.279;0.16875;-0.1943;0 -0.2956;0.17815;-0.1774;0 -0.3069;0.18545;-0.1582;0 -0.3115;0.18975;-0.1423;0 -0.3141;0.19335;-0.1269;0 -0.3168;0.19705;-0.1106;0 -0.3356;0.20235;-0.1119;0 -0.3358;0.20545;-0.09429999999999999;0 -0.3358;0.20855;-0.0766;0 -0.3517;0.20205;-0.0755;0 -0.369;0.19635;-0.0745;0 -0.3882;0.19065;-0.0735;0 -0.4097;0.18395;-0.0723;0 -0.4336;0.17535;-0.0708;0 -0.4603;0.16435;-0.0688;0 -0.4603;0.16705;-0.0493;0 -0.4603;0.17005;-0.0299;0 -0.4603;0.17285;-0.0138;0 -0.4603;0.17635;0.0011;0 -0.4603;0.15885;0.009299999999999999;0 -0.4603;0.13615;-0.0039;0 -0.4427;0.11745;-0.0005999999999999999;0 -0.4436;0.09915;0.0027;0 -0.4445;0.08085000000000001;0.0059;0 -0.4454;0.06265;0.0091;0 -0.4311;0.06505;0.0286;0 -0.4172;0.06685000000000001;0.0483;0 -0.4029;0.06455;0.0487;0 -0.389;0.06515;0.06859999999999999;0 -0.375;0.06494999999999999;0.0886;0 -0.3749;0.06834999999999999;0.1079;0 -0.3748;0.07174999999999999;0.1273;0 -0.3747;0.07514999999999999;0.1467;0 -0.3746;0.07854999999999999;0.1661;0 -0.3692;0.09585;0.163;0 -0.3545;0.09135;0.1638;0 -0.3402;0.08624999999999999;0.1647;0 -0.326;0.08044999999999999;0.1657;0 -0.3121;0.07395;0.1669;0 -0.2985;0.06695;0.1681;0 -0.2853;0.05925;0.1694;0 -0.2725;0.05095;0.1709;0 -0.2601;0.04215;0.1725;0 -0.2481;0.03275;0.1741;0 -0.2365;0.02285;0.1759;0 -0.2255;0.01235;0.1777;0 -0.2149;0.00145;0.1796;0 -0.2049;-0.009950000000000001;0.1817;0 -0.1954;-0.02185;0.1837;0 -0.1865;-0.03405;0.1859;0 -0.1781;-0.04675;0.1881;0 -0.1704;-0.05975;0.1904;0 -0.1633;-0.07305;0.1928;0 -0.1739;-0.09365;0.1964;0 -0.1736;-0.09755;0.1771;0 -0.1681;-0.11075;0.1795;0 -0.1632;-0.12425;0.1818;0 -0.1632;-0.12785;0.1625;0 -0.1589;-0.14145;0.1649;0 -0.1588;-0.14515;0.1456;0 -0.1588;-0.14865;0.1262;0 -0.1553;-0.1657;0.1093;0 -0.1525;-0.18226;0.0922;0 -0.1504;-0.19863;0.0752;0 -0.1487;-0.21612;0.0583;0 -0.129;-0.22985;0.0607;0 -0.1101;-0.24528;0.0634;0 -0.0915;-0.24528;0.0634;0 -0.07290000000000001;-0.24528;0.0634;0 -0.0543;-0.24528;0.0634;0 -0.0543;-0.248714;0.044;0 -0.0543;-0.252132;0.0246;0 -0.0543;-0.25555;0.0052;0 -0.0359;-0.25555;0.0052;0 -0.0201;-0.23703;0.002;0 -0.0023;-0.23707;0.002;0 --0.0119;-0.21867;-0.0011;0 --0.0253;-0.20034;-0.004;0 --0.0384;-0.18212;-0.0068;0 --0.0513;-0.16403;-0.0095;0 --0.0641;-0.14605;-0.012;0 --0.077;-0.12835;-0.0144;0 --0.08989999999999999;-0.11075;-0.0166;0 --0.103;-0.09345000000000001;-0.0187;0 --0.1161;-0.07635;-0.0208;0 --0.1295;-0.05935;-0.0226;0 --0.1431;-0.04245;-0.0244;0 --0.1572;-0.02565;-0.0261;0 --0.1572;-0.00695;-0.0291;0 --0.1572;0.01105;-0.0346;0 --0.1571;0.02845;-0.0425;0 --0.1561;0.05125;-0.0578;0 --0.1696;0.06615;-0.07190000000000001;0 --0.1534;0.07355;-0.0806;0 --0.1397;0.08155;-0.092;0 --0.1294;0.08624999999999999;-0.1;0 --0.1238;0.08855;-0.1045;0 --0.1263;0.09175;-0.1111;0 --0.1164;0.09755;-0.1271;0 --0.1001;0.10145;-0.1436;0 --0.1042;0.10525;-0.165;0 --0.09130000000000001;0.10845;-0.1828;0 --0.0761;0.10735;-0.1765;0 --0.0697;0.10915;-0.1871;0 --0.0602;0.11125;-0.1985;0 --0.0493;0.11325;-0.2102;0 --0.0407;0.11155;-0.2004;0 --0.0398;0.11505;-0.2202;0 --0.0504;0.11725;-0.2328;0 --0.0372;0.11985;-0.2474;0 --0.0255;0.12215;-0.2609;0 --0.0007;0.12245;-0.2622;0 -0.0112;0.12465;-0.2747;0 -0.0233;0.12675;-0.2868;0 -0.0336;0.12835;-0.2961;0 -0.0486;0.13085;-0.31;0 -0.0717;0.13055;-0.3084;0 -0.0878;0.13005;-0.3056;0 -0.08409999999999999;0.13185;-0.3158;0 -0.1017;0.13265;-0.3203;0 -0.1205;0.13625;-0.3408;0 -0.1388;0.13435;-0.3296;0 -0.1535;0.13275;-0.321;0 -0.1803;0.13365;-0.3259;0 -0.1964;0.13145;-0.3134;0 -0.2127;0.12945;-0.3021;0 -0.2288;0.12765;-0.2921;0 -0.2414;0.13625;-0.2813;0 -0.2545;0.14435;-0.2715;0 -0.2581;0.15025;-0.2476;0 -0.2626;0.15625;-0.2255;0 -0.2763;0.16355;-0.2179;0 -0.2919;0.17135;-0.2082;0 -0.3154;0.18225;-0.1924;0 -0.326;0.19045;-0.1639;0 -0.3313;0.19525;-0.1455;0 -0.3337;0.19895;-0.1283;0 -0.3523;0.20325;-0.13;0 -0.3529;0.20655;-0.1126;0 -0.3532;0.20965;-0.095;0 -0.3533;0.21275;-0.0774;0 -0.3646;0.20735;-0.0764;0 -0.3792;0.20375;-0.07580000000000001;0 -0.3966;0.20015;-0.0752;0 -0.4162;0.19595;-0.07439999999999999;0 -0.4376;0.19075;-0.0735;0 -0.4603;0.18435;-0.07240000000000001;0 -0.4603;0.18605;-0.0507;0 -0.4603;0.18605;-0.0312;0 -0.4603;0.18405;-0.0178;0 -0.4603;0.19475;-0.0091;0 -0.4603;0.20045;0.0156;0 -0.4603;0.18125;0.02;0 -0.4603;0.16265;0.0267;0 -0.4603;0.13945;0.0146;0 -0.4603;0.11785;-0.0005999999999999999;0 -0.4603;0.09955;0.0026;0 -0.4603;0.08125;0.0058;0 -0.4603;0.06295000000000001;0.008999999999999999;0 -0.4457;0.06605;0.0285;0 -0.4316;0.06845;0.048;0 -0.4176;0.07035;0.0677;0 -0.4033;0.06805;0.06809999999999999;0 -0.3891;0.06855;0.08790000000000001;0 -0.389;0.07195;0.1073;0 -0.3889;0.07535;0.1267;0 -0.3887;0.07865;0.1461;0 -0.3885;0.08205;0.1654;0 -0.3841;0.09965;0.1623;0 -0.3796;0.11735;0.1592;0 -0.364;0.11325;0.1599;0 -0.3485;0.10855;0.1607;0 -0.3333;0.10305;0.1617;0 -0.3182;0.09694999999999999;0.1628;0 -0.3036;0.09005000000000001;0.164;0 -0.2893;0.08265;0.1653;0 -0.2753;0.07445;0.1668;0 -0.2618;0.06575;0.1683;0 -0.2487;0.05645;0.1699;0 -0.236;0.04645;0.1717;0 -0.2238;0.03595;0.1735;0 -0.2122;0.02495;0.1755;0 -0.2011;0.01345;0.1775;0 -0.1905;0.00135;0.1797;0 -0.1805;-0.01115;0.1819;0 -0.1711;-0.02415;0.1841;0 -0.1623;-0.03745;0.1865;0 -0.1541;-0.05125;0.1889;0 -0.1466;-0.06525;0.1914;0 -0.1568;-0.08674999999999999;0.1952;0 -0.1683;-0.10675;0.1987;0 -0.1634;-0.12015;0.2011;0 -0.1592;-0.13375;0.2035;0 -0.159;-0.13785;0.1842;0 -0.1554;-0.15165;0.1867;0 -0.1553;-0.15525;0.1674;0 -0.1553;-0.15893;0.148;0 -0.1552;-0.16247;0.1287;0 -0.1524;-0.17956;0.1117;0 -0.1502;-0.19624;0.09470000000000001;0 -0.1487;-0.2129;0.07770000000000001;0 -0.1476;-0.23077;0.0608;0 -0.1287;-0.24528;0.0634;0 -0.1101;-0.242;0.082;0 -0.0915;-0.24203;0.0819;0 -0.07290000000000001;-0.24202;0.082;0 -0.0543;-0.24197;0.0822;0 -0.035;-0.24528;0.0634;0 -0.0353;-0.248714;0.044;0 -0.0359;-0.2523;0.0236;0 -0.0176;-0.252361;0.0233;0 -0.0176;-0.25555;0.0052;0 --0.0008;-0.25555;0.0052;0 --0.0156;-0.2371;0.002;0 --0.0294;-0.21871;-0.0011;0 --0.0427;-0.2004;-0.004;0 --0.0557;-0.18217;-0.0068;0 --0.06850000000000001;-0.16407;-0.0095;0 --0.0814;-0.14615;-0.012;0 --0.0944;-0.12835;-0.0144;0 --0.1076;-0.11085;-0.0166;0 --0.1208;-0.09345000000000001;-0.0187;0 --0.1342;-0.07635;-0.0208;0 --0.1478;-0.05935;-0.0226;0 --0.1618;-0.04245;-0.0244;0 --0.1761;-0.02565;-0.0261;0 --0.1761;-0.00695;-0.0291;0 --0.1761;0.01105;-0.0346;0 --0.1761;0.02845;-0.0425;0 --0.18;0.04425;-0.0524;0 --0.1878;0.05815;-0.0638;0 --0.1965;0.06915;-0.07530000000000001;0 --0.1807;0.07605000000000001;-0.0839;0 --0.165;0.08245;-0.0934;0 --0.149;0.08705;-0.1014;0 --0.1368;0.09005000000000001;-0.1074;0 --0.1317;0.09675;-0.1244;0 --0.1195;0.10145;-0.1436;0 --0.1247;0.10365;-0.156;0 --0.1204;0.10765;-0.1784;0 --0.1087;0.10985;-0.1909;0 --0.0974;0.11215;-0.2038;0 --0.083;0.11045;-0.1945;0 --0.0725;0.11265;-0.2068;0 --0.0607;0.11505;-0.2202;0 --0.0742;0.11695;-0.2313;0 --0.0626;0.11935;-0.2451;0 --0.051;0.12185;-0.2588;0 --0.0392;0.12425;-0.2725;0 --0.0271;0.12665;-0.286;0 --0.0137;0.12445;-0.274;0 --0.0015;0.12675;-0.2868;0 -0.011;0.12895;-0.2992;0 -0.0238;0.13105;-0.3113;0 -0.037;0.13315;-0.323;0 -0.0505;0.13515;-0.3344;0 -0.0618;0.13285;-0.3211;0 -0.0751;0.13465;-0.3318;0 -0.0898;0.13645;-0.3417;0 -0.106;0.13865;-0.3542;0 -0.1201;0.14045;-0.3643;0 -0.1308;0.13865;-0.354;0 -0.1468;0.13705;-0.3452;0 -0.1649;0.13545;-0.3361;0 -0.1769;0.13815;-0.3512;0 -0.1917;0.13665;-0.3428;0 -0.2072;0.13435;-0.3299;0 -0.2233;0.13225;-0.318;0 -0.2391;0.13045;-0.3076;0 -0.2516;0.13855;-0.2964;0 -0.2645;0.14635;-0.2862;0 -0.2677;0.15195;-0.2623;0 -0.2718;0.15775;-0.2399;0 -0.2861;0.16475;-0.2332;0 -0.3021;0.17215;-0.2245;0 -0.3215;0.17985;-0.2163;0 -0.3443;0.19045;-0.192;0 -0.3479;0.19555;-0.1679;0 -0.3506;0.19975;-0.1481;0 -0.3672;0.20285;-0.1505;0 -0.3695;0.20675;-0.131;0 -0.3703;0.21005;-0.1132;0 -0.3707;0.21325;-0.09569999999999999;0 -0.3708;0.21635;-0.078;0 -0.374;0.21165;-0.0772;0 -0.3861;0.21125;-0.0771;0 -0.4025;0.21055;-0.077;0 -0.4208;0.20925;-0.07679999999999999;0 -0.4403;0.20715;-0.0764;0 -0.4603;0.20445;-0.0759;0 -0.4603;0.20295;-0.0523;0 -0.4603;0.20065;-0.0309;0 -0.4603;0.21945;-0.0089;0 -0.4603;0.21865;0.013;0 -0.4603;0.21825;0.0303;0 -0.4603;0.20205;0.0327;0 -0.4603;0.18555;0.0343;0 -0.4603;0.16895;0.0429;0 -0.4603;0.14275;0.0331;0 -0.4603;0.12115;0.0179;0 -0.4603;0.10285;0.0213;0 -0.4603;0.08465;0.0248;0 -0.4603;0.06635000000000001;0.0284;0 -0.4459;0.06945;0.0478;0 -0.4318;0.07195;0.0674;0 -0.4318;0.07535;0.0868;0 -0.4176;0.07375;0.08699999999999999;0 -0.4033;0.07145;0.08740000000000001;0 -0.4032;0.07485;0.1068;0 -0.403;0.07825;0.1262;0 -0.4029;0.08165;0.1455;0 -0.4027;0.08505;0.1649;0 -0.399;0.10285;0.1618;0 -0.3955;0.12065;0.1586;0 -0.3921;0.13845;0.1555;0 -0.3754;0.13495;0.1561;0 -0.3588;0.13075;0.1568;0 -0.3425;0.12575;0.1577;0 -0.3265;0.11995;0.1587;0 -0.3107;0.11345;0.1599;0 -0.2953;0.10625;0.1611;0 -0.2802;0.09845;0.1625;0 -0.2655;0.08985;0.164;0 -0.2513;0.08065;0.1657;0 -0.2375;0.07085;0.1674;0 -0.2241;0.06035;0.1693;0 -0.2113;0.04925;0.1712;0 -0.199;0.03765;0.1733;0 -0.1873;0.02545;0.1754;0 -0.1762;0.01285;0.1776;0 -0.1656;-0.00045;0.18;0 -0.1557;-0.01405;0.1824;0 -0.1465;-0.02805;0.1849;0 -0.1379;-0.04255;0.1874;0 -0.13;-0.05745;0.19;0 -0.1398;-0.07975;0.1939;0 -0.151;-0.10065;0.1976;0 -0.1458;-0.11475;0.2001;0 -0.1413;-0.12915;0.2027;0 -0.1555;-0.14765;0.2059;0 -0.1526;-0.16157;0.2084;0 -0.1524;-0.16558;0.1891;0 -0.1524;-0.16918;0.1698;0 -0.1524;-0.1728;0.1504;0 -0.1523;-0.17633;0.1311;0 -0.1501;-0.19345;0.1142;0 -0.1486;-0.21023;0.09719999999999999;0 -0.1476;-0.22728;0.08019999999999999;0 -0.1473;-0.24188;0.0828;0 -0.1473;-0.24528;0.0634;0 -0.1283;-0.24188;0.0828;0 -0.128;-0.23846;0.1021;0 -0.1092;-0.23849;0.1019;0 -0.0915;-0.23869;0.1008;0 -0.0731;-0.23867;0.1009;0 -0.0546;-0.23857;0.1015;0 -0.0349;-0.24191;0.08260000000000001;0 -0.0153;-0.24198;0.0822;0 -0.0164;-0.245861;0.0601;0 -0.0174;-0.24908;0.0419;0 --0.0008;-0.249172;0.0414;0 --0.0008;-0.252361;0.0233;0 --0.0192;-0.252361;0.0233;0 --0.0192;-0.25555;0.0052;0 --0.0335;-0.23713;0.002;0 --0.0471;-0.21875;-0.0011;0 --0.0602;-0.20043;-0.004;0 --0.073;-0.18222;-0.0068;0 --0.0858;-0.1641;-0.0095;0 --0.0988;-0.14615;-0.012;0 --0.1119;-0.12845;-0.0144;0 --0.1252;-0.11085;-0.0166;0 --0.1387;-0.09354999999999999;-0.0187;0 --0.1523;-0.07635;-0.0208;0 --0.1662;-0.05935;-0.0226;0 --0.1804;-0.04245;-0.0244;0 --0.1951;-0.02565;-0.0261;0 --0.1951;-0.00695;-0.0291;0 --0.1951;0.01115;-0.0346;0 --0.1944;0.02735;-0.0419;0 --0.1961;0.04025;-0.0496;0 --0.2025;0.05045;-0.0571;0 --0.2125;0.06185;-0.0674;0 --0.2073;0.07875;-0.0877;0 --0.1918;0.08455;-0.0969;0 --0.1765;0.08975;-0.1069;0 --0.1608;0.09325;-0.1147;0 --0.1465;0.09565;-0.1212;0 --0.1388;0.10145;-0.1436;0 --0.1376;0.10275;-0.1509;0 --0.1326;0.10555;-0.1664;0 --0.1347;0.12425;-0.1652;0 --0.1213;0.12685;-0.1784;0 --0.1089;0.12875;-0.1915;0 --0.0974;0.13005;-0.2046;0 --0.0858;0.11455;-0.2176;0 --0.0858;0.13215;-0.2183;0 --0.0742;0.13425;-0.232;0 --0.0626;0.13635;-0.2457;0 --0.051;0.13855;-0.2594;0 --0.0393;0.14055;-0.273;0 --0.0272;0.14265;-0.2865;0 --0.0145;0.12895;-0.2991;0 --0.0017;0.13115;-0.3119;0 -0.0115;0.13335;-0.3243;0 -0.0251;0.13545;-0.3364;0 -0.039;0.13755;-0.3481;0 -0.0643;0.13705;-0.3454;0 -0.0784;0.13895;-0.356;0 -0.09420000000000001;0.14095;-0.3674;0 -0.1089;0.14265;-0.3772;0 -0.1224;0.14415;-0.3856;0 -0.1311;0.14205;-0.3734;0 -0.1369;0.14035;-0.3641;0 -0.1534;0.14035;-0.3641;0 -0.1749;0.14285;-0.3783;0 -0.1896;0.14075;-0.3664;0 -0.2039;0.13915;-0.3573;0 -0.2186;0.13725;-0.3462;0 -0.2342;0.13505;-0.3337;0 -0.2498;0.13305;-0.3227;0 -0.2621;0.14095;-0.3112;0 -0.2749;0.14835;-0.3006;0 -0.2776;0.15365;-0.2768;0 -0.2813;0.15915;-0.2542;0 -0.2955;0.16585;-0.2469;0 -0.3091;0.17175;-0.2405;0 -0.3237;0.17715;-0.2359;0 -0.3432;0.18285;-0.2333;0 -0.3441;0.18655;-0.2136;0 -0.3634;0.19135;-0.2115;0 -0.3637;0.19485;-0.1921;0 -0.3643;0.19835;-0.1727;0 -0.3838;0.20525;-0.154;0 -0.3869;0.20955;-0.1323;0 -0.3878;0.21295;-0.114;0 -0.3883;0.21615;-0.0963;0 -0.3886;0.21925;-0.0785;0 -0.4064;0.22155;-0.0789;0 -0.4243;0.22325;-0.07920000000000001;0 -0.4422;0.22415;-0.0794;0 -0.4603;0.22455;-0.0794;0 -0.4603;0.22105;-0.0538;0 -0.4603;0.22075;-0.0307;0 -0.4603;0.23675;-0.0114;0 -0.4603;0.23755;0.009299999999999999;0 -0.4603;0.23715;0.028;0 -0.4603;0.23675;0.045;0 -0.4603;0.21785;0.045;0 -0.4603;0.20225;0.046;0 -0.4603;0.18955;0.0453;0 -0.4603;0.17945;0.0596;0 -0.4603;0.15035;0.0712;0 -0.4603;0.14635;0.0519;0 -0.4603;0.12455;0.0366;0 -0.4603;0.10655;0.0404;0 -0.4603;0.08895;0.0444;0 -0.4603;0.06975000000000001;0.0478;0 -0.446;0.07285;0.0672;0 -0.446;0.07625;0.0866;0 -0.4459;0.07975;0.1059;0 -0.4317;0.07875;0.1061;0 -0.4174;0.07715;0.1064;0 -0.4173;0.08055;0.1258;0 -0.4171;0.08395;0.1451;0 -0.417;0.08735;0.1645;0 -0.4144;0.10525;0.1613;0 -0.4118;0.12325;0.1582;0 -0.4092;0.14125;0.155;0 -0.3888;0.15635;0.1523;0 -0.3712;0.15265;0.153;0 -0.3538;0.14815;0.1538;0 -0.3367;0.14295;0.1547;0 -0.3199;0.13695;0.1558;0 -0.3033;0.13015;0.157;0 -0.2871;0.12255;0.1583;0 -0.2712;0.11425;0.1597;0 -0.2558;0.10535;0.1613;0 -0.2409;0.09565;0.163;0 -0.2263;0.08535;0.1649;0 -0.2123;0.07435;0.1668;0 -0.1989;0.06265;0.1688;0 -0.186;0.05045;0.171;0 -0.1736;0.03775;0.1732;0 -0.1619;0.02435;0.1756;0 -0.1509;0.01055;0.1781;0 -0.1405;-0.00385;0.1806;0 -0.1307;-0.01865;0.1832;0 -0.1218;-0.03385;0.1859;0 -0.1135;-0.04945;0.1886;0 -0.1228;-0.07265000000000001;0.1927;0 -0.1337;-0.09435;0.1965;0 -0.1282;-0.10935;0.1992;0 -0.1235;-0.12455;0.2018;0 -0.1375;-0.14375;0.2052;0 -0.1344;-0.15855;0.2079;0 -0.1502;-0.17561;0.2109;0 -0.1502;-0.17958;0.1916;0 -0.1501;-0.18313;0.1723;0 -0.1501;-0.1867;0.1529;0 -0.1501;-0.1902;0.1336;0 -0.1485;-0.2073;0.1166;0 -0.1476;-0.22428;0.09959999999999999;0 -0.1473;-0.23846;0.1021;0 -0.1473;-0.23504;0.1215;0 -0.1278;-0.23504;0.1215;0 -0.1086;-0.23506;0.1214;0 -0.0901;-0.23513;0.121;0 -0.0735;-0.23529;0.1201;0 -0.0551;-0.23521;0.1206;0 -0.0352;-0.23523;0.1204;0 -0.0349;-0.23851;0.1018;0 -0.0146;-0.23841;0.1024;0 --0.0037;-0.23916;0.09810000000000001;0 --0.0014;-0.24264;0.0784;0 --0.0011;-0.245983;0.0595;0 --0.0192;-0.249172;0.0414;0 --0.0376;-0.249172;0.0414;0 --0.0376;-0.252361;0.0233;0 --0.0376;-0.25555;0.0052;0 --0.0515;-0.23715;0.002;0 --0.0648;-0.21878;-0.001;0 --0.07770000000000001;-0.20046;-0.004;0 --0.09039999999999999;-0.18225;-0.0068;0 --0.1031;-0.16415;-0.0095;0 --0.1161;-0.14625;-0.012;0 --0.1294;-0.12845;-0.0144;0 --0.1429;-0.11085;-0.0166;0 --0.1566;-0.09354999999999999;-0.0187;0 --0.1705;-0.07635;-0.0207;0 --0.1846;-0.05935;-0.0226;0 --0.1991;-0.04255;-0.0244;0 --0.214;-0.02565;-0.0261;0 --0.214;-0.00695;-0.0291;0 --0.214;0.01115;-0.0346;0 --0.2115;0.02715;-0.0418;0 --0.2083;0.03735;-0.0477;0 --0.2166;0.04435;-0.0525;0 --0.2276;0.05535;-0.0613;0 --0.223;0.07235;-0.0791;0 --0.2332;0.08155;-0.092;0 --0.2178;0.08685;-0.1011;0 --0.2026;0.09155000000000001;-0.1108;0 --0.1875;0.09565;-0.1211;0 --0.1727;0.09895;-0.132;0 --0.1582;0.10145;-0.1436;0 --0.1452;0.10345;-0.1547;0 --0.1473;0.12155;-0.1538;0 --0.1485;0.14115;-0.1535;0 --0.1354;0.14405;-0.1653;0 --0.1217;0.14675;-0.1788;0 --0.1093;0.14845;-0.1918;0 --0.0974;0.14795;-0.2053;0 --0.0858;0.14975;-0.219;0 --0.0742;0.15155;-0.2326;0 --0.0626;0.15345;-0.2463;0 --0.051;0.15525;-0.26;0 --0.0392;0.15695;-0.2737;0 --0.027;0.15875;-0.2872;0 --0.0146;0.14465;-0.2996;0 --0.0016;0.14665;-0.3125;0 -0.0118;0.14855;-0.3251;0 -0.0255;0.15045;-0.3373;0 -0.0396;0.15225;-0.3491;0 -0.0531;0.13955;-0.3594;0 -0.06759999999999999;0.14145;-0.3703;0 -0.0824;0.14335;-0.3808;0 -0.0975;0.14515;-0.391;0 -0.1129;0.14685;-0.4007;0 -0.1285;0.14845;-0.41;0 -0.1377;0.14575;-0.3946;0 -0.1465;0.14315;-0.3797;0 -0.1639;0.14505;-0.3904;0 -0.1772;0.14645;-0.3984;0 -0.1859;0.14475;-0.3888;0 -0.1979;0.14335;-0.3811;0 -0.2151;0.14205;-0.3735;0 -0.2306;0.14005;-0.3622;0 -0.2457;0.13775;-0.3491;0 -0.2609;0.13575;-0.3376;0 -0.2731;0.14315;-0.3256;0 -0.2858;0.15025;-0.3148;0 -0.288;0.15525;-0.2909;0 -0.2912;0.16055;-0.2682;0 -0.3052;0.16685;-0.2607;0 -0.3161;0.17135;-0.2552;0 -0.3274;0.17525;-0.2525;0 -0.3422;0.17935;-0.2519;0 -0.3624;0.18425;-0.2508;0 -0.3629;0.18785;-0.231;0 -0.3828;0.19155;-0.2307;0 -0.383;0.19495;-0.2116;0 -0.3831;0.19835;-0.1926;0 -0.3832;0.20175;-0.1734;0 -0.4024;0.20435;-0.1741;0 -0.4027;0.20775;-0.1549;0 -0.4043;0.21155;-0.1341;0 -0.4054;0.21515;-0.1149;0 -0.406;0.21835;-0.0969;0 -0.4237;0.21995;-0.09760000000000001;0 -0.4412;0.22075;-0.0984;0 -0.4603;0.22115;-0.0985;0 -0.4603;0.24085;-0.083;0 -0.4603;0.23945;-0.07290000000000001;0 -0.4603;0.23725;-0.0507;0 -0.4603;0.23675;-0.0302;0 -0.4603;0.25555;-0.0114;0 -0.4603;0.25555;0.0074;0 -0.4603;0.25555;0.0262;0 -0.4603;0.25555;0.045;0 -0.4603;0.25555;0.0638;0 -0.4603;0.23675;0.0638;0 -0.4603;0.21785;0.0638;0 -0.4603;0.19995;0.06419999999999999;0 -0.4603;0.19815;0.0871;0 -0.4603;0.17695;0.09080000000000001;0 -0.4603;0.15325;0.09520000000000001;0 -0.4603;0.13085;0.0767;0 -0.4603;0.12875;0.0559;0 -0.4603;0.11125;0.0603;0 -0.4603;0.09254999999999999;0.06370000000000001;0 -0.4603;0.07315000000000001;0.06710000000000001;0 -0.4603;0.07665;0.08649999999999999;0 -0.4603;0.08005;0.1059;0 -0.4603;0.08345;0.1252;0 -0.4459;0.08315;0.1253;0 -0.4316;0.08215;0.1255;0 -0.4315;0.08555;0.1448;0 -0.4314;0.08895;0.1642;0 -0.4296;0.10705;0.161;0 -0.4279;0.12515;0.1578;0 -0.4262;0.14315;0.1546;0 -0.4067;0.15925;0.1518;0 -0.3858;0.17425;0.1491;0 -0.3675;0.17045;0.1498;0 -0.3494;0.16585;0.1506;0 -0.3315;0.16035;0.1516;0 -0.3139;0.15415;0.1527;0 -0.2966;0.14705;0.154;0 -0.2797;0.13925;0.1553;0 -0.2631;0.13065;0.1569;0 -0.247;0.12125;0.1585;0 -0.2313;0.11125;0.1603;0 -0.2161;0.10045;0.1622;0 -0.2014;0.08905;0.1642;0 -0.1873;0.07695;0.1663;0 -0.1738;0.06415;0.1686;0 -0.1608;0.05085;0.1709;0 -0.1485;0.03695;0.1734;0 -0.1369;0.02255;0.1759;0 -0.126;0.00755;0.1786;0 -0.1158;-0.00795;0.1813;0 -0.1063;-0.02375;0.1841;0 -0.09760000000000001;-0.04015;0.187;0 -0.0896;-0.05675;0.1899;0 -0.1059;-0.06544999999999999;0.1914;0 -0.1164;-0.08805;0.1954;0 -0.1107;-0.10385;0.1982;0 -0.1057;-0.11985;0.201;0 -0.1195;-0.13995;0.2046;0 -0.1162;-0.15545;0.2073;0 -0.1319;-0.17336;0.2105;0 -0.1486;-0.18975;0.2134;0 -0.1486;-0.1936;0.1941;0 -0.1485;-0.19708;0.1747;0 -0.1485;-0.20059;0.1554;0 -0.1485;-0.20404;0.136;0 -0.1476;-0.22114;0.119;0 -0.1476;-0.21783;0.1384;0 -0.1473;-0.23162;0.1409;0 -0.1277;-0.23162;0.1409;0 -0.1083;-0.23164;0.1408;0 -0.0896;-0.23165;0.1407;0 -0.0721;-0.23127;0.1429;0 -0.0544;-0.23101;0.1444;0 -0.0353;-0.23143;0.142;0 -0.0132;-0.23555;0.1186;0 --0.0049;-0.23617;0.1151;0 --0.0216;-0.23632;0.1142;0 --0.0196;-0.23959;0.09569999999999999;0 --0.0192;-0.24278;0.0776;0 --0.0192;-0.245983;0.0595;0 --0.0376;-0.245983;0.0595;0 --0.056;-0.245983;0.0595;0 --0.056;-0.249172;0.0414;0 --0.056;-0.252361;0.0233;0 --0.056;-0.25555;0.0052;0 --0.06950000000000001;-0.23716;0.002;0 --0.0825;-0.21881;-0.001;0 --0.09520000000000001;-0.2005;-0.004;0 --0.1077;-0.18228;-0.0068;0 --0.1205;-0.16418;-0.0095;0 --0.1335;-0.14625;-0.012;0 --0.1469;-0.12845;-0.0144;0 --0.1605;-0.11095;-0.0166;0 --0.1744;-0.09354999999999999;-0.0187;0 --0.1886;-0.07645;-0.0207;0 --0.203;-0.05945;-0.0226;0 --0.2177;-0.04255;-0.0244;0 --0.233;-0.02565;-0.0261;0 --0.233;-0.00695;-0.0291;0 --0.233;0.01115;-0.0346;0 --0.2302;0.03265;-0.0448;0 --0.2448;0.04825;-0.0554;0 --0.2388;0.06565;-0.0713;0 --0.2488;0.07585;-0.08359999999999999;0 --0.2547;0.09365;-0.08169999999999999;0 --0.2386;0.09955;-0.0902;0 --0.2226;0.10495;-0.0993;0 --0.2067;0.10975;-0.1091;0 --0.1909;0.11375;-0.1196;0 --0.1754;0.11685;-0.1309;0 --0.1603;0.11905;-0.1427;0 --0.1628;0.13745;-0.1415;0 --0.1639;0.15985;-0.1414;0 --0.1496;0.16245;-0.1533;0 --0.1353;0.16455;-0.1662;0 --0.1217;0.16655;-0.1794;0 --0.1094;0.16625;-0.1923;0 --0.0974;0.16585;-0.2059;0 --0.0858;0.16735;-0.2195;0 --0.0742;0.16885;-0.2332;0 --0.0626;0.17045;-0.2468;0 --0.051;0.17195;-0.2605;0 --0.0391;0.17335;-0.2743;0 --0.0268;0.17485;-0.2879;0 --0.0143;0.16045;-0.3005;0 --0.0012;0.16215;-0.3134;0 -0.0123;0.16375;-0.3261;0 -0.0263;0.16545;-0.3384;0 -0.0405;0.16695;-0.3503;0 -0.054;0.15395;-0.3605;0 -0.0688;0.15565;-0.3716;0 -0.0838;0.15725;-0.3822;0 -0.099;0.15885;-0.3923;0 -0.1145;0.16035;-0.4021;0 -0.1302;0.16175;-0.4113;0 -0.1444;0.15005;-0.4188;0 -0.153;0.14725;-0.4033;0 -0.1687;0.14875;-0.4115;0 -0.1893;0.14775;-0.4056;0 -0.1927;0.14615;-0.397;0 -0.2031;0.14595;-0.3957;0 -0.2251;0.14565;-0.3938;0 -0.2434;0.14275;-0.3776;0 -0.2578;0.14045;-0.3642;0 -0.2725;0.13825;-0.352;0 -0.2845;0.14535;-0.3397;0 -0.297;0.15195;-0.3285;0 -0.2987;0.15675;-0.3047;0 -0.3014;0.16175;-0.2819;0 -0.3129;0.16745;-0.272;0 -0.3192;0.17065;-0.2649;0 -0.3281;0.17285;-0.2672;0 -0.3424;0.17625;-0.2702;0 -0.3619;0.18055;-0.2709;0 -0.3823;0.18465;-0.2694;0 -0.3826;0.18815;-0.25;0 -0.4022;0.19085;-0.2502;0 -0.4023;0.19425;-0.2312;0 -0.4023;0.19755;-0.2122;0 -0.4024;0.20095;-0.1931;0 -0.4216;0.20285;-0.1934;0 -0.4216;0.20625;-0.1744;0 -0.4216;0.20955;-0.1554;0 -0.4219;0.21295;-0.1363;0 -0.423;0.21655;-0.1161;0 -0.4409;0.21745;-0.1175;0 -0.4603;0.21775;-0.1175;0 -0.4603;0.25555;-0.1054;0 -0.4603;0.25555;-0.0866;0 -0.4603;0.25555;-0.0678;0 -0.4603;0.25555;-0.049;0 -0.4603;0.25555;-0.0302;0 -0.4415;0.25555;-0.0114;0 -0.4415;0.25555;0.0074;0 -0.4415;0.25555;0.0262;0 -0.4415;0.25555;0.045;0 -0.4415;0.25555;0.0638;0 -0.4415;0.25555;0.08260000000000001;0 -0.4603;0.25555;0.08260000000000001;0 -0.4603;0.23675;0.08260000000000001;0 -0.4603;0.21695;0.0849;0 -0.4603;0.21585;0.1049;0 -0.4603;0.19775;0.1088;0 -0.4603;0.17645;0.1129;0 -0.4603;0.15665;0.1152;0 -0.4603;0.13515;0.099;0 -0.4603;0.11465;0.0798;0 -0.4603;0.09594999999999999;0.08309999999999999;0 -0.4603;0.09934999999999999;0.1025;0 -0.4603;0.10245;0.1239;0 -0.4603;0.08685;0.1446;0 -0.4458;0.08655;0.1447;0 -0.4458;0.08995;0.164;0 -0.4449;0.10805;0.1608;0 -0.4441;0.12625;0.1576;0 -0.4432;0.14435;0.1544;0 -0.4245;0.16125;0.1515;0 -0.4043;0.17725;0.1486;0 -0.4043;0.18035;0.1665;0 -0.3858;0.17745;0.167;0 -0.3675;0.17365;0.1677;0 -0.3494;0.16895;0.1685;0 -0.3315;0.16355;0.1694;0 -0.3139;0.15725;0.1706;0 -0.2966;0.15025;0.1718;0 -0.2797;0.14235;0.1732;0 -0.2631;0.13375;0.1747;0 -0.247;0.12445;0.1763;0 -0.2313;0.11435;0.1781;0 -0.2161;0.10365;0.18;0 -0.2014;0.09215;0.182;0 -0.1873;0.08005;0.1842;0 -0.1738;0.06734999999999999;0.1864;0 -0.1608;0.05395;0.1888;0 -0.1485;0.04005;0.1912;0 -0.1369;0.02565;0.1938;0 -0.126;0.01065;0.1964;0 -0.1158;-0.00475;0.1991;0 -0.1063;-0.02065;0.2019;0 -0.09760000000000001;-0.03695;0.2048;0 -0.0896;-0.05365;0.2077;0 -0.0824;-0.07385;0.1929;0 -0.09909999999999999;-0.08165;0.1943;0 -0.0931;-0.09825;0.1972;0 -0.08790000000000001;-0.11505;0.2002;0 -0.1015;-0.13605;0.2039;0 -0.098;-0.15245;0.2068;0 -0.1136;-0.17115;0.2101;0 -0.1302;-0.18835;0.2131;0 -0.1476;-0.20397;0.2159;0 -0.1476;-0.20762;0.1965;0 -0.1476;-0.21098;0.1772;0 -0.1476;-0.21441;0.1578;0 -0.1473;-0.22821;0.1602;0 -0.1277;-0.22821;0.1602;0 -0.1085;-0.22819;0.1603;0 -0.091;-0.22793;0.1618;0 -0.0731;-0.22775;0.1628;0 -0.0549;-0.22766;0.1633;0 -0.0365;-0.22763;0.1636;0 -0.0108;-0.22776;0.1628;0 -0.0055;-0.23111;0.1438;0 --0.0102;-0.23255;0.1356;0 --0.0249;-0.23353;0.1301;0 --0.0376;-0.23643;0.1137;0 --0.0376;-0.23959;0.09569999999999999;0 --0.0376;-0.24278;0.0776;0 --0.056;-0.24278;0.0776;0 --0.0743;-0.24278;0.0776;0 --0.0743;-0.245983;0.0595;0 --0.0743;-0.249172;0.0414;0 --0.0743;-0.252361;0.0233;0 --0.0743;-0.25555;0.0052;0 --0.0876;-0.23718;0.002;0 --0.1003;-0.21882;-0.001;0 --0.1127;-0.20051;-0.004;0 --0.1251;-0.18229;-0.0068;0 --0.1378;-0.16421;-0.0094;0 --0.1508;-0.14625;-0.012;0 --0.1644;-0.12855;-0.0144;0 --0.1782;-0.11095;-0.0166;0 --0.1923;-0.09365;-0.0187;0 --0.2067;-0.07645;-0.0207;0 --0.2213;-0.05945;-0.0226;0 --0.2364;-0.04255;-0.0244;0 --0.2519;-0.02565;-0.0261;0 --0.2519;-0.00695;-0.0291;0 --0.2538;0.01075;-0.0345;0 --0.2554;0.02635;-0.0414;0 --0.2628;0.03955;-0.0491;0 --0.2549;0.05845;-0.0641;0 --0.2645;0.06965;-0.07580000000000001;0 --0.2708;0.08724999999999999;-0.0741;0 --0.2773;0.10545;-0.0723;0 --0.2607;0.11205;-0.0798;0 --0.2441;0.11815;-0.0882;0 --0.2274;0.12375;-0.0974;0 --0.2108;0.12865;-0.1073;0 --0.1944;0.13435;-0.1181;0 --0.1778;0.13525;-0.1299;0 --0.1778;0.15755;-0.1306;0 --0.1777;0.18185;-0.1314;0 --0.1633;0.18255;-0.1425;0 --0.1485;0.18405;-0.1548;0 --0.1349;0.18415;-0.167;0 --0.1219;0.18425;-0.1797;0 --0.1094;0.18415;-0.1927;0 --0.0974;0.18385;-0.2063;0 --0.0858;0.18505;-0.22;0 --0.0742;0.18625;-0.2336;0 --0.0626;0.18745;-0.2473;0 --0.051;0.18865;-0.2609;0 --0.039;0.18975;-0.2748;0 --0.0266;0.19095;-0.2885;0 --0.014;0.17625;-0.3012;0 --0.0007;0.17765;-0.3142;0 -0.0129;0.17905;-0.327;0 -0.027;0.18035;-0.3394;0 -0.0414;0.18165;-0.3514;0 -0.0552;0.16845;-0.3618;0 -0.0701;0.16985;-0.3729;0 -0.0852;0.17125;-0.3836;0 -0.1006;0.17255;-0.3937;0 -0.1161;0.17385;-0.4034;0 -0.1319;0.17505;-0.4127;0 -0.1461;0.16315;-0.4201;0 -0.1605;0.15155;-0.4273;0 -0.1769;0.15295;-0.4353;0 -0.1847;0.15015;-0.4192;0 -0.2011;0.14845;-0.4099;0 -0.2212;0.14965;-0.4168;0 -0.2477;0.14795;-0.4071;0 -0.2597;0.14535;-0.3921;0 -0.2705;0.14305;-0.379;0 -0.2847;0.14075;-0.3661;0 -0.2963;0.14735;-0.3532;0 -0.3085;0.15365;-0.3418;0 -0.3097;0.15825;-0.3181;0 -0.3105;0.16285;-0.2937;0 -0.3223;0.16885;-0.2806;0 -0.3389;0.17135;-0.2924;0 -0.3618;0.17695;-0.2914;0 -0.3821;0.18115;-0.2891;0 -0.402;0.18405;-0.2886;0 -0.4021;0.18745;-0.2693;0 -0.4216;0.18945;-0.2696;0 -0.4216;0.19275;-0.2506;0 -0.4216;0.19615;-0.2315;0 -0.4216;0.19945;-0.2125;0 -0.4409;0.20395;-0.1936;0 -0.4409;0.20735;-0.1746;0 -0.4409;0.21075;-0.1556;0 -0.4409;0.21405;-0.1365;0 -0.4603;0.21445;-0.1366;0 -0.4603;0.23995;-0.144;0 -0.4603;0.25555;-0.1241;0 -0.4415;0.25555;-0.1054;0 -0.4415;0.25555;-0.0866;0 -0.4415;0.25555;-0.0678;0 -0.4415;0.25555;-0.049;0 -0.4415;0.25555;-0.0302;0 -0.4227;0.25555;-0.0114;0 -0.4227;0.25555;0.0074;0 -0.4227;0.25555;0.0262;0 -0.4227;0.25555;0.045;0 -0.4227;0.25555;0.0638;0 -0.4227;0.25555;0.08260000000000001;0 -0.4227;0.25555;0.1014;0 -0.4415;0.25555;0.1014;0 -0.4603;0.25555;0.1014;0 -0.4603;0.23675;0.1014;0 -0.4603;0.23675;0.1202;0 -0.4603;0.21675;0.1234;0 -0.4603;0.19765;0.1271;0 -0.4603;0.17785;0.13;0 -0.4603;0.15975;0.1331;0 -0.4603;0.14155;0.1363;0 -0.4603;0.13845;0.1183;0 -0.4603;0.11725;0.1019;0 -0.4603;0.12035;0.1214;0 -0.4603;0.10515;0.1424;0 -0.4603;0.09025;0.164;0 -0.4603;0.10845;0.1608;0 -0.4603;0.12655;0.1576;0 -0.4603;0.14475;0.1544;0 -0.4423;0.16255;0.1512;0 -0.4229;0.17935;0.1483;0 -0.4229;0.18255;0.1661;0 -0.4229;0.18565;0.1839;0 -0.4043;0.18355;0.1843;0 -0.3858;0.18055;0.1848;0 -0.3675;0.17675;0.1855;0 -0.3494;0.17215;0.1863;0 -0.3315;0.16665;0.1873;0 -0.3139;0.16045;0.1884;0 -0.2966;0.15335;0.1896;0 -0.2797;0.14555;0.191;0 -0.2631;0.13695;0.1925;0 -0.247;0.12755;0.1942;0 -0.2313;0.11755;0.1959;0 -0.2161;0.10675;0.1979;0 -0.2014;0.09535;0.1999;0 -0.1873;0.08325;0.202;0 -0.1738;0.07045;0.2043;0 -0.1608;0.05715;0.2066;0 -0.1485;0.04325;0.209;0 -0.1369;0.02875;0.2116;0 -0.126;0.01385;0.2142;0 -0.1158;-0.00165;0.217;0 -0.1063;-0.01755;0.2198;0 -0.09760000000000001;-0.03385;0.2226;0 -0.0896;-0.05045;0.2256;0 -0.0824;-0.07065;0.2108;0 -0.0761;-0.09114999999999999;0.196;0 -0.07049999999999999;-0.10875;0.1991;0 -0.0658;-0.12665;0.2022;0 -0.0835;-0.13215;0.2032;0 -0.0798;-0.14935;0.2062;0 -0.0953;-0.16894;0.2097;0 -0.1118;-0.18698;0.2129;0 -0.1292;-0.20341;0.2158;0 -0.1473;-0.21797;0.2183;0 -0.1473;-0.22139;0.199;0 -0.1473;-0.2248;0.1796;0 -0.1279;-0.2248;0.1796;0 -0.1101;-0.22462;0.1806;0 -0.09180000000000001;-0.22451;0.1812;0 -0.07340000000000001;-0.22445;0.1816;0 -0.055;-0.22441;0.1818;0 -0.0365;-0.22441;0.1819;0 -0.0147;-0.22441;0.1818;0 --0.0005;-0.22438;0.182;0 --0.0029;-0.22776;0.1628;0 --0.0043;-0.22972;0.1517;0 --0.0137;-0.23036;0.1481;0 --0.0268;-0.23117;0.1435;0 --0.0392;-0.23399;0.1275;0 --0.056;-0.23645;0.1135;0 --0.056;-0.23959;0.09569999999999999;0 --0.0743;-0.2396;0.09569999999999999;0 --0.0927;-0.2396;0.0956;0 --0.0927;-0.24278;0.0776;0 --0.0927;-0.245983;0.0595;0 --0.0927;-0.249172;0.0414;0 --0.0927;-0.252361;0.0233;0 --0.0927;-0.25555;0.0052;0 --0.1057;-0.23718;0.002;0 --0.1181;-0.21884;-0.001;0 --0.1302;-0.20054;-0.004;0 --0.1425;-0.18232;-0.0068;0 --0.1551;-0.16424;-0.0094;0 --0.1682;-0.14635;-0.012;0 --0.1818;-0.12855;-0.0144;0 --0.1958;-0.11105;-0.0166;0 --0.2102;-0.09365;-0.0187;0 --0.2248;-0.07645;-0.0207;0 --0.2397;-0.05945;-0.0226;0 --0.2551;-0.04255;-0.0244;0 --0.2708;-0.02565;-0.0261;0 --0.2708;-0.00695;-0.0291;0 --0.2695;0.01075;-0.0345;0 --0.2717;0.02205;-0.0392;0 --0.2784;0.03305;-0.0451;0 --0.271;0.05105;-0.0576;0 --0.2803;0.06304999999999999;-0.06859999999999999;0 --0.287;0.08055;-0.0669;0 --0.2939;0.09845;-0.0653;0 --0.3011;0.11695;-0.06370000000000001;0 --0.2841;0.12425;-0.0704;0 --0.2668;0.13145;-0.078;0 --0.2493;0.13795;-0.08649999999999999;0 --0.2307;0.14465;-0.0964;0 --0.2148;0.15245;-0.1058;0 --0.1991;0.16205;-0.116;0 --0.1942;0.18245;-0.1198;0 --0.1911;0.20185;-0.1223;0 --0.1765;0.20185;-0.1327;0 --0.1624;0.20195;-0.1436;0 --0.1487;0.20195;-0.155;0 --0.1354;0.20185;-0.1669;0 --0.1222;0.20185;-0.1797;0 --0.1096;0.20195;-0.1929;0 --0.0974;0.20175;-0.2067;0 --0.0858;0.20265;-0.2203;0 --0.0742;0.20355;-0.2339;0 --0.0626;0.20445;-0.2476;0 --0.051;0.20535;-0.2612;0 --0.0389;0.20625;-0.2752;0 --0.0264;0.20715;-0.2889;0 --0.0137;0.19215;-0.3018;0 --0.0003;0.19325;-0.315;0 -0.0135;0.19435;-0.3278;0 -0.0277;0.19535;-0.3402;0 -0.0422;0.19645;-0.3523;0 -0.0562;0.18295;-0.363;0 -0.0713;0.18405;-0.3742;0 -0.0866;0.18525;-0.3848;0 -0.1021;0.18635;-0.395;0 -0.1177;0.18745;-0.4047;0 -0.1335;0.18845;-0.4138;0 -0.1478;0.17625;-0.4214;0 -0.1623;0.16445;-0.4285;0 -0.1787;0.16565;-0.4365;0 -0.1934;0.15425;-0.4428;0 -0.1979;0.15115;-0.425;0 -0.2171;0.15265;-0.4335;0 -0.2399;0.15095;-0.4238;0 -0.2643;0.14995;-0.4185;0 -0.2733;0.14795;-0.4068;0 -0.2839;0.14555;-0.3931;0 -0.2974;0.14315;-0.3797;0 -0.3086;0.14935;-0.3663;0 -0.3206;0.15525;-0.3545;0 -0.3212;0.15955;-0.3311;0 -0.323;0.16405;-0.3084;0 -0.348;0.16945;-0.316;0 -0.3645;0.17375;-0.3126;0 -0.3829;0.17745;-0.3107;0 -0.4019;0.18065;-0.308;0 -0.4216;0.18275;-0.3077;0 -0.4216;0.18605;-0.2886;0 -0.4409;0.18715;-0.2889;0 -0.4409;0.19055;-0.2698;0 -0.4409;0.19395;-0.2508;0 -0.4409;0.19725;-0.2317;0 -0.4409;0.20065;-0.2127;0 -0.4603;0.20435;-0.1937;0 -0.4603;0.20775;-0.1747;0 -0.4603;0.21105;-0.1556;0 -0.4603;0.22755;-0.1483;0 -0.4603;0.23915;-0.1606;0 -0.4603;0.25555;-0.1617;0 -0.4603;0.25555;-0.1429;0 -0.4415;0.25555;-0.1241;0 -0.4227;0.25555;-0.1054;0 -0.4227;0.25555;-0.0866;0 -0.4227;0.25555;-0.0678;0 -0.4227;0.25555;-0.049;0 -0.4227;0.25555;-0.0302;0 -0.4039;0.25555;-0.0114;0 -0.4039;0.25555;0.0074;0 -0.4039;0.25555;0.0262;0 -0.4039;0.25555;0.045;0 -0.4039;0.25555;0.0638;0 -0.4039;0.25555;0.08260000000000001;0 -0.4039;0.25555;0.1014;0 -0.4039;0.25555;0.1202;0 -0.4227;0.25555;0.1202;0 -0.4415;0.25555;0.1202;0 -0.4603;0.25555;0.1202;0 -0.4603;0.25555;0.139;0 -0.4603;0.23675;0.139;0 -0.4603;0.21785;0.142;0 -0.4603;0.19895;0.1448;0 -0.4603;0.18105;0.148;0 -0.4603;0.16285;0.1512;0 -0.4416;0.18065;0.148;0 -0.4416;0.18375;0.1659;0 -0.4416;0.18695;0.1837;0 -0.4416;0.19005;0.2015;0 -0.4229;0.18875;0.2018;0 -0.4043;0.18665;0.2021;0 -0.3858;0.18365;0.2027;0 -0.3675;0.17985;0.2033;0 -0.3494;0.17525;0.2042;0 -0.3315;0.16985;0.2051;0 -0.3139;0.16355;0.2062;0 -0.2966;0.15655;0.2075;0 -0.2797;0.14865;0.2089;0 -0.2631;0.14005;0.2104;0 -0.247;0.13075;0.212;0 -0.2313;0.12065;0.2138;0 -0.2161;0.10995;0.2157;0 -0.2014;0.09845;0.2177;0 -0.1873;0.08635;0.2198;0 -0.1738;0.07364999999999999;0.2221;0 -0.1608;0.06025;0.2244;0 -0.1485;0.04635;0.2269;0 -0.1369;0.03195;0.2294;0 -0.126;0.01695;0.2321;0 -0.1158;0.00155;0.2348;0 -0.1063;-0.01435;0.2376;0 -0.09760000000000001;-0.03065;0.2405;0 -0.0896;-0.04735;0.2434;0 -0.0824;-0.06755;0.2286;0 -0.0761;-0.08805;0.2138;0 -0.07049999999999999;-0.10565;0.2169;0 -0.0658;-0.12345;0.22;0 -0.062;-0.14465;0.2054;0 -0.059;-0.16284;0.2086;0 -0.077;-0.16673;0.2093;0 -0.0934;-0.1856;0.2126;0 -0.1107;-0.20286;0.2157;0 -0.1288;-0.21797;0.2183;0 -0.1288;-0.22131;0.1994;0 -0.1104;-0.22125;0.1997;0 -0.092;-0.22122;0.1999;0 -0.0735;-0.2212;0.2;0 -0.0551;-0.22119;0.2001;0 -0.0366;-0.22119;0.2001;0 -0.0181;-0.22117;0.2002;0 --0.0005;-0.22116;0.2003;0 --0.0191;-0.22438;0.182;0 --0.0161;-0.22795;0.1617;0 --0.0316;-0.22828;0.1598;0 --0.0428;-0.23139;0.1422;0 --0.0557;-0.23405;0.1271;0 --0.0736;-0.23437;0.1253;0 --0.07439999999999999;-0.2368;0.1116;0 --0.0926;-0.23706;0.1101;0 --0.1117;-0.23729;0.1088;0 --0.1111;-0.2396;0.0956;0 --0.1111;-0.24278;0.0776;0 --0.1111;-0.245983;0.0595;0 --0.1111;-0.249172;0.0414;0 --0.1111;-0.252361;0.0233;0 --0.1111;-0.25555;0.0052;0 --0.1237;-0.23719;0.002;0 --0.1358;-0.21885;-0.001;0 --0.1477;-0.20056;-0.004;0 --0.1599;-0.18235;-0.0068;0 --0.1724;-0.16427;-0.0094;0 --0.1856;-0.14635;-0.0119;0 --0.1993;-0.12855;-0.0144;0 --0.2135;-0.11105;-0.0166;0 --0.228;-0.09365;-0.0187;0 --0.2429;-0.07655000000000001;-0.0207;0 --0.2581;-0.05945;-0.0226;0 --0.2737;-0.04255;-0.0244;0 --0.2898;-0.02565;-0.0261;0 --0.2869;-0.00705;-0.0291;0 --0.2845;0.009350000000000001;-0.0339;0 --0.2819;0.01915;-0.0379;0 --0.2904;0.02615;-0.0413;0 --0.2872;0.04335;-0.0517;0 --0.2963;0.05615;-0.0619;0 --0.3034;0.07345;-0.0605;0 --0.3107;0.09114999999999999;-0.059;0 --0.3165;0.10875;-0.0581;0 --0.3242;0.12635;-0.0565;0 --0.307;0.13775;-0.0625;0 --0.2916;0.14755;-0.0684;0 --0.2745;0.15875;-0.0756;0 --0.252;0.15885;-0.0859;0 --0.2338;0.16115;-0.0953;0 --0.2177;0.16705;-0.1046;0 --0.2074;0.17045;-0.1109;0 --0.2068;0.18275;-0.1116;0 --0.206;0.20185;-0.1125;0 --0.2062;0.21975;-0.1127;0 --0.1912;0.21975;-0.1225;0 --0.1767;0.21975;-0.1329;0 --0.1626;0.21975;-0.1437;0 --0.1488;0.21975;-0.1552;0 --0.1355;0.21975;-0.1671;0 --0.1226;0.21975;-0.1795;0 --0.1099;0.21985;-0.1928;0 --0.0974;0.21965;-0.2069;0 --0.0858;0.22025;-0.2205;0 --0.0742;0.22085;-0.2342;0 --0.0626;0.22145;-0.2478;0 --0.051;0.22205;-0.2614;0 --0.0388;0.22265;-0.2755;0 --0.0263;0.22325;-0.2893;0 --0.0134;0.20795;-0.3024;0 -0;0.20875;-0.3156;0 -0.0139;0.20965;-0.3284;0 -0.0281;0.21035;-0.3409;0 -0.0428;0.21115;-0.353;0 -0.0571;0.19735;-0.364;0 -0.07240000000000001;0.19835;-0.3752;0 -0.0878;0.19925;-0.3859;0 -0.1033;0.20015;-0.3961;0 -0.119;0.20105;-0.4057;0 -0.1349;0.20185;-0.4149;0 -0.1495;0.18945;-0.4226;0 -0.164;0.17735;-0.4297;0 -0.1804;0.17845;-0.4376;0 -0.1953;0.16685;-0.444;0 -0.2102;0.15555;-0.4499;0 -0.2272;0.15665;-0.4565;0 -0.2336;0.15375;-0.4399;0 -0.2503;0.15485;-0.4459;0 -0.2579;0.15205;-0.4303;0 -0.2736;0.15125;-0.4258;0 -0.2858;0.15065;-0.4224;0 -0.2981;0.14785;-0.4067;0 -0.3108;0.14545;-0.3927;0 -0.3215;0.15125;-0.3788;0 -0.3331;0.15675;-0.3666;0 -0.3319;0.15995;-0.3463;0 -0.342;0.16385;-0.3395;0 -0.3338;0.16445;-0.3238;0 -0.3544;0.16755;-0.3356;0 -0.3695;0.17125;-0.3325;0 -0.3846;0.17425;-0.3303;0 -0.4021;0.17725;-0.3275;0 -0.4216;0.17935;-0.3269;0 -0.4409;0.18045;-0.3269;0 -0.4409;0.18385;-0.3079;0 -0.4603;0.18755;-0.2889;0 -0.4603;0.19095;-0.2699;0 -0.4603;0.19425;-0.2509;0 -0.4603;0.19765;-0.2318;0 -0.4603;0.20105;-0.2127;0 -0.4603;0.22235;-0.1969;0 -0.4603;0.22305;-0.1777;0 -0.4603;0.22505;-0.1591;0 -0.4603;0.23805;-0.1794;0 -0.4603;0.25555;-0.1805;0 -0.4415;0.25555;-0.1617;0 -0.4415;0.25555;-0.1429;0 -0.4227;0.25555;-0.1241;0 -0.4039;0.25555;-0.1054;0 -0.4039;0.25555;-0.0866;0 -0.4039;0.25555;-0.0678;0 -0.4039;0.25555;-0.049;0 -0.4039;0.25555;-0.0302;0 -0.3851;0.25555;-0.0114;0 -0.3851;0.25555;0.0074;0 -0.3851;0.25555;0.0262;0 -0.3851;0.25555;0.045;0 -0.3851;0.25555;0.0638;0 -0.3851;0.25555;0.08260000000000001;0 -0.3851;0.25555;0.1014;0 -0.3851;0.25555;0.1202;0 -0.4039;0.25555;0.139;0 -0.4227;0.25555;0.139;0 -0.4415;0.25555;0.139;0 -0.4415;0.25555;0.1578;0 -0.4603;0.25555;0.1578;0 -0.4603;0.23675;0.1578;0 -0.4603;0.21925;0.1585;0 -0.4603;0.20215;0.1626;0 -0.4603;0.18415;0.1658;0 -0.4603;0.18735;0.1836;0 -0.4603;0.19055;0.2015;0 -0.4603;0.19365;0.2193;0 -0.4416;0.19325;0.2194;0 -0.4229;0.19195;0.2196;0 -0.4043;0.18985;0.22;0 -0.3858;0.18685;0.2205;0 -0.3675;0.18305;0.2212;0 -0.3494;0.17845;0.222;0 -0.3315;0.17295;0.223;0 -0.3139;0.16665;0.2241;0 -0.2966;0.15965;0.2253;0 -0.2797;0.15185;0.2267;0 -0.2631;0.14325;0.2282;0 -0.247;0.13385;0.2299;0 -0.2313;0.12385;0.2316;0 -0.2161;0.11305;0.2335;0 -0.2014;0.10165;0.2355;0 -0.1873;0.08955;0.2377;0 -0.1738;0.07675;0.2399;0 -0.1608;0.06345000000000001;0.2423;0 -0.1485;0.04955;0.2447;0 -0.1369;0.03505;0.2473;0 -0.126;0.02015;0.2499;0 -0.1158;0.00465;0.2526;0 -0.1063;-0.01125;0.2554;0 -0.09760000000000001;-0.02755;0.2583;0 -0.0896;-0.04425;0.2613;0 -0.0824;-0.06435;0.2464;0 -0.0761;-0.08484999999999999;0.2316;0 -0.07049999999999999;-0.10245;0.2348;0 -0.0658;-0.12035;0.2379;0 -0.062;-0.14155;0.2232;0 -0.059;-0.15969;0.2264;0 -0.0568;-0.18115;0.2118;0 -0.075;-0.18424;0.2124;0 -0.09229999999999999;-0.20234;0.2156;0 -0.1104;-0.21797;0.2183;0 -0.092;-0.21797;0.2183;0 -0.0735;-0.21797;0.2183;0 -0.0551;-0.21797;0.2183;0 -0.0367;-0.21797;0.2183;0 -0.0182;-0.21795;0.2184;0 --0.0004;-0.21792;0.2186;0 --0.0191;-0.22114;0.2003;0 --0.0397;-0.22113;0.2004;0 --0.037;-0.22486;0.1792;0 --0.0467;-0.22869;0.1575;0 --0.0607;-0.22956;0.1526;0 --0.0578;-0.23185;0.1396;0 --0.073;-0.23226;0.1373;0 --0.0885;-0.2319;0.1393;0 --0.0914;-0.23455;0.1242;0 --0.1143;-0.2349;0.1223;0 --0.1286;-0.23603;0.1159;0 --0.1291;-0.23791;0.1052;0 --0.1294;-0.24018;0.0924;0 --0.1295;-0.24278;0.0776;0 --0.1295;-0.245983;0.0595;0 --0.1295;-0.249172;0.0414;0 --0.1295;-0.252361;0.0233;0 --0.1295;-0.25555;0.0052;0 --0.1418;-0.23719;0.002;0 --0.1536;-0.21887;-0.001;0 --0.1653;-0.20057;-0.004;0 --0.1772;-0.18238;-0.0068;0 --0.1897;-0.1643;-0.0094;0 --0.2029;-0.14635;-0.0119;0 --0.2168;-0.12865;-0.0144;0 --0.2311;-0.11105;-0.0166;0 --0.2459;-0.09375;-0.0187;0 --0.261;-0.07655000000000001;-0.0207;0 --0.2765;-0.05955;-0.0226;0 --0.2924;-0.04255;-0.0244;0 --0.3087;-0.02565;-0.0261;0 --0.3064;-0.00775;-0.0289;0 --0.3031;0.01405;-0.0357;0 --0.3013;0.03725;-0.0476;0 --0.3123;0.04895;-0.0559;0 --0.3197;0.06605;-0.0547;0 --0.3274;0.08355;-0.0534;0 --0.3331;0.10085;-0.0528;0 --0.3398;0.11585;-0.0517;0 --0.3486;0.12705;-0.05;0 --0.3353;0.14665;-0.0542;0 --0.3121;0.15645;-0.0615;0 --0.2971;0.16235;-0.0669;0 --0.2855;0.16685;-0.07140000000000001;0 --0.2708;0.18295;-0.0779;0 --0.253;0.18415;-0.0861;0 --0.237;0.18405;-0.09420000000000001;0 --0.2199;0.18295;-0.1037;0 --0.2214;0.20185;-0.1032;0 --0.2215;0.21975;-0.1034;0 --0.2062;0.23765;-0.1128;0 --0.1913;0.23765;-0.1226;0 --0.1768;0.23765;-0.133;0 --0.1626;0.23765;-0.1438;0 --0.1489;0.23765;-0.1553;0 --0.1356;0.23765;-0.1672;0 --0.1227;0.23765;-0.1797;0 --0.1103;0.23755;-0.1926;0 --0.0974;0.23755;-0.2071;0 --0.0858;0.23785;-0.2207;0 --0.0742;0.23815;-0.2343;0 --0.0626;0.23845;-0.248;0 --0.051;0.23875;-0.2616;0 --0.0388;0.23905;-0.2757;0 --0.0261;0.23935;-0.2895;0 --0.0132;0.22375;-0.3028;0 -0.0002;0.22435;-0.316;0 -0.0141;0.22485;-0.3288;0 -0.0284;0.22545;-0.3413;0 -0.043;0.22595;-0.3533;0 -0.0578;0.21185;-0.3647;0 -0.073;0.21265;-0.3759;0 -0.0885;0.21325;-0.3866;0 -0.1041;0.21395;-0.3968;0 -0.1199;0.21465;-0.4064;0 -0.1358;0.21525;-0.4156;0 -0.1509;0.20265;-0.4235;0 -0.1657;0.19035;-0.4308;0 -0.182;0.19125;-0.4386;0 -0.197;0.17945;-0.445;0 -0.2121;0.16795;-0.451;0 -0.2291;0.16895;-0.4575;0 -0.2444;0.15775;-0.4627;0 -0.2672;0.15575;-0.4515;0 -0.271;0.15305;-0.436;0 -0.2851;0.15365;-0.4394;0 -0.305;0.15195;-0.4299;0 -0.3122;0.14985;-0.4179;0 -0.3247;0.14755;-0.4049;0 -0.3349;0.15305;-0.3905;0 -0.3455;0.15835;-0.3759;0 -0.341;0.16075;-0.356;0 -0.3463;0.16335;-0.3487;0 -0.3561;0.16535;-0.35;0 -0.371;0.16815;-0.3514;0 -0.3872;0.17085;-0.3522;0 -0.4038;0.17365;-0.3488;0 -0.4218;0.17595;-0.3462;0 -0.441;0.17715;-0.346;0 -0.4603;0.18085;-0.327;0 -0.4603;0.18425;-0.308;0 -0.4603;0.21065;-0.3029;0 -0.4603;0.21385;-0.2739;0 -0.4603;0.21555;-0.2549;0 -0.4603;0.21635;-0.2351;0 -0.4603;0.21945;-0.216;0 -0.4603;0.23675;-0.1993;0 -0.4603;0.25555;-0.1993;0 -0.4415;0.25555;-0.1805;0 -0.4227;0.25555;-0.1617;0 -0.4227;0.25555;-0.1429;0 -0.4039;0.25555;-0.1241;0 -0.3851;0.25555;-0.1054;0 -0.3851;0.25555;-0.0866;0 -0.3851;0.25555;-0.0678;0 -0.3851;0.25555;-0.049;0 -0.3851;0.25555;-0.0302;0 -0.3663;0.25555;-0.0114;0 -0.3663;0.25555;0.0074;0 -0.3663;0.25555;0.0262;0 -0.3663;0.25555;0.045;0 -0.3663;0.25555;0.0638;0 -0.3663;0.25555;0.08260000000000001;0 -0.3663;0.25555;0.1014;0 -0.3663;0.25555;0.1201;0 -0.385;0.25555;0.1389;0 -0.4038;0.25555;0.1577;0 -0.4227;0.25555;0.1578;0 -0.4415;0.25555;0.1765;0 -0.4603;0.25555;0.1765;0 -0.4603;0.23675;0.1765;0 -0.4603;0.22205;0.1778;0 -0.4603;0.20535;0.1805;0 -0.4603;0.20855;0.1983;0 -0.4603;0.20985;0.2166;0 -0.4603;0.19675;0.2371;0 -0.4416;0.19635;0.2372;0 -0.4229;0.19505;0.2375;0 -0.4043;0.19295;0.2378;0 -0.3858;0.18995;0.2384;0 -0.3675;0.18615;0.239;0 -0.3494;0.18155;0.2398;0 -0.3315;0.17605;0.2408;0 -0.3139;0.16985;0.2419;0 -0.2966;0.16275;0.2431;0 -0.2797;0.15495;0.2445;0 -0.2631;0.14635;0.246;0 -0.247;0.13705;0.2477;0 -0.2313;0.12695;0.2495;0 -0.2161;0.11615;0.2514;0 -0.2014;0.10475;0.2534;0 -0.1873;0.09265;0.2555;0 -0.1738;0.07994999999999999;0.2578;0 -0.1608;0.06655;0.2601;0 -0.1485;0.05265;0.2626;0 -0.1369;0.03825;0.2651;0 -0.126;0.02325;0.2678;0 -0.1158;0.007849999999999999;0.2705;0 -0.1063;-0.00805;0.2733;0 -0.09760000000000001;-0.02435;0.2762;0 -0.0896;-0.04105;0.2791;0 -0.0824;-0.06125;0.2642;0 -0.0761;-0.08175;0.2495;0 -0.07049999999999999;-0.09934999999999999;0.2526;0 -0.0658;-0.11715;0.2557;0 -0.062;-0.13835;0.2411;0 -0.059;-0.15655;0.2443;0 -0.0568;-0.178;0.2297;0 -0.0555;-0.19953;0.2151;0 -0.07389999999999999;-0.20184;0.2155;0 -0.0555;-0.19639;0.2329;0 -0.0551;-0.21482;0.2362;0 -0.0368;-0.21482;0.2362;0 -0.0184;-0.21481;0.2363;0 -0;-0.21476;0.2365;0 --0.0185;-0.2147;0.2368;0 --0.019;-0.21788;0.2189;0 --0.0388;-0.21781;0.2192;0 --0.0553;-0.21731;0.222;0 --0.056;-0.22161;0.1977;0 --0.0514;-0.2257;0.1745;0 --0.0684;-0.22712;0.1664;0 --0.0722;-0.23049;0.1473;0 --0.0815;-0.22937;0.1537;0 --0.1031;-0.22752;0.1642;0 --0.1191;-0.23179;0.14;0 --0.14;-0.23475;0.1232;0 --0.1465;-0.23751;0.1075;0 --0.1482;-0.24025;0.092;0 --0.1479;-0.24278;0.0776;0 --0.1479;-0.245983;0.0595;0 --0.1479;-0.249172;0.0414;0 --0.1479;-0.252361;0.0233;0 --0.1479;-0.25555;0.0052;0 --0.1598;-0.23721;0.002;0 --0.1714;-0.21888;-0.001;0 --0.1828;-0.2006;-0.004;0 --0.1946;-0.1824;-0.0068;0 --0.2071;-0.16433;-0.0094;0 --0.2203;-0.14645;-0.0119;0 --0.2343;-0.12865;-0.0143;0 --0.2488;-0.11115;-0.0166;0 --0.2638;-0.09375;-0.0187;0 --0.2791;-0.07655000000000001;-0.0207;0 --0.2949;-0.05955;-0.0226;0 --0.311;-0.04255;-0.0244;0 --0.3277;-0.02565;-0.0261;0 --0.3268;-0.008449999999999999;-0.0288;0 --0.3285;0.00735;-0.0332;0 --0.3183;0.02935;-0.0429;0 --0.328;0.04165;-0.0505;0 --0.3356;0.05845;-0.0496;0 --0.3434;0.07565;-0.0486;0 --0.3488;0.09404999999999999;-0.0483;0 --0.3526;0.10865;-0.0482;0 --0.3554;0.11745;-0.048;0 --0.36061;0.13385;-0.0475;0 --0.3554;0.15435;-0.0495;0 --0.3348;0.17545;-0.0552;0 --0.317;0.17895;-0.0606;0 --0.3007;0.18075;-0.06610000000000001;0 --0.2857;0.18215;-0.0717;0 --0.2857;0.20205;-0.0722;0 --0.2693;0.20205;-0.079;0 --0.2531;0.20195;-0.0864;0 --0.2371;0.20185;-0.0946;0 --0.2371;0.21975;-0.0948;0 --0.2372;0.23765;-0.0949;0 --0.2216;0.23765;-0.1036;0 --0.2216;0.25555;-0.1036;0 --0.2062;0.25555;-0.1129;0 --0.1913;0.25555;-0.1227;0 --0.1768;0.25555;-0.133;0 --0.1626;0.25555;-0.1439;0 --0.1489;0.25555;-0.1553;0 --0.1356;0.25555;-0.1672;0 --0.1227;0.25555;-0.1797;0 --0.1103;0.25555;-0.1926;0 --0.0974;0.25555;-0.2071;0 --0.0858;0.25555;-0.2208;0 --0.0742;0.25555;-0.2344;0 --0.0626;0.25555;-0.248;0 --0.051;0.25555;-0.2616;0 --0.0387;0.25555;-0.2758;0 --0.026;0.25555;-0.2897;0 --0.0131;0.23965;-0.303;0 -0.0004;0.23995;-0.3162;0 -0.0142;0.24025;-0.329;0 -0.0284;0.24045;-0.3414;0 -0.043;0.24075;-0.3534;0 -0.058;0.22645;-0.365;0 -0.0732;0.22695;-0.3762;0 -0.0887;0.22735;-0.3869;0 -0.1044;0.22785;-0.3971;0 -0.1202;0.22825;-0.4068;0 -0.1363;0.22865;-0.416;0 -0.1519;0.21585;-0.4243;0 -0.1671;0.20335;-0.4318;0 -0.1835;0.20405;-0.4395;0 -0.1986;0.19215;-0.446;0 -0.2138;0.18045;-0.452;0 -0.2307;0.18125;-0.4585;0 -0.2462;0.16995;-0.4637;0 -0.2617;0.15875;-0.4684;0 -0.2824;0.15665;-0.4563;0 -0.302;0.15435;-0.4432;0 -0.3165;0.15285;-0.4349;0 -0.3265;0.15165;-0.4277;0 -0.3393;0.14965;-0.4164;0 -0.3489;0.15465;-0.4015;0 -0.3594;0.15965;-0.3865;0 -0.3684;0.16445;-0.3698;0 -0.3528;0.16245;-0.3624;0 -0.3877;0.16635;-0.3779;0 -0.4082;0.17055;-0.3693;0 -0.4235;0.17235;-0.3672;0 -0.441;0.17375;-0.365;0 -0.4603;0.17755;-0.3461;0 -0.4603;0.19615;-0.3321;0 -0.4603;0.20085;-0.3178;0 -0.4603;0.21925;-0.3197;0 -0.4603;0.23645;-0.2965;0 -0.4603;0.23675;-0.2745;0 -0.4603;0.23675;-0.2557;0 -0.4603;0.23675;-0.2369;0 -0.4603;0.23675;-0.2181;0 -0.4603;0.25555;-0.2181;0 -0.4415;0.25555;-0.1993;0 -0.4227;0.25555;-0.1805;0 -0.4039;0.25555;-0.1617;0 -0.4039;0.25555;-0.1429;0 -0.3851;0.25555;-0.1241;0 -0.3663;0.25555;-0.1054;0 -0.3663;0.25555;-0.0866;0 -0.3663;0.25555;-0.0678;0 -0.3663;0.25555;-0.049;0 -0.3663;0.25555;-0.0302;0 -0.3475;0.25555;-0.0114;0 -0.3475;0.25555;0.0074;0 -0.3475;0.25555;0.0262;0 -0.3475;0.25555;0.045;0 -0.3475;0.25555;0.0638;0 -0.3475;0.25555;0.08260000000000001;0 -0.3475;0.25555;0.1013;0 -0.3474;0.25555;0.1201;0 -0.3662;0.25555;0.1389;0 -0.385;0.25555;0.1577;0 -0.4038;0.25555;0.1765;0 -0.4226;0.25555;0.1765;0 -0.4415;0.25555;0.1953;0 -0.4603;0.25555;0.1953;0 -0.4603;0.23845;0.1951;0 -0.4603;0.22365;0.1961;0 -0.4603;0.22385;0.2146;0 -0.4603;0.22585;0.2326;0 -0.4603;0.21285;0.2345;0 -0.4603;0.19995;0.255;0 -0.4416;0.19955;0.2551;0 -0.4229;0.19825;0.2553;0 -0.4043;0.19615;0.2557;0 -0.3858;0.19315;0.2562;0 -0.3675;0.18935;0.2569;0 -0.3494;0.18475;0.2577;0 -0.3315;0.17925;0.2586;0 -0.3139;0.17295;0.2597;0 -0.2966;0.16595;0.261;0 -0.2797;0.15815;0.2624;0 -0.2631;0.14955;0.2639;0 -0.247;0.14015;0.2655;0 -0.2313;0.13015;0.2673;0 -0.2161;0.11935;0.2692;0 -0.2014;0.10785;0.2712;0 -0.1873;0.09575;0.2733;0 -0.1738;0.08305;0.2756;0 -0.1608;0.06975000000000001;0.2779;0 -0.1485;0.05585;0.2804;0 -0.1369;0.04135;0.283;0 -0.126;0.02645;0.2856;0 -0.1158;0.01095;0.2883;0 -0.1063;-0.00495;0.2911;0 -0.09760000000000001;-0.02125;0.294;0 -0.0896;-0.03795;0.2969;0 -0.0824;-0.05805;0.2821;0 -0.0761;-0.07854999999999999;0.2673;0 -0.07049999999999999;-0.09615;0.2704;0 -0.0658;-0.11405;0.2736;0 -0.062;-0.13525;0.2589;0 -0.059;-0.15345;0.2621;0 -0.0568;-0.17486;0.2475;0 -0.0555;-0.19325;0.2507;0 -0.0551;-0.21168;0.254;0 -0.0369;-0.21168;0.254;0 -0.0186;-0.21167;0.254;0 -0.0004;-0.21165;0.2542;0 --0.0161;-0.2116;0.2545;0 --0.0298;-0.21159;0.2545;0 --0.0342;-0.2144;0.2386;0 --0.0474;-0.21363;0.2429;0 --0.07969999999999999;-0.21641;0.2272;0 --0.0829;-0.22282;0.1908;0 --0.1206;-0.21981;0.2079;0 --0.1348;-0.22511;0.1778;0 --0.1503;-0.22956;0.1526;0 --0.1632;-0.23318;0.132;0 --0.1774;-0.23773;0.1063;0 --0.1712;-0.24093;0.0881;0 --0.1678;-0.24336;0.07439999999999999;0 --0.1662;-0.245983;0.0595;0 --0.1662;-0.249172;0.0414;0 --0.1662;-0.252361;0.0233;0 --0.1662;-0.25555;0.0052;0 --0.1779;-0.23721;0.002;0 --0.1891;-0.2189;-0.001;0 --0.2003;-0.20062;-0.004;0 --0.212;-0.18243;-0.0068;0 --0.2244;-0.16436;-0.0094;0 --0.2377;-0.14645;-0.0119;0 --0.2517;-0.12875;-0.0143;0 --0.2664;-0.11115;-0.0166;0 --0.2816;-0.09375;-0.0187;0 --0.2973;-0.07655000000000001;-0.0207;0 --0.3132;-0.05955;-0.0226;0 --0.3297;-0.04265;-0.0244;0 --0.3466;-0.02565;-0.0261;0 --0.3449;-0.00805;-0.0289;0 --0.3415;0.00435;-0.0322;0 --0.3352;0.02075;-0.0386;0 --0.3442;0.03385;-0.0456;0 --0.3545;0.04945;-0.0442;0 --0.36859;0.06795;-0.0425;0 --0.36566;0.09105000000000001;-0.0444;0 --0.36476;0.10745;-0.0455;0 --0.36452;0.11955;-0.0461;0 --0.37624;0.12115;-0.0439;0 --0.37393;0.13845;-0.0451;0 --0.3701;0.15865;-0.0465;0 --0.3523;0.17795;-0.0509;0 --0.3361;0.20005;-0.0555;0 --0.3194;0.20195;-0.0603;0 --0.3023;0.20195;-0.066;0 --0.3024;0.21975;-0.06619999999999999;0 --0.2858;0.21985;-0.07240000000000001;0 --0.2694;0.21985;-0.07920000000000001;0 --0.2531;0.21985;-0.0867;0 --0.2532;0.23765;-0.0868;0 --0.2372;0.25555;-0.0949;0 --0.2272;0.25555;-0.07969999999999999;0 --0.211;0.25555;-0.0887;0 --0.1952;0.25555;-0.0984;0 --0.1797;0.25555;-0.1086;0 --0.1646;0.25555;-0.1194;0 --0.15;0.25555;-0.1308;0 --0.1358;0.25555;-0.1427;0 --0.122;0.25555;-0.1551;0 --0.1087;0.25555;-0.1681;0 --0.096;0.25555;-0.1816;0 --0.0838;0.25555;-0.1954;0 --0.0721;0.25555;-0.2091;0 --0.0604;0.25555;-0.2226;0 --0.0487;0.25555;-0.2361;0 --0.0369;0.25555;-0.2495;0 --0.0248;0.25555;-0.2635;0 --0.0125;0.25555;-0.277;0 -0.0002;0.25555;-0.2901;0 --0.013;0.25555;-0.3032;0 -0.0005;0.25555;-0.3164;0 -0.0143;0.25555;-0.3291;0 -0.0284;0.25555;-0.3414;0 -0.0429;0.25555;-0.3534;0 -0.0577;0.25555;-0.3649;0 -0.0579;0.24095;-0.365;0 -0.0731;0.24125;-0.3762;0 -0.0886;0.24145;-0.3869;0 -0.1043;0.24165;-0.3971;0 -0.1202;0.24185;-0.4068;0 -0.1364;0.24205;-0.4161;0 -0.1525;0.22905;-0.4247;0 -0.1682;0.21635;-0.4325;0 -0.1847;0.21695;-0.4402;0 -0.2001;0.20475;-0.4468;0 -0.2154;0.19285;-0.4529;0 -0.2324;0.19365;-0.4593;0 -0.2479;0.18205;-0.4645;0 -0.2636;0.17085;-0.4693;0 -0.2792;0.15965;-0.4736;0 -0.2996;0.15745;-0.4608;0 -0.3178;0.15495;-0.4467;0 -0.3381;0.15445;-0.4438;0 -0.3547;0.15145;-0.427;0 -0.3634;0.15605;-0.4116;0 -0.3752;0.16085;-0.3972;0 -0.3982;0.16455;-0.3968;0 -0.4116;0.16735;-0.3898;0 -0.4255;0.16905;-0.3869;0 -0.441;0.17045;-0.3841;0 -0.4603;0.17415;-0.3651;0 -0.4603;0.19285;-0.3498;0 -0.4603;0.20825;-0.3342;0 -0.4603;0.20915;-0.3238;0 -0.4603;0.22075;-0.3334;0 -0.4603;0.23675;-0.3309;0 -0.4603;0.23655;-0.3158;0 -0.4603;0.25555;-0.3121;0 -0.4603;0.25555;-0.2933;0 -0.4603;0.25555;-0.2745;0 -0.4603;0.25555;-0.2557;0 -0.4603;0.25555;-0.2369;0 -0.4415;0.25555;-0.2181;0 -0.4227;0.25555;-0.1993;0 -0.4039;0.25555;-0.1805;0 -0.3851;0.25555;-0.1617;0 -0.3851;0.25555;-0.1429;0 -0.3663;0.25555;-0.1241;0 -0.3475;0.25555;-0.1054;0 -0.3475;0.25555;-0.0866;0 -0.3475;0.25555;-0.0678;0 -0.3475;0.25555;-0.049;0 -0.3475;0.25555;-0.0302;0 -0.3287;0.25555;-0.0114;0 -0.3287;0.25555;0.0074;0 -0.3287;0.25555;0.0262;0 -0.3287;0.25555;0.045;0 -0.3287;0.25555;0.0638;0 -0.3287;0.25555;0.0825;0 -0.3286;0.25555;0.1013;0 -0.3284;0.25555;0.1199;0 -0.3471;0.25555;0.1387;0 -0.366;0.25555;0.1576;0 -0.3848;0.25555;0.1764;0 -0.4037;0.25555;0.1953;0 -0.4226;0.25555;0.1953;0 -0.4414;0.25555;0.2141;0 -0.4603;0.25555;0.2141;0 -0.4603;0.23925;0.2143;0 -0.4603;0.23925;0.2324;0 -0.4603;0.22835;0.2498;0 -0.4603;0.21665;0.2519;0 -0.4603;0.21975;0.2658;0 -0.4603;0.20305;0.2728;0 -0.4416;0.20265;0.2729;0 -0.4229;0.20135;0.2731;0 -0.4043;0.19925;0.2735;0 -0.3858;0.19625;0.274;0 -0.3675;0.19245;0.2747;0 -0.3494;0.18785;0.2755;0 -0.3315;0.18235;0.2765;0 -0.3139;0.17615;0.2776;0 -0.2966;0.16905;0.2788;0 -0.2797;0.16125;0.2802;0 -0.2631;0.15265;0.2817;0 -0.247;0.14335;0.2834;0 -0.2313;0.13325;0.2852;0 -0.2161;0.12245;0.287;0 -0.2014;0.11105;0.2891;0 -0.1873;0.09895;0.2912;0 -0.1738;0.08624999999999999;0.2934;0 -0.1608;0.07285;0.2958;0 -0.1485;0.05895;0.2982;0 -0.1369;0.04455;0.3008;0 -0.126;0.02955;0.3034;0 -0.1158;0.01415;0.3061;0 -0.1063;-0.00175;0.3089;0 -0.09760000000000001;-0.01805;0.3118;0 -0.0896;-0.03475;0.3148;0 -0.0824;-0.05495;0.2999;0 -0.0761;-0.07545;0.2852;0 -0.07049999999999999;-0.09304999999999999;0.2883;0 -0.0658;-0.11085;0.2914;0 -0.062;-0.13205;0.2767;0 -0.059;-0.15025;0.28;0 -0.0568;-0.17172;0.2653;0 -0.0555;-0.1901;0.2686;0 -0.0551;-0.20854;0.2718;0 -0.0369;-0.20854;0.2718;0 -0.0187;-0.20854;0.2719;0 -0.0005999999999999999;-0.20851;0.272;0 --0.0176;-0.20849;0.2721;0 --0.032;-0.20887;0.2699;0 --0.0397;-0.21151;0.2549;0 --0.0636;-0.21095;0.2581;0 --0.1036;-0.21038;0.2614;0 --0.1112;-0.21514;0.2344;0 --0.1396;-0.21412;0.2401;0 --0.1487;-0.21846;0.2156;0 --0.1609;-0.22288;0.1905;0 --0.1756;-0.22685;0.168;0 --0.1907;-0.23051;0.1472;0 --0.2158;-0.23576;0.1175;0 --0.1963;-0.24108;0.0873;0 --0.1844;-0.24218;0.081;0 --0.1843;-0.244;0.0707;0 --0.1847;-0.246318;0.0575;0 --0.1846;-0.249172;0.0414;0 --0.1846;-0.252361;0.0233;0 --0.1846;-0.25555;0.0052;0 --0.196;-0.23722;0.002;0 --0.2069;-0.2189;-0.001;0 --0.2179;-0.20063;-0.004;0 --0.2294;-0.18246;-0.0067;0 --0.2417;-0.16439;-0.0094;0 --0.255;-0.14645;-0.0119;0 --0.2692;-0.12875;-0.0143;0 --0.2841;-0.11115;-0.0166;0 --0.2995;-0.09385;-0.0187;0 --0.3154;-0.07665;-0.0207;0 --0.3316;-0.05965;-0.0226;0 --0.3483;-0.04265;-0.0244;0 --0.36557;-0.02565;-0.0261;0 --0.36434;-0.00175;-0.0304;0 --0.3505;0.01285;-0.0353;0 --0.36046;0.02595;-0.0412;0 --0.36955;0.04115;-0.0404;0 --0.37964;0.05525;-0.0396;0 --0.38359;0.07245;-0.04;0 --0.38091;0.08964999999999999;-0.0415;0 --0.37815;0.10625;-0.0429;0 --0.38866;0.12355;-0.042;0 --0.38843;0.14065;-0.0427;0 --0.38639;0.16115;-0.0438;0 --0.36815;0.18005;-0.0475;0 --0.3533;0.20175;-0.0512;0 --0.3366;0.21975;-0.0556;0 --0.3194;0.21975;-0.0606;0 --0.3025;0.23765;-0.0663;0 --0.2859;0.23765;-0.0725;0 --0.2694;0.23765;-0.0794;0 --0.2532;0.25555;-0.08690000000000001;0 --0.2438;0.25555;-0.0712;0 --0.2183;0.25555;-0.063;0 --0.2015;0.25555;-0.07240000000000001;0 --0.185;0.25555;-0.0825;0 --0.169;0.25555;-0.0931;0 --0.1534;0.25555;-0.1043;0 --0.1382;0.25555;-0.1161;0 --0.1234;0.25555;-0.1285;0 --0.1092;0.25555;-0.1416;0 --0.0956;0.25555;-0.1551;0 --0.08260000000000001;0.25555;-0.1693;0 --0.0703;0.25555;-0.1836;0 --0.0585;0.25555;-0.1974;0 --0.0468;0.25555;-0.2109;0 --0.0351;0.25555;-0.2243;0 --0.0233;0.25555;-0.2377;0 --0.0114;0.25555;-0.2515;0 -0.0005999999999999999;0.25555;-0.2646;0 -0.0129;0.25555;-0.2774;0 -0.0255;0.25555;-0.2898;0 -0.0133;0.25555;-0.3029;0 -0.0267;0.25555;-0.3154;0 -0.0404;0.25555;-0.3273;0 -0.0545;0.25555;-0.3389;0 -0.0689;0.25555;-0.3501;0 -0.0727;0.25555;-0.376;0 -0.0883;0.25555;-0.3867;0 -0.104;0.25555;-0.397;0 -0.12;0.25555;-0.4067;0 -0.1363;0.25555;-0.4161;0 -0.1528;0.24225;-0.4249;0 -0.1689;0.22945;-0.433;0 -0.1856;0.22975;-0.4407;0 -0.2014;0.21745;-0.4475;0 -0.2169;0.20535;-0.4537;0 -0.2339;0.20595;-0.4601;0 -0.2495;0.19435;-0.4653;0 -0.2651;0.18285;-0.4701;0 -0.281;0.17165;-0.4745;0 -0.2968;0.16055;-0.4783;0 -0.3169;0.15815;-0.4648;0 -0.336;0.15885;-0.4689;0 -0.3611;0.15675;-0.4571;0 -0.3708;0.15315;-0.4365;0 -0.3803;0.15755;-0.4209;0 -0.3893;0.16135;-0.4079;0 -0.4059;0.16395;-0.4051;0 -0.4153;0.16505;-0.4047;0 -0.428;0.16605;-0.4048;0 -0.4429;0.16705;-0.4034;0 -0.4603;0.17075;-0.3841;0 -0.4603;0.19055;-0.3681;0 -0.4603;0.20595;-0.3518;0 -0.4603;0.21985;-0.3517;0 -0.4603;0.23675;-0.3497;0 -0.4603;0.25555;-0.3309;0 -0.4415;0.25555;-0.3121;0 -0.4415;0.25555;-0.2933;0 -0.4415;0.25555;-0.2745;0 -0.4415;0.25555;-0.2557;0 -0.4415;0.25555;-0.2369;0 -0.4227;0.25555;-0.2181;0 -0.4039;0.25555;-0.1993;0 -0.3851;0.25555;-0.1805;0 -0.3663;0.25555;-0.1617;0 -0.3663;0.25555;-0.1429;0 -0.3475;0.25555;-0.1241;0 -0.3287;0.25555;-0.1054;0 -0.3287;0.25555;-0.0866;0 -0.3287;0.25555;-0.0678;0 -0.3287;0.25555;-0.049;0 -0.3287;0.25555;-0.0302;0 -0.3099;0.25555;-0.0114;0 -0.31;0.25555;0.0074;0 -0.31;0.25555;0.0262;0 -0.31;0.25555;0.045;0 -0.31;0.25555;0.0638;0 -0.3098;0.25555;0.0798;0 -0.3099;0.25555;0.1011;0 -0.3091;0.25555;0.1189;0 -0.3278;0.25555;0.1384;0 -0.3466;0.25555;0.1573;0 -0.3656;0.25555;0.1762;0 -0.3846;0.25555;0.1951;0 -0.4035;0.25555;0.214;0 -0.4226;0.25555;0.2141;0 -0.4414;0.25555;0.2329;0 -0.4603;0.25555;0.2329;0 -0.4603;0.24085;0.2506;0 -0.4603;0.22895;0.2596;0 -0.4603;0.23915;0.2646;0 -0.4603;0.23095;0.2812;0 -0.4603;0.20625;0.2907;0 -0.4416;0.20575;0.2907;0 -0.4229;0.20455;0.291;0 -0.4043;0.20245;0.2913;0 -0.3858;0.19945;0.2919;0 -0.3675;0.19565;0.2925;0 -0.3494;0.19095;0.2933;0 -0.3315;0.18555;0.2943;0 -0.3139;0.17925;0.2954;0 -0.2966;0.17225;0.2967;0 -0.2797;0.16435;0.298;0 -0.2631;0.15575;0.2996;0 -0.247;0.14645;0.3012;0 -0.2313;0.13635;0.303;0 -0.2161;0.12565;0.3049;0 -0.2014;0.11415;0.3069;0 -0.1873;0.10205;0.309;0 -0.1738;0.08935;0.3113;0 -0.1608;0.07605000000000001;0.3136;0 -0.1485;0.06215;0.3161;0 -0.1369;0.04765;0.3186;0 -0.126;0.03265;0.3213;0 -0.1158;0.01725;0.324;0 -0.1063;0.00135;0.3268;0 -0.09760000000000001;-0.01495;0.3297;0 -0.0896;-0.03165;0.3326;0 -0.0824;-0.05185;0.3178;0 -0.0761;-0.07224999999999999;0.303;0 -0.07049999999999999;-0.08985;0.3061;0 -0.0658;-0.10775;0.3092;0 -0.062;-0.12895;0.2946;0 -0.059;-0.14715;0.2978;0 -0.0568;-0.16857;0.2832;0 -0.0555;-0.18696;0.2864;0 -0.0551;-0.20539;0.2897;0 -0.0369;-0.20539;0.2897;0 -0.0188;-0.20538;0.2897;0 -0.0007;-0.20538;0.2897;0 --0.0174;-0.20536;0.2898;0 --0.0341;-0.20558;0.2886;0 --0.047;-0.20594;0.2866;0 --0.0453;-0.20947;0.2666;0 --0.06519999999999999;-0.20596;0.2865;0 --0.1007;-0.20561;0.2884;0 --0.1282;-0.20541;0.2896;0 --0.1328;-0.20974;0.265;0 --0.1579;-0.20927;0.2677;0 --0.165;-0.21327;0.2449;0 --0.174;-0.21708;0.2234;0 --0.1849;-0.22091;0.2016;0 --0.1987;-0.22447;0.1815;0 --0.214;-0.22775;0.1629;0 --0.2339;-0.2313;0.1427;0 --0.2438;-0.23733;0.1085;0 --0.2178;-0.24029;0.0917;0 --0.1996;-0.24348;0.0736;0 --0.2017;-0.246211;0.0582;0 --0.203;-0.249172;0.0414;0 --0.203;-0.252361;0.0233;0 --0.203;-0.25555;0.0052;0 --0.214;-0.23722;0.002;0 --0.2247;-0.21891;-0.001;0 --0.2354;-0.20066;-0.004;0 --0.2467;-0.18247;-0.0067;0 --0.259;-0.16442;-0.0094;0 --0.2724;-0.14655;-0.0119;0 --0.2867;-0.12875;-0.0143;0 --0.3018;-0.11125;-0.0166;0 --0.3174;-0.09385;-0.0187;0 --0.3335;-0.07675;-0.0207;0 --0.35;-0.05975;-0.0226;0 --0.36699;-0.04285;-0.0244;0 --0.38452;-0.02565;-0.0261;0 --0.38874;-0.007849999999999999;-0.0289;0 --0.37673;0.01785;-0.0373;0 --0.38507;0.03445;-0.0372;0 --0.3908;0.04895;-0.0374;0 --0.38686;0.06304999999999999;-0.0389;0 --0.39461;0.07285;-0.0384;0 --0.39344;0.08885;-0.0395;0 --0.39139;0.10565;-0.0407;0 --0.4054;0.12365;-0.0397;0 --0.40477;0.14255;-0.0406;0 --0.40444;0.16145;-0.0413;0 --0.40427;0.18025;-0.0419;0 --0.38591;0.18025;-0.0444;0 --0.36988;0.20115;-0.0477;0 --0.3539;0.21965;-0.0513;0 --0.354;0.23765;-0.0515;0 --0.3367;0.23765;-0.0558;0 --0.3195;0.23765;-0.0607;0 --0.3195;0.25555;-0.0608;0 --0.3025;0.25555;-0.0664;0 --0.2859;0.25555;-0.0726;0 --0.2694;0.25555;-0.0794;0 --0.2606;0.25555;-0.0634;0 --0.253;0.25555;-0.0461;0 --0.2355;0.25555;-0.0542;0 --0.2091;0.25555;-0.0457;0 --0.1916;0.25555;-0.0555;0 --0.1745;0.25555;-0.0659;0 --0.1579;0.25555;-0.077;0 --0.1417;0.25555;-0.0886;0 --0.1259;0.25555;-0.101;0 --0.1107;0.25555;-0.114;0 --0.096;0.25555;-0.1277;0 --0.08210000000000001;0.25555;-0.1422;0 --0.06900000000000001;0.25555;-0.1572;0 --0.0567;0.25555;-0.172;0 --0.0452;0.25555;-0.1857;0 --0.0336;0.25555;-0.1991;0 --0.022;0.25555;-0.2124;0 --0.0105;0.25555;-0.2258;0 -0.0009;0.25555;-0.2392;0 -0.0125;0.25555;-0.2519;0 -0.0244;0.25555;-0.2644;0 -0.0367;0.25555;-0.2765;0 -0.0493;0.25555;-0.2882;0 -0.0385;0.25555;-0.3019;0 -0.0519;0.25555;-0.3135;0 -0.06560000000000001;0.25555;-0.3248;0 -0.0796;0.25555;-0.3357;0 -0.094;0.25555;-0.3461;0 -0.0835;0.25555;-0.3608;0 -0.09859999999999999;0.25555;-0.3713;0 -0.1139;0.25555;-0.3813;0 -0.1295;0.25555;-0.3907;0 -0.1453;0.25555;-0.3998;0 -0.1614;0.25555;-0.4085;0 -0.1529;0.25555;-0.425;0 -0.1694;0.24245;-0.4332;0 -0.1862;0.24265;-0.4411;0 -0.2024;0.23015;-0.4481;0 -0.2183;0.21795;-0.4544;0 -0.2353;0.21835;-0.4607;0 -0.251;0.20655;-0.466;0 -0.2667;0.19495;-0.4708;0 -0.2826;0.18355;-0.4751;0 -0.2987;0.17235;-0.4791;0 -0.3146;0.16125;-0.4826;0 -0.3324;0.16195;-0.4863;0 -0.3543;0.15975;-0.4738;0 -0.3677;0.16085;-0.4799;0 -0.3811;0.15935;-0.4716;0 -0.3876;0.15455;-0.4446;0 -0.3943;0.15845;-0.4283;0 -0.4015;0.16185;-0.4145;0 -0.4139;0.16265;-0.4177;0 -0.4278;0.16325;-0.4204;0 -0.443;0.16375;-0.4221;0 -0.4603;0.16405;-0.4222;0 -0.4603;0.16745;-0.4032;0 -0.4603;0.18985;-0.3875;0 -0.4603;0.20405;-0.3697;0 -0.4603;0.21885;-0.3688;0 -0.4603;0.23675;-0.3685;0 -0.4603;0.25555;-0.3497;0 -0.4415;0.25555;-0.3309;0 -0.4227;0.25555;-0.3121;0 -0.4227;0.25555;-0.2933;0 -0.4227;0.25555;-0.2745;0 -0.4227;0.25555;-0.2557;0 -0.4227;0.25555;-0.2369;0 -0.4039;0.25555;-0.2181;0 -0.3851;0.25555;-0.1993;0 -0.3663;0.25555;-0.1805;0 -0.3475;0.25555;-0.1617;0 -0.3475;0.25555;-0.1429;0 -0.3287;0.25555;-0.1241;0 -0.3099;0.25555;-0.1054;0 -0.3099;0.25555;-0.0866;0 -0.3099;0.25555;-0.0678;0 -0.3099;0.25555;-0.049;0 -0.3099;0.25555;-0.0302;0 -0.2912;0.25555;-0.0114;0 -0.2912;0.25555;0.0074;0 -0.2913;0.25555;0.0262;0 -0.2914;0.25555;0.045;0 -0.2911;0.25555;0.0616;0 -0.2902;0.25555;0.0766;0 -0.2885;0.25555;0.0988;0 -0.2849;0.25555;0.1177;0 -0.3059;0.25555;0.1375;0 -0.3263;0.25555;0.1561;0 -0.3456;0.25555;0.1756;0 -0.3648;0.25555;0.1947;0 -0.384;0.25555;0.2138;0 -0.4032;0.25555;0.2328;0 -0.4225;0.25555;0.2329;0 -0.4414;0.25555;0.2517;0 -0.4603;0.25555;0.2517;0 -0.4603;0.25555;0.2705;0 -0.4603;0.25555;0.2893;0 -0.4603;0.23245;0.3082;0 -0.4603;0.20935;0.3085;0 -0.4417;0.20895;0.3086;0 -0.4231;0.20765;0.3088;0 -0.4045;0.20555;0.3092;0 -0.386;0.20265;0.3097;0 -0.3677;0.19885;0.3104;0 -0.3496;0.19415;0.3112;0 -0.3317;0.18875;0.3121;0 -0.314;0.18245;0.3132;0 -0.2967;0.17545;0.3145;0 -0.2797;0.16755;0.3159;0 -0.2632;0.15895;0.3174;0 -0.247;0.14965;0.319;0 -0.2314;0.13955;0.3208;0 -0.2162;0.12885;0.3227;0 -0.2015;0.11735;0.3247;0 -0.1874;0.10525;0.3268;0 -0.1738;0.09254999999999999;0.3291;0 -0.1609;0.07925;0.3314;0 -0.1486;0.06535000000000001;0.3339;0 -0.137;0.05085;0.3364;0 -0.126;0.03595;0.3391;0 -0.1158;0.02045;0.3418;0 -0.1063;0.00455;0.3446;0 -0.09760000000000001;-0.01175;0.3475;0 -0.0897;-0.02845;0.3504;0 -0.0825;-0.04545;0.3534;0 -0.0824;-0.04865;0.3356;0 -0.0761;-0.06915;0.3208;0 -0.07049999999999999;-0.08674999999999999;0.3239;0 -0.0658;-0.10455;0.3271;0 -0.062;-0.12575;0.3124;0 -0.059;-0.14395;0.3156;0 -0.0568;-0.16543;0.301;0 -0.0555;-0.18382;0.3043;0 -0.0551;-0.20225;0.3075;0 -0.0369;-0.20225;0.3075;0 -0.0188;-0.20224;0.3075;0 -0.0007;-0.20224;0.3076;0 --0.0176;-0.2026;0.3055;0 --0.0346;-0.2032;0.3021;0 --0.045;-0.20378;0.2989;0 --0.0571;-0.20196;0.3092;0 --0.0961;-0.20127;0.313;0 --0.1245;-0.2014;0.3123;0 --0.149;-0.20127;0.313;0 --0.1525;-0.20527;0.2903;0 --0.1722;-0.20507;0.2915;0 --0.1772;-0.20883;0.2702;0 --0.1843;-0.21249;0.2494;0 --0.1935;-0.21603;0.2293;0 --0.2047;-0.21942;0.2101;0 --0.2178;-0.22259;0.1921;0 --0.2327;-0.22552;0.1755;0 --0.2499;-0.22822;0.1601;0 --0.2539;-0.23382;0.1284;0 --0.2602;-0.23896;0.0992;0 --0.2509;-0.24095;0.08799999999999999;0 --0.2385;-0.24052;0.09039999999999999;0 --0.2196;-0.24311;0.0757;0 --0.2214;-0.245983;0.0595;0 --0.2214;-0.249172;0.0414;0 --0.2214;-0.252361;0.0233;0 --0.2214;-0.25555;0.0052;0 --0.2321;-0.23724;0.002;0 --0.2424;-0.21893;-0.001;0 --0.2529;-0.20068;-0.004;0 --0.2641;-0.18251;-0.0067;0 --0.2764;-0.16445;-0.0094;0 --0.2897;-0.14655;-0.0119;0 --0.3042;-0.12885;-0.0143;0 --0.3194;-0.11135;-0.0166;0 --0.3353;-0.09404999999999999;-0.0187;0 --0.3516;-0.07695;-0.0207;0 --0.36838;-0.06005;-0.0225;0 --0.38565;-0.04305;-0.0243;0 --0.40346;-0.02565;-0.0261;0 --0.40535;-0.01225;-0.028;0 --0.40946;0.00105;-0.0312;0 --0.39308;0.009549999999999999;-0.034;0 --0.39942;0.02615;-0.0345;0 --0.40377;0.04165;-0.0351;0 --0.40746;0.05735;-0.0358;0 --0.39455;0.06095;-0.0377;0 --0.40892;0.07105;-0.0365;0 --0.40775;0.08724999999999999;-0.0376;0 --0.4065;0.10465;-0.0387;0 --0.42325;0.12405;-0.038;0 --0.42304;0.14285;-0.0388;0 --0.42292;0.16155;-0.0395;0 --0.42285;0.18035;-0.04;0 --0.40456;0.19925;-0.0422;0 --0.38622;0.20015;-0.0448;0 --0.37134;0.21955;-0.0477;0 --0.37142;0.23755;-0.0478;0 --0.37142;0.25555;-0.0479;0 --0.354;0.25555;-0.0515;0 --0.3367;0.25555;-0.0558;0 --0.3305;0.25555;-0.0387;0 --0.3127;0.25555;-0.0439;0 --0.2951;0.25555;-0.0497;0 --0.2777;0.25555;-0.0562;0 --0.2708;0.25555;-0.0387;0 --0.2451;0.25555;-0.0281;0 --0.2269;0.25555;-0.0366;0 --0.1995;0.25555;-0.0278;0 --0.1813;0.25555;-0.0379;0 --0.1636;0.25555;-0.0488;0 --0.1463;0.25555;-0.0602;0 --0.1295;0.25555;-0.07240000000000001;0 --0.1131;0.25555;-0.0853;0 --0.0973;0.25555;-0.09909999999999999;0 --0.0823;0.25555;-0.1138;0 --0.0682;0.25555;-0.1294;0 --0.0552;0.25555;-0.1455;0 --0.0436;0.25555;-0.1603;0 --0.0323;0.25555;-0.1737;0 --0.021;0.25555;-0.187;0 --0.0097;0.25555;-0.2002;0 -0.0014;0.25555;-0.2134;0 -0.0123;0.25555;-0.2263;0 -0.0235;0.25555;-0.2387;0 -0.0351;0.25555;-0.2509;0 -0.047;0.25555;-0.2627;0 -0.0592;0.25555;-0.2742;0 -0.07190000000000001;0.25555;-0.2852;0 -0.0623;0.25555;-0.2995;0 -0.0756;0.25555;-0.3105;0 -0.0893;0.25555;-0.3211;0 -0.1032;0.25555;-0.3314;0 -0.1174;0.25555;-0.3413;0 -0.1086;0.25555;-0.3563;0 -0.1234;0.25555;-0.366;0 -0.1386;0.25555;-0.3752;0 -0.1541;0.25555;-0.384;0 -0.1697;0.25555;-0.3925;0 -0.1856;0.25555;-0.4005;0 -0.1778;0.25555;-0.4167;0 -0.1697;0.25555;-0.4334;0 -0.1868;0.25555;-0.4414;0 -0.2032;0.24285;-0.4485;0 -0.2194;0.23045;-0.4549;0 -0.2366;0.23075;-0.4613;0 -0.2525;0.21875;-0.4666;0 -0.2683;0.20705;-0.4714;0 -0.2841;0.19555;-0.4758;0 -0.3001;0.18415;-0.4798;0 -0.3164;0.17295;-0.4833;0 -0.3342;0.17355;-0.487;0 -0.3504;0.16255;-0.4896;0 -0.3685;0.16305;-0.4924;0 -0.3866;0.16345;-0.4947;0 -0.4048;0.15995;-0.4753;0 -0.405;0.15575;-0.4513;0 -0.4106;0.15935;-0.4346;0 -0.4258;0.16005;-0.4377;0 -0.4413;0.16035;-0.4412;0 -0.4603;0.16075;-0.4413;0 -0.4603;0.18315;-0.4256;0 -0.4603;0.18645;-0.4066;0 -0.4603;0.20335;-0.4069;0 -0.4603;0.20515;-0.388;0 -0.4603;0.21975;-0.3874;0 -0.4603;0.23675;-0.3872;0 -0.4603;0.25555;-0.3685;0 -0.4415;0.25555;-0.3497;0 -0.4227;0.25555;-0.3309;0 -0.4039;0.25555;-0.3121;0 -0.4039;0.25555;-0.2933;0 -0.4039;0.25555;-0.2745;0 -0.4039;0.25555;-0.2557;0 -0.4039;0.25555;-0.2369;0 -0.3851;0.25555;-0.2181;0 -0.3663;0.25555;-0.1993;0 -0.3475;0.25555;-0.1805;0 -0.3287;0.25555;-0.1617;0 -0.3287;0.25555;-0.1429;0 -0.3099;0.25555;-0.1241;0 -0.2911;0.25555;-0.1054;0 -0.2911;0.25555;-0.0866;0 -0.2911;0.25555;-0.0678;0 -0.2911;0.25555;-0.049;0 -0.2912;0.25555;-0.0302;0 -0.2724;0.25555;-0.0113;0 -0.2725;0.25555;0.0075;0 -0.2725;0.25555;0.0263;0 -0.2746;0.25555;0.0457;0 -0.2741;0.25555;0.0596;0 -0.2718;0.25555;0.07190000000000001;0 -0.2669;0.25555;0.0931;0 -0.2614;0.25555;0.1174;0 -0.2823;0.25555;0.1371;0 -0.3025;0.25555;0.1561;0 -0.3237;0.25555;0.1757;0 -0.3436;0.25555;0.1934;0 -0.3634;0.25555;0.2129;0 -0.3831;0.25555;0.2323;0 -0.4027;0.25555;0.2514;0 -0.4223;0.25555;0.2517;0 -0.4413;0.25555;0.2705;0 -0.4412;0.25555;0.2893;0 -0.4603;0.25555;0.3081;0 -0.4411;0.25555;0.3082;0 -0.4424;0.23125;0.3083;0 -0.4221;0.23065;0.3085;0 -0.3942;0.22915;0.3091;0 -0.3785;0.21785;0.3096;0 -0.3637;0.21405;0.3102;0 -0.347;0.20905;0.311;0 -0.3292;0.20425;0.3119;0 -0.3108;0.19845;0.313;0 -0.2926;0.19185;0.3143;0 -0.2713;0.18475;0.3159;0 -0.254;0.17575;0.3175;0 -0.2402;0.16695;0.319;0 -0.2226;0.15505;0.321;0 -0.2067;0.14405;0.3229;0 -0.1926;0.13285;0.3248;0 -0.1747;0.11955;0.3274;0 -0.1605;0.10625;0.3298;0 -0.147;0.09225;0.3322;0 -0.1341;0.07775;0.3348;0 -0.1219;0.06265;0.3375;0 -0.1105;0.04695;0.3402;0 -0.0998;0.03075;0.3431;0 -0.08989999999999999;0.01415;0.346;0 -0.0809;-0.00155;0.3489;0 -0.0708;-0.01655;0.3519;0 -0.0625;-0.03405;0.3551;0 -0.0761;-0.06285;0.3565;0 -0.0761;-0.06605;0.3387;0 -0.07049999999999999;-0.08365;0.3418;0 -0.0658;-0.10145;0.3449;0 -0.062;-0.12265;0.3303;0 -0.059;-0.14085;0.3335;0 -0.0568;-0.16227;0.3189;0 -0.0555;-0.18067;0.3221;0 -0.0551;-0.19909;0.3253;0 -0.037;-0.19909;0.3253;0 -0.0188;-0.19909;0.3254;0 --0.0003;-0.19914;0.3251;0 --0.0188;-0.19967;0.3221;0 --0.0379;-0.2005;0.3174;0 --0.0675;-0.19575;0.3444;0 --0.0983;-0.19625;0.3415;0 --0.1239;-0.19692;0.3377;0 --0.1477;-0.19737;0.3352;0 --0.1683;-0.1975;0.3344;0 --0.1694;-0.20127;0.313;0 --0.1884;-0.20118;0.3135;0 --0.1914;-0.20472;0.2934;0 --0.1977;-0.20791;0.2754;0 --0.2045;-0.21125;0.2564;0 --0.213;-0.21447;0.2382;0 --0.2234;-0.21752;0.2208;0 --0.2355;-0.22039;0.2046;0 --0.2491;-0.22303;0.1896;0 --0.2643;-0.22544;0.1759;0 --0.2677;-0.23059;0.1468;0 --0.2734;-0.23574;0.1176;0 --0.2934;-0.23747;0.1078;0 --0.2754;-0.24169;0.0838;0 --0.255;-0.24311;0.07580000000000001;0 --0.2386;-0.24314;0.0755;0 --0.2397;-0.245983;0.0595;0 --0.2397;-0.249172;0.0414;0 --0.2397;-0.252361;0.0233;0 --0.2397;-0.25555;0.0052;0 --0.2502;-0.23724;0.002;0 --0.2602;-0.21894;-0.001;0 --0.2705;-0.20069;-0.0039;0 --0.2815;-0.18254;-0.0067;0 --0.2937;-0.16448;-0.0094;0 --0.3071;-0.14665;-0.0119;0 --0.3216;-0.12895;-0.0143;0 --0.3371;-0.11145;-0.0165;0 --0.3531;-0.09435;-0.0187;0 --0.36971;-0.07745;-0.0206;0 --0.38677;-0.06055;-0.0225;0 --0.40431;-0.04345;-0.0243;0 --0.42241;-0.02565;-0.0261;0 --0.42231;-0.01615;-0.0273;0 --0.42591;-0.00745;-0.029;0 --0.43116;0.00555;-0.0298;0 --0.41831;0.01525;-0.0315;0 --0.4269;0.02865;-0.0319;0 --0.42604;0.05385;-0.0338;0 --0.42607;0.06934999999999999;-0.0349;0 --0.42437;0.08635;-0.036;0 --0.42366;0.10515;-0.0371;0 --0.44165;0.12415;-0.0369;0 --0.44159;0.14285;-0.0377;0 --0.44156;0.16165;-0.0384;0 --0.44155;0.18045;-0.0389;0 --0.44153;0.19915;-0.0393;0 --0.42282;0.19915;-0.0405;0 --0.40619;0.21885;-0.0424;0 --0.38893;0.21935;-0.0447;0 --0.38904;0.23755;-0.0448;0 --0.38904;0.25555;-0.0449;0 --0.38486;0.25555;-0.0271;0 --0.36659;0.25555;-0.0303;0 --0.3485;0.25555;-0.0341;0 --0.3256;0.25555;-0.0205;0 --0.3071;0.25555;-0.0258;0 --0.2888;0.25555;-0.0319;0 --0.2673;0.25555;-0.0193;0 --0.2406;0.25555;-0.0091;0 --0.218;0.25555;-0.0183;0 --0.1921;0.25555;-0.0135;0 --0.1727;0.25555;-0.0205;0 --0.1522;0.25555;-0.031;0 --0.1343;0.25555;-0.0428;0 --0.1167;0.25555;-0.0554;0 --0.09959999999999999;0.25555;-0.0692;0 --0.0833;0.25555;-0.08400000000000001;0 --0.0679;0.25555;-0.1;0 --0.0539;0.25555;-0.1172;0 --0.0417;0.25555;-0.1343;0 --0.031;0.25555;-0.1483;0 --0.0201;0.25555;-0.1615;0 --0.0091;0.25555;-0.1745;0 -0.0018;0.25555;-0.1875;0 -0.0124;0.25555;-0.2004;0 -0.023;0.25555;-0.213;0 -0.0338;0.25555;-0.2251;0 -0.045;0.25555;-0.237;0 -0.0565;0.25555;-0.2485;0 -0.0683;0.25555;-0.2597;0 -0.0805;0.25555;-0.2705;0 -0.093;0.25555;-0.281;0 -0.0848;0.25555;-0.296;0 -0.098;0.25555;-0.3063;0 -0.1115;0.25555;-0.3163;0 -0.1253;0.25555;-0.326;0 -0.1393;0.25555;-0.3352;0 -0.1319;0.25555;-0.3507;0 -0.1466;0.25555;-0.3597;0 -0.1616;0.25555;-0.3683;0 -0.1768;0.25555;-0.3766;0 -0.1923;0.25555;-0.3844;0 -0.2079;0.25555;-0.3917;0 -0.2017;0.25555;-0.408;0 -0.1944;0.25555;-0.4245;0 -0.2112;0.25555;-0.4317;0 -0.2041;0.25555;-0.4489;0 -0.2205;0.24295;-0.4554;0 -0.2378;0.24315;-0.4618;0 -0.254;0.23095;-0.4672;0 -0.2699;0.21915;-0.4721;0 -0.2857;0.20755;-0.4764;0 -0.3016;0.19605;-0.4803;0 -0.3177;0.18475;-0.4839;0 -0.3354;0.18525;-0.4875;0 -0.352;0.17405;-0.4902;0 -0.37;0.17455;-0.4929;0 -0.388;0.17515;-0.4951;0 -0.4048;0.16375;-0.4965;0 -0.4233;0.16055;-0.4782;0 -0.4231;0.15665;-0.4562;0 -0.4415;0.15715;-0.4593;0 -0.4603;0.15735;-0.4603;0 -0.4603;0.18135;-0.4603;0 -0.4603;0.18225;-0.4434;0 -0.4603;0.20085;-0.4446;0 -0.4603;0.20225;-0.4252;0 -0.4603;0.21825;-0.4249;0 -0.4603;0.21805;-0.4061;0 -0.4603;0.23675;-0.406;0 -0.4603;0.25555;-0.3872;0 -0.4415;0.25555;-0.3685;0 -0.4227;0.25555;-0.3497;0 -0.4039;0.25555;-0.3309;0 -0.3851;0.25555;-0.3121;0 -0.3851;0.25555;-0.2933;0 -0.3851;0.25555;-0.2745;0 -0.3851;0.25555;-0.2557;0 -0.3851;0.25555;-0.2369;0 -0.3663;0.25555;-0.2181;0 -0.3475;0.25555;-0.1993;0 -0.3287;0.25555;-0.1805;0 -0.3099;0.25555;-0.1617;0 -0.3099;0.25555;-0.1458;0 -0.2911;0.25555;-0.1241;0 -0.2723;0.25555;-0.1054;0 -0.2723;0.25555;-0.0866;0 -0.2723;0.25555;-0.0678;0 -0.2723;0.25555;-0.049;0 -0.2724;0.25555;-0.0302;0 -0.2543;0.25555;-0.0113;0 -0.2554;0.25555;0.0094;0 -0.2572;0.25555;0.0296;0 -0.2611;0.25555;0.0476;0 -0.2643;0.25555;0.0579;0 -0.2574;0.25555;0.0655;0 -0.2417;0.25555;0.08260000000000001;0 -0.2365;0.25555;0.1163;0 -0.2592;0.25555;0.1375;0 -0.2796;0.25555;0.1562;0 -0.301;0.25555;0.1757;0 -0.3221;0.25555;0.1949;0 -0.3411;0.25555;0.2132;0 -0.3617;0.25555;0.2322;0 -0.382;0.25555;0.2512;0 -0.402;0.25555;0.2703;0 -0.422;0.25555;0.2704;0 -0.4217;0.25555;0.2892;0 -0.422;0.25555;0.3084;0 -0.4028;0.25555;0.3087;0 -0.3837;0.25555;0.3092;0 -0.3773;0.23765;0.3095;0 -0.3722;0.22715;0.3098;0 -0.3622;0.22625;0.3101;0 -0.3451;0.22395;0.3108;0 -0.3271;0.22075;0.3117;0 -0.3076;0.21775;0.3129;0 -0.289;0.21345;0.3141;0 -0.2614;0.20715;0.3162;0 -0.2462;0.19215;0.3177;0 -0.2337;0.18445;0.319;0 -0.2133;0.17135;0.3212;0 -0.1969;0.15965;0.3233;0 -0.1842;0.15015;0.325;0 -0.1651;0.13525;0.3277;0 -0.1466;0.12055;0.3307;0 -0.1324;0.10595;0.3332;0 -0.119;0.09064999999999999;0.3359;0 -0.1063;0.07485;0.3387;0 -0.0944;0.05845;0.3416;0 -0.0833;0.04145;0.3446;0 -0.0731;0.02395;0.3476;0 -0.0648;0.01265;0.3499;0 -0.049;0.00035;0.3536;0 -0.0428;-0.02265;0.357;0 -0.0379;-0.03575;0.3593;0 -0.0485;-0.05145;0.3594;0 -0.049;-0.07655000000000001;0.3625;0 -0.07049999999999999;-0.08044999999999999;0.3596;0 -0.0658;-0.09835000000000001;0.3627;0 -0.062;-0.11635;0.3659;0 -0.062;-0.11945;0.3481;0 -0.059;-0.13765;0.3513;0 -0.0568;-0.15913;0.3367;0 -0.0555;-0.17753;0.3399;0 -0.0551;-0.19595;0.3432;0 -0.037;-0.19595;0.3432;0 -0.0182;-0.1956;0.3452;0 --0.0009;-0.19535;0.3466;0 --0.02;-0.19512;0.3479;0 --0.0417;-0.19538;0.3464;0 --0.0409;-0.19035;0.375;0 --0.0683;-0.18913;0.3819;0 --0.1001;-0.19132;0.3694;0 --0.1248;-0.19229;0.364;0 --0.1484;-0.19314;0.3591;0 --0.1686;-0.19374;0.3557;0 --0.1874;-0.1941;0.3537;0 --0.1871;-0.19769;0.3333;0 --0.2079;-0.20085;0.3154;0 --0.2106;-0.20407;0.2972;0 --0.2152;-0.20721;0.2794;0 --0.2215;-0.21026;0.262;0 --0.2294;-0.21319;0.2454;0 --0.239;-0.21598;0.2296;0 --0.2502;-0.21859;0.2148;0 --0.2627;-0.22099;0.2012;0 --0.2765;-0.22317;0.1888;0 --0.2805;-0.22757;0.1639;0 --0.2865;-0.23263;0.1351;0 --0.3063;-0.23439;0.1252;0 --0.3138;-0.2391;0.0984;0 --0.3057;-0.24269;0.07820000000000001;0 --0.2765;-0.245983;0.0595;0 --0.2581;-0.245983;0.0595;0 --0.2581;-0.249172;0.0414;0 --0.2581;-0.252361;0.0233;0 --0.2581;-0.25555;0.0052;0 --0.2682;-0.23725;0.002;0 --0.278;-0.21896;-0.001;0 --0.288;-0.20072;-0.0039;0 --0.2989;-0.18257;-0.0067;0 --0.311;-0.16453;-0.0094;0 --0.3245;-0.14665;-0.0119;0 --0.3391;-0.12915;-0.0143;0 --0.3547;-0.11185;-0.0165;0 --0.371;-0.09485;-0.0186;0 --0.38782;-0.07804999999999999;-0.0205;0 --0.40514;-0.06115;-0.0224;0 --0.42298;-0.04385;-0.0242;0 --0.44135;-0.02565;-0.0261;0 --0.43531;-0.02015;-0.0267;0 --0.44232;-0.01605;-0.0273;0 --0.44475;0.00055;-0.0287;0 --0.43573;0.01385;-0.0302;0 --0.44326;0.03115;-0.0313;0 --0.44261;0.05135;-0.0328;0 --0.4422;0.06784999999999999;-0.0339;0 --0.44191;0.08665;-0.035;0 --0.44174;0.10535;-0.036;0 --0.4603;0.12415;-0.0366;0 --0.4603;0.14285;-0.0374;0 --0.4603;0.16165;-0.038;0 --0.4603;0.18045;-0.0386;0 --0.4603;0.19915;-0.039;0 --0.4603;0.21795;-0.0393;0 --0.44153;0.21795;-0.0397;0 --0.42314;0.21805;-0.0407;0 --0.40676;0.23735;-0.0425;0 --0.40676;0.25555;-0.0425;0 --0.40325;0.25555;-0.0247;0 --0.38199;0.25555;-0.008500000000000001;0 --0.36304;0.25555;-0.0118;0 --0.3443;0.25555;-0.0157;0 --0.3204;0.25555;-0.0015;0 --0.3012;0.25555;-0.0071;0 --0.2823;0.25555;-0.0134;0 --0.264;0.25555;-0.0019;0 --0.2617;0.25555;0.0135;0 --0.2351;0.25555;0.0145;0 --0.2092;0.25555;-0.0013;0 --0.1854;0.25555;-0.0005;0 --0.1654;0.25555;0.0008;0 --0.1384;0.25555;-0.0138;0 --0.1191;0.25555;-0.027;0 --0.1012;0.25555;-0.041;0 --0.0839;0.25555;-0.0559;0 --0.0673;0.25555;-0.0699;0 --0.0525;0.25555;-0.08749999999999999;0 --0.0397;0.25555;-0.1061;0 --0.0289;0.25555;-0.1208;0 --0.0183;0.25555;-0.1344;0 --0.008200000000000001;0.25555;-0.1472;0 -0.0021;0.25555;-0.1601;0 -0.0126;0.25555;-0.1743;0 -0.0228;0.25555;-0.1868;0 -0.0329;0.25555;-0.1991;0 -0.0433;0.25555;-0.211;0 -0.0541;0.25555;-0.2226;0 -0.06519999999999999;0.25555;-0.2338;0 -0.0766;0.25555;-0.2448;0 -0.08840000000000001;0.25555;-0.2554;0 -0.1005;0.25555;-0.2657;0 -0.1129;0.25555;-0.2756;0 -0.1059;0.25555;-0.2911;0 -0.1189;0.25555;-0.3009;0 -0.1322;0.25555;-0.3104;0 -0.1458;0.25555;-0.3194;0 -0.1597;0.25555;-0.328;0 -0.1536;0.25555;-0.344;0 -0.1682;0.25555;-0.3524;0 -0.1829;0.25555;-0.3605;0 -0.1978;0.25555;-0.3681;0 -0.213;0.25555;-0.3753;0 -0.2283;0.25555;-0.3821;0 -0.2237;0.25555;-0.3986;0 -0.218;0.25555;-0.4151;0 -0.2345;0.25555;-0.4216;0 -0.2281;0.25555;-0.4385;0 -0.2215;0.25555;-0.4558;0 -0.2391;0.25555;-0.4623;0 -0.2554;0.24325;-0.4678;0 -0.2715;0.23125;-0.4727;0 -0.2873;0.21945;-0.477;0 -0.3031;0.20785;-0.4809;0 -0.3191;0.19645;-0.4844;0 -0.3367;0.19685;-0.4879;0 -0.3532;0.18565;-0.4906;0 -0.3709;0.18615;-0.4933;0 -0.3888;0.18705;-0.4955;0 -0.406;0.17615;-0.4969;0 -0.423;0.16395;-0.4977;0 -0.4418;0.16085;-0.4805;0 -0.4603;0.16075;-0.4795;0 -0.4603;0.18285;-0.4793;0 -0.4603;0.20025;-0.4614;0 -0.4603;0.21885;-0.4625;0 -0.4603;0.21845;-0.4437;0 -0.4603;0.23675;-0.4248;0 -0.4603;0.25555;-0.406;0 -0.4415;0.25555;-0.3872;0 -0.4227;0.25555;-0.3685;0 -0.4039;0.25555;-0.3497;0 -0.3851;0.25555;-0.3309;0 -0.3663;0.25555;-0.3121;0 -0.3667;0.25555;-0.2951;0 -0.3663;0.25555;-0.2745;0 -0.3663;0.25555;-0.2557;0 -0.3663;0.25555;-0.2369;0 -0.3475;0.25555;-0.2181;0 -0.3287;0.25555;-0.1993;0 -0.3099;0.25555;-0.1805;0 -0.2914;0.25555;-0.165;0 -0.2917;0.25555;-0.1488;0 -0.2735;0.25555;-0.1274;0 -0.2536;0.25555;-0.1054;0 -0.2536;0.25555;-0.0866;0 -0.2537;0.25555;-0.0677;0 -0.2538;0.25555;-0.0489;0 -0.254;0.25555;-0.0301;0 -0.2338;0.25555;-0.0298;0 -0.2342;0.25555;-0.008699999999999999;0 -0.2379;0.25555;0.0127;0 -0.2413;0.25555;0.0331;0 -0.248;0.25555;0.0517;0 -0.2285;0.25555;0.0586;0 -0.2072;0.25555;0.0907;0 -0.2123;0.25555;0.1157;0 -0.2151;0.25555;0.1392;0 -0.2355;0.25555;0.138;0 -0.2572;0.25555;0.1573;0 -0.2788;0.25555;0.1763;0 -0.3001;0.25555;0.1952;0 -0.3212;0.25555;0.214;0 -0.3222;0.25555;0.2338;0 -0.3419;0.25555;0.2329;0 -0.3428;0.25555;0.2525;0 -0.3624;0.25555;0.2518;0 -0.3631;0.25555;0.2713;0 -0.3825;0.25555;0.2706;0 -0.3831;0.25555;0.29;0 -0.4024;0.25555;0.2895;0 -0.3638;0.25555;0.2906;0 -0.3645;0.25555;0.3099;0 -0.3629;0.23905;0.31;0 -0.3445;0.23785;0.3107;0 -0.3262;0.23625;0.3116;0 -0.3071;0.23625;0.3127;0 -0.2879;0.23635;0.3139;0 -0.2668;0.23565;0.3154;0 -0.2439;0.21495;0.3174;0 -0.2391;0.20185;0.3181;0 -0.2287;0.20025;0.319;0 -0.2028;0.19295;0.3217;0 -0.1883;0.17765;0.3236;0 -0.1753;0.16985;0.3252;0 -0.1509;0.16045;0.3284;0 -0.1321;0.13705;0.3316;0 -0.1174;0.12005;0.3344;0 -0.1035;0.10395;0.3372;0 -0.09039999999999999;0.08495;0.3403;0 -0.0786;0.06945;0.3431;0 -0.0684;0.05045;0.3461;0 -0.0602;0.03355;0.3487;0 -0.056;0.02325;0.3503;0 -0.0418;0.02205;0.3527;0 -0.0228;0.00135;0.3579;0 -0.0235;-0.01855;0.3598;0 -0.024;-0.03625;0.3617;0 -0.0246;-0.05395;0.3637;0 -0.0237;-0.07355;0.3663;0 -0.0457;-0.09495000000000001;0.3655;0 -0.0436;-0.11245;0.3683;0 -0.0406;-0.13145;0.3717;0 -0.059;-0.13455;0.3691;0 -0.0568;-0.15285;0.3724;0 -0.0568;-0.15598;0.3545;0 -0.0555;-0.17437;0.3578;0 -0.0551;-0.1928;0.361;0 -0.0375;-0.19248;0.3629;0 -0.0185;-0.19203;0.3655;0 --0.0003;-0.19146;0.3686;0 --0.0188;-0.19088;0.3719;0 --0.0184;-0.18754;0.3909;0 --0.0387;-0.18699;0.394;0 --0.0579;-0.186;0.3996;0 --0.08069999999999999;-0.18618;0.3985;0 --0.1016;-0.18739;0.3918;0 --0.1256;-0.18843;0.3858;0 --0.1494;-0.18945;0.3801;0 --0.1695;-0.19023;0.3757;0 --0.1879;-0.19061;0.3735;0 --0.207;-0.1941;0.3537;0 --0.207;-0.19761;0.3338;0 --0.2079;-0.18119;0.312;0 --0.2106;-0.18428;0.2938;0 --0.2152;-0.1873;0.2759;0 --0.2215;-0.19023;0.2585;0 --0.2295;-0.19303;0.2418;0 --0.2391;-0.1957;0.226;0 --0.2503;-0.19819;0.2112;0 --0.2628;-0.2005;0.1975;0 --0.2767;-0.20259;0.1851;0 --0.2914;-0.22511;0.1779;0 --0.2979;-0.22941;0.1534;0 --0.3163;-0.23097;0.1446;0 --0.3258;-0.23593;0.1165;0 --0.3344;-0.24058;0.0901;0 --0.3266;-0.24359;0.073;0 --0.3224;-0.246471;0.0567;0 --0.3008;-0.246196;0.0583;0 --0.2979;-0.249248;0.041;0 --0.2765;-0.249172;0.0414;0 --0.2765;-0.252361;0.0233;0 --0.2765;-0.25555;0.0052;0 --0.2863;-0.23725;0.002;0 --0.2957;-0.21897;-0.001;0 --0.3055;-0.20074;-0.0039;0 --0.3162;-0.1826;-0.0067;0 --0.3283;-0.16462;-0.0094;0 --0.3418;-0.14695;-0.0119;0 --0.3566;-0.12955;-0.0142;0 --0.37238;-0.11255;-0.0164;0 --0.38887;-0.09575;-0.0185;0 --0.40595;-0.07905;-0.0204;0 --0.42353;-0.06205;-0.0223;0 --0.44164;-0.04435;-0.0242;0 --0.4603;-0.02565;-0.0261;0 --0.4603;-0.00695;-0.0278;0 --0.4603;0.01175;-0.0294;0 --0.44617;0.01355;-0.0298;0 --0.4603;0.03045;-0.0309;0 --0.4603;0.04915;-0.0323;0 --0.4603;0.06784999999999999;-0.0335;0 --0.4603;0.08665;-0.0347;0 --0.4603;0.10535;-0.0357;0 --0.4603;0.10635;-0.017;0 --0.4603;0.12495;-0.0178;0 --0.4603;0.14365;-0.0186;0 --0.4603;0.16225;-0.0192;0 --0.4603;0.18095;-0.0196;0 --0.4603;0.19955;-0.0199;0 --0.4603;0.21825;-0.0199;0 --0.4603;0.23675;-0.0395;0 --0.44173;0.23675;-0.0398;0 --0.42453;0.23715;-0.0408;0 --0.42456;0.25555;-0.0409;0 --0.42169;0.25555;-0.0228;0 --0.40106;0.25555;-0.0059;0 --0.39826;0.25555;0.0144;0 --0.3763;0.25555;0.0107;0 --0.3593;0.25555;0.0074;0 --0.3425;0.25555;0.0037;0 --0.3415;0.25555;0.0219;0 --0.3128;0.25555;0.0232;0 --0.2912;0.25555;0.0095;0 --0.2777;0.25555;0.0024;0 --0.2733;0.25555;0.0124;0 --0.267;0.25555;0.0296;0 --0.2463;0.25555;0.0403;0 --0.2093;0.25555;0.0315;0 --0.1948;0.25555;0.0133;0 --0.1749;0.25555;0.0258;0 --0.1367;0.25555;0.0224;0 --0.1207;0.25555;0.0064;0 --0.1038;0.25555;-0.0102;0 --0.0853;0.25555;-0.025;0 --0.0678;0.25555;-0.0412;0 --0.0507;0.25555;-0.0572;0 --0.0392;0.25555;-0.077;0 --0.0263;0.25555;-0.0955;0 --0.0165;0.25555;-0.1088;0 --0.007;0.25555;-0.1217;0 -0.0027;0.25555;-0.1341;0 -0.0128;0.25555;-0.1465;0 -0.0239;0.25555;-0.1609;0 -0.0338;0.25555;-0.1732;0 -0.0437;0.25555;-0.1847;0 -0.0539;0.25555;-0.1961;0 -0.0644;0.25555;-0.2074;0 -0.0751;0.25555;-0.2183;0 -0.0861;0.25555;-0.229;0 -0.0975;0.25555;-0.2394;0 -0.1092;0.25555;-0.2494;0 -0.121;0.25555;-0.2593;0 -0.133;0.25555;-0.2683;0 -0.1255;0.25555;-0.2852;0 -0.1384;0.25555;-0.2944;0 -0.1515;0.25555;-0.3033;0 -0.1665;0.25555;-0.3119;0 -0.18;0.25555;-0.3195;0 -0.1738;0.25555;-0.3363;0 -0.188;0.25555;-0.3442;0 -0.2024;0.25555;-0.3517;0 -0.217;0.25555;-0.3587;0 -0.2328;0.25555;-0.364;0 -0.2476;0.25555;-0.37;0 -0.2438;0.25555;-0.3884;0 -0.2397;0.25555;-0.405;0 -0.2559;0.25555;-0.4111;0 -0.2512;0.25555;-0.4278;0 -0.2453;0.25555;-0.4448;0 -0.2627;0.25555;-0.4506;0 -0.257;0.25555;-0.4683;0 -0.2732;0.24335;-0.4732;0 -0.2891;0.23145;-0.4776;0 -0.3048;0.21975;-0.4815;0 -0.3206;0.20825;-0.4849;0 -0.3382;0.20855;-0.4884;0 -0.3543;0.19725;-0.491;0 -0.372;0.19775;-0.4937;0 -0.3897;0.19905;-0.4958;0 -0.4066;0.18885;-0.4972;0 -0.4241;0.17785;-0.4981;0 -0.4413;0.16405;-0.4985;0 -0.4603;0.16415;-0.4988;0 -0.4603;0.18235;-0.4992;0 -0.4603;0.20105;-0.4802;0 -0.4603;0.21915;-0.4809;0 -0.4603;0.23695;-0.4624;0 -0.4603;0.23685;-0.4436;0 -0.4603;0.25555;-0.4248;0 -0.4415;0.25555;-0.406;0 -0.4227;0.25555;-0.3872;0 -0.4039;0.25555;-0.3685;0 -0.3851;0.25555;-0.3497;0 -0.3663;0.25555;-0.3309;0 -0.3494;0.25555;-0.3137;0 -0.3483;0.25555;-0.2973;0 -0.3474;0.25555;-0.2771;0 -0.3475;0.25555;-0.2557;0 -0.3475;0.25555;-0.2369;0 -0.3287;0.25555;-0.2181;0 -0.3099;0.25555;-0.1993;0 -0.2911;0.25555;-0.1805;0 -0.2779;0.25555;-0.1673;0 -0.2761;0.25555;-0.1524;0 -0.2552;0.25555;-0.1302;0 -0.2363;0.25555;-0.1282;0 -0.2356;0.25555;-0.1079;0 -0.2363;0.25555;-0.0893;0 -0.2358;0.25555;-0.0704;0 -0.2361;0.25555;-0.0513;0 -0.2183;0.25555;-0.0536;0 -0.2137;0.25555;-0.033;0 -0.2044;0.25555;-0.007900000000000001;0 -0.2132;0.25555;0.0204;0 -0.2198;0.25555;0.0385;0 -0.2004;0.25555;0.0669;0 -0.1839;0.25555;0.09370000000000001;0 -0.1895;0.25555;0.1175;0 -0.1947;0.25555;0.1403;0 -0.1962;0.25555;0.1614;0 -0.2166;0.25555;0.16;0 -0.2369;0.25555;0.1586;0 -0.2385;0.25555;0.1791;0 -0.2586;0.25555;0.1777;0 -0.2601;0.25555;0.1978;0 -0.2801;0.25555;0.1964;0 -0.2814;0.25555;0.2164;0 -0.3013;0.25555;0.2151;0 -0.3025;0.25555;0.2349;0 -0.3232;0.25555;0.2535;0 -0.3437;0.25555;0.272;0 -0.3445;0.25555;0.2914;0 -0.3454;0.25555;0.3106;0 -0.3262;0.25555;0.3116;0 -0.3071;0.25555;0.3126;0 -0.2879;0.25555;0.3138;0 -0.2688;0.25555;0.3152;0 -0.2497;0.25555;0.3166;0 -0.2476;0.23595;0.3169;0 -0.2306;0.23635;0.3183;0 -0.2306;0.21745;0.3186;0 -0.2081;0.21715;0.3206;0 -0.1889;0.21725;0.3226;0 -0.1854;0.19905;0.3233;0 -0.1809;0.18735;0.3241;0 -0.171;0.18605;0.3252;0 -0.1528;0.18415;0.3274;0 -0.1276;0.16735;0.331;0 -0.1165;0.15135;0.3331;0 -0.1006;0.13485;0.336;0 -0.0862;0.11345;0.3391;0 -0.0742;0.09395000000000001;0.342;0 -0.0655;0.07875;0.3444;0 -0.049;0.06405;0.3481;0 -0.0421;0.03825;0.3512;0 -0.0228;0.02225;0.3559;0 -0.0026;0.00455;0.3611;0 -0.0026;-0.01465;0.3631;0 -0.0026;-0.03385;0.3652;0 -0.0026;-0.05305;0.3675;0 -0.0026;-0.07224999999999999;0.3699;0 -0.0217;-0.09185;0.3691;0 -0.0217;-0.11105;0.3718;0 -0.0217;-0.13025;0.3747;0 -0.0385;-0.15065;0.375;0 -0.0555;-0.17123;0.3756;0 -0.0551;-0.18966;0.3789;0 -0.0376;-0.18917;0.3817;0 -0.0201;-0.18865;0.3845;0 -0.0026;-0.18812;0.3876;0 -0.0026;-0.18428;0.40939;0 --0.018;-0.18428;0.40941;0 --0.0368;-0.184;0.41095;0 --0.0551;-0.18357;0.41337;0 --0.0694;-0.18504;0.40512;0 --0.0849;-0.18365;0.41301;0 --0.1035;-0.18386;0.41176;0 --0.1267;-0.18482;0.40632;0 --0.1504;-0.18572;0.40123;0 --0.1712;-0.18643;0.3972;0 --0.1887;-0.1871;0.3934;0 --0.207;-0.19059;0.3736;0 --0.207;-0.17149;0.3703;0 --0.207;-0.17477;0.3503;0 --0.207;-0.17805;0.3304;0 --0.2079;-0.16152;0.3088;0 --0.2106;-0.16445;0.2905;0 --0.2152;-0.16734;0.2726;0 --0.2215;-0.17013;0.2552;0 --0.2295;-0.17282;0.2385;0 --0.2391;-0.17536;0.2226;0 --0.2503;-0.17774;0.2078;0 --0.2628;-0.17996;0.1941;0 --0.2767;-0.18194;0.1817;0 --0.2917;-0.18371;0.1707;0 --0.2917;-0.20443;0.1741;0 --0.3075;-0.22677;0.1684;0 --0.3244;-0.22818;0.1605;0 --0.3351;-0.23222;0.1375;0 --0.3458;-0.23742;0.108;0 --0.3492;-0.24226;0.0806;0 --0.3412;-0.2445;0.0679;0 --0.3386;-0.2467;0.0554;0 --0.3361;-0.249202;0.0412;0 --0.3187;-0.249248;0.0409;0 --0.315;-0.252437;0.0229;0 --0.2949;-0.252361;0.0233;0 --0.2949;-0.25555;0.0052;0 --0.3044;-0.23727;0.002;0 --0.3135;-0.21899;-0.001;0 --0.323;-0.20077;-0.0039;0 --0.3336;-0.18267;-0.0067;0 --0.3456;-0.16482;-0.009299999999999999;0 --0.3591;-0.14735;-0.0118;0 --0.37403;-0.13025;-0.0141;0 --0.39;-0.11355;-0.0163;0 --0.40674;-0.09705;-0.0183;0 --0.42406;-0.08035;-0.0203;0 --0.44191;-0.06304999999999999;-0.0222;0 --0.4603;-0.04495;-0.0241;0 --0.4603;-0.02385;-0.0074;0 --0.4603;-0.00535;-0.0091;0 --0.4603;0.01325;-0.0107;0 --0.4603;0.03185;-0.0122;0 --0.4603;0.05045;-0.0136;0 --0.4603;0.06905;-0.0148;0 --0.4603;0.08774999999999999;-0.016;0 --0.4603;0.08875;0.0026;0 --0.4603;0.10725;0.0017;0 --0.4603;0.12575;0.0008;0 --0.4603;0.14425;0.0001;0 --0.4603;0.16275;-0.0004;0 --0.4603;0.18125;-0.0007;0 --0.4603;0.19955;-0.0005;0 --0.4603;0.21755;0.0003;0 --0.4603;0.23535;0.0017;0 --0.4603;0.23685;-0.0197;0 --0.4603;0.25555;-0.0395;0 --0.44242;0.25555;-0.0399;0 --0.4402;0.25555;-0.0212;0 --0.41986;0.25555;-0.0032;0 --0.41959;0.25555;0.018;0 --0.39725;0.25555;0.0381;0 --0.36826;0.25555;0.0311;0 --0.356;0.25555;0.019;0 --0.3465;0.25555;0.042;0 --0.3255;0.25555;0.0523;0 --0.2921;0.25555;0.0383;0 --0.2802;0.25555;0.0217;0 --0.2755;0.25555;0.0496;0 --0.2563;0.25555;0.0639;0 --0.2226;0.25555;0.0541;0 --0.1851;0.25555;0.0476;0 --0.1476;0.25555;0.0432;0 --0.1145;0.25555;0.0372;0 --0.1047;0.25555;0.0192;0 --0.09039999999999999;0.25555;0.0016;0 --0.0718;0.25555;-0.0126;0 --0.0526;0.25555;-0.029;0 --0.0362;0.25555;-0.0464;0 --0.0245;0.25555;-0.0663;0 --0.0134;0.25555;-0.0844;0 --0.0048;0.25555;-0.0968;0 -0.0039;0.25555;-0.1091;0 -0.0126;0.25555;-0.1218;0 -0.0226;0.25555;-0.134;0 -0.0342;0.25555;-0.1484;0 -0.0438;0.25555;-0.1606;0 -0.0532;0.25555;-0.1725;0 -0.0629;0.25555;-0.1837;0 -0.07290000000000001;0.25555;-0.1948;0 -0.0832;0.25555;-0.2056;0 -0.09379999999999999;0.25555;-0.2161;0 -0.1049;0.25555;-0.2262;0 -0.1162;0.25555;-0.2361;0 -0.1278;0.25555;-0.2456;0 -0.1395;0.25555;-0.2538;0 -0.1513;0.25555;-0.262;0 -0.1452;0.25555;-0.277;0 -0.1585;0.25555;-0.2858;0 -0.1729;0.25555;-0.2952;0 -0.186;0.25555;-0.3031;0 -0.1992;0.25555;-0.3107;0 -0.1938;0.25555;-0.327;0 -0.2077;0.25555;-0.3342;0 -0.2219;0.25555;-0.3408;0 -0.2362;0.25555;-0.3472;0 -0.2511;0.25555;-0.3535;0 -0.2657;0.25555;-0.3591;0 -0.2628;0.25555;-0.3757;0 -0.2594;0.25555;-0.3943;0 -0.275;0.25555;-0.3998;0 -0.2721;0.25555;-0.4167;0 -0.268;0.25555;-0.4335;0 -0.285;0.25555;-0.4387;0 -0.2801;0.25555;-0.4559;0 -0.275;0.25555;-0.4738;0 -0.291;0.24355;-0.4781;0 -0.3068;0.23165;-0.482;0 -0.3224;0.22005;-0.4854;0 -0.3401;0.22035;-0.4889;0 -0.3558;0.20895;-0.4915;0 -0.3734;0.20945;-0.494;0 -0.3908;0.21085;-0.4961;0 -0.4073;0.20155;-0.4975;0 -0.4244;0.19185;-0.4984;0 -0.4421;0.18005;-0.4989;0 -0.4423;0.19595;-0.4992;0 -0.4603;0.20065;-0.4996;0 -0.4603;0.21895;-0.4998;0 -0.4603;0.23705;-0.4812;0 -0.4603;0.25555;-0.4624;0 -0.4603;0.25555;-0.4436;0 -0.4415;0.25555;-0.4248;0 -0.4227;0.25555;-0.406;0 -0.4039;0.25555;-0.3872;0 -0.3851;0.25555;-0.3685;0 -0.3663;0.25555;-0.3497;0 -0.3505;0.25555;-0.3337;0 -0.3347;0.25555;-0.3323;0 -0.333;0.25555;-0.3163;0 -0.3289;0.25555;-0.3019;0 -0.3192;0.25555;-0.2823;0 -0.3247;0.25555;-0.2545;0 -0.3272;0.25555;-0.2355;0 -0.3068;0.25555;-0.2185;0 -0.2911;0.25555;-0.1993;0 -0.2775;0.25555;-0.1808;0 -0.2682;0.25555;-0.1694;0 -0.2587;0.25555;-0.1587;0 -0.2349;0.25555;-0.1518;0 -0.217;0.25555;-0.1472;0 -0.2193;0.25555;-0.126;0 -0.2186;0.25555;-0.1072;0 -0.2186;0.25555;-0.089;0 -0.2185;0.25555;-0.0713;0 -0.1963;0.25555;-0.06950000000000001;0 -0.1941;0.25555;-0.0535;0 -0.1902;0.25555;-0.038;0 -0.1827;0.25555;-0.022;0 -0.1813;0.25555;0.008200000000000001;0 -0.188;0.25555;0.0257;0 -0.1937;0.25555;0.044;0 -0.1783;0.25555;0.07000000000000001;0 -0.1598;0.25555;0.0954;0 -0.165;0.25555;0.1193;0 -0.1715;0.25555;0.143;0 -0.1757;0.25555;0.163;0 -0.1778;0.25555;0.1844;0 -0.1981;0.25555;0.1825;0 -0.2183;0.25555;0.1808;0 -0.2201;0.25555;0.201;0 -0.2401;0.25555;0.1993;0 -0.2417;0.25555;0.2193;0 -0.2616;0.25555;0.2178;0 -0.2828;0.25555;0.2362;0 -0.3036;0.25555;0.2546;0 -0.3242;0.25555;0.273;0 -0.3252;0.25555;0.2923;0 -0.3059;0.25555;0.2934;0 -0.2866;0.25555;0.2946;0 -0.2674;0.25555;0.296;0 -0.2481;0.25555;0.2975;0 -0.2289;0.25555;0.2991;0 -0.2306;0.25555;0.3183;0 -0.2115;0.25555;0.32;0 -0.2115;0.23635;0.3201;0 -0.1924;0.23635;0.322;0 -0.1733;0.23635;0.3241;0 -0.1733;0.21715;0.3243;0 -0.1725;0.20075;0.3247;0 -0.1532;0.19995;0.3269;0 -0.133;0.19915;0.3294;0 -0.131;0.18395;0.33;0 -0.1172;0.17255;0.3322;0 -0.1052;0.16535;0.3341;0 -0.0808;0.15265;0.338;0 -0.06;0.12535;0.3425;0 -0.0575;0.10025;0.3442;0 -0.0553;0.08795;0.3454;0 -0.0418;0.08395;0.3478;0 -0.0217;0.06215;0.3527;0 -0.0218;0.04085;0.3544;0 -0.0026;0.02385;0.3593;0 -0.0026;0.02475;0.3814;0 -0.0026;0.00565;0.3833;0 -0.0026;-0.01345;0.3852;0 -0.0026;-0.03235;0.3873;0 -0.0026;-0.05145;0.3896;0 -0.0026;-0.07045;0.392;0 -0.0026;-0.09145;0.3724;0 -0.0026;-0.11055;0.3751;0 -0.0026;-0.12975;0.378;0 -0.0214;-0.14935;0.3777;0 -0.0376;-0.17066;0.3784;0 -0.0201;-0.16947;0.3812;0 -0.0026;-0.16789;0.3841;0 -0.0026;-0.16537;0.40613;0 -0.0026;-0.18043;0.43123;0 --0.0186;-0.18043;0.43123;0 --0.0385;-0.18051;0.4308;0 --0.0545;-0.18043;0.4312;0 --0.0697;-0.18322;0.41536;0 --0.0872;-0.18008;0.43323;0 --0.1043;-0.18034;0.43178;0 --0.1308;-0.1795;0.43646;0 --0.1561;-0.18151;0.42506;0 --0.1742;-0.18252;0.41939;0 --0.1905;-0.18315;0.41583;0 --0.207;-0.18359;0.4133;0 --0.207;-0.1871;0.3934;0 --0.207;-0.16821;0.3902;0 --0.207;-0.14915;0.387;0 --0.207;-0.15225;0.3671;0 --0.207;-0.15535;0.3471;0 --0.207;-0.1585;0.3272;0 --0.2079;-0.14185;0.3057;0 --0.2106;-0.14465;0.2874;0 --0.2152;-0.14735;0.2695;0 --0.2215;-0.15005;0.252;0 --0.2295;-0.15255;0.2353;0 --0.2391;-0.15505;0.2194;0 --0.2503;-0.15728;0.2046;0 --0.2628;-0.15937;0.1909;0 --0.2767;-0.16128;0.1785;0 --0.2917;-0.16296;0.1674;0 --0.3078;-0.16442;0.1579;0 --0.3078;-0.18524;0.1612;0 --0.3078;-0.20603;0.1646;0 --0.3247;-0.20736;0.1567;0 --0.3419;-0.22927;0.1542;0 --0.3549;-0.2331;0.1325;0 --0.37509;-0.23399;0.1275;0 --0.36817;-0.23913;0.0983;0 --0.3792;-0.24292;0.07679999999999999;0 --0.3591;-0.2443;0.06900000000000001;0 --0.3502;-0.2452;0.0639;0 --0.3503;-0.246852;0.0545;0 --0.35;-0.249141;0.0416;0 --0.35;-0.252346;0.0234;0 --0.3333;-0.252483;0.0226;0 --0.3317;-0.25555;0.0052;0 --0.3133;-0.25555;0.0052;0 --0.3224;-0.23727;0.002;0 --0.3313;-0.219;-0.001;0 --0.3405;-0.20082;-0.0039;0 --0.3508;-0.18283;-0.0067;0 --0.36275;-0.1652;-0.009299999999999999;0 --0.37633;-0.14805;-0.0117;0 --0.39141;-0.13145;-0.014;0 --0.40761;-0.11515;-0.0161;0 --0.42459;-0.09875;-0.0181;0 --0.44217;-0.08185000000000001;-0.0201;0 --0.4603;-0.06415;-0.0221;0 --0.4603;-0.04295;-0.0053;0 --0.4603;-0.02195;0.0111;0 --0.4603;-0.00365;0.0094;0 --0.4603;0.01485;0.0078;0 --0.4603;0.03325;0.0063;0 --0.4603;0.05175;0.005;0 --0.4603;0.07025000000000001;0.0037;0 --0.4603;0.08835;0.0235;0 --0.4603;0.10675;0.0225;0 --0.4603;0.12505;0.0216;0 --0.4603;0.14315;0.021;0 --0.4603;0.16125;0.0209;0 --0.4603;0.17945;0.0216;0 --0.4603;0.19825;0.0239;0 --0.4603;0.21725;0.024;0 --0.4603;0.23515;0.0223;0 --0.4603;0.25555;0.0218;0 --0.4603;0.25555;0.0013;0 --0.4603;0.25555;-0.0191;0 --0.44043;0.25555;-0.0008;0 --0.43958;0.25555;0.0218;0 --0.41814;0.25555;0.0421;0 --0.39644;0.25555;0.0619;0 --0.37358;0.25555;0.0619;0 --0.3525;0.25555;0.0668;0 --0.3321;0.25555;0.074;0 --0.3027;0.25555;0.0598;0 --0.2851;0.25555;0.07190000000000001;0 --0.2658;0.25555;0.0857;0 --0.2365;0.25555;0.08019999999999999;0 --0.1999;0.25555;0.0708;0 --0.1584;0.25555;0.06569999999999999;0 --0.1221;0.25555;0.0546;0 --0.1022;0.25555;0.0587;0 --0.0983;0.25555;0.0449;0 --0.09089999999999999;0.25555;0.0279;0 --0.0786;0.25555;0.0122;0 --0.0593;0.25555;0;0 --0.0392;0.25555;-0.0172;0 --0.0227;0.25555;-0.0356;0 --0.0107;0.25555;-0.0562;0 --0.0007;0.25555;-0.0737;0 -0.0068;0.25555;-0.08500000000000001;0 -0.0148;0.25555;-0.0963;0 -0.0234;0.25555;-0.1084;0 -0.0335;0.25555;-0.1208;0 -0.0455;0.25555;-0.1361;0 -0.0548;0.25555;-0.1481;0 -0.06370000000000001;0.25555;-0.1598;0 -0.073;0.25555;-0.1707;0 -0.08260000000000001;0.25555;-0.1816;0 -0.0926;0.25555;-0.1921;0 -0.1028;0.25555;-0.2022;0 -0.1134;0.25555;-0.2121;0 -0.1243;0.25555;-0.2217;0 -0.1356;0.25555;-0.2311;0 -0.1463;0.25555;-0.2384;0 -0.1579;0.25555;-0.2459;0 -0.1719;0.25555;-0.2555;0 -0.1644;0.25555;-0.2716;0 -0.1784;0.25555;-0.2818;0 -0.1911;0.25555;-0.2895;0 -0.2039;0.25555;-0.2969;0 -0.2169;0.25555;-0.304;0 -0.2126;0.25555;-0.3178;0 -0.2262;0.25555;-0.3246;0 -0.2396;0.25555;-0.3312;0 -0.2543;0.25555;-0.3377;0 -0.2685;0.25555;-0.3441;0 -0.2811;0.25555;-0.3488;0 -0.2794;0.25555;-0.3639;0 -0.2774;0.25555;-0.3808;0 -0.2925;0.25555;-0.3857;0 -0.2908;0.25555;-0.4048;0 -0.2885;0.25555;-0.4218;0 -0.305;0.25555;-0.4264;0 -0.302;0.25555;-0.4435;0 -0.2978;0.25555;-0.4608;0 -0.2931;0.25555;-0.4787;0 -0.309;0.24365;-0.4826;0 -0.3246;0.23185;-0.486;0 -0.3424;0.23205;-0.4894;0 -0.3577;0.22055;-0.4919;0 -0.3753;0.22115;-0.4944;0 -0.3924;0.22235;-0.4964;0 -0.4078;0.21365;-0.4977;0 -0.4246;0.20575;-0.4987;0 -0.4421;0.21175;-0.4995;0 -0.4413;0.22655;-0.4996;0 -0.4603;0.23725;-0.4999;0 -0.4603;0.25555;-0.4812;0 -0.4415;0.25555;-0.4624;0 -0.4415;0.25555;-0.4436;0 -0.4227;0.25555;-0.4248;0 -0.4039;0.25555;-0.406;0 -0.3851;0.25555;-0.3872;0 -0.3675;0.25555;-0.3844;0 -0.3663;0.25555;-0.3685;0 -0.3526;0.25555;-0.3662;0 -0.3518;0.25555;-0.3504;0 -0.3355;0.25555;-0.3471;0 -0.3209;0.25555;-0.3442;0 -0.3203;0.25555;-0.3309;0 -0.3189;0.25555;-0.3187;0 -0.3154;0.25555;-0.3079;0 -0.3055;0.25555;-0.2979;0 -0.2875;0.25555;-0.2713;0 -0.2997;0.25555;-0.2495;0 -0.304;0.25555;-0.2338;0 -0.2895;0.25555;-0.2191;0 -0.276;0.25555;-0.1988;0 -0.2614;0.25555;-0.1949;0 -0.2647;0.25555;-0.1796;0 -0.251;0.25555;-0.1732;0 -0.233;0.25555;-0.1682;0 -0.2137;0.25555;-0.1645;0 -0.1994;0.25555;-0.1426;0 -0.1999;0.25555;-0.1238;0 -0.199;0.25555;-0.1048;0 -0.1978;0.25555;-0.0867;0 -0.1831;0.25555;-0.0852;0 -0.1815;0.25555;-0.0684;0 -0.1789;0.25555;-0.0535;0 -0.1761;0.25555;-0.0426;0 -0.17;0.25555;-0.0321;0 -0.1557;0.25555;-0.0187;0 -0.1698;0.25555;-0.0046;0 -0.1642;0.25555;0.0176;0 -0.1682;0.25555;0.0307;0 -0.1728;0.25555;0.0475;0 -0.1548;0.25555;0.0718;0 -0.1364;0.25555;0.1031;0 -0.1437;0.25555;0.1229;0 -0.1498;0.25555;0.1465;0 -0.1545;0.25555;0.1649;0 -0.1574;0.25555;0.1866;0 -0.1599;0.25555;0.2072;0 -0.18;0.25555;0.2049;0 -0.2001;0.25555;0.2029;0 -0.202;0.25555;0.2229;0 -0.2219;0.25555;0.221;0 -0.2433;0.25555;0.2391;0 -0.2631;0.25555;0.2375;0 -0.2841;0.25555;0.2558;0 -0.3048;0.25555;0.274;0 -0.2854;0.25555;0.2753;0 -0.2659;0.25555;0.2766;0 -0.2465;0.25555;0.2781;0 -0.2271;0.25555;0.2798;0 -0.2078;0.25555;0.2816;0 -0.2096;0.25555;0.3009;0 -0.1904;0.25555;0.3028;0 -0.1924;0.25555;0.3219;0 -0.1733;0.25555;0.324;0 -0.1543;0.25555;0.3262;0 -0.1543;0.23635;0.3263;0 -0.1543;0.21715;0.3265;0 -0.1353;0.21715;0.3288;0 -0.1162;0.21715;0.3313;0 -0.1163;0.19815;0.3316;0 -0.1164;0.18415;0.332;0 -0.1003;0.18155;0.3342;0 -0.0784;0.17935;0.3375;0 -0.0553;0.15745;0.3418;0 -0.0494;0.14175;0.3434;0 -0.0415;0.12195;0.3456;0 -0.0408;0.10045;0.3469;0 -0.0217;0.10075;0.3501;0 -0.0217;0.08144999999999999;0.3513;0 -0.0026;0.06235;0.3561;0 -0.0026;0.04305;0.3576;0 -0.0026;0.04395;0.3798;0 -0.0026;0.02695;0.4035;0 -0.0026;0.00795;0.40532;0 -0.0026;-0.01095;0.40726;0 -0.0026;-0.02975;0.40935;0 -0.0026;-0.04865;0.41159;0 -0.0026;-0.06755;0.41395;0 -0.0026;-0.08645;0.41649;0 -0.0026;-0.08955;0.3945;0 -0.0026;-0.10845;0.3972;0 -0.0026;-0.12745;0.40005;0 -0.0026;-0.14885;0.381;0 -0.0026;-0.14645;0.40303;0 -0.0026;-0.16168;0.42798;0 -0.0026;-0.17658;0.45306;0 --0.0191;-0.17719;0.44955;0 --0.0391;-0.17712;0.45001;0 --0.0539;-0.17707;0.45027;0 --0.06950000000000001;-0.18014;0.43284;0 --0.0857;-0.177;0.45073;0 --0.1033;-0.17738;0.44856;0 --0.1222;-0.1766;0.45297;0 --0.1344;-0.17581;0.45746;0 --0.1445;-0.17694;0.45105;0 --0.1615;-0.17828;0.44345;0 --0.177;-0.17913;0.43858;0 --0.1918;-0.1797;0.43536;0 --0.207;-0.18008;0.43317;0 --0.207;-0.16165;0.43001;0 --0.207;-0.16493;0.41008;0 --0.207;-0.14595;0.40697;0 --0.207;-0.12705;0.40399;0 --0.207;-0.13005;0.384;0 --0.207;-0.13295;0.3641;0 --0.207;-0.13595;0.3441;0 --0.207;-0.13895;0.3242;0 --0.2079;-0.12205;0.3027;0 --0.2106;-0.12475;0.2844;0 --0.2152;-0.12735;0.2665;0 --0.2215;-0.12985;0.249;0 --0.2295;-0.13235;0.2323;0 --0.2391;-0.13465;0.2164;0 --0.2503;-0.13675;0.2015;0 --0.2628;-0.13875;0.1878;0 --0.2767;-0.14055;0.1754;0 --0.2917;-0.14215;0.1643;0 --0.3078;-0.14355;0.1548;0 --0.3247;-0.14475;0.1469;0 --0.3247;-0.16563;0.15;0 --0.3247;-0.1865;0.1533;0 --0.3423;-0.18751;0.1471;0 --0.3423;-0.20841;0.1505;0 --0.36;-0.23007;0.1497;0 --0.37848;-0.23056;0.147;0 --0.39716;-0.23416;0.1266;0 --0.39757;-0.23823;0.1034;0 --0.3998;-0.2418;0.0832;0 --0.4029;-0.24543;0.0625;0 --0.38387;-0.246059;0.059;0 --0.36327;-0.246608;0.0559;0 --0.36582;-0.249156;0.0415;0 --0.36841;-0.25233;0.0234;0 --0.36841;-0.25555;0.0052;0 --0.35;-0.25555;0.0052;0 --0.3405;-0.23727;0.002;0 --0.349;-0.21902;-0.001;0 --0.3579;-0.20089;-0.0039;0 --0.36791;-0.1831;-0.0066;0 --0.3797;-0.16589;-0.0092;0 --0.39339;-0.14935;-0.0115;0 --0.40871;-0.13315;-0.0137;0 --0.42519;-0.11705;-0.0158;0 --0.44245;-0.10055;-0.0179;0 --0.4603;-0.08334999999999999;-0.0199;0 --0.4603;-0.06205;-0.0031;0 --0.4603;-0.04095;0.0134;0 --0.4603;-0.02185;0.0318;0 --0.4603;-0.00355;0.0302;0 --0.4603;0.01485;0.0286;0 --0.4603;0.03325;0.0271;0 --0.4603;0.05155;0.0258;0 --0.4603;0.06995;0.0246;0 --0.4603;0.08905;0.0487;0 --0.4603;0.10745;0.0478;0 --0.4603;0.12575;0.0471;0 --0.4603;0.14415;0.0464;0 --0.4603;0.16275;0.0463;0 --0.4603;0.18115;0.0462;0 --0.4603;0.19915;0.0473;0 --0.4603;0.21745;0.046;0 --0.4603;0.23545;0.043;0 --0.4603;0.25555;0.0422;0 --0.43969;0.25555;0.0422;0 --0.41863;0.25555;0.0623;0 --0.39716;0.25555;0.0827;0 --0.377;0.25555;0.0843;0 --0.3566;0.25555;0.0876;0 --0.3366;0.25555;0.0927;0 --0.3109;0.25555;0.0825;0 --0.2931;0.25555;0.092;0 --0.275;0.25555;0.1043;0 --0.2473;0.25555;0.1004;0 --0.2168;0.25555;0.0968;0 --0.1782;0.25555;0.0905;0 --0.1579;0.25555;0.1131;0 --0.1281;0.25555;0.0828;0 --0.1024;0.25555;0.0786;0 --0.0858;0.25555;0.074;0 --0.0877;0.25555;0.0601;0 --0.0849;0.25555;0.0492;0 --0.0786;0.25555;0.0352;0 --0.06950000000000001;0.25555;0.0234;0 --0.0478;0.25555;0.0172;0 --0.024;0.25555;-0.0045;0 --0.0083;0.25555;-0.0246;0 -0.004;0.25555;-0.0477;0 -0.0103;0.25555;-0.06469999999999999;0 -0.0174;0.25555;-0.0736;0 -0.0253;0.25555;-0.08359999999999999;0 -0.0344;0.25555;-0.09520000000000001;0 -0.0446;0.25555;-0.1078;0 -0.0563;0.25555;-0.1235;0 -0.0654;0.25555;-0.1352;0 -0.0745;0.25555;-0.1457;0 -0.0839;0.25555;-0.1566;0 -0.09329999999999999;0.25555;-0.1675;0 -0.1028;0.25555;-0.1783;0 -0.1114;0.25555;-0.1878;0 -0.1218;0.25555;-0.1982;0 -0.1318;0.25555;-0.2068;0 -0.1431;0.25555;-0.2157;0 -0.1531;0.25555;-0.2233;0 -0.1643;0.25555;-0.2313;0 -0.1807;0.25555;-0.2427;0 -0.1938;0.25555;-0.2512;0 -0.186;0.25555;-0.266;0 -0.198;0.25555;-0.2733;0 -0.2103;0.25555;-0.2811;0 -0.222;0.25555;-0.2886;0 -0.236;0.25555;-0.2969;0 -0.2301;0.25555;-0.3106;0 -0.2448;0.25555;-0.3183;0 -0.2593;0.25555;-0.3255;0 -0.2718;0.25555;-0.3317;0 -0.2831;0.25555;-0.3355;0 -0.2963;0.25555;-0.339;0 -0.295;0.25555;-0.3533;0 -0.294;0.25555;-0.3686;0 -0.3081;0.25555;-0.3727;0 -0.3075;0.25555;-0.3902;0 -0.3067;0.25555;-0.4094;0 -0.3225;0.25555;-0.4136;0 -0.3216;0.25555;-0.4306;0 -0.3192;0.25555;-0.4477;0 -0.3155;0.25555;-0.4651;0 -0.3114;0.25555;-0.4832;0 -0.327;0.24365;-0.4865;0 -0.3451;0.24375;-0.49;0 -0.3602;0.23225;-0.4924;0 -0.3779;0.23255;-0.4948;0 -0.3948;0.23325;-0.4967;0 -0.4084;0.22475;-0.4978;0 -0.4243;0.21865;-0.4988;0 -0.423;0.22935;-0.4989;0 -0.4384;0.23875;-0.4996;0 -0.4603;0.25555;-0.5;0 -0.4415;0.25555;-0.4997;0 -0.4415;0.25555;-0.4812;0 -0.4237;0.25555;-0.4805;0 -0.4229;0.25555;-0.4624;0 -0.4227;0.25555;-0.4436;0 -0.4042;0.25555;-0.4437;0 -0.4039;0.25555;-0.4248;0 -0.3856;0.25555;-0.425;0 -0.3851;0.25555;-0.406;0 -0.3687;0.25555;-0.4033;0 -0.3536;0.25555;-0.4007;0 -0.3529;0.25555;-0.3821;0 -0.337;0.25555;-0.3794;0 -0.3363;0.25555;-0.3632;0 -0.3216;0.25555;-0.3596;0 -0.3083;0.25555;-0.3566;0 -0.3086;0.25555;-0.3417;0 -0.3089;0.25555;-0.3299;0 -0.3084;0.25555;-0.3199;0 -0.308;0.25555;-0.3125;0 -0.2999;0.25555;-0.3089;0 -0.2869;0.25555;-0.3061;0 -0.2872;0.25555;-0.2893;0 -0.2765;0.25555;-0.2758;0 -0.2761;0.25555;-0.2592;0 -0.2849;0.25555;-0.2444;0 -0.2884;0.25555;-0.2324;0 -0.2793;0.25555;-0.2318;0 -0.2736;0.25555;-0.2205;0 -0.2562;0.25555;-0.2106;0 -0.2404;0.25555;-0.2033;0 -0.2456;0.25555;-0.1878;0 -0.2291;0.25555;-0.1827;0 -0.2104;0.25555;-0.1792;0 -0.1945;0.25555;-0.1633;0 -0.1816;0.25555;-0.1404;0 -0.1837;0.25555;-0.1216;0 -0.1838;0.25555;-0.103;0 -0.1688;0.25555;-0.1008;0 -0.1704;0.25555;-0.0837;0 -0.1697;0.25555;-0.0674;0 -0.1687;0.25555;-0.0535;0 -0.1691;0.25555;-0.0462;0 -0.1618;0.25555;-0.0414;0 -0.1464;0.25555;-0.0335;0 -0.1424;0.25555;-0.008699999999999999;0 -0.1563;0.25555;0.0061;0 -0.1552;0.25555;0.0223;0 -0.1543;0.25555;0.0327;0 -0.1541;0.25555;0.0501;0 -0.1331;0.25555;0.0472;0 -0.1254;0.25555;0.0747;0 -0.0977;0.25555;0.0978;0 -0.1105;0.25555;0.1163;0 -0.1199;0.25555;0.1331;0 -0.1256;0.25555;0.1507;0 -0.1308;0.25555;0.1694;0 -0.1366;0.25555;0.1894;0 -0.1397;0.25555;0.21;0 -0.1624;0.25555;0.2272;0 -0.1822;0.25555;0.2249;0 -0.204;0.25555;0.2426;0 -0.2237;0.25555;0.2408;0 -0.2449;0.25555;0.2587;0 -0.2645;0.25555;0.2572;0 -0.2254;0.25555;0.2604;0 -0.2059;0.25555;0.2622;0 -0.1864;0.25555;0.2641;0 -0.1884;0.25555;0.2836;0 -0.169;0.25555;0.2856;0 -0.1712;0.25555;0.3049;0 -0.152;0.25555;0.3071;0 -0.1328;0.25555;0.3095;0 -0.1352;0.25555;0.3285;0 -0.1352;0.23635;0.3286;0 -0.1162;0.23635;0.3311;0 -0.09719999999999999;0.23635;0.3337;0 -0.09719999999999999;0.21715;0.3339;0 -0.0973;0.19805;0.3342;0 -0.07829999999999999;0.19805;0.337;0 -0.0594;0.19805;0.3399;0 -0.0596;0.17895;0.3403;0 -0.0408;0.17795;0.3434;0 -0.0408;0.15855;0.3441;0 -0.0382;0.14065;0.3452;0 -0.0217;0.13935;0.3481;0 -0.0217;0.12005;0.349;0 -0.0026;0.10095;0.3534;0 -0.0026;0.08165;0.3547;0 -0.0026;0.08215;0.3769;0 -0.0026;0.06304999999999999;0.3782;0 -0.0026;0.04595;0.40184;0 -0.0026;0.02915;0.42557;0 -0.0026;0.01035;0.42735;0 -0.0026;-0.008449999999999999;0.42927;0 -0.0026;-0.02725;0.43135;0 -0.0026;-0.04595;0.43356;0 -0.0026;-0.06465;0.43593;0 -0.0026;-0.08334999999999999;0.43843;0 -0.0026;-0.10205;0.44108;0 -0.0026;-0.10525;0.41913;0 -0.0026;-0.12405;0.42195;0 -0.0026;-0.14285;0.4249;0 -0.0026;-0.15798;0.44983;0 --0.001;-0.17341;0.47099;0 --0.0204;-0.17449;0.46489;0 --0.0368;-0.17417;0.4667;0 --0.0513;-0.17417;0.46672;0 --0.0677;-0.17417;0.4667;0 --0.0693;-0.17671;0.45238;0 --0.08450000000000001;-0.17431;0.46594;0 --0.1022;-0.17442;0.46535;0 --0.1203;-0.17422;0.4664;0 --0.1357;-0.17408;0.46718;0 --0.1489;-0.17478;0.46327;0 --0.1659;-0.17552;0.45911;0 --0.1799;-0.17626;0.45483;0 --0.1927;-0.17665;0.45265;0 --0.207;-0.17658;0.45306;0 --0.207;-0.15797;0.44983;0 --0.207;-0.14285;0.42689;0 --0.207;-0.12405;0.42393;0 --0.207;-0.10525;0.42114;0 --0.207;-0.10805;0.40115;0 --0.207;-0.11085;0.3812;0 --0.207;-0.11375;0.3612;0 --0.207;-0.11655;0.3412;0 --0.207;-0.11935;0.3212;0 --0.2079;-0.10235;0.3;0 --0.2106;-0.10485;0.2816;0 --0.2152;-0.10735;0.2636;0 --0.2215;-0.10975;0.2462;0 --0.2295;-0.11205;0.2294;0 --0.2391;-0.11425;0.2135;0 --0.2503;-0.11625;0.1986;0 --0.2628;-0.11815;0.1849;0 --0.2767;-0.11985;0.1725;0 --0.2917;-0.12135;0.1614;0 --0.3078;-0.12275;0.1519;0 --0.3247;-0.12375;0.1439;0 --0.3423;-0.12465;0.1377;0 --0.3423;-0.14565;0.1407;0 --0.3423;-0.16657;0.1438;0 --0.36046;-0.16726;0.1393;0 --0.36046;-0.18823;0.1426;0 --0.36046;-0.20916;0.146;0 --0.37897;-0.20962;0.1433;0 --0.39766;-0.23072;0.146;0 --0.41854;-0.23072;0.146;0 --0.41854;-0.23426;0.1259;0 --0.41878;-0.23783;0.1057;0 --0.41905;-0.24137;0.0856;0 --0.41989;-0.24496;0.0653;0 --0.40489;-0.248943;0.0426;0 --0.38664;-0.24905;0.0421;0 --0.38678;-0.252315;0.0235;0 --0.38678;-0.25555;0.0052;0 --0.37636;-0.23725;0.002;0 --0.3585;-0.23727;0.002;0 --0.36649;-0.21902;-0.001;0 --0.3749;-0.201;-0.0039;0 --0.38458;-0.18357;-0.0066;0 --0.39633;-0.167;-0.008999999999999999;0 --0.41027;-0.15115;-0.0113;0 --0.42595;-0.13545;-0.0134;0 --0.44275;-0.11935;-0.0156;0 --0.4603;-0.10255;-0.0176;0 --0.4603;-0.08115;-0.0009;0 --0.4603;-0.05995;0.0157;0 --0.4603;-0.04005;0.0341;0 --0.4603;-0.02105;0.0572;0 --0.4603;-0.00295;0.0556;0 --0.4603;0.01525;0.054;0 --0.4603;0.03365;0.0525;0 --0.4603;0.05205;0.0511;0 --0.4603;0.07065;0.0499;0 --0.4603;0.07235;0.073;0 --0.4603;0.09064999999999999;0.0718;0 --0.4603;0.10895;0.0708;0 --0.4603;0.12725;0.07000000000000001;0 --0.4603;0.14555;0.0692;0 --0.4603;0.16395;0.06850000000000001;0 --0.4603;0.18225;0.068;0 --0.4603;0.20055;0.06759999999999999;0 --0.4603;0.21865;0.0667;0 --0.4603;0.23615;0.0639;0 --0.4603;0.25555;0.0626;0 --0.43969;0.25555;0.0626;0 --0.41854;0.25555;0.0828;0 --0.39766;0.25555;0.1035;0 --0.37897;0.25555;0.1044;0 --0.36046;0.25555;0.1072;0 --0.3423;0.25555;0.1117;0 --0.3171;0.25555;0.0998;0 --0.3004;0.25555;0.1094;0 --0.2828;0.25555;0.1197;0 --0.2575;0.25555;0.1175;0 --0.23;0.25555;0.1166;0 --0.1976;0.25555;0.1148;0 --0.1796;0.25555;0.1353;0 --0.1394;0.25555;0.1378;0 --0.1133;0.25555;0.1188;0 --0.09180000000000001;0.25555;0.1052;0 --0.07480000000000001;0.25555;0.0946;0 --0.0608;0.25555;0.0828;0 --0.07389999999999999;0.25555;0.068;0 --0.07870000000000001;0.25555;0.0601;0 --0.0746;0.25555;0.0529;0 --0.06850000000000001;0.25555;0.0415;0 --0.0638;0.25555;0.034;0 --0.0516;0.25555;0.0349;0 --0.0299;0.25555;0.0448;0 --0.0184;0.25555;0.0289;0 --0.0041;0.25555;0.0103;0 -0.0078;0.25555;-0.0118;0 -0.0222;0.25555;-0.0431;0 -0.02;0.25555;-0.0597;0 -0.027;0.25555;-0.0648;0 -0.035;0.25555;-0.0721;0 -0.0445;0.25555;-0.0842;0 -0.0545;0.25555;-0.09719999999999999;0 -0.0658;0.25555;-0.1112;0 -0.07480000000000001;0.25555;-0.1224;0 -0.08400000000000001;0.25555;-0.1336;0 -0.0934;0.25555;-0.1447;0 -0.1026;0.25555;-0.1554;0 -0.1119;0.25555;-0.1663;0 -0.1195;0.25555;-0.1757;0 -0.1288;0.25555;-0.1854;0 -0.1381;0.25555;-0.1933;0 -0.1498;0.25555;-0.2016;0 -0.1596;0.25555;-0.2086;0 -0.1743;0.25555;-0.2178;0 -0.192;0.25555;-0.2304;0 -0.2043;0.25555;-0.2394;0 -0.2053;0.25555;-0.2586;0 -0.2171;0.25555;-0.2656;0 -0.2286;0.25555;-0.2737;0 -0.2429;0.25555;-0.2835;0 -0.2573;0.25555;-0.2929;0 -0.2499;0.25555;-0.3054;0 -0.266;0.25555;-0.3149;0 -0.2761;0.25555;-0.3221;0 -0.2848;0.25555;-0.3251;0 -0.2972;0.25555;-0.3283;0 -0.298;0.25555;-0.3185;0 -0.2864;0.25555;-0.3158;0 -0.2799;0.25555;-0.3152;0 -0.2753;0.25555;-0.305;0 -0.2754;0.25555;-0.2848;0 -0.2631;0.25555;-0.2793;0 -0.2692;0.25555;-0.2695;0 -0.2584;0.25555;-0.2601;0 -0.2671;0.25555;-0.2502;0 -0.274;0.25555;-0.2395;0 -0.2624;0.25555;-0.2322;0 -0.2476;0.25555;-0.2238;0 -0.2339;0.25555;-0.2176;0 -0.2224;0.25555;-0.2143;0 -0.2243;0.25555;-0.1976;0 -0.2084;0.25555;-0.1944;0 -0.1923;0.25555;-0.1767;0 -0.1811;0.25555;-0.1751;0 -0.1762;0.25555;-0.1639;0 -0.1583;0.25555;-0.1548;0 -0.1625;0.25555;-0.1393;0 -0.1669;0.25555;-0.1194;0 -0.1519;0.25555;-0.0982;0 -0.1566;0.25555;-0.0818;0 -0.157;0.25555;-0.0659;0 -0.1584;0.25555;-0.0522;0 -0.1427;0.25555;-0.0488;0 -0.1268;0.25555;-0.0465;0 -0.1319;0.25555;-0.0274;0 -0.1286;0.25555;0.0025;0 -0.1463;0.25555;0.0161;0 -0.1398;0.25555;0.0298;0 -0.1172;0.25555;0.0188;0 -0.1067;0.25555;0.0371;0 -0.0953;0.25555;0.0568;0 -0.0788;0.25555;0.07439999999999999;0 -0.06320000000000001;0.25555;0.09379999999999999;0 -0.0815;0.25555;0.1155;0 -0.0934;0.25555;0.13;0 -0.1016;0.25555;0.1423;0 -0.1062;0.25555;0.1562;0 -0.1103;0.25555;0.1725;0 -0.1153;0.25555;0.1934;0 -0.1194;0.25555;0.2135;0 -0.1425;0.25555;0.2297;0 -0.1646;0.25555;0.2468;0 -0.1843;0.25555;0.2446;0 -0.1669;0.25555;0.2663;0 -0.1474;0.25555;0.2686;0 -0.1497;0.25555;0.2879;0 -0.1304;0.25555;0.2903;0 -0.1111;0.25555;0.2928;0 -0.1137;0.25555;0.312;0 -0.1162;0.25555;0.331;0 -0.09719999999999999;0.25555;0.3336;0 -0.07829999999999999;0.23635;0.3364;0 -0.07829999999999999;0.21715;0.3367;0 -0.0593;0.21715;0.3395;0 -0.0407;0.19795;0.3429;0 -0.0217;0.19745;0.3461;0 -0.0217;0.17805;0.3466;0 -0.0217;0.15875;0.3472;0 -0.0026;0.13955;0.3514;0 -0.0026;0.12025;0.3523;0 -0.0026;0.12045;0.3745;0 -0.0026;0.10125;0.3756;0 -0.0026;0.08384999999999999;0.399;0 -0.0026;0.06485;0.40033;0 -0.0026;0.04795;0.42392;0 --0.0011;0.03095;0.44408;0 --0.0011;0.01225;0.44585;0 --0.0011;-0.00635;0.44777;0 --0.0011;-0.02505;0.44983;0 --0.0011;-0.04365;0.45203;0 --0.0011;-0.06225;0.45438;0 --0.0011;-0.08075;0.45685;0 --0.0011;-0.09934999999999999;0.45949;0 --0.0011;-0.11785;0.46225;0 -0.0026;-0.12075;0.44385;0 -0.0026;-0.13935;0.44678;0 --0.0011;-0.15485;0.4682;0 --0.0113;-0.17074;0.48622;0 --0.0231;-0.17257;0.47577;0 --0.0346;-0.17192;0.47952;0 --0.0484;-0.1713;0.48297;0 --0.0655;-0.17112;0.48398;0 --0.0837;-0.17114;0.48389;0 --0.103;-0.17126;0.48322;0 --0.1212;-0.17138;0.48256;0 --0.1382;-0.17159;0.48134;0 --0.1538;-0.1719;0.47961;0 --0.1699;-0.1725;0.47621;0 --0.183;-0.17352;0.47037;0 --0.1926;-0.17446;0.46507;0 --0.2034;-0.17341;0.47104;0 --0.2034;-0.15495;0.46779;0 --0.2034;-0.13645;0.46475;0 --0.207;-0.13935;0.44676;0 --0.207;-0.12065;0.44385;0 --0.207;-0.10205;0.44107;0 --0.207;-0.08635;0.41847;0 --0.207;-0.08905;0.3985;0 --0.207;-0.09175;0.3785;0 --0.207;-0.09435;0.3585;0 --0.207;-0.09705;0.3385;0 --0.207;-0.09975000000000001;0.3185;0 --0.2079;-0.08255;0.2973;0 --0.2106;-0.08495;0.2789;0 --0.2152;-0.08724999999999999;0.261;0 --0.2215;-0.08955;0.2435;0 --0.2295;-0.09175;0.2267;0 --0.2391;-0.09385;0.2108;0 --0.2503;-0.09575;0.1959;0 --0.2628;-0.09755;0.1821;0 --0.2767;-0.09915;0.1697;0 --0.2917;-0.10055;0.1586;0 --0.3078;-0.10185;0.1491;0 --0.3247;-0.10285;0.1412;0 --0.3423;-0.10365;0.1349;0 --0.36046;-0.10425;0.1304;0 --0.36046;-0.12525;0.1332;0 --0.36046;-0.14625;0.1362;0 --0.37897;-0.14665;0.1334;0 --0.37897;-0.16767;0.1366;0 --0.37897;-0.18867;0.1399;0 --0.39766;-0.18881;0.139;0 --0.39766;-0.20977;0.1424;0 --0.4151;-0.20828;0.1422;0 --0.42743;-0.21163;0.1427;0 --0.43943;-0.23072;0.146;0 --0.43959;-0.23426;0.1259;0 --0.43972;-0.23782;0.1058;0 --0.43978;-0.24136;0.0857;0 --0.43982;-0.2449;0.0655;0 --0.42278;-0.248744;0.0438;0 --0.42354;-0.252224;0.024;0 --0.40517;-0.252285;0.0237;0 --0.40517;-0.25555;0.0052;0 --0.39403;-0.23715;0.002;0 --0.3837;-0.21897;-0.001;0 --0.39133;-0.20114;-0.0039;0 --0.40064;-0.18437;-0.0064;0 --0.41257;-0.16876;-0.008800000000000001;0 --0.427;-0.15355;-0.0109;0 --0.44315;-0.13805;-0.0131;0 --0.4603;-0.12175;-0.0153;0 --0.4603;-0.10025;0.0014;0 --0.4603;-0.07895000000000001;0.018;0 --0.4603;-0.05855;0.0366;0 --0.4603;-0.03915;0.0591;0 --0.4603;-0.01915;0.0804;0 --0.4603;-0.00085;0.0786;0 --0.4603;0.01745;0.0771;0 --0.4603;0.03575;0.0756;0 --0.4603;0.05405;0.0742;0 --0.4603;0.07345;0.0912;0 --0.4603;0.09165;0.0901;0 --0.4603;0.10985;0.0891;0 --0.4603;0.12805;0.0882;0 --0.4603;0.14625;0.08749999999999999;0 --0.4603;0.16445;0.0868;0 --0.4603;0.18275;0.0863;0 --0.4603;0.20095;0.0859;0 --0.4603;0.21915;0.0856;0 --0.4603;0.23735;0.0849;0 --0.4603;0.25555;0.08309999999999999;0 --0.43943;0.25555;0.0829;0 --0.41854;0.25555;0.1035;0 --0.41507;0.23345;0.1036;0 --0.39766;0.23425;0.1036;0 --0.37897;0.23425;0.1045;0 --0.36046;0.23425;0.1072;0 --0.3423;0.23435;0.1118;0 --0.3247;0.23435;0.1181;0 --0.3246;0.25555;0.118;0 --0.3077;0.25555;0.126;0 --0.2917;0.25555;0.1357;0 --0.2663;0.25555;0.1318;0 --0.2412;0.25555;0.1322;0 --0.2129;0.25555;0.1333;0 --0.1968;0.25555;0.1517;0 --0.1636;0.25555;0.157;0 --0.1275;0.25555;0.1626;0 --0.1012;0.25555;0.1434;0 --0.0798;0.25555;0.1278;0 --0.06270000000000001;0.25555;0.1141;0 --0.0448;0.25555;0.0984;0 --0.0339;0.25555;0.0839;0 --0.0496;0.25555;0.07099999999999999;0 --0.065;0.25555;0.0598;0 --0.0569;0.25555;0.0483;0 --0.0396;0.25555;0.0587;0 --0.0237;0.25555;0.0716;0 --0.0111;0.25555;0.0545;0 --0.0004;0.25555;0.0394;0 -0.0123;0.25555;0.0217;0 -0.0243;0.25555;0.0032;0 -0.04;0.25555;-0.0217;0 -0.0505;0.25555;-0.0367;0 -0.0357;0.25555;-0.0517;0 -0.0465;0.25555;-0.0612;0 -0.0552;0.25555;-0.0725;0 -0.06510000000000001;0.25555;-0.0862;0 -0.07530000000000001;0.25555;-0.09959999999999999;0 -0.0838;0.25555;-0.1101;0 -0.09379999999999999;0.25555;-0.1215;0 -0.1032;0.25555;-0.1322;0 -0.1121;0.25555;-0.143;0 -0.1214;0.25555;-0.1543;0 -0.1289;0.25555;-0.1632;0 -0.1371;0.25555;-0.1709;0 -0.1459;0.25555;-0.1787;0 -0.157;0.25555;-0.188;0 -0.1666;0.25555;-0.1952;0 -0.1841;0.25555;-0.205;0 -0.2071;0.25555;-0.2159;0 -0.2149;0.25555;-0.229;0 -0.2139;0.25555;-0.246;0 -0.2248;0.25555;-0.2524;0 -0.2366;0.25555;-0.2604;0 -0.2502;0.25555;-0.2702;0 -0.2456;0.25555;-0.2504;0 -0.2538;0.25555;-0.2416;0 -0.2406;0.25555;-0.2334;0 -0.229;0.25555;-0.2273;0 -0.2224;0.25555;-0.2239;0 -0.223;0.25555;-0.2349;0 -0.234;0.25555;-0.2417;0 -0.1888;0.25555;-0.19;0 -0.1752;0.25555;-0.1835;0 -0.1644;0.25555;-0.1753;0 -0.1519;0.25555;-0.1665;0 -0.1475;0.25555;-0.151;0 -0.1488;0.25555;-0.1387;0 -0.1451;0.25555;-0.1189;0 -0.1339;0.25555;-0.1096;0 -0.1359;0.25555;-0.0951;0 -0.1379;0.25555;-0.079;0 -0.1394;0.25555;-0.06320000000000001;0 -0.1233;0.25555;-0.0617;0 -0.1098;0.25555;-0.0448;0 -0.1111;0.25555;-0.0203;0 -0.0983;0.25555;0.003;0 -0.08740000000000001;0.25555;0.022;0 -0.07480000000000001;0.25555;0.0429;0 -0.06270000000000001;0.25555;0.0582;0 -0.0478;0.25555;0.0769;0 -0.0343;0.25555;0.0917;0 -0.0495;0.25555;0.1099;0 -0.0684;0.25555;0.1318;0 -0.08169999999999999;0.25555;0.1417;0 -0.09130000000000001;0.25555;0.1474;0 -0.0914;0.25555;0.1587;0 -0.0927;0.25555;0.1765;0 -0.0958;0.25555;0.1985;0 -0.0988;0.25555;0.2183;0 -0.1226;0.25555;0.2327;0 -0.145;0.25555;0.2492;0 -0.1254;0.25555;0.2518;0 -0.1279;0.25555;0.271;0 -0.1085;0.25555;0.2737;0 -0.089;0.25555;0.2767;0 -0.09180000000000001;0.25555;0.2956;0 -0.0945;0.25555;0.3146;0 -0.07539999999999999;0.25555;0.3174;0 -0.07829999999999999;0.25555;0.3364;0 -0.0593;0.23635;0.3393;0 -0.0404;0.23635;0.3423;0 -0.0405;0.21705;0.3426;0 -0.0216;0.21675;0.3457;0 -0.0026;0.19755;0.3494;0 -0.0026;0.17815;0.3499;0 -0.0026;0.15885;0.3506;0 -0.0026;0.15875;0.3728;0 -0.0026;0.13955;0.3736;0 -0.0026;0.12175;0.3967;0 -0.0026;0.10285;0.3977;0 -0.0026;0.08555;0.42107;0 -0.0026;0.06675;0.42241;0 --0.0011;0.04965;0.44243;0 --0.0115;0.03235;0.45929;0 --0.0115;0.01375;0.46104;0 --0.0115;-0.00475;0.46295;0 --0.0115;-0.02325;0.465;0 --0.0115;-0.04175;0.46718;0 --0.0115;-0.06025;0.46951;0 --0.0115;-0.07865;0.47197;0 --0.0115;-0.09715;0.47458;0 --0.0115;-0.11555;0.47731;0 --0.0115;-0.13395;0.48021;0 --0.0011;-0.13635;0.46515;0 --0.0115;-0.15235;0.48322;0 --0.0267;-0.16894;0.496414;0 --0.045;-0.1683;0.5;0 --0.0641;-0.1683;0.5;0 --0.08309999999999999;-0.1683;0.5;0 --0.1022;-0.1683;0.5;0 --0.1212;-0.1683;0.5;0 --0.1403;-0.1683;0.5;0 --0.1593;-0.1683;0.5;0 --0.1775;-0.16894;0.496414;0 --0.193;-0.17073;0.4863;0 --0.1931;-0.15235;0.48302;0 --0.1931;-0.13395;0.47998;0 --0.1931;-0.11555;0.4771;0 --0.2034;-0.11795;0.46185;0 --0.2034;-0.09934999999999999;0.45908;0 --0.2034;-0.08085000000000001;0.45645;0 --0.207;-0.08334999999999999;0.43843;0 --0.207;-0.06745;0.41595;0 --0.207;-0.06995;0.3959;0 --0.207;-0.07255;0.3759;0 --0.207;-0.07505000000000001;0.3559;0 --0.207;-0.07765;0.3359;0 --0.207;-0.08015;0.3158;0 --0.2079;-0.06275;0.2948;0 --0.2106;-0.06505;0.2765;0 --0.2152;-0.06725;0.2584;0 --0.2215;-0.06934999999999999;0.2409;0 --0.2295;-0.07145;0.2241;0 --0.2391;-0.07335;0.2082;0 --0.2503;-0.07514999999999999;0.1933;0 --0.2628;-0.07685;0.1795;0 --0.2767;-0.07835;0.1671;0 --0.2917;-0.07975;0.156;0 --0.3078;-0.08085000000000001;0.1464;0 --0.3247;-0.08185000000000001;0.1385;0 --0.3423;-0.08265;0.1322;0 --0.36046;-0.08315;0.1277;0 --0.37897;-0.08355;0.125;0 --0.37897;-0.10455;0.1277;0 --0.37897;-0.12565;0.1305;0 --0.39766;-0.12575;0.1296;0 --0.39766;-0.14675;0.1325;0 --0.39766;-0.16783;0.1357;0 --0.41063;-0.17822;0.1373;0 --0.41164;-0.19529;0.14;0 --0.42371;-0.19621;0.1402;0 --0.43286;-0.19564;0.1401;0 --0.44324;-0.2125;0.1429;0 --0.4603;-0.23072;0.146;0 --0.4603;-0.23426;0.1259;0 --0.4603;-0.23782;0.1058;0 --0.4603;-0.24136;0.0857;0 --0.4603;-0.2449;0.0655;0 --0.4403;-0.248455;0.0454;0 --0.44191;-0.252132;0.0245;0 --0.44193;-0.25555;0.0052;0 --0.42354;-0.25555;0.0052;0 --0.41115;-0.23683;0.002;0 --0.40018;-0.21876;-0.0011;0 --0.40676;-0.20135;-0.0038;0 --0.41593;-0.18577;-0.0062;0 --0.42852;-0.17137;-0.008399999999999999;0 --0.44368;-0.15666;-0.0105;0 --0.4603;-0.14095;-0.0127;0 --0.4603;-0.11925;0.0038;0 --0.4603;-0.09785000000000001;0.0204;0 --0.4603;-0.07715;0.0392;0 --0.4603;-0.05735;0.0612;0 --0.4603;-0.03735;0.0822;0 --0.4603;-0.01735;0.09859999999999999;0 --0.4603;0.00085;0.0969;0 --0.4603;0.01895;0.0953;0 --0.4603;0.03715;0.09379999999999999;0 --0.4603;0.05535;0.0924;0 --0.4603;0.07464999999999999;0.1093;0 --0.4603;0.09275;0.1082;0 --0.4603;0.11085;0.1072;0 --0.4603;0.12895;0.1063;0 --0.4603;0.14695;0.1056;0 --0.4603;0.16505;0.105;0 --0.4603;0.18315;0.1044;0 --0.4603;0.20125;0.104;0 --0.4603;0.21935;0.1037;0 --0.4603;0.23745;0.1035;0 --0.4603;0.25555;0.1035;0 --0.43943;0.25555;0.1035;0 --0.42739;0.23675;0.1035;0 --0.42363;0.22145;0.1037;0 --0.41161;0.22015;0.1037;0 --0.39766;0.21305;0.1038;0 --0.37897;0.21305;0.1047;0 --0.36046;0.21305;0.1075;0 --0.3423;0.21315;0.112;0 --0.3247;0.21325;0.1183;0 --0.3078;0.21335;0.1263;0 --0.3078;0.23445;0.1261;0 --0.2917;0.23455;0.1357;0 --0.2767;0.23455;0.1468;0 --0.2766;0.25555;0.1468;0 --0.251;0.25555;0.1455;0 --0.2261;0.25555;0.1483;0 --0.2123;0.25555;0.1659;0 --0.1828;0.25555;0.1716;0 --0.1504;0.25555;0.1785;0 --0.117;0.25555;0.1862;0 --0.0887;0.25555;0.1669;0 --0.0673;0.25555;0.1505;0 --0.0495;0.25555;0.1349;0 --0.03;0.25555;0.1153;0 --0.0166;0.25555;0.0982;0 --0.008;0.25555;0.08450000000000001;0 -0.005;0.25555;0.06610000000000001;0 -0.0165;0.25555;0.0514;0 -0.0288;0.25555;0.0341;0 -0.0405;0.25555;0.0181;0 -0.0545;0.25555;-0.0063;0 -0.06510000000000001;0.25555;-0.0252;0 -0.0727;0.25555;-0.0376;0 -0.0588;0.25555;-0.0484;0 -0.0675;0.25555;-0.0603;0 -0.0772;0.25555;-0.07340000000000001;0 -0.0858;0.25555;-0.08649999999999999;0 -0.09329999999999999;0.25555;-0.0958;0 -0.1035;0.25555;-0.1097;0 -0.1125;0.25555;-0.1225;0 -0.1207;0.25555;-0.1344;0 -0.1292;0.25555;-0.1464;0 -0.1356;0.25555;-0.1544;0 -0.143;0.25555;-0.16;0 -0.1403;0.25555;-0.1493;0 -0.1379;0.25555;-0.1414;0 -0.1318;0.25555;-0.1275;0 -0.1234;0.25555;-0.1138;0 -0.116;0.25555;-0.09470000000000001;0 -0.1203;0.25555;-0.07539999999999999;0 -0.1073;0.25555;-0.0713;0 -0.1087;0.25555;-0.0604;0 -0.09760000000000001;0.25555;-0.0609;0 -0.0935;0.25555;-0.0468;0 -0.0878;0.25555;-0.0299;0 -0.08;0.25555;-0.013;0 -0.0689;0.25555;0.0074;0 -0.0565;0.25555;0.03;0 -0.0452;0.25555;0.046;0 -0.033;0.25555;0.06370000000000001;0 -0.0211;0.25555;0.0781;0 -0.0069;0.25555;0.0953;0 -0.0216;0.25555;0.106;0 -0.0348;0.25555;0.1257;0 -0.0549;0.25555;0.1526;0 -0.0767;0.25555;0.1572;0 -0.0766;0.25555;0.1803;0 -0.07779999999999999;0.25555;0.2029;0 -0.079;0.25555;0.2241;0 -0.1026;0.25555;0.2364;0 -0.1057;0.25555;0.2548;0 -0.0861;0.25555;0.2584;0 -0.0665;0.25555;0.2627;0 -0.0696;0.25555;0.2801;0 -0.0726;0.25555;0.2985;0 -0.0534;0.25555;0.3017;0 -0.0564;0.25555;0.3203;0 -0.0593;0.25555;0.3392;0 -0.0404;0.25555;0.3423;0 -0.0215;0.25555;0.3455;0 -0.0215;0.23635;0.3455;0 -0.0026;0.23615;0.3488;0 -0.0026;0.21685;0.349;0 -0.0026;0.21635;0.3712;0 -0.0026;0.19715;0.3716;0 -0.0026;0.17795;0.3721;0 -0.0026;0.15985;0.3949;0 -0.0026;0.14075;0.3957;0 -0.0026;0.12315;0.41875;0 -0.0026;0.10435;0.41984;0 --0.0011;0.08695;0.43959;0 --0.0011;0.06825000000000001;0.44095;0 --0.0115;0.05085;0.45767;0 --0.0269;0.03325;0.46945;0 --0.0269;0.01475;0.47121;0 --0.0269;-0.00365;0.4731;0 --0.0269;-0.02215;0.47514;0 --0.0269;-0.04055;0.47731;0 --0.0269;-0.05895;0.47963;0 --0.0269;-0.07735;0.48207;0 --0.0269;-0.09565;0.48466;0 --0.0269;-0.11405;0.48741;0 --0.0269;-0.13235;0.49028;0 --0.0269;-0.15065;0.493286;0 --0.045;-0.15005;0.496857;0 --0.0641;-0.15005;0.496857;0 --0.08309999999999999;-0.15005;0.496857;0 --0.1022;-0.15005;0.496857;0 --0.1212;-0.15005;0.496857;0 --0.1403;-0.15005;0.496857;0 --0.1593;-0.15005;0.496857;0 --0.1777;-0.15065;0.493194;0 --0.1777;-0.13235;0.490173;0 --0.1777;-0.11405;0.4873;0 --0.1777;-0.09565;0.48457;0 --0.1931;-0.09715;0.47435;0 --0.1931;-0.07875;0.47174;0 --0.1931;-0.06025;0.46928;0 --0.2034;-0.06225;0.45396;0 --0.207;-0.06455;0.43591;0 --0.207;-0.04855;0.41357;0 --0.207;-0.05095;0.3935;0 --0.207;-0.05335;0.3735;0 --0.207;-0.05575;0.3535;0 --0.207;-0.05815;0.3334;0 --0.207;-0.06055;0.3134;0 --0.2079;-0.04295;0.2925;0 --0.2106;-0.04505;0.2741;0 --0.2152;-0.04715;0.2561;0 --0.2215;-0.04915;0.2386;0 --0.2295;-0.05105;0.2218;0 --0.2391;-0.05285;0.2058;0 --0.2503;-0.05465;0.1909;0 --0.2628;-0.05615;0.1771;0 --0.2767;-0.05765;0.1646;0 --0.2917;-0.05885;0.1535;0 --0.3078;-0.05995;0.144;0 --0.3247;-0.06085;0.136;0 --0.3423;-0.06155;0.1298;0 --0.36046;-0.06215;0.1252;0 --0.37897;-0.06245;0.1225;0 --0.39766;-0.06254999999999999;0.1216;0 --0.39766;-0.08365;0.1241;0 --0.39766;-0.10465;0.1267;0 --0.4102;-0.11995;0.1288;0 --0.41024;-0.13985;0.1315;0 --0.41033;-0.15942;0.1344;0 --0.4229;-0.16967;0.136;0 --0.42317;-0.18519;0.1384;0 --0.43451;-0.18052;0.1376;0 --0.44585;-0.19519;0.14;0 --0.4603;-0.2129;0.1429;0 --0.4603;-0.21615;0.1237;0 --0.4603;-0.21815;0.1022;0 --0.4603;-0.22135;0.0819;0 --0.4603;-0.22512;0.0617;0 --0.4603;-0.248455;0.0454;0 --0.4603;-0.251995;0.0253;0 --0.4603;-0.25555;0.0052;0 --0.44008;-0.23288;0.0013;0 --0.42705;-0.23587;0.0018;0 --0.41529;-0.21818;-0.0012;0 --0.42069;-0.20182;-0.0038;0 --0.43056;-0.18829;-0.0059;0 --0.4444;-0.17497;-0.007900000000000001;0 --0.4603;-0.16007;-0.01;0 --0.4603;-0.13835;0.0064;0 --0.4603;-0.11685;0.0228;0 --0.4603;-0.09565;0.0417;0 --0.4603;-0.07555000000000001;0.0635;0 --0.4603;-0.05565;0.0842;0 --0.4603;-0.03545;0.1004;0 --0.4603;-0.01555;0.1166;0 --0.4603;0.00245;0.115;0 --0.4603;0.02045;0.1134;0 --0.4603;0.03855;0.1119;0 --0.4603;0.05665;0.1106;0 --0.44777;0.05715;0.1105;0 --0.44777;0.07545;0.1093;0 --0.44777;0.09385;0.1082;0 --0.44777;0.11215;0.1072;0 --0.44777;0.13055;0.1063;0 --0.44776;0.14885;0.1055;0 --0.44767;0.16725;0.1049;0 --0.44745;0.18525;0.1044;0 --0.44696;0.20285;0.104;0 --0.44579;0.22005;0.1037;0 --0.44323;0.23735;0.1035;0 --0.43279;0.22085;0.1037;0 --0.4231;0.21025;0.1038;0 --0.41059;0.20265;0.104;0 --0.39766;0.19175;0.1042;0 --0.37897;0.19175;0.1051;0 --0.36046;0.19185;0.1079;0 --0.3423;0.19195;0.1124;0 --0.3247;0.19215;0.1187;0 --0.3078;0.19225;0.1267;0 --0.2917;0.19255;0.1363;0 --0.2917;0.21345;0.1359;0 --0.2767;0.21365;0.1471;0 --0.2628;0.21385;0.1597;0 --0.2628;0.23465;0.1594;0 --0.2628;0.25555;0.1594;0 --0.2371;0.25555;0.1605;0 --0.2248;0.25555;0.177;0 --0.1998;0.25555;0.1852;0 --0.1711;0.25555;0.1923;0 --0.1404;0.25555;0.2016;0 --0.1064;0.25555;0.2139;0 --0.07539999999999999;0.25555;0.1959;0 --0.0511;0.25555;0.1784;0 --0.0331;0.25555;0.1617;0 --0.0103;0.25555;0.136;0 --0.0021;0.25555;0.1085;0 -0.0119;0.25555;0.1141;0 -0.0158;0.25555;0.1349;0 -0.0265;0.25555;0.1665;0 -0.0567;0.25555;0.1863;0 -0.0591;0.25555;0.2072;0 -0.0621;0.25555;0.2284;0 -0.0827;0.25555;0.2412;0 -0.0654;0.25555;0.2458;0 -0.0478;0.25555;0.2495;0 -0.0488;0.25555;0.2669;0 -0.0503;0.25555;0.2838;0 -0.0324;0.25555;0.2874;0 -0.0343;0.25555;0.3051;0 -0.0373;0.25555;0.3235;0 -0.0183;0.25555;0.3266;0 -0.0004;0.25555;0.3292;0 -0.0026;0.25555;0.3488;0 -0.0026;0.25555;0.3709;0 -0.0026;0.23545;0.371;0 -0.0026;0.21685;0.3934;0 -0.0026;0.19785;0.3937;0 -0.0026;0.17885;0.3943;0 -0.0026;0.16085;0.41704;0 -0.0026;0.14205;0.41785;0 --0.0011;0.12435;0.43733;0 --0.0011;0.10565;0.4384;0 --0.0115;0.08805;0.45485;0 --0.0115;0.06945;0.45618;0 --0.0269;0.05175;0.46783;0 --0.045;0.03355;0.47302;0 --0.045;0.01515;0.47478;0 --0.045;-0.00325;0.47668;0 --0.045;-0.02175;0.4787;0 --0.045;-0.04005;0.48088;0 --0.045;-0.05845;0.4832;0 --0.045;-0.07685;0.48564;0 --0.045;-0.09515;0.48824;0 --0.045;-0.11345;0.490967;0 --0.045;-0.13175;0.493835;0 --0.0641;-0.13175;0.493835;0 --0.08309999999999999;-0.13175;0.493835;0 --0.1022;-0.13175;0.493835;0 --0.1212;-0.13175;0.493835;0 --0.1403;-0.13175;0.493835;0 --0.1593;-0.13175;0.493835;0 --0.1593;-0.11345;0.490967;0 --0.1593;-0.09515;0.48824;0 --0.1593;-0.07685;0.48564;0 --0.1777;-0.07735;0.48198;0 --0.1777;-0.05895;0.47952;0 --0.1777;-0.04055;0.47719;0 --0.1931;-0.04175;0.46695;0 --0.2034;-0.04365;0.45164;0 --0.207;-0.04585;0.43356;0 --0.207;-0.02965;0.41131;0 --0.207;-0.03185;0.3913;0 --0.207;-0.03415;0.3712;0 --0.207;-0.03635;0.3512;0 --0.207;-0.03865;0.3311;0 --0.207;-0.04085;0.311;0 --0.2079;-0.02315;0.2903;0 --0.2106;-0.02515;0.2719;0 --0.2152;-0.02705;0.2538;0 --0.2215;-0.02895;0.2363;0 --0.2295;-0.03075;0.2195;0 --0.2391;-0.03245;0.2035;0 --0.2503;-0.03405;0.1886;0 --0.2628;-0.03545;0.1748;0 --0.2767;-0.03685;0.1623;0 --0.2917;-0.03795;0.1512;0 --0.3078;-0.03905;0.1417;0 --0.3247;-0.03985;0.1337;0 --0.3423;-0.04055;0.1274;0 --0.36046;-0.04105;0.1229;0 --0.37897;-0.04125;0.1202;0 --0.39766;-0.04145;0.1193;0 --0.41019;-0.05955;0.1213;0 --0.41019;-0.07975;0.1236;0 --0.41019;-0.09995;0.1261;0 --0.42272;-0.11465;0.1281;0 --0.42273;-0.13355;0.1307;0 --0.42278;-0.15215;0.1333;0 --0.43502;-0.16415;0.1351;0 --0.44704;-0.17823;0.1373;0 --0.4603;-0.19506;0.14;0 --0.4603;-0.19812;0.1213;0 --0.4603;-0.20034;0.1011;0 --0.4603;-0.20335;0.0795;0 --0.4603;-0.20623;0.0572;0 --0.4603;-0.22908;0.0415;0 --0.4603;-0.23323;0.0211;0 --0.4603;-0.23649;0.0019;0 --0.44539;-0.22326;-0.0003;0 --0.42772;-0.21684;-0.0014;0 --0.43302;-0.20344;-0.0035;0 --0.44527;-0.1927;-0.0052;0 --0.4603;-0.17919;-0.0072;0 --0.4603;-0.15734;0.008999999999999999;0 --0.4603;-0.13575;0.0254;0 --0.4603;-0.13255;0.0465;0 --0.4603;-0.11415;0.0441;0 --0.4603;-0.09385;0.0658;0 --0.4603;-0.07385;0.0862;0 --0.4603;-0.05355;0.1023;0 --0.4603;-0.03365;0.1185;0 --0.44777;-0.01615;0.1167;0 --0.44777;0.00215;0.115;0 --0.44777;0.02045;0.1134;0 --0.44777;0.03875;0.1119;0 --0.43524;0.03935;0.1118;0 --0.43524;0.05815;0.1105;0 --0.43524;0.07695;0.1092;0 --0.43524;0.09575;0.108;0 --0.43524;0.11455;0.107;0 --0.43524;0.13345;0.1062;0 --0.43521;0.15225;0.1054;0 --0.43512;0.17075;0.1048;0 --0.43492;0.18875;0.1043;0 --0.43441;0.20555;0.1039;0 --0.42281;0.19435;0.1041;0 --0.4103;0.18345;0.1044;0 --0.39766;0.17055;0.1048;0 --0.37897;0.17055;0.1057;0 --0.36046;0.17065;0.1085;0 --0.3423;0.17075;0.113;0 --0.3247;0.17095;0.1193;0 --0.3078;0.17125;0.1273;0 --0.2917;0.17155;0.1369;0 --0.2767;0.17185;0.148;0 --0.2767;0.19275;0.1475;0 --0.2628;0.19305;0.16;0 --0.2503;0.19335;0.1739;0 --0.2503;0.21405;0.1735;0 --0.2503;0.23475;0.1733;0 --0.2502;0.25555;0.1733;0 --0.2391;0.25555;0.1883;0 --0.2141;0.25555;0.1945;0 --0.1899;0.25555;0.2048;0 --0.1611;0.25555;0.2136;0 --0.1301;0.25555;0.2269;0 --0.0948;0.25555;0.247;0 --0.0539;0.25555;0.2344;0 --0.0311;0.25555;0.2083;0 --0.0139;0.25555;0.1926;0 -0.005;0.25555;0.1771;0 -0.0348;0.25555;0.1944;0 -0.04;0.25555;0.2124;0 -0.0453;0.25555;0.2315;0 -0.0313;0.25555;0.2507;0 -0.0321;0.25555;0.2699;0 -0.0143;0.25555;0.2695;0 -0.0153;0.25555;0.2896;0 -0.0161;0.25555;0.3081;0 --0.0012;0.25555;0.3095;0 --0.0178;0.25555;0.3125;0 --0.0186;0.25555;0.3296;0 --0.0173;0.25555;0.3499;0 --0.016;0.25555;0.3708;0 --0.015;0.25555;0.3924;0 -0.0026;0.25555;0.3931;0 -0.0026;0.23595;0.3932;0 -0.0026;0.21745;0.41553;0 -0.0026;0.19865;0.41589;0 -0.0026;0.17975;0.4164;0 --0.0011;0.16185;0.43561;0 --0.0011;0.14315;0.43639;0 --0.0115;0.12515;0.45261;0 --0.0115;0.10665;0.45364;0 --0.0269;0.08875;0.46503;0 --0.0269;0.07025000000000001;0.46637;0 --0.045;0.05205;0.47142;0 --0.0641;0.03355;0.47302;0 --0.0641;0.01515;0.47478;0 --0.0641;-0.00325;0.47668;0 --0.0641;-0.02175;0.4787;0 --0.0641;-0.04005;0.48088;0 --0.0641;-0.05845;0.4832;0 --0.0641;-0.07685;0.48564;0 --0.0641;-0.09515;0.48824;0 --0.0641;-0.11345;0.490967;0 --0.08309999999999999;-0.11345;0.490967;0 --0.1022;-0.11345;0.490967;0 --0.1212;-0.11345;0.490967;0 --0.1403;-0.11345;0.490967;0 --0.1403;-0.09515;0.48824;0 --0.1403;-0.07685;0.48564;0 --0.1403;-0.05845;0.4832;0 --0.1593;-0.05845;0.4832;0 --0.1593;-0.04005;0.48088;0 --0.1593;-0.02175;0.4787;0 --0.1777;-0.02215;0.47502;0 --0.1931;-0.02325;0.46477;0 --0.2034;-0.02505;0.44943;0 --0.207;-0.02715;0.43133;0 --0.207;-0.01075;0.40924;0 --0.207;-0.01285;0.3892;0 --0.207;-0.01485;0.3691;0 --0.207;-0.01695;0.349;0 --0.207;-0.01905;0.3289;0 --0.207;-0.02115;0.3089;0 --0.2079;-0.00335;0.2883;0 --0.2106;-0.00515;0.2698;0 --0.2152;-0.00695;0.2518;0 --0.2215;-0.00865;0.2342;0 --0.2295;-0.01035;0.2174;0 --0.2391;-0.01195;0.2014;0 --0.2503;-0.01345;0.1865;0 --0.2628;-0.01475;0.1727;0 --0.2767;-0.01595;0.1602;0 --0.2917;-0.01705;0.1491;0 --0.3078;-0.01805;0.1395;0 --0.3247;-0.01885;0.1315;0 --0.3423;-0.01945;0.1253;0 --0.36046;-0.01995;0.1208;0 --0.37897;-0.02015;0.118;0 --0.39766;-0.02025;0.1171;0 --0.41019;-0.03935;0.1191;0 --0.42272;-0.05675;0.121;0 --0.42272;-0.07615;0.1232;0 --0.42272;-0.09544999999999999;0.1256;0 --0.43523;-0.11035;0.1275;0 --0.43521;-0.12875;0.13;0 --0.43517;-0.14675;0.1325;0 --0.4475;-0.16097;0.1347;0 --0.4603;-0.17719;0.1371;0 --0.4603;-0.18008;0.1187;0 --0.4603;-0.18247;0.09959999999999999;0 --0.4603;-0.1842;0.07820000000000001;0 --0.4603;-0.18786;0.0543;0 --0.4603;-0.19238;0.0336;0 --0.4603;-0.21105;0.037;0 --0.4603;-0.2143;0.0178;0 --0.4603;-0.2174;-0.0013;0 --0.446;-0.20921;-0.0026;0 --0.43532;-0.2145;-0.0017;0 --0.4603;-0.19831;-0.0043;0 --0.4603;-0.17636;0.0118;0 --0.4603;-0.15465;0.028;0 --0.4603;-0.15095;0.0489;0 --0.4603;-0.13015;0.0704;0 --0.4603;-0.11205;0.068;0 --0.4603;-0.09205000000000001;0.08840000000000001;0 --0.4603;-0.08985;0.1065;0 --0.4603;-0.07174999999999999;0.1044;0 --0.4603;-0.06965;0.1224;0 --0.4603;-0.05165;0.1204;0 --0.44777;-0.03445;0.1185;0 --0.43524;-0.01695;0.1168;0 --0.43524;0.00185;0.115;0 --0.43524;0.02055;0.1134;0 --0.42272;0.02095;0.1133;0 --0.42272;0.04035;0.1118;0 --0.42272;0.05985;0.1103;0 --0.42272;0.07925;0.109;0 --0.42272;0.09875;0.1079;0 --0.42272;0.11825;0.1069;0 --0.42272;0.13775;0.106;0 --0.42272;0.15715;0.1052;0 --0.42272;0.17625;0.1046;0 --0.41022;0.16355;0.105;0 --0.39766;0.14935;0.1055;0 --0.37897;0.14935;0.1064;0 --0.36046;0.14945;0.1092;0 --0.3423;0.14965;0.1137;0 --0.3247;0.14985;0.12;0 --0.3078;0.15015;0.128;0 --0.2917;0.15055;0.1376;0 --0.2767;0.15095;0.1488;0 --0.2628;0.15145;0.1613;0 --0.2628;0.17225;0.1606;0 --0.2503;0.17265;0.1745;0 --0.2391;0.17315;0.1895;0 --0.2391;0.19375;0.1889;0 --0.2391;0.21435;0.1885;0 --0.2391;0.23495;0.1883;0 --0.2295;0.23505;0.2044;0 --0.2295;0.25555;0.2044;0 --0.2052;0.25555;0.2129;0 --0.1815;0.25555;0.225;0 --0.1524;0.25555;0.2367;0 --0.1212;0.25555;0.2556;0 --0.0901;0.25555;0.2776;0 --0.0578;0.25555;0.2731;0 --0.0269;0.25555;0.245;0 --0.0149;0.25555;0.227;0 --0.0012;0.25555;0.2154;0 -0.0158;0.25555;0.2044;0 -0.0218;0.25555;0.22;0 -0.0272;0.25555;0.2342;0 -0.0109;0.25555;0.2405;0 -0.0131;0.25555;0.253;0 -0.001;0.25555;0.2533;0 --0.0001;0.25555;0.2704;0 --0.0018;0.25555;0.2898;0 --0.0167;0.25555;0.2928;0 --0.0351;0.25555;0.2975;0 --0.0366;0.25555;0.3162;0 --0.0376;0.25555;0.332;0 --0.038;0.25555;0.3512;0 --0.0365;0.25555;0.3722;0 --0.0352;0.25555;0.3918;0 --0.0335;0.25555;0.41113;0 --0.0149;0.25555;0.41307;0 -0.0026;0.25555;0.41525;0 -0.0026;0.23635;0.41533;0 --0.0011;0.21805;0.43413;0 --0.0011;0.19925;0.43446;0 --0.0011;0.18055;0.43497;0 --0.0115;0.16245;0.4509;0 --0.0115;0.14375;0.45169;0 --0.0269;0.12575;0.46278;0 --0.0269;0.10725;0.46384;0 --0.045;0.08895;0.4686;0 --0.045;0.07045;0.46992;0 --0.0641;0.05205;0.47142;0 --0.08309999999999999;0.03355;0.47302;0 --0.08309999999999999;0.01515;0.47478;0 --0.08309999999999999;-0.00325;0.47668;0 --0.08309999999999999;-0.02175;0.4787;0 --0.08309999999999999;-0.04005;0.48088;0 --0.08309999999999999;-0.05845;0.4832;0 --0.08309999999999999;-0.07685;0.48564;0 --0.08309999999999999;-0.09515;0.48824;0 --0.1022;-0.09515;0.48824;0 --0.1212;-0.09515;0.48824;0 --0.1212;-0.07685;0.48564;0 --0.1212;-0.05845;0.4832;0 --0.1212;-0.04005;0.48088;0 --0.1403;-0.04005;0.48088;0 --0.1403;-0.02175;0.4787;0 --0.1403;-0.00325;0.47668;0 --0.1593;-0.00325;0.47668;0 --0.1777;-0.00365;0.47298;0 --0.1931;-0.00475;0.46272;0 --0.2034;-0.00645;0.44739;0 --0.207;-0.00835;0.42927;0 --0.207;0.00825;0.40727;0 --0.207;0.00635;0.3872;0 --0.207;0.00435;0.3671;0 --0.207;0.00245;0.347;0 --0.207;0.00045;0.3269;0 --0.207;-0.00145;0.3069;0 --0.2079;0.01655;0.2864;0 --0.2106;0.01485;0.2679;0 --0.2152;0.01315;0.2499;0 --0.2215;0.01155;0.2323;0 --0.2295;0.01005;0.2155;0 --0.2391;0.00855;0.1995;0 --0.2503;0.00725;0.1845;0 --0.2628;0.00595;0.1707;0 --0.2767;0.00485;0.1582;0 --0.2917;0.00385;0.1471;0 --0.3078;0.00295;0.1375;0 --0.3247;0.00225;0.1295;0 --0.3423;0.00165;0.1233;0 --0.36046;0.00125;0.1187;0 --0.37897;0.00095;0.116;0 --0.39766;0.00085;0.1151;0 --0.41019;-0.01905;0.117;0 --0.42272;-0.03735;0.1188;0 --0.43524;-0.05445;0.1207;0 --0.43524;-0.07315000000000001;0.1228;0 --0.43524;-0.09175;0.1251;0 --0.44776;-0.10735;0.1271;0 --0.44774;-0.12545;0.1295;0 --0.44768;-0.14335;0.1321;0 --0.4603;-0.15931;0.1344;0 --0.4603;-0.16204;0.1162;0 --0.4603;-0.16456;0.09760000000000001;0 --0.4603;-0.16584;0.07580000000000001;0 --0.4603;-0.16944;0.0513;0 --0.4603;-0.17352;0.0308;0 --0.4603;-0.19534;0.0147;0 --0.4603;-0.14805;0.07290000000000001;0 --0.4603;-0.12835;0.093;0 --0.4603;-0.11025;0.0907;0 --0.4603;-0.10785;0.1088;0 --0.4603;-0.10555;0.1269;0 --0.4603;-0.08755;0.1246;0 --0.44777;-0.07095;0.1226;0 --0.44777;-0.05275;0.1205;0 --0.43524;-0.03565;0.1187;0 --0.42272;-0.01795;0.1169;0 --0.42272;0.00145;0.115;0 --0.41019;0.00115;0.1151;0 --0.41019;0.02145;0.1133;0 --0.41019;0.04175;0.1117;0 --0.41019;0.06205;0.1102;0 --0.41019;0.08235000000000001;0.1089;0 --0.41019;0.10265;0.1077;0 --0.41019;0.12295;0.1066;0 --0.41019;0.14325;0.1057;0 --0.39766;0.12805;0.1064;0 --0.37897;0.12815;0.1073;0 --0.36046;0.12825;0.1101;0 --0.3423;0.12845;0.1146;0 --0.3247;0.12875;0.1209;0 --0.3078;0.12905;0.1289;0 --0.2917;0.12955;0.1385;0 --0.2767;0.13005;0.1496;0 --0.2628;0.13065;0.1622;0 --0.2503;0.13125;0.176;0 --0.2503;0.15195;0.1752;0 --0.2391;0.15255;0.1902;0 --0.2295;0.15315;0.2062;0 --0.2295;0.17355;0.2055;0 --0.2295;0.19405;0.205;0 --0.2295;0.21455;0.2046;0 --0.2215;0.21485;0.2215;0 --0.2215;0.23515;0.2213;0 --0.2215;0.25555;0.2213;0 --0.1982;0.25555;0.2322;0 --0.1742;0.25555;0.2459;0 --0.145;0.25555;0.263;0 --0.1174;0.25555;0.2819;0 --0.1167;0.25555;0.309;0 --0.0806;0.25555;0.312;0 --0.057;0.25555;0.3035;0 --0.0558;0.25555;0.3202;0 --0.056;0.25555;0.3337;0 --0.055;0.25555;0.354;0 --0.0519;0.25555;0.3743;0 --0.0501;0.25555;0.3916;0 --0.0487;0.25555;0.40956;0 --0.0472;0.25555;0.4261;0 --0.0327;0.25555;0.42612;0 --0.0183;0.25555;0.42735;0 --0.0011;0.25555;0.43384;0 --0.0011;0.23675;0.4339;0 --0.0115;0.21825;0.44943;0 --0.0115;0.19965;0.44978;0 --0.0115;0.18105;0.45027;0 --0.0269;0.16275;0.46109;0 --0.0269;0.14425;0.46187;0 --0.045;0.12595;0.46637;0 --0.045;0.10745;0.46741;0 --0.0641;0.08895;0.4686;0 --0.0641;0.07045;0.46992;0 --0.08309999999999999;0.05205;0.47142;0 --0.1022;0.03355;0.47302;0 --0.1022;0.01515;0.47478;0 --0.1022;-0.00325;0.47668;0 --0.1022;-0.02175;0.4787;0 --0.1022;-0.04005;0.48088;0 --0.1022;-0.05845;0.4832;0 --0.1022;-0.07685;0.48564;0 --0.1212;-0.02175;0.4787;0 --0.1212;-0.00325;0.47668;0 --0.1212;0.01515;0.47478;0 --0.1403;0.01515;0.47478;0 --0.1593;0.01515;0.47478;0 --0.1777;0.01475;0.4711;0 --0.1931;0.01375;0.46081;0 --0.2034;0.01225;0.44546;0 --0.207;0.01045;0.42734;0 --0.207;0.02725;0.40549;0 --0.207;0.02545;0.3854;0 --0.207;0.02365;0.3653;0 --0.207;0.02185;0.3452;0 --0.207;0.02005;0.3251;0 --0.207;0.01825;0.305;0 --0.2079;0.03645;0.2846;0 --0.2106;0.03485;0.2662;0 --0.2152;0.03335;0.2481;0 --0.2215;0.03185;0.2305;0 --0.2295;0.03045;0.2137;0 --0.2391;0.02915;0.1977;0 --0.2503;0.02785;0.1827;0 --0.2628;0.02675;0.1689;0 --0.2767;0.02565;0.1564;0 --0.2917;0.02475;0.1453;0 --0.3078;0.02395;0.1357;0 --0.3247;0.02325;0.1277;0 --0.3423;0.02275;0.1214;0 --0.36046;0.02235;0.1169;0 --0.37897;0.02215;0.1141;0 --0.39766;0.02205;0.1132;0 --0.39766;0.04325;0.1116;0 --0.39766;0.06444999999999999;0.11;0 --0.39766;0.08565;0.1086;0 --0.39766;0.10685;0.1074;0 --0.37897;0.10685;0.1083;0 --0.36046;0.10705;0.1111;0 --0.3423;0.10725;0.1156;0 --0.3247;0.10765;0.1219;0 --0.3078;0.10805;0.1299;0 --0.2917;0.10855;0.1395;0 --0.2767;0.10915;0.1507;0 --0.2628;0.10985;0.1632;0 --0.2503;0.11055;0.1771;0 --0.2391;0.11135;0.1921;0 --0.2391;0.13195;0.1911;0 --0.2295;0.13265;0.2071;0 --0.2215;0.13345;0.224;0 --0.2215;0.15375;0.2231;0 --0.2215;0.17405;0.2224;0 --0.2215;0.19445;0.2219;0 --0.2152;0.19485;0.2395;0 --0.2152;0.21505;0.2391;0 --0.2152;0.23525;0.2389;0 --0.2151;0.25555;0.239;0 --0.1929;0.25555;0.2519;0 --0.1684;0.25555;0.2689;0 --0.1412;0.25555;0.2865;0 --0.1413;0.25555;0.3106;0 --0.1201;0.25555;0.3336;0 --0.0895;0.25555;0.335;0 --0.06759999999999999;0.25555;0.3232;0 --0.07000000000000001;0.25555;0.3355;0 --0.07049999999999999;0.25555;0.357;0 --0.0683;0.25555;0.3759;0 --0.0663;0.25555;0.3924;0 --0.0649;0.25555;0.40825;0 --0.0645;0.25555;0.42612;0 --0.0641;0.25555;0.44463;0 --0.0465;0.25555;0.4443;0 --0.0327;0.25555;0.44203;0 --0.0215;0.25555;0.43901;0 --0.0115;0.25555;0.44917;0 --0.0115;0.23685;0.44922;0 --0.0269;0.21845;0.45961;0 --0.0269;0.19985;0.45996;0 --0.0269;0.18135;0.46045;0 --0.045;0.16295;0.46468;0 --0.045;0.14445;0.46545;0 --0.0641;0.12595;0.46637;0 --0.0641;0.10745;0.46741;0 --0.08309999999999999;0.08895;0.4686;0 --0.08309999999999999;0.07045;0.46992;0 --0.1022;0.05205;0.47142;0 --0.1212;0.03355;0.47302;0 --0.1403;0.03355;0.47302;0 --0.1593;0.03355;0.47302;0 --0.1777;0.03325;0.46934;0 --0.1931;0.03225;0.45906;0 --0.2034;0.03085;0.44369;0 --0.207;0.02925;0.42557;0 --0.207;0.04625;0.40381;0 --0.207;0.04455;0.3837;0 --0.207;0.04295;0.3636;0 --0.207;0.04125;0.3435;0 --0.207;0.03965;0.3234;0 --0.207;0.03795;0.3032;0 --0.2079;0.05625;0.283;0 --0.2106;0.05485;0.2646;0 --0.2152;0.05345;0.2465;0 --0.2215;0.05215;0.2289;0 --0.2295;0.05085;0.212;0 --0.2391;0.04965;0.196;0 --0.2503;0.04855;0.1811;0 --0.2628;0.04745;0.1672;0 --0.2767;0.04655;0.1547;0 --0.2917;0.04565;0.1436;0 --0.3078;0.04495;0.134;0 --0.3247;0.04435;0.126;0 --0.3423;0.04385;0.1197;0 --0.36046;0.04355;0.1152;0 --0.37897;0.04325;0.1125;0 --0.37897;0.06444999999999999;0.1109;0 --0.37897;0.08565;0.1096;0 --0.36046;0.08585;0.1123;0 --0.3423;0.08615;0.1168;0 --0.3247;0.08655;0.1231;0 --0.3078;0.08705;0.1311;0 --0.2917;0.08755;0.1407;0 --0.2767;0.08825;0.1518;0 --0.2628;0.08905;0.1644;0 --0.2503;0.08985;0.1782;0 --0.2391;0.09075;0.1932;0 --0.2295;0.09175;0.2093;0 --0.2295;0.11215;0.2081;0 --0.2215;0.11305;0.225;0 --0.2152;0.11405;0.2426;0 --0.2152;0.13425;0.2416;0 --0.2152;0.15445;0.2407;0 --0.2152;0.17465;0.24;0 --0.2106;0.17515;0.2582;0 --0.2106;0.19525;0.2577;0 --0.2106;0.21535;0.2573;0 --0.2106;0.23545;0.257;0 --0.2106;0.25555;0.2571;0 --0.1883;0.25555;0.2737;0 --0.1666;0.25555;0.2906;0 --0.1655;0.25555;0.3141;0 --0.1424;0.25555;0.3334;0 --0.1234;0.25555;0.3583;0 --0.0987;0.25555;0.365;0 --0.0898;0.25555;0.3823;0 --0.0852;0.25555;0.3959;0 --0.0834;0.25555;0.40962;0 --0.0837;0.25555;0.42702;0 --0.08309999999999999;0.25555;0.44517;0 --0.0641;0.25555;0.46292;0 --0.045;0.25555;0.46292;0 --0.0269;0.25555;0.45933;0 --0.0269;0.23695;0.45941;0 --0.045;0.21845;0.4632;0 --0.045;0.19995;0.46355;0 --0.045;0.18145;0.46403;0 --0.0641;0.16295;0.46468;0 --0.0641;0.14445;0.46545;0 --0.08309999999999999;0.12595;0.46637;0 --0.08309999999999999;0.10745;0.46741;0 --0.1022;0.08895;0.4686;0 --0.1022;0.07045;0.46992;0 --0.1212;0.05205;0.47142;0 --0.1403;0.05205;0.47142;0 --0.1593;0.05205;0.47142;0 --0.1777;0.05175;0.46771;0 --0.1931;0.05085;0.45743;0 --0.2034;0.04955;0.44205;0 --0.207;0.04805;0.4239;0 --0.207;0.06525;0.4023;0 --0.207;0.06375;0.3822;0 --0.207;0.06225;0.362;0 --0.207;0.06075;0.3419;0 --0.207;0.05925;0.3218;0 --0.207;0.05775;0.3017;0 --0.2079;0.07615;0.2816;0 --0.2106;0.07485;0.2631;0 --0.2152;0.07364999999999999;0.245;0 --0.2215;0.07245;0.2274;0 --0.2295;0.07124999999999999;0.2106;0 --0.2391;0.07025000000000001;0.1946;0 --0.2503;0.06915;0.1796;0 --0.2628;0.06825000000000001;0.1657;0 --0.2767;0.06734999999999999;0.1532;0 --0.2917;0.06665;0.1421;0 --0.3078;0.06594999999999999;0.1325;0 --0.3247;0.06544999999999999;0.1245;0 --0.3423;0.06494999999999999;0.1182;0 --0.36046;0.06465;0.1137;0 --0.2215;0.09275;0.2261;0 --0.2152;0.09385;0.2437;0 --0.2106;0.09495000000000001;0.2619;0 --0.2106;0.11505;0.2607;0 --0.2106;0.13505;0.2597;0 --0.2106;0.15515;0.2589;0 --0.2079;0.15585;0.2774;0 --0.2079;0.17575;0.2767;0 --0.2079;0.19565;0.2762;0 --0.2079;0.21565;0.2758;0 --0.2079;0.23555;0.2756;0 --0.2079;0.25555;0.2756;0 --0.1874;0.25555;0.2937;0 --0.187;0.25555;0.3143;0 --0.1658;0.25555;0.3344;0 --0.1438;0.25555;0.355;0 --0.1449;0.25555;0.375;0 --0.1289;0.25555;0.3784;0 --0.1137;0.25555;0.384;0 --0.1018;0.25555;0.39;0 --0.1013;0.25555;0.40031;0 --0.1014;0.25555;0.41275;0 --0.1019;0.25555;0.42763;0 --0.1012;0.25555;0.44583;0 --0.08309999999999999;0.25555;0.46292;0 --0.08309999999999999;0.23695;0.463;0 --0.0641;0.23695;0.463;0 --0.045;0.23695;0.463;0 --0.0641;0.21845;0.4632;0 --0.0641;0.19995;0.46355;0 --0.0641;0.18145;0.46403;0 --0.08309999999999999;0.16295;0.46468;0 --0.08309999999999999;0.14445;0.46545;0 --0.1022;0.12595;0.46637;0 --0.1022;0.10745;0.46741;0 --0.1212;0.08895;0.4686;0 --0.1212;0.07045;0.46992;0 --0.1403;0.07045;0.46992;0 --0.1593;0.07045;0.46992;0 --0.1777;0.07015;0.46625;0 --0.1931;0.06945;0.45595;0 --0.2034;0.06825000000000001;0.44057;0 --0.207;0.06685000000000001;0.42241;0 --0.207;0.08425000000000001;0.40092;0 --0.207;0.08284999999999999;0.3808;0 --0.207;0.08155;0.3607;0 --0.207;0.08015;0.3405;0 --0.207;0.07885;0.3204;0 --0.207;0.07745;0.3002;0 --0.2079;0.09605;0.2803;0 --0.2079;0.11595;0.2792;0 --0.2079;0.13585;0.2782;0 --0.207;0.13675;0.2969;0 --0.207;0.15655;0.296;0 --0.207;0.17635;0.2954;0 --0.207;0.19615;0.2948;0 --0.207;0.21595;0.2945;0 --0.207;0.23575;0.2942;0 --0.207;0.25555;0.2942;0 --0.207;0.25555;0.3143;0 --0.207;0.25555;0.3345;0 --0.1869;0.25555;0.3345;0 --0.1662;0.25555;0.3547;0 --0.1664;0.25555;0.3749;0 --0.148;0.25555;0.3958;0 --0.1328;0.25555;0.3975;0 --0.1164;0.25555;0.3987;0 --0.1179;0.25555;0.4137;0 --0.119;0.25555;0.42927;0 --0.1204;0.25555;0.44653;0 --0.1022;0.25555;0.46292;0 --0.1022;0.23695;0.463;0 --0.1022;0.21845;0.4632;0 --0.08309999999999999;0.21845;0.4632;0 --0.08309999999999999;0.19995;0.46355;0 --0.08309999999999999;0.18145;0.46403;0 --0.1022;0.16295;0.46468;0 --0.1022;0.14445;0.46545;0 --0.1212;0.12595;0.46637;0 --0.1212;0.10745;0.46741;0 --0.1403;0.08895;0.4686;0 --0.1593;0.08895;0.4686;0 --0.1777;0.08875;0.46489;0 --0.1931;0.08795;0.4546;0 --0.2034;0.08695;0.43921;0 --0.207;0.08575000000000001;0.42103;0 --0.207;0.10325;0.3997;0 --0.207;0.10205;0.3795;0 --0.207;0.10085;0.3594;0 --0.207;0.09965;0.3393;0 --0.207;0.09845;0.3191;0 --0.207;0.09725;0.299;0 --0.207;0.11695;0.2978;0 --0.207;0.13765;0.317;0 --0.207;0.15725;0.3162;0 --0.207;0.17695;0.3155;0 --0.207;0.19655;0.315;0 --0.207;0.21625;0.3146;0 --0.207;0.23585;0.3144;0 --0.207;0.23605;0.3346;0 --0.207;0.23615;0.3548;0 --0.207;0.25555;0.3547;0 --0.1869;0.25555;0.3547;0 --0.1868;0.25555;0.3749;0 --0.1665;0.25555;0.395;0 --0.1502;0.25555;0.41331;0 --0.1348;0.25555;0.41456;0 --0.1372;0.25555;0.42998;0 --0.139;0.25555;0.44658;0 --0.1212;0.25555;0.46292;0 --0.1212;0.23695;0.463;0 --0.1212;0.21845;0.4632;0 --0.1212;0.19995;0.46355;0 --0.1022;0.19995;0.46355;0 --0.1022;0.18145;0.46403;0 --0.1212;0.16295;0.46468;0 --0.1212;0.14445;0.46545;0 --0.1403;0.12595;0.46637;0 --0.1403;0.10745;0.46741;0 --0.1593;0.10745;0.46741;0 --0.1777;0.10725;0.46371;0 --0.1931;0.10655;0.4534;0 --0.2034;0.10565;0.43802;0 --0.207;0.10455;0.41981;0 --0.207;0.12225;0.3986;0 --0.207;0.12115;0.3784;0 --0.207;0.12015;0.3583;0 --0.207;0.11915;0.3381;0 --0.207;0.11805;0.318;0 --0.207;0.13855;0.3372;0 --0.207;0.15805;0.3364;0 --0.207;0.17755;0.3357;0 --0.207;0.19705;0.3352;0 --0.207;0.21655;0.3348;0 --0.207;0.21685;0.355;0 --0.207;0.23635;0.375;0 --0.207;0.25555;0.3749;0 --0.207;0.25555;0.3951;0 --0.1868;0.25555;0.3951;0 --0.1673;0.25555;0.41261;0 --0.1516;0.25555;0.42927;0 --0.1557;0.25555;0.44553;0 --0.1403;0.25555;0.46292;0 --0.1403;0.23695;0.463;0 --0.1403;0.21845;0.4632;0 --0.1403;0.19995;0.46355;0 --0.1403;0.18145;0.46403;0 --0.1212;0.18145;0.46403;0 --0.1403;0.16295;0.46468;0 --0.1403;0.14445;0.46545;0 --0.1593;0.12595;0.46637;0 --0.1777;0.12575;0.46265;0 --0.1931;0.12515;0.45235;0 --0.2034;0.12435;0.43695;0 --0.207;0.12335;0.41875;0 --0.207;0.14125;0.3977;0 --0.207;0.14035;0.3775;0 --0.207;0.13945;0.3573;0 --0.207;0.15885;0.3565;0 --0.207;0.17815;0.3559;0 --0.207;0.19745;0.3554;0 --0.207;0.21715;0.3752;0 --0.207;0.23645;0.3951;0 --0.207;0.23665;0.41533;0 --0.207;0.25555;0.41525;0 --0.1868;0.25555;0.41327;0 --0.1847;0.25555;0.4272;0 --0.1675;0.25555;0.42856;0 --0.1699;0.25555;0.44197;0 --0.1593;0.25555;0.46292;0 --0.1593;0.23695;0.463;0 --0.1593;0.21845;0.4632;0 --0.1593;0.19995;0.46355;0 --0.1593;0.18145;0.46403;0 --0.1593;0.16295;0.46468;0 --0.1593;0.14445;0.46545;0 --0.1777;0.14425;0.46173;0 --0.1931;0.14375;0.45142;0 --0.2034;0.14305;0.43603;0 --0.207;0.14225;0.41781;0 --0.207;0.16035;0.3969;0 --0.207;0.15955;0.3767;0 --0.207;0.17875;0.376;0 --0.207;0.19795;0.3755;0 --0.207;0.21745;0.3954;0 --0.207;0.21775;0.41553;0 --0.2034;0.23675;0.43355;0 --0.2034;0.25555;0.43346;0 --0.1818;0.25555;0.43826;0 --0.1777;0.25555;0.45921;0 --0.1778;0.23695;0.45927;0 --0.1778;0.21845;0.45949;0 --0.1778;0.19985;0.45984;0 --0.1777;0.18135;0.46034;0 --0.1777;0.16275;0.46097;0 --0.1931;0.16235;0.45065;0 --0.2034;0.16185;0.43524;0 --0.207;0.16115;0.41704;0 --0.207;0.17935;0.3962;0 --0.207;0.19835;0.3957;0 --0.207;0.19885;0.41589;0 --0.2034;0.21805;0.43376;0 --0.1931;0.23685;0.44896;0 --0.1931;0.25555;0.4489;0 --0.1931;0.21825;0.44917;0 --0.1931;0.19965;0.44951;0 --0.1931;0.18105;0.45001;0 --0.2034;0.18055;0.4346;0 --0.207;0.17995;0.4164;0 --0.2034;0.19925;0.4341;0 --0.44777;-0.08914999999999999;0.1248;0 --0.4603;-0.12345;0.1293;0 --0.4603;-0.14145;0.1318;0 --0.4603;-0.14405;0.1137;0 --0.4603;-0.14655;0.0953;0 --0.4603;-0.12595;0.1112;0 --0.0327;0.25555;0.2716;0 --0.015;0.25555;0.271;0 --0.0115;0.25555;0.2503;0 --0.0046;0.25555;0.2376;0 -0.0061;0.25555;0.2295;0 -0.002;0.25555;0.2437;0 -0.0806;0.25555;-0.0512;0 -0.0882;0.25555;-0.0649;0 -0.0946;0.25555;-0.0743;0 -0.102;0.25555;-0.08160000000000001;0 -0.0997;0.25555;-0.0689;0 -0.322;0.25555;-0.376;0 -0.3222;0.25555;-0.394;0 -0.3378;0.25555;-0.3977;0 -0.3384;0.25555;-0.4173;0 -0.3382;0.25555;-0.4344;0 -0.3365;0.25555;-0.4515;0 -0.3333;0.25555;-0.4689;0 -0.3297;0.25555;-0.4871;0 -0.3482;0.25555;-0.4905;0 -0.3633;0.24385;-0.4929;0 -0.3813;0.24405;-0.4953;0 -0.3988;0.24425;-0.4972;0 -0.4099;0.23445;-0.498;0 -0.4207;0.23565;-0.4988;0 -0.4289;0.24355;-0.4992;0 -0.4227;0.25555;-0.4989;0 -0.404;0.25555;-0.4976;0 -0.4055;0.25555;-0.4792;0 -0.4058;0.25555;-0.4615;0 -0.3868;0.25555;-0.4597;0 -0.3866;0.25555;-0.4415;0 -0.3697;0.25555;-0.44;0 -0.3699;0.25555;-0.4235;0 -0.3542;0.25555;-0.4207;0 -0.3539;0.25555;-0.437;0 -0.3538;0.25555;-0.4548;0 -0.3513;0.25555;-0.4722;0 -0.3693;0.25555;-0.4751;0 -0.3667;0.25555;-0.4934;0 -0.3854;0.25555;-0.4958;0 -0.3874;0.25555;-0.4774;0 -0.3694;0.25555;-0.4574;0 -0.4151;0.24435;-0.4985;0 -0.4603;0.12335;0.1394;0 -tria3=12946 -0;1;2;1 -0;2;3;1 -0;3;4;1 -0;4;5;1 -0;5;1;1 -1;5;6;1 -1;6;7;1 -1;7;8;1 -1;8;9;1 -1;9;2;1 -2;9;10;1 -2;10;11;1 -2;11;3;1 -3;11;12;1 -3;12;13;1 -3;13;4;1 -4;13;14;1 -4;14;15;1 -4;15;5;1 -5;15;16;1 -5;16;6;1 -6;16;17;1 -6;17;18;1 -6;18;7;1 -7;18;19;1 -7;19;20;1 -7;20;8;1 -8;20;21;1 -8;21;22;1 -8;22;9;1 -9;22;23;1 -9;23;10;1 -10;23;24;1 -10;24;11;1 -11;24;25;1 -11;25;12;1 -12;25;26;1 -12;26;27;1 -12;27;13;1 -13;27;28;1 -13;28;14;1 -14;28;29;1 -14;29;30;1 -14;30;15;1 -15;30;31;1 -15;31;16;1 -16;31;32;1 -16;32;17;1 -17;32;33;1 -17;33;18;1 -18;33;34;1 -18;34;35;1 -18;35;19;1 -19;35;36;1 -19;36;37;1 -19;37;20;1 -20;37;38;1 -20;38;21;1 -21;38;39;1 -21;39;40;1 -21;40;22;1 -22;40;41;1 -22;41;23;1 -23;41;42;1 -23;42;24;1 -24;42;43;1 -24;43;44;1 -24;44;25;1 -25;44;45;1 -25;45;26;1 -26;45;46;1 -26;46;47;1 -26;47;27;1 -27;47;48;1 -27;48;28;1 -28;48;49;1 -28;49;29;1 -29;49;50;1 -29;50;51;1 -29;51;30;1 -30;51;52;1 -30;52;31;1 -31;52;53;1 -31;53;32;1 -32;53;54;1 -32;54;33;1 -33;54;55;1 -33;55;34;1 -34;55;56;1 -34;56;57;1 -34;57;35;1 -35;57;58;1 -35;58;36;1 -36;58;59;1 -36;59;60;1 -36;60;37;1 -37;60;61;1 -37;61;38;1 -38;61;62;1 -38;62;39;1 -39;62;63;1 -39;63;64;1 -39;64;40;1 -40;64;65;1 -40;65;41;1 -41;65;66;1 -41;66;67;1 -41;67;42;1 -42;67;68;1 -42;68;69;1 -42;69;43;1 -43;69;70;1 -43;70;71;1 -43;71;72;1 -43;72;44;1 -44;72;73;1 -44;73;45;1 -45;73;74;1 -45;74;75;1 -45;75;46;1 -46;75;76;1 -46;76;77;1 -46;77;47;1 -47;77;78;1 -47;78;48;1 -48;78;79;1 -48;79;49;1 -49;79;80;1 -49;80;50;1 -50;80;81;1 -50;81;82;1 -50;82;51;1 -51;82;83;1 -51;83;52;1 -52;83;84;1 -52;84;53;1 -53;84;85;1 -53;85;54;1 -54;85;86;1 -54;86;55;1 -55;86;87;1 -55;87;56;1 -56;87;88;1 -56;88;89;1 -56;89;57;1 -57;89;90;1 -57;90;58;1 -58;90;91;1 -58;91;59;1 -59;91;92;1 -59;92;93;1 -59;93;60;1 -60;93;94;1 -60;94;61;1 -61;94;95;1 -61;95;62;1 -62;95;96;1 -62;96;63;1 -63;96;97;1 -63;97;98;1 -63;98;64;1 -64;98;99;1 -64;99;65;1 -65;99;100;1 -65;100;66;1 -66;100;101;1 -66;101;102;1 -66;102;67;1 -67;102;68;1 -68;102;103;1 -68;103;104;1 -68;104;69;1 -69;104;105;1 -69;105;70;1 -70;105;106;1 -70;106;107;1 -70;107;71;1 -71;107;108;1 -71;108;109;1 -71;109;110;1 -71;110;72;1 -72;110;74;1 -74;110;111;1 -74;111;75;1 -75;111;112;1 -75;112;76;1 -76;112;113;1 -76;113;114;1 -76;114;77;1 -77;114;115;1 -77;115;78;1 -78;115;116;1 -78;116;79;1 -79;116;117;1 -79;117;80;1 -80;117;118;1 -80;118;119;1 -80;119;81;1 -81;119;120;1 -81;120;82;1 -82;120;121;1 -82;121;83;1 -83;121;122;1 -83;122;84;1 -84;122;123;1 -84;123;85;1 -85;123;124;1 -85;124;86;1 -86;124;125;1 -86;125;87;1 -87;125;126;1 -87;126;127;1 -87;127;88;1 -88;127;128;1 -88;128;89;1 -89;128;129;1 -89;129;90;1 -90;129;130;1 -90;130;91;1 -91;130;131;1 -91;131;92;1 -92;131;132;1 -92;132;133;1 -92;133;93;1 -93;133;134;1 -93;134;94;1 -94;134;135;1 -94;135;95;1 -95;135;136;1 -95;136;96;1 -96;136;137;1 -96;137;97;1 -97;137;138;1 -97;138;139;1 -97;139;98;1 -98;139;140;1 -98;140;99;1 -99;140;100;1 -100;140;141;1 -100;141;101;1 -101;141;142;1 -101;142;143;1 -101;143;102;1 -102;143;103;1 -103;143;144;1 -103;144;145;1 -103;145;104;1 -104;145;146;1 -104;146;105;1 -105;146;147;1 -105;147;106;1 -106;147;148;1 -106;148;149;1 -106;149;107;1 -107;149;108;1 -108;149;150;1 -108;150;151;1 -108;151;109;1 -109;151;152;1 -109;152;153;1 -109;153;110;1 -110;153;154;1 -110;154;111;1 -111;154;155;1 -111;155;112;1 -112;155;156;1 -112;156;113;1 -113;156;157;1 -113;157;158;1 -113;158;159;1 -113;159;114;1 -114;159;115;1 -115;159;116;1 -116;159;160;1 -116;160;117;1 -117;160;161;1 -117;161;118;1 -118;161;162;1 -118;162;163;1 -118;163;164;1 -118;164;119;1 -119;164;165;1 -119;165;120;1 -120;165;166;1 -120;166;121;1 -121;166;167;1 -121;167;122;1 -122;167;168;1 -122;168;123;1 -123;168;169;1 -123;169;124;1 -124;169;170;1 -124;170;125;1 -125;170;171;1 -125;171;126;1 -126;171;172;1 -126;172;173;1 -126;173;127;1 -127;173;174;1 -127;174;128;1 -128;174;175;1 -128;175;129;1 -129;175;176;1 -129;176;130;1 -130;176;177;1 -130;177;131;1 -131;177;178;1 -131;178;132;1 -132;178;179;1 -132;179;180;1 -132;180;133;1 -133;180;181;1 -133;181;134;1 -134;181;182;1 -134;182;135;1 -135;182;183;1 -135;183;136;1 -136;183;184;1 -136;184;137;1 -137;184;185;1 -137;185;138;1 -138;185;186;1 -138;186;187;1 -138;187;139;1 -139;187;188;1 -139;188;140;1 -140;188;141;1 -141;188;189;1 -141;189;142;1 -142;189;190;1 -142;190;191;1 -142;191;143;1 -143;191;144;1 -144;191;192;1 -144;192;193;1 -144;193;145;1 -145;193;194;1 -145;194;146;1 -146;194;195;1 -146;195;147;1 -147;195;196;1 -147;196;148;1 -148;196;197;1 -148;197;198;1 -148;198;149;1 -149;198;150;1 -150;198;199;1 -150;199;200;1 -150;200;151;1 -151;200;201;1 -151;201;152;1 -152;201;202;1 -152;202;203;1 -152;203;204;1 -152;204;153;1 -153;204;154;1 -154;204;155;1 -155;204;205;1 -155;205;156;1 -156;205;206;1 -156;206;207;1 -156;207;157;1 -157;207;208;1 -157;208;158;1 -158;208;209;1 -158;209;210;1 -158;210;159;1 -159;210;160;1 -160;210;211;1 -160;211;161;1 -161;211;212;1 -161;212;162;1 -162;212;213;1 -162;213;214;1 -162;214;163;1 -163;214;215;1 -163;215;164;1 -164;215;216;1 -164;216;165;1 -165;216;217;1 -165;217;218;1 -165;218;166;1 -166;218;219;1 -166;219;167;1 -167;219;220;1 -167;220;168;1 -168;220;221;1 -168;221;169;1 -169;221;222;1 -169;222;170;1 -170;222;223;1 -170;223;171;1 -171;223;224;1 -171;224;172;1 -172;224;225;1 -172;225;173;1 -173;225;226;1 -173;226;227;1 -173;227;174;1 -174;227;228;1 -174;228;175;1 -175;228;229;1 -175;229;176;1 -176;229;230;1 -176;230;177;1 -177;230;231;1 -177;231;178;1 -178;231;232;1 -178;232;179;1 -179;232;233;1 -179;233;234;1 -179;234;180;1 -180;234;235;1 -180;235;181;1 -181;235;236;1 -181;236;182;1 -182;236;237;1 -182;237;183;1 -183;237;238;1 -183;238;184;1 -184;238;239;1 -184;239;185;1 -185;239;240;1 -185;240;186;1 -186;240;241;1 -186;241;242;1 -186;242;187;1 -187;242;243;1 -187;243;188;1 -188;243;189;1 -189;243;244;1 -189;244;190;1 -190;244;245;1 -190;245;246;1 -190;246;191;1 -191;246;192;1 -192;246;247;1 -192;247;248;1 -192;248;193;1 -193;248;249;1 -193;249;194;1 -194;249;250;1 -194;250;195;1 -195;250;251;1 -195;251;252;1 -195;252;196;1 -196;252;197;1 -197;252;253;1 -197;253;254;1 -197;254;198;1 -198;254;199;1 -199;254;255;1 -199;255;256;1 -199;256;200;1 -200;256;257;1 -200;257;201;1 -201;257;258;1 -201;258;259;1 -201;259;202;1 -202;259;260;1 -202;260;203;1 -203;260;261;1 -203;261;262;1 -203;262;205;1 -205;262;206;1 -206;262;263;1 -206;263;264;1 -206;264;207;1 -207;264;265;1 -207;265;208;1 -208;265;266;1 -208;266;209;1 -209;266;267;1 -209;267;210;1 -210;267;211;1 -211;267;268;1 -211;268;212;1 -212;268;269;1 -212;269;213;1 -213;269;270;1 -213;270;271;1 -213;271;214;1 -214;271;272;1 -214;272;215;1 -215;272;273;1 -215;273;274;1 -215;274;216;1 -216;274;217;1 -217;274;275;1 -217;275;276;1 -217;276;277;1 -217;277;218;1 -218;277;219;1 -219;277;278;1 -219;278;220;1 -220;278;279;1 -220;279;221;1 -221;279;280;1 -221;280;222;1 -222;280;281;1 -222;281;223;1 -223;281;282;1 -223;282;224;1 -224;282;283;1 -224;283;225;1 -225;283;284;1 -225;284;226;1 -226;284;285;1 -226;285;286;1 -226;286;227;1 -227;286;287;1 -227;287;228;1 -228;287;288;1 -228;288;229;1 -229;288;289;1 -229;289;230;1 -230;289;290;1 -230;290;231;1 -231;290;291;1 -231;291;232;1 -232;291;292;1 -232;292;233;1 -233;292;293;1 -233;293;294;1 -233;294;234;1 -234;294;295;1 -234;295;235;1 -235;295;296;1 -235;296;236;1 -236;296;297;1 -236;297;237;1 -237;297;298;1 -237;298;238;1 -238;298;299;1 -238;299;239;1 -239;299;300;1 -239;300;240;1 -240;300;301;1 -240;301;241;1 -241;301;302;1 -241;302;303;1 -241;303;242;1 -242;303;304;1 -242;304;243;1 -243;304;244;1 -244;304;305;1 -244;305;245;1 -245;305;306;1 -245;306;307;1 -245;307;246;1 -246;307;247;1 -247;307;308;1 -247;308;309;1 -247;309;248;1 -248;309;310;1 -248;310;249;1 -249;310;311;1 -249;311;250;1 -250;311;312;1 -250;312;251;1 -251;312;313;1 -251;313;252;1 -252;313;314;1 -252;314;253;1 -253;314;315;1 -253;315;316;1 -253;316;254;1 -254;316;255;1 -255;316;317;1 -255;317;318;1 -255;318;256;1 -256;318;319;1 -256;319;257;1 -257;319;320;1 -257;320;258;1 -258;320;321;1 -258;321;259;1 -259;321;322;1 -259;322;323;1 -259;323;260;1 -260;323;324;1 -260;324;325;1 -260;325;261;1 -261;325;326;1 -261;326;262;1 -262;326;263;1 -263;326;327;1 -263;327;328;1 -263;328;264;1 -264;328;329;1 -264;329;265;1 -265;329;330;1 -265;330;266;1 -266;330;331;1 -266;331;267;1 -267;331;332;1 -267;332;268;1 -268;332;333;1 -268;333;269;1 -269;333;334;1 -269;334;335;1 -269;335;270;1 -270;335;336;1 -270;336;337;1 -270;337;338;1 -270;338;271;1 -271;338;272;1 -272;338;339;1 -272;339;273;1 -273;339;340;1 -273;340;274;1 -274;340;341;1 -274;341;342;1 -274;342;275;1 -275;342;276;1 -276;342;343;1 -276;343;344;1 -276;344;277;1 -277;344;278;1 -278;344;345;1 -278;345;279;1 -279;345;346;1 -279;346;280;1 -280;346;347;1 -280;347;281;1 -281;347;348;1 -281;348;282;1 -282;348;349;1 -282;349;283;1 -283;349;350;1 -283;350;284;1 -284;350;351;1 -284;351;352;1 -284;352;285;1 -285;352;353;1 -285;353;286;1 -286;353;354;1 -286;354;287;1 -287;354;355;1 -287;355;288;1 -288;355;356;1 -288;356;289;1 -289;356;357;1 -289;357;290;1 -290;357;358;1 -290;358;291;1 -291;358;359;1 -291;359;292;1 -292;359;360;1 -292;360;293;1 -293;360;361;1 -293;361;362;1 -293;362;294;1 -294;362;363;1 -294;363;295;1 -295;363;364;1 -295;364;296;1 -296;364;365;1 -296;365;297;1 -297;365;366;1 -297;366;298;1 -298;366;299;1 -299;366;367;1 -299;367;300;1 -300;367;368;1 -300;368;301;1 -301;368;369;1 -301;369;302;1 -302;369;370;1 -302;370;371;1 -302;371;303;1 -303;371;372;1 -303;372;304;1 -304;372;305;1 -305;372;373;1 -305;373;306;1 -306;373;374;1 -306;374;375;1 -306;375;307;1 -307;375;308;1 -308;375;376;1 -308;376;377;1 -308;377;309;1 -309;377;378;1 -309;378;310;1 -310;378;379;1 -310;379;311;1 -311;379;380;1 -311;380;381;1 -311;381;312;1 -312;381;313;1 -313;381;382;1 -313;382;314;1 -314;382;383;1 -314;383;315;1 -315;383;384;1 -315;384;385;1 -315;385;316;1 -316;385;317;1 -317;385;386;1 -317;386;387;1 -317;387;318;1 -318;387;388;1 -318;388;319;1 -319;388;389;1 -319;389;320;1 -320;389;390;1 -320;390;321;1 -321;390;391;1 -321;391;392;1 -321;392;322;1 -322;392;393;1 -322;393;394;1 -322;394;323;1 -323;394;324;1 -324;394;395;1 -324;395;396;1 -324;396;325;1 -325;396;397;1 -325;397;326;1 -326;397;327;1 -327;397;398;1 -327;398;328;1 -328;398;399;1 -328;399;400;1 -328;400;401;1 -328;401;329;1 -329;401;402;1 -329;402;330;1 -330;402;403;1 -330;403;331;1 -331;403;332;1 -332;403;404;1 -332;404;333;1 -333;404;405;1 -333;405;334;1 -334;405;406;1 -334;406;407;1 -334;407;335;1 -335;407;336;1 -336;407;408;1 -336;408;409;1 -336;409;337;1 -337;409;410;1 -337;410;411;1 -337;411;338;1 -338;411;339;1 -339;411;412;1 -339;412;340;1 -340;412;413;1 -340;413;414;1 -340;414;341;1 -341;414;415;1 -341;415;342;1 -342;415;416;1 -342;416;343;1 -343;416;417;1 -343;417;344;1 -344;417;418;1 -344;418;345;1 -345;418;419;1 -345;419;346;1 -346;419;420;1 -346;420;347;1 -347;420;421;1 -347;421;348;1 -348;421;422;1 -348;422;349;1 -349;422;423;1 -349;423;350;1 -350;423;424;1 -350;424;351;1 -351;424;425;1 -351;425;426;1 -351;426;352;1 -352;426;427;1 -352;427;353;1 -353;427;428;1 -353;428;354;1 -354;428;429;1 -354;429;355;1 -355;429;430;1 -355;430;356;1 -356;430;431;1 -356;431;357;1 -357;431;432;1 -357;432;358;1 -358;432;433;1 -358;433;359;1 -359;433;434;1 -359;434;360;1 -360;434;435;1 -360;435;361;1 -361;435;436;1 -361;436;437;1 -361;437;362;1 -362;437;438;1 -362;438;363;1 -363;438;439;1 -363;439;364;1 -364;439;440;1 -364;440;365;1 -365;440;441;1 -365;441;366;1 -366;441;367;1 -367;441;442;1 -367;442;368;1 -368;442;443;1 -368;443;369;1 -369;443;444;1 -369;444;370;1 -370;444;445;1 -370;445;446;1 -370;446;371;1 -371;446;447;1 -371;447;372;1 -372;447;373;1 -373;447;448;1 -373;448;374;1 -374;448;449;1 -374;449;450;1 -374;450;375;1 -375;450;376;1 -376;450;451;1 -376;451;452;1 -376;452;377;1 -377;452;453;1 -377;453;378;1 -378;453;454;1 -378;454;379;1 -379;454;455;1 -379;455;380;1 -380;455;456;1 -380;456;457;1 -380;457;381;1 -381;457;382;1 -382;457;458;1 -382;458;383;1 -383;458;459;1 -383;459;384;1 -384;459;460;1 -384;460;461;1 -384;461;385;1 -385;461;386;1 -386;461;462;1 -386;462;463;1 -386;463;387;1 -387;463;464;1 -387;464;388;1 -388;464;465;1 -388;465;389;1 -389;465;466;1 -389;466;390;1 -390;466;467;1 -390;467;391;1 -391;467;468;1 -391;468;469;1 -391;469;392;1 -392;469;393;1 -393;469;470;1 -393;470;395;1 -395;470;471;1 -395;471;472;1 -395;472;396;1 -396;472;473;1 -396;473;397;1 -397;473;398;1 -398;473;399;1 -399;473;474;1 -399;474;475;1 -399;475;400;1 -400;475;476;1 -400;476;477;1 -400;477;401;1 -401;477;478;1 -401;478;402;1 -402;478;479;1 -402;479;403;1 -403;479;404;1 -404;479;405;1 -405;479;480;1 -405;480;481;1 -405;481;406;1 -406;481;482;1 -406;482;483;1 -406;483;407;1 -407;483;408;1 -408;483;484;1 -408;484;409;1 -409;484;485;1 -409;485;486;1 -409;486;410;1 -410;486;487;1 -410;487;488;1 -410;488;489;1 -410;489;411;1 -411;489;412;1 -412;489;490;1 -412;490;413;1 -413;490;491;1 -413;491;492;1 -413;492;414;1 -414;492;493;1 -414;493;415;1 -415;493;494;1 -415;494;495;1 -415;495;416;1 -416;495;417;1 -417;495;496;1 -417;496;497;1 -417;497;418;1 -418;497;419;1 -419;497;498;1 -419;498;420;1 -420;498;499;1 -420;499;421;1 -421;499;500;1 -421;500;422;1 -422;500;501;1 -422;501;423;1 -423;501;502;1 -423;502;424;1 -424;502;503;1 -424;503;425;1 -425;503;504;1 -425;504;505;1 -425;505;426;1 -426;505;506;1 -426;506;427;1 -427;506;507;1 -427;507;428;1 -428;507;508;1 -428;508;429;1 -429;508;509;1 -429;509;430;1 -430;509;510;1 -430;510;431;1 -431;510;511;1 -431;511;432;1 -432;511;512;1 -432;512;433;1 -433;512;513;1 -433;513;434;1 -434;513;514;1 -434;514;435;1 -435;514;515;1 -435;515;436;1 -436;515;516;1 -436;516;517;1 -436;517;437;1 -437;517;518;1 -437;518;438;1 -438;518;519;1 -438;519;439;1 -439;519;520;1 -439;520;440;1 -440;520;521;1 -440;521;441;1 -441;521;522;1 -441;522;442;1 -442;522;443;1 -443;522;523;1 -443;523;444;1 -444;523;524;1 -444;524;445;1 -445;524;525;1 -445;525;526;1 -445;526;446;1 -446;526;527;1 -446;527;447;1 -447;527;448;1 -448;527;528;1 -448;528;449;1 -449;528;529;1 -449;529;530;1 -449;530;450;1 -450;530;451;1 -451;530;531;1 -451;531;532;1 -451;532;452;1 -452;532;533;1 -452;533;453;1 -453;533;534;1 -453;534;454;1 -454;534;535;1 -454;535;455;1 -455;535;536;1 -455;536;456;1 -456;536;537;1 -456;537;538;1 -456;538;457;1 -457;538;458;1 -458;538;539;1 -458;539;540;1 -458;540;459;1 -459;540;460;1 -460;540;541;1 -460;541;542;1 -460;542;461;1 -461;542;462;1 -462;542;543;1 -462;543;544;1 -462;544;463;1 -463;544;545;1 -463;545;464;1 -464;545;546;1 -464;546;465;1 -465;546;547;1 -465;547;466;1 -466;547;548;1 -466;548;467;1 -467;548;549;1 -467;549;468;1 -468;549;550;1 -468;550;551;1 -468;551;469;1 -469;551;470;1 -470;551;552;1 -470;552;553;1 -470;553;471;1 -471;553;554;1 -471;554;472;1 -472;554;555;1 -472;555;474;1 -474;555;556;1 -474;556;475;1 -475;556;557;1 -475;557;558;1 -475;558;476;1 -476;558;559;1 -476;559;560;1 -476;560;477;1 -477;560;561;1 -477;561;478;1 -478;561;479;1 -479;561;480;1 -480;561;562;1 -480;562;481;1 -481;562;563;1 -481;563;564;1 -481;564;482;1 -482;564;565;1 -482;565;566;1 -482;566;483;1 -483;566;484;1 -484;566;567;1 -484;567;485;1 -485;567;568;1 -485;568;486;1 -486;568;487;1 -487;568;569;1 -487;569;570;1 -487;570;488;1 -488;570;571;1 -488;571;572;1 -488;572;489;1 -489;572;573;1 -489;573;490;1 -490;573;491;1 -491;573;574;1 -491;574;575;1 -491;575;492;1 -492;575;576;1 -492;576;493;1 -493;576;577;1 -493;577;494;1 -494;577;578;1 -494;578;579;1 -494;579;495;1 -495;579;496;1 -496;579;580;1 -496;580;581;1 -496;581;497;1 -497;581;582;1 -497;582;498;1 -498;582;583;1 -498;583;499;1 -499;583;584;1 -499;584;500;1 -500;584;585;1 -500;585;501;1 -501;585;586;1 -501;586;502;1 -502;586;587;1 -502;587;503;1 -503;587;588;1 -503;588;504;1 -504;588;589;1 -504;589;590;1 -504;590;505;1 -505;590;591;1 -505;591;506;1 -506;591;592;1 -506;592;507;1 -507;592;593;1 -507;593;508;1 -508;593;594;1 -508;594;509;1 -509;594;595;1 -509;595;596;1 -509;596;510;1 -510;596;597;1 -510;597;511;1 -511;597;598;1 -511;598;512;1 -512;598;599;1 -512;599;513;1 -513;599;600;1 -513;600;514;1 -514;600;601;1 -514;601;515;1 -515;601;602;1 -515;602;516;1 -516;602;603;1 -516;603;604;1 -516;604;605;1 -516;605;517;1 -517;605;606;1 -517;606;518;1 -518;606;607;1 -518;607;519;1 -519;607;608;1 -519;608;520;1 -520;608;609;1 -520;609;521;1 -521;609;610;1 -521;610;522;1 -522;610;611;1 -522;611;523;1 -523;611;612;1 -523;612;524;1 -524;612;613;1 -524;613;525;1 -525;613;614;1 -525;614;615;1 -525;615;526;1 -526;615;616;1 -526;616;527;1 -527;616;528;1 -528;616;617;1 -528;617;529;1 -529;617;618;1 -529;618;619;1 -529;619;530;1 -530;619;531;1 -531;619;620;1 -531;620;621;1 -531;621;532;1 -532;621;622;1 -532;622;533;1 -533;622;623;1 -533;623;534;1 -534;623;624;1 -534;624;625;1 -534;625;535;1 -535;625;536;1 -536;625;626;1 -536;626;537;1 -537;626;627;1 -537;627;628;1 -537;628;538;1 -538;628;539;1 -539;628;629;1 -539;629;630;1 -539;630;540;1 -540;630;541;1 -541;630;631;1 -541;631;632;1 -541;632;542;1 -542;632;543;1 -543;632;633;1 -543;633;634;1 -543;634;544;1 -544;634;635;1 -544;635;545;1 -545;635;636;1 -545;636;546;1 -546;636;637;1 -546;637;547;1 -547;637;638;1 -547;638;548;1 -548;638;639;1 -548;639;549;1 -549;639;640;1 -549;640;550;1 -550;640;641;1 -550;641;642;1 -550;642;551;1 -551;642;552;1 -552;642;643;1 -552;643;644;1 -552;644;553;1 -553;644;645;1 -553;645;646;1 -553;646;554;1 -554;646;647;1 -554;647;555;1 -555;647;556;1 -556;647;648;1 -556;648;649;1 -556;649;557;1 -557;649;650;1 -557;650;558;1 -558;650;651;1 -558;651;559;1 -559;651;652;1 -559;652;653;1 -559;653;560;1 -560;653;562;1 -562;653;563;1 -563;653;654;1 -563;654;655;1 -563;655;564;1 -564;655;656;1 -564;656;565;1 -565;656;657;1 -565;657;658;1 -565;658;659;1 -565;659;566;1 -566;659;567;1 -567;659;660;1 -567;660;661;1 -567;661;568;1 -568;661;662;1 -568;662;569;1 -569;662;663;1 -569;663;664;1 -569;664;570;1 -570;664;665;1 -570;665;571;1 -571;665;666;1 -571;666;667;1 -571;667;572;1 -572;667;573;1 -573;667;574;1 -574;667;668;1 -574;668;669;1 -574;669;575;1 -575;669;670;1 -575;670;576;1 -576;670;671;1 -576;671;577;1 -577;671;672;1 -577;672;578;1 -578;672;673;1 -578;673;674;1 -578;674;580;1 -580;674;675;1 -580;675;676;1 -580;676;581;1 -581;676;677;1 -581;677;582;1 -582;677;678;1 -582;678;583;1 -583;678;679;1 -583;679;584;1 -584;679;680;1 -584;680;585;1 -585;680;681;1 -585;681;586;1 -586;681;682;1 -586;682;587;1 -587;682;683;1 -587;683;588;1 -588;683;684;1 -588;684;589;1 -589;684;685;1 -589;685;686;1 -589;686;590;1 -590;686;687;1 -590;687;591;1 -591;687;688;1 -591;688;592;1 -592;688;689;1 -592;689;593;1 -593;689;690;1 -593;690;594;1 -594;690;595;1 -595;690;691;1 -595;691;692;1 -595;692;693;1 -595;693;596;1 -596;693;597;1 -597;693;694;1 -597;694;598;1 -598;694;695;1 -598;695;599;1 -599;695;696;1 -599;696;600;1 -600;696;697;1 -600;697;601;1 -601;697;698;1 -601;698;602;1 -602;698;699;1 -602;699;603;1 -603;699;700;1 -603;700;701;1 -603;701;604;1 -604;701;702;1 -604;702;605;1 -605;702;703;1 -605;703;606;1 -606;703;704;1 -606;704;607;1 -607;704;705;1 -607;705;706;1 -607;706;608;1 -608;706;707;1 -608;707;609;1 -609;707;708;1 -609;708;610;1 -610;708;709;1 -610;709;611;1 -611;709;710;1 -611;710;612;1 -612;710;711;1 -612;711;613;1 -613;711;712;1 -613;712;614;1 -614;712;713;1 -614;713;714;1 -614;714;615;1 -615;714;715;1 -615;715;616;1 -616;715;617;1 -617;715;716;1 -617;716;618;1 -618;716;717;1 -618;717;718;1 -618;718;619;1 -619;718;620;1 -620;718;719;1 -620;719;720;1 -620;720;621;1 -621;720;721;1 -621;721;622;1 -622;721;722;1 -622;722;623;1 -623;722;723;1 -623;723;624;1 -624;723;724;1 -624;724;725;1 -624;725;625;1 -625;725;626;1 -626;725;726;1 -626;726;627;1 -627;726;727;1 -627;727;728;1 -627;728;628;1 -628;728;629;1 -629;728;729;1 -629;729;730;1 -629;730;630;1 -630;730;631;1 -631;730;731;1 -631;731;732;1 -631;732;632;1 -632;732;633;1 -633;732;733;1 -633;733;734;1 -633;734;634;1 -634;734;735;1 -634;735;635;1 -635;735;736;1 -635;736;636;1 -636;736;737;1 -636;737;637;1 -637;737;738;1 -637;738;638;1 -638;738;739;1 -638;739;639;1 -639;739;740;1 -639;740;640;1 -640;740;741;1 -640;741;641;1 -641;741;742;1 -641;742;743;1 -641;743;642;1 -642;743;643;1 -643;743;744;1 -643;744;745;1 -643;745;644;1 -644;745;746;1 -644;746;645;1 -645;746;747;1 -645;747;646;1 -646;747;647;1 -647;747;648;1 -648;747;748;1 -648;748;749;1 -648;749;649;1 -649;749;750;1 -649;750;650;1 -650;750;751;1 -650;751;651;1 -651;751;752;1 -651;752;652;1 -652;752;753;1 -652;753;654;1 -654;753;754;1 -654;754;655;1 -655;754;755;1 -655;755;656;1 -656;755;657;1 -657;755;756;1 -657;756;757;1 -657;757;658;1 -658;757;758;1 -658;758;659;1 -659;758;660;1 -660;758;759;1 -660;759;760;1 -660;760;661;1 -661;760;761;1 -661;761;662;1 -662;761;762;1 -662;762;663;1 -663;762;763;1 -663;763;764;1 -663;764;664;1 -664;764;765;1 -664;765;665;1 -665;765;766;1 -665;766;666;1 -666;766;767;1 -666;767;668;1 -668;767;768;1 -668;768;669;1 -669;768;769;1 -669;769;670;1 -670;769;770;1 -670;770;671;1 -671;770;771;1 -671;771;672;1 -672;771;772;1 -672;772;673;1 -673;772;773;1 -673;773;774;1 -673;774;674;1 -674;774;675;1 -675;774;775;1 -675;775;776;1 -675;776;676;1 -676;776;777;1 -676;777;677;1 -677;777;778;1 -677;778;678;1 -678;778;779;1 -678;779;679;1 -679;779;780;1 -679;780;680;1 -680;780;781;1 -680;781;681;1 -681;781;782;1 -681;782;682;1 -682;782;783;1 -682;783;683;1 -683;783;784;1 -683;784;684;1 -684;784;785;1 -684;785;685;1 -685;785;786;1 -685;786;686;1 -686;786;787;1 -686;787;687;1 -687;787;788;1 -687;788;789;1 -687;789;688;1 -688;789;790;1 -688;790;689;1 -689;790;791;1 -689;791;690;1 -690;791;691;1 -691;791;792;1 -691;792;793;1 -691;793;692;1 -692;793;794;1 -692;794;795;1 -692;795;693;1 -693;795;694;1 -694;795;796;1 -694;796;695;1 -695;796;797;1 -695;797;696;1 -696;797;798;1 -696;798;697;1 -697;798;799;1 -697;799;698;1 -698;799;800;1 -698;800;699;1 -699;800;801;1 -699;801;700;1 -700;801;802;1 -700;802;803;1 -700;803;701;1 -701;803;804;1 -701;804;702;1 -702;804;805;1 -702;805;703;1 -703;805;806;1 -703;806;704;1 -704;806;807;1 -704;807;705;1 -705;807;808;1 -705;808;809;1 -705;809;706;1 -706;809;810;1 -706;810;707;1 -707;810;811;1 -707;811;708;1 -708;811;812;1 -708;812;709;1 -709;812;813;1 -709;813;710;1 -710;813;814;1 -710;814;711;1 -711;814;815;1 -711;815;712;1 -712;815;816;1 -712;816;713;1 -713;816;817;1 -713;817;818;1 -713;818;714;1 -714;818;819;1 -714;819;715;1 -715;819;716;1 -716;819;820;1 -716;820;717;1 -717;820;821;1 -717;821;822;1 -717;822;718;1 -718;822;719;1 -719;822;823;1 -719;823;824;1 -719;824;720;1 -720;824;825;1 -720;825;721;1 -721;825;826;1 -721;826;722;1 -722;826;827;1 -722;827;723;1 -723;827;828;1 -723;828;724;1 -724;828;829;1 -724;829;830;1 -724;830;725;1 -725;830;831;1 -725;831;726;1 -726;831;727;1 -727;831;832;1 -727;832;833;1 -727;833;728;1 -728;833;729;1 -729;833;834;1 -729;834;835;1 -729;835;730;1 -730;835;731;1 -731;835;836;1 -731;836;837;1 -731;837;732;1 -732;837;733;1 -733;837;838;1 -733;838;839;1 -733;839;734;1 -734;839;840;1 -734;840;735;1 -735;840;841;1 -735;841;736;1 -736;841;842;1 -736;842;737;1 -737;842;843;1 -737;843;738;1 -738;843;844;1 -738;844;739;1 -739;844;845;1 -739;845;740;1 -740;845;846;1 -740;846;741;1 -741;846;847;1 -741;847;742;1 -742;847;848;1 -742;848;849;1 -742;849;743;1 -743;849;744;1 -744;849;850;1 -744;850;851;1 -744;851;745;1 -745;851;852;1 -745;852;746;1 -746;852;853;1 -746;853;854;1 -746;854;747;1 -747;854;748;1 -748;854;855;1 -748;855;856;1 -748;856;857;1 -748;857;749;1 -749;857;858;1 -749;858;750;1 -750;858;859;1 -750;859;751;1 -751;859;860;1 -751;860;752;1 -752;860;861;1 -752;861;862;1 -752;862;753;1 -753;862;863;1 -753;863;864;1 -753;864;754;1 -754;864;865;1 -754;865;755;1 -755;865;756;1 -756;865;866;1 -756;866;867;1 -756;867;757;1 -757;867;868;1 -757;868;758;1 -758;868;759;1 -759;868;869;1 -759;869;870;1 -759;870;871;1 -759;871;760;1 -760;871;872;1 -760;872;873;1 -760;873;761;1 -761;873;874;1 -761;874;762;1 -762;874;875;1 -762;875;763;1 -763;875;876;1 -763;876;877;1 -763;877;764;1 -764;877;878;1 -764;878;765;1 -765;878;879;1 -765;879;766;1 -766;879;880;1 -766;880;767;1 -767;880;881;1 -767;881;768;1 -768;881;882;1 -768;882;769;1 -769;882;883;1 -769;883;770;1 -770;883;884;1 -770;884;771;1 -771;884;772;1 -772;884;773;1 -773;884;885;1 -773;885;886;1 -773;886;774;1 -774;886;887;1 -774;887;775;1 -775;887;888;1 -775;888;889;1 -775;889;776;1 -776;889;777;1 -777;889;890;1 -777;890;778;1 -778;890;891;1 -778;891;779;1 -779;891;892;1 -779;892;780;1 -780;892;893;1 -780;893;894;1 -780;894;781;1 -781;894;895;1 -781;895;782;1 -782;895;896;1 -782;896;783;1 -783;896;897;1 -783;897;784;1 -784;897;898;1 -784;898;785;1 -785;898;899;1 -785;899;786;1 -786;899;900;1 -786;900;787;1 -787;900;901;1 -787;901;788;1 -788;901;902;1 -788;902;903;1 -788;903;789;1 -789;903;904;1 -789;904;790;1 -790;904;905;1 -790;905;791;1 -791;905;792;1 -792;905;906;1 -792;906;907;1 -792;907;793;1 -793;907;908;1 -793;908;794;1 -794;908;909;1 -794;909;910;1 -794;910;795;1 -795;910;796;1 -796;910;911;1 -796;911;797;1 -797;911;912;1 -797;912;798;1 -798;912;913;1 -798;913;799;1 -799;913;914;1 -799;914;800;1 -800;914;915;1 -800;915;801;1 -801;915;916;1 -801;916;802;1 -802;916;917;1 -802;917;918;1 -802;918;919;1 -802;919;803;1 -803;919;920;1 -803;920;804;1 -804;920;921;1 -804;921;805;1 -805;921;922;1 -805;922;806;1 -806;922;923;1 -806;923;807;1 -807;923;924;1 -807;924;808;1 -808;924;925;1 -808;925;809;1 -809;925;926;1 -809;926;810;1 -810;926;927;1 -810;927;811;1 -811;927;928;1 -811;928;812;1 -812;928;929;1 -812;929;813;1 -813;929;930;1 -813;930;814;1 -814;930;931;1 -814;931;815;1 -815;931;932;1 -815;932;816;1 -816;932;933;1 -816;933;817;1 -817;933;934;1 -817;934;935;1 -817;935;818;1 -818;935;936;1 -818;936;819;1 -819;936;820;1 -820;936;937;1 -820;937;821;1 -821;937;938;1 -821;938;939;1 -821;939;822;1 -822;939;823;1 -823;939;940;1 -823;940;941;1 -823;941;824;1 -824;941;942;1 -824;942;825;1 -825;942;943;1 -825;943;826;1 -826;943;944;1 -826;944;827;1 -827;944;945;1 -827;945;828;1 -828;945;946;1 -828;946;829;1 -829;946;947;1 -829;947;948;1 -829;948;830;1 -830;948;949;1 -830;949;831;1 -831;949;950;1 -831;950;832;1 -832;950;833;1 -833;950;951;1 -833;951;834;1 -834;951;952;1 -834;952;953;1 -834;953;835;1 -835;953;836;1 -836;953;954;1 -836;954;955;1 -836;955;837;1 -837;955;838;1 -838;955;956;1 -838;956;957;1 -838;957;839;1 -839;957;958;1 -839;958;840;1 -840;958;959;1 -840;959;841;1 -841;959;960;1 -841;960;842;1 -842;960;961;1 -842;961;843;1 -843;961;962;1 -843;962;844;1 -844;962;963;1 -844;963;845;1 -845;963;964;1 -845;964;846;1 -846;964;965;1 -846;965;847;1 -847;965;966;1 -847;966;848;1 -848;966;967;1 -848;967;968;1 -848;968;849;1 -849;968;850;1 -850;968;969;1 -850;969;970;1 -850;970;851;1 -851;970;852;1 -852;970;971;1 -852;971;853;1 -853;971;972;1 -853;972;855;1 -855;972;973;1 -855;973;974;1 -855;974;856;1 -856;974;975;1 -856;975;857;1 -857;975;976;1 -857;976;858;1 -858;976;977;1 -858;977;978;1 -858;978;859;1 -859;978;979;1 -859;979;860;1 -860;979;861;1 -861;979;980;1 -861;980;981;1 -861;981;982;1 -861;982;862;1 -862;982;863;1 -863;982;983;1 -863;983;984;1 -863;984;864;1 -864;984;985;1 -864;985;865;1 -865;985;986;1 -865;986;866;1 -866;986;987;1 -866;987;867;1 -867;987;988;1 -867;988;989;1 -867;989;868;1 -868;989;869;1 -869;989;990;1 -869;990;870;1 -870;990;991;1 -870;991;992;1 -870;992;871;1 -871;992;872;1 -872;992;993;1 -872;993;994;1 -872;994;995;1 -872;995;873;1 -873;995;874;1 -874;995;996;1 -874;996;997;1 -874;997;875;1 -875;997;998;1 -875;998;999;1 -875;999;876;1 -876;999;1000;1 -876;1000;1001;1 -876;1001;877;1 -877;1001;1002;1 -877;1002;878;1 -878;1002;1003;1 -878;1003;879;1 -879;1003;1004;1 -879;1004;880;1 -880;1004;1005;1 -880;1005;881;1 -881;1005;1006;1 -881;1006;882;1 -882;1006;1007;1 -882;1007;883;1 -883;1007;885;1 -885;1007;1008;1 -885;1008;886;1 -886;1008;1009;1 -886;1009;887;1 -887;1009;1010;1 -887;1010;888;1 -888;1010;1011;1 -888;1011;889;1 -889;1011;1012;1 -889;1012;890;1 -890;1012;1013;1 -890;1013;891;1 -891;1013;1014;1 -891;1014;892;1 -892;1014;893;1 -893;1014;1015;1 -893;1015;1016;1 -893;1016;894;1 -894;1016;1017;1 -894;1017;895;1 -895;1017;1018;1 -895;1018;896;1 -896;1018;1019;1 -896;1019;897;1 -897;1019;1020;1 -897;1020;898;1 -898;1020;1021;1 -898;1021;899;1 -899;1021;1022;1 -899;1022;1023;1 -899;1023;900;1 -900;1023;1024;1 -900;1024;901;1 -901;1024;1025;1 -901;1025;902;1 -902;1025;1026;1 -902;1026;903;1 -903;1026;1027;1 -903;1027;1028;1 -903;1028;1029;1 -903;1029;904;1 -904;1029;1030;1 -904;1030;905;1 -905;1030;906;1 -906;1030;1031;1 -906;1031;1032;1 -906;1032;907;1 -907;1032;1033;1 -907;1033;908;1 -908;1033;1034;1 -908;1034;909;1 -909;1034;1035;1 -909;1035;1036;1 -909;1036;910;1 -910;1036;911;1 -911;1036;1037;1 -911;1037;912;1 -912;1037;1038;1 -912;1038;913;1 -913;1038;1039;1 -913;1039;914;1 -914;1039;1040;1 -914;1040;915;1 -915;1040;1041;1 -915;1041;916;1 -916;1041;1042;1 -916;1042;917;1 -917;1042;1043;1 -917;1043;1044;1 -917;1044;918;1 -918;1044;1045;1 -918;1045;919;1 -919;1045;1046;1 -919;1046;920;1 -920;1046;1047;1 -920;1047;921;1 -921;1047;1048;1 -921;1048;922;1 -922;1048;1049;1 -922;1049;923;1 -923;1049;1050;1 -923;1050;924;1 -924;1050;1051;1 -924;1051;925;1 -925;1051;1052;1 -925;1052;926;1 -926;1052;1053;1 -926;1053;927;1 -927;1053;1054;1 -927;1054;928;1 -928;1054;1055;1 -928;1055;929;1 -929;1055;1056;1 -929;1056;930;1 -930;1056;1057;1 -930;1057;931;1 -931;1057;1058;1 -931;1058;932;1 -932;1058;1059;1 -932;1059;933;1 -933;1059;1060;1 -933;1060;934;1 -934;1060;1061;1 -934;1061;1062;1 -934;1062;935;1 -935;1062;1063;1 -935;1063;936;1 -936;1063;937;1 -937;1063;1064;1 -937;1064;938;1 -938;1064;1065;1 -938;1065;1066;1 -938;1066;939;1 -939;1066;940;1 -940;1066;1067;1 -940;1067;1068;1 -940;1068;941;1 -941;1068;1069;1 -941;1069;942;1 -942;1069;1070;1 -942;1070;943;1 -943;1070;1071;1 -943;1071;944;1 -944;1071;1072;1 -944;1072;945;1 -945;1072;1073;1 -945;1073;946;1 -946;1073;1074;1 -946;1074;947;1 -947;1074;1075;1 -947;1075;1076;1 -947;1076;948;1 -948;1076;1077;1 -948;1077;949;1 -949;1077;1078;1 -949;1078;950;1 -950;1078;951;1 -951;1078;1079;1 -951;1079;952;1 -952;1079;1080;1 -952;1080;1081;1 -952;1081;953;1 -953;1081;954;1 -954;1081;1082;1 -954;1082;1083;1 -954;1083;955;1 -955;1083;956;1 -956;1083;1084;1 -956;1084;1085;1 -956;1085;957;1 -957;1085;1086;1 -957;1086;958;1 -958;1086;1087;1 -958;1087;959;1 -959;1087;1088;1 -959;1088;960;1 -960;1088;1089;1 -960;1089;961;1 -961;1089;1090;1 -961;1090;962;1 -962;1090;1091;1 -962;1091;963;1 -963;1091;1092;1 -963;1092;964;1 -964;1092;1093;1 -964;1093;965;1 -965;1093;1094;1 -965;1094;966;1 -966;1094;1095;1 -966;1095;967;1 -967;1095;1096;1 -967;1096;1097;1 -967;1097;968;1 -968;1097;969;1 -969;1097;1098;1 -969;1098;1099;1 -969;1099;970;1 -970;1099;971;1 -971;1099;1100;1 -971;1100;973;1 -973;1100;1101;1 -973;1101;1102;1 -973;1102;974;1 -974;1102;1103;1 -974;1103;975;1 -975;1103;1104;1 -975;1104;1105;1 -975;1105;976;1 -976;1105;977;1 -977;1105;1106;1 -977;1106;1107;1 -977;1107;978;1 -978;1107;1108;1 -978;1108;979;1 -979;1108;980;1 -980;1108;1109;1 -980;1109;1110;1 -980;1110;1111;1 -980;1111;981;1 -981;1111;1112;1 -981;1112;982;1 -982;1112;1113;1 -982;1113;983;1 -983;1113;1114;1 -983;1114;1115;1 -983;1115;984;1 -984;1115;986;1 -986;1115;1114;1 -986;1114;1116;1 -986;1116;987;1 -987;1116;1117;1 -987;1117;1118;1 -987;1118;988;1 -988;1118;1119;1 -988;1119;1120;1 -988;1120;989;1 -989;1120;1121;1 -989;1121;990;1 -990;1121;991;1 -991;1121;1122;1 -991;1122;992;1 -992;1122;1123;1 -992;1123;993;1 -993;1123;1124;1 -993;1124;1125;1 -993;1125;994;1 -994;1125;1126;1 -994;1126;995;1 -995;1126;996;1 -996;1126;1127;1 -996;1127;1128;1 -996;1128;998;1 -998;1128;1129;1 -998;1129;1130;1 -998;1130;999;1 -999;1130;1131;1 -999;1131;1000;1 -1000;1131;1132;1 -1000;1132;1133;1 -1000;1133;1001;1 -1001;1133;1134;1 -1001;1134;1002;1 -1002;1134;1135;1 -1002;1135;1003;1 -1003;1135;1136;1 -1003;1136;1004;1 -1004;1136;1137;1 -1004;1137;1005;1 -1005;1137;1138;1 -1005;1138;1006;1 -1006;1138;1139;1 -1006;1139;1007;1 -1007;1139;1008;1 -1008;1139;1140;1 -1008;1140;1009;1 -1009;1140;1141;1 -1009;1141;1010;1 -1010;1141;1142;1 -1010;1142;1011;1 -1011;1142;1143;1 -1011;1143;1012;1 -1012;1143;1144;1 -1012;1144;1013;1 -1013;1144;1145;1 -1013;1145;1014;1 -1014;1145;1015;1 -1015;1145;1146;1 -1015;1146;1147;1 -1015;1147;1016;1 -1016;1147;1148;1 -1016;1148;1017;1 -1017;1148;1149;1 -1017;1149;1018;1 -1018;1149;1150;1 -1018;1150;1019;1 -1019;1150;1151;1 -1019;1151;1020;1 -1020;1151;1152;1 -1020;1152;1021;1 -1021;1152;1153;1 -1021;1153;1022;1 -1022;1153;1154;1 -1022;1154;1155;1 -1022;1155;1023;1 -1023;1155;1156;1 -1023;1156;1024;1 -1024;1156;1025;1 -1025;1156;1157;1 -1025;1157;1158;1 -1025;1158;1026;1 -1026;1158;1027;1 -1027;1158;1159;1 -1027;1159;1160;1 -1027;1160;1161;1 -1027;1161;1028;1 -1028;1161;1162;1 -1028;1162;1163;1 -1028;1163;1029;1 -1029;1163;1164;1 -1029;1164;1030;1 -1030;1164;1031;1 -1031;1164;1165;1 -1031;1165;1032;1 -1032;1165;1166;1 -1032;1166;1167;1 -1032;1167;1033;1 -1033;1167;1168;1 -1033;1168;1034;1 -1034;1168;1169;1 -1034;1169;1035;1 -1035;1169;1170;1 -1035;1170;1171;1 -1035;1171;1036;1 -1036;1171;1037;1 -1037;1171;1172;1 -1037;1172;1038;1 -1038;1172;1173;1 -1038;1173;1039;1 -1039;1173;1174;1 -1039;1174;1040;1 -1040;1174;1175;1 -1040;1175;1041;1 -1041;1175;1176;1 -1041;1176;1042;1 -1042;1176;1177;1 -1042;1177;1043;1 -1043;1177;1178;1 -1043;1178;1179;1 -1043;1179;1044;1 -1044;1179;1180;1 -1044;1180;1045;1 -1045;1180;1181;1 -1045;1181;1046;1 -1046;1181;1182;1 -1046;1182;1047;1 -1047;1182;1183;1 -1047;1183;1048;1 -1048;1183;1184;1 -1048;1184;1049;1 -1049;1184;1185;1 -1049;1185;1050;1 -1050;1185;1186;1 -1050;1186;1051;1 -1051;1186;1187;1 -1051;1187;1052;1 -1052;1187;1188;1 -1052;1188;1053;1 -1053;1188;1189;1 -1053;1189;1054;1 -1054;1189;1190;1 -1054;1190;1055;1 -1055;1190;1191;1 -1055;1191;1056;1 -1056;1191;1192;1 -1056;1192;1057;1 -1057;1192;1193;1 -1057;1193;1058;1 -1058;1193;1194;1 -1058;1194;1059;1 -1059;1194;1195;1 -1059;1195;1060;1 -1060;1195;1196;1 -1060;1196;1061;1 -1061;1196;1197;1 -1061;1197;1198;1 -1061;1198;1062;1 -1062;1198;1199;1 -1062;1199;1063;1 -1063;1199;1064;1 -1064;1199;1200;1 -1064;1200;1065;1 -1065;1200;1201;1 -1065;1201;1202;1 -1065;1202;1066;1 -1066;1202;1067;1 -1067;1202;1203;1 -1067;1203;1204;1 -1067;1204;1068;1 -1068;1204;1205;1 -1068;1205;1069;1 -1069;1205;1206;1 -1069;1206;1070;1 -1070;1206;1207;1 -1070;1207;1071;1 -1071;1207;1208;1 -1071;1208;1072;1 -1072;1208;1209;1 -1072;1209;1073;1 -1073;1209;1210;1 -1073;1210;1074;1 -1074;1210;1211;1 -1074;1211;1075;1 -1075;1211;1212;1 -1075;1212;1213;1 -1075;1213;1076;1 -1076;1213;1077;1 -1077;1213;1214;1 -1077;1214;1078;1 -1078;1214;1215;1 -1078;1215;1216;1 -1078;1216;1217;1 -1078;1217;1079;1 -1079;1217;1080;1 -1080;1217;1218;1 -1080;1218;1081;1 -1081;1218;1082;1 -1082;1218;1219;1 -1082;1219;1220;1 -1082;1220;1083;1 -1083;1220;1084;1 -1084;1220;1221;1 -1084;1221;1222;1 -1084;1222;1085;1 -1085;1222;1223;1 -1085;1223;1086;1 -1086;1223;1224;1 -1086;1224;1087;1 -1087;1224;1225;1 -1087;1225;1088;1 -1088;1225;1226;1 -1088;1226;1089;1 -1089;1226;1227;1 -1089;1227;1090;1 -1090;1227;1228;1 -1090;1228;1091;1 -1091;1228;1229;1 -1091;1229;1092;1 -1092;1229;1230;1 -1092;1230;1093;1 -1093;1230;1231;1 -1093;1231;1094;1 -1094;1231;1232;1 -1094;1232;1095;1 -1095;1232;1233;1 -1095;1233;1096;1 -1096;1233;1234;1 -1096;1234;1235;1 -1096;1235;1097;1 -1097;1235;1098;1 -1098;1235;1236;1 -1098;1236;1237;1 -1098;1237;1099;1 -1099;1237;1238;1 -1099;1238;1100;1 -1100;1238;1101;1 -1101;1238;1239;1 -1101;1239;1240;1 -1101;1240;1241;1 -1101;1241;1242;1 -1101;1242;1102;1 -1102;1242;1243;1 -1102;1243;1103;1 -1103;1243;1244;1 -1103;1244;1104;1 -1104;1244;1106;1 -1106;1244;1245;1 -1106;1245;1107;1 -1107;1245;1246;1 -1107;1246;1108;1 -1108;1246;1109;1 -1109;1246;1247;1 -1109;1247;1248;1 -1109;1248;1249;1 -1109;1249;1110;1 -1110;1249;1250;1 -1110;1250;1251;1 -1110;1251;1111;1 -1111;1251;1112;1 -1112;1251;1252;1 -1112;1252;1113;1 -1113;1252;1253;1 -1113;1253;1114;1 -1114;1253;1116;1 -1116;1253;1117;1 -1117;1253;1254;1 -1117;1254;1255;1 -1117;1255;1118;1 -1118;1255;1256;1 -1118;1256;1119;1 -1119;1256;1257;1 -1119;1257;1258;1 -1119;1258;1259;1 -1119;1259;1120;1 -1120;1259;1121;1 -1121;1259;1260;1 -1121;1260;1122;1 -1122;1260;1261;1 -1122;1261;1123;1 -1123;1261;1262;1 -1123;1262;1124;1 -1124;1262;1263;1 -1124;1263;1264;1 -1124;1264;1265;1 -1124;1265;1125;1 -1125;1265;1127;1 -1127;1265;1266;1 -1127;1266;1267;1 -1127;1267;1128;1 -1128;1267;1129;1 -1129;1267;1268;1 -1129;1268;1269;1 -1129;1269;1270;1 -1129;1270;1130;1 -1130;1270;1271;1 -1130;1271;1131;1 -1131;1271;1272;1 -1131;1272;1132;1 -1132;1272;1273;1 -1132;1273;1274;1 -1132;1274;1275;1 -1132;1275;1133;1 -1133;1275;1276;1 -1133;1276;1134;1 -1134;1276;1277;1 -1134;1277;1135;1 -1135;1277;1278;1 -1135;1278;1136;1 -1136;1278;1279;1 -1136;1279;1137;1 -1137;1279;1280;1 -1137;1280;1138;1 -1138;1280;1281;1 -1138;1281;1139;1 -1139;1281;1140;1 -1140;1281;1282;1 -1140;1282;1141;1 -1141;1282;1283;1 -1141;1283;1284;1 -1141;1284;1142;1 -1142;1284;1285;1 -1142;1285;1143;1 -1143;1285;1286;1 -1143;1286;1144;1 -1144;1286;1287;1 -1144;1287;1145;1 -1145;1287;1146;1 -1146;1287;1288;1 -1146;1288;1289;1 -1146;1289;1147;1 -1147;1289;1290;1 -1147;1290;1148;1 -1148;1290;1291;1 -1148;1291;1149;1 -1149;1291;1292;1 -1149;1292;1150;1 -1150;1292;1293;1 -1150;1293;1151;1 -1151;1293;1294;1 -1151;1294;1152;1 -1152;1294;1295;1 -1152;1295;1153;1 -1153;1295;1296;1 -1153;1296;1154;1 -1154;1296;1297;1 -1154;1297;1298;1 -1154;1298;1155;1 -1155;1298;1299;1 -1155;1299;1156;1 -1156;1299;1300;1 -1156;1300;1157;1 -1157;1300;1158;1 -1158;1300;1159;1 -1159;1300;1301;1 -1159;1301;1160;1 -1160;1301;1302;1 -1160;1302;1303;1 -1160;1303;1304;1 -1160;1304;1305;1 -1160;1305;1161;1 -1161;1305;1162;1 -1162;1305;1306;1 -1162;1306;1307;1 -1162;1307;1163;1 -1163;1307;1308;1 -1163;1308;1164;1 -1164;1308;1165;1 -1165;1308;1309;1 -1165;1309;1166;1 -1166;1309;1310;1 -1166;1310;1167;1 -1167;1310;1311;1 -1167;1311;1168;1 -1168;1311;1312;1 -1168;1312;1169;1 -1169;1312;1313;1 -1169;1313;1170;1 -1170;1313;1314;1 -1170;1314;1315;1 -1170;1315;1316;1 -1170;1316;1171;1 -1171;1316;1172;1 -1172;1316;1317;1 -1172;1317;1173;1 -1173;1317;1318;1 -1173;1318;1174;1 -1174;1318;1319;1 -1174;1319;1175;1 -1175;1319;1320;1 -1175;1320;1176;1 -1176;1320;1321;1 -1176;1321;1177;1 -1177;1321;1322;1 -1177;1322;1178;1 -1178;1322;1323;1 -1178;1323;1324;1 -1178;1324;1179;1 -1179;1324;1325;1 -1179;1325;1180;1 -1180;1325;1326;1 -1180;1326;1181;1 -1181;1326;1327;1 -1181;1327;1182;1 -1182;1327;1328;1 -1182;1328;1183;1 -1183;1328;1329;1 -1183;1329;1184;1 -1184;1329;1330;1 -1184;1330;1185;1 -1185;1330;1331;1 -1185;1331;1186;1 -1186;1331;1332;1 -1186;1332;1187;1 -1187;1332;1333;1 -1187;1333;1188;1 -1188;1333;1334;1 -1188;1334;1189;1 -1189;1334;1335;1 -1189;1335;1190;1 -1190;1335;1336;1 -1190;1336;1191;1 -1191;1336;1337;1 -1191;1337;1192;1 -1192;1337;1338;1 -1192;1338;1193;1 -1193;1338;1339;1 -1193;1339;1194;1 -1194;1339;1340;1 -1194;1340;1195;1 -1195;1340;1341;1 -1195;1341;1196;1 -1196;1341;1342;1 -1196;1342;1197;1 -1197;1342;1343;1 -1197;1343;1344;1 -1197;1344;1198;1 -1198;1344;1345;1 -1198;1345;1199;1 -1199;1345;1200;1 -1200;1345;1346;1 -1200;1346;1201;1 -1201;1346;1347;1 -1201;1347;1348;1 -1201;1348;1202;1 -1202;1348;1203;1 -1203;1348;1349;1 -1203;1349;1350;1 -1203;1350;1204;1 -1204;1350;1351;1 -1204;1351;1205;1 -1205;1351;1352;1 -1205;1352;1206;1 -1206;1352;1353;1 -1206;1353;1207;1 -1207;1353;1354;1 -1207;1354;1208;1 -1208;1354;1355;1 -1208;1355;1209;1 -1209;1355;1356;1 -1209;1356;1210;1 -1210;1356;1357;1 -1210;1357;1358;1 -1210;1358;1211;1 -1211;1358;1357;1 -1211;1357;1359;1 -1211;1359;1212;1 -1212;1359;1360;1 -1212;1360;1361;1 -1212;1361;1362;1 -1212;1362;1213;1 -1213;1362;1214;1 -1214;1362;1363;1 -1214;1363;1215;1 -1215;1363;1364;1 -1215;1364;1365;1 -1215;1365;1216;1 -1216;1365;1366;1 -1216;1366;1367;1 -1216;1367;1217;1 -1217;1367;1368;1 -1217;1368;1218;1 -1218;1368;1219;1 -1219;1368;1369;1 -1219;1369;1370;1 -1219;1370;1220;1 -1220;1370;1221;1 -1221;1370;1371;1 -1221;1371;1372;1 -1221;1372;1222;1 -1222;1372;1373;1 -1222;1373;1223;1 -1223;1373;1374;1 -1223;1374;1224;1 -1224;1374;1375;1 -1224;1375;1225;1 -1225;1375;1376;1 -1225;1376;1226;1 -1226;1376;1377;1 -1226;1377;1227;1 -1227;1377;1378;1 -1227;1378;1228;1 -1228;1378;1379;1 -1228;1379;1229;1 -1229;1379;1380;1 -1229;1380;1230;1 -1230;1380;1381;1 -1230;1381;1231;1 -1231;1381;1382;1 -1231;1382;1232;1 -1232;1382;1383;1 -1232;1383;1233;1 -1233;1383;1384;1 -1233;1384;1234;1 -1234;1384;1385;1 -1234;1385;1235;1 -1235;1385;1386;1 -1235;1386;1236;1 -1236;1386;1387;1 -1236;1387;1388;1 -1236;1388;1237;1 -1237;1388;1389;1 -1237;1389;1238;1 -1238;1389;1390;1 -1238;1390;1239;1 -1239;1390;1391;1 -1239;1391;1240;1 -1240;1391;1392;1 -1240;1392;1393;1 -1240;1393;1241;1 -1241;1393;1394;1 -1241;1394;1242;1 -1242;1394;1395;1 -1242;1395;1243;1 -1243;1395;1396;1 -1243;1396;1244;1 -1244;1396;1245;1 -1245;1396;1397;1 -1245;1397;1246;1 -1246;1397;1247;1 -1247;1397;1398;1 -1247;1398;1399;1 -1247;1399;1248;1 -1248;1399;1400;1 -1248;1400;1401;1 -1248;1401;1249;1 -1249;1401;1402;1 -1249;1402;1250;1 -1250;1402;1403;1 -1250;1403;1404;1 -1250;1404;1251;1 -1251;1404;1252;1 -1252;1404;1254;1 -1254;1404;1405;1 -1254;1405;1406;1 -1254;1406;1255;1 -1255;1406;1407;1 -1255;1407;1256;1 -1256;1407;1408;1 -1256;1408;1257;1 -1257;1408;1409;1 -1257;1409;1258;1 -1258;1409;1410;1 -1258;1410;1411;1 -1258;1411;1260;1 -1260;1411;1412;1 -1260;1412;1261;1 -1261;1412;1262;1 -1262;1412;1413;1 -1262;1413;1263;1 -1263;1413;1414;1 -1263;1414;1264;1 -1264;1414;1415;1 -1264;1415;1416;1 -1264;1416;1266;1 -1266;1416;1417;1 -1266;1417;1267;1 -1267;1417;1418;1 -1267;1418;1268;1 -1268;1418;1419;1 -1268;1419;1269;1 -1269;1419;1420;1 -1269;1420;1421;1 -1269;1421;1422;1 -1269;1422;1270;1 -1270;1422;1271;1 -1271;1422;1423;1 -1271;1423;1272;1 -1272;1423;1273;1 -1273;1423;1424;1 -1273;1424;1425;1 -1273;1425;1274;1 -1274;1425;1426;1 -1274;1426;1427;1 -1274;1427;1275;1 -1275;1427;1428;1 -1275;1428;1276;1 -1276;1428;1429;1 -1276;1429;1277;1 -1277;1429;1430;1 -1277;1430;1278;1 -1278;1430;1431;1 -1278;1431;1279;1 -1279;1431;1432;1 -1279;1432;1280;1 -1280;1432;1433;1 -1280;1433;1281;1 -1281;1433;1282;1 -1282;1433;1434;1 -1282;1434;1283;1 -1283;1434;1435;1 -1283;1435;1436;1 -1283;1436;1284;1 -1284;1436;1437;1 -1284;1437;1438;1 -1284;1438;1285;1 -1285;1438;1439;1 -1285;1439;1440;1 -1285;1440;1441;1 -1285;1441;1286;1 -1286;1441;1288;1 -1288;1441;1442;1 -1288;1442;1289;1 -1289;1442;1443;1 -1289;1443;1290;1 -1290;1443;1444;1 -1290;1444;1291;1 -1291;1444;1445;1 -1291;1445;1292;1 -1292;1445;1446;1 -1292;1446;1294;1 -1294;1446;1295;1 -1295;1446;1447;1 -1295;1447;1296;1 -1296;1447;1448;1 -1296;1448;1297;1 -1297;1448;1449;1 -1297;1449;1450;1 -1297;1450;1298;1 -1298;1450;1451;1 -1298;1451;1299;1 -1299;1451;1452;1 -1299;1452;1300;1 -1300;1452;1301;1 -1301;1452;1453;1 -1301;1453;1454;1 -1301;1454;1302;1 -1302;1454;1455;1 -1302;1455;1303;1 -1303;1455;1456;1 -1303;1456;1457;1 -1303;1457;1304;1 -1304;1457;1458;1 -1304;1458;1459;1 -1304;1459;1305;1 -1305;1459;1306;1 -1306;1459;1460;1 -1306;1460;1461;1 -1306;1461;1462;1 -1306;1462;1307;1 -1307;1462;1463;1 -1307;1463;1308;1 -1308;1463;1309;1 -1309;1463;1464;1 -1309;1464;1310;1 -1310;1464;1465;1 -1310;1465;1466;1 -1310;1466;1311;1 -1311;1466;1312;1 -1312;1466;1467;1 -1312;1467;1313;1 -1313;1467;1468;1 -1313;1468;1314;1 -1314;1468;1469;1 -1314;1469;1470;1 -1314;1470;1315;1 -1315;1470;1471;1 -1315;1471;1316;1 -1316;1471;1317;1 -1317;1471;1472;1 -1317;1472;1318;1 -1318;1472;1473;1 -1318;1473;1319;1 -1319;1473;1474;1 -1319;1474;1320;1 -1320;1474;1475;1 -1320;1475;1321;1 -1321;1475;1476;1 -1321;1476;1322;1 -1322;1476;1477;1 -1322;1477;1323;1 -1323;1477;1478;1 -1323;1478;1479;1 -1323;1479;1324;1 -1324;1479;1480;1 -1324;1480;1325;1 -1325;1480;1481;1 -1325;1481;1326;1 -1326;1481;1482;1 -1326;1482;1327;1 -1327;1482;1483;1 -1327;1483;1328;1 -1328;1483;1484;1 -1328;1484;1329;1 -1329;1484;1485;1 -1329;1485;1330;1 -1330;1485;1486;1 -1330;1486;1331;1 -1331;1486;1487;1 -1331;1487;1332;1 -1332;1487;1488;1 -1332;1488;1333;1 -1333;1488;1489;1 -1333;1489;1334;1 -1334;1489;1490;1 -1334;1490;1335;1 -1335;1490;1491;1 -1335;1491;1336;1 -1336;1491;1492;1 -1336;1492;1337;1 -1337;1492;1493;1 -1337;1493;1338;1 -1338;1493;1494;1 -1338;1494;1339;1 -1339;1494;1495;1 -1339;1495;1340;1 -1340;1495;1341;1 -1341;1495;1496;1 -1341;1496;1342;1 -1342;1496;1497;1 -1342;1497;1343;1 -1343;1497;1498;1 -1343;1498;1499;1 -1343;1499;1344;1 -1344;1499;1500;1 -1344;1500;1345;1 -1345;1500;1346;1 -1346;1500;1501;1 -1346;1501;1347;1 -1347;1501;1502;1 -1347;1502;1503;1 -1347;1503;1348;1 -1348;1503;1349;1 -1349;1503;1504;1 -1349;1504;1505;1 -1349;1505;1350;1 -1350;1505;1506;1 -1350;1506;1351;1 -1351;1506;1507;1 -1351;1507;1352;1 -1352;1507;1508;1 -1352;1508;1353;1 -1353;1508;1509;1 -1353;1509;1354;1 -1354;1509;1510;1 -1354;1510;1355;1 -1355;1510;1511;1 -1355;1511;1356;1 -1356;1511;1357;1 -1357;1511;1512;1 -1357;1512;1359;1 -1359;1512;1360;1 -1360;1512;1513;1 -1360;1513;1514;1 -1360;1514;1361;1 -1361;1514;1515;1 -1361;1515;1362;1 -1362;1515;1516;1 -1362;1516;1363;1 -1363;1516;1517;1 -1363;1517;1364;1 -1364;1517;1518;1 -1364;1518;1519;1 -1364;1519;1520;1 -1364;1520;1365;1 -1365;1520;1366;1 -1366;1520;1521;1 -1366;1521;1522;1 -1366;1522;1523;1 -1366;1523;1367;1 -1367;1523;1524;1 -1367;1524;1369;1 -1369;1524;1525;1 -1369;1525;1370;1 -1370;1525;1371;1 -1371;1525;1526;1 -1371;1526;1527;1 -1371;1527;1372;1 -1372;1527;1528;1 -1372;1528;1373;1 -1373;1528;1529;1 -1373;1529;1374;1 -1374;1529;1530;1 -1374;1530;1375;1 -1375;1530;1531;1 -1375;1531;1376;1 -1376;1531;1532;1 -1376;1532;1377;1 -1377;1532;1533;1 -1377;1533;1378;1 -1378;1533;1534;1 -1378;1534;1379;1 -1379;1534;1535;1 -1379;1535;1380;1 -1380;1535;1536;1 -1380;1536;1381;1 -1381;1536;1537;1 -1381;1537;1382;1 -1382;1537;1538;1 -1382;1538;1383;1 -1383;1538;1539;1 -1383;1539;1384;1 -1384;1539;1540;1 -1384;1540;1385;1 -1385;1540;1541;1 -1385;1541;1386;1 -1386;1541;1542;1 -1386;1542;1387;1 -1387;1542;1543;1 -1387;1543;1544;1 -1387;1544;1388;1 -1388;1544;1545;1 -1388;1545;1389;1 -1389;1545;1390;1 -1390;1545;1546;1 -1390;1546;1391;1 -1391;1546;1547;1 -1391;1547;1548;1 -1391;1548;1392;1 -1392;1548;1549;1 -1392;1549;1550;1 -1392;1550;1393;1 -1393;1550;1551;1 -1393;1551;1394;1 -1394;1551;1552;1 -1394;1552;1553;1 -1394;1553;1395;1 -1395;1553;1396;1 -1396;1553;1554;1 -1396;1554;1397;1 -1397;1554;1555;1 -1397;1555;1398;1 -1398;1555;1399;1 -1399;1555;1556;1 -1399;1556;1400;1 -1400;1556;1557;1 -1400;1557;1558;1 -1400;1558;1401;1 -1401;1558;1559;1 -1401;1559;1402;1 -1402;1559;1560;1 -1402;1560;1403;1 -1403;1560;1561;1 -1403;1561;1405;1 -1405;1561;1562;1 -1405;1562;1406;1 -1406;1562;1563;1 -1406;1563;1407;1 -1407;1563;1564;1 -1407;1564;1408;1 -1408;1564;1565;1 -1408;1565;1409;1 -1409;1565;1566;1 -1409;1566;1410;1 -1410;1566;1567;1 -1410;1567;1568;1 -1410;1568;1411;1 -1411;1568;1412;1 -1412;1568;1569;1 -1412;1569;1413;1 -1413;1569;1570;1 -1413;1570;1414;1 -1414;1570;1571;1 -1414;1571;1415;1 -1415;1571;1572;1 -1415;1572;1573;1 -1415;1573;1416;1 -1416;1573;1574;1 -1416;1574;1417;1 -1417;1574;1575;1 -1417;1575;1418;1 -1418;1575;1576;1 -1418;1576;1419;1 -1419;1576;1577;1 -1419;1577;1420;1 -1420;1577;1578;1 -1420;1578;1579;1 -1420;1579;1421;1 -1421;1579;1580;1 -1421;1580;1422;1 -1422;1580;1423;1 -1423;1580;1424;1 -1424;1580;1581;1 -1424;1581;1582;1 -1424;1582;1583;1 -1424;1583;1425;1 -1425;1583;1584;1 -1425;1584;1426;1 -1426;1584;1585;1 -1426;1585;1586;1 -1426;1586;1427;1 -1427;1586;1587;1 -1427;1587;1428;1 -1428;1587;1588;1 -1428;1588;1429;1 -1429;1588;1589;1 -1429;1589;1430;1 -1430;1589;1431;1 -1431;1589;1590;1 -1431;1590;1591;1 -1431;1591;1432;1 -1432;1591;1592;1 -1432;1592;1433;1 -1433;1592;1434;1 -1434;1592;1593;1 -1434;1593;1435;1 -1435;1593;1594;1 -1435;1594;1436;1 -1436;1594;1595;1 -1436;1595;1596;1 -1436;1596;1437;1 -1437;1596;1597;1 -1437;1597;1598;1 -1437;1598;1438;1 -1438;1598;1439;1 -1439;1598;1599;1 -1439;1599;1600;1 -1439;1600;1440;1 -1440;1600;1601;1 -1440;1601;1441;1 -1441;1601;1602;1 -1441;1602;1442;1 -1442;1602;1603;1 -1442;1603;1604;1 -1442;1604;1443;1 -1443;1604;1605;1 -1443;1605;1606;1 -1443;1606;1444;1 -1444;1606;1445;1 -1445;1606;1607;1 -1445;1607;1446;1 -1446;1607;1447;1 -1447;1607;1608;1 -1447;1608;1448;1 -1448;1608;1609;1 -1448;1609;1449;1 -1449;1609;1610;1 -1449;1610;1450;1 -1450;1610;1611;1 -1450;1611;1612;1 -1450;1612;1451;1 -1451;1612;1613;1 -1451;1613;1452;1 -1452;1613;1614;1 -1452;1614;1453;1 -1453;1614;1615;1 -1453;1615;1616;1 -1453;1616;1454;1 -1454;1616;1617;1 -1454;1617;1455;1 -1455;1617;1618;1 -1455;1618;1456;1 -1456;1618;1619;1 -1456;1619;1620;1 -1456;1620;1621;1 -1456;1621;1457;1 -1457;1621;1458;1 -1458;1621;1622;1 -1458;1622;1459;1 -1459;1622;1460;1 -1460;1622;1623;1 -1460;1623;1624;1 -1460;1624;1461;1 -1461;1624;1625;1 -1461;1625;1626;1 -1461;1626;1627;1 -1461;1627;1462;1 -1462;1627;1463;1 -1463;1627;1464;1 -1464;1627;1628;1 -1464;1628;1629;1 -1464;1629;1465;1 -1465;1629;1630;1 -1465;1630;1466;1 -1466;1630;1467;1 -1467;1630;1631;1 -1467;1631;1468;1 -1468;1631;1632;1 -1468;1632;1469;1 -1469;1632;1633;1 -1469;1633;1634;1 -1469;1634;1470;1 -1470;1634;1635;1 -1470;1635;1471;1 -1471;1635;1472;1 -1472;1635;1636;1 -1472;1636;1473;1 -1473;1636;1637;1 -1473;1637;1474;1 -1474;1637;1638;1 -1474;1638;1475;1 -1475;1638;1639;1 -1475;1639;1476;1 -1476;1639;1640;1 -1476;1640;1477;1 -1477;1640;1641;1 -1477;1641;1478;1 -1478;1641;1642;1 -1478;1642;1643;1 -1478;1643;1479;1 -1479;1643;1644;1 -1479;1644;1480;1 -1480;1644;1645;1 -1480;1645;1481;1 -1481;1645;1646;1 -1481;1646;1482;1 -1482;1646;1647;1 -1482;1647;1483;1 -1483;1647;1648;1 -1483;1648;1484;1 -1484;1648;1649;1 -1484;1649;1485;1 -1485;1649;1650;1 -1485;1650;1486;1 -1486;1650;1651;1 -1486;1651;1487;1 -1487;1651;1652;1 -1487;1652;1488;1 -1488;1652;1653;1 -1488;1653;1489;1 -1489;1653;1654;1 -1489;1654;1490;1 -1490;1654;1655;1 -1490;1655;1491;1 -1491;1655;1656;1 -1491;1656;1492;1 -1492;1656;1657;1 -1492;1657;1493;1 -1493;1657;1658;1 -1493;1658;1494;1 -1494;1658;1659;1 -1494;1659;1495;1 -1495;1659;1660;1 -1495;1660;1496;1 -1496;1660;1661;1 -1496;1661;1497;1 -1497;1661;1662;1 -1497;1662;1498;1 -1498;1662;1663;1 -1498;1663;1664;1 -1498;1664;1499;1 -1499;1664;1665;1 -1499;1665;1500;1 -1500;1665;1501;1 -1501;1665;1666;1 -1501;1666;1502;1 -1502;1666;1667;1 -1502;1667;1668;1 -1502;1668;1503;1 -1503;1668;1504;1 -1504;1668;1669;1 -1504;1669;1670;1 -1504;1670;1505;1 -1505;1670;1671;1 -1505;1671;1506;1 -1506;1671;1672;1 -1506;1672;1507;1 -1507;1672;1673;1 -1507;1673;1508;1 -1508;1673;1674;1 -1508;1674;1509;1 -1509;1674;1675;1 -1509;1675;1510;1 -1510;1675;1676;1 -1510;1676;1511;1 -1511;1676;1512;1 -1512;1676;1513;1 -1513;1676;1677;1 -1513;1677;1678;1 -1513;1678;1514;1 -1514;1678;1679;1 -1514;1679;1515;1 -1515;1679;1680;1 -1515;1680;1516;1 -1516;1680;1681;1 -1516;1681;1517;1 -1517;1681;1682;1 -1517;1682;1518;1 -1518;1682;1683;1 -1518;1683;1684;1 -1518;1684;1519;1 -1519;1684;1685;1 -1519;1685;1521;1 -1521;1685;1686;1 -1521;1686;1522;1 -1522;1686;1687;1 -1522;1687;1688;1 -1522;1688;1523;1 -1523;1688;1689;1 -1523;1689;1524;1 -1524;1689;1690;1 -1524;1690;1525;1 -1525;1690;1691;1 -1525;1691;1526;1 -1526;1691;1692;1 -1526;1692;1693;1 -1526;1693;1527;1 -1527;1693;1694;1 -1527;1694;1528;1 -1528;1694;1695;1 -1528;1695;1529;1 -1529;1695;1696;1 -1529;1696;1530;1 -1530;1696;1697;1 -1530;1697;1531;1 -1531;1697;1698;1 -1531;1698;1532;1 -1532;1698;1699;1 -1532;1699;1533;1 -1533;1699;1700;1 -1533;1700;1534;1 -1534;1700;1701;1 -1534;1701;1535;1 -1535;1701;1702;1 -1535;1702;1536;1 -1536;1702;1703;1 -1536;1703;1537;1 -1537;1703;1704;1 -1537;1704;1538;1 -1538;1704;1705;1 -1538;1705;1539;1 -1539;1705;1706;1 -1539;1706;1540;1 -1540;1706;1707;1 -1540;1707;1541;1 -1541;1707;1708;1 -1541;1708;1542;1 -1542;1708;1709;1 -1542;1709;1543;1 -1543;1709;1710;1 -1543;1710;1544;1 -1544;1710;1711;1 -1544;1711;1546;1 -1546;1711;1547;1 -1547;1711;1712;1 -1547;1712;1713;1 -1547;1713;1548;1 -1548;1713;1714;1 -1548;1714;1549;1 -1549;1714;1715;1 -1549;1715;1716;1 -1549;1716;1550;1 -1550;1716;1717;1 -1550;1717;1718;1 -1550;1718;1551;1 -1551;1718;1719;1 -1551;1719;1552;1 -1552;1719;1720;1 -1552;1720;1553;1 -1553;1720;1721;1 -1553;1721;1554;1 -1554;1721;1555;1 -1555;1721;1556;1 -1556;1721;1722;1 -1556;1722;1557;1 -1557;1722;1723;1 -1557;1723;1724;1 -1557;1724;1558;1 -1558;1724;1725;1 -1558;1725;1559;1 -1559;1725;1726;1 -1559;1726;1560;1 -1560;1726;1727;1 -1560;1727;1728;1 -1560;1728;1561;1 -1561;1728;1562;1 -1562;1728;1729;1 -1562;1729;1563;1 -1563;1729;1730;1 -1563;1730;1564;1 -1564;1730;1731;1 -1564;1731;1565;1 -1565;1731;1732;1 -1565;1732;1566;1 -1566;1732;1733;1 -1566;1733;1567;1 -1567;1733;1734;1 -1567;1734;1735;1 -1567;1735;1568;1 -1568;1735;1569;1 -1569;1735;1736;1 -1569;1736;1570;1 -1570;1736;1737;1 -1570;1737;1571;1 -1571;1737;1738;1 -1571;1738;1572;1 -1572;1738;1739;1 -1572;1739;1740;1 -1572;1740;1573;1 -1573;1740;1574;1 -1574;1740;1741;1 -1574;1741;1575;1 -1575;1741;1742;1 -1575;1742;1576;1 -1576;1742;1743;1 -1576;1743;1577;1 -1577;1743;1744;1 -1577;1744;1578;1 -1578;1744;1745;1 -1578;1745;1746;1 -1578;1746;1747;1 -1578;1747;1579;1 -1579;1747;1580;1 -1580;1747;1581;1 -1581;1747;1748;1 -1581;1748;1582;1 -1582;1748;1749;1 -1582;1749;1750;1 -1582;1750;1583;1 -1583;1750;1584;1 -1584;1750;1751;1 -1584;1751;1585;1 -1585;1751;1752;1 -1585;1752;1753;1 -1585;1753;1586;1 -1586;1753;1754;1 -1586;1754;1587;1 -1587;1754;1755;1 -1587;1755;1588;1 -1588;1755;1756;1 -1588;1756;1589;1 -1589;1756;1590;1 -1590;1756;1757;1 -1590;1757;1758;1 -1590;1758;1591;1 -1591;1758;1759;1 -1591;1759;1592;1 -1592;1759;1593;1 -1593;1759;1760;1 -1593;1760;1761;1 -1593;1761;1594;1 -1594;1761;1595;1 -1595;1761;1762;1 -1595;1762;1596;1 -1596;1762;1763;1 -1596;1763;1764;1 -1596;1764;1597;1 -1597;1764;1765;1 -1597;1765;1766;1 -1597;1766;1598;1 -1598;1766;1599;1 -1599;1766;1767;1 -1599;1767;1768;1 -1599;1768;1600;1 -1600;1768;1769;1 -1600;1769;1601;1 -1601;1769;1770;1 -1601;1770;1603;1 -1603;1770;1771;1 -1603;1771;1772;1 -1603;1772;1604;1 -1604;1772;1773;1 -1604;1773;1774;1 -1604;1774;1605;1 -1605;1774;1775;1 -1605;1775;1606;1 -1606;1775;1608;1 -1608;1775;1609;1 -1609;1775;1776;1 -1609;1776;1777;1 -1609;1777;1610;1 -1610;1777;1778;1 -1610;1778;1611;1 -1611;1778;1779;1 -1611;1779;1780;1 -1611;1780;1612;1 -1612;1780;1613;1 -1613;1780;1781;1 -1613;1781;1614;1 -1614;1781;1782;1 -1614;1782;1615;1 -1615;1782;1783;1 -1615;1783;1784;1 -1615;1784;1616;1 -1616;1784;1785;1 -1616;1785;1617;1 -1617;1785;1786;1 -1617;1786;1618;1 -1618;1786;1787;1 -1618;1787;1619;1 -1619;1787;1788;1 -1619;1788;1789;1 -1619;1789;1620;1 -1620;1789;1790;1 -1620;1790;1621;1 -1621;1790;1791;1 -1621;1791;1622;1 -1622;1791;1623;1 -1623;1791;1792;1 -1623;1792;1793;1 -1623;1793;1624;1 -1624;1793;1794;1 -1624;1794;1625;1 -1625;1794;1795;1 -1625;1795;1796;1 -1625;1796;1626;1 -1626;1796;1797;1 -1626;1797;1628;1 -1628;1797;1629;1 -1629;1797;1798;1 -1629;1798;1630;1 -1630;1798;1631;1 -1631;1798;1799;1 -1631;1799;1632;1 -1632;1799;1633;1 -1633;1799;1800;1 -1633;1800;1801;1 -1633;1801;1634;1 -1634;1801;1802;1 -1634;1802;1635;1 -1635;1802;1636;1 -1636;1802;1803;1 -1636;1803;1637;1 -1637;1803;1804;1 -1637;1804;1638;1 -1638;1804;1805;1 -1638;1805;1639;1 -1639;1805;1806;1 -1639;1806;1640;1 -1640;1806;1807;1 -1640;1807;1641;1 -1641;1807;1808;1 -1641;1808;1642;1 -1642;1808;1809;1 -1642;1809;1810;1 -1642;1810;1643;1 -1643;1810;1811;1 -1643;1811;1644;1 -1644;1811;1812;1 -1644;1812;1645;1 -1645;1812;1813;1 -1645;1813;1646;1 -1646;1813;1814;1 -1646;1814;1647;1 -1647;1814;1815;1 -1647;1815;1648;1 -1648;1815;1816;1 -1648;1816;1649;1 -1649;1816;1817;1 -1649;1817;1650;1 -1650;1817;1818;1 -1650;1818;1651;1 -1651;1818;1819;1 -1651;1819;1652;1 -1652;1819;1820;1 -1652;1820;1653;1 -1653;1820;1821;1 -1653;1821;1654;1 -1654;1821;1822;1 -1654;1822;1655;1 -1655;1822;1823;1 -1655;1823;1656;1 -1656;1823;1824;1 -1656;1824;1657;1 -1657;1824;1825;1 -1657;1825;1658;1 -1658;1825;1826;1 -1658;1826;1659;1 -1659;1826;1827;1 -1659;1827;1660;1 -1660;1827;1828;1 -1660;1828;1661;1 -1661;1828;1829;1 -1661;1829;1662;1 -1662;1829;1830;1 -1662;1830;1663;1 -1663;1830;1831;1 -1663;1831;1832;1 -1663;1832;1664;1 -1664;1832;1833;1 -1664;1833;1665;1 -1665;1833;1666;1 -1666;1833;1834;1 -1666;1834;1667;1 -1667;1834;1835;1 -1667;1835;1836;1 -1667;1836;1668;1 -1668;1836;1669;1 -1669;1836;1837;1 -1669;1837;1838;1 -1669;1838;1670;1 -1670;1838;1839;1 -1670;1839;1671;1 -1671;1839;1840;1 -1671;1840;1672;1 -1672;1840;1841;1 -1672;1841;1673;1 -1673;1841;1842;1 -1673;1842;1674;1 -1674;1842;1843;1 -1674;1843;1675;1 -1675;1843;1677;1 -1677;1843;1844;1 -1677;1844;1678;1 -1678;1844;1679;1 -1679;1844;1845;1 -1679;1845;1846;1 -1679;1846;1680;1 -1680;1846;1681;1 -1681;1846;1847;1 -1681;1847;1682;1 -1682;1847;1848;1 -1682;1848;1683;1 -1683;1848;1849;1 -1683;1849;1850;1 -1683;1850;1684;1 -1684;1850;1851;1 -1684;1851;1852;1 -1684;1852;1685;1 -1685;1852;1853;1 -1685;1853;1686;1 -1686;1853;1687;1 -1687;1853;1854;1 -1687;1854;1855;1 -1687;1855;1856;1 -1687;1856;1688;1 -1688;1856;1857;1 -1688;1857;1689;1 -1689;1857;1690;1 -1690;1857;1691;1 -1691;1857;1858;1 -1691;1858;1692;1 -1692;1858;1859;1 -1692;1859;1860;1 -1692;1860;1693;1 -1693;1860;1861;1 -1693;1861;1694;1 -1694;1861;1862;1 -1694;1862;1695;1 -1695;1862;1863;1 -1695;1863;1696;1 -1696;1863;1864;1 -1696;1864;1697;1 -1697;1864;1865;1 -1697;1865;1698;1 -1698;1865;1866;1 -1698;1866;1699;1 -1699;1866;1867;1 -1699;1867;1700;1 -1700;1867;1868;1 -1700;1868;1701;1 -1701;1868;1869;1 -1701;1869;1702;1 -1702;1869;1870;1 -1702;1870;1703;1 -1703;1870;1871;1 -1703;1871;1704;1 -1704;1871;1872;1 -1704;1872;1705;1 -1705;1872;1873;1 -1705;1873;1706;1 -1706;1873;1874;1 -1706;1874;1707;1 -1707;1874;1875;1 -1707;1875;1708;1 -1708;1875;1876;1 -1708;1876;1709;1 -1709;1876;1877;1 -1709;1877;1710;1 -1710;1877;1878;1 -1710;1878;1879;1 -1710;1879;1711;1 -1711;1879;1712;1 -1712;1879;1880;1 -1712;1880;1881;1 -1712;1881;1713;1 -1713;1881;1882;1 -1713;1882;1714;1 -1714;1882;1883;1 -1714;1883;1715;1 -1715;1883;1884;1 -1715;1884;1885;1 -1715;1885;1716;1 -1716;1885;1886;1 -1716;1886;1717;1 -1717;1886;1887;1 -1717;1887;1888;1 -1717;1888;1718;1 -1718;1888;1719;1 -1719;1888;1889;1 -1719;1889;1890;1 -1719;1890;1720;1 -1720;1890;1722;1 -1722;1890;1891;1 -1722;1891;1723;1 -1723;1891;1892;1 -1723;1892;1893;1 -1723;1893;1724;1 -1724;1893;1894;1 -1724;1894;1725;1 -1725;1894;1895;1 -1725;1895;1726;1 -1726;1895;1896;1 -1726;1896;1897;1 -1726;1897;1727;1 -1727;1897;1898;1 -1727;1898;1728;1 -1728;1898;1729;1 -1729;1898;1899;1 -1729;1899;1730;1 -1730;1899;1900;1 -1730;1900;1731;1 -1731;1900;1901;1 -1731;1901;1732;1 -1732;1901;1902;1 -1732;1902;1733;1 -1733;1902;1903;1 -1733;1903;1734;1 -1734;1903;1904;1 -1734;1904;1905;1 -1734;1905;1735;1 -1735;1905;1736;1 -1736;1905;1906;1 -1736;1906;1737;1 -1737;1906;1907;1 -1737;1907;1738;1 -1738;1907;1908;1 -1738;1908;1739;1 -1739;1908;1909;1 -1739;1909;1910;1 -1739;1910;1740;1 -1740;1910;1741;1 -1741;1910;1911;1 -1741;1911;1742;1 -1742;1911;1912;1 -1742;1912;1743;1 -1743;1912;1913;1 -1743;1913;1744;1 -1744;1913;1914;1 -1744;1914;1745;1 -1745;1914;1915;1 -1745;1915;1916;1 -1745;1916;1746;1 -1746;1916;1917;1 -1746;1917;1747;1 -1747;1917;1748;1 -1748;1917;1918;1 -1748;1918;1919;1 -1748;1919;1749;1 -1749;1919;1920;1 -1749;1920;1750;1 -1750;1920;1751;1 -1751;1920;1921;1 -1751;1921;1752;1 -1752;1921;1922;1 -1752;1922;1753;1 -1753;1922;1923;1 -1753;1923;1924;1 -1753;1924;1754;1 -1754;1924;1925;1 -1754;1925;1755;1 -1755;1925;1926;1 -1755;1926;1756;1 -1756;1926;1757;1 -1757;1926;1927;1 -1757;1927;1928;1 -1757;1928;1758;1 -1758;1928;1929;1 -1758;1929;1759;1 -1759;1929;1930;1 -1759;1930;1760;1 -1760;1930;1761;1 -1761;1930;1762;1 -1762;1930;1763;1 -1763;1930;1931;1 -1763;1931;1932;1 -1763;1932;1764;1 -1764;1932;1933;1 -1764;1933;1765;1 -1765;1933;1934;1 -1765;1934;1935;1 -1765;1935;1766;1 -1766;1935;1767;1 -1767;1935;1936;1 -1767;1936;1937;1 -1767;1937;1768;1 -1768;1937;1938;1 -1768;1938;1769;1 -1769;1938;1939;1 -1769;1939;1770;1 -1770;1939;1771;1 -1771;1939;1940;1 -1771;1940;1941;1 -1771;1941;1772;1 -1772;1941;1942;1 -1772;1942;1773;1 -1773;1942;1774;1 -1774;1942;1943;1 -1774;1943;1776;1 -1776;1943;1777;1 -1777;1943;1944;1 -1777;1944;1945;1 -1777;1945;1946;1 -1777;1946;1778;1 -1778;1946;1947;1 -1778;1947;1948;1 -1778;1948;1779;1 -1779;1948;1949;1 -1779;1949;1780;1 -1780;1949;1950;1 -1780;1950;1781;1 -1781;1950;1951;1 -1781;1951;1782;1 -1782;1951;1783;1 -1783;1951;1952;1 -1783;1952;1953;1 -1783;1953;1784;1 -1784;1953;1954;1 -1784;1954;1785;1 -1785;1954;1955;1 -1785;1955;1786;1 -1786;1955;1956;1 -1786;1956;1787;1 -1787;1956;1957;1 -1787;1957;1788;1 -1788;1957;1958;1 -1788;1958;1959;1 -1788;1959;1789;1 -1789;1959;1960;1 -1789;1960;1790;1 -1790;1960;1961;1 -1790;1961;1791;1 -1791;1961;1792;1 -1792;1961;1962;1 -1792;1962;1963;1 -1792;1963;1793;1 -1793;1963;1964;1 -1793;1964;1794;1 -1794;1964;1965;1 -1794;1965;1795;1 -1795;1965;1966;1 -1795;1966;1967;1 -1795;1967;1968;1 -1795;1968;1796;1 -1796;1968;1969;1 -1796;1969;1797;1 -1797;1969;1799;1 -1799;1969;1800;1 -1800;1969;1970;1 -1800;1970;1971;1 -1800;1971;1801;1 -1801;1971;1972;1 -1801;1972;1802;1 -1802;1972;1803;1 -1803;1972;1973;1 -1803;1973;1804;1 -1804;1973;1974;1 -1804;1974;1805;1 -1805;1974;1975;1 -1805;1975;1806;1 -1806;1975;1976;1 -1806;1976;1807;1 -1807;1976;1977;1 -1807;1977;1808;1 -1808;1977;1978;1 -1808;1978;1809;1 -1809;1978;1979;1 -1809;1979;1980;1 -1809;1980;1810;1 -1810;1980;1981;1 -1810;1981;1811;1 -1811;1981;1982;1 -1811;1982;1812;1 -1812;1982;1983;1 -1812;1983;1813;1 -1813;1983;1984;1 -1813;1984;1814;1 -1814;1984;1985;1 -1814;1985;1815;1 -1815;1985;1986;1 -1815;1986;1816;1 -1816;1986;1987;1 -1816;1987;1817;1 -1817;1987;1988;1 -1817;1988;1818;1 -1818;1988;1989;1 -1818;1989;1819;1 -1819;1989;1990;1 -1819;1990;1820;1 -1820;1990;1991;1 -1820;1991;1821;1 -1821;1991;1992;1 -1821;1992;1822;1 -1822;1992;1993;1 -1822;1993;1823;1 -1823;1993;1994;1 -1823;1994;1824;1 -1824;1994;1995;1 -1824;1995;1825;1 -1825;1995;1996;1 -1825;1996;1826;1 -1826;1996;1997;1 -1826;1997;1827;1 -1827;1997;1998;1 -1827;1998;1828;1 -1828;1998;1999;1 -1828;1999;1829;1 -1829;1999;2000;1 -1829;2000;1830;1 -1830;2000;2001;1 -1830;2001;1831;1 -1831;2001;2002;1 -1831;2002;2003;1 -1831;2003;1832;1 -1832;2003;2004;1 -1832;2004;1833;1 -1833;2004;1834;1 -1834;2004;2005;1 -1834;2005;1835;1 -1835;2005;2006;1 -1835;2006;2007;1 -1835;2007;1836;1 -1836;2007;1837;1 -1837;2007;2008;1 -1837;2008;2009;1 -1837;2009;1838;1 -1838;2009;2010;1 -1838;2010;1839;1 -1839;2010;2011;1 -1839;2011;1840;1 -1840;2011;2012;1 -1840;2012;1841;1 -1841;2012;2013;1 -1841;2013;2014;1 -1841;2014;1842;1 -1842;2014;1843;1 -1843;2014;1844;1 -1844;2014;2015;1 -1844;2015;1845;1 -1845;2015;2016;1 -1845;2016;1846;1 -1846;2016;1847;1 -1847;2016;2017;1 -1847;2017;1848;1 -1848;2017;2018;1 -1848;2018;1849;1 -1849;2018;2019;1 -1849;2019;1850;1 -1850;2019;2020;1 -1850;2020;2021;1 -1850;2021;1851;1 -1851;2021;2022;1 -1851;2022;2023;1 -1851;2023;2024;1 -1851;2024;1852;1 -1852;2024;1853;1 -1853;2024;2025;1 -1853;2025;2026;1 -1853;2026;1854;1 -1854;2026;2027;1 -1854;2027;1855;1 -1855;2027;2028;1 -1855;2028;1856;1 -1856;2028;2029;1 -1856;2029;1857;1 -1857;2029;1858;1 -1858;2029;2030;1 -1858;2030;1859;1 -1859;2030;2031;1 -1859;2031;2032;1 -1859;2032;1860;1 -1860;2032;2033;1 -1860;2033;1861;1 -1861;2033;2034;1 -1861;2034;1862;1 -1862;2034;2035;1 -1862;2035;1863;1 -1863;2035;2036;1 -1863;2036;1864;1 -1864;2036;2037;1 -1864;2037;1865;1 -1865;2037;2038;1 -1865;2038;1866;1 -1866;2038;2039;1 -1866;2039;1867;1 -1867;2039;2040;1 -1867;2040;1868;1 -1868;2040;2041;1 -1868;2041;1869;1 -1869;2041;2042;1 -1869;2042;1870;1 -1870;2042;2043;1 -1870;2043;1871;1 -1871;2043;2044;1 -1871;2044;1872;1 -1872;2044;2045;1 -1872;2045;1873;1 -1873;2045;2046;1 -1873;2046;1874;1 -1874;2046;2047;1 -1874;2047;1875;1 -1875;2047;2048;1 -1875;2048;1876;1 -1876;2048;2049;1 -1876;2049;1877;1 -1877;2049;2050;1 -1877;2050;1878;1 -1878;2050;2051;1 -1878;2051;2052;1 -1878;2052;1879;1 -1879;2052;1880;1 -1880;2052;2053;1 -1880;2053;2054;1 -1880;2054;1881;1 -1881;2054;2055;1 -1881;2055;1882;1 -1882;2055;2056;1 -1882;2056;1883;1 -1883;2056;2057;1 -1883;2057;1884;1 -1884;2057;2058;1 -1884;2058;2059;1 -1884;2059;1885;1 -1885;2059;2060;1 -1885;2060;1886;1 -1886;2060;2061;1 -1886;2061;1887;1 -1887;2061;2062;1 -1887;2062;1888;1 -1888;2062;2063;1 -1888;2063;1889;1 -1889;2063;2064;1 -1889;2064;1891;1 -1891;2064;2065;1 -1891;2065;1892;1 -1892;2065;2066;1 -1892;2066;2067;1 -1892;2067;1893;1 -1893;2067;2068;1 -1893;2068;1894;1 -1894;2068;2069;1 -1894;2069;2070;1 -1894;2070;1895;1 -1895;2070;2071;1 -1895;2071;1896;1 -1896;2071;2072;1 -1896;2072;1897;1 -1897;2072;2073;1 -1897;2073;1898;1 -1898;2073;1899;1 -1899;2073;2074;1 -1899;2074;1900;1 -1900;2074;2075;1 -1900;2075;1901;1 -1901;2075;2076;1 -1901;2076;1902;1 -1902;2076;2077;1 -1902;2077;1903;1 -1903;2077;2078;1 -1903;2078;1904;1 -1904;2078;2079;1 -1904;2079;2080;1 -1904;2080;1905;1 -1905;2080;1906;1 -1906;2080;2081;1 -1906;2081;1907;1 -1907;2081;2082;1 -1907;2082;1908;1 -1908;2082;2083;1 -1908;2083;1909;1 -1909;2083;2084;1 -1909;2084;2085;1 -1909;2085;1910;1 -1910;2085;1911;1 -1911;2085;2086;1 -1911;2086;1912;1 -1912;2086;2087;1 -1912;2087;1913;1 -1913;2087;2088;1 -1913;2088;1914;1 -1914;2088;2089;1 -1914;2089;1915;1 -1915;2089;2090;1 -1915;2090;2091;1 -1915;2091;1916;1 -1916;2091;2092;1 -1916;2092;1917;1 -1917;2092;1918;1 -1918;2092;2093;1 -1918;2093;2094;1 -1918;2094;2095;1 -1918;2095;1919;1 -1919;2095;1920;1 -1920;2095;1921;1 -1921;2095;2096;1 -1921;2096;2097;1 -1921;2097;1922;1 -1922;2097;2098;1 -1922;2098;2099;1 -1922;2099;1923;1 -1923;2099;2100;1 -1923;2100;1924;1 -1924;2100;2101;1 -1924;2101;1925;1 -1925;2101;2102;1 -1925;2102;1926;1 -1926;2102;1927;1 -1927;2102;2103;1 -1927;2103;2104;1 -1927;2104;1928;1 -1928;2104;2105;1 -1928;2105;1929;1 -1929;2105;1930;1 -1930;2105;1931;1 -1931;2105;2106;1 -1931;2106;1932;1 -1932;2106;2107;1 -1932;2107;2108;1 -1932;2108;1933;1 -1933;2108;2109;1 -1933;2109;1934;1 -1934;2109;2110;1 -1934;2110;2111;1 -1934;2111;1935;1 -1935;2111;1936;1 -1936;2111;2112;1 -1936;2112;2113;1 -1936;2113;1937;1 -1937;2113;2114;1 -1937;2114;1938;1 -1938;2114;2115;1 -1938;2115;2116;1 -1938;2116;1939;1 -1939;2116;1940;1 -1940;2116;2117;1 -1940;2117;2118;1 -1940;2118;1941;1 -1941;2118;2119;1 -1941;2119;1942;1 -1942;2119;1944;1 -1944;2119;2120;1 -1944;2120;1945;1 -1945;2120;2121;1 -1945;2121;2122;1 -1945;2122;2123;1 -1945;2123;1946;1 -1946;2123;2124;1 -1946;2124;1947;1 -1947;2124;2125;1 -1947;2125;2126;1 -1947;2126;1948;1 -1948;2126;2127;1 -1948;2127;1949;1 -1949;2127;2128;1 -1949;2128;1950;1 -1950;2128;2129;1 -1950;2129;1951;1 -1951;2129;1952;1 -1952;2129;2130;1 -1952;2130;2131;1 -1952;2131;1953;1 -1953;2131;2132;1 -1953;2132;1954;1 -1954;2132;2133;1 -1954;2133;1955;1 -1955;2133;2134;1 -1955;2134;1956;1 -1956;2134;2135;1 -1956;2135;1957;1 -1957;2135;2136;1 -1957;2136;1958;1 -1958;2136;2137;1 -1958;2137;2138;1 -1958;2138;1959;1 -1959;2138;2139;1 -1959;2139;1960;1 -1960;2139;2140;1 -1960;2140;1961;1 -1961;2140;1962;1 -1962;2140;2141;1 -1962;2141;2142;1 -1962;2142;1963;1 -1963;2142;2143;1 -1963;2143;1964;1 -1964;2143;2144;1 -1964;2144;1965;1 -1965;2144;2145;1 -1965;2145;2146;1 -1965;2146;1966;1 -1966;2146;1975;1 -1975;2146;1976;1 -1976;2146;2147;1 -1976;2147;1977;1 -1977;2147;2148;1 -1977;2148;1978;1 -1978;2148;2149;1 -1978;2149;1979;1 -1979;2149;2150;1 -1979;2150;2151;1 -1979;2151;1980;1 -1980;2151;2152;1 -1980;2152;1981;1 -1981;2152;2153;1 -1981;2153;1982;1 -1982;2153;2154;1 -1982;2154;1983;1 -1983;2154;2155;1 -1983;2155;1984;1 -1984;2155;2156;1 -1984;2156;1985;1 -1985;2156;2157;1 -1985;2157;1986;1 -1986;2157;2158;1 -1986;2158;1987;1 -1987;2158;2159;1 -1987;2159;1988;1 -1988;2159;2160;1 -1988;2160;1989;1 -1989;2160;2161;1 -1989;2161;1990;1 -1990;2161;2162;1 -1990;2162;1991;1 -1991;2162;2163;1 -1991;2163;1992;1 -1992;2163;2164;1 -1992;2164;1993;1 -1993;2164;2165;1 -1993;2165;1994;1 -1994;2165;2166;1 -1994;2166;1995;1 -1995;2166;2167;1 -1995;2167;1996;1 -1996;2167;2168;1 -1996;2168;1997;1 -1997;2168;2169;1 -1997;2169;1998;1 -1998;2169;2170;1 -1998;2170;1999;1 -1999;2170;2171;1 -1999;2171;2000;1 -2000;2171;2172;1 -2000;2172;2001;1 -2001;2172;2173;1 -2001;2173;2002;1 -2002;2173;2174;1 -2002;2174;2175;1 -2002;2175;2003;1 -2003;2175;2176;1 -2003;2176;2004;1 -2004;2176;2005;1 -2005;2176;2177;1 -2005;2177;2006;1 -2006;2177;2178;1 -2006;2178;2179;1 -2006;2179;2007;1 -2007;2179;2008;1 -2008;2179;2180;1 -2008;2180;2181;1 -2008;2181;2009;1 -2009;2181;2182;1 -2009;2182;2010;1 -2010;2182;2183;1 -2010;2183;2011;1 -2011;2183;2184;1 -2011;2184;2012;1 -2012;2184;2185;1 -2012;2185;2013;1 -2013;2185;2014;1 -2014;2185;2015;1 -2015;2185;2016;1 -2016;2185;2186;1 -2016;2186;2017;1 -2017;2186;2187;1 -2017;2187;2018;1 -2018;2187;2188;1 -2018;2188;2019;1 -2019;2188;2189;1 -2019;2189;2020;1 -2020;2189;2190;1 -2020;2190;2191;1 -2020;2191;2021;1 -2021;2191;2192;1 -2021;2192;2022;1 -2022;2192;2193;1 -2022;2193;2023;1 -2023;2193;2194;1 -2023;2194;2024;1 -2024;2194;2025;1 -2025;2194;2026;1 -2026;2194;2195;1 -2026;2195;2196;1 -2026;2196;2027;1 -2027;2196;2197;1 -2027;2197;2028;1 -2028;2197;2198;1 -2028;2198;2199;1 -2028;2199;2029;1 -2029;2199;2030;1 -2030;2199;2200;1 -2030;2200;2031;1 -2031;2200;2201;1 -2031;2201;2202;1 -2031;2202;2032;1 -2032;2202;2203;1 -2032;2203;2033;1 -2033;2203;2204;1 -2033;2204;2034;1 -2034;2204;2205;1 -2034;2205;2035;1 -2035;2205;2206;1 -2035;2206;2036;1 -2036;2206;2207;1 -2036;2207;2037;1 -2037;2207;2208;1 -2037;2208;2038;1 -2038;2208;2209;1 -2038;2209;2039;1 -2039;2209;2210;1 -2039;2210;2040;1 -2040;2210;2211;1 -2040;2211;2041;1 -2041;2211;2212;1 -2041;2212;2042;1 -2042;2212;2213;1 -2042;2213;2043;1 -2043;2213;2214;1 -2043;2214;2044;1 -2044;2214;2215;1 -2044;2215;2045;1 -2045;2215;2216;1 -2045;2216;2046;1 -2046;2216;2217;1 -2046;2217;2047;1 -2047;2217;2218;1 -2047;2218;2048;1 -2048;2218;2219;1 -2048;2219;2049;1 -2049;2219;2220;1 -2049;2220;2221;1 -2049;2221;2050;1 -2050;2221;2222;1 -2050;2222;2051;1 -2051;2222;2223;1 -2051;2223;2052;1 -2052;2223;2053;1 -2053;2223;2224;1 -2053;2224;2225;1 -2053;2225;2054;1 -2054;2225;2226;1 -2054;2226;2055;1 -2055;2226;2227;1 -2055;2227;2056;1 -2056;2227;2228;1 -2056;2228;2057;1 -2057;2228;2229;1 -2057;2229;2058;1 -2058;2229;2230;1 -2058;2230;2231;1 -2058;2231;2059;1 -2059;2231;2232;1 -2059;2232;2060;1 -2060;2232;2233;1 -2060;2233;2234;1 -2060;2234;2061;1 -2061;2234;2062;1 -2062;2234;2235;1 -2062;2235;2063;1 -2063;2235;2236;1 -2063;2236;2237;1 -2063;2237;2064;1 -2064;2237;2065;1 -2065;2237;2238;1 -2065;2238;2239;1 -2065;2239;2066;1 -2066;2239;2240;1 -2066;2240;2241;1 -2066;2241;2067;1 -2067;2241;2242;1 -2067;2242;2068;1 -2068;2242;2243;1 -2068;2243;2069;1 -2069;2243;2244;1 -2069;2244;2245;1 -2069;2245;2070;1 -2070;2245;2246;1 -2070;2246;2071;1 -2071;2246;2247;1 -2071;2247;2072;1 -2072;2247;2248;1 -2072;2248;2073;1 -2073;2248;2074;1 -2074;2248;2249;1 -2074;2249;2075;1 -2075;2249;2250;1 -2075;2250;2076;1 -2076;2250;2251;1 -2076;2251;2077;1 -2077;2251;2252;1 -2077;2252;2078;1 -2078;2252;2253;1 -2078;2253;2079;1 -2079;2253;2254;1 -2079;2254;2255;1 -2079;2255;2080;1 -2080;2255;2081;1 -2081;2255;2256;1 -2081;2256;2082;1 -2082;2256;2257;1 -2082;2257;2083;1 -2083;2257;2258;1 -2083;2258;2084;1 -2084;2258;2259;1 -2084;2259;2260;1 -2084;2260;2085;1 -2085;2260;2086;1 -2086;2260;2261;1 -2086;2261;2087;1 -2087;2261;2262;1 -2087;2262;2088;1 -2088;2262;2263;1 -2088;2263;2089;1 -2089;2263;2264;1 -2089;2264;2090;1 -2090;2264;2265;1 -2090;2265;2266;1 -2090;2266;2091;1 -2091;2266;2267;1 -2091;2267;2092;1 -2092;2267;2093;1 -2093;2267;2268;1 -2093;2268;2269;1 -2093;2269;2094;1 -2094;2269;2270;1 -2094;2270;2096;1 -2096;2270;2271;1 -2096;2271;2272;1 -2096;2272;2097;1 -2097;2272;2273;1 -2097;2273;2274;1 -2097;2274;2098;1 -2098;2274;2275;1 -2098;2275;2099;1 -2099;2275;2276;1 -2099;2276;2277;1 -2099;2277;2100;1 -2100;2277;2278;1 -2100;2278;2101;1 -2101;2278;2279;1 -2101;2279;2102;1 -2102;2279;2103;1 -2103;2279;2280;1 -2103;2280;2281;1 -2103;2281;2104;1 -2104;2281;2282;1 -2104;2282;2283;1 -2104;2283;2105;1 -2105;2283;2106;1 -2106;2283;2284;1 -2106;2284;2107;1 -2107;2284;2285;1 -2107;2285;2108;1 -2108;2285;2286;1 -2108;2286;2287;1 -2108;2287;2109;1 -2109;2287;2288;1 -2109;2288;2110;1 -2110;2288;2289;1 -2110;2289;2290;1 -2110;2290;2111;1 -2111;2290;2112;1 -2112;2290;2291;1 -2112;2291;2292;1 -2112;2292;2113;1 -2113;2292;2293;1 -2113;2293;2114;1 -2114;2293;2294;1 -2114;2294;2115;1 -2115;2294;2295;1 -2115;2295;2116;1 -2116;2295;2117;1 -2117;2295;2296;1 -2117;2296;2297;1 -2117;2297;2118;1 -2118;2297;2298;1 -2118;2298;2119;1 -2119;2298;2120;1 -2120;2298;2121;1 -2121;2298;2297;1 -2121;2297;2299;1 -2121;2299;2122;1 -2122;2299;2300;1 -2122;2300;2301;1 -2122;2301;2302;1 -2122;2302;2123;1 -2123;2302;2124;1 -2124;2302;2303;1 -2124;2303;2125;1 -2125;2303;2304;1 -2125;2304;2305;1 -2125;2305;2126;1 -2126;2305;2306;1 -2126;2306;2127;1 -2127;2306;2307;1 -2127;2307;2128;1 -2128;2307;2308;1 -2128;2308;2129;1 -2129;2308;2130;1 -2130;2308;2309;1 -2130;2309;2310;1 -2130;2310;2131;1 -2131;2310;2311;1 -2131;2311;2132;1 -2132;2311;2312;1 -2132;2312;2133;1 -2133;2312;2313;1 -2133;2313;2134;1 -2134;2313;2314;1 -2134;2314;2135;1 -2135;2314;2315;1 -2135;2315;2136;1 -2136;2315;2137;1 -2137;2315;2316;1 -2137;2316;2317;1 -2137;2317;2318;1 -2137;2318;2138;1 -2138;2318;2139;1 -2139;2318;2319;1 -2139;2319;2140;1 -2140;2319;2141;1 -2141;2319;2320;1 -2141;2320;2321;1 -2141;2321;2142;1 -2142;2321;2322;1 -2142;2322;2143;1 -2143;2322;2323;1 -2143;2323;2144;1 -2144;2323;2324;1 -2144;2324;2325;1 -2144;2325;2145;1 -2145;2325;2147;1 -2147;2325;2148;1 -2148;2325;2326;1 -2148;2326;2149;1 -2149;2326;2327;1 -2149;2327;2150;1 -2150;2327;2328;1 -2150;2328;2329;1 -2150;2329;2151;1 -2151;2329;2330;1 -2151;2330;2152;1 -2152;2330;2331;1 -2152;2331;2153;1 -2153;2331;2332;1 -2153;2332;2154;1 -2154;2332;2333;1 -2154;2333;2155;1 -2155;2333;2334;1 -2155;2334;2156;1 -2156;2334;2335;1 -2156;2335;2157;1 -2157;2335;2336;1 -2157;2336;2158;1 -2158;2336;2337;1 -2158;2337;2159;1 -2159;2337;2338;1 -2159;2338;2160;1 -2160;2338;2339;1 -2160;2339;2161;1 -2161;2339;2340;1 -2161;2340;2162;1 -2162;2340;2341;1 -2162;2341;2163;1 -2163;2341;2342;1 -2163;2342;2164;1 -2164;2342;2343;1 -2164;2343;2165;1 -2165;2343;2344;1 -2165;2344;2166;1 -2166;2344;2345;1 -2166;2345;2167;1 -2167;2345;2346;1 -2167;2346;2168;1 -2168;2346;2347;1 -2168;2347;2169;1 -2169;2347;2348;1 -2169;2348;2170;1 -2170;2348;2349;1 -2170;2349;2171;1 -2171;2349;2350;1 -2171;2350;2172;1 -2172;2350;2351;1 -2172;2351;2173;1 -2173;2351;2352;1 -2173;2352;2174;1 -2174;2352;2353;1 -2174;2353;2354;1 -2174;2354;2175;1 -2175;2354;2355;1 -2175;2355;2176;1 -2176;2355;2177;1 -2177;2355;2356;1 -2177;2356;2178;1 -2178;2356;2357;1 -2178;2357;2358;1 -2178;2358;2179;1 -2179;2358;2180;1 -2180;2358;2359;1 -2180;2359;2360;1 -2180;2360;2181;1 -2181;2360;2361;1 -2181;2361;2182;1 -2182;2361;2362;1 -2182;2362;2183;1 -2183;2362;2363;1 -2183;2363;2184;1 -2184;2363;2186;1 -2186;2363;2187;1 -2187;2363;2364;1 -2187;2364;2188;1 -2188;2364;2365;1 -2188;2365;2189;1 -2189;2365;2366;1 -2189;2366;2367;1 -2189;2367;2190;1 -2190;2367;2368;1 -2190;2368;2191;1 -2191;2368;2192;1 -2192;2368;2369;1 -2192;2369;2370;1 -2192;2370;2193;1 -2193;2370;2371;1 -2193;2371;2372;1 -2193;2372;2195;1 -2195;2372;2373;1 -2195;2373;2196;1 -2196;2373;2374;1 -2196;2374;2375;1 -2196;2375;2197;1 -2197;2375;2376;1 -2197;2376;2198;1 -2198;2376;2377;1 -2198;2377;2378;1 -2198;2378;2199;1 -2199;2378;2200;1 -2200;2378;2379;1 -2200;2379;2201;1 -2201;2379;2380;1 -2201;2380;2381;1 -2201;2381;2202;1 -2202;2381;2382;1 -2202;2382;2203;1 -2203;2382;2383;1 -2203;2383;2204;1 -2204;2383;2384;1 -2204;2384;2205;1 -2205;2384;2385;1 -2205;2385;2206;1 -2206;2385;2386;1 -2206;2386;2207;1 -2207;2386;2387;1 -2207;2387;2208;1 -2208;2387;2388;1 -2208;2388;2209;1 -2209;2388;2389;1 -2209;2389;2210;1 -2210;2389;2390;1 -2210;2390;2211;1 -2211;2390;2391;1 -2211;2391;2212;1 -2212;2391;2392;1 -2212;2392;2213;1 -2213;2392;2393;1 -2213;2393;2214;1 -2214;2393;2394;1 -2214;2394;2215;1 -2215;2394;2395;1 -2215;2395;2216;1 -2216;2395;2396;1 -2216;2396;2217;1 -2217;2396;2397;1 -2217;2397;2218;1 -2218;2397;2398;1 -2218;2398;2219;1 -2219;2398;2399;1 -2219;2399;2220;1 -2220;2399;2400;1 -2220;2400;2401;1 -2220;2401;2221;1 -2221;2401;2402;1 -2221;2402;2222;1 -2222;2402;2224;1 -2224;2402;2403;1 -2224;2403;2225;1 -2225;2403;2226;1 -2226;2403;2404;1 -2226;2404;2405;1 -2226;2405;2227;1 -2227;2405;2406;1 -2227;2406;2228;1 -2228;2406;2407;1 -2228;2407;2229;1 -2229;2407;2408;1 -2229;2408;2230;1 -2230;2408;2409;1 -2230;2409;2410;1 -2230;2410;2231;1 -2231;2410;2411;1 -2231;2411;2232;1 -2232;2411;2412;1 -2232;2412;2413;1 -2232;2413;2233;1 -2233;2413;2414;1 -2233;2414;2234;1 -2234;2414;2415;1 -2234;2415;2416;1 -2234;2416;2235;1 -2235;2416;2417;1 -2235;2417;2236;1 -2236;2417;2237;1 -2237;2417;2238;1 -2238;2417;2239;1 -2239;2417;2418;1 -2239;2418;2240;1 -2240;2418;2419;1 -2240;2419;2420;1 -2240;2420;2241;1 -2241;2420;2421;1 -2241;2421;2242;1 -2242;2421;2422;1 -2242;2422;2243;1 -2243;2422;2423;1 -2243;2423;2244;1 -2244;2423;2424;1 -2244;2424;2245;1 -2245;2424;2425;1 -2245;2425;2246;1 -2246;2425;2426;1 -2246;2426;2427;1 -2246;2427;2247;1 -2247;2427;2428;1 -2247;2428;2248;1 -2248;2428;2249;1 -2249;2428;2429;1 -2249;2429;2250;1 -2250;2429;2430;1 -2250;2430;2251;1 -2251;2430;2431;1 -2251;2431;2252;1 -2252;2431;2432;1 -2252;2432;2253;1 -2253;2432;2433;1 -2253;2433;2254;1 -2254;2433;2434;1 -2254;2434;2435;1 -2254;2435;2255;1 -2255;2435;2256;1 -2256;2435;2436;1 -2256;2436;2257;1 -2257;2436;2437;1 -2257;2437;2258;1 -2258;2437;2438;1 -2258;2438;2259;1 -2259;2438;2439;1 -2259;2439;2440;1 -2259;2440;2260;1 -2260;2440;2261;1 -2261;2440;2441;1 -2261;2441;2262;1 -2262;2441;2442;1 -2262;2442;2263;1 -2263;2442;2443;1 -2263;2443;2264;1 -2264;2443;2444;1 -2264;2444;2265;1 -2265;2444;2445;1 -2265;2445;2446;1 -2265;2446;2266;1 -2266;2446;2447;1 -2266;2447;2267;1 -2267;2447;2268;1 -2268;2447;2448;1 -2268;2448;2449;1 -2268;2449;2269;1 -2269;2449;2450;1 -2269;2450;2270;1 -2270;2450;2271;1 -2271;2450;2451;1 -2271;2451;2452;1 -2271;2452;2272;1 -2272;2452;2273;1 -2273;2452;2453;1 -2273;2453;2454;1 -2273;2454;2274;1 -2274;2454;2275;1 -2275;2454;2455;1 -2275;2455;2276;1 -2276;2455;2456;1 -2276;2456;2277;1 -2277;2456;2457;1 -2277;2457;2278;1 -2278;2457;2458;1 -2278;2458;2459;1 -2278;2459;2279;1 -2279;2459;2280;1 -2280;2459;2460;1 -2280;2460;2461;1 -2280;2461;2281;1 -2281;2461;2462;1 -2281;2462;2282;1 -2282;2462;2284;1 -2284;2462;2463;1 -2284;2463;2285;1 -2285;2463;2464;1 -2285;2464;2286;1 -2286;2464;2465;1 -2286;2465;2466;1 -2286;2466;2287;1 -2287;2466;2467;1 -2287;2467;2288;1 -2288;2467;2468;1 -2288;2468;2289;1 -2289;2468;2469;1 -2289;2469;2470;1 -2289;2470;2290;1 -2290;2470;2291;1 -2291;2470;2471;1 -2291;2471;2472;1 -2291;2472;2292;1 -2292;2472;2473;1 -2292;2473;2293;1 -2293;2473;2474;1 -2293;2474;2294;1 -2294;2474;2475;1 -2294;2475;2295;1 -2295;2475;2296;1 -2296;2475;2476;1 -2296;2476;2299;1 -2299;2476;2477;1 -2299;2477;2300;1 -2300;2477;2478;1 -2300;2478;2301;1 -2301;2478;2479;1 -2301;2479;2480;1 -2301;2480;2302;1 -2302;2480;2303;1 -2303;2480;2481;1 -2303;2481;2304;1 -2304;2481;2482;1 -2304;2482;2483;1 -2304;2483;2305;1 -2305;2483;2484;1 -2305;2484;2306;1 -2306;2484;2485;1 -2306;2485;2307;1 -2307;2485;2486;1 -2307;2486;2308;1 -2308;2486;2309;1 -2309;2486;2487;1 -2309;2487;2488;1 -2309;2488;2310;1 -2310;2488;2489;1 -2310;2489;2311;1 -2311;2489;2490;1 -2311;2490;2312;1 -2312;2490;2491;1 -2312;2491;2313;1 -2313;2491;2492;1 -2313;2492;2314;1 -2314;2492;2315;1 -2315;2492;2493;1 -2315;2493;2316;1 -2316;2493;2494;1 -2316;2494;2495;1 -2316;2495;2317;1 -2317;2495;2496;1 -2317;2496;2497;1 -2317;2497;2318;1 -2318;2497;2320;1 -2320;2497;2498;1 -2320;2498;2321;1 -2321;2498;2499;1 -2321;2499;2322;1 -2322;2499;2500;1 -2322;2500;2501;1 -2322;2501;2323;1 -2323;2501;2324;1 -2324;2501;2502;1 -2324;2502;2326;1 -2326;2502;2327;1 -2327;2502;2503;1 -2327;2503;2504;1 -2327;2504;2328;1 -2328;2504;2505;1 -2328;2505;2329;1 -2329;2505;2506;1 -2329;2506;2330;1 -2330;2506;2507;1 -2330;2507;2331;1 -2331;2507;2508;1 -2331;2508;2332;1 -2332;2508;2509;1 -2332;2509;2333;1 -2333;2509;2510;1 -2333;2510;2334;1 -2334;2510;2511;1 -2334;2511;2335;1 -2335;2511;2512;1 -2335;2512;2336;1 -2336;2512;2513;1 -2336;2513;2337;1 -2337;2513;2514;1 -2337;2514;2338;1 -2338;2514;2515;1 -2338;2515;2339;1 -2339;2515;2516;1 -2339;2516;2340;1 -2340;2516;2517;1 -2340;2517;2341;1 -2341;2517;2518;1 -2341;2518;2342;1 -2342;2518;2519;1 -2342;2519;2343;1 -2343;2519;2520;1 -2343;2520;2344;1 -2344;2520;2521;1 -2344;2521;2345;1 -2345;2521;2522;1 -2345;2522;2346;1 -2346;2522;2523;1 -2346;2523;2347;1 -2347;2523;2524;1 -2347;2524;2348;1 -2348;2524;2525;1 -2348;2525;2349;1 -2349;2525;2526;1 -2349;2526;2350;1 -2350;2526;2527;1 -2350;2527;2351;1 -2351;2527;2528;1 -2351;2528;2352;1 -2352;2528;2529;1 -2352;2529;2353;1 -2353;2529;2530;1 -2353;2530;2531;1 -2353;2531;2354;1 -2354;2531;2532;1 -2354;2532;2355;1 -2355;2532;2356;1 -2356;2532;2533;1 -2356;2533;2357;1 -2357;2533;2534;1 -2357;2534;2535;1 -2357;2535;2358;1 -2358;2535;2359;1 -2359;2535;2536;1 -2359;2536;2537;1 -2359;2537;2360;1 -2360;2537;2538;1 -2360;2538;2361;1 -2361;2538;2539;1 -2361;2539;2362;1 -2362;2539;2364;1 -2364;2539;2365;1 -2365;2539;2366;1 -2366;2539;2538;1 -2366;2538;2540;1 -2366;2540;2541;1 -2366;2541;2542;1 -2366;2542;2367;1 -2367;2542;2543;1 -2367;2543;2368;1 -2368;2543;2544;1 -2368;2544;2369;1 -2369;2544;2545;1 -2369;2545;2546;1 -2369;2546;2370;1 -2370;2546;2547;1 -2370;2547;2371;1 -2371;2547;2548;1 -2371;2548;2549;1 -2371;2549;2372;1 -2372;2549;2550;1 -2372;2550;2373;1 -2373;2550;2551;1 -2373;2551;2374;1 -2374;2551;2552;1 -2374;2552;2375;1 -2375;2552;2376;1 -2376;2552;2377;1 -2377;2552;2553;1 -2377;2553;2554;1 -2377;2554;2555;1 -2377;2555;2379;1 -2379;2555;2556;1 -2379;2556;2380;1 -2380;2556;2557;1 -2380;2557;2381;1 -2381;2557;2382;1 -2382;2557;2558;1 -2382;2558;2383;1 -2383;2558;2559;1 -2383;2559;2384;1 -2384;2559;2560;1 -2384;2560;2385;1 -2385;2560;2561;1 -2385;2561;2386;1 -2386;2561;2562;1 -2386;2562;2387;1 -2387;2562;2563;1 -2387;2563;2388;1 -2388;2563;2564;1 -2388;2564;2389;1 -2389;2564;2565;1 -2389;2565;2390;1 -2390;2565;2566;1 -2390;2566;2391;1 -2391;2566;2567;1 -2391;2567;2392;1 -2392;2567;2568;1 -2392;2568;2393;1 -2393;2568;2569;1 -2393;2569;2394;1 -2394;2569;2570;1 -2394;2570;2395;1 -2395;2570;2571;1 -2395;2571;2396;1 -2396;2571;2572;1 -2396;2572;2397;1 -2397;2572;2573;1 -2397;2573;2398;1 -2398;2573;2574;1 -2398;2574;2399;1 -2399;2574;2575;1 -2399;2575;2400;1 -2400;2575;2576;1 -2400;2576;2577;1 -2400;2577;2401;1 -2401;2577;2578;1 -2401;2578;2402;1 -2402;2578;2579;1 -2402;2579;2403;1 -2403;2579;2404;1 -2404;2579;2580;1 -2404;2580;2581;1 -2404;2581;2405;1 -2405;2581;2582;1 -2405;2582;2406;1 -2406;2582;2583;1 -2406;2583;2407;1 -2407;2583;2584;1 -2407;2584;2408;1 -2408;2584;2585;1 -2408;2585;2409;1 -2409;2585;2586;1 -2409;2586;2587;1 -2409;2587;2410;1 -2410;2587;2588;1 -2410;2588;2411;1 -2411;2588;2589;1 -2411;2589;2412;1 -2412;2589;2590;1 -2412;2590;2413;1 -2413;2590;2591;1 -2413;2591;2414;1 -2414;2591;2592;1 -2414;2592;2593;1 -2414;2593;2415;1 -2415;2593;2594;1 -2415;2594;2595;1 -2415;2595;2416;1 -2416;2595;2418;1 -2418;2595;2596;1 -2418;2596;2419;1 -2419;2596;2597;1 -2419;2597;2598;1 -2419;2598;2420;1 -2420;2598;2599;1 -2420;2599;2600;1 -2420;2600;2421;1 -2421;2600;2601;1 -2421;2601;2422;1 -2422;2601;2602;1 -2422;2602;2423;1 -2423;2602;2603;1 -2423;2603;2424;1 -2424;2603;2604;1 -2424;2604;2425;1 -2425;2604;2605;1 -2425;2605;2606;1 -2425;2606;2426;1 -2426;2606;2607;1 -2426;2607;2427;1 -2427;2607;2428;1 -2428;2607;2608;1 -2428;2608;2429;1 -2429;2608;2609;1 -2429;2609;2430;1 -2430;2609;2610;1 -2430;2610;2431;1 -2431;2610;2611;1 -2431;2611;2432;1 -2432;2611;2612;1 -2432;2612;2433;1 -2433;2612;2613;1 -2433;2613;2434;1 -2434;2613;2614;1 -2434;2614;2615;1 -2434;2615;2435;1 -2435;2615;2436;1 -2436;2615;2616;1 -2436;2616;2437;1 -2437;2616;2617;1 -2437;2617;2438;1 -2438;2617;2618;1 -2438;2618;2439;1 -2439;2618;2619;1 -2439;2619;2620;1 -2439;2620;2440;1 -2440;2620;2441;1 -2441;2620;2621;1 -2441;2621;2442;1 -2442;2621;2622;1 -2442;2622;2443;1 -2443;2622;2623;1 -2443;2623;2444;1 -2444;2623;2624;1 -2444;2624;2445;1 -2445;2624;2625;1 -2445;2625;2626;1 -2445;2626;2446;1 -2446;2626;2627;1 -2446;2627;2447;1 -2447;2627;2448;1 -2448;2627;2628;1 -2448;2628;2629;1 -2448;2629;2449;1 -2449;2629;2630;1 -2449;2630;2450;1 -2450;2630;2451;1 -2451;2630;2631;1 -2451;2631;2632;1 -2451;2632;2452;1 -2452;2632;2633;1 -2452;2633;2453;1 -2453;2633;2634;1 -2453;2634;2455;1 -2455;2634;2635;1 -2455;2635;2456;1 -2456;2635;2636;1 -2456;2636;2457;1 -2457;2636;2637;1 -2457;2637;2458;1 -2458;2637;2638;1 -2458;2638;2639;1 -2458;2639;2459;1 -2459;2639;2640;1 -2459;2640;2460;1 -2460;2640;2641;1 -2460;2641;2642;1 -2460;2642;2461;1 -2461;2642;2462;1 -2462;2642;2463;1 -2463;2642;2464;1 -2464;2642;2641;1 -2464;2641;2465;1 -2465;2641;2643;1 -2465;2643;2644;1 -2465;2644;2466;1 -2466;2644;2645;1 -2466;2645;2467;1 -2467;2645;2646;1 -2467;2646;2468;1 -2468;2646;2647;1 -2468;2647;2469;1 -2469;2647;2648;1 -2469;2648;2649;1 -2469;2649;2470;1 -2470;2649;2471;1 -2471;2649;2650;1 -2471;2650;2651;1 -2471;2651;2472;1 -2472;2651;2652;1 -2472;2652;2473;1 -2473;2652;2653;1 -2473;2653;2654;1 -2473;2654;2474;1 -2474;2654;2655;1 -2474;2655;2475;1 -2475;2655;2476;1 -2476;2655;2477;1 -2477;2655;2656;1 -2477;2656;2657;1 -2477;2657;2478;1 -2478;2657;2658;1 -2478;2658;2479;1 -2479;2658;2659;1 -2479;2659;2660;1 -2479;2660;2480;1 -2480;2660;2481;1 -2481;2660;2661;1 -2481;2661;2482;1 -2482;2661;2662;1 -2482;2662;2663;1 -2482;2663;2483;1 -2483;2663;2664;1 -2483;2664;2484;1 -2484;2664;2665;1 -2484;2665;2485;1 -2485;2665;2666;1 -2485;2666;2486;1 -2486;2666;2487;1 -2487;2666;2667;1 -2487;2667;2668;1 -2487;2668;2488;1 -2488;2668;2669;1 -2488;2669;2489;1 -2489;2669;2670;1 -2489;2670;2490;1 -2490;2670;2671;1 -2490;2671;2491;1 -2491;2671;2672;1 -2491;2672;2492;1 -2492;2672;2493;1 -2493;2672;2673;1 -2493;2673;2494;1 -2494;2673;2674;1 -2494;2674;2675;1 -2494;2675;2495;1 -2495;2675;2676;1 -2495;2676;2496;1 -2496;2676;2677;1 -2496;2677;2678;1 -2496;2678;2497;1 -2497;2678;2498;1 -2498;2678;2679;1 -2498;2679;2680;1 -2498;2680;2499;1 -2499;2680;2681;1 -2499;2681;2500;1 -2500;2681;2682;1 -2500;2682;2501;1 -2501;2682;2502;1 -2502;2682;2503;1 -2503;2682;2683;1 -2503;2683;2504;1 -2504;2683;2684;1 -2504;2684;2685;1 -2504;2685;2505;1 -2505;2685;2686;1 -2505;2686;2506;1 -2506;2686;2687;1 -2506;2687;2507;1 -2507;2687;2688;1 -2507;2688;2508;1 -2508;2688;2689;1 -2508;2689;2509;1 -2509;2689;2690;1 -2509;2690;2510;1 -2510;2690;2691;1 -2510;2691;2511;1 -2511;2691;2692;1 -2511;2692;2512;1 -2512;2692;2693;1 -2512;2693;2513;1 -2513;2693;2694;1 -2513;2694;2514;1 -2514;2694;2695;1 -2514;2695;2515;1 -2515;2695;2696;1 -2515;2696;2516;1 -2516;2696;2697;1 -2516;2697;2517;1 -2517;2697;2698;1 -2517;2698;2518;1 -2518;2698;2699;1 -2518;2699;2519;1 -2519;2699;2700;1 -2519;2700;2520;1 -2520;2700;2701;1 -2520;2701;2521;1 -2521;2701;2702;1 -2521;2702;2522;1 -2522;2702;2703;1 -2522;2703;2523;1 -2523;2703;2704;1 -2523;2704;2524;1 -2524;2704;2705;1 -2524;2705;2525;1 -2525;2705;2706;1 -2525;2706;2526;1 -2526;2706;2707;1 -2526;2707;2527;1 -2527;2707;2708;1 -2527;2708;2528;1 -2528;2708;2709;1 -2528;2709;2529;1 -2529;2709;2710;1 -2529;2710;2530;1 -2530;2710;2711;1 -2530;2711;2712;1 -2530;2712;2531;1 -2531;2712;2713;1 -2531;2713;2532;1 -2532;2713;2533;1 -2533;2713;2714;1 -2533;2714;2534;1 -2534;2714;2715;1 -2534;2715;2716;1 -2534;2716;2535;1 -2535;2716;2536;1 -2536;2716;2717;1 -2536;2717;2718;1 -2536;2718;2537;1 -2537;2718;2540;1 -2540;2718;2719;1 -2540;2719;2541;1 -2541;2719;2720;1 -2541;2720;2721;1 -2541;2721;2542;1 -2542;2721;2722;1 -2542;2722;2543;1 -2543;2722;2723;1 -2543;2723;2544;1 -2544;2723;2724;1 -2544;2724;2545;1 -2545;2724;2725;1 -2545;2725;2726;1 -2545;2726;2546;1 -2546;2726;2547;1 -2547;2726;2727;1 -2547;2727;2548;1 -2548;2727;2728;1 -2548;2728;2549;1 -2549;2728;2729;1 -2549;2729;2551;1 -2551;2729;2554;1 -2554;2729;2730;1 -2554;2730;2731;1 -2554;2731;2555;1 -2555;2731;2732;1 -2555;2732;2556;1 -2556;2732;2733;1 -2556;2733;2557;1 -2557;2733;2734;1 -2557;2734;2735;1 -2557;2735;2558;1 -2558;2735;2559;1 -2559;2735;2736;1 -2559;2736;2560;1 -2560;2736;2737;1 -2560;2737;2561;1 -2561;2737;2738;1 -2561;2738;2562;1 -2562;2738;2739;1 -2562;2739;2563;1 -2563;2739;2740;1 -2563;2740;2564;1 -2564;2740;2741;1 -2564;2741;2565;1 -2565;2741;2742;1 -2565;2742;2566;1 -2566;2742;2743;1 -2566;2743;2567;1 -2567;2743;2744;1 -2567;2744;2568;1 -2568;2744;2745;1 -2568;2745;2569;1 -2569;2745;2746;1 -2569;2746;2570;1 -2570;2746;2747;1 -2570;2747;2571;1 -2571;2747;2748;1 -2571;2748;2572;1 -2572;2748;2749;1 -2572;2749;2573;1 -2573;2749;2750;1 -2573;2750;2574;1 -2574;2750;2751;1 -2574;2751;2575;1 -2575;2751;2752;1 -2575;2752;2576;1 -2576;2752;2753;1 -2576;2753;2754;1 -2576;2754;2577;1 -2577;2754;2755;1 -2577;2755;2578;1 -2578;2755;2756;1 -2578;2756;2579;1 -2579;2756;2580;1 -2580;2756;2757;1 -2580;2757;2581;1 -2581;2757;2758;1 -2581;2758;2582;1 -2582;2758;2759;1 -2582;2759;2760;1 -2582;2760;2583;1 -2583;2760;2761;1 -2583;2761;2584;1 -2584;2761;2585;1 -2585;2761;2762;1 -2585;2762;2586;1 -2586;2762;2763;1 -2586;2763;2764;1 -2586;2764;2587;1 -2587;2764;2765;1 -2587;2765;2766;1 -2587;2766;2588;1 -2588;2766;2767;1 -2588;2767;2589;1 -2589;2767;2768;1 -2589;2768;2769;1 -2589;2769;2590;1 -2590;2769;2591;1 -2591;2769;2592;1 -2592;2769;2770;1 -2592;2770;2771;1 -2592;2771;2772;1 -2592;2772;2593;1 -2593;2772;2773;1 -2593;2773;2594;1 -2594;2773;2596;1 -2596;2773;2597;1 -2597;2773;2774;1 -2597;2774;2775;1 -2597;2775;2598;1 -2598;2775;2599;1 -2599;2775;2776;1 -2599;2776;2777;1 -2599;2777;2600;1 -2600;2777;2778;1 -2600;2778;2601;1 -2601;2778;2779;1 -2601;2779;2602;1 -2602;2779;2780;1 -2602;2780;2603;1 -2603;2780;2781;1 -2603;2781;2604;1 -2604;2781;2782;1 -2604;2782;2605;1 -2605;2782;2783;1 -2605;2783;2606;1 -2606;2783;2784;1 -2606;2784;2607;1 -2607;2784;2785;1 -2607;2785;2608;1 -2608;2785;2786;1 -2608;2786;2787;1 -2608;2787;2609;1 -2609;2787;2610;1 -2610;2787;2788;1 -2610;2788;2611;1 -2611;2788;2789;1 -2611;2789;2612;1 -2612;2789;2790;1 -2612;2790;2791;1 -2612;2791;2613;1 -2613;2791;2614;1 -2614;2791;2792;1 -2614;2792;2793;1 -2614;2793;2794;1 -2614;2794;2615;1 -2615;2794;2616;1 -2616;2794;2795;1 -2616;2795;2617;1 -2617;2795;2796;1 -2617;2796;2618;1 -2618;2796;2797;1 -2618;2797;2619;1 -2619;2797;2798;1 -2619;2798;2799;1 -2619;2799;2800;1 -2619;2800;2620;1 -2620;2800;2621;1 -2621;2800;2801;1 -2621;2801;2622;1 -2622;2801;2802;1 -2622;2802;2623;1 -2623;2802;2803;1 -2623;2803;2624;1 -2624;2803;2804;1 -2624;2804;2625;1 -2625;2804;2805;1 -2625;2805;2806;1 -2625;2806;2626;1 -2626;2806;2807;1 -2626;2807;2627;1 -2627;2807;2628;1 -2628;2807;2808;1 -2628;2808;2809;1 -2628;2809;2629;1 -2629;2809;2810;1 -2629;2810;2630;1 -2630;2810;2631;1 -2631;2810;2811;1 -2631;2811;2812;1 -2631;2812;2632;1 -2632;2812;2813;1 -2632;2813;2633;1 -2633;2813;2814;1 -2633;2814;2634;1 -2634;2814;2815;1 -2634;2815;2635;1 -2635;2815;2816;1 -2635;2816;2636;1 -2636;2816;2637;1 -2637;2816;2817;1 -2637;2817;2638;1 -2638;2817;2818;1 -2638;2818;2819;1 -2638;2819;2639;1 -2639;2819;2640;1 -2640;2819;2820;1 -2640;2820;2641;1 -2641;2820;2643;1 -2643;2820;2821;1 -2643;2821;2822;1 -2643;2822;2644;1 -2644;2822;2823;1 -2644;2823;2645;1 -2645;2823;2824;1 -2645;2824;2646;1 -2646;2824;2825;1 -2646;2825;2647;1 -2647;2825;2826;1 -2647;2826;2648;1 -2648;2826;2827;1 -2648;2827;2828;1 -2648;2828;2649;1 -2649;2828;2650;1 -2650;2828;2829;1 -2650;2829;2830;1 -2650;2830;2831;1 -2650;2831;2651;1 -2651;2831;2832;1 -2651;2832;2833;1 -2651;2833;2652;1 -2652;2833;2834;1 -2652;2834;2835;1 -2652;2835;2653;1 -2653;2835;2836;1 -2653;2836;2654;1 -2654;2836;2656;1 -2656;2836;2837;1 -2656;2837;2657;1 -2657;2837;2838;1 -2657;2838;2658;1 -2658;2838;2839;1 -2658;2839;2659;1 -2659;2839;2840;1 -2659;2840;2841;1 -2659;2841;2660;1 -2660;2841;2661;1 -2661;2841;2842;1 -2661;2842;2662;1 -2662;2842;2843;1 -2662;2843;2844;1 -2662;2844;2663;1 -2663;2844;2845;1 -2663;2845;2664;1 -2664;2845;2846;1 -2664;2846;2665;1 -2665;2846;2847;1 -2665;2847;2666;1 -2666;2847;2667;1 -2667;2847;2848;1 -2667;2848;2849;1 -2667;2849;2668;1 -2668;2849;2850;1 -2668;2850;2669;1 -2669;2850;2851;1 -2669;2851;2670;1 -2670;2851;2852;1 -2670;2852;2671;1 -2671;2852;2672;1 -2672;2852;2853;1 -2672;2853;2673;1 -2673;2853;2854;1 -2673;2854;2674;1 -2674;2854;2855;1 -2674;2855;2856;1 -2674;2856;2675;1 -2675;2856;2857;1 -2675;2857;2676;1 -2676;2857;2858;1 -2676;2858;2677;1 -2677;2858;2859;1 -2677;2859;2860;1 -2677;2860;2678;1 -2678;2860;2679;1 -2679;2860;2861;1 -2679;2861;2862;1 -2679;2862;2680;1 -2680;2862;2863;1 -2680;2863;2681;1 -2681;2863;2682;1 -2682;2863;2683;1 -2683;2863;2684;1 -2684;2863;2864;1 -2684;2864;2865;1 -2684;2865;2866;1 -2684;2866;2685;1 -2685;2866;2686;1 -2686;2866;2867;1 -2686;2867;2868;1 -2686;2868;2687;1 -2687;2868;2869;1 -2687;2869;2688;1 -2688;2869;2870;1 -2688;2870;2689;1 -2689;2870;2871;1 -2689;2871;2690;1 -2690;2871;2872;1 -2690;2872;2691;1 -2691;2872;2873;1 -2691;2873;2692;1 -2692;2873;2874;1 -2692;2874;2693;1 -2693;2874;2875;1 -2693;2875;2694;1 -2694;2875;2876;1 -2694;2876;2695;1 -2695;2876;2877;1 -2695;2877;2696;1 -2696;2877;2878;1 -2696;2878;2697;1 -2697;2878;2879;1 -2697;2879;2698;1 -2698;2879;2880;1 -2698;2880;2699;1 -2699;2880;2881;1 -2699;2881;2700;1 -2700;2881;2882;1 -2700;2882;2701;1 -2701;2882;2883;1 -2701;2883;2702;1 -2702;2883;2884;1 -2702;2884;2703;1 -2703;2884;2885;1 -2703;2885;2704;1 -2704;2885;2886;1 -2704;2886;2705;1 -2705;2886;2887;1 -2705;2887;2706;1 -2706;2887;2888;1 -2706;2888;2707;1 -2707;2888;2889;1 -2707;2889;2708;1 -2708;2889;2890;1 -2708;2890;2709;1 -2709;2890;2891;1 -2709;2891;2710;1 -2710;2891;2892;1 -2710;2892;2711;1 -2711;2892;2893;1 -2711;2893;2894;1 -2711;2894;2712;1 -2712;2894;2895;1 -2712;2895;2713;1 -2713;2895;2714;1 -2714;2895;2896;1 -2714;2896;2715;1 -2715;2896;2897;1 -2715;2897;2898;1 -2715;2898;2716;1 -2716;2898;2717;1 -2717;2898;2899;1 -2717;2899;2900;1 -2717;2900;2718;1 -2718;2900;2719;1 -2719;2900;2901;1 -2719;2901;2720;1 -2720;2901;2902;1 -2720;2902;2903;1 -2720;2903;2721;1 -2721;2903;2904;1 -2721;2904;2722;1 -2722;2904;2905;1 -2722;2905;2723;1 -2723;2905;2724;1 -2724;2905;2906;1 -2724;2906;2725;1 -2725;2906;2907;1 -2725;2907;2908;1 -2725;2908;2726;1 -2726;2908;2727;1 -2727;2908;2909;1 -2727;2909;2728;1 -2728;2909;2910;1 -2728;2910;2911;1 -2728;2911;2730;1 -2730;2911;2912;1 -2730;2912;2913;1 -2730;2913;2731;1 -2731;2913;2914;1 -2731;2914;2732;1 -2732;2914;2915;1 -2732;2915;2733;1 -2733;2915;2916;1 -2733;2916;2734;1 -2734;2916;2917;1 -2734;2917;2918;1 -2734;2918;2735;1 -2735;2918;2919;1 -2735;2919;2736;1 -2736;2919;2920;1 -2736;2920;2737;1 -2737;2920;2921;1 -2737;2921;2738;1 -2738;2921;2922;1 -2738;2922;2739;1 -2739;2922;2923;1 -2739;2923;2740;1 -2740;2923;2924;1 -2740;2924;2741;1 -2741;2924;2925;1 -2741;2925;2742;1 -2742;2925;2926;1 -2742;2926;2743;1 -2743;2926;2927;1 -2743;2927;2744;1 -2744;2927;2928;1 -2744;2928;2745;1 -2745;2928;2929;1 -2745;2929;2746;1 -2746;2929;2930;1 -2746;2930;2747;1 -2747;2930;2931;1 -2747;2931;2748;1 -2748;2931;2932;1 -2748;2932;2749;1 -2749;2932;2933;1 -2749;2933;2750;1 -2750;2933;2934;1 -2750;2934;2751;1 -2751;2934;2935;1 -2751;2935;2752;1 -2752;2935;2936;1 -2752;2936;2753;1 -2753;2936;2937;1 -2753;2937;2754;1 -2754;2937;2938;1 -2754;2938;2939;1 -2754;2939;2755;1 -2755;2939;2756;1 -2756;2939;2757;1 -2757;2939;2940;1 -2757;2940;2758;1 -2758;2940;2941;1 -2758;2941;2942;1 -2758;2942;2759;1 -2759;2942;2943;1 -2759;2943;2944;1 -2759;2944;2760;1 -2760;2944;2945;1 -2760;2945;2761;1 -2761;2945;2763;1 -2763;2945;2946;1 -2763;2946;2764;1 -2764;2946;2947;1 -2764;2947;2948;1 -2764;2948;2765;1 -2765;2948;2949;1 -2765;2949;2766;1 -2766;2949;2950;1 -2766;2950;2767;1 -2767;2950;2951;1 -2767;2951;2768;1 -2768;2951;2952;1 -2768;2952;2770;1 -2770;2952;2953;1 -2770;2953;2771;1 -2771;2953;2954;1 -2771;2954;2955;1 -2771;2955;2772;1 -2772;2955;2774;1 -2774;2955;2956;1 -2774;2956;2775;1 -2775;2956;2957;1 -2775;2957;2776;1 -2776;2957;2958;1 -2776;2958;2777;1 -2777;2958;2959;1 -2777;2959;2960;1 -2777;2960;2778;1 -2778;2960;2961;1 -2778;2961;2779;1 -2779;2961;2780;1 -2780;2961;2962;1 -2780;2962;2963;1 -2780;2963;2781;1 -2781;2963;2964;1 -2781;2964;2782;1 -2782;2964;2965;1 -2782;2965;2783;1 -2783;2965;2966;1 -2783;2966;2784;1 -2784;2966;2967;1 -2784;2967;2785;1 -2785;2967;2968;1 -2785;2968;2786;1 -2786;2968;2969;1 -2786;2969;2787;1 -2787;2969;2788;1 -2788;2969;2970;1 -2788;2970;2789;1 -2789;2970;2971;1 -2789;2971;2790;1 -2790;2971;2972;1 -2790;2972;2973;1 -2790;2973;2791;1 -2791;2973;2974;1 -2791;2974;2792;1 -2792;2974;2975;1 -2792;2975;2793;1 -2793;2975;2976;1 -2793;2976;2977;1 -2793;2977;2794;1 -2794;2977;2795;1 -2795;2977;2978;1 -2795;2978;2796;1 -2796;2978;2797;1 -2797;2978;2979;1 -2797;2979;2980;1 -2797;2980;2798;1 -2798;2980;2799;1 -2799;2980;2981;1 -2799;2981;2982;1 -2799;2982;2800;1 -2800;2982;2801;1 -2801;2982;2983;1 -2801;2983;2802;1 -2802;2983;2984;1 -2802;2984;2803;1 -2803;2984;2985;1 -2803;2985;2804;1 -2804;2985;2986;1 -2804;2986;2805;1 -2805;2986;2987;1 -2805;2987;2806;1 -2806;2987;2988;1 -2806;2988;2807;1 -2807;2988;2808;1 -2808;2988;2989;1 -2808;2989;2990;1 -2808;2990;2809;1 -2809;2990;2991;1 -2809;2991;2810;1 -2810;2991;2811;1 -2811;2991;2992;1 -2811;2992;2993;1 -2811;2993;2812;1 -2812;2993;2994;1 -2812;2994;2813;1 -2813;2994;2995;1 -2813;2995;2814;1 -2814;2995;2996;1 -2814;2996;2815;1 -2815;2996;2997;1 -2815;2997;2816;1 -2816;2997;2998;1 -2816;2998;2817;1 -2817;2998;2999;1 -2817;2999;2818;1 -2818;2999;3000;1 -2818;3000;2819;1 -2819;3000;3001;1 -2819;3001;2820;1 -2820;3001;3002;1 -2820;3002;2821;1 -2821;3002;3003;1 -2821;3003;2822;1 -2822;3003;3004;1 -2822;3004;2823;1 -2823;3004;3005;1 -2823;3005;3006;1 -2823;3006;2824;1 -2824;3006;3007;1 -2824;3007;2825;1 -2825;3007;3008;1 -2825;3008;2826;1 -2826;3008;3009;1 -2826;3009;2827;1 -2827;3009;3010;1 -2827;3010;2829;1 -2829;3010;3011;1 -2829;3011;2830;1 -2830;3011;3012;1 -2830;3012;2831;1 -2831;3012;2832;1 -2832;3012;3013;1 -2832;3013;3014;1 -2832;3014;2833;1 -2833;3014;3015;1 -2833;3015;2834;1 -2834;3015;3016;1 -2834;3016;2835;1 -2835;3016;3017;1 -2835;3017;2836;1 -2836;3017;2837;1 -2837;3017;3018;1 -2837;3018;2838;1 -2838;3018;3019;1 -2838;3019;2839;1 -2839;3019;3020;1 -2839;3020;2840;1 -2840;3020;3021;1 -2840;3021;3022;1 -2840;3022;2841;1 -2841;3022;2842;1 -2842;3022;3023;1 -2842;3023;2843;1 -2843;3023;3024;1 -2843;3024;3025;1 -2843;3025;2844;1 -2844;3025;3026;1 -2844;3026;2845;1 -2845;3026;3027;1 -2845;3027;2846;1 -2846;3027;3028;1 -2846;3028;2847;1 -2847;3028;2848;1 -2848;3028;3029;1 -2848;3029;3030;1 -2848;3030;2849;1 -2849;3030;3031;1 -2849;3031;2850;1 -2850;3031;3032;1 -2850;3032;2851;1 -2851;3032;3033;1 -2851;3033;2852;1 -2852;3033;3034;1 -2852;3034;2853;1 -2853;3034;3035;1 -2853;3035;2854;1 -2854;3035;3036;1 -2854;3036;2855;1 -2855;3036;3037;1 -2855;3037;2856;1 -2856;3037;3038;1 -2856;3038;2857;1 -2857;3038;3039;1 -2857;3039;2858;1 -2858;3039;3040;1 -2858;3040;2859;1 -2859;3040;3041;1 -2859;3041;3042;1 -2859;3042;2860;1 -2860;3042;2861;1 -2861;3042;3043;1 -2861;3043;3044;1 -2861;3044;2862;1 -2862;3044;2864;1 -2864;3044;3045;1 -2864;3045;2865;1 -2865;3045;3046;1 -2865;3046;2866;1 -2866;3046;2867;1 -2867;3046;3047;1 -2867;3047;3048;1 -2867;3048;3049;1 -2867;3049;2868;1 -2868;3049;2869;1 -2869;3049;3050;1 -2869;3050;2870;1 -2870;3050;3051;1 -2870;3051;2871;1 -2871;3051;3052;1 -2871;3052;2872;1 -2872;3052;3053;1 -2872;3053;2873;1 -2873;3053;3054;1 -2873;3054;2874;1 -2874;3054;3055;1 -2874;3055;2875;1 -2875;3055;3056;1 -2875;3056;2876;1 -2876;3056;3057;1 -2876;3057;2877;1 -2877;3057;3058;1 -2877;3058;2878;1 -2878;3058;3059;1 -2878;3059;2879;1 -2879;3059;3060;1 -2879;3060;2880;1 -2880;3060;3061;1 -2880;3061;2881;1 -2881;3061;3062;1 -2881;3062;2882;1 -2882;3062;3063;1 -2882;3063;2883;1 -2883;3063;3064;1 -2883;3064;2884;1 -2884;3064;3065;1 -2884;3065;2885;1 -2885;3065;3066;1 -2885;3066;2886;1 -2886;3066;3067;1 -2886;3067;2887;1 -2887;3067;3068;1 -2887;3068;2888;1 -2888;3068;3069;1 -2888;3069;2889;1 -2889;3069;3070;1 -2889;3070;2890;1 -2890;3070;3071;1 -2890;3071;2891;1 -2891;3071;3072;1 -2891;3072;2892;1 -2892;3072;3073;1 -2892;3073;2893;1 -2893;3073;3074;1 -2893;3074;3075;1 -2893;3075;2894;1 -2894;3075;3076;1 -2894;3076;2895;1 -2895;3076;2896;1 -2896;3076;3077;1 -2896;3077;2897;1 -2897;3077;3078;1 -2897;3078;3079;1 -2897;3079;2898;1 -2898;3079;2899;1 -2899;3079;3080;1 -2899;3080;3081;1 -2899;3081;2900;1 -2900;3081;2901;1 -2901;3081;3082;1 -2901;3082;2902;1 -2902;3082;3083;1 -2902;3083;3084;1 -2902;3084;2903;1 -2903;3084;3085;1 -2903;3085;2904;1 -2904;3085;3086;1 -2904;3086;2905;1 -2905;3086;3087;1 -2905;3087;2906;1 -2906;3087;3088;1 -2906;3088;2907;1 -2907;3088;3089;1 -2907;3089;3090;1 -2907;3090;2908;1 -2908;3090;2909;1 -2909;3090;3091;1 -2909;3091;2910;1 -2910;3091;3092;1 -2910;3092;3093;1 -2910;3093;3094;1 -2910;3094;2911;1 -2911;3094;2912;1 -2912;3094;3095;1 -2912;3095;3096;1 -2912;3096;2913;1 -2913;3096;3097;1 -2913;3097;2914;1 -2914;3097;3098;1 -2914;3098;2915;1 -2915;3098;3099;1 -2915;3099;2916;1 -2916;3099;3100;1 -2916;3100;3101;1 -2916;3101;2917;1 -2917;3101;3102;1 -2917;3102;3103;1 -2917;3103;2918;1 -2918;3103;3104;1 -2918;3104;2919;1 -2919;3104;2920;1 -2920;3104;3105;1 -2920;3105;2921;1 -2921;3105;2922;1 -2922;3105;3106;1 -2922;3106;2923;1 -2923;3106;3107;1 -2923;3107;2924;1 -2924;3107;3108;1 -2924;3108;2925;1 -2925;3108;3109;1 -2925;3109;2926;1 -2926;3109;3110;1 -2926;3110;2927;1 -2927;3110;3111;1 -2927;3111;2928;1 -2928;3111;3112;1 -2928;3112;2929;1 -2929;3112;3113;1 -2929;3113;2930;1 -2930;3113;3114;1 -2930;3114;2931;1 -2931;3114;3115;1 -2931;3115;2932;1 -2932;3115;3116;1 -2932;3116;2933;1 -2933;3116;3117;1 -2933;3117;2934;1 -2934;3117;3118;1 -2934;3118;2935;1 -2935;3118;3119;1 -2935;3119;2936;1 -2936;3119;3120;1 -2936;3120;2937;1 -2937;3120;3121;1 -2937;3121;3122;1 -2937;3122;2938;1 -2938;3122;3123;1 -2938;3123;2939;1 -2939;3123;2940;1 -2940;3123;2941;1 -2941;3123;3124;1 -2941;3124;2942;1 -2942;3124;3125;1 -2942;3125;3126;1 -2942;3126;2943;1 -2943;3126;3127;1 -2943;3127;3128;1 -2943;3128;2944;1 -2944;3128;3129;1 -2944;3129;2945;1 -2945;3129;2946;1 -2946;3129;3130;1 -2946;3130;2947;1 -2947;3130;3131;1 -2947;3131;3132;1 -2947;3132;2948;1 -2948;3132;3133;1 -2948;3133;3134;1 -2948;3134;2949;1 -2949;3134;3135;1 -2949;3135;2950;1 -2950;3135;3136;1 -2950;3136;2951;1 -2951;3136;3137;1 -2951;3137;3138;1 -2951;3138;2952;1 -2952;3138;3139;1 -2952;3139;2953;1 -2953;3139;3140;1 -2953;3140;3141;1 -2953;3141;2954;1 -2954;3141;3142;1 -2954;3142;3143;1 -2954;3143;2955;1 -2955;3143;2956;1 -2956;3143;3144;1 -2956;3144;2957;1 -2957;3144;3145;1 -2957;3145;3146;1 -2957;3146;2958;1 -2958;3146;3147;1 -2958;3147;2959;1 -2959;3147;3148;1 -2959;3148;3149;1 -2959;3149;2960;1 -2960;3149;2961;1 -2961;3149;3150;1 -2961;3150;2962;1 -2962;3150;3151;1 -2962;3151;3152;1 -2962;3152;2963;1 -2963;3152;3153;1 -2963;3153;2964;1 -2964;3153;3154;1 -2964;3154;2965;1 -2965;3154;3155;1 -2965;3155;2966;1 -2966;3155;3156;1 -2966;3156;2967;1 -2967;3156;3157;1 -2967;3157;2968;1 -2968;3157;3158;1 -2968;3158;2969;1 -2969;3158;3159;1 -2969;3159;2970;1 -2970;3159;3160;1 -2970;3160;2971;1 -2971;3160;3161;1 -2971;3161;2972;1 -2972;3161;3162;1 -2972;3162;2973;1 -2973;3162;3163;1 -2973;3163;2974;1 -2974;3163;3164;1 -2974;3164;2975;1 -2975;3164;3165;1 -2975;3165;2976;1 -2976;3165;3166;1 -2976;3166;3167;1 -2976;3167;2977;1 -2977;3167;2978;1 -2978;3167;3168;1 -2978;3168;2979;1 -2979;3168;3169;1 -2979;3169;2980;1 -2980;3169;3170;1 -2980;3170;2981;1 -2981;3170;3171;1 -2981;3171;3172;1 -2981;3172;2982;1 -2982;3172;3173;1 -2982;3173;2983;1 -2983;3173;3174;1 -2983;3174;2984;1 -2984;3174;2985;1 -2985;3174;3175;1 -2985;3175;2986;1 -2986;3175;3176;1 -2986;3176;3177;1 -2986;3177;3178;1 -2986;3178;2987;1 -2987;3178;3179;1 -2987;3179;2988;1 -2988;3179;2989;1 -2989;3179;3180;1 -2989;3180;3181;1 -2989;3181;2990;1 -2990;3181;3182;1 -2990;3182;2991;1 -2991;3182;2992;1 -2992;3182;3183;1 -2992;3183;3184;1 -2992;3184;2993;1 -2993;3184;3185;1 -2993;3185;2994;1 -2994;3185;3186;1 -2994;3186;2995;1 -2995;3186;3187;1 -2995;3187;2996;1 -2996;3187;3188;1 -2996;3188;2997;1 -2997;3188;2998;1 -2998;3188;3189;1 -2998;3189;3190;1 -2998;3190;2999;1 -2999;3190;3191;1 -2999;3191;3192;1 -2999;3192;3193;1 -2999;3193;3000;1 -3000;3193;3001;1 -3001;3193;3194;1 -3001;3194;3002;1 -3002;3194;3195;1 -3002;3195;3003;1 -3003;3195;3196;1 -3003;3196;3004;1 -3004;3196;3005;1 -3005;3196;3197;1 -3005;3197;3198;1 -3005;3198;3006;1 -3006;3198;3199;1 -3006;3199;3200;1 -3006;3200;3007;1 -3007;3200;3201;1 -3007;3201;3008;1 -3008;3201;3202;1 -3008;3202;3009;1 -3009;3202;3203;1 -3009;3203;3010;1 -3010;3203;3204;1 -3010;3204;3011;1 -3011;3204;3205;1 -3011;3205;3012;1 -3012;3205;3206;1 -3012;3206;3013;1 -3013;3206;3207;1 -3013;3207;3208;1 -3013;3208;3014;1 -3014;3208;3209;1 -3014;3209;3015;1 -3015;3209;3210;1 -3015;3210;3016;1 -3016;3210;3211;1 -3016;3211;3017;1 -3017;3211;3018;1 -3018;3211;3212;1 -3018;3212;3019;1 -3019;3212;3213;1 -3019;3213;3020;1 -3020;3213;3214;1 -3020;3214;3021;1 -3021;3214;3215;1 -3021;3215;3216;1 -3021;3216;3022;1 -3022;3216;3023;1 -3023;3216;3217;1 -3023;3217;3024;1 -3024;3217;3218;1 -3024;3218;3219;1 -3024;3219;3025;1 -3025;3219;3220;1 -3025;3220;3026;1 -3026;3220;3221;1 -3026;3221;3027;1 -3027;3221;3222;1 -3027;3222;3028;1 -3028;3222;3029;1 -3029;3222;3223;1 -3029;3223;3224;1 -3029;3224;3030;1 -3030;3224;3225;1 -3030;3225;3031;1 -3031;3225;3226;1 -3031;3226;3032;1 -3032;3226;3227;1 -3032;3227;3033;1 -3033;3227;3228;1 -3033;3228;3034;1 -3034;3228;3229;1 -3034;3229;3035;1 -3035;3229;3036;1 -3036;3229;3230;1 -3036;3230;3231;1 -3036;3231;3037;1 -3037;3231;3232;1 -3037;3232;3038;1 -3038;3232;3233;1 -3038;3233;3039;1 -3039;3233;3234;1 -3039;3234;3040;1 -3040;3234;3235;1 -3040;3235;3041;1 -3041;3235;3236;1 -3041;3236;3237;1 -3041;3237;3042;1 -3042;3237;3043;1 -3043;3237;3238;1 -3043;3238;3239;1 -3043;3239;3044;1 -3044;3239;3045;1 -3045;3239;3047;1 -3047;3239;3240;1 -3047;3240;3048;1 -3048;3240;3241;1 -3048;3241;3242;1 -3048;3242;3049;1 -3049;3242;3243;1 -3049;3243;3244;1 -3049;3244;3050;1 -3050;3244;3245;1 -3050;3245;3051;1 -3051;3245;3246;1 -3051;3246;3052;1 -3052;3246;3247;1 -3052;3247;3053;1 -3053;3247;3248;1 -3053;3248;3054;1 -3054;3248;3249;1 -3054;3249;3055;1 -3055;3249;3250;1 -3055;3250;3056;1 -3056;3250;3251;1 -3056;3251;3057;1 -3057;3251;3252;1 -3057;3252;3058;1 -3058;3252;3253;1 -3058;3253;3059;1 -3059;3253;3254;1 -3059;3254;3060;1 -3060;3254;3255;1 -3060;3255;3061;1 -3061;3255;3256;1 -3061;3256;3062;1 -3062;3256;3257;1 -3062;3257;3063;1 -3063;3257;3258;1 -3063;3258;3064;1 -3064;3258;3259;1 -3064;3259;3065;1 -3065;3259;3260;1 -3065;3260;3066;1 -3066;3260;3261;1 -3066;3261;3067;1 -3067;3261;3262;1 -3067;3262;3068;1 -3068;3262;3263;1 -3068;3263;3069;1 -3069;3263;3264;1 -3069;3264;3070;1 -3070;3264;3265;1 -3070;3265;3071;1 -3071;3265;3266;1 -3071;3266;3072;1 -3072;3266;3267;1 -3072;3267;3073;1 -3073;3267;3268;1 -3073;3268;3074;1 -3074;3268;3269;1 -3074;3269;3270;1 -3074;3270;3075;1 -3075;3270;3271;1 -3075;3271;3076;1 -3076;3271;3077;1 -3077;3271;3272;1 -3077;3272;3078;1 -3078;3272;3273;1 -3078;3273;3274;1 -3078;3274;3079;1 -3079;3274;3080;1 -3080;3274;3275;1 -3080;3275;3276;1 -3080;3276;3081;1 -3081;3276;3082;1 -3082;3276;3277;1 -3082;3277;3083;1 -3083;3277;3278;1 -3083;3278;3279;1 -3083;3279;3084;1 -3084;3279;3280;1 -3084;3280;3085;1 -3085;3280;3281;1 -3085;3281;3086;1 -3086;3281;3282;1 -3086;3282;3087;1 -3087;3282;3283;1 -3087;3283;3088;1 -3088;3283;3284;1 -3088;3284;3089;1 -3089;3284;3091;1 -3091;3284;3285;1 -3091;3285;3286;1 -3091;3286;3092;1 -3092;3286;3287;1 -3092;3287;3093;1 -3093;3287;3288;1 -3093;3288;3289;1 -3093;3289;3094;1 -3094;3289;3095;1 -3095;3289;3290;1 -3095;3290;3291;1 -3095;3291;3096;1 -3096;3291;3292;1 -3096;3292;3097;1 -3097;3292;3293;1 -3097;3293;3098;1 -3098;3293;3294;1 -3098;3294;3099;1 -3099;3294;3295;1 -3099;3295;3100;1 -3100;3295;3296;1 -3100;3296;3101;1 -3101;3296;3297;1 -3101;3297;3298;1 -3101;3298;3102;1 -3102;3298;3299;1 -3102;3299;3300;1 -3102;3300;3301;1 -3102;3301;3103;1 -3103;3301;3302;1 -3103;3302;3104;1 -3104;3302;3105;1 -3105;3302;3303;1 -3105;3303;3106;1 -3106;3303;3304;1 -3106;3304;3107;1 -3107;3304;3305;1 -3107;3305;3108;1 -3108;3305;3306;1 -3108;3306;3109;1 -3109;3306;3307;1 -3109;3307;3110;1 -3110;3307;3308;1 -3110;3308;3111;1 -3111;3308;3309;1 -3111;3309;3112;1 -3112;3309;3310;1 -3112;3310;3113;1 -3113;3310;3311;1 -3113;3311;3114;1 -3114;3311;3312;1 -3114;3312;3115;1 -3115;3312;3313;1 -3115;3313;3116;1 -3116;3313;3314;1 -3116;3314;3117;1 -3117;3314;3315;1 -3117;3315;3118;1 -3118;3315;3316;1 -3118;3316;3119;1 -3119;3316;3317;1 -3119;3317;3120;1 -3120;3317;3318;1 -3120;3318;3121;1 -3121;3318;3319;1 -3121;3319;3122;1 -3122;3319;3320;1 -3122;3320;3321;1 -3122;3321;3322;1 -3122;3322;3123;1 -3123;3322;3323;1 -3123;3323;3124;1 -3124;3323;3324;1 -3124;3324;3125;1 -3125;3324;3325;1 -3125;3325;3326;1 -3125;3326;3126;1 -3126;3326;3127;1 -3127;3326;3327;1 -3127;3327;3328;1 -3127;3328;3128;1 -3128;3328;3329;1 -3128;3329;3129;1 -3129;3329;3130;1 -3130;3329;3330;1 -3130;3330;3331;1 -3130;3331;3131;1 -3131;3331;3332;1 -3131;3332;3132;1 -3132;3332;3333;1 -3132;3333;3133;1 -3133;3333;3334;1 -3133;3334;3134;1 -3134;3334;3335;1 -3134;3335;3135;1 -3135;3335;3336;1 -3135;3336;3136;1 -3136;3336;3337;1 -3136;3337;3137;1 -3137;3337;3338;1 -3137;3338;3339;1 -3137;3339;3138;1 -3138;3339;3340;1 -3138;3340;3139;1 -3139;3340;3140;1 -3140;3340;3341;1 -3140;3341;3342;1 -3140;3342;3141;1 -3141;3342;3343;1 -3141;3343;3142;1 -3142;3343;3344;1 -3142;3344;3143;1 -3143;3344;3144;1 -3144;3344;3345;1 -3144;3345;3145;1 -3145;3345;3346;1 -3145;3346;3146;1 -3146;3346;3347;1 -3146;3347;3147;1 -3147;3347;3348;1 -3147;3348;3148;1 -3148;3348;3349;1 -3148;3349;3350;1 -3148;3350;3149;1 -3149;3350;3150;1 -3150;3350;3351;1 -3150;3351;3151;1 -3151;3351;3352;1 -3151;3352;3353;1 -3151;3353;3152;1 -3152;3353;3354;1 -3152;3354;3153;1 -3153;3354;3355;1 -3153;3355;3154;1 -3154;3355;3356;1 -3154;3356;3155;1 -3155;3356;3357;1 -3155;3357;3156;1 -3156;3357;3358;1 -3156;3358;3157;1 -3157;3358;3359;1 -3157;3359;3158;1 -3158;3359;3360;1 -3158;3360;3159;1 -3159;3360;3361;1 -3159;3361;3160;1 -3160;3361;3362;1 -3160;3362;3161;1 -3161;3362;3363;1 -3161;3363;3162;1 -3162;3363;3364;1 -3162;3364;3163;1 -3163;3364;3365;1 -3163;3365;3164;1 -3164;3365;3366;1 -3164;3366;3165;1 -3165;3366;3367;1 -3165;3367;3166;1 -3166;3367;3368;1 -3166;3368;3369;1 -3166;3369;3167;1 -3167;3369;3168;1 -3168;3369;3370;1 -3168;3370;3169;1 -3169;3370;3371;1 -3169;3371;3170;1 -3170;3371;3372;1 -3170;3372;3171;1 -3171;3372;3373;1 -3171;3373;3374;1 -3171;3374;3172;1 -3172;3374;3173;1 -3173;3374;3375;1 -3173;3375;3174;1 -3174;3375;3376;1 -3174;3376;3175;1 -3175;3376;3377;1 -3175;3377;3176;1 -3176;3377;3378;1 -3176;3378;3177;1 -3177;3378;3379;1 -3177;3379;3380;1 -3177;3380;3178;1 -3178;3380;3381;1 -3178;3381;3179;1 -3179;3381;3180;1 -3180;3381;3382;1 -3180;3382;3383;1 -3180;3383;3181;1 -3181;3383;3384;1 -3181;3384;3182;1 -3182;3384;3183;1 -3183;3384;3385;1 -3183;3385;3386;1 -3183;3386;3184;1 -3184;3386;3387;1 -3184;3387;3185;1 -3185;3387;3388;1 -3185;3388;3186;1 -3186;3388;3389;1 -3186;3389;3187;1 -3187;3389;3390;1 -3187;3390;3188;1 -3188;3390;3189;1 -3189;3390;3391;1 -3189;3391;3392;1 -3189;3392;3190;1 -3190;3392;3191;1 -3191;3392;3393;1 -3191;3393;3394;1 -3191;3394;3192;1 -3192;3394;3395;1 -3192;3395;3396;1 -3192;3396;3193;1 -3193;3396;3194;1 -3194;3396;3397;1 -3194;3397;3195;1 -3195;3397;3196;1 -3196;3397;3197;1 -3197;3397;3398;1 -3197;3398;3198;1 -3198;3398;3399;1 -3198;3399;3400;1 -3198;3400;3199;1 -3199;3400;3401;1 -3199;3401;3402;1 -3199;3402;3200;1 -3200;3402;3201;1 -3201;3402;3403;1 -3201;3403;3404;1 -3201;3404;3202;1 -3202;3404;3203;1 -3203;3404;3405;1 -3203;3405;3204;1 -3204;3405;3406;1 -3204;3406;3407;1 -3204;3407;3205;1 -3205;3407;3408;1 -3205;3408;3206;1 -3206;3408;3409;1 -3206;3409;3207;1 -3207;3409;3410;1 -3207;3410;3411;1 -3207;3411;3208;1 -3208;3411;3412;1 -3208;3412;3209;1 -3209;3412;3413;1 -3209;3413;3210;1 -3210;3413;3414;1 -3210;3414;3211;1 -3211;3414;3212;1 -3212;3414;3415;1 -3212;3415;3213;1 -3213;3415;3416;1 -3213;3416;3214;1 -3214;3416;3417;1 -3214;3417;3215;1 -3215;3417;3418;1 -3215;3418;3419;1 -3215;3419;3216;1 -3216;3419;3217;1 -3217;3419;3420;1 -3217;3420;3218;1 -3218;3420;3421;1 -3218;3421;3422;1 -3218;3422;3219;1 -3219;3422;3423;1 -3219;3423;3220;1 -3220;3423;3424;1 -3220;3424;3221;1 -3221;3424;3425;1 -3221;3425;3222;1 -3222;3425;3223;1 -3223;3425;3426;1 -3223;3426;3427;1 -3223;3427;3224;1 -3224;3427;3428;1 -3224;3428;3225;1 -3225;3428;3429;1 -3225;3429;3226;1 -3226;3429;3430;1 -3226;3430;3227;1 -3227;3430;3431;1 -3227;3431;3228;1 -3228;3431;3432;1 -3228;3432;3229;1 -3229;3432;3230;1 -3230;3432;3433;1 -3230;3433;3434;1 -3230;3434;3231;1 -3231;3434;3435;1 -3231;3435;3232;1 -3232;3435;3436;1 -3232;3436;3233;1 -3233;3436;3437;1 -3233;3437;3234;1 -3234;3437;3438;1 -3234;3438;3235;1 -3235;3438;3439;1 -3235;3439;3236;1 -3236;3439;3440;1 -3236;3440;3441;1 -3236;3441;3237;1 -3237;3441;3238;1 -3238;3441;3442;1 -3238;3442;3240;1 -3240;3442;3241;1 -3241;3442;3443;1 -3241;3443;3444;1 -3241;3444;3242;1 -3242;3444;3445;1 -3242;3445;3446;1 -3242;3446;3243;1 -3243;3446;3244;1 -3244;3446;3447;1 -3244;3447;3245;1 -3245;3447;3246;1 -3246;3447;3448;1 -3246;3448;3247;1 -3247;3448;3449;1 -3247;3449;3248;1 -3248;3449;3450;1 -3248;3450;3451;1 -3248;3451;3249;1 -3249;3451;3452;1 -3249;3452;3250;1 -3250;3452;3453;1 -3250;3453;3251;1 -3251;3453;3454;1 -3251;3454;3252;1 -3252;3454;3455;1 -3252;3455;3253;1 -3253;3455;3254;1 -3254;3455;3456;1 -3254;3456;3457;1 -3254;3457;3255;1 -3255;3457;3458;1 -3255;3458;3256;1 -3256;3458;3459;1 -3256;3459;3257;1 -3257;3459;3460;1 -3257;3460;3258;1 -3258;3460;3461;1 -3258;3461;3259;1 -3259;3461;3462;1 -3259;3462;3260;1 -3260;3462;3463;1 -3260;3463;3261;1 -3261;3463;3464;1 -3261;3464;3262;1 -3262;3464;3465;1 -3262;3465;3263;1 -3263;3465;3466;1 -3263;3466;3264;1 -3264;3466;3467;1 -3264;3467;3265;1 -3265;3467;3266;1 -3266;3467;3468;1 -3266;3468;3469;1 -3266;3469;3267;1 -3267;3469;3470;1 -3267;3470;3268;1 -3268;3470;3471;1 -3268;3471;3269;1 -3269;3471;3472;1 -3269;3472;3270;1 -3270;3472;3473;1 -3270;3473;3271;1 -3271;3473;3272;1 -3272;3473;3474;1 -3272;3474;3273;1 -3273;3474;3475;1 -3273;3475;3476;1 -3273;3476;3274;1 -3274;3476;3275;1 -3275;3476;3477;1 -3275;3477;3478;1 -3275;3478;3276;1 -3276;3478;3277;1 -3277;3478;3479;1 -3277;3479;3278;1 -3278;3479;3480;1 -3278;3480;3481;1 -3278;3481;3279;1 -3279;3481;3482;1 -3279;3482;3280;1 -3280;3482;3281;1 -3281;3482;3483;1 -3281;3483;3484;1 -3281;3484;3282;1 -3282;3484;3485;1 -3282;3485;3283;1 -3283;3485;3284;1 -3284;3485;3285;1 -3285;3485;3486;1 -3285;3486;3286;1 -3286;3486;3487;1 -3286;3487;3488;1 -3286;3488;3287;1 -3287;3488;3489;1 -3287;3489;3288;1 -3288;3489;3490;1 -3288;3490;3491;1 -3288;3491;3289;1 -3289;3491;3290;1 -3290;3491;3492;1 -3290;3492;3493;1 -3290;3493;3291;1 -3291;3493;3494;1 -3291;3494;3292;1 -3292;3494;3495;1 -3292;3495;3293;1 -3293;3495;3496;1 -3293;3496;3294;1 -3294;3496;3497;1 -3294;3497;3295;1 -3295;3497;3498;1 -3295;3498;3296;1 -3296;3498;3499;1 -3296;3499;3297;1 -3297;3499;3500;1 -3297;3500;3501;1 -3297;3501;3298;1 -3298;3501;3502;1 -3298;3502;3299;1 -3299;3502;3503;1 -3299;3503;3504;1 -3299;3504;3505;1 -3299;3505;3300;1 -3300;3505;3506;1 -3300;3506;3301;1 -3301;3506;3302;1 -3302;3506;3303;1 -3303;3506;3507;1 -3303;3507;3304;1 -3304;3507;3508;1 -3304;3508;3305;1 -3305;3508;3509;1 -3305;3509;3306;1 -3306;3509;3510;1 -3306;3510;3307;1 -3307;3510;3511;1 -3307;3511;3308;1 -3308;3511;3512;1 -3308;3512;3309;1 -3309;3512;3513;1 -3309;3513;3310;1 -3310;3513;3514;1 -3310;3514;3311;1 -3311;3514;3515;1 -3311;3515;3312;1 -3312;3515;3516;1 -3312;3516;3313;1 -3313;3516;3517;1 -3313;3517;3314;1 -3314;3517;3518;1 -3314;3518;3315;1 -3315;3518;3519;1 -3315;3519;3316;1 -3316;3519;3520;1 -3316;3520;3317;1 -3317;3520;3521;1 -3317;3521;3318;1 -3318;3521;3522;1 -3318;3522;3319;1 -3319;3522;3523;1 -3319;3523;3524;1 -3319;3524;3320;1 -3320;3524;3525;1 -3320;3525;3321;1 -3321;3525;3526;1 -3321;3526;3527;1 -3321;3527;3322;1 -3322;3527;3323;1 -3323;3527;3528;1 -3323;3528;3324;1 -3324;3528;3529;1 -3324;3529;3325;1 -3325;3529;3530;1 -3325;3530;3327;1 -3327;3530;3531;1 -3327;3531;3328;1 -3328;3531;3532;1 -3328;3532;3329;1 -3329;3532;3330;1 -3330;3532;3533;1 -3330;3533;3534;1 -3330;3534;3331;1 -3331;3534;3535;1 -3331;3535;3332;1 -3332;3535;3536;1 -3332;3536;3333;1 -3333;3536;3537;1 -3333;3537;3538;1 -3333;3538;3334;1 -3334;3538;3539;1 -3334;3539;3540;1 -3334;3540;3335;1 -3335;3540;3336;1 -3336;3540;3541;1 -3336;3541;3337;1 -3337;3541;3542;1 -3337;3542;3338;1 -3338;3542;3543;1 -3338;3543;3544;1 -3338;3544;3339;1 -3339;3544;3545;1 -3339;3545;3340;1 -3340;3545;3341;1 -3341;3545;3546;1 -3341;3546;3342;1 -3342;3546;3547;1 -3342;3547;3343;1 -3343;3547;3548;1 -3343;3548;3344;1 -3344;3548;3345;1 -3345;3548;3549;1 -3345;3549;3346;1 -3346;3549;3550;1 -3346;3550;3551;1 -3346;3551;3347;1 -3347;3551;3348;1 -3348;3551;3552;1 -3348;3552;3349;1 -3349;3552;3553;1 -3349;3553;3350;1 -3350;3553;3554;1 -3350;3554;3351;1 -3351;3554;3555;1 -3351;3555;3352;1 -3352;3555;3556;1 -3352;3556;3557;1 -3352;3557;3353;1 -3353;3557;3558;1 -3353;3558;3354;1 -3354;3558;3559;1 -3354;3559;3355;1 -3355;3559;3560;1 -3355;3560;3356;1 -3356;3560;3561;1 -3356;3561;3357;1 -3357;3561;3562;1 -3357;3562;3358;1 -3358;3562;3563;1 -3358;3563;3359;1 -3359;3563;3564;1 -3359;3564;3360;1 -3360;3564;3565;1 -3360;3565;3361;1 -3361;3565;3566;1 -3361;3566;3362;1 -3362;3566;3567;1 -3362;3567;3363;1 -3363;3567;3568;1 -3363;3568;3364;1 -3364;3568;3569;1 -3364;3569;3365;1 -3365;3569;3570;1 -3365;3570;3366;1 -3366;3570;3571;1 -3366;3571;3367;1 -3367;3571;3572;1 -3367;3572;3368;1 -3368;3572;3573;1 -3368;3573;3574;1 -3368;3574;3369;1 -3369;3574;3370;1 -3370;3574;3575;1 -3370;3575;3371;1 -3371;3575;3576;1 -3371;3576;3372;1 -3372;3576;3577;1 -3372;3577;3373;1 -3373;3577;3578;1 -3373;3578;3579;1 -3373;3579;3374;1 -3374;3579;3375;1 -3375;3579;3580;1 -3375;3580;3376;1 -3376;3580;3581;1 -3376;3581;3377;1 -3377;3581;3582;1 -3377;3582;3378;1 -3378;3582;3583;1 -3378;3583;3379;1 -3379;3583;3584;1 -3379;3584;3585;1 -3379;3585;3380;1 -3380;3585;3586;1 -3380;3586;3381;1 -3381;3586;3382;1 -3382;3586;3587;1 -3382;3587;3588;1 -3382;3588;3383;1 -3383;3588;3589;1 -3383;3589;3384;1 -3384;3589;3385;1 -3385;3589;3590;1 -3385;3590;3591;1 -3385;3591;3386;1 -3386;3591;3592;1 -3386;3592;3387;1 -3387;3592;3593;1 -3387;3593;3388;1 -3388;3593;3594;1 -3388;3594;3389;1 -3389;3594;3595;1 -3389;3595;3390;1 -3390;3595;3391;1 -3391;3595;3596;1 -3391;3596;3597;1 -3391;3597;3392;1 -3392;3597;3393;1 -3393;3597;3598;1 -3393;3598;3394;1 -3394;3598;3599;1 -3394;3599;3600;1 -3394;3600;3395;1 -3395;3600;3601;1 -3395;3601;3602;1 -3395;3602;3396;1 -3396;3602;3397;1 -3397;3602;3398;1 -3398;3602;3399;1 -3399;3602;3603;1 -3399;3603;3400;1 -3400;3603;3604;1 -3400;3604;3605;1 -3400;3605;3606;1 -3400;3606;3401;1 -3401;3606;3607;1 -3401;3607;3608;1 -3401;3608;3402;1 -3402;3608;3403;1 -3403;3608;3609;1 -3403;3609;3610;1 -3403;3610;3404;1 -3404;3610;3405;1 -3405;3610;3611;1 -3405;3611;3406;1 -3406;3611;3612;1 -3406;3612;3407;1 -3407;3612;3613;1 -3407;3613;3408;1 -3408;3613;3614;1 -3408;3614;3409;1 -3409;3614;3615;1 -3409;3615;3410;1 -3410;3615;3616;1 -3410;3616;3617;1 -3410;3617;3411;1 -3411;3617;3618;1 -3411;3618;3412;1 -3412;3618;3619;1 -3412;3619;3413;1 -3413;3619;3620;1 -3413;3620;3414;1 -3414;3620;3415;1 -3415;3620;3621;1 -3415;3621;3416;1 -3416;3621;3622;1 -3416;3622;3417;1 -3417;3622;3623;1 -3417;3623;3418;1 -3418;3623;3624;1 -3418;3624;3625;1 -3418;3625;3419;1 -3419;3625;3420;1 -3420;3625;3626;1 -3420;3626;3421;1 -3421;3626;3627;1 -3421;3627;3628;1 -3421;3628;3422;1 -3422;3628;3629;1 -3422;3629;3423;1 -3423;3629;3630;1 -3423;3630;3424;1 -3424;3630;3631;1 -3424;3631;3425;1 -3425;3631;3426;1 -3426;3631;3632;1 -3426;3632;3427;1 -3427;3632;3633;1 -3427;3633;3428;1 -3428;3633;3634;1 -3428;3634;3429;1 -3429;3634;3635;1 -3429;3635;3636;1 -3429;3636;3430;1 -3430;3636;3431;1 -3431;3636;3637;1 -3431;3637;3432;1 -3432;3637;3638;1 -3432;3638;3639;1 -3432;3639;3433;1 -3433;3639;3640;1 -3433;3640;3434;1 -3434;3640;3641;1 -3434;3641;3435;1 -3435;3641;3642;1 -3435;3642;3436;1 -3436;3642;3643;1 -3436;3643;3437;1 -3437;3643;3644;1 -3437;3644;3438;1 -3438;3644;3645;1 -3438;3645;3439;1 -3439;3645;3646;1 -3439;3646;3440;1 -3440;3646;3647;1 -3440;3647;3648;1 -3440;3648;3441;1 -3441;3648;3442;1 -3442;3648;3443;1 -3443;3648;3649;1 -3443;3649;3650;1 -3443;3650;3445;1 -3445;3650;3447;1 -3447;3650;3651;1 -3447;3651;3448;1 -3448;3651;3652;1 -3448;3652;3653;1 -3448;3653;3449;1 -3449;3653;3654;1 -3449;3654;3450;1 -3450;3654;3655;1 -3450;3655;3656;1 -3450;3656;3451;1 -3451;3656;3657;1 -3451;3657;3452;1 -3452;3657;3658;1 -3452;3658;3453;1 -3453;3658;3659;1 -3453;3659;3454;1 -3454;3659;3455;1 -3455;3659;3660;1 -3455;3660;3661;1 -3455;3661;3456;1 -3456;3661;3662;1 -3456;3662;3457;1 -3457;3662;3663;1 -3457;3663;3458;1 -3458;3663;3664;1 -3458;3664;3459;1 -3459;3664;3665;1 -3459;3665;3460;1 -3460;3665;3666;1 -3460;3666;3461;1 -3461;3666;3667;1 -3461;3667;3462;1 -3462;3667;3668;1 -3462;3668;3463;1 -3463;3668;3669;1 -3463;3669;3464;1 -3464;3669;3670;1 -3464;3670;3465;1 -3465;3670;3671;1 -3465;3671;3466;1 -3466;3671;3672;1 -3466;3672;3467;1 -3467;3672;3673;1 -3467;3673;3468;1 -3468;3673;3674;1 -3468;3674;3469;1 -3469;3674;3470;1 -3470;3674;3675;1 -3470;3675;3676;1 -3470;3676;3471;1 -3471;3676;3677;1 -3471;3677;3678;1 -3471;3678;3472;1 -3472;3678;3679;1 -3472;3679;3680;1 -3472;3680;3473;1 -3473;3680;3474;1 -3474;3680;3681;1 -3474;3681;3475;1 -3475;3681;3682;1 -3475;3682;3683;1 -3475;3683;3476;1 -3476;3683;3477;1 -3477;3683;3684;1 -3477;3684;3685;1 -3477;3685;3478;1 -3478;3685;3479;1 -3479;3685;3686;1 -3479;3686;3480;1 -3480;3686;3687;1 -3480;3687;3688;1 -3480;3688;3481;1 -3481;3688;3482;1 -3482;3688;3689;1 -3482;3689;3483;1 -3483;3689;3690;1 -3483;3690;3691;1 -3483;3691;3484;1 -3484;3691;3692;1 -3484;3692;3485;1 -3485;3692;3486;1 -3486;3692;3693;1 -3486;3693;3694;1 -3486;3694;3695;1 -3486;3695;3487;1 -3487;3695;3696;1 -3487;3696;3488;1 -3488;3696;3697;1 -3488;3697;3489;1 -3489;3697;3698;1 -3489;3698;3490;1 -3490;3698;3699;1 -3490;3699;3700;1 -3490;3700;3491;1 -3491;3700;3492;1 -3492;3700;3701;1 -3492;3701;3493;1 -3493;3701;3702;1 -3493;3702;3494;1 -3494;3702;3703;1 -3494;3703;3495;1 -3495;3703;3704;1 -3495;3704;3496;1 -3496;3704;3705;1 -3496;3705;3497;1 -3497;3705;3706;1 -3497;3706;3498;1 -3498;3706;3707;1 -3498;3707;3499;1 -3499;3707;3708;1 -3499;3708;3500;1 -3500;3708;3709;1 -3500;3709;3710;1 -3500;3710;3501;1 -3501;3710;3711;1 -3501;3711;3502;1 -3502;3711;3503;1 -3503;3711;3712;1 -3503;3712;3713;1 -3503;3713;3714;1 -3503;3714;3504;1 -3504;3714;3715;1 -3504;3715;3505;1 -3505;3715;3716;1 -3505;3716;3507;1 -3507;3716;3508;1 -3508;3716;3717;1 -3508;3717;3509;1 -3509;3717;3718;1 -3509;3718;3510;1 -3510;3718;3719;1 -3510;3719;3511;1 -3511;3719;3720;1 -3511;3720;3512;1 -3512;3720;3721;1 -3512;3721;3513;1 -3513;3721;3722;1 -3513;3722;3514;1 -3514;3722;3723;1 -3514;3723;3515;1 -3515;3723;3724;1 -3515;3724;3516;1 -3516;3724;3725;1 -3516;3725;3517;1 -3517;3725;3726;1 -3517;3726;3518;1 -3518;3726;3727;1 -3518;3727;3519;1 -3519;3727;3728;1 -3519;3728;3520;1 -3520;3728;3729;1 -3520;3729;3521;1 -3521;3729;3730;1 -3521;3730;3522;1 -3522;3730;3731;1 -3522;3731;3523;1 -3523;3731;3732;1 -3523;3732;3733;1 -3523;3733;3524;1 -3524;3733;3525;1 -3525;3733;3734;1 -3525;3734;3735;1 -3525;3735;3526;1 -3526;3735;3736;1 -3526;3736;3527;1 -3527;3736;3528;1 -3528;3736;3737;1 -3528;3737;3738;1 -3528;3738;3529;1 -3529;3738;3739;1 -3529;3739;3530;1 -3530;3739;3740;1 -3530;3740;3531;1 -3531;3740;3741;1 -3531;3741;3532;1 -3532;3741;3533;1 -3533;3741;3742;1 -3533;3742;3743;1 -3533;3743;3534;1 -3534;3743;3744;1 -3534;3744;3535;1 -3535;3744;3745;1 -3535;3745;3536;1 -3536;3745;3746;1 -3536;3746;3537;1 -3537;3746;3747;1 -3537;3747;3748;1 -3537;3748;3749;1 -3537;3749;3538;1 -3538;3749;3539;1 -3539;3749;3750;1 -3539;3750;3541;1 -3541;3750;3751;1 -3541;3751;3542;1 -3542;3751;3752;1 -3542;3752;3543;1 -3543;3752;3753;1 -3543;3753;3754;1 -3543;3754;3544;1 -3544;3754;3545;1 -3545;3754;3755;1 -3545;3755;3546;1 -3546;3755;3756;1 -3546;3756;3547;1 -3547;3756;3757;1 -3547;3757;3548;1 -3548;3757;3758;1 -3548;3758;3549;1 -3549;3758;3759;1 -3549;3759;3550;1 -3550;3759;3760;1 -3550;3760;3761;1 -3550;3761;3762;1 -3550;3762;3551;1 -3551;3762;3552;1 -3552;3762;3763;1 -3552;3763;3553;1 -3553;3763;3764;1 -3553;3764;3554;1 -3554;3764;3765;1 -3554;3765;3555;1 -3555;3765;3766;1 -3555;3766;3556;1 -3556;3766;3767;1 -3556;3767;3557;1 -3557;3767;3768;1 -3557;3768;3558;1 -3558;3768;3769;1 -3558;3769;3559;1 -3559;3769;3770;1 -3559;3770;3771;1 -3559;3771;3560;1 -3560;3771;3772;1 -3560;3772;3561;1 -3561;3772;3773;1 -3561;3773;3562;1 -3562;3773;3774;1 -3562;3774;3563;1 -3563;3774;3775;1 -3563;3775;3564;1 -3564;3775;3776;1 -3564;3776;3565;1 -3565;3776;3777;1 -3565;3777;3566;1 -3566;3777;3778;1 -3566;3778;3567;1 -3567;3778;3779;1 -3567;3779;3568;1 -3568;3779;3780;1 -3568;3780;3569;1 -3569;3780;3781;1 -3569;3781;3570;1 -3570;3781;3782;1 -3570;3782;3571;1 -3571;3782;3783;1 -3571;3783;3572;1 -3572;3783;3784;1 -3572;3784;3573;1 -3573;3784;3785;1 -3573;3785;3786;1 -3573;3786;3574;1 -3574;3786;3575;1 -3575;3786;3787;1 -3575;3787;3576;1 -3576;3787;3788;1 -3576;3788;3577;1 -3577;3788;3789;1 -3577;3789;3578;1 -3578;3789;3790;1 -3578;3790;3791;1 -3578;3791;3579;1 -3579;3791;3580;1 -3580;3791;3792;1 -3580;3792;3581;1 -3581;3792;3793;1 -3581;3793;3582;1 -3582;3793;3794;1 -3582;3794;3583;1 -3583;3794;3795;1 -3583;3795;3584;1 -3584;3795;3796;1 -3584;3796;3797;1 -3584;3797;3585;1 -3585;3797;3798;1 -3585;3798;3586;1 -3586;3798;3587;1 -3587;3798;3799;1 -3587;3799;3800;1 -3587;3800;3801;1 -3587;3801;3588;1 -3588;3801;3589;1 -3589;3801;3590;1 -3590;3801;3802;1 -3590;3802;3803;1 -3590;3803;3591;1 -3591;3803;3804;1 -3591;3804;3592;1 -3592;3804;3805;1 -3592;3805;3593;1 -3593;3805;3806;1 -3593;3806;3594;1 -3594;3806;3807;1 -3594;3807;3595;1 -3595;3807;3596;1 -3596;3807;3808;1 -3596;3808;3809;1 -3596;3809;3597;1 -3597;3809;3598;1 -3598;3809;3810;1 -3598;3810;3599;1 -3599;3810;3811;1 -3599;3811;3812;1 -3599;3812;3600;1 -3600;3812;3813;1 -3600;3813;3601;1 -3601;3813;3814;1 -3601;3814;3603;1 -3603;3814;3604;1 -3604;3814;3815;1 -3604;3815;3605;1 -3605;3815;3816;1 -3605;3816;3817;1 -3605;3817;3607;1 -3607;3817;3818;1 -3607;3818;3819;1 -3607;3819;3608;1 -3608;3819;3609;1 -3609;3819;3820;1 -3609;3820;3611;1 -3611;3820;3821;1 -3611;3821;3612;1 -3612;3821;3822;1 -3612;3822;3613;1 -3613;3822;3823;1 -3613;3823;3614;1 -3614;3823;3824;1 -3614;3824;3615;1 -3615;3824;3825;1 -3615;3825;3616;1 -3616;3825;3826;1 -3616;3826;3827;1 -3616;3827;3617;1 -3617;3827;3828;1 -3617;3828;3618;1 -3618;3828;3829;1 -3618;3829;3619;1 -3619;3829;3830;1 -3619;3830;3620;1 -3620;3830;3621;1 -3621;3830;3831;1 -3621;3831;3622;1 -3622;3831;3832;1 -3622;3832;3623;1 -3623;3832;3833;1 -3623;3833;3624;1 -3624;3833;3834;1 -3624;3834;3835;1 -3624;3835;3625;1 -3625;3835;3626;1 -3626;3835;3836;1 -3626;3836;3627;1 -3627;3836;3837;1 -3627;3837;3838;1 -3627;3838;3628;1 -3628;3838;3839;1 -3628;3839;3629;1 -3629;3839;3840;1 -3629;3840;3630;1 -3630;3840;3841;1 -3630;3841;3631;1 -3631;3841;3632;1 -3632;3841;3842;1 -3632;3842;3843;1 -3632;3843;3633;1 -3633;3843;3844;1 -3633;3844;3634;1 -3634;3844;3845;1 -3634;3845;3846;1 -3634;3846;3635;1 -3635;3846;3636;1 -3636;3846;3637;1 -3637;3846;3847;1 -3637;3847;3638;1 -3638;3847;3848;1 -3638;3848;3639;1 -3639;3848;3849;1 -3639;3849;3850;1 -3639;3850;3851;1 -3639;3851;3640;1 -3640;3851;3852;1 -3640;3852;3641;1 -3641;3852;3853;1 -3641;3853;3642;1 -3642;3853;3854;1 -3642;3854;3643;1 -3643;3854;3855;1 -3643;3855;3644;1 -3644;3855;3856;1 -3644;3856;3857;1 -3644;3857;3645;1 -3645;3857;3858;1 -3645;3858;3859;1 -3645;3859;3646;1 -3646;3859;3860;1 -3646;3860;3861;1 -3646;3861;3647;1 -3647;3861;3862;1 -3647;3862;3863;1 -3647;3863;3649;1 -3649;3863;3651;1 -3651;3863;3862;1 -3651;3862;3652;1 -3652;3862;3864;1 -3652;3864;3865;1 -3652;3865;3653;1 -3653;3865;3866;1 -3653;3866;3654;1 -3654;3866;3655;1 -3655;3866;3867;1 -3655;3867;3656;1 -3656;3867;3868;1 -3656;3868;3657;1 -3657;3868;3869;1 -3657;3869;3658;1 -3658;3869;3870;1 -3658;3870;3659;1 -3659;3870;3871;1 -3659;3871;3660;1 -3660;3871;3872;1 -3660;3872;3661;1 -3661;3872;3873;1 -3661;3873;3662;1 -3662;3873;3874;1 -3662;3874;3875;1 -3662;3875;3663;1 -3663;3875;3876;1 -3663;3876;3664;1 -3664;3876;3877;1 -3664;3877;3665;1 -3665;3877;3878;1 -3665;3878;3666;1 -3666;3878;3879;1 -3666;3879;3667;1 -3667;3879;3880;1 -3667;3880;3668;1 -3668;3880;3881;1 -3668;3881;3669;1 -3669;3881;3670;1 -3670;3881;3882;1 -3670;3882;3671;1 -3671;3882;3883;1 -3671;3883;3884;1 -3671;3884;3672;1 -3672;3884;3885;1 -3672;3885;3673;1 -3673;3885;3886;1 -3673;3886;3674;1 -3674;3886;3675;1 -3675;3886;3887;1 -3675;3887;3888;1 -3675;3888;3676;1 -3676;3888;3889;1 -3676;3889;3677;1 -3677;3889;3890;1 -3677;3890;3891;1 -3677;3891;3678;1 -3678;3891;3679;1 -3679;3891;3892;1 -3679;3892;3893;1 -3679;3893;3681;1 -3681;3893;3682;1 -3682;3893;3894;1 -3682;3894;3895;1 -3682;3895;3896;1 -3682;3896;3683;1 -3683;3896;3684;1 -3684;3896;3897;1 -3684;3897;3898;1 -3684;3898;3685;1 -3685;3898;3686;1 -3686;3898;3899;1 -3686;3899;3687;1 -3687;3899;3900;1 -3687;3900;3688;1 -3688;3900;3901;1 -3688;3901;3689;1 -3689;3901;3902;1 -3689;3902;3690;1 -3690;3902;3903;1 -3690;3903;3691;1 -3691;3903;3904;1 -3691;3904;3693;1 -3693;3904;3905;1 -3693;3905;3906;1 -3693;3906;3907;1 -3693;3907;3694;1 -3694;3907;3908;1 -3694;3908;3909;1 -3694;3909;3695;1 -3695;3909;3910;1 -3695;3910;3696;1 -3696;3910;3911;1 -3696;3911;3697;1 -3697;3911;3912;1 -3697;3912;3698;1 -3698;3912;3913;1 -3698;3913;3699;1 -3699;3913;3914;1 -3699;3914;3915;1 -3699;3915;3700;1 -3700;3915;3701;1 -3701;3915;3916;1 -3701;3916;3702;1 -3702;3916;3917;1 -3702;3917;3703;1 -3703;3917;3918;1 -3703;3918;3704;1 -3704;3918;3919;1 -3704;3919;3705;1 -3705;3919;3920;1 -3705;3920;3706;1 -3706;3920;3921;1 -3706;3921;3707;1 -3707;3921;3922;1 -3707;3922;3708;1 -3708;3922;3923;1 -3708;3923;3709;1 -3709;3923;3924;1 -3709;3924;3925;1 -3709;3925;3710;1 -3710;3925;3926;1 -3710;3926;3711;1 -3711;3926;3712;1 -3712;3926;3927;1 -3712;3927;3928;1 -3712;3928;3713;1 -3713;3928;3929;1 -3713;3929;3930;1 -3713;3930;3714;1 -3714;3930;3931;1 -3714;3931;3932;1 -3714;3932;3715;1 -3715;3932;3933;1 -3715;3933;3934;1 -3715;3934;3717;1 -3717;3934;3718;1 -3718;3934;3935;1 -3718;3935;3719;1 -3719;3935;3936;1 -3719;3936;3720;1 -3720;3936;3937;1 -3720;3937;3721;1 -3721;3937;3938;1 -3721;3938;3722;1 -3722;3938;3939;1 -3722;3939;3723;1 -3723;3939;3940;1 -3723;3940;3724;1 -3724;3940;3941;1 -3724;3941;3725;1 -3725;3941;3942;1 -3725;3942;3726;1 -3726;3942;3943;1 -3726;3943;3727;1 -3727;3943;3944;1 -3727;3944;3728;1 -3728;3944;3945;1 -3728;3945;3729;1 -3729;3945;3946;1 -3729;3946;3730;1 -3730;3946;3947;1 -3730;3947;3731;1 -3731;3947;3948;1 -3731;3948;3732;1 -3732;3948;3949;1 -3732;3949;3734;1 -3734;3949;3950;1 -3734;3950;3735;1 -3735;3950;3951;1 -3735;3951;3952;1 -3735;3952;3736;1 -3736;3952;3737;1 -3737;3952;3953;1 -3737;3953;3954;1 -3737;3954;3738;1 -3738;3954;3955;1 -3738;3955;3739;1 -3739;3955;3956;1 -3739;3956;3740;1 -3740;3956;3957;1 -3740;3957;3741;1 -3741;3957;3742;1 -3742;3957;3958;1 -3742;3958;3959;1 -3742;3959;3743;1 -3743;3959;3960;1 -3743;3960;3744;1 -3744;3960;3961;1 -3744;3961;3745;1 -3745;3961;3962;1 -3745;3962;3746;1 -3746;3962;3963;1 -3746;3963;3747;1 -3747;3963;3964;1 -3747;3964;3965;1 -3747;3965;3966;1 -3747;3966;3748;1 -3748;3966;3967;1 -3748;3967;3749;1 -3749;3967;3750;1 -3750;3967;3968;1 -3750;3968;3751;1 -3751;3968;3969;1 -3751;3969;3752;1 -3752;3969;3970;1 -3752;3970;3753;1 -3753;3970;3971;1 -3753;3971;3972;1 -3753;3972;3754;1 -3754;3972;3973;1 -3754;3973;3974;1 -3754;3974;3755;1 -3755;3974;3756;1 -3756;3974;3975;1 -3756;3975;3976;1 -3756;3976;3977;1 -3756;3977;3757;1 -3757;3977;3758;1 -3758;3977;3978;1 -3758;3978;3759;1 -3759;3978;3979;1 -3759;3979;3760;1 -3760;3979;3980;1 -3760;3980;3981;1 -3760;3981;3761;1 -3761;3981;3982;1 -3761;3982;3762;1 -3762;3982;3983;1 -3762;3983;3763;1 -3763;3983;3984;1 -3763;3984;3764;1 -3764;3984;3985;1 -3764;3985;3765;1 -3765;3985;3986;1 -3765;3986;3766;1 -3766;3986;3987;1 -3766;3987;3767;1 -3767;3987;3988;1 -3767;3988;3768;1 -3768;3988;3989;1 -3768;3989;3769;1 -3769;3989;3990;1 -3769;3990;3991;1 -3769;3991;3770;1 -3770;3991;3992;1 -3770;3992;3771;1 -3771;3992;3993;1 -3771;3993;3772;1 -3772;3993;3994;1 -3772;3994;3773;1 -3773;3994;3995;1 -3773;3995;3774;1 -3774;3995;3996;1 -3774;3996;3775;1 -3775;3996;3997;1 -3775;3997;3776;1 -3776;3997;3998;1 -3776;3998;3777;1 -3777;3998;3999;1 -3777;3999;3778;1 -3778;3999;4000;1 -3778;4000;3779;1 -3779;4000;4001;1 -3779;4001;3780;1 -3780;4001;4002;1 -3780;4002;3781;1 -3781;4002;4003;1 -3781;4003;3782;1 -3782;4003;4004;1 -3782;4004;3783;1 -3783;4004;4005;1 -3783;4005;3784;1 -3784;4005;4006;1 -3784;4006;3785;1 -3785;4006;4007;1 -3785;4007;4008;1 -3785;4008;3786;1 -3786;4008;3787;1 -3787;4008;4009;1 -3787;4009;3788;1 -3788;4009;4010;1 -3788;4010;3789;1 -3789;4010;4011;1 -3789;4011;3790;1 -3790;4011;4012;1 -3790;4012;4013;1 -3790;4013;3791;1 -3791;4013;3792;1 -3792;4013;4014;1 -3792;4014;3793;1 -3793;4014;4015;1 -3793;4015;3794;1 -3794;4015;4016;1 -3794;4016;3795;1 -3795;4016;4017;1 -3795;4017;3796;1 -3796;4017;4018;1 -3796;4018;4019;1 -3796;4019;3797;1 -3797;4019;4020;1 -3797;4020;3798;1 -3798;4020;3799;1 -3799;4020;4021;1 -3799;4021;4022;1 -3799;4022;3800;1 -3800;4022;4023;1 -3800;4023;3802;1 -3802;4023;4024;1 -3802;4024;4025;1 -3802;4025;3803;1 -3803;4025;4026;1 -3803;4026;3804;1 -3804;4026;4027;1 -3804;4027;3805;1 -3805;4027;4028;1 -3805;4028;3806;1 -3806;4028;4029;1 -3806;4029;3807;1 -3807;4029;3808;1 -3808;4029;4030;1 -3808;4030;4031;1 -3808;4031;3809;1 -3809;4031;3810;1 -3810;4031;4032;1 -3810;4032;3811;1 -3811;4032;4033;1 -3811;4033;4034;1 -3811;4034;3812;1 -3812;4034;4035;1 -3812;4035;3813;1 -3813;4035;4036;1 -3813;4036;3814;1 -3814;4036;4037;1 -3814;4037;3815;1 -3815;4037;3816;1 -3816;4037;4038;1 -3816;4038;4039;1 -3816;4039;3817;1 -3817;4039;3818;1 -3818;4039;4040;1 -3818;4040;4041;1 -3818;4041;4042;1 -3818;4042;3819;1 -3819;4042;3820;1 -3820;4042;4043;1 -3820;4043;3821;1 -3821;4043;4044;1 -3821;4044;3822;1 -3822;4044;4045;1 -3822;4045;3823;1 -3823;4045;4046;1 -3823;4046;3824;1 -3824;4046;4047;1 -3824;4047;3825;1 -3825;4047;4048;1 -3825;4048;3826;1 -3826;4048;4049;1 -3826;4049;4050;1 -3826;4050;3827;1 -3827;4050;4051;1 -3827;4051;3828;1 -3828;4051;4052;1 -3828;4052;3829;1 -3829;4052;4053;1 -3829;4053;3830;1 -3830;4053;3831;1 -3831;4053;4054;1 -3831;4054;3832;1 -3832;4054;4055;1 -3832;4055;3833;1 -3833;4055;4056;1 -3833;4056;3834;1 -3834;4056;4057;1 -3834;4057;4058;1 -3834;4058;3835;1 -3835;4058;3836;1 -3836;4058;4059;1 -3836;4059;3837;1 -3837;4059;4060;1 -3837;4060;4061;1 -3837;4061;4062;1 -3837;4062;3838;1 -3838;4062;4063;1 -3838;4063;3839;1 -3839;4063;4064;1 -3839;4064;3840;1 -3840;4064;3842;1 -3842;4064;4065;1 -3842;4065;4066;1 -3842;4066;3843;1 -3843;4066;4067;1 -3843;4067;4068;1 -3843;4068;3844;1 -3844;4068;3845;1 -3845;4068;4069;1 -3845;4069;3847;1 -3847;4069;4070;1 -3847;4070;3848;1 -3848;4070;4071;1 -3848;4071;4072;1 -3848;4072;3849;1 -3849;4072;4073;1 -3849;4073;3850;1 -3850;4073;4074;1 -3850;4074;4075;1 -3850;4075;3851;1 -3851;4075;4076;1 -3851;4076;3852;1 -3852;4076;4077;1 -3852;4077;4078;1 -3852;4078;3853;1 -3853;4078;4079;1 -3853;4079;4080;1 -3853;4080;3854;1 -3854;4080;4081;1 -3854;4081;4082;1 -3854;4082;3855;1 -3855;4082;3856;1 -3856;4082;4083;1 -3856;4083;4084;1 -3856;4084;3858;1 -3858;4084;4085;1 -3858;4085;3860;1 -3860;4085;3864;1 -3864;4085;4086;1 -3864;4086;3865;1 -3865;4086;4087;1 -3865;4087;3866;1 -3866;4087;3867;1 -3867;4087;4088;1 -3867;4088;3868;1 -3868;4088;3869;1 -3869;4088;4089;1 -3869;4089;3870;1 -3870;4089;4090;1 -3870;4090;4091;1 -3870;4091;3871;1 -3871;4091;4092;1 -3871;4092;4093;1 -3871;4093;3872;1 -3872;4093;4094;1 -3872;4094;4095;1 -3872;4095;3873;1 -3873;4095;3874;1 -3874;4095;4096;1 -3874;4096;3875;1 -3875;4096;4097;1 -3875;4097;4098;1 -3875;4098;3876;1 -3876;4098;4099;1 -3876;4099;3877;1 -3877;4099;4100;1 -3877;4100;4101;1 -3877;4101;3878;1 -3878;4101;4102;1 -3878;4102;3879;1 -3879;4102;4103;1 -3879;4103;3880;1 -3880;4103;4104;1 -3880;4104;3881;1 -3881;4104;4105;1 -3881;4105;3882;1 -3882;4105;4106;1 -3882;4106;3883;1 -3883;4106;4107;1 -3883;4107;3884;1 -3884;4107;4108;1 -3884;4108;4109;1 -3884;4109;3885;1 -3885;4109;3886;1 -3886;4109;3887;1 -3887;4109;4110;1 -3887;4110;3888;1 -3888;4110;4111;1 -3888;4111;4112;1 -3888;4112;3889;1 -3889;4112;4113;1 -3889;4113;3890;1 -3890;4113;4114;1 -3890;4114;3891;1 -3891;4114;4115;1 -3891;4115;3892;1 -3892;4115;4116;1 -3892;4116;3893;1 -3893;4116;4117;1 -3893;4117;3894;1 -3894;4117;3895;1 -3895;4117;4118;1 -3895;4118;4119;1 -3895;4119;3896;1 -3896;4119;3897;1 -3897;4119;4120;1 -3897;4120;3898;1 -3898;4120;3899;1 -3899;4120;3900;1 -3900;4120;4121;1 -3900;4121;3901;1 -3901;4121;4122;1 -3901;4122;3902;1 -3902;4122;4123;1 -3902;4123;3903;1 -3903;4123;4124;1 -3903;4124;3904;1 -3904;4124;3905;1 -3905;4124;4125;1 -3905;4125;4126;1 -3905;4126;3906;1 -3906;4126;4127;1 -3906;4127;3907;1 -3907;4127;4128;1 -3907;4128;4129;1 -3907;4129;3908;1 -3908;4129;4130;1 -3908;4130;4131;1 -3908;4131;3909;1 -3909;4131;4132;1 -3909;4132;3910;1 -3910;4132;4133;1 -3910;4133;3911;1 -3911;4133;4134;1 -3911;4134;3912;1 -3912;4134;4135;1 -3912;4135;3913;1 -3913;4135;4136;1 -3913;4136;3914;1 -3914;4136;4137;1 -3914;4137;4138;1 -3914;4138;3915;1 -3915;4138;4139;1 -3915;4139;3916;1 -3916;4139;4140;1 -3916;4140;4141;1 -3916;4141;3917;1 -3917;4141;4142;1 -3917;4142;3918;1 -3918;4142;4143;1 -3918;4143;3919;1 -3919;4143;4144;1 -3919;4144;3920;1 -3920;4144;4145;1 -3920;4145;3921;1 -3921;4145;4146;1 -3921;4146;3922;1 -3922;4146;4147;1 -3922;4147;3923;1 -3923;4147;4148;1 -3923;4148;3924;1 -3924;4148;4149;1 -3924;4149;4150;1 -3924;4150;3925;1 -3925;4150;4151;1 -3925;4151;3926;1 -3926;4151;3927;1 -3927;4151;4152;1 -3927;4152;4153;1 -3927;4153;3928;1 -3928;4153;4154;1 -3928;4154;3929;1 -3929;4154;4155;1 -3929;4155;4156;1 -3929;4156;3930;1 -3930;4156;4157;1 -3930;4157;3931;1 -3931;4157;4158;1 -3931;4158;4159;1 -3931;4159;3932;1 -3932;4159;3933;1 -3933;4159;4160;1 -3933;4160;4161;1 -3933;4161;3934;1 -3934;4161;3935;1 -3935;4161;4162;1 -3935;4162;3936;1 -3936;4162;3937;1 -3937;4162;4163;1 -3937;4163;3938;1 -3938;4163;4164;1 -3938;4164;3939;1 -3939;4164;4165;1 -3939;4165;3940;1 -3940;4165;4166;1 -3940;4166;3941;1 -3941;4166;4167;1 -3941;4167;3942;1 -3942;4167;4168;1 -3942;4168;3943;1 -3943;4168;4169;1 -3943;4169;3944;1 -3944;4169;4170;1 -3944;4170;3945;1 -3945;4170;4171;1 -3945;4171;3946;1 -3946;4171;4172;1 -3946;4172;3947;1 -3947;4172;4173;1 -3947;4173;3948;1 -3948;4173;4174;1 -3948;4174;3949;1 -3949;4174;4175;1 -3949;4175;4176;1 -3949;4176;3950;1 -3950;4176;4177;1 -3950;4177;3951;1 -3951;4177;4178;1 -3951;4178;3953;1 -3953;4178;4179;1 -3953;4179;3954;1 -3954;4179;4180;1 -3954;4180;3955;1 -3955;4180;3956;1 -3956;4180;4181;1 -3956;4181;3957;1 -3957;4181;3958;1 -3958;4181;4182;1 -3958;4182;4183;1 -3958;4183;3959;1 -3959;4183;4184;1 -3959;4184;3960;1 -3960;4184;4185;1 -3960;4185;3961;1 -3961;4185;4186;1 -3961;4186;3962;1 -3962;4186;4187;1 -3962;4187;3963;1 -3963;4187;4188;1 -3963;4188;3964;1 -3964;4188;4189;1 -3964;4189;4190;1 -3964;4190;4191;1 -3964;4191;3965;1 -3965;4191;4192;1 -3965;4192;4193;1 -3965;4193;3966;1 -3966;4193;3968;1 -3968;4193;4194;1 -3968;4194;3969;1 -3969;4194;4195;1 -3969;4195;3970;1 -3970;4195;3971;1 -3971;4195;4196;1 -3971;4196;4197;1 -3971;4197;4198;1 -3971;4198;3972;1 -3972;4198;4199;1 -3972;4199;3973;1 -3973;4199;3974;1 -3974;4199;3975;1 -3975;4199;4200;1 -3975;4200;4201;1 -3975;4201;3976;1 -3976;4201;4202;1 -3976;4202;3977;1 -3977;4202;4203;1 -3977;4203;3979;1 -3979;4203;3980;1 -3980;4203;4202;1 -3980;4202;4204;1 -3980;4204;3981;1 -3981;4204;4205;1 -3981;4205;4206;1 -3981;4206;3982;1 -3982;4206;4207;1 -3982;4207;3984;1 -3984;4207;4208;1 -3984;4208;3985;1 -3985;4208;4209;1 -3985;4209;3986;1 -3986;4209;4210;1 -3986;4210;3987;1 -3987;4210;4211;1 -3987;4211;3988;1 -3988;4211;4212;1 -3988;4212;3989;1 -3989;4212;4213;1 -3989;4213;3990;1 -3990;4213;4214;1 -3990;4214;4215;1 -3990;4215;3991;1 -3991;4215;4216;1 -3991;4216;3992;1 -3992;4216;4217;1 -3992;4217;3993;1 -3993;4217;4218;1 -3993;4218;3994;1 -3994;4218;4219;1 -3994;4219;3995;1 -3995;4219;4220;1 -3995;4220;3996;1 -3996;4220;4221;1 -3996;4221;3997;1 -3997;4221;4222;1 -3997;4222;3998;1 -3998;4222;4223;1 -3998;4223;3999;1 -3999;4223;4224;1 -3999;4224;4000;1 -4000;4224;4225;1 -4000;4225;4001;1 -4001;4225;4226;1 -4001;4226;4002;1 -4002;4226;4227;1 -4002;4227;4003;1 -4003;4227;4228;1 -4003;4228;4004;1 -4004;4228;4229;1 -4004;4229;4005;1 -4005;4229;4230;1 -4005;4230;4006;1 -4006;4230;4231;1 -4006;4231;4007;1 -4007;4231;4232;1 -4007;4232;4233;1 -4007;4233;4008;1 -4008;4233;4009;1 -4009;4233;4234;1 -4009;4234;4010;1 -4010;4234;4235;1 -4010;4235;4011;1 -4011;4235;4236;1 -4011;4236;4012;1 -4012;4236;4237;1 -4012;4237;4238;1 -4012;4238;4013;1 -4013;4238;4014;1 -4014;4238;4239;1 -4014;4239;4015;1 -4015;4239;4240;1 -4015;4240;4016;1 -4016;4240;4241;1 -4016;4241;4017;1 -4017;4241;4242;1 -4017;4242;4018;1 -4018;4242;4243;1 -4018;4243;4244;1 -4018;4244;4019;1 -4019;4244;4245;1 -4019;4245;4020;1 -4020;4245;4021;1 -4021;4245;4246;1 -4021;4246;4247;1 -4021;4247;4022;1 -4022;4247;4248;1 -4022;4248;4023;1 -4023;4248;4024;1 -4024;4248;4249;1 -4024;4249;4250;1 -4024;4250;4025;1 -4025;4250;4251;1 -4025;4251;4026;1 -4026;4251;4252;1 -4026;4252;4027;1 -4027;4252;4253;1 -4027;4253;4028;1 -4028;4253;4254;1 -4028;4254;4029;1 -4029;4254;4030;1 -4030;4254;4255;1 -4030;4255;4256;1 -4030;4256;4031;1 -4031;4256;4032;1 -4032;4256;4257;1 -4032;4257;4033;1 -4033;4257;4258;1 -4033;4258;4259;1 -4033;4259;4034;1 -4034;4259;4260;1 -4034;4260;4035;1 -4035;4260;4261;1 -4035;4261;4036;1 -4036;4261;4037;1 -4037;4261;4038;1 -4038;4261;4262;1 -4038;4262;4263;1 -4038;4263;4039;1 -4039;4263;4040;1 -4040;4263;4264;1 -4040;4264;4265;1 -4040;4265;4041;1 -4041;4265;4266;1 -4041;4266;4267;1 -4041;4267;4042;1 -4042;4267;4043;1 -4043;4267;4268;1 -4043;4268;4044;1 -4044;4268;4269;1 -4044;4269;4045;1 -4045;4269;4270;1 -4045;4270;4046;1 -4046;4270;4271;1 -4046;4271;4047;1 -4047;4271;4272;1 -4047;4272;4048;1 -4048;4272;4273;1 -4048;4273;4049;1 -4049;4273;4274;1 -4049;4274;4275;1 -4049;4275;4276;1 -4049;4276;4050;1 -4050;4276;4051;1 -4051;4276;4277;1 -4051;4277;4278;1 -4051;4278;4052;1 -4052;4278;4279;1 -4052;4279;4053;1 -4053;4279;4054;1 -4054;4279;4280;1 -4054;4280;4055;1 -4055;4280;4281;1 -4055;4281;4056;1 -4056;4281;4282;1 -4056;4282;4057;1 -4057;4282;4283;1 -4057;4283;4058;1 -4058;4283;4284;1 -4058;4284;4059;1 -4059;4284;4285;1 -4059;4285;4060;1 -4060;4285;4286;1 -4060;4286;4287;1 -4060;4287;4061;1 -4061;4287;4288;1 -4061;4288;4062;1 -4062;4288;4289;1 -4062;4289;4290;1 -4062;4290;4063;1 -4063;4290;4065;1 -4065;4290;4291;1 -4065;4291;4292;1 -4065;4292;4066;1 -4066;4292;4293;1 -4066;4293;4294;1 -4066;4294;4067;1 -4067;4294;4295;1 -4067;4295;4068;1 -4068;4295;4296;1 -4068;4296;4297;1 -4068;4297;4069;1 -4069;4297;4070;1 -4070;4297;4298;1 -4070;4298;4071;1 -4071;4298;4299;1 -4071;4299;4300;1 -4071;4300;4072;1 -4072;4300;4301;1 -4072;4301;4073;1 -4073;4301;4302;1 -4073;4302;4074;1 -4074;4302;4303;1 -4074;4303;4304;1 -4074;4304;4075;1 -4075;4304;4305;1 -4075;4305;4076;1 -4076;4305;4077;1 -4077;4305;4306;1 -4077;4306;4307;1 -4077;4307;4078;1 -4078;4307;4079;1 -4079;4307;4308;1 -4079;4308;4309;1 -4079;4309;4080;1 -4080;4309;4081;1 -4081;4309;4310;1 -4081;4310;4083;1 -4083;4310;4311;1 -4083;4311;4084;1 -4084;4311;4312;1 -4084;4312;4085;1 -4085;4312;4086;1 -4086;4312;4313;1 -4086;4313;4087;1 -4087;4313;4088;1 -4088;4313;4314;1 -4088;4314;4089;1 -4089;4314;4315;1 -4089;4315;4090;1 -4090;4315;4316;1 -4090;4316;4091;1 -4091;4316;4317;1 -4091;4317;4092;1 -4092;4317;4318;1 -4092;4318;4319;1 -4092;4319;4093;1 -4093;4319;4094;1 -4094;4319;4320;1 -4094;4320;4321;1 -4094;4321;4095;1 -4095;4321;4096;1 -4096;4321;4322;1 -4096;4322;4097;1 -4097;4322;4323;1 -4097;4323;4324;1 -4097;4324;4098;1 -4098;4324;4325;1 -4098;4325;4099;1 -4099;4325;4100;1 -4100;4325;4326;1 -4100;4326;4101;1 -4101;4326;4327;1 -4101;4327;4328;1 -4101;4328;4102;1 -4102;4328;4329;1 -4102;4329;4103;1 -4103;4329;4330;1 -4103;4330;4104;1 -4104;4330;4331;1 -4104;4331;4105;1 -4105;4331;4332;1 -4105;4332;4333;1 -4105;4333;4106;1 -4106;4333;4334;1 -4106;4334;4107;1 -4107;4334;4335;1 -4107;4335;4108;1 -4108;4335;4336;1 -4108;4336;4109;1 -4109;4336;4337;1 -4109;4337;4110;1 -4110;4337;4338;1 -4110;4338;4111;1 -4111;4338;4339;1 -4111;4339;4340;1 -4111;4340;4112;1 -4112;4340;4341;1 -4112;4341;4113;1 -4113;4341;4342;1 -4113;4342;4114;1 -4114;4342;4343;1 -4114;4343;4115;1 -4115;4343;4344;1 -4115;4344;4345;1 -4115;4345;4116;1 -4116;4345;4346;1 -4116;4346;4117;1 -4117;4346;4347;1 -4117;4347;4118;1 -4118;4347;4348;1 -4118;4348;4119;1 -4119;4348;4349;1 -4119;4349;4120;1 -4120;4349;4121;1 -4121;4349;4122;1 -4122;4349;4123;1 -4123;4349;4350;1 -4123;4350;4124;1 -4124;4350;4351;1 -4124;4351;4352;1 -4124;4352;4125;1 -4125;4352;4353;1 -4125;4353;4126;1 -4126;4353;4354;1 -4126;4354;4127;1 -4127;4354;4355;1 -4127;4355;4128;1 -4128;4355;4356;1 -4128;4356;4357;1 -4128;4357;4129;1 -4129;4357;4130;1 -4130;4357;4358;1 -4130;4358;4359;1 -4130;4359;4131;1 -4131;4359;4132;1 -4132;4359;4360;1 -4132;4360;4361;1 -4132;4361;4133;1 -4133;4361;4362;1 -4133;4362;4134;1 -4134;4362;4363;1 -4134;4363;4135;1 -4135;4363;4364;1 -4135;4364;4365;1 -4135;4365;4136;1 -4136;4365;4366;1 -4136;4366;4137;1 -4137;4366;4367;1 -4137;4367;4368;1 -4137;4368;4138;1 -4138;4368;4369;1 -4138;4369;4139;1 -4139;4369;4370;1 -4139;4370;4140;1 -4140;4370;4371;1 -4140;4371;4372;1 -4140;4372;4141;1 -4141;4372;4373;1 -4141;4373;4142;1 -4142;4373;4374;1 -4142;4374;4143;1 -4143;4374;4375;1 -4143;4375;4144;1 -4144;4375;4376;1 -4144;4376;4145;1 -4145;4376;4377;1 -4145;4377;4146;1 -4146;4377;4378;1 -4146;4378;4147;1 -4147;4378;4379;1 -4147;4379;4148;1 -4148;4379;4380;1 -4148;4380;4149;1 -4149;4380;4381;1 -4149;4381;4382;1 -4149;4382;4150;1 -4150;4382;4383;1 -4150;4383;4151;1 -4151;4383;4152;1 -4152;4383;4384;1 -4152;4384;4385;1 -4152;4385;4153;1 -4153;4385;4386;1 -4153;4386;4154;1 -4154;4386;4387;1 -4154;4387;4388;1 -4154;4388;4155;1 -4155;4388;4389;1 -4155;4389;4390;1 -4155;4390;4391;1 -4155;4391;4156;1 -4156;4391;4157;1 -4157;4391;4392;1 -4157;4392;4393;1 -4157;4393;4158;1 -4158;4393;4394;1 -4158;4394;4395;1 -4158;4395;4159;1 -4159;4395;4160;1 -4160;4395;4396;1 -4160;4396;4397;1 -4160;4397;4161;1 -4161;4397;4162;1 -4162;4397;4163;1 -4163;4397;4398;1 -4163;4398;4164;1 -4164;4398;4399;1 -4164;4399;4165;1 -4165;4399;4400;1 -4165;4400;4166;1 -4166;4400;4401;1 -4166;4401;4167;1 -4167;4401;4402;1 -4167;4402;4168;1 -4168;4402;4403;1 -4168;4403;4169;1 -4169;4403;4404;1 -4169;4404;4170;1 -4170;4404;4405;1 -4170;4405;4171;1 -4171;4405;4406;1 -4171;4406;4172;1 -4172;4406;4407;1 -4172;4407;4173;1 -4173;4407;4408;1 -4173;4408;4174;1 -4174;4408;4409;1 -4174;4409;4175;1 -4175;4409;4410;1 -4175;4410;4176;1 -4176;4410;4411;1 -4176;4411;4412;1 -4176;4412;4177;1 -4177;4412;4413;1 -4177;4413;4178;1 -4178;4413;4414;1 -4178;4414;4179;1 -4179;4414;4415;1 -4179;4415;4180;1 -4180;4415;4181;1 -4181;4415;4182;1 -4182;4415;4416;1 -4182;4416;4417;1 -4182;4417;4183;1 -4183;4417;4418;1 -4183;4418;4184;1 -4184;4418;4419;1 -4184;4419;4185;1 -4185;4419;4420;1 -4185;4420;4186;1 -4186;4420;4421;1 -4186;4421;4187;1 -4187;4421;4422;1 -4187;4422;4188;1 -4188;4422;4423;1 -4188;4423;4189;1 -4189;4423;4424;1 -4189;4424;4190;1 -4190;4424;4425;1 -4190;4425;4426;1 -4190;4426;4191;1 -4191;4426;4427;1 -4191;4427;4192;1 -4192;4427;4194;1 -4194;4427;4428;1 -4194;4428;4195;1 -4195;4428;4196;1 -4196;4428;4429;1 -4196;4429;4430;1 -4196;4430;4197;1 -4197;4430;4431;1 -4197;4431;4432;1 -4197;4432;4198;1 -4198;4432;4200;1 -4200;4432;4433;1 -4200;4433;4201;1 -4201;4433;4434;1 -4201;4434;4435;1 -4201;4435;4202;1 -4202;4435;4204;1 -4204;4435;4436;1 -4204;4436;4205;1 -4205;4436;4437;1 -4205;4437;4438;1 -4205;4438;4206;1 -4206;4438;4439;1 -4206;4439;4207;1 -4207;4439;4440;1 -4207;4440;4208;1 -4208;4440;4441;1 -4208;4441;4209;1 -4209;4441;4442;1 -4209;4442;4443;1 -4209;4443;4444;1 -4209;4444;4210;1 -4210;4444;4211;1 -4211;4444;4445;1 -4211;4445;4212;1 -4212;4445;4446;1 -4212;4446;4213;1 -4213;4446;4447;1 -4213;4447;4214;1 -4214;4447;4448;1 -4214;4448;4449;1 -4214;4449;4215;1 -4215;4449;4450;1 -4215;4450;4216;1 -4216;4450;4451;1 -4216;4451;4217;1 -4217;4451;4452;1 -4217;4452;4218;1 -4218;4452;4453;1 -4218;4453;4219;1 -4219;4453;4454;1 -4219;4454;4220;1 -4220;4454;4455;1 -4220;4455;4221;1 -4221;4455;4456;1 -4221;4456;4222;1 -4222;4456;4457;1 -4222;4457;4223;1 -4223;4457;4458;1 -4223;4458;4224;1 -4224;4458;4459;1 -4224;4459;4225;1 -4225;4459;4460;1 -4225;4460;4226;1 -4226;4460;4461;1 -4226;4461;4227;1 -4227;4461;4462;1 -4227;4462;4228;1 -4228;4462;4463;1 -4228;4463;4229;1 -4229;4463;4464;1 -4229;4464;4230;1 -4230;4464;4465;1 -4230;4465;4231;1 -4231;4465;4466;1 -4231;4466;4232;1 -4232;4466;4467;1 -4232;4467;4468;1 -4232;4468;4233;1 -4233;4468;4234;1 -4234;4468;4469;1 -4234;4469;4235;1 -4235;4469;4470;1 -4235;4470;4236;1 -4236;4470;4471;1 -4236;4471;4237;1 -4237;4471;4472;1 -4237;4472;4473;1 -4237;4473;4238;1 -4238;4473;4239;1 -4239;4473;4474;1 -4239;4474;4240;1 -4240;4474;4475;1 -4240;4475;4241;1 -4241;4475;4476;1 -4241;4476;4242;1 -4242;4476;4477;1 -4242;4477;4243;1 -4243;4477;4478;1 -4243;4478;4479;1 -4243;4479;4244;1 -4244;4479;4480;1 -4244;4480;4245;1 -4245;4480;4246;1 -4246;4480;4481;1 -4246;4481;4482;1 -4246;4482;4247;1 -4247;4482;4483;1 -4247;4483;4248;1 -4248;4483;4249;1 -4249;4483;4484;1 -4249;4484;4485;1 -4249;4485;4250;1 -4250;4485;4486;1 -4250;4486;4251;1 -4251;4486;4487;1 -4251;4487;4252;1 -4252;4487;4488;1 -4252;4488;4253;1 -4253;4488;4489;1 -4253;4489;4254;1 -4254;4489;4255;1 -4255;4489;4490;1 -4255;4490;4491;1 -4255;4491;4256;1 -4256;4491;4257;1 -4257;4491;4492;1 -4257;4492;4258;1 -4258;4492;4493;1 -4258;4493;4494;1 -4258;4494;4259;1 -4259;4494;4495;1 -4259;4495;4260;1 -4260;4495;4262;1 -4262;4495;4496;1 -4262;4496;4263;1 -4263;4496;4264;1 -4264;4496;4497;1 -4264;4497;4498;1 -4264;4498;4265;1 -4265;4498;4499;1 -4265;4499;4266;1 -4266;4499;4500;1 -4266;4500;4501;1 -4266;4501;4267;1 -4267;4501;4268;1 -4268;4501;4502;1 -4268;4502;4269;1 -4269;4502;4503;1 -4269;4503;4270;1 -4270;4503;4504;1 -4270;4504;4271;1 -4271;4504;4505;1 -4271;4505;4506;1 -4271;4506;4272;1 -4272;4506;4507;1 -4272;4507;4508;1 -4272;4508;4273;1 -4273;4508;4509;1 -4273;4509;4274;1 -4274;4509;4510;1 -4274;4510;4511;1 -4274;4511;4275;1 -4275;4511;4512;1 -4275;4512;4513;1 -4275;4513;4276;1 -4276;4513;4514;1 -4276;4514;4277;1 -4277;4514;4515;1 -4277;4515;4516;1 -4277;4516;4278;1 -4278;4516;4517;1 -4278;4517;4279;1 -4279;4517;4280;1 -4280;4517;4518;1 -4280;4518;4281;1 -4281;4518;4519;1 -4281;4519;4282;1 -4282;4519;4520;1 -4282;4520;4521;1 -4282;4521;4283;1 -4283;4521;4522;1 -4283;4522;4284;1 -4284;4522;4285;1 -4285;4522;4523;1 -4285;4523;4524;1 -4285;4524;4286;1 -4286;4524;4525;1 -4286;4525;4287;1 -4287;4525;4526;1 -4287;4526;4288;1 -4288;4526;4527;1 -4288;4527;4289;1 -4289;4527;4528;1 -4289;4528;4290;1 -4290;4528;4291;1 -4291;4528;4529;1 -4291;4529;4530;1 -4291;4530;4292;1 -4292;4530;4531;1 -4292;4531;4293;1 -4293;4531;4532;1 -4293;4532;4533;1 -4293;4533;4294;1 -4294;4533;4534;1 -4294;4534;4535;1 -4294;4535;4295;1 -4295;4535;4536;1 -4295;4536;4296;1 -4296;4536;4537;1 -4296;4537;4538;1 -4296;4538;4297;1 -4297;4538;4298;1 -4298;4538;4539;1 -4298;4539;4299;1 -4299;4539;4540;1 -4299;4540;4541;1 -4299;4541;4300;1 -4300;4541;4542;1 -4300;4542;4301;1 -4301;4542;4543;1 -4301;4543;4302;1 -4302;4543;4544;1 -4302;4544;4303;1 -4303;4544;4545;1 -4303;4545;4546;1 -4303;4546;4304;1 -4304;4546;4547;1 -4304;4547;4305;1 -4305;4547;4306;1 -4306;4547;4548;1 -4306;4548;4549;1 -4306;4549;4307;1 -4307;4549;4308;1 -4308;4549;4550;1 -4308;4550;4551;1 -4308;4551;4309;1 -4309;4551;4310;1 -4310;4551;4552;1 -4310;4552;4311;1 -4311;4552;4553;1 -4311;4553;4312;1 -4312;4553;4313;1 -4313;4553;4314;1 -4314;4553;4554;1 -4314;4554;4315;1 -4315;4554;4555;1 -4315;4555;4316;1 -4316;4555;4556;1 -4316;4556;4317;1 -4317;4556;4557;1 -4317;4557;4318;1 -4318;4557;4558;1 -4318;4558;4559;1 -4318;4559;4319;1 -4319;4559;4320;1 -4320;4559;4560;1 -4320;4560;4561;1 -4320;4561;4321;1 -4321;4561;4322;1 -4322;4561;4562;1 -4322;4562;4323;1 -4323;4562;4563;1 -4323;4563;4564;1 -4323;4564;4324;1 -4324;4564;4565;1 -4324;4565;4325;1 -4325;4565;4326;1 -4326;4565;4566;1 -4326;4566;4327;1 -4327;4566;4567;1 -4327;4567;4568;1 -4327;4568;4328;1 -4328;4568;4569;1 -4328;4569;4329;1 -4329;4569;4570;1 -4329;4570;4330;1 -4330;4570;4571;1 -4330;4571;4331;1 -4331;4571;4572;1 -4331;4572;4332;1 -4332;4572;4573;1 -4332;4573;4574;1 -4332;4574;4333;1 -4333;4574;4575;1 -4333;4575;4334;1 -4334;4575;4335;1 -4335;4575;4576;1 -4335;4576;4577;1 -4335;4577;4336;1 -4336;4577;4578;1 -4336;4578;4579;1 -4336;4579;4337;1 -4337;4579;4338;1 -4338;4579;4580;1 -4338;4580;4339;1 -4339;4580;4581;1 -4339;4581;4582;1 -4339;4582;4340;1 -4340;4582;4583;1 -4340;4583;4341;1 -4341;4583;4584;1 -4341;4584;4342;1 -4342;4584;4585;1 -4342;4585;4343;1 -4343;4585;4586;1 -4343;4586;4344;1 -4344;4586;4587;1 -4344;4587;4588;1 -4344;4588;4345;1 -4345;4588;4346;1 -4346;4588;4589;1 -4346;4589;4347;1 -4347;4589;4590;1 -4347;4590;4591;1 -4347;4591;4348;1 -4348;4591;4350;1 -4350;4591;4351;1 -4351;4591;4592;1 -4351;4592;4352;1 -4352;4592;4593;1 -4352;4593;4353;1 -4353;4593;4594;1 -4353;4594;4595;1 -4353;4595;4354;1 -4354;4595;4355;1 -4355;4595;4596;1 -4355;4596;4356;1 -4356;4596;4597;1 -4356;4597;4598;1 -4356;4598;4357;1 -4357;4598;4358;1 -4358;4598;4599;1 -4358;4599;4600;1 -4358;4600;4359;1 -4359;4600;4601;1 -4359;4601;4360;1 -4360;4601;4602;1 -4360;4602;4603;1 -4360;4603;4361;1 -4361;4603;4604;1 -4361;4604;4605;1 -4361;4605;4362;1 -4362;4605;4606;1 -4362;4606;4363;1 -4363;4606;4607;1 -4363;4607;4364;1 -4364;4607;4608;1 -4364;4608;4609;1 -4364;4609;4365;1 -4365;4609;4366;1 -4366;4609;4610;1 -4366;4610;4367;1 -4367;4610;4611;1 -4367;4611;4612;1 -4367;4612;4368;1 -4368;4612;4613;1 -4368;4613;4369;1 -4369;4613;4614;1 -4369;4614;4370;1 -4370;4614;4615;1 -4370;4615;4371;1 -4371;4615;4616;1 -4371;4616;4617;1 -4371;4617;4372;1 -4372;4617;4618;1 -4372;4618;4373;1 -4373;4618;4619;1 -4373;4619;4374;1 -4374;4619;4620;1 -4374;4620;4375;1 -4375;4620;4621;1 -4375;4621;4376;1 -4376;4621;4622;1 -4376;4622;4377;1 -4377;4622;4623;1 -4377;4623;4378;1 -4378;4623;4624;1 -4378;4624;4379;1 -4379;4624;4625;1 -4379;4625;4380;1 -4380;4625;4626;1 -4380;4626;4381;1 -4381;4626;4627;1 -4381;4627;4628;1 -4381;4628;4382;1 -4382;4628;4629;1 -4382;4629;4383;1 -4383;4629;4384;1 -4384;4629;4630;1 -4384;4630;4631;1 -4384;4631;4385;1 -4385;4631;4632;1 -4385;4632;4386;1 -4386;4632;4387;1 -4387;4632;4633;1 -4387;4633;4634;1 -4387;4634;4635;1 -4387;4635;4388;1 -4388;4635;4389;1 -4389;4635;4636;1 -4389;4636;4637;1 -4389;4637;4638;1 -4389;4638;4639;1 -4389;4639;4390;1 -4390;4639;4391;1 -4391;4639;4392;1 -4392;4639;4393;1 -4393;4639;4640;1 -4393;4640;4394;1 -4394;4640;4641;1 -4394;4641;4642;1 -4394;4642;4643;1 -4394;4643;4395;1 -4395;4643;4396;1 -4396;4643;4644;1 -4396;4644;4398;1 -4398;4644;4399;1 -4399;4644;4645;1 -4399;4645;4400;1 -4400;4645;4646;1 -4400;4646;4401;1 -4401;4646;4647;1 -4401;4647;4402;1 -4402;4647;4648;1 -4402;4648;4403;1 -4403;4648;4649;1 -4403;4649;4404;1 -4404;4649;4650;1 -4404;4650;4405;1 -4405;4650;4651;1 -4405;4651;4406;1 -4406;4651;4652;1 -4406;4652;4407;1 -4407;4652;4653;1 -4407;4653;4408;1 -4408;4653;4654;1 -4408;4654;4409;1 -4409;4654;4655;1 -4409;4655;4410;1 -4410;4655;4656;1 -4410;4656;4657;1 -4410;4657;4411;1 -4411;4657;4658;1 -4411;4658;4412;1 -4412;4658;4659;1 -4412;4659;4413;1 -4413;4659;4660;1 -4413;4660;4414;1 -4414;4660;4661;1 -4414;4661;4415;1 -4415;4661;4416;1 -4416;4661;4662;1 -4416;4662;4663;1 -4416;4663;4417;1 -4417;4663;4664;1 -4417;4664;4418;1 -4418;4664;4665;1 -4418;4665;4419;1 -4419;4665;4420;1 -4420;4665;4666;1 -4420;4666;4421;1 -4421;4666;4667;1 -4421;4667;4422;1 -4422;4667;4668;1 -4422;4668;4669;1 -4422;4669;4423;1 -4423;4669;4670;1 -4423;4670;4424;1 -4424;4670;4671;1 -4424;4671;4425;1 -4425;4671;4672;1 -4425;4672;4429;1 -4429;4672;4430;1 -4430;4672;4673;1 -4430;4673;4431;1 -4431;4673;4674;1 -4431;4674;4675;1 -4431;4675;4432;1 -4432;4675;4433;1 -4433;4675;4676;1 -4433;4676;4434;1 -4434;4676;4677;1 -4434;4677;4678;1 -4434;4678;4435;1 -4435;4678;4436;1 -4436;4678;4679;1 -4436;4679;4437;1 -4437;4679;4680;1 -4437;4680;4681;1 -4437;4681;4438;1 -4438;4681;4682;1 -4438;4682;4439;1 -4439;4682;4683;1 -4439;4683;4440;1 -4440;4683;4684;1 -4440;4684;4685;1 -4440;4685;4441;1 -4441;4685;4686;1 -4441;4686;4442;1 -4442;4686;4687;1 -4442;4687;4688;1 -4442;4688;4443;1 -4443;4688;4689;1 -4443;4689;4690;1 -4443;4690;4444;1 -4444;4690;4691;1 -4444;4691;4445;1 -4445;4691;4446;1 -4446;4691;4692;1 -4446;4692;4447;1 -4447;4692;4693;1 -4447;4693;4448;1 -4448;4693;4694;1 -4448;4694;4695;1 -4448;4695;4449;1 -4449;4695;4696;1 -4449;4696;4450;1 -4450;4696;4697;1 -4450;4697;4451;1 -4451;4697;4698;1 -4451;4698;4452;1 -4452;4698;4699;1 -4452;4699;4453;1 -4453;4699;4700;1 -4453;4700;4454;1 -4454;4700;4701;1 -4454;4701;4455;1 -4455;4701;4702;1 -4455;4702;4456;1 -4456;4702;4703;1 -4456;4703;4457;1 -4457;4703;4704;1 -4457;4704;4458;1 -4458;4704;4705;1 -4458;4705;4459;1 -4459;4705;4706;1 -4459;4706;4460;1 -4460;4706;4707;1 -4460;4707;4461;1 -4461;4707;4708;1 -4461;4708;4462;1 -4462;4708;4709;1 -4462;4709;4463;1 -4463;4709;4710;1 -4463;4710;4464;1 -4464;4710;4711;1 -4464;4711;4465;1 -4465;4711;4712;1 -4465;4712;4466;1 -4466;4712;4713;1 -4466;4713;4467;1 -4467;4713;4714;1 -4467;4714;4715;1 -4467;4715;4468;1 -4468;4715;4469;1 -4469;4715;4716;1 -4469;4716;4470;1 -4470;4716;4717;1 -4470;4717;4471;1 -4471;4717;4718;1 -4471;4718;4472;1 -4472;4718;4719;1 -4472;4719;4720;1 -4472;4720;4473;1 -4473;4720;4474;1 -4474;4720;4721;1 -4474;4721;4475;1 -4475;4721;4722;1 -4475;4722;4476;1 -4476;4722;4723;1 -4476;4723;4477;1 -4477;4723;4724;1 -4477;4724;4478;1 -4478;4724;4725;1 -4478;4725;4726;1 -4478;4726;4479;1 -4479;4726;4727;1 -4479;4727;4480;1 -4480;4727;4481;1 -4481;4727;4728;1 -4481;4728;4729;1 -4481;4729;4482;1 -4482;4729;4730;1 -4482;4730;4483;1 -4483;4730;4484;1 -4484;4730;4731;1 -4484;4731;4732;1 -4484;4732;4485;1 -4485;4732;4733;1 -4485;4733;4486;1 -4486;4733;4734;1 -4486;4734;4487;1 -4487;4734;4735;1 -4487;4735;4488;1 -4488;4735;4736;1 -4488;4736;4489;1 -4489;4736;4490;1 -4490;4736;4737;1 -4490;4737;4738;1 -4490;4738;4491;1 -4491;4738;4492;1 -4492;4738;4739;1 -4492;4739;4493;1 -4493;4739;4740;1 -4493;4740;4741;1 -4493;4741;4494;1 -4494;4741;4742;1 -4494;4742;4495;1 -4495;4742;4496;1 -4496;4742;4497;1 -4497;4742;4743;1 -4497;4743;4744;1 -4497;4744;4498;1 -4498;4744;4745;1 -4498;4745;4499;1 -4499;4745;4746;1 -4499;4746;4747;1 -4499;4747;4500;1 -4500;4747;4748;1 -4500;4748;4749;1 -4500;4749;4501;1 -4501;4749;4750;1 -4501;4750;4502;1 -4502;4750;4751;1 -4502;4751;4752;1 -4502;4752;4503;1 -4503;4752;4753;1 -4503;4753;4754;1 -4503;4754;4504;1 -4504;4754;4755;1 -4504;4755;4505;1 -4505;4755;4756;1 -4505;4756;4757;1 -4505;4757;4506;1 -4506;4757;4507;1 -4507;4757;4758;1 -4507;4758;4759;1 -4507;4759;4508;1 -4508;4759;4509;1 -4509;4759;4760;1 -4509;4760;4510;1 -4510;4760;4761;1 -4510;4761;4762;1 -4510;4762;4511;1 -4511;4762;4763;1 -4511;4763;4512;1 -4512;4763;4764;1 -4512;4764;4765;1 -4512;4765;4513;1 -4513;4765;4514;1 -4514;4765;4766;1 -4514;4766;4767;1 -4514;4767;4768;1 -4514;4768;4515;1 -4515;4768;4769;1 -4515;4769;4770;1 -4515;4770;4516;1 -4516;4770;4771;1 -4516;4771;4772;1 -4516;4772;4517;1 -4517;4772;4518;1 -4518;4772;4773;1 -4518;4773;4774;1 -4518;4774;4519;1 -4519;4774;4775;1 -4519;4775;4520;1 -4520;4775;4776;1 -4520;4776;4777;1 -4520;4777;4521;1 -4521;4777;4522;1 -4522;4777;4523;1 -4523;4777;4778;1 -4523;4778;4524;1 -4524;4778;4779;1 -4524;4779;4780;1 -4524;4780;4525;1 -4525;4780;4781;1 -4525;4781;4526;1 -4526;4781;4782;1 -4526;4782;4527;1 -4527;4782;4783;1 -4527;4783;4528;1 -4528;4783;4529;1 -4529;4783;4784;1 -4529;4784;4785;1 -4529;4785;4530;1 -4530;4785;4786;1 -4530;4786;4531;1 -4531;4786;4787;1 -4531;4787;4788;1 -4531;4788;4532;1 -4532;4788;4533;1 -4533;4788;4789;1 -4533;4789;4534;1 -4534;4789;4790;1 -4534;4790;4791;1 -4534;4791;4792;1 -4534;4792;4535;1 -4535;4792;4536;1 -4536;4792;4793;1 -4536;4793;4537;1 -4537;4793;4794;1 -4537;4794;4538;1 -4538;4794;4795;1 -4538;4795;4539;1 -4539;4795;4796;1 -4539;4796;4797;1 -4539;4797;4540;1 -4540;4797;4798;1 -4540;4798;4799;1 -4540;4799;4541;1 -4541;4799;4800;1 -4541;4800;4542;1 -4542;4800;4801;1 -4542;4801;4802;1 -4542;4802;4543;1 -4543;4802;4803;1 -4543;4803;4544;1 -4544;4803;4804;1 -4544;4804;4545;1 -4545;4804;4805;1 -4545;4805;4546;1 -4546;4805;4806;1 -4546;4806;4547;1 -4547;4806;4548;1 -4548;4806;4807;1 -4548;4807;4808;1 -4548;4808;4549;1 -4549;4808;4550;1 -4550;4808;4809;1 -4550;4809;4810;1 -4550;4810;4551;1 -4551;4810;4552;1 -4552;4810;4554;1 -4554;4810;4555;1 -4555;4810;4809;1 -4555;4809;4556;1 -4556;4809;4811;1 -4556;4811;4557;1 -4557;4811;4812;1 -4557;4812;4558;1 -4558;4812;4813;1 -4558;4813;4814;1 -4558;4814;4559;1 -4559;4814;4560;1 -4560;4814;4815;1 -4560;4815;4816;1 -4560;4816;4561;1 -4561;4816;4562;1 -4562;4816;4817;1 -4562;4817;4563;1 -4563;4817;4818;1 -4563;4818;4819;1 -4563;4819;4564;1 -4564;4819;4820;1 -4564;4820;4565;1 -4565;4820;4566;1 -4566;4820;4821;1 -4566;4821;4567;1 -4567;4821;4822;1 -4567;4822;4823;1 -4567;4823;4568;1 -4568;4823;4824;1 -4568;4824;4570;1 -4570;4824;4571;1 -4571;4824;4825;1 -4571;4825;4826;1 -4571;4826;4827;1 -4571;4827;4572;1 -4572;4827;4828;1 -4572;4828;4829;1 -4572;4829;4573;1 -4573;4829;4830;1 -4573;4830;4574;1 -4574;4830;4831;1 -4574;4831;4832;1 -4574;4832;4575;1 -4575;4832;4576;1 -4576;4832;4833;1 -4576;4833;4577;1 -4577;4833;4834;1 -4577;4834;4578;1 -4578;4834;4835;1 -4578;4835;4836;1 -4578;4836;4579;1 -4579;4836;4580;1 -4580;4836;4837;1 -4580;4837;4581;1 -4581;4837;4838;1 -4581;4838;4839;1 -4581;4839;4582;1 -4582;4839;4840;1 -4582;4840;4583;1 -4583;4840;4841;1 -4583;4841;4584;1 -4584;4841;4842;1 -4584;4842;4585;1 -4585;4842;4843;1 -4585;4843;4586;1 -4586;4843;4844;1 -4586;4844;4587;1 -4587;4844;4845;1 -4587;4845;4846;1 -4587;4846;4588;1 -4588;4846;4589;1 -4589;4846;4847;1 -4589;4847;4590;1 -4590;4847;4848;1 -4590;4848;4592;1 -4592;4848;4593;1 -4593;4848;4849;1 -4593;4849;4594;1 -4594;4849;4850;1 -4594;4850;4851;1 -4594;4851;4595;1 -4595;4851;4596;1 -4596;4851;4852;1 -4596;4852;4853;1 -4596;4853;4597;1 -4597;4853;4854;1 -4597;4854;4855;1 -4597;4855;4598;1 -4598;4855;4599;1 -4599;4855;4856;1 -4599;4856;4857;1 -4599;4857;4600;1 -4600;4857;4601;1 -4601;4857;4858;1 -4601;4858;4602;1 -4602;4858;4859;1 -4602;4859;4860;1 -4602;4860;4603;1 -4603;4860;4861;1 -4603;4861;4604;1 -4604;4861;4862;1 -4604;4862;4605;1 -4605;4862;4863;1 -4605;4863;4606;1 -4606;4863;4864;1 -4606;4864;4607;1 -4607;4864;4608;1 -4608;4864;4865;1 -4608;4865;4866;1 -4608;4866;4609;1 -4609;4866;4610;1 -4610;4866;4867;1 -4610;4867;4611;1 -4611;4867;4868;1 -4611;4868;4869;1 -4611;4869;4612;1 -4612;4869;4870;1 -4612;4870;4613;1 -4613;4870;4871;1 -4613;4871;4614;1 -4614;4871;4872;1 -4614;4872;4615;1 -4615;4872;4873;1 -4615;4873;4616;1 -4616;4873;4874;1 -4616;4874;4875;1 -4616;4875;4617;1 -4617;4875;4876;1 -4617;4876;4618;1 -4618;4876;4877;1 -4618;4877;4619;1 -4619;4877;4878;1 -4619;4878;4620;1 -4620;4878;4879;1 -4620;4879;4621;1 -4621;4879;4880;1 -4621;4880;4622;1 -4622;4880;4881;1 -4622;4881;4623;1 -4623;4881;4882;1 -4623;4882;4624;1 -4624;4882;4883;1 -4624;4883;4625;1 -4625;4883;4884;1 -4625;4884;4626;1 -4626;4884;4885;1 -4626;4885;4627;1 -4627;4885;4886;1 -4627;4886;4887;1 -4627;4887;4628;1 -4628;4887;4888;1 -4628;4888;4629;1 -4629;4888;4630;1 -4630;4888;4889;1 -4630;4889;4890;1 -4630;4890;4631;1 -4631;4890;4891;1 -4631;4891;4632;1 -4632;4891;4633;1 -4633;4891;4892;1 -4633;4892;4893;1 -4633;4893;4634;1 -4634;4893;4894;1 -4634;4894;4895;1 -4634;4895;4896;1 -4634;4896;4635;1 -4635;4896;4897;1 -4635;4897;4636;1 -4636;4897;4898;1 -4636;4898;4637;1 -4637;4898;4899;1 -4637;4899;4900;1 -4637;4900;4638;1 -4638;4900;4640;1 -4640;4900;4641;1 -4641;4900;4901;1 -4641;4901;4902;1 -4641;4902;4642;1 -4642;4902;4903;1 -4642;4903;4904;1 -4642;4904;4643;1 -4643;4904;4644;1 -4644;4904;4645;1 -4645;4904;4905;1 -4645;4905;4646;1 -4646;4905;4906;1 -4646;4906;4647;1 -4647;4906;4907;1 -4647;4907;4648;1 -4648;4907;4908;1 -4648;4908;4649;1 -4649;4908;4909;1 -4649;4909;4650;1 -4650;4909;4910;1 -4650;4910;4651;1 -4651;4910;4911;1 -4651;4911;4652;1 -4652;4911;4912;1 -4652;4912;4653;1 -4653;4912;4913;1 -4653;4913;4654;1 -4654;4913;4914;1 -4654;4914;4655;1 -4655;4914;4915;1 -4655;4915;4656;1 -4656;4915;4916;1 -4656;4916;4917;1 -4656;4917;4657;1 -4657;4917;4918;1 -4657;4918;4658;1 -4658;4918;4919;1 -4658;4919;4659;1 -4659;4919;4920;1 -4659;4920;4660;1 -4660;4920;4921;1 -4660;4921;4661;1 -4661;4921;4662;1 -4662;4921;4922;1 -4662;4922;4923;1 -4662;4923;4663;1 -4663;4923;4924;1 -4663;4924;4664;1 -4664;4924;4925;1 -4664;4925;4665;1 -4665;4925;4926;1 -4665;4926;4666;1 -4666;4926;4927;1 -4666;4927;4667;1 -4667;4927;4928;1 -4667;4928;4668;1 -4668;4928;4929;1 -4668;4929;4669;1 -4669;4929;4930;1 -4669;4930;4931;1 -4669;4931;4670;1 -4670;4931;4932;1 -4670;4932;4671;1 -4671;4932;4672;1 -4672;4932;4933;1 -4672;4933;4673;1 -4673;4933;4934;1 -4673;4934;4674;1 -4674;4934;4935;1 -4674;4935;4675;1 -4675;4935;4936;1 -4675;4936;4676;1 -4676;4936;4937;1 -4676;4937;4677;1 -4677;4937;4938;1 -4677;4938;4939;1 -4677;4939;4678;1 -4678;4939;4679;1 -4679;4939;4940;1 -4679;4940;4680;1 -4680;4940;4941;1 -4680;4941;4942;1 -4680;4942;4681;1 -4681;4942;4943;1 -4681;4943;4682;1 -4682;4943;4944;1 -4682;4944;4683;1 -4683;4944;4684;1 -4684;4944;4945;1 -4684;4945;4946;1 -4684;4946;4947;1 -4684;4947;4685;1 -4685;4947;4686;1 -4686;4947;4948;1 -4686;4948;4687;1 -4687;4948;4949;1 -4687;4949;4950;1 -4687;4950;4951;1 -4687;4951;4952;1 -4687;4952;4688;1 -4688;4952;4689;1 -4689;4952;4953;1 -4689;4953;4954;1 -4689;4954;4690;1 -4690;4954;4955;1 -4690;4955;4691;1 -4691;4955;4956;1 -4691;4956;4692;1 -4692;4956;4957;1 -4692;4957;4958;1 -4692;4958;4693;1 -4693;4958;4959;1 -4693;4959;4960;1 -4693;4960;4694;1 -4694;4960;4961;1 -4694;4961;4695;1 -4695;4961;4962;1 -4695;4962;4696;1 -4696;4962;4697;1 -4697;4962;4963;1 -4697;4963;4964;1 -4697;4964;4698;1 -4698;4964;4965;1 -4698;4965;4699;1 -4699;4965;4966;1 -4699;4966;4700;1 -4700;4966;4967;1 -4700;4967;4701;1 -4701;4967;4968;1 -4701;4968;4702;1 -4702;4968;4969;1 -4702;4969;4703;1 -4703;4969;4970;1 -4703;4970;4704;1 -4704;4970;4971;1 -4704;4971;4705;1 -4705;4971;4972;1 -4705;4972;4706;1 -4706;4972;4973;1 -4706;4973;4707;1 -4707;4973;4974;1 -4707;4974;4708;1 -4708;4974;4975;1 -4708;4975;4709;1 -4709;4975;4976;1 -4709;4976;4710;1 -4710;4976;4977;1 -4710;4977;4711;1 -4711;4977;4978;1 -4711;4978;4712;1 -4712;4978;4713;1 -4713;4978;4979;1 -4713;4979;4714;1 -4714;4979;4980;1 -4714;4980;4981;1 -4714;4981;4715;1 -4715;4981;4716;1 -4716;4981;4982;1 -4716;4982;4717;1 -4717;4982;4983;1 -4717;4983;4718;1 -4718;4983;4984;1 -4718;4984;4719;1 -4719;4984;4985;1 -4719;4985;4986;1 -4719;4986;4720;1 -4720;4986;4721;1 -4721;4986;4987;1 -4721;4987;4722;1 -4722;4987;4988;1 -4722;4988;4723;1 -4723;4988;4989;1 -4723;4989;4724;1 -4724;4989;4990;1 -4724;4990;4725;1 -4725;4990;4763;1 -4763;4990;4764;1 -4764;4990;4991;1 -4764;4991;4765;1 -4765;4991;4766;1 -4766;4991;4992;1 -4766;4992;4767;1 -4767;4992;4993;1 -4767;4993;4994;1 -4767;4994;4768;1 -4768;4994;4995;1 -4768;4995;4769;1 -4769;4995;4996;1 -4769;4996;4997;1 -4769;4997;4770;1 -4770;4997;4998;1 -4770;4998;4999;1 -4770;4999;4771;1 -4771;4999;5000;1 -4771;5000;4773;1 -4773;5000;5001;1 -4773;5001;4774;1 -4774;5001;4775;1 -4775;5001;5002;1 -4775;5002;4776;1 -4776;5002;5003;1 -4776;5003;5004;1 -4776;5004;5005;1 -4776;5005;4777;1 -4777;5005;4778;1 -4778;5005;4779;1 -4779;5005;5006;1 -4779;5006;5007;1 -4779;5007;4780;1 -4780;5007;5008;1 -4780;5008;5009;1 -4780;5009;4781;1 -4781;5009;5010;1 -4781;5010;5011;1 -4781;5011;5012;1 -4781;5012;4782;1 -4782;5012;4783;1 -4783;5012;4784;1 -4784;5012;5013;1 -4784;5013;5014;1 -4784;5014;4785;1 -4785;5014;4786;1 -4786;5014;5015;1 -4786;5015;4787;1 -4787;5015;5016;1 -4787;5016;4788;1 -4788;5016;4789;1 -4789;5016;5017;1 -4789;5017;4790;1 -4790;5017;5018;1 -4790;5018;5019;1 -4790;5019;4791;1 -4791;5019;5020;1 -4791;5020;5021;1 -4791;5021;4792;1 -4792;5021;4793;1 -4793;5021;5022;1 -4793;5022;4794;1 -4794;5022;4795;1 -4795;5022;4796;1 -4796;5022;5023;1 -4796;5023;5024;1 -4796;5024;5025;1 -4796;5025;4797;1 -4797;5025;4798;1 -4798;5025;5026;1 -4798;5026;5027;1 -4798;5027;5028;1 -4798;5028;4799;1 -4799;5028;5029;1 -4799;5029;4800;1 -4800;5029;5030;1 -4800;5030;4801;1 -4801;5030;5031;1 -4801;5031;5032;1 -4801;5032;4802;1 -4802;5032;5033;1 -4802;5033;4803;1 -4803;5033;4804;1 -4804;5033;5034;1 -4804;5034;5035;1 -4804;5035;4805;1 -4805;5035;5036;1 -4805;5036;5037;1 -4805;5037;4806;1 -4806;5037;4807;1 -4807;5037;4812;1 -4812;5037;4813;1 -4813;5037;5036;1 -4813;5036;5038;1 -4813;5038;4814;1 -4814;5038;4815;1 -4815;5038;5039;1 -4815;5039;5040;1 -4815;5040;4816;1 -4816;5040;4817;1 -4817;5040;5041;1 -4817;5041;4818;1 -4818;5041;5042;1 -4818;5042;5043;1 -4818;5043;4819;1 -4819;5043;5044;1 -4819;5044;4820;1 -4820;5044;4821;1 -4821;5044;4822;1 -4822;5044;5045;1 -4822;5045;5046;1 -4822;5046;4823;1 -4823;5046;5047;1 -4823;5047;4824;1 -4824;5047;4825;1 -4825;5047;4826;1 -4826;5047;5048;1 -4826;5048;5049;1 -4826;5049;4827;1 -4827;5049;4828;1 -4828;5049;5050;1 -4828;5050;5051;1 -4828;5051;4829;1 -4829;5051;5052;1 -4829;5052;4830;1 -4830;5052;4831;1 -4831;5052;5053;1 -4831;5053;5054;1 -4831;5054;4832;1 -4832;5054;4833;1 -4833;5054;5055;1 -4833;5055;5056;1 -4833;5056;4834;1 -4834;5056;4835;1 -4835;5056;5057;1 -4835;5057;5058;1 -4835;5058;4836;1 -4836;5058;4837;1 -4837;5058;5059;1 -4837;5059;4838;1 -4838;5059;5060;1 -4838;5060;5061;1 -4838;5061;4839;1 -4839;5061;5062;1 -4839;5062;4840;1 -4840;5062;5063;1 -4840;5063;4841;1 -4841;5063;5064;1 -4841;5064;4842;1 -4842;5064;5065;1 -4842;5065;4843;1 -4843;5065;5066;1 -4843;5066;4844;1 -4844;5066;5067;1 -4844;5067;4845;1 -4845;5067;5068;1 -4845;5068;5069;1 -4845;5069;4846;1 -4846;5069;4847;1 -4847;5069;5070;1 -4847;5070;4848;1 -4848;5070;4849;1 -4849;5070;5071;1 -4849;5071;4850;1 -4850;5071;5072;1 -4850;5072;5073;1 -4850;5073;4851;1 -4851;5073;4852;1 -4852;5073;5074;1 -4852;5074;5075;1 -4852;5075;4853;1 -4853;5075;5076;1 -4853;5076;4854;1 -4854;5076;5077;1 -4854;5077;4856;1 -4856;5077;5078;1 -4856;5078;4857;1 -4857;5078;4858;1 -4858;5078;5079;1 -4858;5079;4859;1 -4859;5079;5080;1 -4859;5080;4860;1 -4860;5080;5081;1 -4860;5081;4861;1 -4861;5081;5082;1 -4861;5082;5083;1 -4861;5083;4862;1 -4862;5083;5084;1 -4862;5084;4863;1 -4863;5084;4864;1 -4864;5084;5085;1 -4864;5085;5086;1 -4864;5086;4865;1 -4865;5086;5087;1 -4865;5087;5088;1 -4865;5088;4866;1 -4866;5088;4867;1 -4867;5088;5089;1 -4867;5089;4868;1 -4868;5089;5090;1 -4868;5090;5091;1 -4868;5091;4869;1 -4869;5091;5092;1 -4869;5092;4870;1 -4870;5092;5093;1 -4870;5093;4871;1 -4871;5093;5094;1 -4871;5094;4872;1 -4872;5094;5095;1 -4872;5095;4873;1 -4873;5095;5096;1 -4873;5096;4874;1 -4874;5096;5097;1 -4874;5097;5098;1 -4874;5098;4875;1 -4875;5098;5099;1 -4875;5099;4876;1 -4876;5099;5100;1 -4876;5100;4877;1 -4877;5100;5101;1 -4877;5101;4878;1 -4878;5101;5102;1 -4878;5102;4879;1 -4879;5102;5103;1 -4879;5103;4880;1 -4880;5103;5104;1 -4880;5104;4881;1 -4881;5104;5105;1 -4881;5105;4882;1 -4882;5105;5106;1 -4882;5106;4883;1 -4883;5106;5107;1 -4883;5107;4884;1 -4884;5107;5108;1 -4884;5108;4885;1 -4885;5108;5109;1 -4885;5109;4886;1 -4886;5109;5110;1 -4886;5110;5111;1 -4886;5111;4887;1 -4887;5111;5112;1 -4887;5112;4888;1 -4888;5112;4889;1 -4889;5112;5113;1 -4889;5113;5114;1 -4889;5114;4890;1 -4890;5114;5115;1 -4890;5115;4891;1 -4891;5115;4892;1 -4892;5115;5116;1 -4892;5116;5117;1 -4892;5117;4893;1 -4893;5117;5118;1 -4893;5118;4894;1 -4894;5118;5119;1 -4894;5119;5120;1 -4894;5120;4895;1 -4895;5120;5121;1 -4895;5121;4896;1 -4896;5121;5122;1 -4896;5122;4897;1 -4897;5122;5123;1 -4897;5123;4898;1 -4898;5123;5124;1 -4898;5124;5125;1 -4898;5125;4899;1 -4899;5125;5126;1 -4899;5126;5127;1 -4899;5127;4900;1 -4900;5127;4901;1 -4901;5127;5128;1 -4901;5128;4902;1 -4902;5128;5129;1 -4902;5129;4903;1 -4903;5129;5130;1 -4903;5130;4905;1 -4905;5130;4906;1 -4906;5130;5131;1 -4906;5131;4907;1 -4907;5131;5132;1 -4907;5132;4908;1 -4908;5132;5133;1 -4908;5133;4909;1 -4909;5133;5134;1 -4909;5134;4910;1 -4910;5134;5135;1 -4910;5135;4911;1 -4911;5135;5136;1 -4911;5136;4912;1 -4912;5136;5137;1 -4912;5137;4913;1 -4913;5137;5138;1 -4913;5138;4914;1 -4914;5138;5139;1 -4914;5139;4915;1 -4915;5139;5140;1 -4915;5140;4916;1 -4916;5140;5141;1 -4916;5141;5142;1 -4916;5142;4917;1 -4917;5142;4918;1 -4918;5142;5143;1 -4918;5143;4919;1 -4919;5143;5144;1 -4919;5144;4920;1 -4920;5144;5145;1 -4920;5145;4921;1 -4921;5145;4922;1 -4922;5145;5146;1 -4922;5146;5147;1 -4922;5147;4923;1 -4923;5147;5148;1 -4923;5148;4924;1 -4924;5148;5149;1 -4924;5149;4925;1 -4925;5149;5150;1 -4925;5150;4926;1 -4926;5150;5151;1 -4926;5151;4927;1 -4927;5151;5152;1 -4927;5152;4928;1 -4928;5152;5153;1 -4928;5153;4929;1 -4929;5153;5154;1 -4929;5154;4930;1 -4930;5154;5155;1 -4930;5155;4931;1 -4931;5155;5156;1 -4931;5156;4932;1 -4932;5156;4933;1 -4933;5156;5157;1 -4933;5157;4934;1 -4934;5157;5158;1 -4934;5158;4935;1 -4935;5158;5159;1 -4935;5159;5160;1 -4935;5160;5161;1 -4935;5161;4936;1 -4936;5161;5162;1 -4936;5162;4937;1 -4937;5162;5163;1 -4937;5163;4938;1 -4938;5163;5164;1 -4938;5164;5165;1 -4938;5165;4939;1 -4939;5165;4940;1 -4940;5165;5166;1 -4940;5166;4941;1 -4941;5166;5167;1 -4941;5167;5168;1 -4941;5168;4942;1 -4942;5168;5169;1 -4942;5169;4943;1 -4943;5169;5170;1 -4943;5170;4944;1 -4944;5170;4945;1 -4945;5170;5171;1 -4945;5171;5172;1 -4945;5172;4946;1 -4946;5172;5173;1 -4946;5173;5174;1 -4946;5174;4947;1 -4947;5174;5175;1 -4947;5175;4948;1 -4948;5175;5176;1 -4948;5176;4949;1 -4949;5176;5177;1 -4949;5177;4950;1 -4950;5177;5178;1 -4950;5178;5179;1 -4950;5179;5180;1 -4950;5180;4951;1 -4951;5180;4952;1 -4952;5180;4953;1 -4953;5180;5181;1 -4953;5181;4954;1 -4954;5181;4955;1 -4955;5181;4956;1 -4956;5181;5182;1 -4956;5182;4957;1 -4957;5182;5183;1 -4957;5183;5184;1 -4957;5184;4958;1 -4958;5184;5185;1 -4958;5185;4959;1 -4959;5185;5186;1 -4959;5186;5187;1 -4959;5187;4960;1 -4960;5187;5188;1 -4960;5188;4961;1 -4961;5188;5189;1 -4961;5189;5190;1 -4961;5190;4962;1 -4962;5190;4963;1 -4963;5190;5191;1 -4963;5191;4964;1 -4964;5191;5192;1 -4964;5192;4965;1 -4965;5192;5193;1 -4965;5193;4966;1 -4966;5193;5194;1 -4966;5194;4967;1 -4967;5194;5195;1 -4967;5195;4968;1 -4968;5195;5196;1 -4968;5196;4969;1 -4969;5196;5197;1 -4969;5197;4970;1 -4970;5197;5198;1 -4970;5198;4971;1 -4971;5198;5199;1 -4971;5199;4972;1 -4972;5199;5200;1 -4972;5200;4973;1 -4973;5200;5201;1 -4973;5201;4974;1 -4974;5201;5202;1 -4974;5202;4975;1 -4975;5202;5203;1 -4975;5203;4976;1 -4976;5203;5204;1 -4976;5204;4977;1 -4977;5204;4978;1 -4978;5204;5205;1 -4978;5205;4979;1 -4979;5205;5206;1 -4979;5206;5207;1 -4979;5207;4980;1 -4980;5207;5208;1 -4980;5208;4981;1 -4981;5208;4982;1 -4982;5208;5209;1 -4982;5209;5210;1 -4982;5210;4983;1 -4983;5210;5211;1 -4983;5211;4984;1 -4984;5211;4996;1 -4996;5211;4997;1 -4997;5211;4998;1 -4998;5211;5212;1 -4998;5212;5213;1 -4998;5213;4999;1 -4999;5213;5001;1 -5001;5213;5002;1 -5002;5213;5214;1 -5002;5214;5003;1 -5003;5214;5215;1 -5003;5215;5216;1 -5003;5216;5004;1 -5004;5216;5207;1 -5207;5216;5217;1 -5207;5217;5208;1 -5208;5217;5209;1 -5209;5217;5218;1 -5209;5218;5210;1 -5210;5218;5212;1 -5212;5218;5214;1 -5214;5218;5215;1 -5215;5218;5217;1 -5215;5217;5216;1 -5212;5214;5213;1 -5210;5212;5211;1 -5004;5207;5206;1 -5004;5206;5006;1 -5006;5206;5205;1 -5006;5205;5219;1 -5006;5219;5007;1 -5007;5219;5008;1 -5008;5219;5220;1 -5008;5220;5221;1 -5008;5221;5009;1 -5009;5221;5010;1 -5010;5221;5222;1 -5010;5222;5223;1 -5010;5223;5224;1 -5010;5224;5011;1 -5011;5224;5012;1 -5012;5224;5225;1 -5012;5225;5013;1 -5013;5225;5226;1 -5013;5226;5227;1 -5013;5227;5228;1 -5013;5228;5014;1 -5014;5228;5015;1 -5015;5228;5229;1 -5015;5229;5016;1 -5016;5229;5017;1 -5017;5229;5018;1 -5018;5229;5230;1 -5018;5230;5231;1 -5018;5231;5019;1 -5019;5231;5232;1 -5019;5232;5020;1 -5020;5232;5233;1 -5020;5233;5023;1 -5023;5233;5234;1 -5023;5234;5024;1 -5024;5234;5235;1 -5024;5235;5025;1 -5025;5235;5026;1 -5026;5235;5236;1 -5026;5236;5237;1 -5026;5237;5027;1 -5027;5237;5238;1 -5027;5238;5239;1 -5027;5239;5028;1 -5028;5239;5240;1 -5028;5240;5029;1 -5029;5240;5241;1 -5029;5241;5242;1 -5029;5242;5030;1 -5030;5242;5031;1 -5031;5242;5243;1 -5031;5243;5032;1 -5032;5243;5244;1 -5032;5244;5033;1 -5033;5244;5245;1 -5033;5245;5034;1 -5034;5245;5246;1 -5034;5246;5247;1 -5034;5247;5035;1 -5035;5247;5248;1 -5035;5248;5036;1 -5036;5248;5038;1 -5038;5248;5039;1 -5039;5248;5249;1 -5039;5249;5250;1 -5039;5250;5040;1 -5040;5250;5041;1 -5041;5250;5251;1 -5041;5251;5042;1 -5042;5251;5252;1 -5042;5252;5253;1 -5042;5253;5043;1 -5043;5253;5254;1 -5043;5254;5044;1 -5044;5254;5045;1 -5045;5254;5255;1 -5045;5255;5256;1 -5045;5256;5046;1 -5046;5256;5257;1 -5046;5257;5048;1 -5048;5257;5258;1 -5048;5258;5259;1 -5048;5259;5049;1 -5049;5259;5260;1 -5049;5260;5050;1 -5050;5260;5261;1 -5050;5261;5262;1 -5050;5262;5051;1 -5051;5262;5263;1 -5051;5263;5052;1 -5052;5263;5053;1 -5053;5263;5264;1 -5053;5264;5265;1 -5053;5265;5054;1 -5054;5265;5055;1 -5055;5265;5266;1 -5055;5266;5267;1 -5055;5267;5056;1 -5056;5267;5057;1 -5057;5267;5268;1 -5057;5268;5269;1 -5057;5269;5058;1 -5058;5269;5059;1 -5059;5269;5270;1 -5059;5270;5060;1 -5060;5270;5271;1 -5060;5271;5272;1 -5060;5272;5061;1 -5061;5272;5273;1 -5061;5273;5062;1 -5062;5273;5274;1 -5062;5274;5063;1 -5063;5274;5275;1 -5063;5275;5064;1 -5064;5275;5276;1 -5064;5276;5065;1 -5065;5276;5277;1 -5065;5277;5066;1 -5066;5277;5278;1 -5066;5278;5067;1 -5067;5278;5279;1 -5067;5279;5068;1 -5068;5279;5280;1 -5068;5280;5281;1 -5068;5281;5069;1 -5069;5281;5070;1 -5070;5281;5071;1 -5071;5281;5282;1 -5071;5282;5072;1 -5072;5282;5283;1 -5072;5283;5073;1 -5073;5283;5074;1 -5074;5283;5284;1 -5074;5284;5075;1 -5075;5284;5285;1 -5075;5285;5076;1 -5076;5285;5286;1 -5076;5286;5077;1 -5077;5286;5287;1 -5077;5287;5078;1 -5078;5287;5288;1 -5078;5288;5079;1 -5079;5288;5080;1 -5080;5288;5289;1 -5080;5289;5081;1 -5081;5289;5290;1 -5081;5290;5082;1 -5082;5290;5291;1 -5082;5291;5292;1 -5082;5292;5083;1 -5083;5292;5085;1 -5085;5292;5293;1 -5085;5293;5086;1 -5086;5293;5294;1 -5086;5294;5087;1 -5087;5294;5295;1 -5087;5295;5296;1 -5087;5296;5088;1 -5088;5296;5089;1 -5089;5296;5297;1 -5089;5297;5090;1 -5090;5297;5298;1 -5090;5298;5299;1 -5090;5299;5091;1 -5091;5299;5300;1 -5091;5300;5092;1 -5092;5300;5301;1 -5092;5301;5093;1 -5093;5301;5302;1 -5093;5302;5094;1 -5094;5302;5303;1 -5094;5303;5095;1 -5095;5303;5304;1 -5095;5304;5096;1 -5096;5304;5305;1 -5096;5305;5097;1 -5097;5305;5306;1 -5097;5306;5307;1 -5097;5307;5098;1 -5098;5307;5308;1 -5098;5308;5099;1 -5099;5308;5309;1 -5099;5309;5100;1 -5100;5309;5310;1 -5100;5310;5101;1 -5101;5310;5311;1 -5101;5311;5102;1 -5102;5311;5312;1 -5102;5312;5103;1 -5103;5312;5313;1 -5103;5313;5104;1 -5104;5313;5314;1 -5104;5314;5105;1 -5105;5314;5315;1 -5105;5315;5106;1 -5106;5315;5316;1 -5106;5316;5107;1 -5107;5316;5317;1 -5107;5317;5108;1 -5108;5317;5318;1 -5108;5318;5109;1 -5109;5318;5319;1 -5109;5319;5110;1 -5110;5319;5320;1 -5110;5320;5321;1 -5110;5321;5111;1 -5111;5321;5322;1 -5111;5322;5112;1 -5112;5322;5113;1 -5113;5322;5323;1 -5113;5323;5324;1 -5113;5324;5114;1 -5114;5324;5325;1 -5114;5325;5115;1 -5115;5325;5116;1 -5116;5325;5326;1 -5116;5326;5327;1 -5116;5327;5117;1 -5117;5327;5118;1 -5118;5327;5328;1 -5118;5328;5119;1 -5119;5328;5329;1 -5119;5329;5330;1 -5119;5330;5120;1 -5120;5330;5331;1 -5120;5331;5121;1 -5121;5331;5332;1 -5121;5332;5122;1 -5122;5332;5333;1 -5122;5333;5123;1 -5123;5333;5334;1 -5123;5334;5124;1 -5124;5334;5335;1 -5124;5335;5336;1 -5124;5336;5125;1 -5125;5336;5337;1 -5125;5337;5126;1 -5126;5337;5338;1 -5126;5338;5339;1 -5126;5339;5127;1 -5127;5339;5128;1 -5128;5339;5340;1 -5128;5340;5129;1 -5129;5340;5341;1 -5129;5341;5130;1 -5130;5341;5131;1 -5131;5341;5342;1 -5131;5342;5132;1 -5132;5342;5343;1 -5132;5343;5133;1 -5133;5343;5344;1 -5133;5344;5134;1 -5134;5344;5345;1 -5134;5345;5135;1 -5135;5345;5346;1 -5135;5346;5136;1 -5136;5346;5347;1 -5136;5347;5137;1 -5137;5347;5348;1 -5137;5348;5138;1 -5138;5348;5349;1 -5138;5349;5139;1 -5139;5349;5350;1 -5139;5350;5140;1 -5140;5350;5351;1 -5140;5351;5141;1 -5141;5351;5352;1 -5141;5352;5353;1 -5141;5353;5142;1 -5142;5353;5354;1 -5142;5354;5143;1 -5143;5354;5355;1 -5143;5355;5144;1 -5144;5355;5356;1 -5144;5356;5145;1 -5145;5356;5146;1 -5146;5356;5357;1 -5146;5357;5358;1 -5146;5358;5147;1 -5147;5358;5359;1 -5147;5359;5148;1 -5148;5359;5360;1 -5148;5360;5149;1 -5149;5360;5361;1 -5149;5361;5150;1 -5150;5361;5362;1 -5150;5362;5151;1 -5151;5362;5363;1 -5151;5363;5152;1 -5152;5363;5364;1 -5152;5364;5153;1 -5153;5364;5154;1 -5154;5364;5365;1 -5154;5365;5366;1 -5154;5366;5155;1 -5155;5366;5367;1 -5155;5367;5156;1 -5156;5367;5368;1 -5156;5368;5157;1 -5157;5368;5158;1 -5158;5368;5369;1 -5158;5369;5159;1 -5159;5369;5370;1 -5159;5370;5371;1 -5159;5371;5160;1 -5160;5371;5372;1 -5160;5372;5373;1 -5160;5373;5161;1 -5161;5373;5374;1 -5161;5374;5162;1 -5162;5374;5375;1 -5162;5375;5163;1 -5163;5375;5376;1 -5163;5376;5164;1 -5164;5376;5377;1 -5164;5377;5378;1 -5164;5378;5165;1 -5165;5378;5166;1 -5166;5378;5379;1 -5166;5379;5167;1 -5167;5379;5380;1 -5167;5380;5381;1 -5167;5381;5168;1 -5168;5381;5382;1 -5168;5382;5169;1 -5169;5382;5383;1 -5169;5383;5170;1 -5170;5383;5171;1 -5171;5383;5384;1 -5171;5384;5385;1 -5171;5385;5172;1 -5172;5385;5386;1 -5172;5386;5173;1 -5173;5386;5387;1 -5173;5387;5388;1 -5173;5388;5174;1 -5174;5388;5389;1 -5174;5389;5175;1 -5175;5389;5390;1 -5175;5390;5176;1 -5176;5390;5391;1 -5176;5391;5177;1 -5177;5391;5392;1 -5177;5392;5178;1 -5178;5392;5393;1 -5178;5393;5183;1 -5183;5393;5394;1 -5183;5394;5184;1 -5184;5394;5185;1 -5185;5394;5395;1 -5185;5395;5396;1 -5185;5396;5186;1 -5186;5396;5397;1 -5186;5397;5187;1 -5187;5397;5398;1 -5187;5398;5188;1 -5188;5398;5399;1 -5188;5399;5189;1 -5189;5399;5400;1 -5189;5400;5401;1 -5189;5401;5190;1 -5190;5401;5191;1 -5191;5401;5402;1 -5191;5402;5192;1 -5192;5402;5403;1 -5192;5403;5193;1 -5193;5403;5404;1 -5193;5404;5194;1 -5194;5404;5405;1 -5194;5405;5195;1 -5195;5405;5406;1 -5195;5406;5196;1 -5196;5406;5407;1 -5196;5407;5197;1 -5197;5407;5408;1 -5197;5408;5198;1 -5198;5408;5409;1 -5198;5409;5199;1 -5199;5409;5410;1 -5199;5410;5200;1 -5200;5410;5411;1 -5200;5411;5201;1 -5201;5411;5222;1 -5222;5411;5223;1 -5223;5411;5412;1 -5223;5412;5224;1 -5224;5412;5413;1 -5224;5413;5414;1 -5224;5414;5225;1 -5225;5414;5226;1 -5226;5414;5415;1 -5226;5415;5227;1 -5227;5415;5416;1 -5227;5416;5417;1 -5227;5417;5228;1 -5228;5417;5230;1 -5230;5417;5418;1 -5230;5418;5419;1 -5230;5419;5231;1 -5231;5419;5420;1 -5231;5420;5421;1 -5231;5421;5422;1 -5231;5422;5232;1 -5232;5422;5423;1 -5232;5423;5233;1 -5233;5423;5424;1 -5233;5424;5234;1 -5234;5424;5425;1 -5234;5425;5235;1 -5235;5425;5236;1 -5236;5425;5426;1 -5236;5426;5427;1 -5236;5427;5237;1 -5237;5427;5428;1 -5237;5428;5238;1 -5238;5428;5429;1 -5238;5429;5430;1 -5238;5430;5239;1 -5239;5430;5431;1 -5239;5431;5240;1 -5240;5431;5432;1 -5240;5432;5433;1 -5240;5433;5241;1 -5241;5433;5242;1 -5242;5433;5243;1 -5243;5433;5244;1 -5244;5433;5434;1 -5244;5434;5245;1 -5245;5434;5435;1 -5245;5435;5246;1 -5246;5435;5436;1 -5246;5436;5437;1 -5246;5437;5247;1 -5247;5437;5249;1 -5249;5437;5438;1 -5249;5438;5250;1 -5250;5438;5251;1 -5251;5438;5439;1 -5251;5439;5252;1 -5252;5439;5440;1 -5252;5440;5441;1 -5252;5441;5253;1 -5253;5441;5442;1 -5253;5442;5254;1 -5254;5442;5255;1 -5255;5442;5443;1 -5255;5443;5444;1 -5255;5444;5256;1 -5256;5444;5445;1 -5256;5445;5257;1 -5257;5445;5258;1 -5258;5445;5446;1 -5258;5446;5447;1 -5258;5447;5448;1 -5258;5448;5259;1 -5259;5448;5260;1 -5260;5448;5449;1 -5260;5449;5450;1 -5260;5450;5261;1 -5261;5450;5451;1 -5261;5451;5452;1 -5261;5452;5262;1 -5262;5452;5453;1 -5262;5453;5263;1 -5263;5453;5264;1 -5264;5453;5454;1 -5264;5454;5455;1 -5264;5455;5265;1 -5265;5455;5266;1 -5266;5455;5456;1 -5266;5456;5457;1 -5266;5457;5267;1 -5267;5457;5268;1 -5268;5457;5458;1 -5268;5458;5459;1 -5268;5459;5269;1 -5269;5459;5270;1 -5270;5459;5460;1 -5270;5460;5271;1 -5271;5460;5461;1 -5271;5461;5462;1 -5271;5462;5272;1 -5272;5462;5463;1 -5272;5463;5273;1 -5273;5463;5464;1 -5273;5464;5274;1 -5274;5464;5465;1 -5274;5465;5275;1 -5275;5465;5466;1 -5275;5466;5276;1 -5276;5466;5467;1 -5276;5467;5277;1 -5277;5467;5468;1 -5277;5468;5278;1 -5278;5468;5469;1 -5278;5469;5279;1 -5279;5469;5470;1 -5279;5470;5280;1 -5280;5470;5471;1 -5280;5471;5282;1 -5282;5471;5283;1 -5283;5471;5284;1 -5284;5471;5472;1 -5284;5472;5285;1 -5285;5472;5473;1 -5285;5473;5286;1 -5286;5473;5474;1 -5286;5474;5287;1 -5287;5474;5475;1 -5287;5475;5288;1 -5288;5475;5476;1 -5288;5476;5289;1 -5289;5476;5477;1 -5289;5477;5290;1 -5290;5477;5478;1 -5290;5478;5291;1 -5291;5478;5479;1 -5291;5479;5292;1 -5292;5479;5293;1 -5293;5479;5480;1 -5293;5480;5294;1 -5294;5480;5481;1 -5294;5481;5295;1 -5295;5481;5482;1 -5295;5482;5483;1 -5295;5483;5296;1 -5296;5483;5297;1 -5297;5483;5484;1 -5297;5484;5298;1 -5298;5484;5485;1 -5298;5485;5486;1 -5298;5486;5299;1 -5299;5486;5487;1 -5299;5487;5300;1 -5300;5487;5488;1 -5300;5488;5301;1 -5301;5488;5489;1 -5301;5489;5302;1 -5302;5489;5490;1 -5302;5490;5303;1 -5303;5490;5491;1 -5303;5491;5304;1 -5304;5491;5492;1 -5304;5492;5305;1 -5305;5492;5493;1 -5305;5493;5306;1 -5306;5493;5494;1 -5306;5494;5495;1 -5306;5495;5307;1 -5307;5495;5496;1 -5307;5496;5308;1 -5308;5496;5497;1 -5308;5497;5309;1 -5309;5497;5498;1 -5309;5498;5310;1 -5310;5498;5499;1 -5310;5499;5311;1 -5311;5499;5500;1 -5311;5500;5312;1 -5312;5500;5501;1 -5312;5501;5313;1 -5313;5501;5502;1 -5313;5502;5314;1 -5314;5502;5503;1 -5314;5503;5315;1 -5315;5503;5504;1 -5315;5504;5316;1 -5316;5504;5505;1 -5316;5505;5317;1 -5317;5505;5506;1 -5317;5506;5318;1 -5318;5506;5507;1 -5318;5507;5319;1 -5319;5507;5508;1 -5319;5508;5320;1 -5320;5508;5509;1 -5320;5509;5510;1 -5320;5510;5321;1 -5321;5510;5511;1 -5321;5511;5322;1 -5322;5511;5323;1 -5323;5511;5512;1 -5323;5512;5513;1 -5323;5513;5324;1 -5324;5513;5514;1 -5324;5514;5325;1 -5325;5514;5326;1 -5326;5514;5515;1 -5326;5515;5516;1 -5326;5516;5327;1 -5327;5516;5328;1 -5328;5516;5329;1 -5329;5516;5517;1 -5329;5517;5518;1 -5329;5518;5330;1 -5330;5518;5519;1 -5330;5519;5331;1 -5331;5519;5520;1 -5331;5520;5332;1 -5332;5520;5333;1 -5333;5520;5521;1 -5333;5521;5334;1 -5334;5521;5522;1 -5334;5522;5335;1 -5335;5522;5523;1 -5335;5523;5524;1 -5335;5524;5336;1 -5336;5524;5337;1 -5337;5524;5525;1 -5337;5525;5526;1 -5337;5526;5338;1 -5338;5526;5527;1 -5338;5527;5528;1 -5338;5528;5339;1 -5339;5528;5340;1 -5340;5528;5529;1 -5340;5529;5341;1 -5341;5529;5342;1 -5342;5529;5530;1 -5342;5530;5343;1 -5343;5530;5531;1 -5343;5531;5344;1 -5344;5531;5532;1 -5344;5532;5345;1 -5345;5532;5533;1 -5345;5533;5346;1 -5346;5533;5534;1 -5346;5534;5347;1 -5347;5534;5535;1 -5347;5535;5348;1 -5348;5535;5536;1 -5348;5536;5349;1 -5349;5536;5537;1 -5349;5537;5350;1 -5350;5537;5538;1 -5350;5538;5351;1 -5351;5538;5539;1 -5351;5539;5352;1 -5352;5539;5540;1 -5352;5540;5541;1 -5352;5541;5353;1 -5353;5541;5542;1 -5353;5542;5354;1 -5354;5542;5543;1 -5354;5543;5355;1 -5355;5543;5544;1 -5355;5544;5356;1 -5356;5544;5357;1 -5357;5544;5545;1 -5357;5545;5546;1 -5357;5546;5358;1 -5358;5546;5547;1 -5358;5547;5359;1 -5359;5547;5548;1 -5359;5548;5360;1 -5360;5548;5549;1 -5360;5549;5361;1 -5361;5549;5550;1 -5361;5550;5362;1 -5362;5550;5551;1 -5362;5551;5363;1 -5363;5551;5552;1 -5363;5552;5364;1 -5364;5552;5553;1 -5364;5553;5365;1 -5365;5553;5554;1 -5365;5554;5366;1 -5366;5554;5555;1 -5366;5555;5367;1 -5367;5555;5368;1 -5368;5555;5369;1 -5369;5555;5556;1 -5369;5556;5370;1 -5370;5556;5557;1 -5370;5557;5371;1 -5371;5557;5558;1 -5371;5558;5372;1 -5372;5558;5559;1 -5372;5559;5560;1 -5372;5560;5373;1 -5373;5560;5561;1 -5373;5561;5374;1 -5374;5561;5562;1 -5374;5562;5375;1 -5375;5562;5563;1 -5375;5563;5376;1 -5376;5563;5564;1 -5376;5564;5377;1 -5377;5564;5565;1 -5377;5565;5566;1 -5377;5566;5378;1 -5378;5566;5379;1 -5379;5566;5567;1 -5379;5567;5380;1 -5380;5567;5568;1 -5380;5568;5569;1 -5380;5569;5381;1 -5381;5569;5570;1 -5381;5570;5382;1 -5382;5570;5571;1 -5382;5571;5383;1 -5383;5571;5384;1 -5384;5571;5572;1 -5384;5572;5573;1 -5384;5573;5385;1 -5385;5573;5574;1 -5385;5574;5386;1 -5386;5574;5575;1 -5386;5575;5387;1 -5387;5575;5576;1 -5387;5576;5577;1 -5387;5577;5388;1 -5388;5577;5578;1 -5388;5578;5389;1 -5389;5578;5579;1 -5389;5579;5390;1 -5390;5579;5580;1 -5390;5580;5391;1 -5391;5580;5581;1 -5391;5581;5392;1 -5392;5581;5429;1 -5429;5581;5582;1 -5429;5582;5430;1 -5430;5582;5431;1 -5431;5582;5583;1 -5431;5583;5584;1 -5431;5584;5432;1 -5432;5584;5585;1 -5432;5585;5434;1 -5434;5585;5435;1 -5435;5585;5586;1 -5435;5586;5436;1 -5436;5586;5587;1 -5436;5587;5588;1 -5436;5588;5437;1 -5437;5588;5438;1 -5438;5588;5439;1 -5439;5588;5589;1 -5439;5589;5440;1 -5440;5589;5590;1 -5440;5590;5591;1 -5440;5591;5441;1 -5441;5591;5592;1 -5441;5592;5442;1 -5442;5592;5443;1 -5443;5592;5593;1 -5443;5593;5594;1 -5443;5594;5444;1 -5444;5594;5595;1 -5444;5595;5445;1 -5445;5595;5446;1 -5446;5595;5447;1 -5447;5595;5596;1 -5447;5596;5597;1 -5447;5597;5598;1 -5447;5598;5448;1 -5448;5598;5449;1 -5449;5598;5599;1 -5449;5599;5600;1 -5449;5600;5450;1 -5450;5600;5451;1 -5451;5600;5601;1 -5451;5601;5602;1 -5451;5602;5452;1 -5452;5602;5603;1 -5452;5603;5453;1 -5453;5603;5454;1 -5454;5603;5604;1 -5454;5604;5605;1 -5454;5605;5455;1 -5455;5605;5456;1 -5456;5605;5606;1 -5456;5606;5607;1 -5456;5607;5457;1 -5457;5607;5458;1 -5458;5607;5608;1 -5458;5608;5609;1 -5458;5609;5459;1 -5459;5609;5460;1 -5460;5609;5610;1 -5460;5610;5461;1 -5461;5610;5611;1 -5461;5611;5612;1 -5461;5612;5462;1 -5462;5612;5613;1 -5462;5613;5463;1 -5463;5613;5614;1 -5463;5614;5464;1 -5464;5614;5615;1 -5464;5615;5465;1 -5465;5615;5616;1 -5465;5616;5466;1 -5466;5616;5617;1 -5466;5617;5467;1 -5467;5617;5618;1 -5467;5618;5468;1 -5468;5618;5619;1 -5468;5619;5469;1 -5469;5619;5620;1 -5469;5620;5470;1 -5470;5620;5472;1 -5472;5620;5473;1 -5473;5620;5621;1 -5473;5621;5474;1 -5474;5621;5622;1 -5474;5622;5475;1 -5475;5622;5623;1 -5475;5623;5476;1 -5476;5623;5624;1 -5476;5624;5477;1 -5477;5624;5625;1 -5477;5625;5478;1 -5478;5625;5626;1 -5478;5626;5479;1 -5479;5626;5480;1 -5480;5626;5627;1 -5480;5627;5481;1 -5481;5627;5628;1 -5481;5628;5482;1 -5482;5628;5629;1 -5482;5629;5630;1 -5482;5630;5483;1 -5483;5630;5484;1 -5484;5630;5631;1 -5484;5631;5485;1 -5485;5631;5632;1 -5485;5632;5633;1 -5485;5633;5486;1 -5486;5633;5634;1 -5486;5634;5487;1 -5487;5634;5635;1 -5487;5635;5488;1 -5488;5635;5636;1 -5488;5636;5489;1 -5489;5636;5637;1 -5489;5637;5490;1 -5490;5637;5638;1 -5490;5638;5491;1 -5491;5638;5639;1 -5491;5639;5492;1 -5492;5639;5640;1 -5492;5640;5493;1 -5493;5640;5641;1 -5493;5641;5494;1 -5494;5641;5642;1 -5494;5642;5643;1 -5494;5643;5495;1 -5495;5643;5644;1 -5495;5644;5496;1 -5496;5644;5645;1 -5496;5645;5497;1 -5497;5645;5646;1 -5497;5646;5498;1 -5498;5646;5647;1 -5498;5647;5499;1 -5499;5647;5648;1 -5499;5648;5500;1 -5500;5648;5649;1 -5500;5649;5501;1 -5501;5649;5650;1 -5501;5650;5502;1 -5502;5650;5651;1 -5502;5651;5503;1 -5503;5651;5652;1 -5503;5652;5504;1 -5504;5652;5653;1 -5504;5653;5505;1 -5505;5653;5654;1 -5505;5654;5506;1 -5506;5654;5655;1 -5506;5655;5507;1 -5507;5655;5656;1 -5507;5656;5508;1 -5508;5656;5657;1 -5508;5657;5509;1 -5509;5657;5658;1 -5509;5658;5659;1 -5509;5659;5510;1 -5510;5659;5660;1 -5510;5660;5511;1 -5511;5660;5512;1 -5512;5660;5661;1 -5512;5661;5662;1 -5512;5662;5513;1 -5513;5662;5663;1 -5513;5663;5514;1 -5514;5663;5515;1 -5515;5663;5664;1 -5515;5664;5517;1 -5517;5664;5665;1 -5517;5665;5518;1 -5518;5665;5666;1 -5518;5666;5519;1 -5519;5666;5667;1 -5519;5667;5520;1 -5520;5667;5668;1 -5520;5668;5521;1 -5521;5668;5669;1 -5521;5669;5522;1 -5522;5669;5523;1 -5523;5669;5670;1 -5523;5670;5671;1 -5523;5671;5524;1 -5524;5671;5525;1 -5525;5671;5672;1 -5525;5672;5526;1 -5526;5672;5673;1 -5526;5673;5527;1 -5527;5673;5674;1 -5527;5674;5675;1 -5527;5675;5528;1 -5528;5675;5529;1 -5529;5675;5530;1 -5530;5675;5676;1 -5530;5676;5531;1 -5531;5676;5677;1 -5531;5677;5532;1 -5532;5677;5678;1 -5532;5678;5533;1 -5533;5678;5679;1 -5533;5679;5534;1 -5534;5679;5680;1 -5534;5680;5535;1 -5535;5680;5681;1 -5535;5681;5682;1 -5535;5682;5536;1 -5536;5682;5683;1 -5536;5683;5537;1 -5537;5683;5684;1 -5537;5684;5538;1 -5538;5684;5685;1 -5538;5685;5539;1 -5539;5685;5686;1 -5539;5686;5540;1 -5540;5686;5687;1 -5540;5687;5688;1 -5540;5688;5541;1 -5541;5688;5689;1 -5541;5689;5542;1 -5542;5689;5543;1 -5543;5689;5690;1 -5543;5690;5544;1 -5544;5690;5545;1 -5545;5690;5691;1 -5545;5691;5692;1 -5545;5692;5546;1 -5546;5692;5693;1 -5546;5693;5547;1 -5547;5693;5694;1 -5547;5694;5548;1 -5548;5694;5695;1 -5548;5695;5549;1 -5549;5695;5696;1 -5549;5696;5550;1 -5550;5696;5697;1 -5550;5697;5551;1 -5551;5697;5698;1 -5551;5698;5552;1 -5552;5698;5699;1 -5552;5699;5553;1 -5553;5699;5700;1 -5553;5700;5554;1 -5554;5700;5556;1 -5556;5700;5557;1 -5557;5700;5701;1 -5557;5701;5558;1 -5558;5701;5702;1 -5558;5702;5559;1 -5559;5702;5703;1 -5559;5703;5704;1 -5559;5704;5560;1 -5560;5704;5705;1 -5560;5705;5561;1 -5561;5705;5706;1 -5561;5706;5562;1 -5562;5706;5707;1 -5562;5707;5563;1 -5563;5707;5708;1 -5563;5708;5564;1 -5564;5708;5709;1 -5564;5709;5565;1 -5565;5709;5710;1 -5565;5710;5711;1 -5565;5711;5566;1 -5566;5711;5567;1 -5567;5711;5712;1 -5567;5712;5568;1 -5568;5712;5713;1 -5568;5713;5714;1 -5568;5714;5569;1 -5569;5714;5715;1 -5569;5715;5570;1 -5570;5715;5716;1 -5570;5716;5571;1 -5571;5716;5572;1 -5572;5716;5717;1 -5572;5717;5718;1 -5572;5718;5573;1 -5573;5718;5719;1 -5573;5719;5574;1 -5574;5719;5720;1 -5574;5720;5575;1 -5575;5720;5721;1 -5575;5721;5576;1 -5576;5721;5722;1 -5576;5722;5577;1 -5577;5722;5723;1 -5577;5723;5724;1 -5577;5724;5578;1 -5578;5724;5725;1 -5578;5725;5579;1 -5579;5725;5726;1 -5579;5726;5580;1 -5580;5726;5583;1 -5583;5726;5584;1 -5584;5726;5727;1 -5584;5727;5585;1 -5585;5727;5586;1 -5586;5727;5728;1 -5586;5728;5587;1 -5587;5728;5729;1 -5587;5729;5589;1 -5589;5729;5590;1 -5590;5729;5730;1 -5590;5730;5591;1 -5591;5730;5731;1 -5591;5731;5592;1 -5592;5731;5593;1 -5593;5731;5732;1 -5593;5732;5733;1 -5593;5733;5594;1 -5594;5733;5734;1 -5594;5734;5595;1 -5595;5734;5596;1 -5596;5734;5735;1 -5596;5735;5597;1 -5597;5735;5736;1 -5597;5736;5737;1 -5597;5737;5738;1 -5597;5738;5598;1 -5598;5738;5739;1 -5598;5739;5599;1 -5599;5739;5740;1 -5599;5740;5741;1 -5599;5741;5742;1 -5599;5742;5600;1 -5600;5742;5601;1 -5601;5742;5743;1 -5601;5743;5744;1 -5601;5744;5602;1 -5602;5744;5745;1 -5602;5745;5603;1 -5603;5745;5604;1 -5604;5745;5746;1 -5604;5746;5747;1 -5604;5747;5605;1 -5605;5747;5606;1 -5606;5747;5748;1 -5606;5748;5749;1 -5606;5749;5607;1 -5607;5749;5608;1 -5608;5749;5750;1 -5608;5750;5751;1 -5608;5751;5609;1 -5609;5751;5610;1 -5610;5751;5752;1 -5610;5752;5611;1 -5611;5752;5753;1 -5611;5753;5754;1 -5611;5754;5612;1 -5612;5754;5755;1 -5612;5755;5613;1 -5613;5755;5756;1 -5613;5756;5614;1 -5614;5756;5757;1 -5614;5757;5615;1 -5615;5757;5758;1 -5615;5758;5616;1 -5616;5758;5759;1 -5616;5759;5617;1 -5617;5759;5760;1 -5617;5760;5618;1 -5618;5760;5761;1 -5618;5761;5619;1 -5619;5761;5621;1 -5621;5761;5622;1 -5622;5761;5762;1 -5622;5762;5623;1 -5623;5762;5763;1 -5623;5763;5624;1 -5624;5763;5764;1 -5624;5764;5625;1 -5625;5764;5765;1 -5625;5765;5626;1 -5626;5765;5627;1 -5627;5765;5766;1 -5627;5766;5628;1 -5628;5766;5767;1 -5628;5767;5629;1 -5629;5767;5768;1 -5629;5768;5769;1 -5629;5769;5630;1 -5630;5769;5631;1 -5631;5769;5770;1 -5631;5770;5632;1 -5632;5770;5771;1 -5632;5771;5772;1 -5632;5772;5633;1 -5633;5772;5773;1 -5633;5773;5634;1 -5634;5773;5774;1 -5634;5774;5635;1 -5635;5774;5775;1 -5635;5775;5636;1 -5636;5775;5776;1 -5636;5776;5637;1 -5637;5776;5777;1 -5637;5777;5638;1 -5638;5777;5778;1 -5638;5778;5639;1 -5639;5778;5779;1 -5639;5779;5640;1 -5640;5779;5780;1 -5640;5780;5641;1 -5641;5780;5781;1 -5641;5781;5642;1 -5642;5781;5782;1 -5642;5782;5783;1 -5642;5783;5643;1 -5643;5783;5784;1 -5643;5784;5644;1 -5644;5784;5785;1 -5644;5785;5645;1 -5645;5785;5786;1 -5645;5786;5646;1 -5646;5786;5787;1 -5646;5787;5647;1 -5647;5787;5788;1 -5647;5788;5648;1 -5648;5788;5789;1 -5648;5789;5649;1 -5649;5789;5790;1 -5649;5790;5650;1 -5650;5790;5791;1 -5650;5791;5651;1 -5651;5791;5792;1 -5651;5792;5652;1 -5652;5792;5793;1 -5652;5793;5653;1 -5653;5793;5794;1 -5653;5794;5654;1 -5654;5794;5795;1 -5654;5795;5655;1 -5655;5795;5796;1 -5655;5796;5656;1 -5656;5796;5797;1 -5656;5797;5657;1 -5657;5797;5798;1 -5657;5798;5658;1 -5658;5798;5799;1 -5658;5799;5800;1 -5658;5800;5659;1 -5659;5800;5801;1 -5659;5801;5660;1 -5660;5801;5661;1 -5661;5801;5802;1 -5661;5802;5803;1 -5661;5803;5662;1 -5662;5803;5804;1 -5662;5804;5663;1 -5663;5804;5664;1 -5664;5804;5805;1 -5664;5805;5665;1 -5665;5805;5806;1 -5665;5806;5666;1 -5666;5806;5807;1 -5666;5807;5667;1 -5667;5807;5808;1 -5667;5808;5668;1 -5668;5808;5809;1 -5668;5809;5669;1 -5669;5809;5810;1 -5669;5810;5670;1 -5670;5810;5811;1 -5670;5811;5812;1 -5670;5812;5671;1 -5671;5812;5672;1 -5672;5812;5813;1 -5672;5813;5673;1 -5673;5813;5814;1 -5673;5814;5674;1 -5674;5814;5815;1 -5674;5815;5816;1 -5674;5816;5675;1 -5675;5816;5676;1 -5676;5816;5815;1 -5676;5815;5677;1 -5677;5815;5817;1 -5677;5817;5678;1 -5678;5817;5818;1 -5678;5818;5679;1 -5679;5818;5819;1 -5679;5819;5680;1 -5680;5819;5820;1 -5680;5820;5681;1 -5681;5820;5821;1 -5681;5821;5822;1 -5681;5822;5682;1 -5682;5822;5683;1 -5683;5822;5823;1 -5683;5823;5684;1 -5684;5823;5824;1 -5684;5824;5825;1 -5684;5825;5685;1 -5685;5825;5826;1 -5685;5826;5827;1 -5685;5827;5686;1 -5686;5827;5828;1 -5686;5828;5687;1 -5687;5828;5829;1 -5687;5829;5830;1 -5687;5830;5688;1 -5688;5830;5831;1 -5688;5831;5689;1 -5689;5831;5690;1 -5690;5831;5691;1 -5691;5831;5832;1 -5691;5832;5833;1 -5691;5833;5692;1 -5692;5833;5834;1 -5692;5834;5693;1 -5693;5834;5835;1 -5693;5835;5694;1 -5694;5835;5836;1 -5694;5836;5695;1 -5695;5836;5837;1 -5695;5837;5696;1 -5696;5837;5838;1 -5696;5838;5697;1 -5697;5838;5839;1 -5697;5839;5698;1 -5698;5839;5840;1 -5698;5840;5699;1 -5699;5840;5701;1 -5701;5840;5702;1 -5702;5840;5841;1 -5702;5841;5703;1 -5703;5841;5842;1 -5703;5842;5843;1 -5703;5843;5704;1 -5704;5843;5844;1 -5704;5844;5705;1 -5705;5844;5845;1 -5705;5845;5706;1 -5706;5845;5846;1 -5706;5846;5707;1 -5707;5846;5847;1 -5707;5847;5708;1 -5708;5847;5848;1 -5708;5848;5709;1 -5709;5848;5849;1 -5709;5849;5710;1 -5710;5849;5850;1 -5710;5850;5851;1 -5710;5851;5711;1 -5711;5851;5712;1 -5712;5851;5852;1 -5712;5852;5713;1 -5713;5852;5853;1 -5713;5853;5854;1 -5713;5854;5714;1 -5714;5854;5855;1 -5714;5855;5715;1 -5715;5855;5856;1 -5715;5856;5716;1 -5716;5856;5717;1 -5717;5856;5857;1 -5717;5857;5858;1 -5717;5858;5718;1 -5718;5858;5859;1 -5718;5859;5719;1 -5719;5859;5860;1 -5719;5860;5720;1 -5720;5860;5861;1 -5720;5861;5721;1 -5721;5861;5862;1 -5721;5862;5722;1 -5722;5862;5863;1 -5722;5863;5864;1 -5722;5864;5723;1 -5723;5864;5865;1 -5723;5865;5724;1 -5724;5865;5866;1 -5724;5866;5867;1 -5724;5867;5725;1 -5725;5867;5868;1 -5725;5868;5726;1 -5726;5868;5727;1 -5727;5868;5728;1 -5728;5868;5869;1 -5728;5869;5870;1 -5728;5870;5729;1 -5729;5870;5730;1 -5730;5870;5871;1 -5730;5871;5872;1 -5730;5872;5732;1 -5732;5872;5873;1 -5732;5873;5874;1 -5732;5874;5733;1 -5733;5874;5875;1 -5733;5875;5734;1 -5734;5875;5735;1 -5735;5875;5876;1 -5735;5876;5736;1 -5736;5876;5877;1 -5736;5877;5878;1 -5736;5878;5737;1 -5737;5878;5879;1 -5737;5879;5738;1 -5738;5879;5880;1 -5738;5880;5881;1 -5738;5881;5739;1 -5739;5881;5882;1 -5739;5882;5740;1 -5740;5882;5883;1 -5740;5883;5884;1 -5740;5884;5741;1 -5741;5884;5885;1 -5741;5885;5886;1 -5741;5886;5742;1 -5742;5886;5743;1 -5743;5886;5887;1 -5743;5887;5888;1 -5743;5888;5744;1 -5744;5888;5889;1 -5744;5889;5745;1 -5745;5889;5746;1 -5746;5889;5890;1 -5746;5890;5891;1 -5746;5891;5747;1 -5747;5891;5748;1 -5748;5891;5892;1 -5748;5892;5893;1 -5748;5893;5749;1 -5749;5893;5750;1 -5750;5893;5894;1 -5750;5894;5895;1 -5750;5895;5751;1 -5751;5895;5752;1 -5752;5895;5896;1 -5752;5896;5753;1 -5753;5896;5897;1 -5753;5897;5898;1 -5753;5898;5754;1 -5754;5898;5899;1 -5754;5899;5755;1 -5755;5899;5900;1 -5755;5900;5756;1 -5756;5900;5901;1 -5756;5901;5757;1 -5757;5901;5902;1 -5757;5902;5758;1 -5758;5902;5903;1 -5758;5903;5759;1 -5759;5903;5904;1 -5759;5904;5760;1 -5760;5904;5762;1 -5762;5904;5763;1 -5763;5904;5905;1 -5763;5905;5764;1 -5764;5905;5906;1 -5764;5906;5765;1 -5765;5906;5766;1 -5766;5906;5907;1 -5766;5907;5767;1 -5767;5907;5908;1 -5767;5908;5768;1 -5768;5908;5909;1 -5768;5909;5910;1 -5768;5910;5769;1 -5769;5910;5770;1 -5770;5910;5911;1 -5770;5911;5771;1 -5771;5911;5912;1 -5771;5912;5913;1 -5771;5913;5772;1 -5772;5913;5914;1 -5772;5914;5773;1 -5773;5914;5915;1 -5773;5915;5774;1 -5774;5915;5916;1 -5774;5916;5775;1 -5775;5916;5917;1 -5775;5917;5776;1 -5776;5917;5918;1 -5776;5918;5777;1 -5777;5918;5919;1 -5777;5919;5778;1 -5778;5919;5920;1 -5778;5920;5779;1 -5779;5920;5921;1 -5779;5921;5780;1 -5780;5921;5922;1 -5780;5922;5781;1 -5781;5922;5923;1 -5781;5923;5782;1 -5782;5923;5924;1 -5782;5924;5925;1 -5782;5925;5783;1 -5783;5925;5926;1 -5783;5926;5784;1 -5784;5926;5927;1 -5784;5927;5785;1 -5785;5927;5928;1 -5785;5928;5786;1 -5786;5928;5929;1 -5786;5929;5787;1 -5787;5929;5930;1 -5787;5930;5788;1 -5788;5930;5931;1 -5788;5931;5789;1 -5789;5931;5932;1 -5789;5932;5790;1 -5790;5932;5933;1 -5790;5933;5791;1 -5791;5933;5934;1 -5791;5934;5792;1 -5792;5934;5935;1 -5792;5935;5793;1 -5793;5935;5936;1 -5793;5936;5794;1 -5794;5936;5937;1 -5794;5937;5795;1 -5795;5937;5938;1 -5795;5938;5796;1 -5796;5938;5939;1 -5796;5939;5797;1 -5797;5939;5940;1 -5797;5940;5798;1 -5798;5940;5941;1 -5798;5941;5799;1 -5799;5941;5942;1 -5799;5942;5943;1 -5799;5943;5800;1 -5800;5943;5944;1 -5800;5944;5801;1 -5801;5944;5802;1 -5802;5944;5945;1 -5802;5945;5946;1 -5802;5946;5803;1 -5803;5946;5947;1 -5803;5947;5804;1 -5804;5947;5805;1 -5805;5947;5948;1 -5805;5948;5806;1 -5806;5948;5949;1 -5806;5949;5807;1 -5807;5949;5950;1 -5807;5950;5808;1 -5808;5950;5809;1 -5809;5950;5951;1 -5809;5951;5952;1 -5809;5952;5810;1 -5810;5952;5953;1 -5810;5953;5811;1 -5811;5953;5954;1 -5811;5954;5813;1 -5813;5954;5814;1 -5814;5954;5817;1 -5817;5954;5818;1 -5818;5954;5953;1 -5818;5953;5819;1 -5819;5953;5952;1 -5819;5952;5820;1 -5820;5952;5955;1 -5820;5955;5821;1 -5821;5955;5956;1 -5821;5956;5957;1 -5821;5957;5822;1 -5822;5957;5823;1 -5823;5957;5958;1 -5823;5958;5824;1 -5824;5958;5959;1 -5824;5959;5960;1 -5824;5960;5825;1 -5825;5960;5826;1 -5826;5960;5961;1 -5826;5961;5962;1 -5826;5962;5827;1 -5827;5962;5828;1 -5828;5962;5963;1 -5828;5963;5829;1 -5829;5963;5964;1 -5829;5964;5965;1 -5829;5965;5830;1 -5830;5965;5832;1 -5832;5965;5966;1 -5832;5966;5967;1 -5832;5967;5833;1 -5833;5967;5968;1 -5833;5968;5834;1 -5834;5968;5969;1 -5834;5969;5835;1 -5835;5969;5970;1 -5835;5970;5836;1 -5836;5970;5971;1 -5836;5971;5837;1 -5837;5971;5972;1 -5837;5972;5838;1 -5838;5972;5973;1 -5838;5973;5839;1 -5839;5973;5841;1 -5841;5973;5842;1 -5842;5973;5974;1 -5842;5974;5975;1 -5842;5975;5843;1 -5843;5975;5976;1 -5843;5976;5844;1 -5844;5976;5977;1 -5844;5977;5845;1 -5845;5977;5978;1 -5845;5978;5846;1 -5846;5978;5979;1 -5846;5979;5847;1 -5847;5979;5980;1 -5847;5980;5848;1 -5848;5980;5981;1 -5848;5981;5849;1 -5849;5981;5982;1 -5849;5982;5850;1 -5850;5982;5983;1 -5850;5983;5984;1 -5850;5984;5851;1 -5851;5984;5852;1 -5852;5984;5985;1 -5852;5985;5853;1 -5853;5985;5986;1 -5853;5986;5987;1 -5853;5987;5854;1 -5854;5987;5988;1 -5854;5988;5855;1 -5855;5988;5989;1 -5855;5989;5856;1 -5856;5989;5857;1 -5857;5989;5990;1 -5857;5990;5991;1 -5857;5991;5858;1 -5858;5991;5992;1 -5858;5992;5859;1 -5859;5992;5993;1 -5859;5993;5860;1 -5860;5993;5994;1 -5860;5994;5861;1 -5861;5994;5995;1 -5861;5995;5862;1 -5862;5995;5996;1 -5862;5996;5863;1 -5863;5996;5997;1 -5863;5997;5998;1 -5863;5998;5999;1 -5863;5999;5864;1 -5864;5999;5877;1 -5877;5999;5878;1 -5878;5999;6000;1 -5878;6000;5879;1 -5879;6000;6001;1 -5879;6001;5880;1 -5880;6001;6002;1 -5880;6002;5881;1 -5881;6002;6003;1 -5881;6003;6004;1 -5881;6004;5882;1 -5882;6004;6005;1 -5882;6005;5883;1 -5883;6005;6006;1 -5883;6006;6007;1 -5883;6007;5884;1 -5884;6007;6008;1 -5884;6008;5885;1 -5885;6008;6009;1 -5885;6009;6010;1 -5885;6010;5886;1 -5886;6010;5887;1 -5887;6010;6011;1 -5887;6011;6012;1 -5887;6012;5888;1 -5888;6012;6013;1 -5888;6013;5889;1 -5889;6013;5890;1 -5890;6013;6014;1 -5890;6014;6015;1 -5890;6015;5891;1 -5891;6015;5892;1 -5892;6015;6016;1 -5892;6016;6017;1 -5892;6017;5893;1 -5893;6017;5894;1 -5894;6017;6018;1 -5894;6018;6019;1 -5894;6019;5895;1 -5895;6019;5896;1 -5896;6019;6020;1 -5896;6020;5897;1 -5897;6020;6021;1 -5897;6021;6022;1 -5897;6022;5898;1 -5898;6022;6023;1 -5898;6023;5899;1 -5899;6023;6024;1 -5899;6024;5900;1 -5900;6024;6025;1 -5900;6025;5901;1 -5901;6025;6026;1 -5901;6026;5902;1 -5902;6026;6027;1 -5902;6027;5903;1 -5903;6027;5905;1 -5905;6027;5906;1 -5906;6027;5907;1 -5907;6027;6026;1 -5907;6026;5908;1 -5908;6026;6025;1 -5908;6025;5909;1 -5909;6025;6024;1 -5909;6024;6028;1 -5909;6028;5910;1 -5910;6028;5911;1 -5911;6028;6029;1 -5911;6029;5912;1 -5912;6029;6030;1 -5912;6030;6031;1 -5912;6031;5913;1 -5913;6031;6032;1 -5913;6032;5914;1 -5914;6032;6033;1 -5914;6033;5915;1 -5915;6033;6034;1 -5915;6034;5916;1 -5916;6034;6035;1 -5916;6035;5917;1 -5917;6035;6036;1 -5917;6036;5918;1 -5918;6036;6037;1 -5918;6037;5919;1 -5919;6037;6038;1 -5919;6038;5920;1 -5920;6038;6039;1 -5920;6039;5921;1 -5921;6039;6040;1 -5921;6040;5922;1 -5922;6040;6041;1 -5922;6041;5923;1 -5923;6041;6042;1 -5923;6042;5924;1 -5924;6042;6043;1 -5924;6043;6044;1 -5924;6044;5925;1 -5925;6044;6045;1 -5925;6045;5926;1 -5926;6045;6046;1 -5926;6046;5927;1 -5927;6046;6047;1 -5927;6047;5928;1 -5928;6047;6048;1 -5928;6048;5929;1 -5929;6048;6049;1 -5929;6049;5930;1 -5930;6049;6050;1 -5930;6050;5931;1 -5931;6050;6051;1 -5931;6051;5932;1 -5932;6051;6052;1 -5932;6052;5933;1 -5933;6052;6053;1 -5933;6053;5934;1 -5934;6053;6054;1 -5934;6054;5935;1 -5935;6054;6055;1 -5935;6055;5936;1 -5936;6055;6056;1 -5936;6056;5937;1 -5937;6056;6057;1 -5937;6057;5938;1 -5938;6057;6058;1 -5938;6058;5939;1 -5939;6058;5967;1 -5967;6058;5968;1 -5968;6058;6059;1 -5968;6059;5969;1 -5969;6059;6060;1 -5969;6060;5970;1 -5970;6060;6061;1 -5970;6061;5971;1 -5971;6061;6062;1 -5971;6062;5972;1 -5972;6062;5974;1 -5974;6062;6063;1 -5974;6063;5975;1 -5975;6063;6064;1 -5975;6064;5976;1 -5976;6064;6065;1 -5976;6065;5977;1 -5977;6065;6066;1 -5977;6066;5978;1 -5978;6066;6067;1 -5978;6067;5979;1 -5979;6067;6068;1 -5979;6068;5980;1 -5980;6068;6069;1 -5980;6069;5981;1 -5981;6069;6070;1 -5981;6070;5982;1 -5982;6070;6071;1 -5982;6071;5983;1 -5983;6071;6072;1 -5983;6072;6073;1 -5983;6073;5984;1 -5984;6073;5985;1 -5985;6073;6074;1 -5985;6074;5986;1 -5986;6074;6075;1 -5986;6075;6076;1 -5986;6076;5987;1 -5987;6076;6077;1 -5987;6077;5988;1 -5988;6077;6078;1 -5988;6078;5989;1 -5989;6078;5990;1 -5990;6078;6079;1 -5990;6079;6080;1 -5990;6080;5991;1 -5991;6080;6081;1 -5991;6081;5992;1 -5992;6081;6082;1 -5992;6082;5993;1 -5993;6082;6083;1 -5993;6083;5994;1 -5994;6083;6084;1 -5994;6084;5995;1 -5995;6084;6085;1 -5995;6085;5996;1 -5996;6085;5997;1 -5997;6085;6086;1 -5997;6086;6087;1 -5997;6087;6088;1 -5997;6088;5998;1 -5998;6088;6089;1 -5998;6089;5999;1 -5999;6089;6000;1 -6000;6089;6001;1 -6001;6089;6090;1 -6001;6090;6002;1 -6002;6090;6091;1 -6002;6091;6003;1 -6003;6091;6092;1 -6003;6092;6093;1 -6003;6093;6004;1 -6004;6093;6094;1 -6004;6094;6005;1 -6005;6094;6095;1 -6005;6095;6006;1 -6006;6095;6096;1 -6006;6096;6097;1 -6006;6097;6098;1 -6006;6098;6007;1 -6007;6098;6099;1 -6007;6099;6008;1 -6008;6099;6009;1 -6009;6099;6100;1 -6009;6100;6101;1 -6009;6101;6010;1 -6010;6101;6011;1 -6011;6101;6102;1 -6011;6102;6103;1 -6011;6103;6012;1 -6012;6103;6104;1 -6012;6104;6013;1 -6013;6104;6014;1 -6014;6104;6105;1 -6014;6105;6106;1 -6014;6106;6015;1 -6015;6106;6016;1 -6016;6106;6107;1 -6016;6107;6108;1 -6016;6108;6017;1 -6017;6108;6018;1 -6018;6108;6109;1 -6018;6109;6110;1 -6018;6110;6019;1 -6019;6110;6020;1 -6020;6110;6111;1 -6020;6111;6021;1 -6021;6111;6112;1 -6021;6112;6030;1 -6030;6112;6031;1 -6031;6112;6113;1 -6031;6113;6032;1 -6032;6113;6114;1 -6032;6114;6033;1 -6033;6114;6115;1 -6033;6115;6034;1 -6034;6115;6116;1 -6034;6116;6035;1 -6035;6116;6117;1 -6035;6117;6036;1 -6036;6117;6118;1 -6036;6118;6037;1 -6037;6118;6119;1 -6037;6119;6038;1 -6038;6119;6120;1 -6038;6120;6039;1 -6039;6120;6121;1 -6039;6121;6040;1 -6040;6121;6122;1 -6040;6122;6041;1 -6041;6122;6123;1 -6041;6123;6042;1 -6042;6123;6124;1 -6042;6124;6043;1 -6043;6124;6125;1 -6043;6125;6126;1 -6043;6126;6044;1 -6044;6126;6127;1 -6044;6127;6045;1 -6045;6127;6128;1 -6045;6128;6046;1 -6046;6128;6129;1 -6046;6129;6047;1 -6047;6129;6130;1 -6047;6130;6048;1 -6048;6130;6131;1 -6048;6131;6049;1 -6049;6131;6132;1 -6049;6132;6050;1 -6050;6132;6133;1 -6050;6133;6051;1 -6051;6133;6134;1 -6051;6134;6052;1 -6052;6134;6135;1 -6052;6135;6053;1 -6053;6135;6136;1 -6053;6136;6054;1 -6054;6136;6137;1 -6054;6137;6055;1 -6055;6137;6138;1 -6055;6138;6056;1 -6056;6138;6139;1 -6056;6139;6057;1 -6057;6139;6059;1 -6059;6139;6060;1 -6060;6139;6140;1 -6060;6140;6061;1 -6061;6140;6141;1 -6061;6141;6062;1 -6062;6141;6063;1 -6063;6141;6142;1 -6063;6142;6064;1 -6064;6142;6143;1 -6064;6143;6065;1 -6065;6143;6144;1 -6065;6144;6066;1 -6066;6144;6145;1 -6066;6145;6067;1 -6067;6145;6146;1 -6067;6146;6068;1 -6068;6146;6147;1 -6068;6147;6069;1 -6069;6147;6148;1 -6069;6148;6070;1 -6070;6148;6149;1 -6070;6149;6071;1 -6071;6149;6150;1 -6071;6150;6072;1 -6072;6150;6151;1 -6072;6151;6152;1 -6072;6152;6073;1 -6073;6152;6074;1 -6074;6152;6153;1 -6074;6153;6075;1 -6075;6153;6154;1 -6075;6154;6155;1 -6075;6155;6076;1 -6076;6155;6156;1 -6076;6156;6077;1 -6077;6156;6157;1 -6077;6157;6078;1 -6078;6157;6079;1 -6079;6157;6158;1 -6079;6158;6159;1 -6079;6159;6080;1 -6080;6159;6160;1 -6080;6160;6081;1 -6081;6160;6161;1 -6081;6161;6082;1 -6082;6161;6162;1 -6082;6162;6083;1 -6083;6162;6163;1 -6083;6163;6084;1 -6084;6163;6164;1 -6084;6164;6085;1 -6085;6164;6086;1 -6086;6164;6165;1 -6086;6165;6166;1 -6086;6166;6087;1 -6087;6166;6167;1 -6087;6167;6168;1 -6087;6168;6088;1 -6088;6168;6091;1 -6091;6168;6169;1 -6091;6169;6092;1 -6092;6169;6093;1 -6093;6169;6170;1 -6093;6170;6094;1 -6094;6170;6171;1 -6094;6171;6095;1 -6095;6171;6172;1 -6095;6172;6096;1 -6096;6172;6173;1 -6096;6173;6174;1 -6096;6174;6097;1 -6097;6174;6175;1 -6097;6175;6098;1 -6098;6175;6176;1 -6098;6176;6099;1 -6099;6176;6100;1 -6100;6176;6177;1 -6100;6177;6101;1 -6101;6177;6102;1 -6102;6177;6178;1 -6102;6178;6179;1 -6102;6179;6103;1 -6103;6179;6180;1 -6103;6180;6104;1 -6104;6180;6105;1 -6105;6180;6181;1 -6105;6181;6182;1 -6105;6182;6106;1 -6106;6182;6107;1 -6107;6182;6183;1 -6107;6183;6184;1 -6107;6184;6108;1 -6108;6184;6109;1 -6109;6184;6185;1 -6109;6185;6186;1 -6109;6186;6110;1 -6110;6186;6111;1 -6111;6186;6187;1 -6111;6187;6112;1 -6112;6187;6113;1 -6113;6187;6188;1 -6113;6188;6114;1 -6114;6188;6189;1 -6114;6189;6115;1 -6115;6189;6190;1 -6115;6190;6116;1 -6116;6190;6191;1 -6116;6191;6117;1 -6117;6191;6192;1 -6117;6192;6118;1 -6118;6192;6193;1 -6118;6193;6119;1 -6119;6193;6194;1 -6119;6194;6120;1 -6120;6194;6195;1 -6120;6195;6121;1 -6121;6195;6196;1 -6121;6196;6122;1 -6122;6196;6197;1 -6122;6197;6123;1 -6123;6197;6198;1 -6123;6198;6124;1 -6124;6198;6199;1 -6124;6199;6125;1 -6125;6199;6200;1 -6125;6200;6201;1 -6125;6201;6126;1 -6126;6201;6202;1 -6126;6202;6127;1 -6127;6202;6203;1 -6127;6203;6128;1 -6128;6203;6204;1 -6128;6204;6129;1 -6129;6204;6205;1 -6129;6205;6130;1 -6130;6205;6206;1 -6130;6206;6131;1 -6131;6206;6207;1 -6131;6207;6132;1 -6132;6207;6208;1 -6132;6208;6133;1 -6133;6208;6209;1 -6133;6209;6134;1 -6134;6209;6210;1 -6134;6210;6135;1 -6135;6210;6211;1 -6135;6211;6136;1 -6136;6211;6212;1 -6136;6212;6137;1 -6137;6212;6213;1 -6137;6213;6138;1 -6138;6213;6140;1 -6140;6213;6141;1 -6141;6213;6142;1 -6142;6213;6212;1 -6142;6212;6143;1 -6143;6212;6211;1 -6143;6211;6144;1 -6144;6211;6210;1 -6144;6210;6145;1 -6145;6210;6209;1 -6145;6209;6146;1 -6146;6209;6208;1 -6146;6208;6147;1 -6147;6208;6207;1 -6147;6207;6148;1 -6148;6207;6206;1 -6148;6206;6149;1 -6149;6206;6205;1 -6149;6205;6150;1 -6150;6205;6204;1 -6150;6204;6151;1 -6151;6204;6203;1 -6151;6203;6214;1 -6151;6214;6152;1 -6152;6214;6153;1 -6153;6214;6215;1 -6153;6215;6154;1 -6154;6215;6216;1 -6154;6216;6217;1 -6154;6217;6155;1 -6155;6217;6218;1 -6155;6218;6156;1 -6156;6218;6219;1 -6156;6219;6157;1 -6157;6219;6158;1 -6158;6219;6220;1 -6158;6220;6221;1 -6158;6221;6159;1 -6159;6221;6222;1 -6159;6222;6160;1 -6160;6222;6223;1 -6160;6223;6161;1 -6161;6223;6224;1 -6161;6224;6162;1 -6162;6224;6225;1 -6162;6225;6163;1 -6163;6225;6226;1 -6163;6226;6164;1 -6164;6226;6165;1 -6165;6226;6227;1 -6165;6227;6228;1 -6165;6228;6166;1 -6166;6228;6229;1 -6166;6229;6167;1 -6167;6229;6230;1 -6167;6230;6231;1 -6167;6231;6232;1 -6167;6232;6168;1 -6168;6232;6169;1 -6169;6232;6233;1 -6169;6233;6170;1 -6170;6233;6234;1 -6170;6234;6171;1 -6171;6234;6235;1 -6171;6235;6172;1 -6172;6235;6236;1 -6172;6236;6237;1 -6172;6237;6173;1 -6173;6237;6238;1 -6173;6238;6174;1 -6174;6238;6239;1 -6174;6239;6240;1 -6174;6240;6175;1 -6175;6240;6241;1 -6175;6241;6176;1 -6176;6241;6177;1 -6177;6241;6178;1 -6178;6241;6242;1 -6178;6242;6243;1 -6178;6243;6179;1 -6179;6243;6244;1 -6179;6244;6180;1 -6180;6244;6181;1 -6181;6244;6245;1 -6181;6245;6246;1 -6181;6246;6182;1 -6182;6246;6183;1 -6183;6246;6247;1 -6183;6247;6248;1 -6183;6248;6184;1 -6184;6248;6185;1 -6185;6248;6249;1 -6185;6249;6250;1 -6185;6250;6186;1 -6186;6250;6187;1 -6187;6250;6188;1 -6188;6250;6251;1 -6188;6251;6189;1 -6189;6251;6252;1 -6189;6252;6190;1 -6190;6252;6253;1 -6190;6253;6191;1 -6191;6253;6254;1 -6191;6254;6192;1 -6192;6254;6255;1 -6192;6255;6193;1 -6193;6255;6256;1 -6193;6256;6194;1 -6194;6256;6257;1 -6194;6257;6195;1 -6195;6257;6258;1 -6195;6258;6196;1 -6196;6258;6259;1 -6196;6259;6197;1 -6197;6259;6260;1 -6197;6260;6198;1 -6198;6260;6261;1 -6198;6261;6199;1 -6199;6261;6262;1 -6199;6262;6200;1 -6200;6262;6263;1 -6200;6263;6216;1 -6216;6263;6217;1 -6217;6263;6264;1 -6217;6264;6218;1 -6218;6264;6265;1 -6218;6265;6219;1 -6219;6265;6220;1 -6220;6265;6266;1 -6220;6266;6267;1 -6220;6267;6221;1 -6221;6267;6268;1 -6221;6268;6222;1 -6222;6268;6269;1 -6222;6269;6223;1 -6223;6269;6270;1 -6223;6270;6224;1 -6224;6270;6271;1 -6224;6271;6225;1 -6225;6271;6272;1 -6225;6272;6226;1 -6226;6272;6227;1 -6227;6272;6273;1 -6227;6273;6274;1 -6227;6274;6275;1 -6227;6275;6228;1 -6228;6275;6276;1 -6228;6276;6229;1 -6229;6276;6230;1 -6230;6276;6277;1 -6230;6277;6278;1 -6230;6278;6279;1 -6230;6279;6231;1 -6231;6279;6232;1 -6232;6279;6280;1 -6232;6280;6233;1 -6233;6280;6234;1 -6234;6280;6235;1 -6235;6280;6281;1 -6235;6281;6236;1 -6236;6281;6282;1 -6236;6282;6237;1 -6237;6282;6283;1 -6237;6283;6284;1 -6237;6284;6238;1 -6238;6284;6285;1 -6238;6285;6239;1 -6239;6285;6286;1 -6239;6286;6287;1 -6239;6287;6240;1 -6240;6287;6242;1 -6242;6287;6288;1 -6242;6288;6243;1 -6243;6288;6289;1 -6243;6289;6244;1 -6244;6289;6245;1 -6245;6289;6290;1 -6245;6290;6291;1 -6245;6291;6246;1 -6246;6291;6247;1 -6247;6291;6292;1 -6247;6292;6293;1 -6247;6293;6248;1 -6248;6293;6249;1 -6249;6293;6294;1 -6249;6294;6251;1 -6251;6294;6252;1 -6252;6294;6295;1 -6252;6295;6253;1 -6253;6295;6296;1 -6253;6296;6254;1 -6254;6296;6297;1 -6254;6297;6255;1 -6255;6297;6298;1 -6255;6298;6256;1 -6256;6298;6299;1 -6256;6299;6257;1 -6257;6299;6300;1 -6257;6300;6258;1 -6258;6300;6301;1 -6258;6301;6259;1 -6259;6301;6302;1 -6259;6302;6260;1 -6260;6302;6303;1 -6260;6303;6261;1 -6261;6303;6304;1 -6261;6304;6262;1 -6262;6304;6305;1 -6262;6305;6263;1 -6263;6305;6264;1 -6264;6305;6306;1 -6264;6306;6265;1 -6265;6306;6266;1 -6266;6306;6307;1 -6266;6307;6308;1 -6266;6308;6267;1 -6267;6308;6309;1 -6267;6309;6268;1 -6268;6309;6310;1 -6268;6310;6269;1 -6269;6310;6311;1 -6269;6311;6270;1 -6270;6311;6312;1 -6270;6312;6271;1 -6271;6312;6272;1 -6272;6312;6273;1 -6273;6312;6313;1 -6273;6313;6274;1 -6274;6313;6314;1 -6274;6314;6315;1 -6274;6315;6275;1 -6275;6315;6316;1 -6275;6316;6276;1 -6276;6316;6277;1 -6277;6316;6317;1 -6277;6317;6318;1 -6277;6318;6278;1 -6278;6318;6319;1 -6278;6319;6320;1 -6278;6320;6279;1 -6279;6320;6281;1 -6281;6320;6282;1 -6282;6320;6321;1 -6282;6321;6283;1 -6283;6321;6322;1 -6283;6322;6323;1 -6283;6323;6284;1 -6284;6323;6324;1 -6284;6324;6285;1 -6285;6324;6325;1 -6285;6325;6286;1 -6286;6325;6326;1 -6286;6326;6327;1 -6286;6327;6287;1 -6287;6327;6288;1 -6288;6327;6328;1 -6288;6328;6289;1 -6289;6328;6290;1 -6290;6328;6329;1 -6290;6329;6330;1 -6290;6330;6291;1 -6291;6330;6292;1 -6292;6330;6331;1 -6292;6331;6332;1 -6292;6332;6293;1 -6293;6332;6294;1 -6294;6332;6295;1 -6295;6332;6333;1 -6295;6333;6296;1 -6296;6333;6334;1 -6296;6334;6297;1 -6297;6334;6335;1 -6297;6335;6298;1 -6298;6335;6336;1 -6298;6336;6299;1 -6299;6336;6337;1 -6299;6337;6300;1 -6300;6337;6338;1 -6300;6338;6301;1 -6301;6338;6339;1 -6301;6339;6302;1 -6302;6339;6340;1 -6302;6340;6303;1 -6303;6340;6341;1 -6303;6341;6304;1 -6304;6341;6342;1 -6304;6342;6305;1 -6305;6342;6306;1 -6306;6342;6307;1 -6307;6342;6343;1 -6307;6343;6344;1 -6307;6344;6308;1 -6308;6344;6345;1 -6308;6345;6309;1 -6309;6345;6346;1 -6309;6346;6310;1 -6310;6346;6347;1 -6310;6347;6311;1 -6311;6347;6313;1 -6313;6347;6314;1 -6314;6347;6348;1 -6314;6348;6349;1 -6314;6349;6315;1 -6315;6349;6350;1 -6315;6350;6316;1 -6316;6350;6317;1 -6317;6350;6351;1 -6317;6351;6352;1 -6317;6352;6318;1 -6318;6352;6353;1 -6318;6353;6319;1 -6319;6353;6354;1 -6319;6354;6321;1 -6321;6354;6322;1 -6322;6354;6355;1 -6322;6355;6356;1 -6322;6356;6323;1 -6323;6356;6357;1 -6323;6357;6324;1 -6324;6357;6358;1 -6324;6358;6325;1 -6325;6358;6359;1 -6325;6359;6326;1 -6326;6359;6360;1 -6326;6360;6361;1 -6326;6361;6327;1 -6327;6361;6328;1 -6328;6361;6329;1 -6329;6361;6362;1 -6329;6362;6363;1 -6329;6363;6330;1 -6330;6363;6331;1 -6331;6363;6364;1 -6331;6364;6333;1 -6333;6364;6334;1 -6334;6364;6365;1 -6334;6365;6335;1 -6335;6365;6366;1 -6335;6366;6336;1 -6336;6366;6367;1 -6336;6367;6337;1 -6337;6367;6368;1 -6337;6368;6338;1 -6338;6368;6369;1 -6338;6369;6339;1 -6339;6369;6370;1 -6339;6370;6340;1 -6340;6370;6371;1 -6340;6371;6341;1 -6341;6371;6343;1 -6343;6371;6372;1 -6343;6372;6344;1 -6344;6372;6373;1 -6344;6373;6345;1 -6345;6373;6374;1 -6345;6374;6346;1 -6346;6374;6348;1 -6348;6374;6375;1 -6348;6375;6349;1 -6349;6375;6376;1 -6349;6376;6350;1 -6350;6376;6351;1 -6351;6376;6377;1 -6351;6377;6378;1 -6351;6378;6379;1 -6351;6379;6352;1 -6352;6379;6353;1 -6353;6379;6380;1 -6353;6380;6381;1 -6353;6381;6354;1 -6354;6381;6355;1 -6355;6381;6382;1 -6355;6382;6383;1 -6355;6383;6356;1 -6356;6383;6384;1 -6356;6384;6357;1 -6357;6384;6385;1 -6357;6385;6358;1 -6358;6385;6386;1 -6358;6386;6359;1 -6359;6386;6387;1 -6359;6387;6360;1 -6360;6387;6388;1 -6360;6388;6362;1 -6362;6388;6389;1 -6362;6389;6363;1 -6363;6389;6364;1 -6364;6389;6365;1 -6365;6389;6390;1 -6365;6390;6366;1 -6366;6390;6391;1 -6366;6391;6367;1 -6367;6391;6392;1 -6367;6392;6368;1 -6368;6392;6393;1 -6368;6393;6369;1 -6369;6393;6394;1 -6369;6394;6370;1 -6370;6394;6395;1 -6370;6395;6371;1 -6371;6395;6372;1 -6372;6395;6396;1 -6372;6396;6373;1 -6373;6396;6397;1 -6373;6397;6374;1 -6374;6397;6375;1 -6375;6397;6398;1 -6375;6398;6376;1 -6376;6398;6399;1 -6376;6399;6377;1 -6377;6399;6400;1 -6377;6400;6401;1 -6377;6401;6378;1 -6378;6401;6380;1 -6380;6401;6402;1 -6380;6402;6381;1 -6381;6402;6382;1 -6382;6402;6403;1 -6382;6403;6383;1 -6383;6403;6384;1 -6384;6403;6404;1 -6384;6404;6405;1 -6384;6405;6385;1 -6385;6405;6406;1 -6385;6406;6386;1 -6386;6406;6407;1 -6386;6407;6387;1 -6387;6407;6408;1 -6387;6408;6388;1 -6388;6408;6390;1 -6390;6408;6391;1 -6391;6408;6409;1 -6391;6409;6392;1 -6392;6409;6410;1 -6392;6410;6393;1 -6393;6410;6411;1 -6393;6411;6394;1 -6394;6411;6412;1 -6394;6412;6395;1 -6395;6412;6396;1 -6396;6412;6413;1 -6396;6413;6397;1 -6397;6413;6398;1 -6398;6413;6414;1 -6398;6414;6399;1 -6399;6414;6415;1 -6399;6415;6400;1 -6400;6415;6416;1 -6400;6416;6401;1 -6401;6416;6417;1 -6401;6417;6402;1 -6402;6417;6403;1 -6403;6417;6404;1 -6404;6417;6416;1 -6404;6416;6418;1 -6404;6418;6405;1 -6405;6418;6419;1 -6405;6419;6406;1 -6406;6419;6420;1 -6406;6420;6407;1 -6407;6420;6409;1 -6409;6420;6410;1 -6410;6420;6421;1 -6410;6421;6411;1 -6411;6421;6422;1 -6411;6422;6412;1 -6412;6422;6413;1 -6413;6422;6414;1 -6414;6422;6423;1 -6414;6423;6415;1 -6415;6423;6418;1 -6418;6423;6419;1 -6419;6423;6421;1 -6421;6423;6422;1 -6419;6421;6420;1 -6415;6418;6416;1 -6407;6409;6408;1 -6388;6390;6389;1 -6378;6380;6379;1 -6360;6362;6361;1 -6346;6348;6347;1 -6341;6343;6342;1 -6331;6333;6332;1 -6319;6321;6320;1 -6311;6313;6312;1 -6279;6281;6280;1 -6249;6251;6250;1 -6240;6242;6241;1 -6200;6216;6201;1 -6201;6216;6215;1 -6201;6215;6202;1 -6202;6215;6214;1 -6202;6214;6203;1 -6138;6140;6139;1 -6088;6091;6090;1 -6088;6090;6089;1 -6057;6059;6058;1 -6021;6030;6022;1 -6022;6030;6029;1 -6022;6029;6023;1 -6023;6029;6028;1 -6023;6028;6024;1 -5972;5974;5973;1 -5939;5967;5966;1 -5939;5966;5940;1 -5940;5966;5964;1 -5964;5966;5965;1 -5940;5964;5941;1 -5941;5964;5963;1 -5941;5963;5942;1 -5942;5963;5962;1 -5942;5962;5961;1 -5942;5961;5943;1 -5943;5961;6424;1 -5943;6424;5944;1 -5944;6424;5945;1 -5945;6424;5959;1 -5959;6424;5960;1 -5960;6424;5961;1 -5945;5959;6425;1 -5945;6425;5946;1 -5946;6425;6426;1 -5946;6426;5947;1 -5947;6426;5948;1 -5948;6426;6427;1 -5948;6427;5949;1 -5949;6427;6428;1 -5949;6428;5950;1 -5950;6428;5951;1 -5951;6428;5955;1 -5955;6428;5956;1 -5956;6428;6427;1 -5956;6427;6429;1 -5956;6429;5957;1 -5957;6429;5958;1 -5958;6429;6425;1 -6425;6429;6426;1 -6426;6429;6427;1 -5958;6425;5959;1 -5951;5955;5952;1 -5903;5905;5904;1 -5864;5877;6430;1 -5864;6430;5865;1 -5865;6430;6431;1 -5865;6431;6432;1 -5865;6432;6433;1 -5865;6433;5866;1 -5866;6433;6434;1 -5866;6434;5867;1 -5867;6434;5869;1 -5869;6434;5870;1 -5870;6434;5871;1 -5871;6434;6435;1 -5871;6435;5872;1 -5872;6435;5873;1 -5873;6435;6432;1 -6432;6435;6433;1 -6433;6435;6434;1 -5873;6432;5874;1 -5874;6432;6431;1 -5874;6431;5875;1 -5875;6431;5876;1 -5876;6431;6430;1 -5876;6430;5877;1 -5867;5869;5868;1 -5839;5841;5840;1 -5830;5832;5831;1 -5814;5817;5815;1 -5811;5813;5812;1 -5760;5762;5761;1 -5730;5732;5731;1 -5699;5701;5700;1 -5619;5621;5620;1 -5587;5589;5588;1 -5580;5583;5582;1 -5580;5582;5581;1 -5554;5556;5555;1 -5515;5517;5516;1 -5470;5472;5471;1 -5432;5434;5433;1 -5392;5429;5393;1 -5393;5429;5394;1 -5394;5429;5428;1 -5394;5428;5395;1 -5395;5428;5427;1 -5395;5427;5426;1 -5395;5426;5396;1 -5396;5426;5425;1 -5396;5425;5397;1 -5397;5425;5424;1 -5397;5424;5398;1 -5398;5424;5423;1 -5398;5423;5399;1 -5399;5423;5422;1 -5399;5422;5400;1 -5400;5422;6436;1 -5400;6436;5401;1 -5401;6436;5402;1 -5402;6436;6437;1 -5402;6437;5403;1 -5403;6437;6438;1 -5403;6438;5404;1 -5404;6438;6439;1 -5404;6439;5405;1 -5405;6439;5416;1 -5416;6439;5417;1 -5417;6439;5418;1 -5418;6439;6440;1 -5418;6440;5419;1 -5419;6440;5420;1 -5420;6440;6437;1 -6437;6440;6438;1 -6438;6440;6439;1 -5420;6437;5421;1 -5421;6437;6436;1 -5421;6436;5422;1 -5405;5416;5406;1 -5406;5416;5415;1 -5406;5415;5407;1 -5407;5415;5414;1 -5407;5414;5408;1 -5408;5414;5413;1 -5408;5413;5409;1 -5409;5413;5412;1 -5409;5412;5410;1 -5410;5412;5411;1 -5280;5282;5281;1 -5247;5249;5248;1 -5228;5230;5229;1 -5201;5222;5202;1 -5202;5222;5221;1 -5202;5221;5203;1 -5203;5221;5220;1 -5203;5220;5204;1 -5204;5220;5219;1 -5204;5219;5205;1 -5178;5183;5182;1 -5178;5182;5179;1 -5179;5182;5181;1 -5179;5181;5180;1 -5083;5085;5084;1 -5046;5048;5047;1 -5020;5023;5021;1 -5021;5023;5022;1 -5004;5006;5005;1 -4999;5001;5000;1 -4984;4996;4985;1 -4985;4996;4995;1 -4985;4995;4994;1 -4985;4994;4987;1 -4987;4994;4993;1 -4987;4993;4988;1 -4988;4993;4989;1 -4989;4993;4992;1 -4989;4992;4991;1 -4989;4991;4990;1 -4985;4987;4986;1 -4903;4905;4904;1 -4854;4856;4855;1 -4807;4812;4811;1 -4807;4811;4808;1 -4808;4811;4809;1 -4771;4773;4772;1 -4725;4763;4762;1 -4725;4762;4726;1 -4726;4762;4761;1 -4726;4761;4727;1 -4727;4761;4728;1 -4728;4761;4760;1 -4728;4760;6441;1 -4728;6441;4729;1 -4729;6441;6442;1 -4729;6442;4730;1 -4730;6442;4731;1 -4731;6442;6443;1 -4731;6443;6444;1 -4731;6444;4732;1 -4732;6444;6445;1 -4732;6445;4733;1 -4733;6445;6446;1 -4733;6446;4734;1 -4734;6446;6447;1 -4734;6447;6448;1 -4734;6448;4735;1 -4735;6448;4736;1 -4736;6448;4737;1 -4737;6448;6449;1 -4737;6449;6450;1 -4737;6450;4738;1 -4738;6450;4739;1 -4739;6450;6451;1 -4739;6451;4740;1 -4740;6451;6452;1 -4740;6452;6453;1 -4740;6453;4741;1 -4741;6453;4743;1 -4743;6453;6454;1 -4743;6454;6455;1 -4743;6455;4744;1 -4744;6455;4746;1 -4746;6455;6456;1 -4746;6456;4747;1 -4747;6456;4748;1 -4748;6456;6457;1 -4748;6457;6458;1 -4748;6458;4749;1 -4749;6458;6459;1 -4749;6459;4750;1 -4750;6459;4751;1 -4751;6459;6460;1 -4751;6460;6461;1 -4751;6461;4752;1 -4752;6461;4753;1 -4753;6461;6462;1 -4753;6462;6463;1 -4753;6463;4754;1 -4754;6463;4755;1 -4755;6463;6464;1 -4755;6464;4756;1 -4756;6464;6444;1 -6444;6464;6445;1 -6445;6464;6465;1 -6445;6465;6446;1 -6446;6465;6466;1 -6446;6466;6447;1 -6447;6466;6467;1 -6447;6467;6448;1 -6448;6467;6449;1 -6449;6467;6468;1 -6449;6468;6469;1 -6449;6469;6450;1 -6450;6469;6451;1 -6451;6469;6470;1 -6451;6470;6452;1 -6452;6470;6457;1 -6457;6470;6458;1 -6458;6470;6471;1 -6458;6471;6459;1 -6459;6471;6460;1 -6460;6471;6468;1 -6468;6471;6469;1 -6469;6471;6470;1 -6460;6468;6472;1 -6460;6472;6461;1 -6461;6472;6462;1 -6462;6472;6466;1 -6466;6472;6467;1 -6467;6472;6468;1 -6462;6466;6465;1 -6462;6465;6463;1 -6463;6465;6464;1 -6452;6457;6473;1 -6452;6473;6453;1 -6453;6473;6454;1 -6454;6473;6455;1 -6455;6473;6456;1 -6456;6473;6457;1 -4756;6444;6443;1 -4756;6443;4757;1 -4757;6443;4758;1 -4758;6443;6442;1 -4758;6442;6441;1 -4758;6441;4759;1 -4759;6441;4760;1 -4744;4746;4745;1 -4741;4743;4742;1 -4638;4640;4639;1 -4590;4592;4591;1 -4568;4570;4569;1 -4552;4554;4553;1 -4425;4429;4426;1 -4426;4429;4428;1 -4426;4428;4427;1 -4396;4398;4397;1 -4348;4350;4349;1 -4260;4262;4261;1 -4198;4200;4199;1 -4192;4194;4193;1 -4081;4083;4082;1 -4063;4065;4064;1 -3982;3984;3983;1 -3977;3979;3978;1 -3966;3968;3967;1 -3951;3953;3952;1 -3860;3864;3862;1 -3860;3862;3861;1 -3858;3860;3859;1 -3856;3858;3857;1 -3845;3847;3846;1 -3840;3842;3841;1 -3800;3802;3801;1 -3732;3734;3733;1 -3715;3717;3716;1 -3691;3693;3692;1 -3679;3681;3680;1 -3649;3651;3650;1 -3647;3649;3648;1 -3609;3611;3610;1 -3605;3607;3606;1 -3601;3603;3602;1 -3539;3541;3540;1 -3505;3507;3506;1 -3445;3447;3446;1 -3443;3445;3444;1 -3325;3327;3326;1 -3238;3240;3239;1 -3089;3091;3090;1 -3045;3047;3046;1 -2862;2864;2863;1 -2827;2829;2828;1 -2772;2774;2773;1 -2768;2770;2769;1 -2761;2763;2762;1 -2728;2730;2729;1 -2654;2656;2655;1 -2594;2596;2595;1 -2551;2554;2553;1 -2551;2553;2552;1 -2549;2551;2550;1 -2537;2540;2538;1 -2453;2455;2454;1 -2416;2418;2417;1 -2377;2379;2378;1 -2362;2364;2363;1 -2324;2326;2325;1 -2318;2320;2319;1 -2296;2299;2297;1 -2282;2284;2283;1 -2222;2224;2223;1 -2193;2195;2194;1 -2184;2186;2185;1 -2145;2147;2146;1 -2094;2096;2095;1 -1966;1975;1967;1 -1967;1975;1974;1 -1967;1974;6474;1 -1967;6474;1970;1 -1970;6474;1971;1 -1971;6474;1973;1 -1973;6474;1974;1 -1971;1973;1972;1 -1967;1970;1968;1 -1968;1970;1969;1 -1942;1944;1943;1 -1889;1891;1890;1 -1797;1799;1798;1 -1774;1776;1775;1 -1720;1722;1721;1 -1675;1677;1676;1 -1626;1628;1627;1 -1606;1608;1607;1 -1601;1603;1602;1 -1544;1546;1545;1 -1519;1521;1520;1 -1403;1405;1404;1 -1367;1369;1368;1 -1292;1294;1293;1 -1286;1288;1287;1 -1264;1266;1265;1 -1258;1260;1259;1 -1252;1254;1253;1 -1125;1127;1126;1 -1104;1106;1105;1 -996;998;997;1 -984;986;985;1 -971;973;972;1 -883;885;884;1 -853;855;854;1 -666;668;667;1 -652;654;653;1 -578;580;579;1 -560;562;561;1 -472;474;473;1 -393;395;394;1 -203;205;204;1 -72;74;73;1 diff --git a/inc/jigsaw_const.h b/inc/jigsaw_const.h index 3f2e73e..39f7f8e 100644 --- a/inc/jigsaw_const.h +++ b/inc/jigsaw_const.h @@ -4,48 +4,48 @@ * Constants for the JIGSAW meshing library. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 20 December, 2018 + * Last updated: 27 November, 2019 * - * Copyright 2013-2018 + * Copyright 2013-2019 * Darren Engwirda - * de2363@columbia.edu - * https://github.com/dengwirda/ + * darren.engwirda@columbia.edu + * https://github.com/dengwirda * -------------------------------------------------------- */ - - /* + + /* -------------------------------------------------------- * return codes for JIGSAW. -------------------------------------------------------- - */ + */ # define JIGSAW_UNKNOWN_ERROR -1 @@ -56,18 +56,18 @@ # define JIGSAW_INVALID_ARGUMENT +4 - /* + /* -------------------------------------------------------- * constants for JIGSAW. -------------------------------------------------------- - */ + */ # define JIGSAW_NULL_FLAG -100 # define JIGSAW_EUCLIDEAN_MESH +100 # define JIGSAW_EUCLIDEAN_GRID +101 # define JIGSAW_EUCLIDEAN_DUAL +102 - + # define JIGSAW_ELLIPSOID_MESH +200 # define JIGSAW_ELLIPSOID_GRID +201 # define JIGSAW_ELLIPSOID_DUAL +202 @@ -83,12 +83,16 @@ # define JIGSAW_HFUN_RELATIVE +300 # define JIGSAW_HFUN_ABSOLUTE +301 - + # define JIGSAW_KERN_DELFRONT +400 # define JIGSAW_KERN_DELAUNAY +401 +# define JIGSAW_KERN_BISECTOR +402 # define JIGSAW_BNDS_TRIACELL +402 # define JIGSAW_BNDS_DUALCELL +403 - - - + +# define JIGSAW_KERN_ODT_DQDX +404 +# define JIGSAW_KERN_CVT_DQDX +405 + + + diff --git a/inc/jigsaw_jig_t.h b/inc/jigsaw_jig_t.h index 86db880..b911745 100644 --- a/inc/jigsaw_jig_t.h +++ b/inc/jigsaw_jig_t.h @@ -4,39 +4,39 @@ * JIGSAW's "jig" config. type definition. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 10 April, 2019 + * Last updated: 29 October, 2019 * * Copyright 2013-2019 * Darren Engwirda - * de2363@columbia.edu - * https://github.com/dengwirda/ + * darren.engwirda@columbia.edu + * https://github.com/dengwirda * -------------------------------------------------------- */ @@ -47,326 +47,340 @@ # define __JIGSAW_JIG_T__ /*------------------------------------------- "jig" class */ - + typedef struct { - - /* + + /* -------------------------------------------------------- * VERBOSITY - {default=0} verbosity of log-file gene- * rated by JIGSAW. Set VERBOSITY > 0 for more output. -------------------------------------------------------- - */ - + */ + indx_t _verbosity ; - - /* + + /* -------------------------------------------------------- - * GEOM-SEED - {default = 8} number of "seed" vertices + * GEOM-SEED - {default = 8} number of "seed" vertices * used to initialise mesh generation. -------------------------------------------------------- - */ - + */ + indx_t _geom_seed ; - - /* + + /* -------------------------------------------------------- - * GEOM_FEAT - {default = false} attempt to auto-detect - * "sharp-features" in the input geometry. Features can - * lie adjacent to 1-dim. entities, (i.e. geometry - * "edges") and/or 2-dim. entities, (i.e. geometry + * GEOM_FEAT - {default = false} attempt to auto-detect + * "sharp-features" in the input geometry. Features can + * lie adjacent to 1-dim. entities, (i.e. geometry + * "edges") and/or 2-dim. entities, (i.e. geometry * "faces") based on both geometrical and/or topologic- - * al constraints. Geometrically, features are located - * between any neighbouring entities that subtend - * angles less than GEOM_ETAX degrees, where "X" is the + * al constraints. Geometrically, features are located + * between any neighbouring entities that subtend + * angles less than GEOM_ETAX degrees, where "X" is the * (topological) dimension of the feature. Topological- * ly, features are located at the apex of any non-man- * ifold connections. -------------------------------------------------------- - */ - + */ + indx_t _geom_feat ; - - /* + + /* -------------------------------------------------------- - * GEOM_ETA1 - {default = 45deg} 1-dim. feature-angle, - * features are located between any neighbouring + * GEOM_ETA1 - {default = 45deg} 1-dim. feature-angle, + * features are located between any neighbouring * "edges" that subtend angles less than ETA1 deg. -------------------------------------------------------- */ - + real_t _geom_eta1 ; - - /* + + /* -------------------------------------------------------- - * GEOM_ETA2 - {default = 45deg} 2-dim. feature-angle, - * features are located between any neighbouring + * GEOM_ETA2 - {default = 45deg} 2-dim. feature-angle, + * features are located between any neighbouring * "faces" that subtend angles less than ETA2 deg. -------------------------------------------------------- */ - + real_t _geom_eta2 ; - - /* + + /* -------------------------------------------------------- * INIT_NEAR - {default = 1.E-8} relative "zip" tol. * applied when processing initial conditions. In cases - * where "sharp-feature" detection is active, nodes in + * where "sharp-feature" detection is active, nodes in * the initial set are zipped to their nearest feature * node if the separation length is less than NEAR*SCAL - * where SCAL is the max. bounding-box dimension. + * where SCAL is the max. bounding-box dimension. -------------------------------------------------------- */ real_t _init_near ; - /* + /* -------------------------------------------------------- - * HFUN_SCAL - {default = 'relative'} scaling type for - * mesh-size function. HFUN_SCAL='relative' interprets - * mesh-size values as percentages of the (mean) length - * of the axis-aligned bounding-box (AABB) associated - * with the geometry. HFUN_SCAL = 'absolute' interprets + * HFUN_SCAL - {default = 'relative'} scaling type for + * mesh-size function. HFUN_SCAL='relative' interprets + * mesh-size values as percentages of the (mean) length + * of the axis-aligned bounding-box (AABB) associated + * with the geometry. HFUN_SCAL = 'absolute' interprets * mesh-size values as absolute measures. -------------------------------------------------------- */ - - indx_t _hfun_scal ; - - /* + + indx_t _hfun_scal ; + + /* -------------------------------------------------------- - * HFUN_HMAX - {default = 0.02} max. mesh-size function + * HFUN_HMAX - {default = 0.02} max. mesh-size function * value. Interpreted based on SCAL setting. -------------------------------------------------------- */ - + real_t _hfun_hmax ; - - /* + + /* -------------------------------------------------------- - * HFUN_HMIN - {default = 0.00} min. mesh-size function + * HFUN_HMIN - {default = 0.00} min. mesh-size function * value. Interpreted based on SCAL setting. -------------------------------------------------------- */ - + real_t _hfun_hmin ; - - /* + + /* -------------------------------------------------------- * BNDS_KERN - {default = 'bnd-tria'} placement of bou- - * ndary, enforcing conformance w.r.t the triangulation - * (KERN='bnd-tria') or w.r.t the dual voronoi complex + * ndary, enforcing conformance w.r.t the triangulation + * (KERN='bnd-tria') or w.r.t the dual voronoi complex * (KERN='bnd-dual'). -------------------------------------------------------- */ - + indx_t _bnds_kern ; - - /* + + /* -------------------------------------------------------- * MESH_DIMS - {default=+3} number of "topological" di- * mensions to mesh. DIMS=K meshes K-dimensional featu- - * res, irrespective of the number of spatial dim.'s of - * the problem (i.e. if the geometry is 3-dimensional + * res, irrespective of the number of spatial dim.'s of + * the problem (i.e. if the geometry is 3-dimensional * and DIMS=2 a surface mesh will be produced). -------------------------------------------------------- */ - - indx_t _mesh_dims ; - - /* + + indx_t _mesh_dims ; + + /* -------------------------------------------------------- * MESH_KERN - {default = 'delfront'} meshing kernel, - * choice of the standard Delaunay-refinement algorithm - * (KERN='delaunay') or the Frontal-Delaunay method + * choice of the standard Delaunay-refinement algorithm + * (KERN='delaunay') or the Frontal-Delaunay method * (KERN='delfront'). -------------------------------------------------------- */ - + indx_t _mesh_kern ; - - /* + + /* -------------------------------------------------------- * MESH_ITER - {default = INF} max. number of mesh ref- - * inement iterations. Set ITER=N to see progress after + * inement iterations. Set ITER=N to see progress after * N iterations. -------------------------------------------------------- */ - + indx_t _mesh_iter ; - - /* + + /* -------------------------------------------------------- * 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 - * are either centred at topological "features", or lie + * ical constraints. 1-dim. edges are refined until all + * embedded nodes are "locally 1-manifold", i.e. nodes + * are either centred at topological "features", or lie * on 1-manifold complexes. -------------------------------------------------------- */ - - indx_t _mesh_top1 ; - - /* + + indx_t _mesh_top1 ; + + /* -------------------------------------------------------- * MESH_TOP2 - {default=false} enforce 2-dim. topolog- - * ical constraints. 2-dim. trias are refined until all - * embedded nodes are "locally 2-manifold", i.e. nodes - * are either centred at topological "features", or lie + * ical constraints. 2-dim. trias are refined until all + * embedded nodes are "locally 2-manifold", i.e. nodes + * are either centred at topological "features", or lie * on 2-manifold complexes. -------------------------------------------------------- - */ - + */ + indx_t _mesh_top2 ; - - /* + + /* -------------------------------------------------------- - * MESH_RAD2 - {default = 1.05} max. radius-edge ratio - * for 2-tria elements. 2-trias are refined until the - * ratio of the element circumradii to min. edge length + * MESH_RAD2 - {default = 1.05} max. radius-edge ratio + * for 2-tria elements. 2-trias are refined until the + * ratio of the element circumradii to min. edge length * is less-than RAD2. -------------------------------------------------------- - */ - + */ + real_t _mesh_rad2 ; - - /* + + /* -------------------------------------------------------- - * MESH_RAD3 - {default = 2.05} max. radius-edge ratio - * for 3-tria elements. 3-trias are refined until the - * ratio of the element circumradii to min. edge length + * MESH_RAD3 - {default = 2.05} max. radius-edge ratio + * for 3-tria elements. 3-trias are refined until the + * ratio of the element circumradii to min. edge length * is less-than RAD3. -------------------------------------------------------- - */ - + */ + real_t _mesh_rad3 ; - - /* + + /* -------------------------------------------------------- * MESH_SIZ1 - {default=4/3+eps} h(x)-based refinement - * multiplier for 1-dimensional elements. Edges are - * refined if they are locally larger than SIZ1 * h(x). + * multiplier for 1-dimensional elements. Edges are + * refined if they are locally larger than SIZ1 * h(x). -------------------------------------------------------- - */ - + */ + real_t _mesh_siz1 ; - - /* + + /* -------------------------------------------------------- * MESH_SIZ2 - {default=4/3+eps} h(x)-based refinement - * multiplier for 2-dimensional elements. Cells are - * refined if they are locally larger than SIZ2 * h(x). + * multiplier for 2-dimensional elements. Cells are + * refined if they are locally larger than SIZ2 * h(x). -------------------------------------------------------- */ - + real_t _mesh_siz2 ; - - /* + + /* -------------------------------------------------------- * MESH_SIZ3 - {default=4/3+eps} h(x)-based refinement - * multiplier for 3-dimensional elements. Cells are - * refined if they are locally larger than SIZ3 * h(x). + * multiplier for 3-dimensional elements. Cells are + * refined if they are locally larger than SIZ3 * h(x). -------------------------------------------------------- */ - + real_t _mesh_siz3 ; - - /* + + /* -------------------------------------------------------- * MESH_OFF2 - {default=0.90} radius-edge ratio target * for insertion of "shape"-type offcentres for 2-tria * elements. When refining an element II, offcentres - * are positioned to form a new "frontal" element JJ + * are positioned to form a new "frontal" element JJ * that satisfies JRAD <= OFF2. -------------------------------------------------------- */ - + real_t _mesh_off2 ; - - /* + + /* -------------------------------------------------------- * MESH_OFF3 - {default=1.10} radius-edge ratio target * for insertion of "shape"-type offcentres for 3-tria * elements. When refining an element II, offcentres - * are positioned to form a new "frontal" element JJ + * are positioned to form a new "frontal" element JJ * that satisfies JRAD <= OFF3. -------------------------------------------------------- */ - + real_t _mesh_off3 ; - - /* + + /* -------------------------------------------------------- * MESH_SNK2 - {default=0.20} inflation tolerance for * insertion of "sink" offcentres for 2-tria elements. * When refining an element II, "sinks" are positioned * at the centre of the largest adj. circumball staisf- - * ying |JBAL-IBAL| < SNK2 * IRAD, where IRAD is the - * radius of the circumball, and [IBAL,JBAL] are the + * ying |JBAL-IBAL| < SNK2 * IRAD, where IRAD is the + * radius of the circumball, and [IBAL,JBAL] are the * circumball centres. -------------------------------------------------------- */ - + real_t _mesh_snk2 ; - - /* + + /* -------------------------------------------------------- * MESH_SNK3 - {default=0.33} inflation tolerance for * insertion of "sink" offcentres for 3-tria elements. * When refining an element II, "sinks" are positioned * at the centre of the largest adj. circumball staisf- - * ying |JBAL-IBAL| < SNK3 * IRAD, where IRAD is the - * radius of the circumball, and [IBAL,JBAL] are the + * ying |JBAL-IBAL| < SNK3 * IRAD, where IRAD is the + * radius of the circumball, and [IBAL,JBAL] are the * circumball centres. -------------------------------------------------------- */ - + real_t _mesh_snk3 ; - - /* + + /* -------------------------------------------------------- * MESH_EPS1 - {default=0.33} max. surface-discretisa- - * tion error multiplier for 1-edge elements. 1-edge - * elements are refined until the surface-disc. error + * tion error multiplier for 1-edge elements. 1-edge + * elements are refined until the surface-disc. error * is less-than EPS1 * HFUN(X). -------------------------------------------------------- */ - + real_t _mesh_eps1 ; - - /* + + /* -------------------------------------------------------- * MESH_EPS2 - {default=0.33} max. surface-discretisa- - * tion error multiplier for 2-tria elements. 2-tria - * elements are refined until the surface-disc. error + * tion error multiplier for 2-tria elements. 2-tria + * elements are refined until the surface-disc. error * is less-than EPS2 * HFUN(X). -------------------------------------------------------- */ - + real_t _mesh_eps2 ; - - /* + + /* -------------------------------------------------------- - * MESH_VOL3 - {default=0.00} min. volume-length ratio - * for 3-tria elements. 3-tria elements are refined - * until the volume-length ratio exceeds VOL3. Can be + * MESH_VOL3 - {default=0.00} min. volume-length ratio + * for 3-tria elements. 3-tria elements are refined + * until the volume-length ratio exceeds VOL3. Can be * used to supress "sliver" elements. -------------------------------------------------------- */ - + real_t _mesh_vol3 ; - - /* + + /* + -------------------------------------------------------- + * OPTM_KERN - {default = 'odt+dqdx'} mesh optimisation + * kernel, choice of an Optimal Delaunay Tessellation + * strategy (KERN='odt+dqdx') or a Centroidal Voronoi + * Tessellation method (KERN='cvt+dqdx'). In both cases + * a hybrid formulation is employed, using a "blend" of + * ODT/CVT updates, and gradients of a "fall-back" mesh + * quality function Q. + -------------------------------------------------------- + */ + + indx_t _optm_kern ; + + /* -------------------------------------------------------- * OPTM_ITER - {default=16} max. number of mesh optim- - * isation iterations. Set ITER=N to see progress after + * isation iterations. Set ITER=N to see progress after * N iterations. -------------------------------------------------------- */ indx_t _optm_iter ; - - /* + + /* -------------------------------------------------------- * OPTM_QTOL - {default=1.E-04} tolerance on mesh cost * function for convergence. Iteration on a given node @@ -374,59 +388,59 @@ * improved by less than QTOL. -------------------------------------------------------- */ - + real_t _optm_qtol ; - - /* + + /* -------------------------------------------------------- * OPTM_QLIM - {default=0.9375} threshold on mesh cost * function above which gradient-based optimisation is * attempted. -------------------------------------------------------- */ - + real_t _optm_qlim ; - + /* -------------------------------------------------------- * OPTM_TRIA - {default= true} allow for optimisation * of TRIA grid geometry. -------------------------------------------------------- */ - + indx_t _optm_tria ; - + /* -------------------------------------------------------- * OPTM_DUAL - {default=false} allow for optimisation * of DUAL grid geometry. -------------------------------------------------------- */ - + indx_t _optm_dual ; - + /* -------------------------------------------------------- * OPTM_ZIP_ - {default= true} allow for "merge" oper- * ations on sub-faces within the optimisation stages. -------------------------------------------------------- */ - + indx_t _optm_zip_ ; - + /* -------------------------------------------------------- * OPTM_DIV_ - {default= true} allow for "split" oper- * ations on sub-faces within the optimisation stages. -------------------------------------------------------- */ - + indx_t _optm_div_ ; - + } jigsaw_jig_t ; - - -# endif //__JIGSAW_JIG_T__ - - + + +# endif //__JIGSAW_JIG_T__ + + diff --git a/inc/jigsaw_msh_t.h b/inc/jigsaw_msh_t.h index 0ab48a1..8b76ea6 100644 --- a/inc/jigsaw_msh_t.h +++ b/inc/jigsaw_msh_t.h @@ -4,39 +4,39 @@ * JIGSAW's "msh" mesh type definition. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 19 January, 2019 + * Last updated: 27 June, 2019 * * Copyright 2013-2019 * Darren Engwirda - * de2363@columbia.edu - * https://github.com/dengwirda/ + * darren.engwirda@columbia.edu + * https://github.com/dengwirda * -------------------------------------------------------- */ @@ -48,60 +48,60 @@ /*------------------------------------------- geom. types */ - typedef struct + typedef struct { real_t _ppos [2] ; // coord.'s indx_t _itag ; // ID tag } jigsaw_VERT2_t ; - + typedef struct { real_t _ppos [3] ; // coord.'s indx_t _itag ; // ID tag } jigsaw_VERT3_t ; - + typedef struct { indx_t _node [2] ; // indexing indx_t _itag ; // ID tag } jigsaw_EDGE2_t ; - + typedef struct { indx_t _node [3] ; // indexing indx_t _itag ; // ID tag } jigsaw_TRIA3_t ; - + typedef struct { indx_t _node [4] ; // indexing indx_t _itag ; // ID tag } jigsaw_QUAD4_t ; - + typedef struct { indx_t _node [4] ; // indexing indx_t _itag ; // ID tag } jigsaw_TRIA4_t ; - + typedef struct { indx_t _node [8] ; // indexing indx_t _itag ; // ID tag } jigsaw_HEXA8_t ; - + typedef struct { indx_t _node [6] ; // indexing indx_t _itag ; // ID tag } jigsaw_WEDG6_t ; - + typedef struct { indx_t _node [5] ; // indexing indx_t _itag ; // ID tag } jigsaw_PYRA5_t ; - + typedef struct { indx_t _itag ; // ID tag @@ -109,134 +109,137 @@ indx_t _kind ; // MSH obj. } jigsaw_BOUND_t ; -/*------------------------------------------- array types */ - +/*------------------------------------------- array types */ + typedef struct { size_t _size ; jigsaw_VERT2_t *_data ; } jigsaw_VERT2_array_t ; - + typedef struct { size_t _size ; jigsaw_VERT3_t *_data ; } jigsaw_VERT3_array_t ; - + typedef struct { size_t _size ; jigsaw_EDGE2_t *_data ; } jigsaw_EDGE2_array_t ; - + typedef struct { size_t _size ; jigsaw_TRIA3_t *_data ; } jigsaw_TRIA3_array_t ; - + typedef struct { size_t _size ; jigsaw_QUAD4_t *_data ; } jigsaw_QUAD4_array_t ; - + typedef struct { size_t _size ; jigsaw_TRIA4_t *_data ; } jigsaw_TRIA4_array_t ; - + typedef struct { size_t _size ; jigsaw_HEXA8_t *_data ; } jigsaw_HEXA8_array_t ; - + typedef struct { size_t _size ; jigsaw_WEDG6_t *_data ; } jigsaw_WEDG6_array_t ; - + typedef struct { size_t _size ; jigsaw_PYRA5_t *_data ; } jigsaw_PYRA5_array_t ; - + typedef struct { size_t _size ; jigsaw_BOUND_t *_data ; } jigsaw_BOUND_array_t ; - + typedef struct { size_t _size ; indx_t *_data ; } jigsaw_INDEX_array_t ; - + typedef struct { size_t _size ; real_t *_data ; } jigsaw_REALS_array_t ; - + /*------------------------------------------- "msh" class */ - typedef struct + typedef struct { - + indx_t _flags; - + /* if (_flags == EUCLIDEAN_MESH) */ - + jigsaw_VERT2_array_t _vert2; jigsaw_VERT3_array_t _vert3; - + jigsaw_REALS_array_t _power; - + jigsaw_EDGE2_array_t _edge2; - + jigsaw_TRIA3_array_t _tria3; jigsaw_QUAD4_array_t _quad4; - + jigsaw_TRIA4_array_t _tria4; jigsaw_HEXA8_array_t _hexa8; jigsaw_WEDG6_array_t _wedg6; jigsaw_PYRA5_array_t _pyra5; - + jigsaw_BOUND_array_t _bound; - + /* if (_flags == ELLIPSOID_MESH) */ - + jigsaw_REALS_array_t _radii; - + /* if (_flags == EUCLIDEAN_GRID) */ /* OR (_flags == ELLIPSOID_GRID) */ - + jigsaw_REALS_array_t _xgrid; jigsaw_REALS_array_t _ygrid; jigsaw_REALS_array_t _zgrid; - /* if (_flags == EUCLIDEAN_MESH) */ /* OR (_flags == EUCLIDEAN_GRID) */ /* OR (_flags == ELLIPSOID_MESH) */ /* OR (_flags == ELLIPSOID_GRID) */ - + jigsaw_REALS_array_t _value; - + + /* for |dfdx| limiting in MARCHE */ + + jigsaw_REALS_array_t _slope; + /* if (_flags == EUCLIDEAN_DUAL) */ - + /*!! todo: dual-mesh data here!! */ - + } jigsaw_msh_t ; - - -# endif //__JIGSAW_MSH_T__ - - + + +# endif //__JIGSAW_MSH_T__ + + diff --git a/inc/lib_jigsaw.h b/inc/lib_jigsaw.h index 1ef21b2..1e2f94b 100644 --- a/inc/lib_jigsaw.h +++ b/inc/lib_jigsaw.h @@ -2,13 +2,13 @@ /* -------------------------------------------------------- * - * ,o, ,o, / + * ,o, ,o, / * ` ` e88~88e d88~\ /~~~8e Y88b e / - * 888 888 88 88 C888 88b Y88b d8b / - * 888 888 "8b_d8" Y88b e88~-888 Y888/Y88b/ - * 888 888 / 888D C88 888 Y8/ Y8/ - * 88P 888 Cb \_88P "8b_-888 Y Y - * \_8" Y8""8D + * 888 888 88 88 C888 88b Y88b d8b / + * 888 888 "8b_d8" Y88b e88~-888 Y888/Y88b/ + * 888 888 / 888D C88 888 Y8/ Y8/ + * 88P 888 Cb \_88P "8b_-888 Y Y + * \_8" Y8""8D * -------------------------------------------------------- * JIGSAW: Interface to the JIGSAW meshing library. @@ -23,29 +23,29 @@ * -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- @@ -84,88 +84,88 @@ # include "jigsaw_jig_t.h" # include "jigsaw_msh_t.h" - /* + /* -------------------------------------------------------- * generate mesh via JIGSAW. -------------------------------------------------------- - */ - -# define jigsaw_make_mesh jigsaw - - SHARED indx_t jigsaw ( - + */ + +# define jigsaw_make_mesh jigsaw + + SHARED indx_t jigsaw ( + /* JCFG (REQUIRED): settings obj. definition. */ jigsaw_jig_t *_jcfg, - + /* GEOM (REQUIRED): geometry obj. definition. */ jigsaw_msh_t *_geom, - - /* INIT (OPTIONAL): initial tria. definition. - * => NULL for empty IC's. + + /* INIT (OPTIONAL): initial tria. definition. + * => NULL for empty IC's. */ jigsaw_msh_t *_init, - - /* HFUN (OPTIONAL): mesh-spacing function h(x). - * => NULL for empty h(x). + + /* HFUN (OPTIONAL): mesh-spacing function h(x). + * => NULL for empty h(x). */ jigsaw_msh_t *_hfun, - + /* MESH (REQUIRED): output mesh data-structure. */ jigsaw_msh_t *_mesh ) ; - - /* + + /* -------------------------------------------------------- * compute rDT's via TRIPOD. -------------------------------------------------------- */ - - SHARED indx_t tripod ( - + + SHARED indx_t tripod ( + /* JCFG (REQUIRED): settings obj. definition. */ jigsaw_jig_t *_jcfg, - - /* INIT (REQUIRED): initial point definition. + + /* INIT (REQUIRED): initial point definition. */ jigsaw_msh_t *_init, - + /* GEOM (OPTIONAL): geometry obj. definition. * => NULL for empty GEOM. */ jigsaw_msh_t *_geom, - + /* MESH (REQUIRED): output mesh data-structure. */ jigsaw_msh_t *_mesh ) ; - - /* + + /* -------------------------------------------------------- * limit |df/dx| via MARCHE. -------------------------------------------------------- */ - - SHARED indx_t marche ( - + + SHARED indx_t marche ( + /* JCFG (REQUIRED): settings obj. definition. */ jigsaw_jig_t *_jcfg, - - /* HFUN (REQUIRED): apply limiter to |df/dx|. + + /* FFUN (REQUIRED): apply limiter to |df/dx|. */ jigsaw_msh_t *_ffun ) ; - /* + /* -------------------------------------------------------- * setup objects for JIGSAW. -------------------------------------------------------- */ - + SHARED void jigsaw_init_msh_t ( jigsaw_msh_t *_mesh ) ; @@ -173,13 +173,13 @@ SHARED void jigsaw_init_jig_t ( jigsaw_jig_t *_jjig ) ; - - /* + + /* -------------------------------------------------------- * parse-to-file for JIGSAW. -------------------------------------------------------- */ - + /* SHARED indx_t jigsaw_save_msh_t ( char *_file, @@ -191,7 +191,7 @@ char *_file, jigsaw_jig_t *_jjig ) ; - + SHARED indx_t jigsaw_load_msh_t ( char *_file, jigsaw_msh_t *_mesh @@ -202,130 +202,130 @@ jigsaw_jig_t *_jjig ) ; - /* + /* -------------------------------------------------------- * alloc objects for JIGSAW. -------------------------------------------------------- */ - + SHARED void jigsaw_alloc_vert2 ( jigsaw_VERT2_array_t *_xsrc , size_t _size ) ; - + SHARED void jigsaw_alloc_vert3 ( jigsaw_VERT3_array_t *_xsrc , size_t _size ) ; - + SHARED void jigsaw_alloc_edge2 ( jigsaw_EDGE2_array_t *_xsrc , size_t _size ) ; - + SHARED void jigsaw_alloc_tria3 ( jigsaw_TRIA3_array_t *_xsrc , size_t _size ) ; - + SHARED void jigsaw_alloc_quad4 ( jigsaw_QUAD4_array_t *_xsrc , size_t _size ) ; - + SHARED void jigsaw_alloc_tria4 ( jigsaw_TRIA4_array_t *_xsrc , size_t _size ) ; - + SHARED void jigsaw_alloc_hexa8 ( jigsaw_HEXA8_array_t *_xsrc , size_t _size ) ; - + SHARED void jigsaw_alloc_wedg6 ( jigsaw_WEDG6_array_t *_xsrc , size_t _size ) ; - + SHARED void jigsaw_alloc_pyra5 ( jigsaw_PYRA5_array_t *_xsrc , size_t _size ) ; - + SHARED void jigsaw_alloc_bound ( jigsaw_BOUND_array_t *_xsrc , size_t _size ) ; - + SHARED void jigsaw_alloc_index ( jigsaw_INDEX_array_t *_xsrc , size_t _size ) ; - + SHARED void jigsaw_alloc_reals ( jigsaw_REALS_array_t *_xsrc , size_t _size ) ; - + SHARED void jigsaw_free_msh_t ( jigsaw_msh_t *_mesh ) ; - + SHARED void jigsaw_free_vert2 ( jigsaw_VERT2_array_t *_xsrc ) ; - + SHARED void jigsaw_free_vert3 ( jigsaw_VERT3_array_t *_xsrc ) ; - + SHARED void jigsaw_free_edge2 ( jigsaw_EDGE2_array_t *_xsrc ) ; - + SHARED void jigsaw_free_tria3 ( jigsaw_TRIA3_array_t *_xsrc ) ; - + SHARED void jigsaw_free_quad4 ( jigsaw_QUAD4_array_t *_xsrc ) ; - + SHARED void jigsaw_free_tria4 ( jigsaw_TRIA4_array_t *_xsrc ) ; - + SHARED void jigsaw_free_hexa8 ( jigsaw_HEXA8_array_t *_xsrc ) ; - + SHARED void jigsaw_free_wedg6 ( jigsaw_WEDG6_array_t *_xsrc ) ; - + SHARED void jigsaw_free_pyra5 ( jigsaw_PYRA5_array_t *_xsrc ) ; - + SHARED void jigsaw_free_bound ( jigsaw_BOUND_array_t *_xsrc ) ; - + SHARED void jigsaw_free_index ( jigsaw_INDEX_array_t *_xsrc ) ; - + SHARED void jigsaw_free_reals ( jigsaw_REALS_array_t *_xsrc ) ; - + # ifdef __cplusplus } # endif # undef SHARED - + # endif // __LIB_JIGSAW__ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index fa8f80e..eda1ba6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -52,6 +52,15 @@ else () install (TARGETS tripod-cmd DESTINATION bin) endif () +add_executable (marche-cmd jigsaw.cpp) +target_compile_definitions (marche-cmd PRIVATE __cmd_marche) +set_target_properties (marche-cmd PROPERTIES OUTPUT_NAME marche) +if (DEFINED INSTALL_LOCAL) + install (TARGETS marche-cmd DESTINATION "${PROJECT_SOURCE_DIR}/bin") +else () + install (TARGETS marche-cmd DESTINATION bin) +endif () + add_library (jigsaw-lib SHARED jigsaw.cpp) target_compile_definitions (jigsaw-lib PRIVATE __lib_jigsaw) set_target_properties (jigsaw-lib PROPERTIES OUTPUT_NAME jigsaw) diff --git a/src/geo_load.hpp b/src/geo_load.hpp index 2b993a0..b8b2c04 100644 --- a/src/geo_load.hpp +++ b/src/geo_load.hpp @@ -4,34 +4,34 @@ * GEO-LOAD: parse *.MSH file into GEOM data. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 28 February, 2019 + * Last updated: 22 July, 2019 * * Copyright 2013-2019 * Darren Engwirda @@ -53,7 +53,7 @@ * GEOM-FROM-JMSH: read *.JMSH file into GEOM data. -------------------------------------------------------- */ - + template < typename jlog_data > @@ -63,7 +63,7 @@ geom_data &_geom ) { - class geom_reader: + class geom_reader: public jmsh_reader_base { public : @@ -79,14 +79,14 @@ ) : _geom(_gsrc) {} /*---------------------------------- parse MSHID data */ __normal_call void_type push_mshid ( - std::int32_t _ftag , - jmsh_kind::enum_data _kind + std::int32_t _FTAG , + jmsh_kind::enum_data _KIND ) - { - this->_ftag = _ftag ; - this->_kind = _kind ; + { + this->_ftag = _FTAG ; + this->_kind = _KIND ; this-> - _geom->_kind = _kind ; + _geom->_kind = _KIND ; } /*---------------------------------- parse RADII data */ __normal_call void_type push_radii ( @@ -98,16 +98,16 @@ this->_geom->_ellipsoid_mesh_3d. _radB = _erad[ 1] ; this->_geom->_ellipsoid_mesh_3d. - _radC = _erad[ 2] ; + _radC = _erad[ 2] ; } /*---------------------------------- parse NDIMS data */ __normal_call void_type push_ndims ( - std:: size_t _ndim + std:: size_t _NDIM ) - { - this->_ndim = _ndim ; + { + this->_ndim = _NDIM ; this-> - _geom->_ndim = _ndim ; + _geom->_ndim = _NDIM ; } /*---------------------------------- parse POINT data */ __normal_call void_type push_point ( @@ -119,49 +119,49 @@ __unreferenced(_ipos) ; if (this->_ndim == +2 && - this->_kind == + this->_kind == jmsh_kind::euclidean_mesh) { - typename + typename geom_data::euclidean_mesh_2d ::node_type _ndat ; _ndat.pval(0) = _pval[0]; _ndat.pval(1) = _pval[1]; _ndat.itag () = _itag ; - + this->_geom-> _euclidean_mesh_2d. _tria.push_node(_ndat, false) ; } else if (this->_ndim == +3 && - this->_kind == + this->_kind == jmsh_kind::euclidean_mesh) { - typename + typename geom_data::euclidean_mesh_3d ::node_type _ndat ; _ndat.pval(0) = _pval[0]; _ndat.pval(1) = _pval[1]; _ndat.pval(2) = _pval[2]; _ndat.itag () = _itag ; - + this->_geom-> _euclidean_mesh_3d. _tria.push_node(_ndat, false) ; } else - if (this->_kind == + if (this->_kind == jmsh_kind::ellipsoid_mesh) { - typename + typename geom_data::ellipsoid_mesh_3d ::node_type _ndat ; _ndat.pval(0) = _pval[0]; _ndat.pval(1) = _pval[1]; _ndat.pval(2) = + 0.0 ; _ndat.itag () = _itag ; - + this->_geom-> _ellipsoid_mesh_3d. _mesh.push_node(_ndat, false) ; @@ -177,26 +177,26 @@ __unreferenced(_ipos) ; if (this->_ndim == +2 && - this->_kind == + this->_kind == jmsh_kind::euclidean_mesh) { - typename + typename geom_data::euclidean_mesh_2d ::edge_type _edat ; _edat.node(0) = _node[0]; _edat.node(1) = _node[1]; _edat.itag () = _itag ; - + this->_geom-> _euclidean_mesh_2d. _tria.push_edge(_edat, false) ; } else if (this->_ndim == +3 && - this->_kind == + this->_kind == jmsh_kind::euclidean_mesh) { - typename + typename geom_data::euclidean_mesh_3d ::edge_type _edat ; _edat.node(0) = _node[0]; @@ -208,10 +208,10 @@ _tria.push_edge(_edat, false) ; } else - if (this->_kind == + if (this->_kind == jmsh_kind::ellipsoid_mesh) { - typename + typename geom_data::ellipsoid_mesh_3d ::edge_type _edat ; _edat.node(0) = _node[0]; @@ -221,7 +221,7 @@ this->_geom-> _ellipsoid_mesh_3d. _mesh.push_edge(_edat, false) ; - } + } } /*---------------------------------- parse TRIA3 data */ __normal_call void_type push_tria3 ( @@ -233,30 +233,30 @@ __unreferenced(_ipos) ; if (this->_ndim == +2 && - this->_kind == + this->_kind == jmsh_kind::euclidean_mesh) { // do nothing... } else if (this->_ndim == +3 && - this->_kind == + this->_kind == jmsh_kind::euclidean_mesh) { - typename + typename geom_data::euclidean_mesh_3d ::tri3_type _tdat ; _tdat.node(0) = _node[0]; _tdat.node(1) = _node[1]; _tdat.node(2) = _node[2]; _tdat.itag () = _itag ; - + this->_geom-> _euclidean_mesh_3d. _tria.push_tri3(_tdat, false) ; } else - if (this->_kind == + if (this->_kind == jmsh_kind::ellipsoid_mesh) { // do nothing... @@ -267,57 +267,57 @@ std:: size_t _ipos , std::int32_t _itag , std::int32_t _inum , - std::int32_t _kind + std::int32_t _KIND ) { __unreferenced(_ipos) ; - - if (this->_kind == + + if (this->_kind == jmsh_kind::euclidean_mesh) { - typename + typename geom_data::euclidean_mesh_2d ::part_data _pdat ; _pdat.itag () = _itag ; _pdat.indx () = _inum ; - _pdat.kind () = _kind ; - + _pdat.kind () = _KIND ; + this->_geom-> _euclidean_mesh_2d. _part.push(_pdat) ; } else if (this->_ndim == +3 && - this->_kind == + this->_kind == jmsh_kind::euclidean_mesh) { - typename + typename geom_data::euclidean_mesh_3d ::part_data _pdat ; _pdat.itag () = _itag ; _pdat.indx () = _inum ; - _pdat.kind () = _kind ; - + _pdat.kind () = _KIND ; + this->_geom-> _euclidean_mesh_3d. _part.push(_pdat) ; } else - if (this->_kind == + if (this->_kind == jmsh_kind::ellipsoid_mesh) { //!! do things here... - } + } } } ; - + /*---------------------------------- parse GEOM. file */ iptr_type _errv = __no_error ; - + try { jmsh_reader _jmsh ; - std::ifstream _file ; + std::ifstream _file ; _file. open( _jcfg._geom_file, std::ifstream::in) ; @@ -327,18 +327,18 @@ _file, geom_reader(&_geom)); } else - { + { _jlog.push( "**parse error: file not found!\n" ) ; - + _errv = __file_not_located ; } _file.close (); - for (auto _iter = + for (auto _iter = _jmsh._errs.head(); - _iter != - _jmsh._errs.tend(); + _iter != + _jmsh._errs.tend(); ++_iter ) { _jlog.push( @@ -358,7 +358,7 @@ * GEOM-FROM-MSHT: read MSH_t data into GEOM data. -------------------------------------------------------- */ - + template < typename jlog_data > @@ -370,28 +370,28 @@ ) { iptr_type _errv = __no_error ; - + try { - + __unreferenced (_jlog) ; __unreferenced (_jcfg) ; - if (_gmsh._flags == + if (_gmsh._flags == JIGSAW_EUCLIDEAN_MESH ) { if (_gmsh._vert2._size > 0) { /*--------------------------------- euclidean-mesh-2d */ - _geom._kind + _geom._kind = jmsh_kind::euclidean_mesh ; _geom._ndim = +2; - + for (auto _ipos = (size_t) +0 ; - _ipos != _gmsh._vert2._size ; + _ipos != _gmsh._vert2._size ; ++_ipos ) { - typename + typename geom_data::euclidean_mesh_2d ::node_type _ndat ; _ndat.pval(0) = _gmsh. @@ -400,16 +400,16 @@ _vert2._data[_ipos]._ppos[1]; _ndat.itag () = _gmsh. _vert2._data[_ipos]._itag ; - + _geom._euclidean_mesh_2d. _tria.push_node(_ndat , false) ; } - + for (auto _ipos = (size_t) +0 ; - _ipos != _gmsh._edge2._size ; + _ipos != _gmsh._edge2._size ; ++_ipos ) { - typename + typename geom_data::euclidean_mesh_2d ::edge_type _edat ; _edat.node(0) = _gmsh. @@ -418,16 +418,16 @@ _edge2._data[_ipos]._node[1]; _edat.itag () = _gmsh. _edge2._data[_ipos]._itag ; - + _geom._euclidean_mesh_2d. _tria.push_edge(_edat , false) ; } - + for (auto _ipos = (size_t) +0 ; - _ipos != _gmsh._bound._size ; + _ipos != _gmsh._bound._size ; ++_ipos ) { - typename + typename geom_data::euclidean_mesh_2d ::part_data _pdat ; _pdat.itag () = _gmsh. @@ -436,25 +436,25 @@ _bound._data[_ipos]._indx ; _pdat.kind () = _gmsh. _bound._data[_ipos]._kind ; - + _geom._euclidean_mesh_2d. _part.push(_pdat) ; } - + } else if (_gmsh._vert3._size > 0) { /*--------------------------------- euclidean-mesh-3d */ - _geom._kind + _geom._kind = jmsh_kind::euclidean_mesh ; _geom._ndim = +3; - + for (auto _ipos = (size_t) +0 ; - _ipos != _gmsh._vert3._size ; + _ipos != _gmsh._vert3._size ; ++_ipos ) { - typename + typename geom_data::euclidean_mesh_3d ::node_type _ndat ; _ndat.pval(0) = _gmsh. @@ -465,16 +465,16 @@ _vert3._data[_ipos]._ppos[2]; _ndat.itag () = _gmsh. _vert3._data[_ipos]._itag ; - + _geom._euclidean_mesh_3d. _tria.push_node(_ndat , false) ; } - + for (auto _ipos = (size_t) +0 ; - _ipos != _gmsh._edge2._size ; + _ipos != _gmsh._edge2._size ; ++_ipos ) { - typename + typename geom_data::euclidean_mesh_3d ::edge_type _edat ; _edat.node(0) = _gmsh. @@ -483,16 +483,16 @@ _edge2._data[_ipos]._node[1]; _edat.itag () = _gmsh. _edge2._data[_ipos]._itag ; - + _geom._euclidean_mesh_3d. _tria.push_edge(_edat , false) ; } - + for (auto _ipos = (size_t) +0 ; - _ipos != _gmsh._tria3._size ; + _ipos != _gmsh._tria3._size ; ++_ipos ) { - typename + typename geom_data::euclidean_mesh_3d ::tri3_type _tdat ; _tdat.node(0) = _gmsh. @@ -503,16 +503,16 @@ _tria3._data[_ipos]._node[2]; _tdat.itag () = _gmsh. _tria3._data[_ipos]._itag ; - + _geom._euclidean_mesh_3d. _tria.push_tri3(_tdat , false) ; } - + for (auto _ipos = (size_t) +0 ; - _ipos != _gmsh._bound._size ; + _ipos != _gmsh._bound._size ; ++_ipos ) { - typename + typename geom_data::euclidean_mesh_3d ::part_data _pdat ; _pdat.itag () = _gmsh. @@ -521,22 +521,22 @@ _bound._data[_ipos]._indx ; _pdat.kind () = _gmsh. _bound._data[_ipos]._kind ; - + _geom._euclidean_mesh_3d. _part.push(_pdat) ; } - - } + + } } else - if (_gmsh._flags == + if (_gmsh._flags == JIGSAW_ELLIPSOID_MESH ) { /*--------------------------------- ellipsoid-mesh-3d */ - _geom._kind + _geom._kind = jmsh_kind::ellipsoid_mesh ; - _geom._ndim = +3; - + _geom._ndim = +2; + if (_gmsh._radii._size==+3) { _geom._ellipsoid_mesh_3d. @@ -556,12 +556,12 @@ _geom._ellipsoid_mesh_3d. _radC = _gmsh._radii._data[0] ; } - + for (auto _ipos = (size_t) +0 ; - _ipos != _gmsh._vert3._size ; + _ipos != _gmsh._vert3._size ; ++_ipos ) { - typename + typename geom_data::ellipsoid_mesh_3d ::node_type _ndat ; _ndat.pval(0) = _gmsh. @@ -571,16 +571,16 @@ _ndat.pval(2) = + 0.0 ; _ndat.itag () = _gmsh. _vert3._data[_ipos]._itag ; - + _geom._ellipsoid_mesh_3d. _mesh.push_node(_ndat , false) ; } - + for (auto _ipos = (size_t) +0 ; - _ipos != _gmsh._edge2._size ; + _ipos != _gmsh._edge2._size ; ++_ipos ) { - typename + typename geom_data::ellipsoid_mesh_3d ::edge_type _edat ; _edat.node(0) = _gmsh. @@ -589,12 +589,12 @@ _edge2._data[_ipos]._node[1]; _edat.itag () = _gmsh. _edge2._data[_ipos]._itag ; - + _geom._ellipsoid_mesh_3d. _mesh.push_edge(_edat , false) ; } } - + } catch (...) { @@ -603,13 +603,13 @@ return ( _errv ) ; } - + /* -------------------------------------------------------- * READ-GEOM: read geometry input file. -------------------------------------------------------- */ - + template < typename jlog_data > @@ -622,13 +622,13 @@ return geom_from_jmsh ( _jcfg, _jlog, _geom ) ; } - + /* -------------------------------------------------------- * COPY-GEOM: read geometry input data. -------------------------------------------------------- */ - + template < typename jlog_data > @@ -642,13 +642,13 @@ return geom_from_msht ( _jcfg, _jlog, _geom, _gmsh); } - + /* -------------------------------------------------------- * TEST-GEOM: test GEOM data validity. -------------------------------------------------------- */ - + template < typename jlog_data > @@ -667,9 +667,9 @@ jmsh_kind::euclidean_mesh) { /*--------------------------------- euclidean-mesh-2d */ - iptr_type _imin = + iptr_type _imin = std::numeric_limits::max() ; - iptr_type _imax = + iptr_type _imax = std::numeric_limits::min() ; iptr_type _nnPT = +0 ; @@ -682,7 +682,7 @@ ++_iter ) { if (_iter->mark() < 0) continue; - + _nnPT += +1 ; } @@ -693,7 +693,7 @@ ++_iter ) { if (_iter->mark() < 0) continue; - + _imin = std::min( _imin, _iter->node(0)) ; _imin = std::min( @@ -702,14 +702,14 @@ _imax, _iter->node(0)) ; _imax = std::max( _imax, _iter->node(1)) ; - + _nnE2 += +1 ; - - if (_imin < +0 || + + if (_imin < +0 || _imax >= _nnPT) { _errv = __invalid_argument ; - } + } } if (_errv != __no_error) @@ -719,7 +719,7 @@ return _errv ; } - + for (auto _iter = _geom. _euclidean_mesh_2d._part._lptr.head() ; _iter != _geom. @@ -727,17 +727,17 @@ ++_iter ) { if (*_iter == nullptr) continue; - + for (auto _pptr = *_iter ; _pptr != nullptr; _pptr = _pptr->_next ) { - - if (_pptr->_data.kind() + + if (_pptr->_data.kind() == JIGSAW_EDGE2_TAG ) { if (_pptr->_data.indx() < +0 || - _pptr->_data.indx() >= _nnE2 + _pptr->_data.indx() >= _nnE2 ) { _errv = __invalid_argument ; @@ -747,15 +747,15 @@ { _errv = __invalid_argument ; } - + } } - + if (_errv != __no_error) { _jlog. push ( "**input error: GEOM. BOUND indexing is incorrect.\n") ; - + return _errv ; } } @@ -765,9 +765,9 @@ jmsh_kind::euclidean_mesh) { /*--------------------------------- euclidean-mesh-3d */ - iptr_type _imin = + iptr_type _imin = std::numeric_limits::max() ; - iptr_type _imax = + iptr_type _imax = std::numeric_limits::min() ; iptr_type _nnPT = +0 ; @@ -781,7 +781,7 @@ ++_iter ) { if (_iter->mark() < 0) continue ; - + _nnPT += +1 ; } @@ -792,7 +792,7 @@ ++_iter ) { if (_iter->mark() < 0) continue ; - + _imin = std::min( _imin, _iter->node(0)) ; _imin = std::min( @@ -801,10 +801,10 @@ _imax, _iter->node(0)) ; _imax = std::max( _imax, _iter->node(1)) ; - + _nnE2 += +1 ; - - if (_imin < +0 || + + if (_imin < +0 || _imax >= _nnPT) { _errv = __invalid_argument ; @@ -826,7 +826,7 @@ ++_iter ) { if (_iter->mark() < 0) continue ; - + _imin = std::min( _imin, _iter->node(0)) ; _imin = std::min( @@ -839,10 +839,10 @@ _imax, _iter->node(1)) ; _imax = std::max( _imax, _iter->node(2)) ; - + _nnT3 += +1 ; - - if (_imin < +0 || + + if (_imin < +0 || _imax >= _nnPT) { _errv = __invalid_argument ; @@ -856,7 +856,7 @@ return _errv ; } - + for (auto _iter = _geom. _euclidean_mesh_3d._part._lptr.head() ; _iter != _geom. @@ -864,17 +864,17 @@ ++_iter ) { if (*_iter == nullptr) continue; - + for (auto _pptr = *_iter ; _pptr != nullptr; _pptr = _pptr->_next ) { - - if (_pptr->_data.kind() + + if (_pptr->_data.kind() == JIGSAW_TRIA3_TAG ) { if (_pptr->_data.indx() < +0 || - _pptr->_data.indx() >= _nnT3 + _pptr->_data.indx() >= _nnT3 ) { _errv = __invalid_argument ; @@ -884,15 +884,15 @@ { _errv = __invalid_argument ; } - + } } - + if (_errv != __no_error) { _jlog. push ( "**input error: GEOM. BOUND indexing is incorrect.\n") ; - + return _errv ; } } @@ -910,13 +910,34 @@ { _jlog.push ( "**input error: GEOM. RADII entries are incorrect.\n") ; - + _errv = __invalid_argument ; } - - iptr_type _imin = + + real_type static const _PI = + (real_type)std::atan(+1.0) * 4. ; + + // careful with the way PI truncations onto float + // expanded range so that we don't throw warnings + // due to rounding issues... + + real_type static const _XMIN = + (real_type) -2.1 * _PI ; + real_type static const _XMAX = + (real_type) +2.1 * _PI ; + real_type static const _YMIN = + (real_type) -1.1 * _PI ; + real_type static const _YMAX = + (real_type) +1.1 * _PI ; + + real_type _xmin = _XMAX; + real_type _xmax = _XMIN; + real_type _ymin = _YMAX; + real_type _ymax = _YMIN; + + iptr_type _imin = std::numeric_limits::max() ; - iptr_type _imax = + iptr_type _imax = std::numeric_limits::min() ; iptr_type _nnPT = +0 ; @@ -929,10 +950,38 @@ ++_iter ) { if (_iter->mark() < 0) continue; - + + _xmin = std::min( + _xmin, _iter->pval(0)) ; + _xmax = std::max( + _xmax, _iter->pval(0)) ; + + _ymin = std::min( + _ymin, _iter->pval(1)) ; + _ymax = std::max( + _ymax, _iter->pval(1)) ; + _nnPT += +1 ; } + if (_xmin < _XMIN || + _xmax > _XMAX ) + { + _jlog.push ( + "**input error: XPOS. must be in [-1.*pi, +1.*pi].\n") ; + + _errv = __invalid_argument ; + } + + if (_ymin < _YMIN || + _ymax > _YMAX ) + { + _jlog.push ( + "**input error: YPOS. must be in [-.5*pi, +.5*pi].\n") ; + + _errv = __invalid_argument ; + } + for (auto _iter = _geom. _ellipsoid_mesh_3d._mesh._set2.head() ; _iter != _geom. @@ -940,7 +989,7 @@ ++_iter ) { if (_iter->mark() < 0) continue; - + _imin = std::min( _imin, _iter->node(0)) ; _imin = std::min( @@ -949,14 +998,14 @@ _imax, _iter->node(0)) ; _imax = std::max( _imax, _iter->node(1)) ; - + _nnE2 += +1 ; - - if (_imin < +0 || + + if (_imin < +0 || _imax >= _nnPT) { _errv = __invalid_argument ; - } + } } if (_errv != __no_error) @@ -976,7 +1025,7 @@ * ECHO-GEOM: print summary of GEOM data. -------------------------------------------------------- */ - + template < typename jlog_data > @@ -995,7 +1044,7 @@ _sstr << " " __tag " = " \ << __var << "\n" ; \ _jlog.push(_sstr.str()); - + /*---------------------------------- push "real" data */ #define __dumpREAL(__tag,__var) \ _sstr.str(""); \ @@ -1008,7 +1057,7 @@ _jlog.push(_sstr.str()) ; \ iptr_type _errv = __no_error ; - + __unreferenced(_jcfg) ; if (_geom._ndim == +2 && @@ -1018,14 +1067,14 @@ /*--------------------------------- euclidean-mesh-2d */ _jlog.push( " EUCLIDEAN-MESH\n\n") ; - + __dumpINTS("|NDIMS.|", +2) ; - + _jlog.push("\n") ; - + iptr_type _nnPT = +0 ; iptr_type _nnE2 = +0 ; - + for (auto _iter = _geom. _euclidean_mesh_2d._tria._set1.head() ; _iter != _geom. @@ -1034,9 +1083,9 @@ { if (_iter->mark()>=+0) _nnPT += +1 ; } - + __dumpINTS("|COORD.|", _nnPT) - + for (auto _iter = _geom. _euclidean_mesh_2d._tria._set2.head() ; _iter != _geom. @@ -1045,8 +1094,8 @@ { if (_iter->mark()>=+0) _nnE2 += +1 ; } - - __dumpINTS("|EDGE-2|", _nnE2) + + __dumpINTS("|EDGE-2|", _nnE2) } else if (_geom._ndim == +3 && @@ -1056,15 +1105,15 @@ /*--------------------------------- euclidean-mesh-3d */ _jlog.push( " EUCLIDEAN-MESH\n\n") ; - + __dumpINTS("|NDIMS.|", +3) ; - + _jlog.push("\n") ; - + iptr_type _nnPT = +0 ; iptr_type _nnE2 = +0 ; iptr_type _nnT3 = +0 ; - + for (auto _iter = _geom. _euclidean_mesh_3d._tria._set1.head() ; _iter != _geom. @@ -1073,9 +1122,9 @@ { if (_iter->mark()>=+0) _nnPT += +1 ; } - + __dumpINTS("|COORD.|", _nnPT) - + for (auto _iter = _geom. _euclidean_mesh_3d._tria._set2.head() ; _iter != _geom. @@ -1084,9 +1133,9 @@ { if (_iter->mark()>=+0) _nnE2 += +1 ; } - + __dumpINTS("|EDGE-2|", _nnE2) - + for (auto _iter = _geom. _euclidean_mesh_3d._tria._set3.head() ; _iter != _geom. @@ -1095,8 +1144,8 @@ { if (_iter->mark()>=+0) _nnT3 += +1 ; } - - __dumpINTS("|TRIA-3|", _nnT3) + + __dumpINTS("|TRIA-3|", _nnT3) } else if (_geom._kind == @@ -1105,25 +1154,25 @@ /*--------------------------------- ellipsoid-mesh-3d */ _jlog.push( " ELLIPSOID-MESH\n\n") ; - + __dumpINTS("|NDIMS.|", +3) ; - + _jlog.push("\n") ; - - __dumpREAL("|1-RAD.|", + + __dumpREAL("|1-RAD.|", _geom._ellipsoid_mesh_3d._radA) ; - - __dumpREAL("|2-RAD.|", + + __dumpREAL("|2-RAD.|", _geom._ellipsoid_mesh_3d._radB) ; - - __dumpREAL("|3-RAD.|", - _geom._ellipsoid_mesh_3d._radC) ; - + + __dumpREAL("|3-RAD.|", + _geom._ellipsoid_mesh_3d._radC) ; + _jlog.push("\n") ; - + iptr_type _nnPT = +0 ; iptr_type _nnE2 = +0 ; - + for (auto _iter = _geom. _ellipsoid_mesh_3d._mesh._set1.head() ; _iter != _geom. @@ -1132,9 +1181,9 @@ { if (_iter->mark()>=+0) _nnPT += +1 ; } - + __dumpINTS("|COORD.|", _nnPT) - + for (auto _iter = _geom. _ellipsoid_mesh_3d._mesh._set2.head() ; _iter != _geom. @@ -1143,8 +1192,8 @@ { if (_iter->mark()>=+0) _nnE2 += +1 ; } - - __dumpINTS("|EDGE-2|", _nnE2) + + __dumpINTS("|EDGE-2|", _nnE2) } _jlog.push("\n") ; diff --git a/src/hfn_init.hpp b/src/hfn_init.hpp index 86ca443..4c51fde 100644 --- a/src/hfn_init.hpp +++ b/src/hfn_init.hpp @@ -4,34 +4,34 @@ * HFN-INIT: init HFUN data via GEOM/CFG., etc. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 18 April, 2019 + * Last updated: 28 June, 2019 * * Copyright 2013-2019 * Darren Engwirda @@ -65,27 +65,27 @@ iptr_type _errv = __no_error ; __unreferenced(_jlog) ; - + /*--------------------------------- find GEOM scaling */ real_type _scal = (real_type) +1. ; - - if (_jcfg._hfun_scal == + + if (_jcfg._hfun_scal == jcfg_data::hfun_scal::relative) { - + if (_geom._ndim == +2 && _geom._kind == jmsh_kind::euclidean_mesh) { /*--------------------------------- euclidean-mesh-2d */ _scal = (real_type) +0. ; - _scal += + _scal += _geom._euclidean_mesh_2d._bmax[0] - _geom._euclidean_mesh_2d._bmin[0] ; - _scal += + _scal += _geom._euclidean_mesh_2d._bmax[1] - _geom._euclidean_mesh_2d._bmin[1] ; - + _scal /= (real_type) +2. ; } else @@ -95,16 +95,16 @@ { /*--------------------------------- euclidean-mesh-3d */ _scal = (real_type) +0. ; - _scal += + _scal += _geom._euclidean_mesh_3d._bmax[0] - _geom._euclidean_mesh_3d._bmin[0] ; - _scal += + _scal += _geom._euclidean_mesh_3d._bmax[1] - _geom._euclidean_mesh_3d._bmin[1] ; - _scal += + _scal += _geom._euclidean_mesh_3d._bmax[2] - _geom._euclidean_mesh_3d._bmin[2] ; - + _scal /= (real_type) +3. ; } else @@ -113,55 +113,50 @@ { /*--------------------------------- ellipsoid-mesh-3d */ _scal = (real_type) +0. ; - _scal += + _scal += _geom._ellipsoid_mesh_3d._bmax[0] - _geom._ellipsoid_mesh_3d._bmin[0] ; - _scal += + _scal += _geom._ellipsoid_mesh_3d._bmax[1] - _geom._ellipsoid_mesh_3d._bmin[1] ; - _scal += + _scal += _geom._ellipsoid_mesh_3d._bmax[2] - _geom._ellipsoid_mesh_3d._bmin[2] ; - + _scal /= (real_type) +3. ; } - + } - - /*--------------------------------- push GEOM scaling */ + + /*--------------------------------- push GEOM scaling */ if (_hfun._ndim == +0) { /*--------------------------------- constant-value-kd */ _hfun._constant_value_kd. _hval = _scal*_jcfg._hfun_hmax ; } - else + else if (_hfun._ndim == +2) { if (_hfun._kind == jmsh_kind::euclidean_mesh) { /*--------------------------------- euclidean-mesh-2d */ - for (auto _node = _hfun. - _euclidean_mesh_2d._mesh._set1.head(); - _node != _hfun. - _euclidean_mesh_2d._mesh._set1.tend(); - ++_node ) + for (auto _iter = _hfun. + _euclidean_mesh_2d._hval.head(); + _iter != _hfun. + _euclidean_mesh_2d._hval.tend(); + ++_iter ) { - if (_node->mark() < 0) continue; - - _node->hval() = - _scal * _node->hval(); - - _node->hval() = - std::min(_node->hval(), + *_iter = _scal * *_iter; + + *_iter = std::min(*_iter, _scal *_jcfg._hfun_hmax) ; - - _node->hval() = - std::max(_node->hval(), + + *_iter = std::max(*_iter, _scal *_jcfg._hfun_hmin) ; } - + } if (_hfun._kind == jmsh_kind::euclidean_grid) @@ -174,43 +169,38 @@ ++_iter ) { *_iter = _scal * *_iter; - - *_iter = std::min(*_iter, + + *_iter = std::min(*_iter, _scal *_jcfg._hfun_hmax) ; - - *_iter = std::max(*_iter, + + *_iter = std::max(*_iter, _scal *_jcfg._hfun_hmin) ; } - + } } - else + else if (_hfun._ndim == +3) { if (_hfun._kind == jmsh_kind::euclidean_mesh) { /*--------------------------------- euclidean-mesh-3d */ - for (auto _node = _hfun. - _euclidean_mesh_3d._mesh._set1.head(); - _node != _hfun. - _euclidean_mesh_3d._mesh._set1.tend(); - ++_node ) + for (auto _iter = _hfun. + _euclidean_mesh_3d._hval.head(); + _iter != _hfun. + _euclidean_mesh_3d._hval.tend(); + ++_iter ) { - if (_node->mark() < 0) continue; + *_iter = _scal * *_iter; - _node->hval() = - _scal * _node->hval(); - - _node->hval() = - std::min(_node->hval(), + *_iter = std::min(*_iter, _scal *_jcfg._hfun_hmax) ; - - _node->hval() = - std::max(_node->hval(), + + *_iter = std::max(*_iter, _scal *_jcfg._hfun_hmin) ; } - + } if (_hfun._kind == jmsh_kind::euclidean_grid) @@ -223,14 +213,14 @@ ++_iter ) { *_iter = _scal * *_iter; - - *_iter = std::min(*_iter, + + *_iter = std::min(*_iter, _scal *_jcfg._hfun_hmax) ; - - *_iter = std::max(*_iter, + + *_iter = std::max(*_iter, _scal *_jcfg._hfun_hmin) ; } - + } } else @@ -238,23 +228,18 @@ jmsh_kind::ellipsoid_mesh) { /*--------------------------------- ellipsoid-mesh-3d */ - for (auto _node = _hfun. - _ellipsoid_mesh_3d._mesh._set1.head(); - _node != _hfun. - _ellipsoid_mesh_3d._mesh._set1.tend(); - ++_node ) + for (auto _iter = _hfun. + _ellipsoid_mesh_3d._hval.head(); + _iter != _hfun. + _ellipsoid_mesh_3d._hval.tend(); + ++_iter ) { - if (_node->mark() < 0) continue; + *_iter = _scal * *_iter; - _node->hval() = - _scal * _node->hval(); - - _node->hval() = - std::min(_node->hval(), + *_iter = std::min(*_iter, _scal *_jcfg._hfun_hmax) ; - - _node->hval() = - std::max(_node->hval(), + + *_iter = std::max(*_iter, _scal *_jcfg._hfun_hmin) ; } @@ -271,17 +256,17 @@ ++_iter ) { *_iter = _scal * *_iter; - - *_iter = std::min(*_iter, + + *_iter = std::min(*_iter, _scal *_jcfg._hfun_hmax) ; - - *_iter = std::max(*_iter, + + *_iter = std::max(*_iter, _scal *_jcfg._hfun_hmin) ; } - + } - - + + return ( _errv ) ; } diff --git a/src/hfn_load.hpp b/src/hfn_load.hpp index aff36a7..7a0ede8 100644 --- a/src/hfn_load.hpp +++ b/src/hfn_load.hpp @@ -4,34 +4,34 @@ * HFN-LOAD: parse *.MSH file into HFUN data. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 30 April, 2019 + * Last updated: 22 July, 2019 * * Copyright 2013-2019 * Darren Engwirda @@ -53,7 +53,7 @@ * HFUN-FROM-JMSH: read *.JMSH file into HFUN data. -------------------------------------------------------- */ - + template < typename jlog_data > @@ -63,43 +63,40 @@ hfun_data &_hfun ) { - class hfun_reader: + class hfun_reader: public jmsh_reader_base { public : hfun_data *_hfun ; - - containers::array< - std::int32_t > _pmap ; - + std::int32_t _ftag ; jmsh_kind:: enum_data _kind ; std:: size_t _ndim ; - + public : __normal_call hfun_reader ( hfun_data*_hsrc = nullptr - ) : _hfun(_hsrc) {} + ) : _hfun(_hsrc) {} /*-------------------------------- read MSHID section */ __normal_call void_type push_mshid ( - std::int32_t _ftag , - jmsh_kind::enum_data _kind + std::int32_t _FTAG , + jmsh_kind::enum_data _KIND ) - { - this->_ftag = _ftag ; - this->_kind = _kind ; + { + this->_ftag = _FTAG ; + this->_kind = _KIND ; this-> - _hfun->_kind = _kind ; + _hfun->_kind = _KIND ; } /*-------------------------------- read NDIMS section */ __normal_call void_type push_ndims ( - std:: size_t _ndim + std:: size_t _NDIM ) - { - this->_ndim = _ndim ; + { + this->_ndim = _NDIM ; this-> - _hfun->_ndim = _ndim ; + _hfun->_ndim = _NDIM ; } /*-------------------------------- read POINT section */ __normal_call void_type push_point ( @@ -112,63 +109,119 @@ __unreferenced(_itag) ; if (this->_ndim == +2 && - this->_kind == + this->_kind == jmsh_kind::euclidean_mesh) { - std::int32_t _npos ; - typename + typename hfun_data::euclidean_mesh_2d ::node_type _ndat ; _ndat.pval(0) = _pval[0]; _ndat.pval(1) = _pval[1]; - - _npos = this->_hfun-> - _euclidean_mesh_2d. + + this->_hfun-> + _euclidean_mesh_2d. _mesh.push_node(_ndat, false) ; - - this->_pmap. - push_tail(_npos) ; - } + } else if (this->_ndim == +3 && - this->_kind == + this->_kind == jmsh_kind::euclidean_mesh) { - std::int32_t _npos ; - typename + typename hfun_data::euclidean_mesh_3d ::node_type _ndat ; _ndat.pval(0) = _pval[0]; _ndat.pval(1) = _pval[1]; _ndat.pval(2) = _pval[2]; - - _npos = this->_hfun-> - _euclidean_mesh_3d. + + this->_hfun-> + _euclidean_mesh_3d. _mesh.push_node(_ndat, false) ; - - this->_pmap. - push_tail(_npos) ; } else - if (this->_kind == + if (this->_kind == jmsh_kind::ellipsoid_mesh) { - std::int32_t _npos ; - typename + typename hfun_data::ellipsoid_mesh_3d ::node_type _ndat ; _ndat.pval(0) = _pval[0]; _ndat.pval(1) = _pval[1]; _ndat.pval(2) = +0.0 ; - - _npos = this->_hfun-> - _ellipsoid_mesh_3d. + + this->_hfun-> + _ellipsoid_mesh_3d. _mesh.push_node(_ndat, false) ; - - this->_pmap. - push_tail(_npos) ; } - } + } + /*-------------------------------- read TRIA3 section */ + __normal_call void_type push_tria3 ( + std:: size_t _ipos , + std::int32_t *_node , + std::int32_t _itag + ) + { + __unreferenced(_ipos) ; + __unreferenced(_itag) ; + + if (this->_ndim == +2 && + this->_kind == + jmsh_kind::euclidean_mesh) + { + typename + hfun_data::euclidean_mesh_2d + ::tri3_type _tdat ; + _tdat.node(0) = _node[0]; + _tdat.node(1) = _node[1]; + _tdat.node(2) = _node[2]; + + this->_hfun-> + _euclidean_mesh_2d. + _mesh.push_tri3(_tdat, false) ; + } + else + if (this->_kind == + jmsh_kind::ellipsoid_mesh) + { + typename + hfun_data::ellipsoid_mesh_3d + ::tri3_type _tdat ; + _tdat.node(0) = _node[0]; + _tdat.node(1) = _node[1]; + _tdat.node(2) = _node[2]; + + this->_hfun-> + _ellipsoid_mesh_3d. + _mesh.push_tri3(_tdat, false) ; + } + } + /*-------------------------------- read TRIA4 section */ + __normal_call void_type push_tria4 ( + std:: size_t _ipos , + std::int32_t *_node , + std::int32_t _itag + ) + { + __unreferenced(_ipos) ; + __unreferenced(_itag) ; + + if (this->_ndim == +3 && + this->_kind == + jmsh_kind::euclidean_mesh) + { + typename + hfun_data::euclidean_mesh_3d + ::tri4_type _tdat ; + _tdat.node(0) = _node[0]; + _tdat.node(1) = _node[1]; + _tdat.node(2) = _node[2]; + _tdat.node(3) = _node[3]; + + this->_hfun-> + _euclidean_mesh_3d. + _mesh.push_tri4(_tdat, false) ; + } + } /*-------------------------------- read COORD section */ __normal_call void_type push_coord ( std:: size_t _idim, @@ -179,7 +232,7 @@ __unreferenced(_irow) ; if (this->_ndim == +2 && - this->_kind == + this->_kind == jmsh_kind::euclidean_grid) { if (_idim == +1) @@ -194,11 +247,11 @@ this->_hfun-> _euclidean_grid_2d. _ypos.push_tail(_ppos) ; - } + } } else if (this->_ndim == +3 && - this->_kind == + this->_kind == jmsh_kind::euclidean_grid) { if (_idim == +1) @@ -223,7 +276,7 @@ } } else - if (this->_kind == + if (this->_kind == jmsh_kind::ellipsoid_grid) { if (_idim == +1) @@ -238,9 +291,69 @@ this->_hfun-> _ellipsoid_grid_3d. _ypos.push_tail(_ppos) ; - } + } + } + } + /*-------------------------------- open VALUE section */ + __normal_call void_type open_value ( + std:: size_t _nrow , + std:: size_t _nval + ) + { + __unreferenced(_nval) ; + + if (this->_ndim == +2 && + this->_kind == + jmsh_kind::euclidean_mesh) + { + this->_hfun-> + _euclidean_mesh_2d. + _hval.set_count(_nrow) ; + } + else + if (this->_ndim == +2 && + this->_kind == + jmsh_kind::euclidean_grid) + { + this->_hfun-> + _euclidean_grid_2d. + _hmat.set_count(_nrow) ; + } + else + if (this->_ndim == +3 && + this->_kind == + jmsh_kind::euclidean_mesh) + { + this->_hfun-> + _euclidean_mesh_3d. + _hval.set_count(_nrow) ; + } + else + if (this->_ndim == +3 && + this->_kind == + jmsh_kind::euclidean_grid) + { + this->_hfun-> + _euclidean_grid_3d. + _hmat.set_count(_nrow) ; + } + else + if (this->_kind == + jmsh_kind::ellipsoid_mesh) + { + this->_hfun-> + _ellipsoid_mesh_3d. + _hval.set_count(_nrow) ; + } + else + if (this->_kind == + jmsh_kind::ellipsoid_grid) + { + this->_hfun-> + _ellipsoid_grid_3d. + _hmat.set_count(_nrow) ; } - } + } /*-------------------------------- read VALUE section */ __normal_call void_type push_value ( std:: size_t _ipos , @@ -248,141 +361,173 @@ ) { if (this->_ndim == +2 && - this->_kind == + this->_kind == jmsh_kind::euclidean_mesh) { - if (_ipos < this->_pmap.count()) - { - std::int32_t _nmap ; - _nmap = this->_pmap [_ipos]; - this->_hfun-> - _euclidean_mesh_2d._mesh. - _set1[_nmap].hval() = *_vval; - } + _euclidean_mesh_2d. + _hval[_ipos] = *_vval; } else if (this->_ndim == +2 && - this->_kind == + this->_kind == jmsh_kind::euclidean_grid) { this->_hfun-> _euclidean_grid_2d. - _hmat.push_tail(*_vval) ; + _hmat[_ipos] = *_vval; } else if (this->_ndim == +3 && - this->_kind == + this->_kind == jmsh_kind::euclidean_mesh) { - if (_ipos < this->_pmap.count()) - { - std::int32_t _nmap ; - _nmap = this->_pmap [_ipos]; - this->_hfun-> - _euclidean_mesh_3d._mesh. - _set1[_nmap].hval() = *_vval; - } + _euclidean_mesh_3d. + _hval[_ipos] = *_vval; } else if (this->_ndim == +3 && - this->_kind == + this->_kind == jmsh_kind::euclidean_grid) { this->_hfun-> _euclidean_grid_3d. - _hmat.push_tail(*_vval) ; + _hmat[_ipos] = *_vval; } else - if (this->_kind == + if (this->_kind == jmsh_kind::ellipsoid_mesh) { - if (_ipos < this->_pmap.count()) - { - std::int32_t _nmap ; - _nmap = this->_pmap [_ipos]; - this->_hfun-> - _ellipsoid_mesh_3d._mesh. - _set1[_nmap].hval() = *_vval; - } + _ellipsoid_mesh_3d. + _hval[_ipos] = *_vval; } else - if (this->_kind == + if (this->_kind == jmsh_kind::ellipsoid_grid) { this->_hfun-> _ellipsoid_grid_3d. - _hmat.push_tail(*_vval) ; + _hmat[_ipos] = *_vval; } } - /*-------------------------------- read TRIA3 section */ - __normal_call void_type push_tria3 ( - std:: size_t _ipos , - std::int32_t *_node , - std::int32_t _itag + /*-------------------------------- open SLOPE section */ + __normal_call void_type open_slope ( + std:: size_t _nrow , + std:: size_t _nval ) { - __unreferenced(_ipos) ; - __unreferenced(_itag) ; + __unreferenced(_nval) ; if (this->_ndim == +2 && - this->_kind == + this->_kind == jmsh_kind::euclidean_mesh) { - typename - hfun_data::euclidean_mesh_2d - ::tri3_type _tdat ; - _tdat.node(0) = _node[0]; - _tdat.node(1) = _node[1]; - _tdat.node(2) = _node[2]; - this->_hfun-> _euclidean_mesh_2d. - _mesh.push_tri3(_tdat, false) ; + _dhdx.set_count(_nrow) ; } else - if (this->_kind == + if (this->_ndim == +2 && + this->_kind == + jmsh_kind::euclidean_grid) + { + this->_hfun-> + _euclidean_grid_2d. + _dhdx.set_count(_nrow) ; + } + else + if (this->_ndim == +3 && + this->_kind == + jmsh_kind::euclidean_mesh) + { + this->_hfun-> + _euclidean_mesh_3d. + _dhdx.set_count(_nrow) ; + } + else + if (this->_ndim == +3 && + this->_kind == + jmsh_kind::euclidean_grid) + { + this->_hfun-> + _euclidean_grid_3d. + _dhdx.set_count(_nrow) ; + } + else + if (this->_kind == jmsh_kind::ellipsoid_mesh) { - typename - hfun_data::ellipsoid_mesh_3d - ::tri3_type _tdat ; - _tdat.node(0) = _node[0]; - _tdat.node(1) = _node[1]; - _tdat.node(2) = _node[2]; - this->_hfun-> _ellipsoid_mesh_3d. - _mesh.push_tri3(_tdat, false) ; + _dhdx.set_count(_nrow) ; + } + else + if (this->_kind == + jmsh_kind::ellipsoid_grid) + { + this->_hfun-> + _ellipsoid_grid_3d. + _dhdx.set_count(_nrow) ; } } - /*-------------------------------- read TRIA4 section */ - __normal_call void_type push_tria4 ( + /*-------------------------------- read SLOPE section */ + __normal_call void_type push_slope ( std:: size_t _ipos , - std::int32_t *_node , - std::int32_t _itag + double *_vval ) { - __unreferenced(_ipos) ; - __unreferenced(_itag) ; - + if (this->_ndim == +2 && + this->_kind == + jmsh_kind::euclidean_mesh) + { + this->_hfun-> + _euclidean_mesh_2d. + _dhdx[_ipos] = *_vval; + } + else + if (this->_ndim == +2 && + this->_kind == + jmsh_kind::euclidean_grid) + { + this->_hfun-> + _euclidean_grid_2d. + _dhdx[_ipos] = *_vval; + } + else if (this->_ndim == +3 && - this->_kind == + this->_kind == jmsh_kind::euclidean_mesh) { - typename - hfun_data::euclidean_mesh_3d - ::tri4_type _tdat ; - _tdat.node(0) = _node[0]; - _tdat.node(1) = _node[1]; - _tdat.node(2) = _node[2]; - _tdat.node(3) = _node[3]; - this->_hfun-> _euclidean_mesh_3d. - _mesh.push_tri4(_tdat, false) ; + _dhdx[_ipos] = *_vval; + } + else + if (this->_ndim == +3 && + this->_kind == + jmsh_kind::euclidean_grid) + { + this->_hfun-> + _euclidean_grid_3d. + _dhdx[_ipos] = *_vval; + } + else + if (this->_kind == + jmsh_kind::ellipsoid_mesh) + { + this->_hfun-> + _ellipsoid_mesh_3d. + _dhdx[_ipos] = *_vval; + } + else + if (this->_kind == + jmsh_kind::ellipsoid_grid) + { + this->_hfun-> + _ellipsoid_grid_3d. + _dhdx[_ipos] = *_vval; } } /*---------------------------------- parse RADII data */ @@ -402,17 +547,17 @@ this->_hfun->_ellipsoid_grid_3d. _radB = _erad[ 1] ; this->_hfun->_ellipsoid_grid_3d. - _radC = _erad[ 2] ; - } + _radC = _erad[ 2] ; + } } ; - + /*---------------------------------- parse HFUN. file */ iptr_type _errv = __no_error ; - + try { jmsh_reader _jmsh ; - std::ifstream _file ; + std::ifstream _file ; _file. open( _jcfg._hfun_file, std::ifstream::in) ; @@ -422,18 +567,18 @@ _file, hfun_reader(&_hfun)); } else - { + { _jlog.push( "**parse error: file not found!\n" ) ; - + _errv = __file_not_located ; } _file.close (); - for (auto _iter = + for (auto _iter = _jmsh._errs.head(); - _iter != - _jmsh._errs.tend(); + _iter != + _jmsh._errs.tend(); ++_iter ) { _jlog.push( @@ -447,13 +592,13 @@ return ( _errv ) ; } - + /* -------------------------------------------------------- * HFUN-FROM-MSHT: read MSH_t data into HFUN data. -------------------------------------------------------- */ - + template < typename jlog_data > @@ -465,127 +610,171 @@ ) { iptr_type _errv = __no_error ; - + try { - + __unreferenced (_jlog) ; __unreferenced (_jcfg) ; - if (_hmsh._flags == + if (_hmsh._flags == JIGSAW_EUCLIDEAN_MESH ) { if (_hmsh._vert2._size > 0) { /*--------------------------------- euclidean-mesh-2d */ - _hfun._kind + _hfun._kind = jmsh_kind::euclidean_mesh ; _hfun._ndim = +2; - + if (_hmsh._vert2._size != _hmsh._value._size ) return __invalid_argument ; - + for (auto _ipos = (size_t) +0 ; - _ipos != _hmsh._vert2._size ; + _ipos != _hmsh._vert2._size ; ++_ipos ) { - typename + typename hfun_data::euclidean_mesh_2d ::node_type _ndat ; _ndat.pval(0) = _hmsh. - _vert2._data[_ipos]._ppos[0]; + _vert2._data[_ipos]._ppos[0]; _ndat.pval(1) = _hmsh. - _vert2._data[_ipos]._ppos[1]; - _ndat.hval () = _hmsh. - _value._data[_ipos] ; - + _vert2._data[_ipos]._ppos[1]; + _hfun._euclidean_mesh_2d. _mesh.push_node(_ndat, false) ; } for (auto _ipos = (size_t) +0 ; - _ipos != _hmsh._tria3._size ; + _ipos != _hmsh._tria3._size ; ++_ipos ) { - typename + typename hfun_data::euclidean_mesh_2d ::tri3_type _tdat ; _tdat.node(0) = _hmsh. - _tria3._data[_ipos]._node[0]; + _tria3._data[_ipos]._node[0]; _tdat.node(1) = _hmsh. - _tria3._data[_ipos]._node[1]; + _tria3._data[_ipos]._node[1]; _tdat.node(2) = _hmsh. - _tria3._data[_ipos]._node[2]; - + _tria3._data[_ipos]._node[2]; + _hfun._euclidean_mesh_2d. _mesh.push_tri3(_tdat, false) ; } - + + _hfun._euclidean_mesh_2d._hval. + set_count(_hmsh._value._size) ; + + _hfun._euclidean_mesh_2d._dhdx. + set_count(_hmsh._slope._size) ; + + for (auto _ipos = (size_t) +0 ; + _ipos != _hmsh._value._size ; + ++_ipos ) + { + _hfun._euclidean_mesh_2d. + _hval[_ipos] = + _hmsh._value._data[_ipos] ; + } + + for (auto _ipos = (size_t) +0 ; + _ipos != _hmsh._slope._size ; + ++_ipos ) + { + _hfun._euclidean_mesh_2d. + _dhdx[_ipos] = + _hmsh._slope._data[_ipos] ; + } + } else if (_hmsh._vert3._size > 0) { /*--------------------------------- euclidean-mesh-3d */ - _hfun._kind + _hfun._kind = jmsh_kind::euclidean_mesh ; _hfun._ndim = +3; - + if (_hmsh._vert3._size != _hmsh._value._size ) return __invalid_argument ; - + for (auto _ipos = (size_t) +0 ; - _ipos != _hmsh._vert3._size ; + _ipos != _hmsh._vert3._size ; ++_ipos ) { - typename + typename hfun_data::euclidean_mesh_3d ::node_type _ndat ; _ndat.pval(0) = _hmsh. - _vert3._data[_ipos]._ppos[0]; + _vert3._data[_ipos]._ppos[0]; _ndat.pval(1) = _hmsh. - _vert3._data[_ipos]._ppos[1]; + _vert3._data[_ipos]._ppos[1]; _ndat.pval(2) = _hmsh. - _vert3._data[_ipos]._ppos[2]; - _ndat.hval () = _hmsh. - _value._data[_ipos] ; - + _vert3._data[_ipos]._ppos[2]; + _hfun._euclidean_mesh_3d. _mesh.push_node(_ndat, false) ; } - + for (auto _ipos = (size_t) +0 ; - _ipos != _hmsh._tria4._size ; + _ipos != _hmsh._tria4._size ; ++_ipos ) { - typename + typename hfun_data::euclidean_mesh_3d ::tri4_type _tdat ; _tdat.node(0) = _hmsh. - _tria4._data[_ipos]._node[0]; + _tria4._data[_ipos]._node[0]; _tdat.node(1) = _hmsh. - _tria4._data[_ipos]._node[1]; + _tria4._data[_ipos]._node[1]; _tdat.node(2) = _hmsh. - _tria4._data[_ipos]._node[2]; + _tria4._data[_ipos]._node[2]; _tdat.node(3) = _hmsh. - _tria4._data[_ipos]._node[3]; - + _tria4._data[_ipos]._node[3]; + _hfun._euclidean_mesh_3d. _mesh.push_tri4(_tdat, false) ; } - + + _hfun._euclidean_mesh_3d._hval. + set_count(_hmsh._value._size) ; + + _hfun._euclidean_mesh_3d._dhdx. + set_count(_hmsh._slope._size) ; + + for (auto _ipos = (size_t) +0 ; + _ipos != _hmsh._value._size ; + ++_ipos ) + { + _hfun._euclidean_mesh_3d. + _hval[_ipos] = + _hmsh._value._data[_ipos] ; + } + + for (auto _ipos = (size_t) +0 ; + _ipos != _hmsh._slope._size ; + ++_ipos ) + { + _hfun._euclidean_mesh_3d. + _dhdx[_ipos] = + _hmsh._slope._data[_ipos] ; + } + } } else - if (_hmsh._flags == + if (_hmsh._flags == JIGSAW_ELLIPSOID_MESH ) { /*--------------------------------- ellipsoid-mesh-3d */ - _hfun._kind + _hfun._kind = jmsh_kind::ellipsoid_mesh ; - _hfun._ndim = +3; - + _hfun._ndim = +2; + if (_hmsh._vert2._size != _hmsh._value._size ) return __invalid_argument ; @@ -609,141 +798,205 @@ _hfun._ellipsoid_mesh_3d. _radC = _hmsh._radii._data[0] ; } - + for (auto _ipos = (size_t) +0 ; - _ipos != _hmsh._vert2._size ; + _ipos != _hmsh._vert2._size ; ++_ipos ) { - typename + typename hfun_data::ellipsoid_mesh_3d ::node_type _ndat ; _ndat.pval(0) = _hmsh. - _vert2._data[_ipos]._ppos[0]; + _vert2._data[_ipos]._ppos[0]; _ndat.pval(1) = _hmsh. - _vert2._data[_ipos]._ppos[1]; + _vert2._data[_ipos]._ppos[1]; _ndat.pval(2) = + 0.0 ; - _ndat.hval () = _hmsh. - _value._data[_ipos] ; - + _hfun._ellipsoid_mesh_3d. _mesh.push_node(_ndat, false) ; } - + for (auto _ipos = (size_t) +0 ; - _ipos != _hmsh._tria3._size ; + _ipos != _hmsh._tria3._size ; ++_ipos ) { - typename + typename hfun_data::ellipsoid_mesh_3d ::tri3_type _tdat ; _tdat.node(0) = _hmsh. - _tria3._data[_ipos]._node[0]; + _tria3._data[_ipos]._node[0]; _tdat.node(1) = _hmsh. - _tria3._data[_ipos]._node[1]; + _tria3._data[_ipos]._node[1]; _tdat.node(2) = _hmsh. - _tria3._data[_ipos]._node[2]; - + _tria3._data[_ipos]._node[2]; + _hfun._ellipsoid_mesh_3d. _mesh.push_tri3(_tdat, false) ; - } - + } + + _hfun._ellipsoid_mesh_3d._hval. + set_count(_hmsh._value._size) ; + + _hfun._ellipsoid_mesh_3d._dhdx. + set_count(_hmsh._slope._size) ; + + for (auto _ipos = (size_t) +0 ; + _ipos != _hmsh._value._size ; + ++_ipos ) + { + _hfun._ellipsoid_mesh_3d. + _hval[_ipos] = + _hmsh._value._data[_ipos] ; + } + + for (auto _ipos = (size_t) +0 ; + _ipos != _hmsh._slope._size ; + ++_ipos ) + { + _hfun._ellipsoid_mesh_3d. + _dhdx[_ipos] = + _hmsh._slope._data[_ipos] ; + } + } else - if (_hmsh._flags == + if (_hmsh._flags == JIGSAW_EUCLIDEAN_GRID ) { if (_hmsh._zgrid._size== 0) { /*--------------------------------- euclidean-grid-2d */ - _hfun._kind + _hfun._kind = jmsh_kind::euclidean_grid ; _hfun._ndim = +2; - + + _hfun._euclidean_grid_2d._xpos. + set_count(_hmsh._xgrid._size) ; + _hfun._euclidean_grid_2d._ypos. + set_count(_hmsh._ygrid._size) ; + + _hfun._euclidean_grid_2d._hmat. + set_count(_hmsh._value._size) ; + + _hfun._euclidean_grid_2d._dhdx. + set_count(_hmsh._slope._size) ; + + for (auto _ipos = (size_t) +0 ; + _ipos != _hmsh._xgrid._size ; + ++_ipos ) + { + _hfun._euclidean_grid_2d. + _xpos[_ipos] = + _hmsh._xgrid._data[_ipos] ; + } + for (auto _ipos = (size_t) +0 ; - _ipos != _hmsh._xgrid._size ; + _ipos != _hmsh._ygrid._size ; ++_ipos ) { - _hfun._euclidean_grid_2d._xpos. - push_tail(_hmsh. - _xgrid._data[_ipos]); + _hfun._euclidean_grid_2d. + _ypos[_ipos] = + _hmsh._ygrid._data[_ipos] ; } - + for (auto _ipos = (size_t) +0 ; - _ipos != _hmsh._ygrid._size ; + _ipos != _hmsh._value._size ; ++_ipos ) { - _hfun._euclidean_grid_2d._ypos. - push_tail(_hmsh. - _ygrid._data[_ipos]); + _hfun._euclidean_grid_2d. + _hmat[_ipos] = + _hmsh._value._data[_ipos] ; } - + for (auto _ipos = (size_t) +0 ; - _ipos != _hmsh._value._size ; + _ipos != _hmsh._slope._size ; ++_ipos ) { - _hfun._euclidean_grid_2d._hmat. - push_tail(_hmsh. - _value._data[_ipos]); + _hfun._euclidean_grid_2d. + _dhdx[_ipos] = + _hmsh._slope._data[_ipos] ; } - + } else if (_hmsh._zgrid._size!= 0) { /*--------------------------------- euclidean-grid-3d */ - _hfun._kind + _hfun._kind = jmsh_kind::euclidean_grid ; _hfun._ndim = +3; - + + _hfun._euclidean_grid_3d._xpos. + set_count(_hmsh._xgrid._size) ; + _hfun._euclidean_grid_3d._ypos. + set_count(_hmsh._ygrid._size) ; + _hfun._euclidean_grid_3d._zpos. + set_count(_hmsh._zgrid._size) ; + + _hfun._euclidean_grid_3d._hmat. + set_count(_hmsh._value._size) ; + + _hfun._euclidean_grid_3d._dhdx. + set_count(_hmsh._slope._size) ; + for (auto _ipos = (size_t) +0 ; - _ipos != _hmsh._xgrid._size ; + _ipos != _hmsh._xgrid._size ; ++_ipos ) { - _hfun._euclidean_grid_3d._xpos. - push_tail(_hmsh. - _xgrid._data[_ipos]); + _hfun._euclidean_grid_3d. + _xpos[_ipos] = + _hmsh._xgrid._data[_ipos] ; } - + for (auto _ipos = (size_t) +0 ; - _ipos != _hmsh._ygrid._size ; + _ipos != _hmsh._ygrid._size ; ++_ipos ) { - _hfun._euclidean_grid_3d._ypos. - push_tail(_hmsh. - _ygrid._data[_ipos]); + _hfun._euclidean_grid_3d. + _ypos[_ipos] = + _hmsh._ygrid._data[_ipos] ; } - + for (auto _ipos = (size_t) +0 ; - _ipos != _hmsh._zgrid._size ; + _ipos != _hmsh._zgrid._size ; ++_ipos ) { - _hfun._euclidean_grid_3d._zpos. - push_tail(_hmsh. - _zgrid._data[_ipos]); + _hfun._euclidean_grid_3d. + _zpos[_ipos] = + _hmsh._zgrid._data[_ipos] ; } - + for (auto _ipos = (size_t) +0 ; - _ipos != _hmsh._value._size ; + _ipos != _hmsh._value._size ; ++_ipos ) { - _hfun._euclidean_grid_3d._hmat. - push_tail(_hmsh. - _value._data[_ipos]); + _hfun._euclidean_grid_3d. + _hmat[_ipos] = + _hmsh._value._data[_ipos] ; } - + + for (auto _ipos = (size_t) +0 ; + _ipos != _hmsh._slope._size ; + ++_ipos ) + { + _hfun._euclidean_grid_3d. + _dhdx[_ipos] = + _hmsh._slope._data[_ipos] ; + } + } } else - if (_hmsh._flags == + if (_hmsh._flags == JIGSAW_ELLIPSOID_GRID ) { if (_hmsh._zgrid._size== 0) { /*--------------------------------- ellipsoid-grid-3d */ - _hfun._kind + _hfun._kind = jmsh_kind::ellipsoid_grid ; - _hfun._ndim = +3; - + _hfun._ndim = +2; + if (_hmsh._radii._size==+3) { _hfun._ellipsoid_grid_3d. @@ -764,36 +1017,56 @@ _radC = _hmsh._radii._data[0] ; } + _hfun._ellipsoid_grid_3d._xpos. + set_count(_hmsh._xgrid._size) ; + _hfun._ellipsoid_grid_3d._ypos. + set_count(_hmsh._ygrid._size) ; + + _hfun._ellipsoid_grid_3d._hmat. + set_count(_hmsh._value._size) ; + + _hfun._ellipsoid_grid_3d._dhdx. + set_count(_hmsh._slope._size) ; + + for (auto _ipos = (size_t) +0 ; + _ipos != _hmsh._xgrid._size ; + ++_ipos ) + { + _hfun._ellipsoid_grid_3d. + _xpos[_ipos] = + _hmsh._xgrid._data[_ipos] ; + } + for (auto _ipos = (size_t) +0 ; - _ipos != _hmsh._xgrid._size ; + _ipos != _hmsh._ygrid._size ; ++_ipos ) { - _hfun._ellipsoid_grid_3d._xpos. - push_tail(_hmsh. - _xgrid._data[_ipos]); + _hfun._ellipsoid_grid_3d. + _ypos[_ipos] = + _hmsh._ygrid._data[_ipos] ; } - + for (auto _ipos = (size_t) +0 ; - _ipos != _hmsh._ygrid._size ; + _ipos != _hmsh._value._size ; ++_ipos ) { - _hfun._ellipsoid_grid_3d._ypos. - push_tail(_hmsh. - _ygrid._data[_ipos]); + _hfun._ellipsoid_grid_3d. + _hmat[_ipos] = + _hmsh._value._data[_ipos] ; } - + for (auto _ipos = (size_t) +0 ; - _ipos != _hmsh._value._size ; + _ipos != _hmsh._value._size ; ++_ipos ) { - _hfun._ellipsoid_grid_3d._hmat. - push_tail(_hmsh. - _value._data[_ipos]); - } - - } - } - + _hfun._ellipsoid_grid_3d. + _dhdx[_ipos] = + _hmsh._slope._data[_ipos] ; + } + + } + } + } catch (...) { @@ -802,13 +1075,13 @@ return ( _errv ) ; } - + /* -------------------------------------------------------- * READ-HFUN: read HFUN input file. -------------------------------------------------------- */ - + template < typename jlog_data > @@ -821,13 +1094,13 @@ return hfun_from_jmsh ( _jcfg, _jlog, _hfun ) ; } - + /* -------------------------------------------------------- * COPY-HFUN: copy HFUN input data. -------------------------------------------------------- */ - + template < typename jlog_data > @@ -837,17 +1110,17 @@ hfun_data &_hfun , jigsaw_msh_t const&_hmsh ) - { + { return hfun_from_msht ( _jcfg, _jlog, _hfun, _hmsh); } - + /* -------------------------------------------------------- * TEST-HFUN: test HFUN data validity. -------------------------------------------------------- */ - + template < typename jlog_data > @@ -861,33 +1134,41 @@ __unreferenced(_jcfg) ; - if (_hfun._ndim == +2 && + if (_hfun._ndim == +2 && _hfun._kind == jmsh_kind::euclidean_mesh) { /*--------------------------------- euclidean-mesh-2d */ - real_type _hmin = + real_type _hmin = std::numeric_limits::max() ; - - iptr_type _imin = + real_type _smin = + std::numeric_limits::max() ; + + iptr_type _imin = std::numeric_limits::max() ; - iptr_type _imax = + iptr_type _imax = std::numeric_limits::min() ; iptr_type _nmax = +0 ; for (auto _iter = _hfun. - _euclidean_mesh_2d._mesh._set1.head() ; + _euclidean_mesh_2d._hval.head() ; _iter != _hfun. - _euclidean_mesh_2d._mesh._set1.tend() ; + _euclidean_mesh_2d._hval.tend() ; ++_iter ) { - if (_iter->mark() < 0) continue ; - - _hmin = std::min( - _hmin, _iter->hval ()) ; + _hmin = std::min(_hmin, *_iter) ; + } + + for (auto _iter = _hfun. + _euclidean_mesh_2d._dhdx.head() ; + _iter != _hfun. + _euclidean_mesh_2d._dhdx.tend() ; + ++_iter ) + { + _smin = std::min(_smin, *_iter) ; } - + for (auto _iter = _hfun. _euclidean_mesh_2d._mesh._set1.head() ; _iter != _hfun. @@ -895,7 +1176,7 @@ ++_iter ) { if (_iter->mark() < 0) continue ; - + _nmax += +1 ; } @@ -906,14 +1187,14 @@ ++_iter ) { if (_iter->mark() < 0) continue ; - + _imin = std::min( _imin, _iter->node(0)) ; _imin = std::min( _imin, _iter->node(1)) ; _imin = std::min( _imin, _iter->node(2)) ; - + _imax = std::max( _imax, _iter->node(0)) ; _imax = std::max( @@ -922,11 +1203,35 @@ _imax, _iter->node(2)) ; } + auto _hnum = _hfun. + _euclidean_mesh_2d._hval.count(); + + auto _gnum = _hfun. + _euclidean_mesh_2d._dhdx.count(); + + if (_gnum > +0 && + _gnum != 1 && + _gnum != _hnum) + { + _jlog.push ( + "**input error: DHDX. matrix incorrect dimensions.\n") ; + + _errv = __invalid_argument ; + } + if (_hmin <= (real_type) +0.) { _jlog.push ( "**input error: HFUN. values must be strictly +ve.\n") ; - + + _errv = __invalid_argument ; + } + + if (_smin <= (real_type) +0.) + { + _jlog.push ( + "**input error: DHDX. values must be strictly +ve.\n") ; + _errv = __invalid_argument ; } @@ -934,19 +1239,21 @@ { _jlog.push ( "**input error: HFUN. tria. indexing is incorrect.\n") ; - + _errv = __invalid_argument ; } } else - if (_hfun._ndim == +2 && + if (_hfun._ndim == +2 && _hfun._kind == jmsh_kind::euclidean_grid) { /*--------------------------------- euclidean-grid-2d */ - real_type _hmin = + real_type _hmin = + std::numeric_limits::infinity(); + real_type _smin = std::numeric_limits::infinity(); - + for (auto _iter = _hfun. _euclidean_grid_2d._hmat.head(); _iter != _hfun. @@ -955,10 +1262,19 @@ { _hmin = std::min(_hmin, *_iter) ; } - + + for (auto _iter = _hfun. + _euclidean_grid_2d._dhdx.head(); + _iter != _hfun. + _euclidean_grid_2d._dhdx.tend(); + ++_iter ) + { + _smin = std::min(_smin, *_iter) ; + } + bool_type _mono = true; - - if(!_hfun._euclidean_grid_2d._xpos.empty()) + + if(!_hfun._euclidean_grid_2d._xpos.empty()) for (auto _iter = _hfun. _euclidean_grid_2d._xpos.head(); _iter != _hfun. @@ -970,8 +1286,8 @@ _mono = false; break; } } - - if(!_hfun._euclidean_grid_2d._ypos.empty()) + + if(!_hfun._euclidean_grid_2d._ypos.empty()) for (auto _iter = _hfun. _euclidean_grid_2d._ypos.head(); _iter != _hfun. @@ -983,66 +1299,95 @@ _mono = false; break; } } - + auto _xnum = _hfun. _euclidean_grid_2d._xpos.count(); - + auto _ynum = _hfun. _euclidean_grid_2d._ypos.count(); - + auto _hnum = _hfun. _euclidean_grid_2d._hmat.count(); - + + auto _gnum = _hfun. + _euclidean_grid_2d._dhdx.count(); + if (_hnum != _xnum * _ynum) { _jlog.push ( "**input error: HFUN. matrix incorrect dimensions.\n") ; - + _errv = __invalid_argument ; } - + + if (_gnum > +0 && + _gnum != 1 && + _gnum != _hnum) + { + _jlog.push ( + "**input error: DHDX. matrix incorrect dimensions.\n") ; + + _errv = __invalid_argument ; + } + if (_hmin <= (real_type) +0.) { _jlog.push ( "**input error: HFUN. values must be strictly +ve.\n") ; - + + _errv = __invalid_argument ; + } + + if (_smin <= (real_type) +0.) + { + _jlog.push ( + "**input error: DHDX. values must be strictly +ve.\n") ; + _errv = __invalid_argument ; } - + if (!_mono) { _jlog.push ( "**input error: grid must be monotonic increasing.\n") ; - + _errv = __invalid_argument ; - } + } } else - if (_hfun._ndim == +3 && + if (_hfun._ndim == +3 && _hfun._kind == jmsh_kind::euclidean_mesh) { /*--------------------------------- euclidean-mesh-3d */ - real_type _hmin = + real_type _hmin = std::numeric_limits::max() ; - - iptr_type _imin = + real_type _smin = + std::numeric_limits::max() ; + + iptr_type _imin = std::numeric_limits::max() ; - iptr_type _imax = + iptr_type _imax = std::numeric_limits::min() ; iptr_type _nmax = +0 ; for (auto _iter = _hfun. - _euclidean_mesh_3d._mesh._set1.head() ; + _euclidean_mesh_3d._hval.head() ; _iter != _hfun. - _euclidean_mesh_3d._mesh._set1.tend() ; + _euclidean_mesh_3d._hval.tend() ; ++_iter ) { - if (_iter->mark() < 0) continue ; - - _hmin = std::min( - _hmin, _iter->hval ()) ; + _hmin = std::min(_hmin, *_iter) ; + } + + for (auto _iter = _hfun. + _euclidean_mesh_3d._dhdx.head() ; + _iter != _hfun. + _euclidean_mesh_3d._dhdx.tend() ; + ++_iter ) + { + _smin = std::min(_smin, *_iter) ; } for (auto _iter = _hfun. @@ -1053,7 +1398,7 @@ { if (_iter->mark() < 0) continue ; - _nmax += +1 ; + _nmax += +1 ; } for (auto _iter = _hfun. @@ -1063,7 +1408,7 @@ ++_iter ) { if (_iter->mark() < 0) continue ; - + _imin = std::min( _imin, _iter->node(0)) ; _imin = std::min( @@ -1072,7 +1417,7 @@ _imin, _iter->node(2)) ; _imin = std::min( _imin, _iter->node(3)) ; - + _imax = std::max( _imax, _iter->node(0)) ; _imax = std::max( @@ -1083,11 +1428,35 @@ _imax, _iter->node(3)) ; } + auto _hnum = _hfun. + _euclidean_mesh_3d._hval.count(); + + auto _gnum = _hfun. + _euclidean_mesh_3d._dhdx.count(); + + if (_gnum > +0 && + _gnum != 1 && + _gnum != _hnum) + { + _jlog.push ( + "**input error: DHDX. matrix incorrect dimensions.\n") ; + + _errv = __invalid_argument ; + } + if (_hmin <= (real_type) +0.) { _jlog.push ( "**input error: HFUN. values must be strictly +ve.\n") ; - + + _errv = __invalid_argument ; + } + + if (_smin <= (real_type) +0.) + { + _jlog.push ( + "**input error: DHDX. values must be strictly +ve.\n") ; + _errv = __invalid_argument ; } @@ -1095,19 +1464,21 @@ { _jlog.push ( "**input error: HFUN. tria. indexing is incorrect.\n") ; - + _errv = __invalid_argument ; } } else - if (_hfun._ndim == +3 && + if (_hfun._ndim == +3 && _hfun._kind == jmsh_kind::euclidean_grid) { /*--------------------------------- euclidean-grid-3d */ - real_type _hmin = + real_type _hmin = std::numeric_limits::infinity(); - + real_type _smin = + std::numeric_limits::infinity(); + for (auto _iter = _hfun. _euclidean_grid_3d._hmat.head(); _iter != _hfun. @@ -1116,10 +1487,19 @@ { _hmin = std::min(_hmin, *_iter) ; } - + + for (auto _iter = _hfun. + _euclidean_grid_3d._dhdx.head(); + _iter != _hfun. + _euclidean_grid_3d._dhdx.tend(); + ++_iter ) + { + _smin = std::min(_smin, *_iter) ; + } + bool_type _mono = true; - - if(!_hfun._euclidean_grid_3d._xpos.empty()) + + if(!_hfun._euclidean_grid_3d._xpos.empty()) for (auto _iter = _hfun. _euclidean_grid_3d._xpos.head(); _iter != _hfun. @@ -1131,8 +1511,8 @@ _mono = false; break; } } - - if(!_hfun._euclidean_grid_3d._ypos.empty()) + + if(!_hfun._euclidean_grid_3d._ypos.empty()) for (auto _iter = _hfun. _euclidean_grid_3d._ypos.head(); _iter != _hfun. @@ -1144,8 +1524,8 @@ _mono = false; break; } } - - if(!_hfun._euclidean_grid_3d._zpos.empty()) + + if(!_hfun._euclidean_grid_3d._zpos.empty()) for (auto _iter = _hfun. _euclidean_grid_3d._zpos.head(); _iter != _hfun. @@ -1157,68 +1537,131 @@ _mono = false; break; } } - + auto _xnum = _hfun. _euclidean_grid_3d._xpos.count(); - + auto _ynum = _hfun. _euclidean_grid_3d._ypos.count(); - + auto _znum = _hfun. _euclidean_grid_3d._zpos.count(); - + auto _hnum = _hfun. _euclidean_grid_3d._hmat.count(); - + + auto _gnum = _hfun. + _euclidean_grid_3d._dhdx.count(); + if (_hnum!=_xnum*_ynum*_znum) { _jlog.push ( "**input error: HFUN. matrix incorrect dimensions.\n") ; - + + _errv = __invalid_argument ; + } + + if (_gnum > +0 && + _gnum != 1 && + _gnum != _hnum) + { + _jlog.push ( + "**input error: DHDX. matrix incorrect dimensions.\n") ; + _errv = __invalid_argument ; } - + if (_hmin <= (real_type) +0.) { _jlog.push ( "**input error: HFUN. values must be strictly +ve.\n") ; - + + _errv = __invalid_argument ; + } + + if (_smin <= (real_type) +0.) + { + _jlog.push ( + "**input error: DHDX. values must be strictly +ve.\n") ; + _errv = __invalid_argument ; } - + if (!_mono) { _jlog.push ( "**input error: grid must be monotonic increasing.\n") ; - + _errv = __invalid_argument ; - } + } } else if (_hfun._kind == jmsh_kind::ellipsoid_mesh) { /*--------------------------------- ellipsoid-mesh-3d */ - real_type _hmin = + if (_hfun._ellipsoid_mesh_3d. + _radA <= (real_type) +0. || + _hfun._ellipsoid_mesh_3d. + _radB <= (real_type) +0. || + _hfun._ellipsoid_mesh_3d. + _radC <= (real_type) +0. ) + { + _jlog.push ( + "**input error: HFUN. RADII entries are incorrect.\n") ; + + _errv = __invalid_argument ; + } + + real_type _hmin = std::numeric_limits::max() ; - - iptr_type _imin = + real_type _smin = + std::numeric_limits::max() ; + + real_type static const _PI = + (real_type)std::atan(+1.0) * 4. ; + + // careful with the way PI truncations onto float + // expanded range so that we don't throw warnings + // due to rounding issues... + + real_type static const _XMIN = + (real_type) -2.1 * _PI ; + real_type static const _XMAX = + (real_type) +2.1 * _PI ; + real_type static const _YMIN = + (real_type) -1.1 * _PI ; + real_type static const _YMAX = + (real_type) +1.1 * _PI ; + + real_type _xmin = _XMAX; + real_type _xmax = _XMIN; + real_type _ymin = _YMAX; + real_type _ymax = _YMIN; + + iptr_type _imin = std::numeric_limits::max() ; - iptr_type _imax = + iptr_type _imax = std::numeric_limits::min() ; iptr_type _nmax = +0 ; for (auto _iter = _hfun. - _ellipsoid_mesh_3d._mesh._set1.head() ; + _ellipsoid_mesh_3d._hval.head() ; _iter != _hfun. - _ellipsoid_mesh_3d._mesh._set1.tend() ; + _ellipsoid_mesh_3d._hval.tend() ; ++_iter ) { - if (_iter->mark() < 0) continue ; - - _hmin = std::min( - _hmin, _iter->hval ()) ; + _hmin = std::min(_hmin, *_iter) ; + } + + for (auto _iter = _hfun. + _ellipsoid_mesh_3d._dhdx.head() ; + _iter != _hfun. + _ellipsoid_mesh_3d._dhdx.tend() ; + ++_iter ) + { + _smin = std::min(_smin, *_iter) ; } for (auto _iter = _hfun. @@ -1229,7 +1672,17 @@ { if (_iter->mark() < 0) continue ; - _nmax += +1 ; + _xmin = std::min( + _xmin, _iter->pval(0)) ; + _xmax = std::max( + _xmax, _iter->pval(0)) ; + + _ymin = std::min( + _ymin, _iter->pval(1)) ; + _ymax = std::max( + _ymax, _iter->pval(1)) ; + + _nmax += +1 ; } for (auto _iter = _hfun. @@ -1239,14 +1692,14 @@ ++_iter ) { if (_iter->mark() < 0) continue ; - + _imin = std::min( _imin, _iter->node(0)) ; _imin = std::min( _imin, _iter->node(1)) ; _imin = std::min( _imin, _iter->node(2)) ; - + _imax = std::max( _imax, _iter->node(0)) ; _imax = std::max( @@ -1255,11 +1708,53 @@ _imax, _iter->node(2)) ; } + auto _hnum = _hfun. + _ellipsoid_mesh_3d._hval.count(); + + auto _gnum = _hfun. + _ellipsoid_mesh_3d._dhdx.count(); + + if (_xmin < _XMIN || + _xmax > _XMAX ) + { + _jlog.push ( + "**input error: XPOS. must be in [-1.*pi, +1.*pi].\n") ; + + _errv = __invalid_argument ; + } + + if (_ymin < _YMIN || + _ymax > _YMAX ) + { + _jlog.push ( + "**input error: YPOS. must be in [-.5*pi, +.5*pi].\n") ; + + _errv = __invalid_argument ; + } + + if (_gnum > +0 && + _gnum != 1 && + _gnum != _hnum) + { + _jlog.push ( + "**input error: DHDX. matrix incorrect dimensions.\n") ; + + _errv = __invalid_argument ; + } + if (_hmin <= (real_type) +0.) { _jlog.push ( "**input error: HFUN. values must be strictly +ve.\n") ; - + + _errv = __invalid_argument ; + } + + if (_smin <= (real_type) +0.) + { + _jlog.push ( + "**input error: DHDX. values must be strictly +ve.\n") ; + _errv = __invalid_argument ; } @@ -1267,7 +1762,7 @@ { _jlog.push ( "**input error: HFUN. tria. indexing is incorrect.\n") ; - + _errv = __invalid_argument ; } } @@ -1276,9 +1771,45 @@ jmsh_kind::ellipsoid_grid) { /*--------------------------------- ellipsoid-grid-3d */ - real_type _hmin = + if (_hfun._ellipsoid_grid_3d. + _radA <= (real_type) +0. || + _hfun._ellipsoid_grid_3d. + _radB <= (real_type) +0. || + _hfun._ellipsoid_grid_3d. + _radC <= (real_type) +0. ) + { + _jlog.push ( + "**input error: HFUN. RADII entries are incorrect.\n") ; + + _errv = __invalid_argument ; + } + + real_type _hmin = + std::numeric_limits::infinity(); + real_type _smin = std::numeric_limits::infinity(); - + + real_type static const _PI = + (real_type)std::atan(+1.0) * 4. ; + + // careful with the way PI truncations onto float + // expanded range so that we don't throw warnings + // due to rounding issues... + + real_type static const _XMIN = + (real_type) -2.1 * _PI ; + real_type static const _XMAX = + (real_type) +2.1 * _PI ; + real_type static const _YMIN = + (real_type) -1.1 * _PI ; + real_type static const _YMAX = + (real_type) +1.1 * _PI ; + + real_type _xmin = _XMAX; + real_type _xmax = _XMIN; + real_type _ymin = _YMAX; + real_type _ymax = _YMIN; + for (auto _iter = _hfun. _ellipsoid_grid_3d._hmat.head(); _iter != _hfun. @@ -1287,10 +1818,19 @@ { _hmin = std::min(_hmin, *_iter) ; } - + + for (auto _iter = _hfun. + _ellipsoid_grid_3d._dhdx.head(); + _iter != _hfun. + _ellipsoid_grid_3d._dhdx.tend(); + ++_iter ) + { + _smin = std::min(_smin, *_iter) ; + } + bool_type _mono = true; - - if(!_hfun._ellipsoid_grid_3d._xpos.empty()) + + if(!_hfun._ellipsoid_grid_3d._xpos.empty()) for (auto _iter = _hfun. _ellipsoid_grid_3d._xpos.head(); _iter != _hfun. @@ -1301,9 +1841,14 @@ { _mono = false; break; } + + _xmin = std::min( + _xmin , *_iter) ; + _xmax = std::max( + _xmax , *_iter) ; } - - if(!_hfun._ellipsoid_grid_3d._ypos.empty()) + + if(!_hfun._ellipsoid_grid_3d._ypos.empty()) for (auto _iter = _hfun. _ellipsoid_grid_3d._ypos.head(); _iter != _hfun. @@ -1314,51 +1859,95 @@ { _mono = false; break; } + + _ymin = std::min( + _ymin , *_iter) ; + _ymax = std::max( + _ymax , *_iter) ; } - + auto _xnum = _hfun. _ellipsoid_grid_3d._xpos.count(); - + auto _ynum = _hfun. _ellipsoid_grid_3d._ypos.count(); - + auto _hnum = _hfun. _ellipsoid_grid_3d._hmat.count(); - + + auto _gnum = _hfun. + _ellipsoid_grid_3d._dhdx.count(); + + if (_xmin < _XMIN || + _xmax > _XMAX ) + { + _jlog.push ( + "**input error: XPOS. must be in [-1.*pi, +1.*pi].\n") ; + + _errv = __invalid_argument ; + } + + if (_ymin < _YMIN || + _ymax > _YMAX ) + { + _jlog.push ( + "**input error: YPOS. must be in [-.5*pi, +.5*pi].\n") ; + + _errv = __invalid_argument ; + } + if (_hnum != _xnum * _ynum) { _jlog.push ( "**input error: HFUN. matrix incorrect dimensions.\n") ; - + + _errv = __invalid_argument ; + } + + if (_gnum > +0 && + _gnum != 1 && + _gnum != _hnum) + { + _jlog.push ( + "**input error: DHDX. matrix incorrect dimensions.\n") ; + _errv = __invalid_argument ; } - + if (_hmin <= (real_type) +0.) { _jlog.push ( "**input error: HFUN. values must be strictly +ve.\n") ; - + + _errv = __invalid_argument ; + } + + if (_smin <= (real_type) +0.) + { + _jlog.push ( + "**input error: DHDX. values must be strictly +ve.\n") ; + _errv = __invalid_argument ; } - + if (!_mono) { _jlog.push ( "**input error: grid must be monotonic increasing.\n") ; - + _errv = __invalid_argument ; - } + } } return ( _errv ) ; } - + /* -------------------------------------------------------- * ECHO-HFUN: print summary of HFUN data. -------------------------------------------------------- */ - + template < typename jlog_data > @@ -1377,7 +1966,7 @@ _sstr << " " __tag " = " \ << __var << "\n" ; \ _jlog.push(_sstr.str()); - + /*---------------------------------- push "real" data */ #define __dumpREAL(__tag,__var) \ _sstr.str(""); \ @@ -1389,26 +1978,26 @@ _jlog.push(_sstr.str()); iptr_type _errv = __no_error ; - + __unreferenced(_jcfg) ; - real_type _hmin = + real_type _hmin = +std::numeric_limits ::infinity() ; - - real_type _hmax = + + real_type _hmax = -std::numeric_limits ::infinity() ; - + if (_hfun._ndim == +0) { /*--------------------------------- constant-value-kd */ _jlog.push( " CONSTANT-VALUE\n\n") ; - - __dumpREAL(".VAL(H).", + + __dumpREAL(".VAL(H).", _hfun._constant_value_kd._hval) - + } else if (_hfun._ndim == +2 && @@ -1418,33 +2007,31 @@ /*--------------------------------- euclidean-mesh-2d */ _jlog.push( " EUCLIDEAN-MESH\n\n") ; - + __dumpINTS("|NDIMS.|", +2) ; - + _jlog.push("\n") ; - + iptr_type _num1 = +0 ; iptr_type _num3 = +0 ; - + for (auto _iter = _hfun. - _euclidean_mesh_2d._mesh._set1.head() ; + _euclidean_mesh_2d._hval.head() ; _iter != _hfun. - _euclidean_mesh_2d._mesh._set1.tend() ; - ++_iter ) + _euclidean_mesh_2d._hval.tend() ; + ++_iter ) { - if (_iter->mark() < 0) continue ; - - _hmin = std::min ( - _hmin, _iter->hval()) ; - _hmax = std::max ( - _hmax, _iter->hval()) ; + _hmin = std::min( + _hmin,*_iter) ; + _hmax = std::max( + _hmax,*_iter) ; } - + __dumpREAL(".MIN(H).", _hmin) __dumpREAL(".MAX(H).", _hmax) - + _jlog.push(" \n") ; - + for (auto _iter = _hfun. _euclidean_mesh_2d._mesh._set1.head() ; _iter != _hfun. @@ -1453,7 +2040,7 @@ { if (_iter->mark()>=+0) _num1 += +1 ; } - + __dumpINTS("|COORD.|", _num1) for (auto _iter = _hfun. @@ -1464,9 +2051,9 @@ { if (_iter->mark()>=+0) _num3 += +1 ; } - + __dumpINTS("|TRIA-3|", _num3) - + } else if (_hfun._ndim == +2 && @@ -1476,37 +2063,37 @@ /*--------------------------------- euclidean-grid-2d */ _jlog.push( " EUCLIDEAN-GRID\n\n") ; - + __dumpINTS("|NDIMS.|", +2) ; - + _jlog.push("\n") ; - + for (auto _iter = _hfun. _euclidean_grid_2d._hmat.head() ; _iter != _hfun. _euclidean_grid_2d._hmat.tend() ; ++_iter ) { - _hmin = + _hmin = std::min(_hmin, *_iter) ; - _hmax = + _hmax = std::max(_hmax, *_iter) ; } - + __dumpREAL(".MIN(H).", _hmin) __dumpREAL(".MAX(H).", _hmax) - + _jlog.push(" \n") ; - + auto _xnum = _hfun. _euclidean_grid_2d._xpos.count(); - + auto _ynum = _hfun. _euclidean_grid_2d._ypos.count(); - + __dumpINTS("|XGRID.|", _xnum) __dumpINTS("|YGRID.|", _ynum) - + } else if (_hfun._ndim == +3 && @@ -1516,33 +2103,31 @@ /*--------------------------------- euclidean-mesh-3d */ _jlog.push( " EUCLIDEAN-MESH\n\n") ; - + __dumpINTS("|NDIMS.|", +3) ; - + _jlog.push("\n") ; - + iptr_type _num1 = +0 ; iptr_type _num4 = +0 ; - + for (auto _iter = _hfun. - _euclidean_mesh_3d._mesh._set1.head() ; + _euclidean_mesh_3d._hval.head() ; _iter != _hfun. - _euclidean_mesh_3d._mesh._set1.tend() ; - ++_iter ) + _euclidean_mesh_3d._hval.tend() ; + ++_iter ) { - if (_iter->mark() < 0) continue ; - - _hmin = std::min ( - _hmin, _iter->hval()) ; - _hmax = std::max ( - _hmax, _iter->hval()) ; + _hmin = std::min( + _hmin,*_iter) ; + _hmax = std::max( + _hmax,*_iter) ; } - + __dumpREAL(".MIN(H).", _hmin) __dumpREAL(".MAX(H).", _hmax) - + _jlog.push(" \n") ; - + for (auto _iter = _hfun. _euclidean_mesh_3d._mesh._set1.head() ; _iter != _hfun. @@ -1551,9 +2136,9 @@ { if (_iter->mark()>=+0) _num1 += +1 ; } - + __dumpINTS("|COORD.|", _num1) - + for (auto _iter = _hfun. _euclidean_mesh_3d._mesh._set4.head() ; _iter != _hfun. @@ -1562,9 +2147,9 @@ { if (_iter->mark()>=+0) _num4 += +1 ; } - + __dumpINTS("|TRIA-4|", _num4) - + } else if (_hfun._ndim == +3 && @@ -1574,41 +2159,41 @@ /*--------------------------------- euclidean-grid-3d */ _jlog.push( " EUCLIDEAN-GRID\n\n") ; - + __dumpINTS("|NDIMS.|", +3) ; - + _jlog.push("\n") ; - + for (auto _iter = _hfun. _euclidean_grid_3d._hmat.head() ; _iter != _hfun. _euclidean_grid_3d._hmat.tend() ; ++_iter ) { - _hmin = + _hmin = std::min(_hmin, *_iter) ; - _hmax = + _hmax = std::max(_hmax, *_iter) ; } - + __dumpREAL(".MIN(H).", _hmin) __dumpREAL(".MAX(H).", _hmax) - + _jlog.push(" \n") ; - + auto _xnum = _hfun. _euclidean_grid_3d._xpos.count(); - + auto _ynum = _hfun. _euclidean_grid_3d._ypos.count(); - + auto _znum = _hfun. _euclidean_grid_3d._zpos.count(); - + __dumpINTS("|XGRID.|", _xnum) __dumpINTS("|YGRID.|", _ynum) __dumpINTS("|ZGRID.|", _znum) - + } else if (_hfun._kind == @@ -1617,29 +2202,27 @@ /*--------------------------------- ellipsoid-mesh-3d */ _jlog.push( " ELLIPSOID-MESH\n\n") ; - + iptr_type _num1 = +0 ; iptr_type _num3 = +0 ; - + for (auto _iter = _hfun. - _ellipsoid_mesh_3d._mesh._set1.head() ; + _ellipsoid_mesh_3d._hval.head() ; _iter != _hfun. - _ellipsoid_mesh_3d._mesh._set1.tend() ; - ++_iter ) + _ellipsoid_mesh_3d._hval.tend() ; + ++_iter ) { - if (_iter->mark() < 0) continue ; - - _hmin = std::min ( - _hmin, _iter->hval()) ; - _hmax = std::max ( - _hmax, _iter->hval()) ; + _hmin = std::min( + _hmin,*_iter) ; + _hmax = std::max( + _hmax,*_iter) ; } - + __dumpREAL(".MIN(H).", _hmin) __dumpREAL(".MAX(H).", _hmax) - + _jlog.push(" \n") ; - + for (auto _iter = _hfun. _ellipsoid_mesh_3d._mesh._set1.head() ; _iter != _hfun. @@ -1648,7 +2231,7 @@ { if (_iter->mark()>=+0) _num1 += +1 ; } - + __dumpINTS("|COORD.|", _num1) for (auto _iter = _hfun. @@ -1659,9 +2242,9 @@ { if (_iter->mark()>=+0) _num3 += +1 ; } - + __dumpINTS("|TRIA-3|", _num3) - + } else if (_hfun._kind == @@ -1670,33 +2253,38 @@ /*--------------------------------- ellipsoid-grid-3d */ _jlog.push( " ELLIPSOID-GRID\n\n") ; - + for (auto _iter = _hfun. _ellipsoid_grid_3d._hmat.head() ; _iter != _hfun. _ellipsoid_grid_3d._hmat.tend() ; ++_iter ) { - _hmin = + _hmin = std::min(_hmin, *_iter) ; - _hmax = + _hmax = std::max(_hmax, *_iter) ; } - + __dumpREAL(".MIN(H).", _hmin) __dumpREAL(".MAX(H).", _hmax) - + _jlog.push(" \n") ; - + auto _xnum = _hfun. _ellipsoid_grid_3d._xpos.count(); - + auto _ynum = _hfun. _ellipsoid_grid_3d._ypos.count(); - + __dumpINTS("|XGRID.|", _xnum) __dumpINTS("|YGRID.|", _ynum) - + + _jlog.push(" \n") ; + + if (_hfun._ellipsoid_grid_3d._wrap) + _jlog.push("PERIODIC = TRUE") ; + } _jlog.push("\n") ; @@ -1707,7 +2295,7 @@ return ( _errv) ; } - + # endif //__HFN_LOAD__ diff --git a/src/ini_load.hpp b/src/ini_load.hpp index 46d98ce..aa60503 100644 --- a/src/ini_load.hpp +++ b/src/ini_load.hpp @@ -4,29 +4,29 @@ * INI-LOAD: parse *.MSH file into INIT data. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- @@ -53,7 +53,7 @@ * INIT-FROM-JMSH: read *.JMSH file into INIT data. -------------------------------------------------------- */ - + template < typename jlog_data > @@ -63,7 +63,7 @@ mesh_data &_init ) { - class init_reader: + class init_reader: public jmsh_reader_base { public : @@ -79,23 +79,23 @@ ) : _init(_isrc) {} /*---------------------------------- parse MSHID data */ __normal_call void_type push_mshid ( - std::int32_t _ftag , - jmsh_kind::enum_data _kind + std::int32_t _FTAG , + jmsh_kind::enum_data _KIND ) - { - this->_ftag = _ftag ; - this->_kind = _kind ; + { + this->_ftag = _FTAG ; + this->_kind = _KIND ; this-> - _init->_kind = _kind ; + _init->_kind = _KIND ; } /*---------------------------------- parse NDIMS data */ __normal_call void_type push_ndims ( - std:: size_t _ndim + std:: size_t _NDIM ) - { - this->_ndim = _ndim ; + { + this->_ndim = _NDIM ; this-> - _init->_ndim = _ndim ; + _init->_ndim = _NDIM ; } /*---------------------------------- parse POINT data */ __normal_call void_type push_point ( @@ -107,57 +107,57 @@ __unreferenced(_ipos) ; if (this->_ndim == +2 && - this->_kind == + this->_kind == jmsh_kind::euclidean_mesh) { - typename + typename mesh_data::euclidean_mesh_2d ::node_type _ndat ; _ndat.pval(0) = _pval[0]; _ndat.pval(1) = _pval[1]; _ndat.itag () = _itag ; - - _ndat.pval(2) = + + _ndat.pval(2) = (real_type) +0. ; - + _ndat.fdim () = +0 ; - + if (_itag < +0) - _ndat.feat () = + _ndat.feat () = mesh::user_feat ; else - _ndat.feat () = + _ndat.feat () = mesh::null_feat ; - + this->_init-> _euclidean_mesh_2d. _mesh.push_node(_ndat, false) ; } else if (this->_ndim == +3 && - this->_kind == + this->_kind == jmsh_kind::euclidean_mesh) { - typename + typename mesh_data::euclidean_mesh_3d ::node_type _ndat ; _ndat.pval(0) = _pval[0]; _ndat.pval(1) = _pval[1]; _ndat.pval(2) = _pval[2]; _ndat.itag () = _itag ; - - _ndat.pval(3) = + + _ndat.pval(3) = (real_type) +0. ; - + _ndat.fdim () = +0 ; - + if (_itag < +0) - _ndat.feat () = + _ndat.feat () = mesh::user_feat ; else - _ndat.feat () = + _ndat.feat () = mesh::null_feat ; - + this->_init-> _euclidean_mesh_3d. _mesh.push_node(_ndat, false) ; @@ -174,36 +174,36 @@ __unreferenced(_itag) ; if (this->_ndim == +2 && - this->_kind == + this->_kind == jmsh_kind::euclidean_mesh) { - typename + typename mesh_data::euclidean_mesh_2d ::edge_type _edat ; _edat.node(0) = _node[0]; _edat.node(1) = _node[1]; _edat.itag () = _itag ; - + this->_init-> _euclidean_mesh_2d. _mesh.push_edge(_edat, false) ; } else if (this->_ndim == +3 && - this->_kind == + this->_kind == jmsh_kind::euclidean_mesh) { - typename + typename mesh_data::euclidean_mesh_3d ::edge_type _edat ; _edat.node(0) = _node[0]; _edat.node(1) = _node[1]; - _edat.itag () = _itag ; + _edat.itag () = _itag ; this->_init-> _euclidean_mesh_3d. _mesh.push_edge(_edat, false) ; - } + } } /*---------------------------------- parse TRIA3 data */ __normal_call void_type push_tria3 ( @@ -216,33 +216,33 @@ __unreferenced(_itag) ; if (this->_ndim == +2 && - this->_kind == + this->_kind == jmsh_kind::euclidean_mesh) { - typename + typename mesh_data::euclidean_mesh_2d ::tria_type _tdat ; _tdat.node(0) = _node[0]; _tdat.node(1) = _node[1]; _tdat.node(2) = _node[2]; _tdat.itag () = _itag ; - + this->_init-> _euclidean_mesh_2d. _mesh.push_tri3(_tdat, false) ; } else if (this->_ndim == +3 && - this->_kind == + this->_kind == jmsh_kind::euclidean_mesh) { - typename + typename mesh_data::euclidean_mesh_3d ::face_type _tdat ; _tdat.node(0) = _node[0]; _tdat.node(1) = _node[1]; _tdat.node(2) = _node[2]; - _tdat.itag () = _itag ; + _tdat.itag () = _itag ; this->_init-> _euclidean_mesh_3d. @@ -260,17 +260,17 @@ __unreferenced(_itag) ; if (this->_ndim == +2 && - this->_kind == + this->_kind == jmsh_kind::euclidean_mesh) { // do nothing... } else if (this->_ndim == +3 && - this->_kind == + this->_kind == jmsh_kind::euclidean_mesh) { - typename + typename mesh_data::euclidean_mesh_3d ::tria_type _tdat ; _tdat.node(0) = _node[0]; @@ -278,21 +278,21 @@ _tdat.node(2) = _node[2]; _tdat.node(3) = _node[3]; _tdat.itag () = _itag ; - + this->_init-> _euclidean_mesh_3d. _mesh.push_tri4(_tdat, false) ; } - } + } } ; - + /*---------------------------------- parse INIT. file */ iptr_type _errv = __no_error ; - + try { jmsh_reader _jmsh ; - std::ifstream _file ; + std::ifstream _file ; _file. open( _jcfg._init_file, std::ifstream::in) ; @@ -302,18 +302,18 @@ _file, init_reader(&_init)); } else - { + { _jlog.push( "**parse error: file not found!\n" ) ; - + _errv = __file_not_located ; } _file.close (); - for (auto _iter = + for (auto _iter = _jmsh._errs.head(); - _iter != - _jmsh._errs.tend(); + _iter != + _jmsh._errs.tend(); ++_iter ) { _jlog.push( @@ -327,13 +327,13 @@ return ( _errv ) ; } - + /* -------------------------------------------------------- * INIT-FROM-MSHT: read MSH_t data into INIT data. -------------------------------------------------------- */ - + template < typename jlog_data > @@ -345,28 +345,28 @@ ) { iptr_type _errv = __no_error ; - + try { - + __unreferenced (_jlog) ; __unreferenced (_jcfg) ; - if (_imsh._flags == + if (_imsh._flags == JIGSAW_EUCLIDEAN_MESH ) { if (_imsh._vert2._size > 0) { /*--------------------------------- euclidean-mesh-2d */ - _init._kind + _init._kind = jmsh_kind::euclidean_mesh ; _init._ndim = +2; - + for (auto _ipos = (size_t) +0 ; - _ipos != _imsh._vert2._size ; + _ipos != _imsh._vert2._size ; ++_ipos ) { - typename + typename mesh_data::euclidean_mesh_2d ::node_type _ndat ; _ndat.pval(0) = _imsh. @@ -375,28 +375,28 @@ _vert2._data[_ipos]._ppos[1]; _ndat.itag () = _imsh. _vert2._data[_ipos]._itag ; - - _ndat.pval(2) = + + _ndat.pval(2) = (real_type) +0. ; - + _ndat.fdim () = +0 ; - + if (_ndat.itag () < +0) - _ndat.feat () = + _ndat.feat () = mesh::user_feat ; else - _ndat.feat () = + _ndat.feat () = mesh::null_feat ; - + _init._euclidean_mesh_2d. _mesh.push_node(_ndat,false); } - + for (auto _ipos = (size_t) +0 ; - _ipos != _imsh._edge2._size ; + _ipos != _imsh._edge2._size ; ++_ipos ) { - typename + typename mesh_data::euclidean_mesh_2d ::edge_type _edat ; _edat.node(0) = _imsh. @@ -405,16 +405,16 @@ _edge2._data[_ipos]._node[1]; _edat.itag () = _imsh. _edge2._data[_ipos]._itag ; - + _init._euclidean_mesh_2d. _mesh.push_edge(_edat,false); } - + for (auto _ipos = (size_t) +0 ; - _ipos != _imsh._tria3._size ; + _ipos != _imsh._tria3._size ; ++_ipos ) { - typename + typename mesh_data::euclidean_mesh_2d ::tria_type _tdat ; _tdat.node(0) = _imsh. @@ -425,25 +425,25 @@ _tria3._data[_ipos]._node[2]; _tdat.itag () = _imsh. _tria3._data[_ipos]._itag ; - + _init._euclidean_mesh_2d. _mesh.push_tri3(_tdat,false); } - + } else if (_imsh._vert3._size > 0) { /*--------------------------------- euclidean-mesh-3d */ - _init._kind + _init._kind = jmsh_kind::euclidean_mesh ; _init._ndim = +3; - + for (auto _ipos = (size_t) +0 ; - _ipos != _imsh._vert3._size ; + _ipos != _imsh._vert3._size ; ++_ipos ) { - typename + typename mesh_data::euclidean_mesh_3d ::node_type _ndat ; _ndat.pval(0) = _imsh. @@ -454,28 +454,28 @@ _vert3._data[_ipos]._ppos[2]; _ndat.itag () = _imsh. _vert3._data[_ipos]._itag ; - - _ndat.pval(3) = + + _ndat.pval(3) = (real_type) +0. ; - + _ndat.fdim () = +0 ; - + if (_ndat.itag () < +0) - _ndat.feat () = + _ndat.feat () = mesh::user_feat ; else - _ndat.feat () = + _ndat.feat () = mesh::null_feat ; - + _init._euclidean_mesh_3d. _mesh.push_node(_ndat,false); } - + for (auto _ipos = (size_t) +0 ; - _ipos != _imsh._edge2._size ; + _ipos != _imsh._edge2._size ; ++_ipos ) { - typename + typename mesh_data::euclidean_mesh_3d ::edge_type _edat ; _edat.node(0) = _imsh. @@ -484,16 +484,16 @@ _edge2._data[_ipos]._node[1]; _edat.itag () = _imsh. _edge2._data[_ipos]._itag ; - + _init._euclidean_mesh_3d. _mesh.push_edge(_edat,false); } - + for (auto _ipos = (size_t) +0 ; - _ipos != _imsh._tria3._size ; + _ipos != _imsh._tria3._size ; ++_ipos ) { - typename + typename mesh_data::euclidean_mesh_3d ::face_type _tdat ; _tdat.node(0) = _imsh. @@ -504,16 +504,16 @@ _tria3._data[_ipos]._node[2]; _tdat.itag () = _imsh. _tria3._data[_ipos]._itag ; - + _init._euclidean_mesh_3d. _mesh.push_tri3(_tdat,false); } - + for (auto _ipos = (size_t) +0 ; - _ipos != _imsh._tria4._size ; + _ipos != _imsh._tria4._size ; ++_ipos ) { - typename + typename mesh_data::euclidean_mesh_3d ::tria_type _tdat ; _tdat.node(0) = _imsh. @@ -525,29 +525,29 @@ _tdat.node(3) = _imsh. _tria4._data[_ipos]._node[3]; _tdat.itag () = _imsh. - _tria4._data[_ipos]._itag ; + _tria4._data[_ipos]._itag ; _init._euclidean_mesh_3d. _mesh.push_tri4(_tdat,false); } - + } } else - if (_imsh._flags == + if (_imsh._flags == JIGSAW_EUCLIDEAN_GRID) { - _errv = + _errv = __invalid_argument ; } else - if (_imsh._flags == + if (_imsh._flags == JIGSAW_ELLIPSOID_GRID) { - _errv = - __invalid_argument ; - } - + _errv = + __invalid_argument ; + } + } catch (...) { @@ -556,13 +556,13 @@ return ( _errv ) ; } - + /* -------------------------------------------------------- * READ-INIT: read init. distribution file. -------------------------------------------------------- */ - + template < typename jlog_data > @@ -575,13 +575,13 @@ return init_from_jmsh ( _jcfg, _jlog, _init ) ; } - + /* -------------------------------------------------------- * COPY-INIT: copy INIT input data. -------------------------------------------------------- */ - + template < typename jlog_data > @@ -591,17 +591,17 @@ mesh_data &_init , jigsaw_msh_t const&_imsh ) - { + { return init_from_msht ( _jcfg, _jlog, _init, _imsh); } - + /* -------------------------------------------------------- * TEST-INIT: test INIT data validity. -------------------------------------------------------- */ - + template < typename jlog_data > @@ -620,9 +620,9 @@ jmsh_kind::euclidean_mesh) { /*--------------------------------- euclidean-mesh-2d */ - iptr_type _imin = + iptr_type _imin = std::numeric_limits::max() ; - iptr_type _imax = + iptr_type _imax = std::numeric_limits::min() ; iptr_type _nmax = +0 ; @@ -634,7 +634,7 @@ ++_iter ) { if (_iter->mark() < 0) continue ; - + _nmax += + 1 ; } @@ -645,7 +645,7 @@ ++_iter ) { if (_iter->mark() < 0) continue ; - + _imin = std::min( _imin, _iter->node(0)) ; _imin = std::min( @@ -655,7 +655,7 @@ _imax = std::max( _imax, _iter->node(1)) ; } - + for (auto _iter = _init. _euclidean_mesh_2d._mesh._set3.head() ; _iter != _init. @@ -663,7 +663,7 @@ ++_iter ) { if (_iter->mark() < 0) continue ; - + _imin = std::min( _imin, _iter->node(0)) ; _imin = std::min( @@ -682,7 +682,7 @@ { _jlog.push ( "**input error: GEOM. tria. indexing is incorrect.\n") ; - + _errv = __invalid_argument ; } } @@ -692,9 +692,9 @@ jmsh_kind::euclidean_mesh) { /*--------------------------------- euclidean-mesh-3d */ - iptr_type _imin = + iptr_type _imin = std::numeric_limits::max() ; - iptr_type _imax = + iptr_type _imax = std::numeric_limits::min() ; iptr_type _nmax = +0 ; @@ -706,7 +706,7 @@ ++_iter ) { if (_iter->mark() < 0) continue ; - + _nmax += + 1 ; } @@ -717,7 +717,7 @@ ++_iter ) { if (_iter->mark() < 0) continue ; - + _imin = std::min( _imin, _iter->node(0)) ; _imin = std::min( @@ -735,7 +735,7 @@ ++_iter ) { if (_iter->mark() < 0) continue ; - + _imin = std::min( _imin, _iter->node(0)) ; _imin = std::min( @@ -749,7 +749,7 @@ _imax = std::max( _imax, _iter->node(2)) ; } - + for (auto _iter = _init. _euclidean_mesh_3d._mesh._set4.head() ; _iter != _init. @@ -757,7 +757,7 @@ ++_iter ) { if (_iter->mark() < 0) continue ; - + _imin = std::min( _imin, _iter->node(0)) ; _imin = std::min( @@ -780,20 +780,20 @@ { _jlog.push ( "**input error: GEOM. tria. indexing is incorrect.\n") ; - + _errv = __invalid_argument ; } } - + return ( _errv ) ; } - + /* -------------------------------------------------------- * ECHO-INIT: print summary of INIT data. -------------------------------------------------------- */ - + template < typename jlog_data > @@ -812,7 +812,7 @@ _sstr << " " __tag " = " \ << __var << "\n" ; \ _jlog.push(_sstr.str()); - + /*---------------------------------- push "real" data */ #define __dumpREAL(__tag,__var) \ _sstr.str(""); \ @@ -825,7 +825,7 @@ _jlog.push(_sstr.str()) ; \ iptr_type _errv = __no_error ; - + __unreferenced(_jcfg) ; if (_init._ndim == +2 && @@ -835,15 +835,15 @@ /*--------------------------------- euclidean-mesh-2d */ _jlog.push( " EUCLIDEAN-MESH\n\n") ; - + __dumpINTS("|NDIMS.|", +2) ; - + _jlog.push("\n") ; - + iptr_type _num1 = +0 ; iptr_type _num2 = +0 ; iptr_type _num3 = +0 ; - + for (auto _iter = _init. _euclidean_mesh_2d._mesh._set1.head() ; _iter != _init. @@ -852,9 +852,9 @@ { if (_iter->mark()>=+0) _num1 += +1 ; } - + __dumpINTS("|COORD.|", _num1) - + for (auto _iter = _init. _euclidean_mesh_2d._mesh._set2.head() ; _iter != _init. @@ -863,9 +863,9 @@ { if (_iter->mark()>=+0) _num2 += +1 ; } - + __dumpINTS("|EDGE-2|", _num2) - + for (auto _iter = _init. _euclidean_mesh_2d._mesh._set3.head() ; _iter != _init. @@ -874,8 +874,8 @@ { if (_iter->mark()>=+0) _num3 += +1 ; } - - __dumpINTS("|TRIA-3|", _num3) + + __dumpINTS("|TRIA-3|", _num3) } else if (_init._ndim == +3 && @@ -885,16 +885,16 @@ /*--------------------------------- euclidean-mesh-3d */ _jlog.push( " EUCLIDEAN-MESH\n\n") ; - + __dumpINTS("|NDIMS.|", +3) ; - + _jlog.push("\n") ; - + iptr_type _num1 = +0 ; iptr_type _num2 = +0 ; iptr_type _num3 = +0 ; iptr_type _num4 = +0 ; - + for (auto _iter = _init. _euclidean_mesh_3d._mesh._set1.head() ; _iter != _init. @@ -903,9 +903,9 @@ { if (_iter->mark()>=+0) _num1 += +1 ; } - + __dumpINTS("|COORD.|", _num1) - + for (auto _iter = _init. _euclidean_mesh_3d._mesh._set2.head() ; _iter != _init. @@ -914,9 +914,9 @@ { if (_iter->mark()>=+0) _num2 += +1 ; } - + __dumpINTS("|EDGE-2|", _num2) - + for (auto _iter = _init. _euclidean_mesh_3d._mesh._set3.head() ; _iter != _init. @@ -925,9 +925,9 @@ { if (_iter->mark()>=+0) _num3 += +1 ; } - - __dumpINTS("|TRIA-3|", _num3) - + + __dumpINTS("|TRIA-3|", _num3) + for (auto _iter = _init. _euclidean_mesh_3d._mesh._set4.head() ; _iter != _init. @@ -936,7 +936,7 @@ { if (_iter->mark()>=+0) _num4 += +1 ; } - + __dumpINTS("|TRIA-4|", _num4) } @@ -947,9 +947,9 @@ return ( _errv) ; } - - + + # endif //__INI_LOAD__ - - - + + + diff --git a/src/jig_load.hpp b/src/jig_load.hpp index 3e8e036..37a31f2 100644 --- a/src/jig_load.hpp +++ b/src/jig_load.hpp @@ -4,34 +4,34 @@ * JIG-LOAD: parse *.JIG file into JCFG data. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 10 April, 2019 + * Last updated: 29 October, 2019 * * Copyright 2013-2019 * Darren Engwirda @@ -53,7 +53,7 @@ * READ-JCFG: read *.JCFG input file. -------------------------------------------------------- */ - + template < typename jlog_data > @@ -62,350 +62,358 @@ jlog_data &_jlog ) { - class jcfg_loader: + class jcfg_loader: public jcfg_reader_base { public : jcfg_data *_jjig; - + public : /*------------------------------------- create loader */ __normal_call jcfg_loader ( jcfg_data *_jsrc = nullptr ) : _jjig( _jsrc ) {} - + /*------------------------------------- MISC keywords */ __normal_call void_type push_verbosity ( std::int32_t _verb - ) + ) { this->_jjig->_verbosity = _verb ; this->_jjig-> - _rdel_opts.verb() = _verb; + _mesh_opts.verb() = _verb; this->_jjig-> - _iter_opts.verb() = _verb; - } - - /*------------------------------------- GEOM keywords */ + _iter_opts.verb() = _verb; + } + + /*------------------------------------- GEOM keywords */ __normal_call void_type push_geom_file ( std::string _file - ) - { + ) + { this-> _jjig->_geom_file = _file; } __normal_call void_type push_geom_seed ( std::int32_t _seed - ) + ) { this->_jjig-> - _rdel_opts.seed() = _seed; + _mesh_opts.seed() = _seed; } __normal_call void_type push_geom_feat ( bool _feat - ) + ) { this->_jjig-> - _rdel_opts.feat() = _feat; + _mesh_opts.feat() = _feat; } __normal_call void_type push_geom_phi1 ( double _phi1 - ) + ) { this->_jjig-> - _rdel_opts.phi1() = _phi1; + _mesh_opts.phi1() = _phi1; } __normal_call void_type push_geom_phi2 ( double _phi2 - ) + ) { this->_jjig-> - _rdel_opts.phi2() = _phi2; + _mesh_opts.phi2() = _phi2; } __normal_call void_type push_geom_eta1 ( double _eta1 - ) + ) { this->_jjig-> - _rdel_opts.eta1() = _eta1; + _mesh_opts.eta1() = _eta1; } __normal_call void_type push_geom_eta2 ( double _eta2 - ) + ) { this->_jjig-> - _rdel_opts.eta2() = _eta2; + _mesh_opts.eta2() = _eta2; } - + /*------------------------------------- INIT keywords */ __normal_call void_type push_init_near ( double _near - ) + ) { this->_jjig-> - _rdel_opts.near() = _near; + _mesh_opts.near() = _near; } - + /*------------------------------------- HFUN keywords */ __normal_call void_type push_hfun_file ( std::string _file - ) - { + ) + { this-> _jjig->_hfun_file = _file; } __normal_call void_type push_hfun_scal ( std::int32_t _scal - ) + ) { - this->_jjig->_hfun_scal = - (jcfg_data::hfun_scal::enum_data)_scal ; + this->_jjig->_hfun_scal = + (jcfg_data::hfun_scal::enum_data)_scal ; } - + __normal_call void_type push_hfun_hmax ( double _hmax - ) + ) { this-> - _jjig->_hfun_hmax = _hmax; + _jjig->_hfun_hmax = _hmax; } __normal_call void_type push_hfun_hmin ( double _hmin - ) + ) { this-> - _jjig->_hfun_hmin = _hmin; + _jjig->_hfun_hmin = _hmin; } - - /*------------------------------------- INIT keywords */ + + /*------------------------------------- INIT keywords */ __normal_call void_type push_init_file ( std::string _file - ) - { + ) + { this-> _jjig->_init_file = _file; } - - /*------------------------------------- KERN keywords */ + + /*------------------------------------- BNDS keywords */ __normal_call void_type push_bnds_kern ( std::int32_t _kern - ) - { - this->_jjig->_bnds_pred = + ) + { + this->_jjig->_bnds_pred = (jcfg_data::bnds_pred::enum_data)_kern ; } - + + /*------------------------------------- MESH keywords */ __normal_call void_type push_mesh_kern ( std::int32_t _kern - ) + ) { - this->_jjig->_mesh_pred = + this->_jjig->_mesh_pred = (jcfg_data::mesh_pred::enum_data)_kern ; } - - /*------------------------------------- MESH keywords */ + __normal_call void_type push_mesh_file ( std::string _file - ) - { + ) + { this-> _jjig->_mesh_file = _file; } __normal_call void_type push_tria_file ( std::string _file - ) - { + ) + { this-> _jjig->_tria_file = _file; } __normal_call void_type push_bnds_file ( std::string _file - ) - { + ) + { this-> _jjig->_bnds_file = _file; } - + __normal_call void_type push_mesh_dims ( std::int32_t _dims - ) - { + ) + { this->_jjig-> - _rdel_opts.dims() = _dims; + _mesh_opts.dims() = _dims; } __normal_call void_type push_mesh_iter ( std::int32_t _iter - ) - { + ) + { this->_jjig-> - _rdel_opts.iter() = _iter; + _mesh_opts.iter() = _iter; } __normal_call void_type push_mesh_rule ( std::int32_t _rule - ) - { + ) + { this->_jjig-> - _rdel_opts.rule() = _rule; + _mesh_opts.rule() = _rule; } __normal_call void_type push_mesh_siz1 ( double _siz1 - ) - { + ) + { this->_jjig-> - _rdel_opts.siz1() = _siz1; + _mesh_opts.siz1() = _siz1; } __normal_call void_type push_mesh_siz2 ( double _siz2 - ) - { + ) + { this->_jjig-> - _rdel_opts.siz2() = _siz2; + _mesh_opts.siz2() = _siz2; } __normal_call void_type push_mesh_siz3 ( double _siz3 - ) + ) { this->_jjig-> - _rdel_opts.siz3() = _siz3; - } + _mesh_opts.siz3() = _siz3; + } __normal_call void_type push_mesh_top1 ( bool _top1 - ) - { + ) + { this->_jjig-> - _rdel_opts.top1() = _top1; + _mesh_opts.top1() = _top1; } __normal_call void_type push_mesh_top2 ( bool _top2 - ) + ) { this->_jjig-> - _rdel_opts.top2() = _top2; + _mesh_opts.top2() = _top2; } __normal_call void_type push_mesh_rad2 ( double _rad2 - ) + ) { this->_jjig-> - _rdel_opts.rad2() = _rad2; + _mesh_opts.rad2() = _rad2; } __normal_call void_type push_mesh_rad3 ( double _rad3 - ) + ) { this->_jjig-> - _rdel_opts.rad3() = _rad3; + _mesh_opts.rad3() = _rad3; } __normal_call void_type push_mesh_off2 ( double _off2 - ) - { + ) + { this->_jjig-> - _rdel_opts.off2() = _off2; + _mesh_opts.off2() = _off2; } __normal_call void_type push_mesh_off3 ( double _off3 - ) + ) { this->_jjig-> - _rdel_opts.off3() = _off3; + _mesh_opts.off3() = _off3; } __normal_call void_type push_mesh_snk2 ( double _snk2 - ) + ) { this->_jjig-> - _rdel_opts.snk2() = _snk2; + _mesh_opts.snk2() = _snk2; } __normal_call void_type push_mesh_snk3 ( double _snk3 - ) + ) { this->_jjig-> - _rdel_opts.snk3() = _snk3; + _mesh_opts.snk3() = _snk3; } __normal_call void_type push_mesh_eps1 ( double _eps1 - ) + ) { this->_jjig-> - _rdel_opts.eps1() = _eps1; + _mesh_opts.eps1() = _eps1; } __normal_call void_type push_mesh_eps2 ( double _eps2 - ) + ) { this->_jjig-> - _rdel_opts.eps2() = _eps2; + _mesh_opts.eps2() = _eps2; } __normal_call void_type push_mesh_vol3 ( double _vol3 - ) + ) { this->_jjig-> - _rdel_opts.vol3() = _vol3; + _mesh_opts.vol3() = _vol3; } - + /*------------------------------------- OPTM keywords */ + __normal_call void_type push_optm_kern ( + std::int32_t _kern + ) + { + this->_jjig->_iter_pred = + (jcfg_data::iter_pred::enum_data)_kern ; + } + __normal_call void_type push_optm_iter ( std::int32_t _iter - ) + ) { this->_jjig-> - _iter_opts.iter() = _iter; + _iter_opts.iter() = _iter; } __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_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; } - + } ; - - /*---------------------------------- parse JCFG. file */ + + /*---------------------------------- parse JCFG. file */ iptr_type _errv = __no_error ; - + try { jcfg_reader _read; - std::ifstream _file; + std::ifstream _file; _file. open( _jcfg._jcfg_file, std::ifstream::in) ; @@ -415,23 +423,23 @@ _file, jcfg_loader(&_jcfg)); } else - { + { _jlog.push( "**parse error: file not found!\n" ) ; - + _errv = __file_not_located ; } _file.close (); - for (auto _iter = + for (auto _iter = _read._errs.head(); - _iter != - _read._errs.tend(); + _iter != + _read._errs.tend(); ++_iter ) { _jlog.push( "**parse error: " + * _iter + "\n" ) ; - } + } } catch (...) { @@ -440,13 +448,13 @@ return ( _errv ) ; } - + /* -------------------------------------------------------- * COPY-JCFG: read *.JCFG input data. -------------------------------------------------------- */ - + template < typename jlog_data > @@ -463,105 +471,120 @@ __unreferenced(_jlog) ; /*------------------------------------- MISC keywords */ - _jcfg._verbosity = + _jcfg._verbosity = _jjig._verbosity ; - _jcfg._rdel_opts. + _jcfg._mesh_opts. verb() = _jjig._verbosity ; _jcfg._iter_opts. verb() = _jjig._verbosity ; - + /*------------------------------------- BNDS keywords */ - if (_jjig._bnds_kern == + if (_jjig._bnds_kern == JIGSAW_BNDS_TRIACELL) - _jcfg._bnds_pred = + _jcfg._bnds_pred = jcfg_data::bnds_pred::bnd_tria ; else if (_jjig._bnds_kern == JIGSAW_BNDS_DUALCELL) - _jcfg._bnds_pred = + _jcfg._bnds_pred = jcfg_data::bnds_pred::bnd_dual ; - + /*------------------------------------- GEOM keywords */ - _jcfg._rdel_opts. + _jcfg._mesh_opts. seed() = _jjig._geom_seed ; - _jcfg._rdel_opts. + _jcfg._mesh_opts. feat() = _jjig._geom_feat ; - _jcfg._rdel_opts. + _jcfg._mesh_opts. eta1() = _jjig._geom_eta1 ; - _jcfg._rdel_opts. + _jcfg._mesh_opts. eta2() = _jjig._geom_eta2 ; /*------------------------------------- INIT keywords */ - _jcfg._rdel_opts. + _jcfg._mesh_opts. near() = _jjig._init_near ; - + /*------------------------------------- HFUN keywords */ - if (_jjig._hfun_scal == + if (_jjig._hfun_scal == JIGSAW_HFUN_RELATIVE) - _jcfg._hfun_scal = + _jcfg._hfun_scal = jcfg_data::hfun_scal::relative ; else if (_jjig._hfun_scal == JIGSAW_HFUN_ABSOLUTE) - _jcfg._hfun_scal = + _jcfg._hfun_scal = jcfg_data::hfun_scal::absolute ; - + _jcfg. _hfun_hmax = _jjig._hfun_hmax ; _jcfg. _hfun_hmin = _jjig._hfun_hmin ; - + /*------------------------------------- RDEL keywords */ - if (_jjig._mesh_kern == + if (_jjig._mesh_kern == JIGSAW_KERN_DELFRONT) - _jcfg._mesh_pred = + _jcfg._mesh_pred = jcfg_data::mesh_pred::delfront ; else if (_jjig._mesh_kern == JIGSAW_KERN_DELAUNAY) - _jcfg._mesh_pred = + _jcfg._mesh_pred = jcfg_data::mesh_pred::delaunay ; - - _jcfg._rdel_opts. + else + if (_jjig._mesh_kern == + JIGSAW_KERN_BISECTOR) + _jcfg._mesh_pred = + jcfg_data::mesh_pred::bisector ; + + _jcfg._mesh_opts. dims() = _jjig._mesh_dims ; - _jcfg._rdel_opts. + _jcfg._mesh_opts. iter() = _jjig._mesh_iter ; - - _jcfg._rdel_opts. + + _jcfg._mesh_opts. top1() = _jjig._mesh_top1 ; - _jcfg._rdel_opts. + _jcfg._mesh_opts. top2() = _jjig._mesh_top2 ; - - _jcfg._rdel_opts. + + _jcfg._mesh_opts. rad2() = _jjig._mesh_rad2 ; - _jcfg._rdel_opts. + _jcfg._mesh_opts. rad3() = _jjig._mesh_rad3 ; - _jcfg._rdel_opts. + _jcfg._mesh_opts. off2() = _jjig._mesh_off2 ; - _jcfg._rdel_opts. + _jcfg._mesh_opts. off3() = _jjig._mesh_off3 ; - _jcfg._rdel_opts. + _jcfg._mesh_opts. snk2() = _jjig._mesh_snk2 ; - _jcfg._rdel_opts. + _jcfg._mesh_opts. snk3() = _jjig._mesh_snk3 ; - - _jcfg._rdel_opts. + + _jcfg._mesh_opts. eps1() = _jjig._mesh_eps1 ; - _jcfg._rdel_opts. + _jcfg._mesh_opts. eps2() = _jjig._mesh_eps2 ; - - _jcfg._rdel_opts. + + _jcfg._mesh_opts. vol3() = _jjig._mesh_vol3 ; - + /*------------------------------------- ITER keywords */ + if (_jjig._optm_kern == + JIGSAW_KERN_ODT_DQDX) + _jcfg._iter_pred = + jcfg_data::iter_pred::odt_dqdx ; + else + if (_jjig._optm_kern == + JIGSAW_KERN_CVT_DQDX) + _jcfg._iter_pred = + jcfg_data::iter_pred::cvt_dqdx ; + _jcfg._iter_opts. iter() = _jjig._optm_iter ; - + _jcfg._iter_opts. qtol() = _jjig._optm_qtol ; _jcfg._iter_opts. qlim() = _jjig._optm_qlim ; - + _jcfg._iter_opts. tria() = _jjig._optm_tria ; _jcfg._iter_opts. @@ -570,7 +593,7 @@ div_() = _jjig._optm_div_ ; _jcfg._iter_opts. zip_() = _jjig._optm_zip_ ; - + } catch (...) { @@ -585,7 +608,7 @@ * TEST-JCFG: test the JCFG data for validity. -------------------------------------------------------- */ - + template < typename jlog_data > @@ -611,7 +634,7 @@ << __var << "\n"; \ _jlog.push(_sstr.str()) ; \ } \ - + /*---------------------------------- test "real" data */ #define __testREAL(__tag, __var, __vlo, __vhi) \ if ( (__var < __vlo) || \ @@ -627,7 +650,7 @@ << __var << "\n"; \ _jlog.push(_sstr.str()) ; \ } \ - + /*---------------------------------- warn "real" data */ #define __warnREAL(__tag, __var, __vlo, __vhi) \ if ( (__var < __vlo) || \ @@ -647,144 +670,144 @@ iptr_type _errv = __no_error ; /*---------------------------- test GEOM keywords */ - __testINTS("GEOM-SEED", - _jcfg._rdel_opts.seed(), - (iptr_type) + 0, + __testINTS("GEOM-SEED", + _jcfg._mesh_opts.seed(), + (iptr_type) + 0, std::numeric_limits:: max()) - __testREAL("GEOM-PHI1", - _jcfg._rdel_opts.phi1(), - (real_type) 0., + __testREAL("GEOM-PHI1", + _jcfg._mesh_opts.phi1(), + (real_type) 0., (real_type)180.) - __testREAL("GEOM-PHI2", - _jcfg._rdel_opts.phi2(), - (real_type) 0., + __testREAL("GEOM-PHI2", + _jcfg._mesh_opts.phi2(), + (real_type) 0., (real_type)180.) - - __testREAL("GEOM-ETA1", - _jcfg._rdel_opts.eta1(), - (real_type) 0., + + __testREAL("GEOM-ETA1", + _jcfg._mesh_opts.eta1(), + (real_type) 0., (real_type)180.) - __testREAL("GEOM-ETA2", - _jcfg._rdel_opts.eta2(), - (real_type) 0., + __testREAL("GEOM-ETA2", + _jcfg._mesh_opts.eta2(), + (real_type) 0., (real_type)180.) /*---------------------------- test INIT keywords */ - __testREAL("INIT-NEAR", - _jcfg._rdel_opts.near(), - (real_type) 0., + __testREAL("INIT-NEAR", + _jcfg._mesh_opts.near(), + (real_type) 0., (real_type) 1.) /*---------------------------- test HFUN keywords */ - __testREAL("HFUN-HMAX", - _jcfg ._hfun_hmax , - (real_type) 0., + __testREAL("HFUN-HMAX", + _jcfg ._hfun_hmax , + (real_type) 0., std::numeric_limits::infinity()) - __testREAL("HFUN-HMIN", - _jcfg ._hfun_hmin , - (real_type) 0., + __testREAL("HFUN-HMIN", + _jcfg ._hfun_hmin , + (real_type) 0., std::numeric_limits::infinity()) - + /*---------------------------- test MESH keywords */ - __testINTS("MESH-ITER", - _jcfg._rdel_opts.iter(), + __testINTS("MESH-ITER", + _jcfg._mesh_opts.iter(), (iptr_type) + 0, std::numeric_limits:: max()) - __testINTS("MESH-DIMS", - _jcfg._rdel_opts.dims(), + __testINTS("MESH-DIMS", + _jcfg._mesh_opts.dims(), (iptr_type) + 1, (iptr_type) + 3) - __testREAL("MESH-SIZ1", - _jcfg._rdel_opts.siz1(), - (real_type) 0., + __testREAL("MESH-SIZ1", + _jcfg._mesh_opts.siz1(), + (real_type) 0., std::numeric_limits::infinity()) - __testREAL("MESH-SIZ2", - _jcfg._rdel_opts.siz2(), - (real_type) 0., + __testREAL("MESH-SIZ2", + _jcfg._mesh_opts.siz2(), + (real_type) 0., std::numeric_limits::infinity()) - __testREAL("MESH-SIZ3", - _jcfg._rdel_opts.siz3(), - (real_type) 0., + __testREAL("MESH-SIZ3", + _jcfg._mesh_opts.siz3(), + (real_type) 0., std::numeric_limits::infinity()) - __testREAL("MESH-EPS1", - _jcfg._rdel_opts.eps1(), - (real_type) 0., + __testREAL("MESH-EPS1", + _jcfg._mesh_opts.eps1(), + (real_type) 0., std::numeric_limits::infinity()) - __testREAL("MESH-EPS2", - _jcfg._rdel_opts.eps2(), - (real_type) 0., + __testREAL("MESH-EPS2", + _jcfg._mesh_opts.eps2(), + (real_type) 0., std::numeric_limits::infinity()) - __testREAL("MESH-RAD2", - _jcfg._rdel_opts.rad2(), - (real_type) 0., + __testREAL("MESH-RAD2", + _jcfg._mesh_opts.rad2(), + (real_type) 0., std::numeric_limits::infinity()) - __testREAL("MESH-RAD3", - _jcfg._rdel_opts.rad3(), - (real_type) 0., + __testREAL("MESH-RAD3", + _jcfg._mesh_opts.rad3(), + (real_type) 0., std::numeric_limits::infinity()) - - __warnREAL("MESH-RAD2", - _jcfg._rdel_opts.rad2(), - (real_type) 1., + + __warnREAL("MESH-RAD2", + _jcfg._mesh_opts.rad2(), + (real_type) 1., std::numeric_limits::infinity()) - __warnREAL("MESH-RAD3", - _jcfg._rdel_opts.rad3(), - (real_type) 2., + __warnREAL("MESH-RAD3", + _jcfg._mesh_opts.rad3(), + (real_type) 2., std::numeric_limits::infinity()) - __testREAL("MESH-OFF2", - _jcfg._rdel_opts.off2(), - (real_type) 0., + __testREAL("MESH-OFF2", + _jcfg._mesh_opts.off2(), + (real_type) 0., std::numeric_limits::infinity()) - __testREAL("MESH-OFF3", - _jcfg._rdel_opts.off3(), - (real_type) 0., + __testREAL("MESH-OFF3", + _jcfg._mesh_opts.off3(), + (real_type) 0., std::numeric_limits::infinity()) - __testREAL("MESH-SNK2", - _jcfg._rdel_opts.snk2(), - (real_type) 0., + __testREAL("MESH-SNK2", + _jcfg._mesh_opts.snk2(), + (real_type) 0., (real_type) 1.) - __testREAL("MESH-SNK3", - _jcfg._rdel_opts.snk3(), - (real_type) 0., + __testREAL("MESH-SNK3", + _jcfg._mesh_opts.snk3(), + (real_type) 0., (real_type) 1.) - __testREAL("MESH-VOL3", - _jcfg._rdel_opts.vol3(), - (real_type) 0., - (real_type) 1.) - __warnREAL("MESH-VOL3", - _jcfg._rdel_opts.vol3(), - (real_type) 0., + __testREAL("MESH-VOL3", + _jcfg._mesh_opts.vol3(), + (real_type) 0., + (real_type) 1.) + __warnREAL("MESH-VOL3", + _jcfg._mesh_opts.vol3(), + (real_type) 0., (real_type) .3) /*---------------------------- test OPTM keywords */ - __testINTS("OPTM-ITER", - _jcfg._iter_opts.iter(), + __testINTS("OPTM-ITER", + _jcfg._iter_opts.iter(), (iptr_type) + 0, std::numeric_limits:: max()) - - __testREAL("OPTM-QTOL", + + __testREAL("OPTM-QTOL", _jcfg._iter_opts.qtol(), - (real_type) 0., + (real_type) 0., (real_type) 1.) - - __testREAL("OPTM-QLIM", + + __testREAL("OPTM-QLIM", _jcfg._iter_opts.qlim(), - (real_type) 0., + (real_type) 0., (real_type) 1.) - + #undef __testINTS #undef __testREAL #undef __warnREAL - + return ( _errv ) ; } @@ -793,7 +816,7 @@ * ECHO-JCFG: print a summary of the JCFG data. -------------------------------------------------------- */ - + template < typename jlog_data > @@ -814,7 +837,7 @@ (__var != \ std::numeric_limits::max() ? \ std::to_string(__var) : "MAXINT") - + #define __dumpINTS(__tag,__var) \ _sstr.str(""); \ _sstr.clear(); \ @@ -826,7 +849,7 @@ /*---------------------------------- push "bool" data */ #define __pushBVAL(__var) \ ( __var ? "TRUE" : "FALSE" ) - + #define __dumpBOOL(__tag,__var) \ _sstr.str(""); \ _sstr.clear(); \ @@ -834,7 +857,7 @@ << __pushBVAL(__var) \ << " \n" ; \ _jlog.push(_sstr.str()) ; \ - + /*---------------------------------- push "real" data */ #define __dumpREAL(__tag,__var) \ _sstr.str(""); \ @@ -845,10 +868,10 @@ << __var \ << " \n" ; \ _jlog.push(_sstr.str()) ; \ - - + + iptr_type _errv = __no_error; - + __dumpFILE( "GEOM-FILE", _geom_file) __dumpFILE( @@ -867,27 +890,27 @@ if (_jcfg._verbosity > +0) { /*---------------------------- push GEOM keywords */ - __dumpINTS("GEOM-SEED", - _jcfg._rdel_opts.seed()) - - __dumpREAL("GEOM-PHI1", - _jcfg._rdel_opts.phi1()) - __dumpREAL("GEOM-PHI2", - _jcfg._rdel_opts.phi2()) - - __dumpREAL("GEOM-ETA1", - _jcfg._rdel_opts.eta1()) - __dumpREAL("GEOM-ETA2", - _jcfg._rdel_opts.eta2()) - - __dumpBOOL("GEOM-FEAT", - _jcfg._rdel_opts.feat()) + __dumpINTS("GEOM-SEED", + _jcfg._mesh_opts.seed()) + + __dumpREAL("GEOM-PHI1", + _jcfg._mesh_opts.phi1()) + __dumpREAL("GEOM-PHI2", + _jcfg._mesh_opts.phi2()) + + __dumpREAL("GEOM-ETA1", + _jcfg._mesh_opts.eta1()) + __dumpREAL("GEOM-ETA2", + _jcfg._mesh_opts.eta2()) + + __dumpBOOL("GEOM-FEAT", + _jcfg._mesh_opts.feat()) _jlog.push("\n") ; /*---------------------------- push INIT keywords */ - __dumpREAL("INIT-NEAR", - _jcfg._rdel_opts.near()) + __dumpREAL("INIT-NEAR", + _jcfg._mesh_opts.near()) _jlog.push("\n") ; @@ -908,7 +931,18 @@ "HFUN-HMIN", _jcfg._hfun_hmin) _jlog.push("\n") ; - + + /*---------------------------- push BNDS keywords */ + if(_jcfg._bnds_pred == + jcfg_data::bnds_pred::bnd_tria) + _jlog.push ( + " BNDS-KERN = BND-TRIA \n") ; + else + if(_jcfg._bnds_pred == + jcfg_data::bnds_pred::bnd_dual) + _jlog.push ( + " BNDS-KERN = BND-DUAL \n") ; + /*---------------------------- push MESH keywords */ if(_jcfg._mesh_pred == jcfg_data::mesh_pred::delaunay) @@ -919,80 +953,85 @@ jcfg_data::mesh_pred::delfront) _jlog.push ( " MESH-KERN = DELFRONT \n") ; - - if(_jcfg._bnds_pred == - jcfg_data::bnds_pred::bnd_tria) - _jlog.push ( - " BNDS-KERN = BND-TRIA \n") ; else - if(_jcfg._bnds_pred == - jcfg_data::bnds_pred::bnd_dual) + if(_jcfg._mesh_pred == + jcfg_data::mesh_pred::bisector) _jlog.push ( - " BNDS-KERN = BND-DUAL \n") ; + " MESH-KERN = BISECTOR \n") ; - __dumpBOOL("MESH-TOP1", - _jcfg._rdel_opts.top1()) - __dumpBOOL("MESH-TOP2", - _jcfg._rdel_opts.top2()) + __dumpBOOL("MESH-TOP1", + _jcfg._mesh_opts.top1()) + __dumpBOOL("MESH-TOP2", + _jcfg._mesh_opts.top2()) - __dumpINTS("MESH-ITER", - _jcfg._rdel_opts.iter()) + __dumpINTS("MESH-ITER", + _jcfg._mesh_opts.iter()) - __dumpINTS("MESH-DIMS", - _jcfg._rdel_opts.dims()) + __dumpINTS("MESH-DIMS", + _jcfg._mesh_opts.dims()) - __dumpREAL("MESH-SIZ1", - _jcfg._rdel_opts.siz1()) - __dumpREAL("MESH-SIZ2", - _jcfg._rdel_opts.siz2()) - __dumpREAL("MESH-SIZ3", - _jcfg._rdel_opts.siz3()) + __dumpREAL("MESH-SIZ1", + _jcfg._mesh_opts.siz1()) + __dumpREAL("MESH-SIZ2", + _jcfg._mesh_opts.siz2()) + __dumpREAL("MESH-SIZ3", + _jcfg._mesh_opts.siz3()) - __dumpREAL("MESH-EPS1", - _jcfg._rdel_opts.eps1()) - __dumpREAL("MESH-EPS2", - _jcfg._rdel_opts.eps2()) + __dumpREAL("MESH-EPS1", + _jcfg._mesh_opts.eps1()) + __dumpREAL("MESH-EPS2", + _jcfg._mesh_opts.eps2()) - __dumpREAL("MESH-RAD2", - _jcfg._rdel_opts.rad2()) - __dumpREAL("MESH-RAD3", - _jcfg._rdel_opts.rad3()) + __dumpREAL("MESH-RAD2", + _jcfg._mesh_opts.rad2()) + __dumpREAL("MESH-RAD3", + _jcfg._mesh_opts.rad3()) - __dumpREAL("MESH-OFF2", - _jcfg._rdel_opts.off2()) - __dumpREAL("MESH-OFF3", - _jcfg._rdel_opts.off3()) + __dumpREAL("MESH-OFF2", + _jcfg._mesh_opts.off2()) + __dumpREAL("MESH-OFF3", + _jcfg._mesh_opts.off3()) - __dumpREAL("MESH-SNK2", - _jcfg._rdel_opts.snk2()) - __dumpREAL("MESH-SNK3", - _jcfg._rdel_opts.snk3()) + __dumpREAL("MESH-SNK2", + _jcfg._mesh_opts.snk2()) + __dumpREAL("MESH-SNK3", + _jcfg._mesh_opts.snk3()) - __dumpREAL("MESH-VOL3", - _jcfg._rdel_opts.vol3()) + __dumpREAL("MESH-VOL3", + _jcfg._mesh_opts.vol3()) _jlog.push("\n") ; - + /*---------------------------- push OPTM keywords */ - __dumpINTS("OPTM-ITER", + if(_jcfg._iter_pred == + jcfg_data::iter_pred::odt_dqdx) + _jlog.push ( + " OPTM-KERN = ODT+DQDX \n") ; + else + if(_jcfg._iter_pred == + jcfg_data::iter_pred::cvt_dqdx) + _jlog.push ( + " OPTM-KERN = CVT+DQDX \n") ; + + __dumpINTS("OPTM-ITER", _jcfg._iter_opts.iter()) - __dumpREAL("OPTM-QTOL", + __dumpREAL("OPTM-QTOL", _jcfg._iter_opts.qtol()) - __dumpREAL("OPTM-QLIM", + __dumpREAL("OPTM-QLIM", _jcfg._iter_opts.qlim()) - - __dumpBOOL("OPTM-ZIP_", + + __dumpBOOL("OPTM-ZIP_", _jcfg._iter_opts.zip_()) - __dumpBOOL("OPTM-DIV_", + __dumpBOOL("OPTM-DIV_", _jcfg._iter_opts.div_()) - __dumpBOOL("OPTM-TRIA", + __dumpBOOL("OPTM-TRIA", _jcfg._iter_opts.tria()) - __dumpBOOL("OPTM-DUAL", + __dumpBOOL("OPTM-DUAL", _jcfg._iter_opts.dual()) _jlog.push("\n") ; - + } #undef __dumpFILE @@ -1004,8 +1043,8 @@ return ( _errv) ; } - - + + # endif //__JIG_LOAD__ diff --git a/src/jig_read.hpp b/src/jig_read.hpp index 445eb91..5956cf9 100644 --- a/src/jig_read.hpp +++ b/src/jig_read.hpp @@ -4,34 +4,34 @@ * JIG-READ: parse *.JIG file into config. data. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 19 June, 2019 + * Last updated: 29 October, 2019 * * Copyright 2013-2019 * Darren Engwirda @@ -53,7 +53,7 @@ __normal_call void_type push_verbosity ( std::int32_t /*_verb*/ ) { } - + __normal_call void_type push_geom_file ( std::string /*_file*/ ) { } @@ -72,7 +72,7 @@ __normal_call void_type push_bnds_file ( std::string /*_file*/ ) { } - + __normal_call void_type push_geom_seed ( std::int32_t /*_seed*/ ) { } @@ -95,7 +95,7 @@ __normal_call void_type push_init_near ( double /*_near*/ ) { } - + __normal_call void_type push_hfun_scal ( std::int32_t /*_scal*/ ) { } @@ -105,7 +105,7 @@ __normal_call void_type push_hfun_hmin ( double /*_hmin*/ ) { } - + __normal_call void_type push_mesh_kern ( std::int32_t /*_kern*/ ) { } @@ -129,7 +129,7 @@ ) { } __normal_call void_type push_mesh_siz3 ( double /*_siz3*/ - ) { } + ) { } __normal_call void_type push_mesh_top1 ( bool /*_top1*/ ) { } @@ -163,7 +163,10 @@ __normal_call void_type push_mesh_vol3 ( double /*_vol3*/ ) { } - + + __normal_call void_type push_optm_kern ( + std::int32_t /*_kern*/ + ) { } __normal_call void_type push_optm_iter ( std::int32_t /*_iter*/ ) { } @@ -185,9 +188,9 @@ __normal_call void_type push_optm_zip_ ( bool /*_flag*/ ) { } - + } ; - + /* -------------------------------------------------------- * JCFG-READER: read *.JIG mesh files @@ -197,14 +200,14 @@ class jcfg_reader { public : - + typedef containers::array < std::string > string_tokens; - + string_tokens _errs ; - + public : - + /* -------------------------------------------------------- * READ-FILE: read *.MSH file into MESH @@ -219,7 +222,7 @@ dest_type &&_dest ) { - + /*---------------------------------- flip to up.-case */ #define __toUPPER(__str) \ std::transform(__str.begin(), \ @@ -235,7 +238,7 @@ trim(__tok[ 1])) ; \ else \ _errs.push_tail(_line) ; - + /*---------------------------------- read "MESH" pred */ #define __putMESH(__fun, __str) \ if (__str.count() == 2 ) \ @@ -257,7 +260,29 @@ } \ else \ _errs.push_tail(_line) ; - + + /*---------------------------------- read "OPTM" pred */ + #define __putOPTM(__fun, __str) \ + if (__str.count() == 2 ) \ + { \ + __toUPPER(__str [1]) \ + if (__str[1].find("ODT+DQDX")!= \ + std::string::npos ) \ + _dest.__fun ( \ + jcfg_data \ + ::iter_pred::odt_dqdx) ; \ + else \ + if (__str[1].find("CVT+DQDX")!= \ + std::string::npos ) \ + _dest.__fun ( \ + jcfg_data \ + ::iter_pred::cvt_dqdx) ; \ + else \ + _errs.push_tail(_line) ; \ + } \ + else \ + _errs.push_tail(_line) ; + /*---------------------------------- read "BNDS" pred */ #define __putBNDS(__fun, __str) \ if (__str.count() == 2 ) \ @@ -279,7 +304,7 @@ } \ else \ _errs.push_tail(_line) ; - + /*---------------------------------- read "SCAL" data */ #define __putSCAL(__fun, __str) \ if (__str.count() == 2 ) \ @@ -301,7 +326,7 @@ } \ else \ _errs.push_tail(_line) ; - + /*---------------------------------- read "real" data */ #define __putREAL(__fun, __tok) \ if (__tok.count() == +2) \ @@ -311,7 +336,7 @@ } \ else \ _errs.push_tail(_line) ; - + /*---------------------------------- read "ints" data */ #define __putINTS(__fun, __tok) \ if (__tok.count() == +2) \ @@ -321,7 +346,7 @@ } \ else \ _errs.push_tail(_line) ; - + /*---------------------------------- read "bool" data */ #define __putBOOL(__fun, __str) \ if (__str.count() == 2 ) \ @@ -339,36 +364,36 @@ } \ else \ _errs.push_tail(_line) ; - - + + std::string _line; while (std::getline(_ffid, _line)) { _line = trim(_line) ; - + if (_line.size() <= 0) continue ; if (_line[ +0] == '#') continue ; - + try { containers:: array _stok ; - + find_toks(_line, "=;", _stok); - + for (auto _iter = _stok.head() ; _iter != _stok.tend() ; ++_iter ) /*---------------------------- trim on each token */ *_iter = trim( *_iter ) ; - - std::transform(_stok[0].begin() , - _stok[0]. end() , - _stok[0].begin() , - [](unsigned char c){ return + + std::transform(_stok[0].begin() , + _stok[0]. end() , + _stok[0].begin() , + [](unsigned char c){ return (unsigned char)::toupper(c); } ) ; - - /*---------------------------- read MISC keywords */ + + /*---------------------------- read MISC keywords */ if (_stok[0] == "VERBOSITY") { __putINTS(push_verbosity, _stok) ; @@ -440,7 +465,7 @@ if (_stok[0] == "HFUN_HMIN") { __putREAL(push_hfun_hmin, _stok) ; - } + } else /*---------------------------- read MESH keywords */ if (_stok[0] == "TRIA_FILE") @@ -512,7 +537,7 @@ if (_stok[0] == "MESH_OFF2") { __putREAL(push_mesh_off2, _stok) ; - } + } else if (_stok[0] == "MESH_OFF3") { @@ -555,6 +580,11 @@ } else /*---------------------------- read OPTM keywords */ + if (_stok[0] == "OPTM_KERN") + { + __putOPTM(push_optm_kern, _stok) ; + } + else if (_stok[0] == "OPTM_ITER") { __putINTS(push_optm_iter, _stok) ; @@ -588,31 +618,32 @@ { __putBOOL(push_optm_dual, _stok) ; } - + } catch (...) { this-> _errs.push_tail (_line) ; - } + } } - + #undef __toUPPER - + #undef __putFILE #undef __putSCAL #undef __putMESH + #undef __putOPTM #undef __putBNDS #undef __putREAL - #undef __putINTS + #undef __putINTS #undef __putBOOL - - } - + + } + } ; - + # endif //__JIG_READ__ - - - + + + diff --git a/src/jigsaw.cpp b/src/jigsaw.cpp index 337e917..46eae57 100644 --- a/src/jigsaw.cpp +++ b/src/jigsaw.cpp @@ -1,770 +1,823 @@ - - // - // for cmd-jigsaw: - // - // g++ -std=c++11 -pedantic -Wall -Wextra -O3 -flto - // -D NDEBUG -D __cmd_jigsaw jigsaw.cpp -o ../bin/jigsaw - // - // g++ -std=c++11 -pedantic -Wall -Wextra -O3 -flto - // -D NDEBUG -D __cmd_tripod jigsaw.cpp -o ../bin/tripod - // - // - // for lib-jigsaw: - // - // g++ -std=c++11 -pedantic -Wall -Wextra -O3 -flto - // -fPIC -D NDEBUG -D __lib_jigsaw jigsaw.cpp -shared - // -o ../lib/libjigsaw.so - // - - /* - -------------------------------------------------------- - * - * ,o, ,o, / - * ` ` e88~88e d88~\ /~~~8e Y88b e / - * 888 888 88 88 C888 88b Y88b d8b / - * 888 888 "8b_d8" Y88b e88~-888 Y888/Y88b/ - * 888 888 / 888D C88 888 Y8/ Y8/ - * 88P 888 Cb \_88P "8b_-888 Y Y - * \_8" Y8""8D - * - -------------------------------------------------------- - * JIGSAW: an unstructured mesh generation library. - -------------------------------------------------------- - * - * JIGSAW release 0.9.10.x - * Last updated: 18 April, 2019 - * - * Copyright 2013 -- 2019 - * Darren Engwirda - * darren.engwirda@columbia.edu - * https://github.com/dengwirda - * - -------------------------------------------------------- - * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) - * - * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The - * University of Sydney, nor the National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be - * used at your own risk. - * - -------------------------------------------------------- - * - * JIGSAW is a collection of unstructured triangle- and - * tetrahedron-based meshing algorithms, designed to - * produce very high quality Delaunay-based grids for - * computational simulation. JIGSAW includes both - * Delaunay 'refinement' based algorithms for the - * construction of new meshes, as well as optimisation - * driven methods for the 'improvement' of existing - * grids. JIGSAW supports both two- and - * three-dimensional operations, catering to a variety - * of planar, surface and volumetric configurations. - * - * JIGSAW's 'frontal' Delaunay-refinement algorithms - * are described here: - * - * D. Engwirda, D. Ivers, (2016): "Off-centre Steiner - * points for Delaunay-refinement on curved surfaces", - * Computer-Aided Design, 72, pp. 157-171, - * http://dx.doi.org/10.1016/j.cad.2015.10.007 - * - * D. Engwirda, (2016): "Conforming restricted Delaunay - * mesh generation for piecewise smooth complexes", - * Procedia Engineering, 163, pp. 84-96, - * http://dx.doi.org/10.1016/j.proeng.2016.11.024 - * - * D. Engwirda, (2015): "Voronoi-based point-placement - * for three-dimensional Delaunay-refinement", - * Procedia Engineering, 124, pp. 330-342, - * http://dx.doi.org/10.1016/j.proeng.2015.10.143 - * - * JIGSAW's hybrid, optimisation-based mesh improvement - * schemes are discussed here: - * - * D. Engwirda, (2018): "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 - * - * JIGSAW originally grew out of my Ph.D. research, in - * which I explored initial versions of the refinement - * and optimisation-based algorithms: - * - * D. Engwirda, (2014): "Locally-optimal Delaunay- - * refinement and optimisation-based mesh generation", - * Ph.D. Thesis, School of Mathematics and Statistics, - * Univ. of Sydney. - * http://hdl.handle.net/2123/13148 - * - -------------------------------------------------------- - * - * JIGSAW's "restricted" Delaunay refinement strategies - * are generalisations of the methods developed in: - * - * J.D. Boissonnat, S. Oudot, (2005): "Provably Good - * Sampling and Meshing of Surfaces", Graphical Models, - * 67, pp. 405-451, - * https://doi.org/10.1016/j.gmod.2005.01.004 - * - * L. Rineau, M. Yvinec, (2008): "Meshing 3D Domains - * Bounded by Piecewise Smooth Surfaces", Proc. of the - * 16th International Meshing Roundtable, pp. 443-460, - * https://doi.org/10.1007/978-3-540-75103-8_25 - * - * C. Jamin, P. Alliez, M. Yvinec, and J.D. Boissonnat, - * (2015): "CGALmesh: a generic framework for Delaunay - * mesh generation", ACM Transactions on Mathematical - * Software (TOMS), 41, pp. 23 - * https://doi.org/10.1145/2699463 - * - * S.W. Cheng, T.K. Dey, E.A. Ramos, (2010): "Delaunay - * Refinement for Piecewise Smooth Complexes", - * Discrete & Computational Geometry, 43, pp. 121-166, - * https://doi.org/10.1007/s00454-008-9109-3 - * - * JIGSAW employs a "hybrid" mesh-optimisation approach - * based on a combination of ODT techniques and direct - * gradient-based optimisation: - * - * L. Chen, J.C. Xu, (2004): "Optimal Delaunay - * triangulations, J. Comp. Math., 22, pp. 299-308, - * https://www.jstor.org/stable/43693155 - * - * L.A. Freitag, C. Ollivier-Gooch, (1997): "Tetrahedral - * mesh improvement using swapping and smoothing", - * International Journal for Numerical Methods in - * Engineering 40 (21), pp. 3979-4002, - * https://doi.org/10.1002/(SICI)1097-0207 - * (19971115)40:21<3979::AID-NME251>3.0.CO;2-9 - * - * B.M. Klingner, J.R. Shewchuk, (2008)" "Aggressive - * Tetrahedral Mesh Improvement", Proc. of the 16th - * International Meshing Roundtable, pp. 3-23, - * https://doi.org/10.1007/978-3-540-75103-8_1 - * - * P. Mullen, P. Memari, F. de Goes, M. Desbrun, (2011): - * "HOT: Hodge-optimized triangulations", ACM - * Transactions on Graphics (TOG), 30 (4) pp. 103, - * https://doi.org/10.1145/2010324.1964998 - * - * Core theory and techniques for Delaunay tessellation - * and refinement can be found (for example) here: - * - * S. Cheng, T. Dey and J. Shewchuk, (2012): "Delaunay - * mesh generation", CRC Press. - * - * Additional references are provided inline throughout - * the JIGSAW src. - * - -------------------------------------------------------- - */ - - -# define __jloglndv \ -"#------------------------------------------------------------\n" - -// define __cmd_jigsaw // the cmd-ln exe's -// define __cmd_tripod -// define __cmd_marche - -// define __lib_jigsaw // a shared library - -# if !defined(__cmd_jigsaw) && \ - !defined(__cmd_tripod) && \ - !defined(__cmd_marche) && \ - !defined(__lib_jigsaw) - - /*---------------------------------- build by default */ -# define __cmd_jigsaw - -# endif - -# define __JGSWVSTR "JIGSAW VERSION 0.9.10" - - /*---------------------------------- for i/o on files */ - -# include -# include -# include -# include - - /*---------------------------------- for ascii string */ - -# include - - /*---------------------------------- for many things! */ - -# include - - /*---------------------------------- to do cpu timing */ - -# define __use_timers - -# ifdef __use_timers -# include -# endif//__use_timers - - /*---------------------------------- JIGSAW's backend */ - -# include "libcpp/libbasic.hpp" -# include "libcpp/libparse.hpp" - -# include "libcpp/rdelmesh.hpp" -# include "libcpp/itermesh.hpp" - - extern "C" - { -# include "../inc/lib_jigsaw.h" - } - - typedef real_t real_type ; // double-precision - typedef indx_t iptr_type ; // 32bit signed int - - /*---------------------------------- JIGSAW mesh kind */ - - struct jmsh_kind { - enum enum_data { - null_mesh_kind = +0 , - euclidean_mesh , - euclidean_grid , - euclidean_dual , - ellipsoid_mesh , - ellipsoid_grid , - ellipsoid_dual - } ; - } ; - - /*---------------------------------- run-time errors! */ - - iptr_type static constexpr - __unknown_error = -1 ; - - iptr_type static constexpr - __no_error = +0 ; - - iptr_type static constexpr - __file_not_located = +2 ; - iptr_type static constexpr - __file_not_created = +3 ; - - iptr_type static constexpr - __invalid_argument = +4 ; - - - /* - -------------------------------------------------------- - * JCFG-DATA: JIGSAW's config data. - -------------------------------------------------------- - */ - - class jcfg_data - { - public : - /*------------------------------- "top-level" config. */ - std::string _file_path ; - std::string _file_name ; - - std::string _jcfg_file ; - std::string _geom_file ; - std::string _init_file ; - std::string _hfun_file ; - std::string _tria_file ; - std::string _mesh_file ; - std::string _bnds_file ; - - iptr_type _verbosity = 0 ; - - /*--------------------------------- geom-bnd. kernels */ - struct bnds_pred { - enum enum_data { - nullkern , - bnd_tria = JIGSAW_BNDS_TRIACELL, - bnd_dual = JIGSAW_BNDS_DUALCELL - } ; - } ; - - bnds_pred::enum_data - _bnds_pred = bnds_pred::bnd_tria ; - - /*--------------------------------- mesh-gen. kernels */ - struct mesh_pred { - enum enum_data { - nullkern , - delfront = JIGSAW_KERN_DELFRONT, - delaunay = JIGSAW_KERN_DELAUNAY - } ; - } ; - - mesh_pred::enum_data - _mesh_pred = mesh_pred::delfront ; - - /*--------------------------------- H(x) fun. scaling */ - struct hfun_scal { - enum enum_data { - nullscal , - absolute = JIGSAW_HFUN_ABSOLUTE, - relative = JIGSAW_HFUN_RELATIVE - } ; - } ; - - hfun_scal::enum_data - _hfun_scal = hfun_scal::relative ; - - real_type _hfun_hmax = - (real_type) +2.00E-02 ; - real_type _hfun_hmin = - (real_type) +0.00E+00 ; - - /*------------------------------- "low-level" config. */ - typedef mesh::rdel_params < - real_type , - iptr_type > rdel_opts ; - - rdel_opts _rdel_opts ; - - typedef mesh::iter_params < - real_type , - iptr_type > iter_opts ; - - iter_opts _iter_opts ; - - } ; - - /* - -------------------------------------------------------- - * aggregated GEOM data containers. - -------------------------------------------------------- - */ - - class geom_data // holds the GEOM obj. - { - public : - - typedef mesh ::geom_mesh_euclidean_2d < - real_type, - iptr_type> euclidean_mesh_2d ; - - typedef mesh ::geom_mesh_euclidean_3d < - real_type, - iptr_type> euclidean_mesh_3d ; - - typedef mesh ::geom_mesh_ellipsoid_3d < - real_type, - iptr_type> ellipsoid_mesh_3d ; - - std::size_t _ndim = +0; - - jmsh_kind :: - enum_data _kind = - jmsh_kind::null_mesh_kind ; - - euclidean_mesh_2d _euclidean_mesh_2d ; - euclidean_mesh_3d _euclidean_mesh_3d ; - - ellipsoid_mesh_3d _ellipsoid_mesh_3d ; - - public : - - /*------------------------- helper: init. everything! */ - - __normal_call void_type init_geom ( - jcfg_data &_jcfg - ) - { - this->_euclidean_mesh_2d. - _tria.make_ptrs() ; - this->_euclidean_mesh_2d. - init_geom(_jcfg._rdel_opts) ; - - this->_euclidean_mesh_3d. - _tria.make_ptrs() ; - this->_euclidean_mesh_3d. - init_geom(_jcfg._rdel_opts) ; - - this->_ellipsoid_mesh_3d. - init_geom(_jcfg._rdel_opts) ; - } - - } ; - - /* - -------------------------------------------------------- - * aggregated HFUN data containers. - -------------------------------------------------------- - */ - - class hfun_data // holds the HFUN obj. - { - public : - - typedef mesh ::hfun_constant_value_kd < - iptr_type, - real_type> constant_value_kd ; - - typedef mesh ::hfun_mesh_euclidean_2d < - real_type, - iptr_type> euclidean_mesh_2d ; - - typedef mesh ::hfun_mesh_euclidean_3d < - real_type, - iptr_type> euclidean_mesh_3d ; - - typedef mesh ::hfun_mesh_ellipsoid_3d < - real_type, - iptr_type> ellipsoid_mesh_3d ; - - typedef mesh ::hfun_grid_euclidean_2d < - real_type, - iptr_type> euclidean_grid_2d ; - - typedef mesh ::hfun_grid_euclidean_3d < - real_type, - iptr_type> euclidean_grid_3d ; - - typedef mesh ::hfun_grid_ellipsoid_3d < - iptr_type, - real_type> ellipsoid_grid_3d ; - - std::size_t _ndim = +0; - - jmsh_kind :: - enum_data _kind = - jmsh_kind::null_mesh_kind ; - - constant_value_kd _constant_value_kd ; - - euclidean_mesh_2d _euclidean_mesh_2d ; - euclidean_mesh_3d _euclidean_mesh_3d ; - - ellipsoid_mesh_3d _ellipsoid_mesh_3d ; - - euclidean_grid_2d _euclidean_grid_2d ; - euclidean_grid_3d _euclidean_grid_3d ; - - ellipsoid_grid_3d _ellipsoid_grid_3d ; - - public : - - /*------------------------- helper: init. everything! */ - - __normal_call void_type init_hfun ( - jcfg_data &_jcfg - ) - { - __unreferenced(_jcfg) ; - - this-> - _constant_value_kd.init() ; - - this-> - _euclidean_mesh_2d.init() ; - this-> - _euclidean_mesh_3d.init() ; - this-> - _ellipsoid_mesh_3d.init() ; - - this-> - _euclidean_grid_2d.init() ; - this-> - _euclidean_grid_3d.init() ; - this-> - _ellipsoid_grid_3d.init() ; - } - - } ; - - /* - -------------------------------------------------------- - * aggregated RDEL data containers. - -------------------------------------------------------- - */ - - class rdel_data // holds the restrict-del obj. - { - public : - - typedef mesh::rdel_complex_2d < - real_type , - iptr_type > euclidean_rdel_2d ; - - typedef mesh::rdel_complex_3d < - real_type , - iptr_type > euclidean_rdel_3d ; - - std::size_t _ndim = +0; - - jmsh_kind :: - enum_data _kind = - jmsh_kind::null_mesh_kind ; - - euclidean_rdel_2d _euclidean_rdel_2d ; - euclidean_rdel_3d _euclidean_rdel_3d ; - - euclidean_rdel_2d _euclidean_rvor_2d ; - euclidean_rdel_3d _euclidean_rvor_3d ; - - } ; - - /* - -------------------------------------------------------- - * aggregated MESH data containers. - -------------------------------------------------------- - */ - - class mesh_data // holds the tria-complex obj. - { - public : - - typedef mesh::iter_mesh_euclidean_2d < - real_type , - iptr_type > euclidean_mesh_2d ; - - typedef mesh::iter_mesh_euclidean_3d < - real_type , - iptr_type > euclidean_mesh_3d ; - - std::size_t _ndim = +0; - - jmsh_kind :: - enum_data _kind = - jmsh_kind::null_mesh_kind ; - - euclidean_mesh_2d _euclidean_mesh_2d ; - euclidean_mesh_3d _euclidean_mesh_3d ; - - } ; - - /* - -------------------------------------------------------- - * JLOG-DATA: log-file writer for JIGSAW. - -------------------------------------------------------- - */ - - class jlog_text - { - public : - /*-------------------------- a "real" log-file writer */ - std::ofstream _file ; - - public : - - __inline_call jlog_text ( - jcfg_data const& _jcfg - ) - { - if (_jcfg._file_path.length() == +0) - { - this->_file.open ( - _jcfg._file_name + ".log", - std::ofstream::out|std::ofstream::trunc) ; - } - else - { - this->_file.open ( - _jcfg._file_path + "/" + - _jcfg._file_name + ".log", - std::ofstream::out|std::ofstream::trunc) ; - } - } - - __inline_call ~jlog_text ( - ) - { this->_file.close () ; - } - - /*-------------------------- echo onto logfile/stdout */ - - template < - typename data_type - > - __inline_call void_type push ( - data_type const&_data - ) - { - std :: cout << _data ; - this->_file << _data ; - } - - } ; - - class jlog_null - { - public : - /*-------------------------- a "null" log-file writer */ - - iptr_type _verbosity ; - - public : - - __inline_call jlog_null ( - jcfg_data const& _jcfg - ) - { - /*-------------------------- def. no: for lib_jigsaw! */ - this->_verbosity = - _jcfg._verbosity ; - } - - template < - typename data_type - > - __inline_call void_type push ( - data_type const&_data - ) - { - /*-------------------------- def. no: for lib_jigsaw! */ - if (this->_verbosity > +0) - { - std::cout << _data ; - } - } - - } ; - - /* - -------------------------------------------------------- - * READ-JCFG: load JCFG data from file. - -------------------------------------------------------- - */ - - # include "jig_load.hpp" - - - /* - -------------------------------------------------------- - * READ-DATA: load MESH data from file. - -------------------------------------------------------- - */ - - # include "geo_load.hpp" - # include "ini_load.hpp" - # include "hfn_load.hpp" - - - /* - -------------------------------------------------------- - * INIT-DATA: initialise mesh pointers. - -------------------------------------------------------- - */ - - # include "msh_init.hpp" - # include "hfn_init.hpp" - - - /* - -------------------------------------------------------- - * SAVE-MESH: push MESH data into file. - -------------------------------------------------------- - */ - - # include "msh_save.hpp" - - - /* - -------------------------------------------------------- - * COPY-MESH: copy r-DT to tri-complex. - -------------------------------------------------------- - */ - - # include "msh_copy.hpp" - - - /* - -------------------------------------------------------- - * CALC-MESH: call mesh generator. - -------------------------------------------------------- - */ - - # include "run_mesh.hpp" - # include "run_iter.hpp" - # include "run_tria.hpp" - - - /* - -------------------------------------------------------- - * TIME-SPAN: elapsed sec. between markers. - -------------------------------------------------------- - */ - -# ifdef __use_timers - - __inline_call double time_span ( - typename std:: - chrono::high_resolution_clock - ::time_point const& _ttic , - typename std:: - chrono::high_resolution_clock - ::time_point const& _ttoc - ) - { - return (double)( - std::chrono::duration_cast< - std::chrono::microseconds > - (_ttoc-_ttic).count()) / 1.E+06 ; - } - -# endif//__use_timers - - /* - -------------------------------------------------------- - * DUMP-TIME: "dump" time-span to a string. - -------------------------------------------------------- - */ - -# ifdef __use_timers - - __inline_call std::string dump_time ( - typename std:: - chrono::high_resolution_clock - ::time_point const& _ttic , - typename std:: - chrono::high_resolution_clock - ::time_point const& _ttoc - ) - { - std::stringstream _sstr; - _sstr << " Done. (" - << std::scientific - << std::setprecision(2) - << time_span(_ttic, _ttoc ) - << "sec)\n\n" ; - - return _sstr.str () ; - } - -# endif//__use_timers - - /* - -------------------------------------------------------- - * Jumping-off points for CMD + LIB JIGSAW! - -------------------------------------------------------- - */ - - # include "jigsaw.hpp" - # include "tripod.hpp" - - # include "marche.hpp" - -// # include "stitch.hpp" - - - + + // + // for cmd-jigsaw: + // + // g++ -std=c++11 -pedantic -Wall -Wextra -O3 -flto + // -DNDEBUG -D__cmd_jigsaw jigsaw.cpp -o../bin/jigsaw + // + // g++ -std=c++11 -pedantic -Wall -Wextra -O3 -flto + // -DNDEBUG -D__cmd_tripod jigsaw.cpp -o../bin/tripod + // + // g++ -std=c++11 -pedantic -Wall -Wextra -O3 -flto + // -DNDEBUG -D__cmd_marche jigsaw.cpp -o../bin/marche + // + // + // for lib-jigsaw: + // + // g++ -std=c++11 -pedantic -Wall -Wextra -O3 -flto + // -fPIC -DNDEBUG -D__lib_jigsaw jigsaw.cpp -shared + // -o../lib/libjigsaw.so + // + // + // -Wfloat-conversion -Wsign-conversion -Wshadow + // + + /* + -------------------------------------------------------- + * + * ,o, ,o, / + * ` ` e88~88e d88~\ /~~~8e Y88b e / + * 888 888 88 88 C888 88b Y88b d8b / + * 888 888 "8b_d8" Y88b e88~-888 Y888/Y88b/ + * 888 888 / 888D C88 888 Y8/ Y8/ + * 88P 888 Cb \_88P "8b_-888 Y Y + * \_8" Y8""8D + * + -------------------------------------------------------- + * JIGSAW: an unstructured mesh generation library. + -------------------------------------------------------- + * + * JIGSAW release 0.9.12.x + * Last updated: 25 November, 2019 + * + * Copyright 2013 -- 2019 + * Darren Engwirda + * darren.engwirda@columbia.edu + * https://github.com/dengwirda + * + -------------------------------------------------------- + * + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) + * + * Disclaimer: Neither I nor: Columbia University, The + * Massachusetts Institute of Technology, The + * University of Sydney, nor the National Aeronautics + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be + * used at your own risk. + * + -------------------------------------------------------- + * + * JIGSAW is a collection of unstructured triangle- and + * tetrahedron-based meshing algorithms, designed to + * produce very high quality Delaunay-based grids for + * computational simulation. JIGSAW includes both + * Delaunay 'refinement' based algorithms for the + * construction of new meshes, as well as optimisation + * driven methods for the 'improvement' of existing + * grids. JIGSAW supports both two- and + * three-dimensional operations, catering to a variety + * of planar, surface and volumetric configurations. + * + * JIGSAW's 'frontal' Delaunay-refinement algorithms + * are described here: + * + * D. Engwirda, D. Ivers, (2016): "Off-centre Steiner + * points for Delaunay-refinement on curved surfaces", + * Computer-Aided Design, 72, pp. 157-171, + * http://dx.doi.org/10.1016/j.cad.2015.10.007 + * + * D. Engwirda, (2016): "Conforming restricted Delaunay + * mesh generation for piecewise smooth complexes", + * Procedia Engineering, 163, pp. 84-96, + * http://dx.doi.org/10.1016/j.proeng.2016.11.024 + * + * D. Engwirda, (2015): "Voronoi-based point-placement + * for three-dimensional Delaunay-refinement", + * Procedia Engineering, 124, pp. 330-342, + * http://dx.doi.org/10.1016/j.proeng.2015.10.143 + * + * JIGSAW's hybrid, optimisation-based mesh improvement + * schemes are discussed here: + * + * D. Engwirda, (2018): "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 + * + * JIGSAW originally grew out of my Ph.D. research, in + * which I explored initial versions of the refinement + * and optimisation-based algorithms: + * + * D. Engwirda, (2014): "Locally-optimal Delaunay- + * refinement and optimisation-based mesh generation", + * Ph.D. Thesis, School of Mathematics and Statistics, + * Univ. of Sydney. + * http://hdl.handle.net/2123/13148 + * + -------------------------------------------------------- + * + * JIGSAW's "restricted" Delaunay refinement strategies + * are generalisations of the methods developed in: + * + * J.D. Boissonnat, S. Oudot, (2005): "Provably Good + * Sampling and Meshing of Surfaces", Graphical Models, + * 67, pp. 405-451, + * https://doi.org/10.1016/j.gmod.2005.01.004 + * + * L. Rineau, M. Yvinec, (2008): "Meshing 3D Domains + * Bounded by Piecewise Smooth Surfaces", Proc. of the + * 16th International Meshing Roundtable, pp. 443-460, + * https://doi.org/10.1007/978-3-540-75103-8_25 + * + * C. Jamin, P. Alliez, M. Yvinec, and J.D. Boissonnat, + * (2015): "CGALmesh: a generic framework for Delaunay + * mesh generation", ACM Transactions on Mathematical + * Software (TOMS), 41, pp. 23 + * https://doi.org/10.1145/2699463 + * + * S.W. Cheng, T.K. Dey, E.A. Ramos, (2010): "Delaunay + * Refinement for Piecewise Smooth Complexes", + * Discrete & Computational Geometry, 43, pp. 121-166, + * https://doi.org/10.1007/s00454-008-9109-3 + * + * JIGSAW employs a "hybrid" mesh-optimisation approach + * based on a combination of ODT techniques and direct + * gradient-based optimisation: + * + * L. Chen, J.C. Xu, (2004): "Optimal Delaunay + * triangulations, J. Comp. Math., 22, pp. 299-308, + * https://www.jstor.org/stable/43693155 + * + * L.A. Freitag, C. Ollivier-Gooch, (1997): "Tetrahedral + * mesh improvement using swapping and smoothing", + * International Journal for Numerical Methods in + * Engineering 40 (21), pp. 3979-4002, + * https://doi.org/10.1002/(SICI)1097-0207 + * (19971115)40:21<3979::AID-NME251>3.0.CO;2-9 + * + * B.M. Klingner, J.R. Shewchuk, (2008)" "Aggressive + * Tetrahedral Mesh Improvement", Proc. of the 16th + * International Meshing Roundtable, pp. 3-23, + * https://doi.org/10.1007/978-3-540-75103-8_1 + * + * P. Mullen, P. Memari, F. de Goes, M. Desbrun, (2011): + * "HOT: Hodge-optimized triangulations", ACM + * Transactions on Graphics (TOG), 30 (4) pp. 103, + * https://doi.org/10.1145/2010324.1964998 + * + * Core theory and techniques for Delaunay tessellation + * and refinement can be found (for example) here: + * + * S. Cheng, T. Dey and J. Shewchuk, (2012): "Delaunay + * mesh generation", CRC Press. + * + * Additional references are provided inline throughout + * the JIGSAW src. + * + -------------------------------------------------------- + */ + + +# define __jloglndv \ +"#------------------------------------------------------------\n" + +// define __cmd_jigsaw // the cmd-ln exe's +// define __cmd_tripod +// define __cmd_marche + +// define __lib_jigsaw // a shared library + +# if !defined(__cmd_jigsaw) && \ + !defined(__cmd_tripod) && \ + !defined(__cmd_marche) && \ + !defined(__lib_jigsaw) + + /*---------------------------------- build by default */ +# define __cmd_jigsaw + +# endif + +# define __JGSWVSTR "JIGSAW VERSION 0.9.12" + + /*---------------------------------- for i/o on files */ + +# include +# include +# include +# include + + /*---------------------------------- for ascii string */ + +# include + + /*---------------------------------- for many things! */ + +# include + + /*---------------------------------- to do cpu timing */ + +# define __use_timers + +# ifdef __use_timers +# include +# endif//__use_timers + + /*---------------------------------- JIGSAW's backend */ + + +# include "libcpp/libbasic.hpp" +# include "libcpp/libparse.hpp" + +# include "libcpp/useropts.hpp" + +# include "libcpp/rdelmesh.hpp" +# include "libcpp/treemesh.hpp" +# include "libcpp/itermesh.hpp" + + extern "C" + { +# include "../inc/lib_jigsaw.h" + } + + typedef real_t real_type ; // double-precision + typedef indx_t iptr_type ; // 32bit signed int + + /*---------------------------------- JIGSAW mesh kind */ + + struct jmsh_kind { + enum enum_data { + null_mesh_kind = +0 , + euclidean_mesh , + euclidean_grid , + euclidean_dual , + ellipsoid_mesh , + ellipsoid_grid , + ellipsoid_dual + } ; + } ; + + /*---------------------------------- run-time errors! */ + + iptr_type static constexpr + __unknown_error = -1 ; + + iptr_type static constexpr + __no_error = +0 ; + + iptr_type static constexpr + __file_not_located = +2 ; + iptr_type static constexpr + __file_not_created = +3 ; + + iptr_type static constexpr + __invalid_argument = +4 ; + + + /* + -------------------------------------------------------- + * JCFG-DATA: JIGSAW's config data. + -------------------------------------------------------- + */ + + class jcfg_data + { + public : + /*------------------------------- "top-level" config. */ + std::string _file_path ; + std::string _file_name ; + + std::string _jcfg_file ; + std::string _geom_file ; + std::string _init_file ; + std::string _hfun_file ; + std::string _tria_file ; + std::string _mesh_file ; + std::string _bnds_file ; + + iptr_type _verbosity = 0 ; + + /*--------------------------------- geom-bnd. kernels */ + struct bnds_pred { + enum enum_data { + nullkern , + bnd_tria = JIGSAW_BNDS_TRIACELL, + bnd_dual = JIGSAW_BNDS_DUALCELL + } ; + } ; + + bnds_pred::enum_data + _bnds_pred = bnds_pred::bnd_tria ; + + /*--------------------------------- mesh-gen. kernels */ + struct mesh_pred { + enum enum_data { + nullkern , + delfront = JIGSAW_KERN_DELFRONT, + delaunay = JIGSAW_KERN_DELAUNAY, + bisector = JIGSAW_KERN_BISECTOR + } ; + } ; + + mesh_pred::enum_data + _mesh_pred = mesh_pred::delfront ; + + struct iter_pred { + enum enum_data { + nullkern , + odt_dqdx = JIGSAW_KERN_ODT_DQDX, + cvt_dqdx = JIGSAW_KERN_CVT_DQDX + } ; + } ; + + iter_pred::enum_data + _iter_pred = iter_pred::odt_dqdx ; + + /*--------------------------------- H(x) fun. scaling */ + struct hfun_scal { + enum enum_data { + nullscal , + absolute = JIGSAW_HFUN_ABSOLUTE, + relative = JIGSAW_HFUN_RELATIVE + } ; + } ; + + hfun_scal::enum_data + _hfun_scal = hfun_scal::relative ; + + real_type _hfun_hmax = + (real_type) +2.00E-02 ; + real_type _hfun_hmin = + (real_type) +0.00E+00 ; + + /*------------------------------- "low-level" config. */ + typedef mesh::mesh_params < + real_type , + iptr_type > mesh_opts ; + + mesh_opts _mesh_opts ; + + typedef mesh::iter_params < + real_type , + iptr_type > iter_opts ; + + iter_opts _iter_opts ; + + } ; + + /* + -------------------------------------------------------- + * aggregated GEOM data containers. + -------------------------------------------------------- + */ + + class geom_data // holds the GEOM obj. + { + public : + + typedef mesh ::geom_mesh_euclidean_2d < + real_type, + iptr_type> euclidean_mesh_2d ; + + typedef mesh ::geom_mesh_euclidean_3d < + real_type, + iptr_type> euclidean_mesh_3d ; + + typedef mesh ::geom_mesh_ellipsoid_3d < + real_type, + iptr_type> ellipsoid_mesh_3d ; + + std::size_t _ndim = +0; + + jmsh_kind :: + enum_data _kind = + jmsh_kind::null_mesh_kind ; + + euclidean_mesh_2d _euclidean_mesh_2d ; + euclidean_mesh_3d _euclidean_mesh_3d ; + + ellipsoid_mesh_3d _ellipsoid_mesh_3d ; + + public : + + /*------------------------- helper: init. everything! */ + + __normal_call void_type init_geom ( + jcfg_data &_jcfg + ) + { + this->_euclidean_mesh_2d. + _tria.make_link() ; + this->_euclidean_mesh_2d. + init_geom(_jcfg._mesh_opts) ; + + this->_euclidean_mesh_3d. + _tria.make_link() ; + this->_euclidean_mesh_3d. + init_geom(_jcfg._mesh_opts) ; + + this->_ellipsoid_mesh_3d. + _mesh.make_link() ; + this->_ellipsoid_mesh_3d. + init_geom(_jcfg._mesh_opts) ; + } + + } ; + + /* + -------------------------------------------------------- + * aggregated HFUN data containers. + -------------------------------------------------------- + */ + + class hfun_data // holds the HFUN obj. + { + public : + + typedef mesh ::hfun_constant_value_kd < + iptr_type, + real_type> constant_value_kd ; + + typedef mesh ::hfun_mesh_euclidean_2d < + real_type, + iptr_type> euclidean_mesh_2d ; + + typedef mesh ::hfun_mesh_euclidean_3d < + real_type, + iptr_type> euclidean_mesh_3d ; + + typedef mesh ::hfun_mesh_ellipsoid_3d < + real_type, + iptr_type> ellipsoid_mesh_3d ; + + typedef mesh ::hfun_grid_euclidean_2d < + real_type, + iptr_type> euclidean_grid_2d ; + + typedef mesh ::hfun_grid_euclidean_3d < + real_type, + iptr_type> euclidean_grid_3d ; + + typedef mesh ::hfun_grid_ellipsoid_3d < + iptr_type, + real_type> ellipsoid_grid_3d ; + + std::size_t _ndim = +0; + + jmsh_kind :: + enum_data _kind = + jmsh_kind::null_mesh_kind ; + + constant_value_kd _constant_value_kd ; + + euclidean_mesh_2d _euclidean_mesh_2d ; + euclidean_mesh_3d _euclidean_mesh_3d ; + + ellipsoid_mesh_3d _ellipsoid_mesh_3d ; + + euclidean_grid_2d _euclidean_grid_2d ; + euclidean_grid_3d _euclidean_grid_3d ; + + ellipsoid_grid_3d _ellipsoid_grid_3d ; + + public : + + /*------------------------- helper: init. everything! */ + + __normal_call void_type init_hfun ( + jcfg_data &_jcfg, + bool_type _link = false + ) + { + __unreferenced(_jcfg) ; + + if (_link) + { + this-> + _euclidean_mesh_2d._mesh.make_link () ; + this-> + _euclidean_mesh_3d._mesh.make_link () ; + this-> + _ellipsoid_mesh_3d._mesh.make_link () ; + } + + this-> + _constant_value_kd.init() ; + + this-> + _euclidean_mesh_2d.init() ; + this-> + _euclidean_mesh_3d.init() ; + this-> + _ellipsoid_mesh_3d.init() ; + + this-> + _euclidean_grid_2d.init() ; + this-> + _euclidean_grid_3d.init() ; + this-> + _ellipsoid_grid_3d.init() ; + } + + /*------------------------- helper: limit everything! */ + + __normal_call void_type clip_hfun ( + jcfg_data &_jcfg + ) + { + __unreferenced(_jcfg) ; + + this-> + _constant_value_kd.clip() ; + + this-> + _euclidean_mesh_2d.clip() ; + this-> + _euclidean_mesh_3d.clip() ; + this-> + _ellipsoid_mesh_3d.clip() ; + + this-> + _euclidean_grid_2d.clip() ; + this-> + _euclidean_grid_3d.clip() ; + this-> + _ellipsoid_grid_3d.clip() ; + } + + } ; + + /* + -------------------------------------------------------- + * aggregated RDEL data containers. + -------------------------------------------------------- + */ + + class rdel_data // holds the restrict-del obj. + { + public : + + typedef mesh::rdel_complex_2d < + real_type , + iptr_type > euclidean_rdel_2d ; + + typedef mesh::rdel_complex_3d < + real_type , + iptr_type > euclidean_rdel_3d ; + + std::size_t _ndim = +0; + + jmsh_kind :: + enum_data _kind = + jmsh_kind::null_mesh_kind ; + + euclidean_rdel_2d _euclidean_rdel_2d ; + euclidean_rdel_3d _euclidean_rdel_3d ; + + euclidean_rdel_2d _euclidean_rvor_2d ; + euclidean_rdel_3d _euclidean_rvor_3d ; + + } ; + + /* + -------------------------------------------------------- + * aggregated MESH data containers. + -------------------------------------------------------- + */ + + class mesh_data // holds the tria-complex obj. + { + public : + + typedef mesh::iter_mesh_euclidean_2d < + real_type , + iptr_type > euclidean_mesh_2d ; + + typedef mesh::iter_mesh_euclidean_3d < + real_type , + iptr_type > euclidean_mesh_3d ; + + std::size_t _ndim = +0; + + jmsh_kind :: + enum_data _kind = + jmsh_kind::null_mesh_kind ; + + euclidean_mesh_2d _euclidean_mesh_2d ; + euclidean_mesh_3d _euclidean_mesh_3d ; + + } ; + + /* + -------------------------------------------------------- + * JLOG-DATA: log-file writer for JIGSAW. + -------------------------------------------------------- + */ + + class jlog_text + { + public : + /*-------------------------- a "real" log-file writer */ + std::ofstream _file ; + + iptr_type _verbosity ; + + public : + + __inline_call jlog_text ( + jcfg_data const& _jcfg + ) + { + if (_jcfg._file_path.length() == +0) + { + this->_file.open ( + _jcfg._file_name + ".log", + std::ofstream::out|std::ofstream::trunc) ; + } + else + { + this->_file.open ( + _jcfg._file_path + "/" + + _jcfg._file_name + ".log", + std::ofstream::out|std::ofstream::trunc) ; + } + + this->_verbosity = + _jcfg._verbosity ; + } + + __inline_call ~jlog_text ( + ) + { this->_file.close () ; + } + + /*-------------------------- echo onto logfile/stdout */ + + template < + typename data_type + > + __inline_call void_type push ( + data_type const&_data + ) + { + std :: cout << _data ; + this->_file << _data ; + } + + } ; + + class jlog_null + { + public : + /*-------------------------- a "null" log-file writer */ + + iptr_type _verbosity ; + + public : + + __inline_call jlog_null ( + jcfg_data const& _jcfg + ) + { + /*-------------------------- def. no: for lib_jigsaw! */ + this->_verbosity = + _jcfg._verbosity ; + } + + template < + typename data_type + > + __inline_call void_type push ( + data_type const&_data + ) + { + /*-------------------------- def. no: for lib_jigsaw! */ + if (this->_verbosity > +0) + { + std::cout << _data ; + } + } + + } ; + + /* + -------------------------------------------------------- + * READ-JCFG: load JCFG data from file. + -------------------------------------------------------- + */ + + # include "jig_load.hpp" + + + /* + -------------------------------------------------------- + * READ-DATA: load MESH data from file. + -------------------------------------------------------- + */ + + # include "geo_load.hpp" + # include "ini_load.hpp" + # include "hfn_load.hpp" + + + /* + -------------------------------------------------------- + * INIT-DATA: initialise mesh pointers. + -------------------------------------------------------- + */ + + # include "msh_init.hpp" + # include "hfn_init.hpp" + + + /* + -------------------------------------------------------- + * SAVE-MESH: push MESH data into file. + -------------------------------------------------------- + */ + + # include "msh_save.hpp" + + + /* + -------------------------------------------------------- + * COPY-MESH: copy r-DT to tri-complex. + -------------------------------------------------------- + */ + + # include "msh_copy.hpp" + + + /* + -------------------------------------------------------- + * TIME-SPAN: elapsed sec. between markers. + -------------------------------------------------------- + */ + +# ifdef __use_timers + + __inline_call double time_span ( + typename std:: + chrono::high_resolution_clock + ::time_point const& _ttic , + typename std:: + chrono::high_resolution_clock + ::time_point const& _ttoc + ) + { + return (double)( + std::chrono::duration_cast< + std::chrono::microseconds > + (_ttoc-_ttic).count()) / 1.E+06 ; + } + +# endif//__use_timers + + /* + -------------------------------------------------------- + * DUMP-TIME: "dump" time-span to a string. + -------------------------------------------------------- + */ + +# ifdef __use_timers + + __inline_call std::string dump_time ( + typename std:: + chrono::high_resolution_clock + ::time_point const& _ttic , + typename std:: + chrono::high_resolution_clock + ::time_point const& _ttoc + ) + { + std::stringstream _sstr; + _sstr << " Done. (" + << std::scientific + << std::setprecision(2) + << time_span(_ttic, _ttoc ) + << "sec)\n\n" ; + + return _sstr.str () ; + } + +# endif//__use_timers + + /* + -------------------------------------------------------- + * Jumping-off points for CMD + LIB JIGSAW! + -------------------------------------------------------- + */ + + # include "jigsaw.hpp" + # include "tripod.hpp" + + # include "marche.hpp" + + + diff --git a/src/jigsaw.hpp b/src/jigsaw.hpp index 2402dbd..5e769ac 100644 --- a/src/jigsaw.hpp +++ b/src/jigsaw.hpp @@ -2,19 +2,19 @@ /* -------------------------------------------------------- * - * ,o, ,o, / + * ,o, ,o, / * ` ` e88~88e d88~\ /~~~8e Y88b e / - * 888 888 88 88 C888 88b Y88b d8b / - * 888 888 "8b_d8" Y88b e88~-888 Y888/Y88b/ - * 888 888 / 888D C88 888 Y8/ Y8/ - * 88P 888 Cb \_88P "8b_-888 Y Y - * \_8" Y8""8D + * 888 888 88 88 C888 88b Y88b d8b / + * 888 888 "8b_d8" Y88b e88~-888 Y888/Y88b/ + * 888 888 / 888D C88 888 Y8/ Y8/ + * 88P 888 Cb \_88P "8b_-888 Y Y + * \_8" Y8""8D * -------------------------------------------------------- * JIGSAW: an unstructured mesh generation library. -------------------------------------------------------- * - * Last updated: 19 January, 2019 + * Last updated: 25 November, 2019 * * Copyright 2013 -- 2019 * Darren Engwirda @@ -22,44 +22,38 @@ * https://github.com/dengwirda * -------------------------------------------------------- - * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor the National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- */ - - template < - typename jlog_data - > - __normal_call void_type jigsaw_banner ( - jlog_data &_jlog - ) - { - /*-- NB: silliness re. escape sequences */ - _jlog.push ( + + namespace JIGSAW { + + std::string asciibanner = " \n" "#------------------------------------------------------------\n" "#\n" @@ -75,10 +69,904 @@ "# JIGSAW: an unstructured mesh generation library. \n" "#------------------------------------------------------------\n" " \n" - " " __JGSWVSTR "\n\n" - ) ; + " " __JGSWVSTR "\n\n" ; + + /* + -------------------------------------------------------- + * Call the 2-dimensional mesh generator. + -------------------------------------------------------- + */ + + template < + typename geom_type , + typename init_type , + typename hfun_type , + typename mesh_type , + typename jlog_data + > + __normal_call void_type mesh_euclidean_2d ( + geom_type &_geom, + init_type &_init, + hfun_type &_hfun, + mesh_type &_mesh, + jcfg_data &_args, + jlog_data &_jlog + ) + { + if (_args._mesh_pred == + jcfg_data::mesh_pred::delaunay) + { + /*-------------------------- call DELAUNAY kernel */ + typedef + mesh::rdel_delaunay_2d < + geom_type , + hfun_type , + mesh_type > rdel_pred ; + + typedef mesh::rdel_mesh_2d < + mesh_type , + rdel_pred , + geom_type , + hfun_type , + init_type > mesh_func ; + + typedef + jcfg_data::mesh_opts mesh_opts ; + + mesh_opts *_opts = + &_args._mesh_opts ; + + mesh_func::rdel_mesh ( + _geom, _init , + _hfun, _mesh , + *_opts, _jlog ) ; + } + else + if (_args._mesh_pred == + jcfg_data::mesh_pred::delfront) + { + /*-------------------------- call DELFRONT kernel */ + typedef + mesh::rdel_delfront_2d < + geom_type , + hfun_type , + mesh_type > rdel_pred ; + + typedef mesh::rdel_mesh_2d < + mesh_type , + rdel_pred , + geom_type , + hfun_type , + init_type > mesh_func ; + + typedef + jcfg_data::mesh_opts mesh_opts ; + + mesh_opts *_opts = + &_args._mesh_opts ; + + mesh_func::rdel_mesh ( + _geom, _init , + _hfun, _mesh , + *_opts, _jlog ) ; + } + else + if (_args._mesh_pred == + jcfg_data::mesh_pred::bisector) + { + /*-------------------------- call BISECTOR kernel */ + + /* + typedef + mesh::tree_bisector_2d < + geom_type , + hfun_type , + mesh_type > tree_pred ; + + typedef mesh::tree_mesh_2d < + mesh_type , + tree_pred , + geom_type , + hfun_type , + init_type > mesh_func ; + + typedef + jcfg_data::mesh_opts mesh_opts ; + + mesh_opts *_opts = + &_args._mesh_opts ; + + mesh_func::tree_mesh ( + _geom, _init , + _hfun, _mesh , + *_opts, _jlog ) ; + */ + + } + } + + /* + -------------------------------------------------------- + * Call the 3-dimensional mesh generator. + -------------------------------------------------------- + */ + + template < + typename geom_type , + typename init_type , + typename hfun_type , + typename mesh_type , + typename jlog_data + > + __normal_call void_type mesh_euclidean_3d ( + geom_type &_geom, + init_type &_init, + hfun_type &_hfun, + mesh_type &_mesh, + jcfg_data &_args, + jlog_data &_jlog + ) + { + if (_args._mesh_pred == + jcfg_data::mesh_pred::delaunay) + { + /*-------------------------- call DELAUNAY kernel */ + typedef + mesh::rdel_delaunay_3d < + geom_type , + hfun_type , + mesh_type > rdel_pred ; + + typedef mesh::rdel_mesh_3d < + mesh_type , + rdel_pred , + geom_type , + hfun_type , + init_type > mesh_func ; + + typedef + jcfg_data::mesh_opts mesh_opts ; + + mesh_opts *_opts = + &_args._mesh_opts ; + + mesh_func::rdel_mesh ( + _geom, _init , + _hfun, _mesh , + *_opts, _jlog ) ; + } + else + if (_args._mesh_pred == + jcfg_data::mesh_pred::delfront) + { + /*-------------------------- call DELFRONT kernel */ + typedef + mesh::rdel_delfront_3d < + geom_type , + hfun_type , + mesh_type > rdel_pred ; + + typedef mesh::rdel_mesh_3d < + mesh_type , + rdel_pred , + geom_type , + hfun_type , + init_type > mesh_func ; + + typedef + jcfg_data::mesh_opts mesh_opts ; + + mesh_opts *_opts = + &_args._mesh_opts ; + + mesh_func::rdel_mesh ( + _geom, _init , + _hfun, _mesh , + *_opts, _jlog ) ; + } + else + if (_args._mesh_pred == + jcfg_data::mesh_pred::bisector) + { + /*-------------------------- call BISECTOR kernel */ + + /* + typedef + mesh::tree_bisector_3d < + geom_type , + hfun_type , + mesh_type > tree_pred ; + + typedef mesh::tree_mesh_3d < + mesh_type , + tree_pred , + geom_type , + hfun_type , + init_type > mesh_func ; + + typedef + jcfg_data::mesh_opts mesh_opts ; + + mesh_opts *_opts = + &_args._mesh_opts ; + + mesh_func::tree_mesh ( + _geom, _init , + _hfun, _mesh , + *_opts, _jlog ) ; + */ + + } } - + + /* + -------------------------------------------------------- + * Call the k-dimensional mesh generator. + -------------------------------------------------------- + */ + + template < + typename jlog_data + > + __normal_call iptr_type mesh_impl ( + jcfg_data &_args, + jlog_data &_jlog, + geom_data &_geom, + mesh_data &_init, + hfun_data &_hfun, + rdel_data &_rdel + ) + { + iptr_type _errv = __no_error ; + + try + { + if (_geom._ndim == +2 && + _geom._kind == + jmsh_kind::euclidean_mesh) + { + /*--------------- have euclidean-mesh GEOM kernel */ + + if (_hfun._ndim == +0 ) + { + /*--------------- with constant-value HFUN kernel */ + _rdel._kind = + jmsh_kind::euclidean_mesh; + + _rdel._ndim = +2 ; + + mesh_euclidean_2d ( + _geom._euclidean_mesh_2d, + _init._euclidean_mesh_2d, + _hfun._constant_value_kd, + _rdel._euclidean_rdel_2d, + _args, _jlog) ; + } + else + if (_hfun._ndim == +2 && + _hfun._kind == + jmsh_kind::euclidean_mesh) + { + /*--------------- with euclidean-mesh HFUN kernel */ + _rdel._kind = + jmsh_kind::euclidean_mesh; + + _rdel._ndim = +2 ; + + mesh_euclidean_2d ( + _geom._euclidean_mesh_2d, + _init._euclidean_mesh_2d, + _hfun._euclidean_mesh_2d, + _rdel._euclidean_rdel_2d, + _args, _jlog) ; + } + else + if (_hfun._ndim == +2 && + _hfun._kind == + jmsh_kind::euclidean_grid) + { + /*--------------- with euclidean-grid HFUN kernel */ + _rdel._kind = + jmsh_kind::euclidean_mesh; + + _rdel._ndim = +2 ; + + mesh_euclidean_2d ( + _geom._euclidean_mesh_2d, + _init._euclidean_mesh_2d, + _hfun._euclidean_grid_2d, + _rdel._euclidean_rdel_2d, + _args, _jlog) ; + } + + } + else + if (_geom._ndim == +3 && + _geom._kind == + jmsh_kind::euclidean_mesh) + { + /*--------------- have euclidean-mesh GEOM kernel */ + + if (_hfun._ndim == +0 ) + { + /*--------------- with constant-value HFUN kernel */ + _rdel._kind = + jmsh_kind::euclidean_mesh; + + _rdel._ndim = +3 ; + + mesh_euclidean_3d ( + _geom._euclidean_mesh_3d, + _init._euclidean_mesh_3d, + _hfun._constant_value_kd, + _rdel._euclidean_rdel_3d, + _args, _jlog) ; + } + else + if (_hfun._ndim == +3 && + _hfun._kind == + jmsh_kind::euclidean_mesh) + { + /*--------------- with euclidean-mesh HFUN kernel */ + _rdel._kind = + jmsh_kind::euclidean_mesh; + + _rdel._ndim = +3 ; + + mesh_euclidean_3d ( + _geom._euclidean_mesh_3d, + _init._euclidean_mesh_3d, + _hfun._euclidean_mesh_3d, + _rdel._euclidean_rdel_3d, + _args, _jlog) ; + } + else + if (_hfun._ndim == +3 && + _hfun._kind == + jmsh_kind::euclidean_grid) + { + /*--------------- with euclidean-grid HFUN kernel */ + _rdel._kind = + jmsh_kind::euclidean_mesh; + + _rdel._ndim = +3 ; + + mesh_euclidean_3d ( + _geom._euclidean_mesh_3d, + _init._euclidean_mesh_3d, + _hfun._euclidean_grid_3d, + _rdel._euclidean_rdel_3d, + _args, _jlog) ; + } + + } + else + if (_geom._kind == + jmsh_kind::ellipsoid_mesh) + { + /*--------------- have ellipsoid-mesh GEOM kernel */ + + if (_hfun._ndim == +0 ) + { + /*--------------- with constant-value HFUN kernel */ + _rdel._kind = + jmsh_kind::euclidean_mesh; + + _rdel._ndim = +3 ; + + mesh_euclidean_3d ( + _geom._ellipsoid_mesh_3d, + _init._euclidean_mesh_3d, + _hfun._constant_value_kd, + _rdel._euclidean_rdel_3d, + _args, _jlog) ; + } + else + if (_hfun._kind == + jmsh_kind::ellipsoid_grid) + { + /*--------------- with ellipsoid-grid HFUN kernel */ + _rdel._kind = + jmsh_kind::euclidean_mesh; + + _rdel._ndim = +3 ; + + mesh_euclidean_3d ( + _geom._ellipsoid_mesh_3d, + _init._euclidean_mesh_3d, + _hfun._ellipsoid_grid_3d, + _rdel._euclidean_rdel_3d, + _args, _jlog) ; + } + else + if (_hfun._kind == + jmsh_kind::ellipsoid_mesh) + { + /*--------------- with ellipsoid-mesh HFUN kernel */ + _rdel._kind = + jmsh_kind::euclidean_mesh; + + _rdel._ndim = +3 ; + + mesh_euclidean_3d ( + _geom._ellipsoid_mesh_3d, + _init._euclidean_mesh_3d, + _hfun._ellipsoid_mesh_3d, + _rdel._euclidean_rdel_3d, + _args, _jlog) ; + } + else + if (_hfun._ndim == +3 && + _hfun._kind == + jmsh_kind::euclidean_mesh) + { + /*--------------- with euclidean-mesh HFUN kernel */ + _rdel._kind = + jmsh_kind::euclidean_mesh; + + _rdel._ndim = +3 ; + + mesh_euclidean_3d ( + _geom._ellipsoid_mesh_3d, + _init._euclidean_mesh_3d, + _hfun._euclidean_mesh_3d, + _rdel._euclidean_rdel_3d, + _args, _jlog) ; + } + else + if (_hfun._ndim == +3 && + _hfun._kind == + jmsh_kind::euclidean_grid) + { + /*--------------- with euclidean-grid HFUN kernel */ + _rdel._kind = + jmsh_kind::euclidean_mesh; + + _rdel._ndim = +3 ; + + mesh_euclidean_3d ( + _geom._ellipsoid_mesh_3d, + _init._euclidean_mesh_3d, + _hfun._euclidean_grid_3d, + _rdel._euclidean_rdel_3d, + _args, _jlog) ; + } + + } + } + catch (...) + { + _errv = __unknown_error ; + } + + return ( _errv ) ; + } + + /* + -------------------------------------------------------- + * Call the 2-dimensional mesh optimiser. + -------------------------------------------------------- + */ + + template < + typename geom_type , + typename hfun_type , + typename mesh_type , + typename jlog_data + > + __normal_call void_type iter_euclidean_2d ( + geom_type &_geom , + hfun_type &_hfun , + mesh_type &_mesh , + jcfg_data &_args , + jlog_data &_jlog + ) + { + if (_args._iter_pred == + jcfg_data::iter_pred::odt_dqdx) + { + /*-------------------------- call ODT-ITER kernel */ + typedef mesh:: + iter_pred_euclidean_2d < + real_type , + iptr_type > pred_type ; + + typedef mesh::iter_mesh_2 < + geom_type , + typename + mesh_type:: + mesh_type , + hfun_type , + pred_type > iter_func ; + + typedef + jcfg_data::iter_opts iter_opts ; + + iter_opts *_opts = + &_args._iter_opts ; + + pred_type _pred ; + iter_func::iter_mesh ( + _geom, _hfun , + _mesh. _mesh , + iter_func::_odt_kern , + _pred, + *_opts, _jlog ) ; + } + else + if (_args._iter_pred == + jcfg_data::iter_pred::cvt_dqdx) + { + /*-------------------------- call CVT-ITER kernel */ + typedef mesh:: + iter_pred_euclidean_2d < + real_type , + iptr_type > pred_type ; + + typedef mesh::iter_mesh_2 < + geom_type , + typename + mesh_type:: + mesh_type , + hfun_type , + pred_type > iter_func ; + + typedef + jcfg_data::iter_opts iter_opts ; + + iter_opts *_opts = + &_args._iter_opts ; + + pred_type _pred ; + iter_func::iter_mesh ( + _geom, _hfun , + _mesh. _mesh , + iter_func::_cvt_kern , + _pred, + *_opts, _jlog ) ; + } + } + + template < + typename geom_type , + typename hfun_type , + typename mesh_type , + typename jlog_data + > + __normal_call void_type iter_ellipsoid_3d ( + geom_type &_geom , + hfun_type &_hfun , + mesh_type &_mesh , + jcfg_data &_args , + jlog_data &_jlog + ) + { + if (_args._iter_pred == + jcfg_data::iter_pred::odt_dqdx) + { + /*-------------------------- call ODT-ITER kernel */ + typedef mesh:: + iter_pred_ellipsoid_3d < + real_type , + iptr_type > pred_type ; + + typedef mesh::iter_mesh_2 < + geom_type , + typename + mesh_type:: + mesh_type , + hfun_type , + pred_type > iter_func ; + + typedef + jcfg_data::iter_opts iter_opts ; + + iter_opts *_opts = + &_args._iter_opts ; + + pred_type _pred ; + iter_func::iter_mesh ( + _geom, _hfun , + _mesh. _mesh , + iter_func::_odt_kern , + _pred, + *_opts, _jlog ) ; + } + else + if (_args._iter_pred == + jcfg_data::iter_pred::cvt_dqdx) + { + /*-------------------------- call CVT-ITER kernel */ + typedef mesh:: + iter_pred_ellipsoid_3d < + real_type , + iptr_type > pred_type ; + + typedef mesh::iter_mesh_2 < + geom_type , + typename + mesh_type:: + mesh_type , + hfun_type , + pred_type > iter_func ; + + typedef + jcfg_data::iter_opts iter_opts ; + + iter_opts *_opts = + &_args._iter_opts ; + + pred_type _pred ; + iter_func::iter_mesh ( + _geom, _hfun , + _mesh. _mesh , + iter_func::_cvt_kern , + _pred, + *_opts, _jlog ) ; + } + } + + /* + -------------------------------------------------------- + * Call the 3-dimensional mesh optimiser. + -------------------------------------------------------- + */ + + template < + typename geom_type , + typename hfun_type , + typename mesh_type , + typename jlog_data + > + __normal_call void_type iter_euclidean_3d ( + geom_type &/*_geom*/, + hfun_type &/*_hfun*/, + mesh_type &/*_mesh*/, + jcfg_data &/*_args*/, + jlog_data &/*_jlog*/ + ) + { //!! yes, indeed... + + } + + /* + -------------------------------------------------------- + * Call the k-dimensional mesh optimiser. + -------------------------------------------------------- + */ + + template < + typename jlog_data + > + __normal_call iptr_type iter_impl ( + jcfg_data &_args, + jlog_data &_jlog, + geom_data &_geom, + hfun_data &_hfun, + mesh_data &_mesh + ) + { + iptr_type _errv = __no_error ; + + try + { + if (_geom._ndim == +2 && + _geom._kind == + jmsh_kind::euclidean_mesh) + { + /*----------- have euclidean-mesh GEOM kernel */ + + if (_hfun._ndim == +0 ) + { + /*----------- with constant-value HFUN kernel */ + _mesh._kind = + jmsh_kind::euclidean_mesh; + + _mesh._ndim = +2 ; + + iter_euclidean_2d ( + _geom._euclidean_mesh_2d, + _hfun._constant_value_kd, + _mesh._euclidean_mesh_2d, + _args, _jlog) ; + } + else + if (_hfun._ndim == +2 && + _hfun._kind == + jmsh_kind::euclidean_mesh) + { + /*----------- with euclidean-mesh HFUN kernel */ + _mesh._kind = + jmsh_kind::euclidean_mesh; + + _mesh._ndim = +2 ; + + iter_euclidean_2d ( + _geom._euclidean_mesh_2d, + _hfun._euclidean_mesh_2d, + _mesh._euclidean_mesh_2d, + _args, _jlog) ; + } + else + if (_hfun._ndim == +2 && + _hfun._kind == + jmsh_kind::euclidean_grid) + { + /*----------- with euclidean-grid HFUN kernel */ + _mesh._kind = + jmsh_kind::euclidean_mesh; + + _mesh._ndim = +2 ; + + iter_euclidean_2d ( + _geom._euclidean_mesh_2d, + _hfun._euclidean_grid_2d, + _mesh._euclidean_mesh_2d, + _args, _jlog) ; + } + + } + else + if (_geom._ndim == +3 && + _geom._kind == + jmsh_kind::euclidean_mesh) + { + /*----------- have euclidean-mesh GEOM kernel */ + + if (_hfun._ndim == +0 ) + { + /*----------- with constant-value HFUN kernel */ + _mesh._kind = + jmsh_kind::euclidean_mesh; + + _mesh._ndim = +3 ; + + /* + iter_euclidean_3d ( + _geom._euclidean_mesh_3d, + _hfun._constant_value_kd, + _mesh._euclidean_mesh_3d, + _args, _jlog) ; + */ + } + else + if (_hfun._ndim == +3 && + _hfun._kind == + jmsh_kind::euclidean_mesh) + { + /*----------- with euclidean-mesh HFUN kernel */ + _mesh._kind = + jmsh_kind::euclidean_mesh; + + _mesh._ndim = +3 ; + + /* + iter_euclidean_3d ( + _geom._euclidean_mesh_3d, + _hfun._euclidean_mesh_3d, + _mesh._euclidean_mesh_3d, + _args, _jlog) ; + */ + } + else + if (_hfun._ndim == +3 && + _hfun._kind == + jmsh_kind::euclidean_grid) + { + /*----------- with euclidean-grid HFUN kernel */ + _mesh._kind = + jmsh_kind::euclidean_mesh; + + _mesh._ndim = +3 ; + + /* + iter_euclidean_3d ( + _geom._euclidean_mesh_3d, + _hfun._euclidean_grid_3d, + _mesh._euclidean_mesh_3d, + _args, _jlog) ; + */ + } + + } + if (_geom._kind == + jmsh_kind::ellipsoid_mesh) + { + /*----------- have ellipsoid-mesh GEOM kernel */ + + if (_hfun._ndim == +0 ) + { + /*----------- with constant-value HFUN kernel */ + _mesh._kind = + jmsh_kind::euclidean_mesh; + + _mesh._ndim = +3 ; + + iter_ellipsoid_3d ( + _geom._ellipsoid_mesh_3d, + _hfun._constant_value_kd, + _mesh._euclidean_mesh_3d, + _args, _jlog) ; + } + else + if (_hfun._kind == + jmsh_kind::ellipsoid_grid) + { + /*----------- with ellipsoid-grid HFUN kernel */ + _mesh._kind = + jmsh_kind::euclidean_mesh; + + _mesh._ndim = +3 ; + + iter_ellipsoid_3d ( + _geom._ellipsoid_mesh_3d, + _hfun._ellipsoid_grid_3d, + _mesh._euclidean_mesh_3d, + _args, _jlog) ; + } + else + if (_hfun._kind == + jmsh_kind::ellipsoid_mesh) + { + /*----------- with ellipsoid-mesh HFUN kernel */ + _mesh._kind = + jmsh_kind::euclidean_mesh; + + _mesh._ndim = +3 ; + + iter_ellipsoid_3d ( + _geom._ellipsoid_mesh_3d, + _hfun._ellipsoid_mesh_3d, + _mesh._euclidean_mesh_3d, + _args, _jlog) ; + } + else + if (_hfun._ndim == +3 && + _hfun._kind == + jmsh_kind::euclidean_mesh) + { + /*----------- with euclidean-mesh HFUN kernel */ + _mesh._kind = + jmsh_kind::euclidean_mesh; + + _mesh._ndim = +3 ; + + iter_ellipsoid_3d ( + _geom._ellipsoid_mesh_3d, + _hfun._euclidean_mesh_3d, + _mesh._euclidean_mesh_3d, + _args, _jlog) ; + } + else + if (_hfun._ndim == +3 && + _hfun._kind == + jmsh_kind::euclidean_grid) + { + /*----------- with euclidean-grid HFUN kernel */ + _mesh._kind = + jmsh_kind::euclidean_mesh; + + _mesh._ndim = +3 ; + + iter_ellipsoid_3d ( + _geom._ellipsoid_mesh_3d, + _hfun._euclidean_grid_3d, + _mesh._euclidean_mesh_3d, + _args, _jlog) ; + } + } + + } + catch (...) + { + _errv = __unknown_error ; + } + + return ( _errv ) ; + } + + } + # ifdef __lib_jigsaw # include "liblib/init_jig_t.hpp" @@ -89,7 +977,7 @@ # include "liblib/save_jig_t.hpp" # include "liblib/save_msh_t.hpp" - + __normal_call iptr_type jigsaw ( // lib-jigsaw jigsaw_jig_t *_jjig , jigsaw_msh_t *_gmsh , @@ -99,13 +987,13 @@ ) { iptr_type _retv = +0; - + hfun_data _hfun ; // HFUN data geom_data _geom ; // GEOM data rdel_data _rdel ; // TRIA data mesh_data _mesh ; // MESH data jcfg_data _jcfg ; - + # ifdef __use_timers typename std ::chrono:: high_resolution_clock:: @@ -115,38 +1003,39 @@ time_point _ttoc ; typename std ::chrono:: high_resolution_clock _time; - + __unreferenced(_time) ; # endif//__use_timers - - /*--------------------------------- init. output data */ + + /*--------------------------------- init. output data */ jigsaw_init_msh_t(_mmsh) ; - + /*--------------------------------- setup *.JLOG data */ if (_jjig != nullptr ) { _jcfg._verbosity = _jjig->_verbosity ; } - jlog_null _jlog(_jcfg) ; - jigsaw_banner (_jlog) ; - + jlog_null _jlog(_jcfg) ; + _jlog.push(JIGSAW:: + asciibanner) ; + /*--------------------------------- parse *.JCFG data */ if (_jjig != nullptr ) { _jlog.push ( " Reading CFG. data...\n\n" ) ; -# ifdef __use_timers +# ifdef __use_timers _ttic = _time.now(); # endif//__use_timers - + if ((_retv = copy_jcfg ( - _jcfg, + _jcfg, _jlog,*_jjig)) != __no_error) { return _retv ; - } - + } + if ((_retv = test_jcfg ( _jcfg, _jlog)) != __no_error) { @@ -162,56 +1051,56 @@ return _retv ; } -# ifdef __use_timers +# ifdef __use_timers _ttoc = _time.now(); _jlog.push(dump_time(_ttic, _ttoc)); # endif//__use_timers } - + if (_gmsh != nullptr ) { /*--------------------------------- parse *.GEOM data */ _jlog.push ( __jloglndv "\n" ) ; _jlog.push ( " Reading GEOM data...\n\n" ) ; - + # ifdef __use_timers _ttic = _time.now(); # endif//__use_timers if ((_retv = copy_geom ( - _jcfg, _jlog , + _jcfg, _jlog , _geom,*_gmsh)) != __no_error) { return _retv ; } - + if ((_retv = test_geom ( - _jcfg, + _jcfg, _jlog, _geom)) != __no_error) { return _retv ; } - + # ifdef __use_timers _ttoc = _time.now(); _jlog.push(dump_time(_ttic, _ttoc)); # endif//__use_timers } - + if (_gmsh != nullptr ) { /*--------------------------------- parse *.GEOM data */ _jlog.push ( __jloglndv "\n" ) ; _jlog.push ( " Forming GEOM data...\n\n" ) ; - + # ifdef __use_timers _ttic = _time.now(); # endif//__use_timers _geom.init_geom(_jcfg) ; - + if (_jcfg._verbosity > 0 ) { @@ -219,12 +1108,12 @@ " GEOM data summary...\n\n" ) ; if ((_retv = echo_geom ( - _jcfg, + _jcfg, _jlog, _geom)) != __no_error) { return _retv ; } - + } # ifdef __use_timers @@ -239,46 +1128,46 @@ _jlog.push ( __jloglndv "\n" ) ; _jlog.push ( " Reading INIT data...\n\n" ) ; - + # ifdef __use_timers _ttic = _time.now(); # endif//__use_timers if ((_retv = copy_init ( - _jcfg, _jlog, + _jcfg, _jlog, _mesh,*_imsh)) != __no_error) { return _retv ; } if ((_retv = test_init ( - _jcfg, + _jcfg, _jlog, _mesh)) != __no_error) { return _retv ; } - + # ifdef __use_timers _ttoc = _time.now(); _jlog.push(dump_time(_ttic, _ttoc)); # endif//__use_timers } - + if (_imsh != nullptr ) { /*--------------------------------- assemble init-con */ _jlog.push ( __jloglndv "\n" ) ; _jlog.push ( " Forming INIT data...\n\n" ) ; - + # ifdef __use_timers _ttic = _time.now(); # endif//__use_timers _mesh._euclidean_mesh_2d. - _mesh.make_ptrs(); + _mesh.make_link(); _mesh._euclidean_mesh_3d. - _mesh.make_ptrs(); + _mesh.make_link(); if (_jcfg._verbosity > 0 ) { @@ -287,58 +1176,58 @@ " INIT data summary...\n\n" ) ; if ((_retv = echo_init ( - _jcfg, + _jcfg, _jlog, _mesh)) != __no_error) { return _retv ; } - + } - + # ifdef __use_timers _ttoc = _time.now(); _jlog.push(dump_time(_ttic, _ttoc)); # endif//__use_timers } - + if (_hmsh != nullptr ) { /*--------------------------------- parse *.HFUN data */ _jlog.push ( __jloglndv "\n" ) ; _jlog.push ( " Reading HFUN data...\n\n" ) ; - + # ifdef __use_timers _ttic = _time.now(); # endif//__use_timers if ((_retv = copy_hfun ( - _jcfg, _jlog , + _jcfg, _jlog , _hfun,*_hmsh)) != __no_error) { return _retv ; } - + if ((_retv = test_hfun ( - _jcfg, + _jcfg, _jlog, _hfun)) != __no_error) { return _retv ; } - -# ifdef __use_timers + +# ifdef __use_timers _ttoc = _time.now(); _jlog.push(dump_time(_ttic, _ttoc)); # endif//__use_timers } - + if (_gmsh != nullptr ) { /*--------------------------------- assemble size-fun */ _jlog.push ( __jloglndv "\n" ) ; _jlog.push ( " Forming HFUN data...\n\n" ) ; - + # ifdef __use_timers _ttic = _time.now(); # endif//__use_timers @@ -351,20 +1240,20 @@ } _hfun.init_hfun (_jcfg); - + if (_jcfg._verbosity > 0 ) { _jlog.push ( " HFUN data summary...\n\n" ) ; - + if ((_retv = echo_hfun ( - _jcfg, + _jcfg, _jlog, _hfun)) != __no_error) { return _retv ; - } - + } + } # ifdef __use_timers @@ -372,39 +1261,40 @@ _jlog.push(dump_time(_ttic, _ttoc)); # endif//__use_timers } - + if (_gmsh != nullptr ) { - if(_jcfg._rdel_opts.iter() != +0 ) + if(_jcfg._mesh_opts.iter() != +0 ) { /*--------------------------------- call mesh routine */ _jlog.push ( __jloglndv "\n" ) ; _jlog.push ( " Generate rDT MESH...\n\n" ) ; - + # ifdef __use_timers _ttic = _time.now(); # endif//__use_timers - if ((_retv = make_mesh ( + if ((_retv = + JIGSAW ::mesh_impl ( _jcfg, _jlog , - _geom, _mesh , + _geom, _mesh , _hfun, _rdel)) != __no_error) { return _retv ; } -# ifdef __use_timers +# ifdef __use_timers _ttoc = _time.now(); _jlog.push(dump_time(_ttic, _ttoc)); # endif//__use_timers } } - + if (_gmsh != nullptr ) { /*--------------------------------- call copy routine */ - if(_jcfg._rdel_opts.iter() != +0 && + if(_jcfg._mesh_opts.iter() != +0 && _jcfg._iter_opts.iter() != +0 ) { _jlog.push ( __jloglndv "\n" ) ; @@ -428,7 +1318,7 @@ # endif//__use_timers } } - + if (_gmsh != nullptr ) { if(_jcfg._iter_opts.iter() != +0 ) @@ -443,15 +1333,16 @@ # endif//__use_timers if ((_retv = init_mesh ( - _jcfg, + _jcfg, _jlog, _mesh)) != __no_error) { return _retv ; } - if ((_retv = iter_mesh ( + if ((_retv = + JIGSAW ::iter_impl ( _jcfg, _jlog , - _geom, + _geom, _hfun, _mesh)) != __no_error) { return _retv ; @@ -463,59 +1354,59 @@ # endif//__use_timers } } - + if (_gmsh != nullptr ) { /*--------------------------------- dump mesh to data */ _jlog.push ( __jloglndv "\n" ) ; _jlog.push ( - " Writing MESH file...\n\n" ) ; + " Writing MESH data...\n\n" ) ; # ifdef __use_timers _ttic = _time.now(); # endif//__use_timers - if (_jcfg._rdel_opts.iter() != +0 && + if (_jcfg._mesh_opts.iter() != +0 && _jcfg._iter_opts.iter() == +0 ) { - if ((_retv = save_msht ( - _jcfg, _jlog , + if ((_retv = save_rdel ( + _jcfg, _jlog , _rdel,*_mmsh)) != __no_error) { return _retv ; } - - } + + } else { - if ((_retv = save_msht ( - _jcfg, _jlog , + if ((_retv = save_mesh ( + _jcfg, _jlog , _mesh,*_mmsh)) != __no_error) { return _retv ; } - + } -# ifdef __use_timers +# ifdef __use_timers _ttoc = _time.now(); _jlog.push(dump_time(_ttic, _ttoc)); # endif//__use_timers } - + /*-------------------------- success, if we got here! */ return ( _retv ) ; } - + # else # if defined(__cmd_jigsaw) __normal_call iptr_type main ( // cmd-jigsaw - int _argc , + int _argc , char **_argv ) { @@ -523,7 +1414,7 @@ geom_data _geom ; // GEOM data rdel_data _rdel ; // TRIA data mesh_data _mesh ; // MESH data - + # ifdef __use_timers typename std ::chrono:: high_resolution_clock:: @@ -533,33 +1424,50 @@ time_point _ttoc ; typename std ::chrono:: high_resolution_clock _time; - + __unreferenced(_time) ; # endif//__use_timers - - /*-------------------------- find *.JFCG file in args */ + + /*-------------------------- find *.JFCG file in args */ iptr_type _retv = -1 ; jcfg_data _jcfg ; for (; _argc-- != +0; ) { std::string _ssrc(_argv[_argc]) ; - - std::string _path ; - std::string _name ; - std::string _fext ; - file_part ( _ssrc , - _path , _name , _fext) ; - if (_ssrc.find("-whoami") == 0) + if (_ssrc.find("-h") == 0 || + _ssrc.find( + "--help") == 0 ) + { + _retv = -2 ; + + std::cout << + "run jigsaw jigname.jig"; + std::cout << std::endl ; + + break ; + } + + if (_ssrc.find("-v") == 0 || + _ssrc.find( + "--version") == 0 || + _ssrc.find( + "-whoami") == 0 ) { _retv = -2 ; - + std::cout << __JGSWVSTR ; std::cout << std::endl ; - + break ; } + std::string _path ; + std::string _name ; + std::string _fext ; + file_part ( _ssrc , + _path , _name , _fext ) ; + if (_fext.find("jig") == 0) { _retv = +0 ; @@ -575,25 +1483,26 @@ if (_retv != +0) return ( _retv ) ; /*--------------------------------- setup *.JLOG file */ - jlog_text _jlog(_jcfg) ; - jigsaw_banner (_jlog) ; - + jlog_text _jlog(_jcfg) ; + _jlog.push(JIGSAW:: + asciibanner) ; + if(!_jcfg._jcfg_file.empty()) { /*--------------------------------- parse *.JCFG file */ _jlog.push ( " Reading CFG. file...\n\n" ) ; - + # ifdef __use_timers _ttic = _time.now(); # endif//__use_timers - + if ((_retv = read_jcfg ( _jcfg, _jlog)) != __no_error) { return _retv ; - } - + } + if ((_retv = test_jcfg ( _jcfg, _jlog)) != __no_error) { @@ -608,7 +1517,7 @@ { return _retv ; } - + # ifdef __use_timers _ttoc = _time.now(); _jlog.push(dump_time(_ttic, _ttoc)); @@ -621,20 +1530,20 @@ _jlog.push ( __jloglndv "\n" ) ; _jlog.push ( " Reading GEOM file...\n\n" ) ; - + # ifdef __use_timers _ttic = _time.now(); # endif//__use_timers if ((_retv = read_geom ( - _jcfg, + _jcfg, _jlog, _geom)) != __no_error) { return _retv ; } if ((_retv = test_geom ( - _jcfg, + _jcfg, _jlog, _geom)) != __no_error) { return _retv ; @@ -652,13 +1561,13 @@ _jlog.push ( __jloglndv "\n" ) ; _jlog.push ( " Forming GEOM data...\n\n" ) ; - + # ifdef __use_timers _ttic = _time.now(); # endif//__use_timers _geom.init_geom(_jcfg) ; - + if (_jcfg._verbosity > 0 ) { @@ -666,12 +1575,12 @@ " GEOM data summary...\n\n" ) ; if ((_retv = echo_geom ( - _jcfg, + _jcfg, _jlog, _geom)) != __no_error) { return _retv ; } - + } # ifdef __use_timers @@ -679,53 +1588,53 @@ _jlog.push(dump_time(_ttic, _ttoc)); # endif//__use_timers } - + if(!_jcfg._init_file.empty()) { /*--------------------------------- parse *.INIT file */ _jlog.push ( __jloglndv "\n" ) ; _jlog.push ( " Reading INIT file...\n\n" ) ; - + # ifdef __use_timers _ttic = _time.now(); # endif//__use_timers if ((_retv = read_init ( - _jcfg, + _jcfg, _jlog, _mesh)) != __no_error) { return _retv ; } if ((_retv = test_init ( - _jcfg, + _jcfg, _jlog, _mesh)) != __no_error) { return _retv ; } - + # ifdef __use_timers _ttoc = _time.now(); _jlog.push(dump_time(_ttic, _ttoc)); # endif//__use_timers } - + if(!_jcfg._init_file.empty()) { /*--------------------------------- assemble init-con */ _jlog.push ( __jloglndv "\n" ) ; _jlog.push ( " Forming INIT data...\n\n" ) ; - + # ifdef __use_timers _ttic = _time.now(); # endif//__use_timers _mesh._euclidean_mesh_2d. - _mesh.make_ptrs(); + _mesh.make_link(); _mesh._euclidean_mesh_3d. - _mesh.make_ptrs(); + _mesh.make_link(); if (_jcfg._verbosity > 0 ) { @@ -734,14 +1643,14 @@ " INIT data summary...\n\n" ) ; if ((_retv = echo_init ( - _jcfg, + _jcfg, _jlog, _mesh)) != __no_error) { return _retv ; } - + } - + # ifdef __use_timers _ttoc = _time.now(); _jlog.push(dump_time(_ttic, _ttoc)); @@ -754,38 +1663,38 @@ _jlog.push ( __jloglndv "\n" ) ; _jlog.push ( " Reading HFUN file...\n\n" ) ; - + # ifdef __use_timers _ttic = _time.now(); # endif//__use_timers if ((_retv = read_hfun ( - _jcfg, + _jcfg, _jlog, _hfun)) != __no_error) { return _retv ; } - + if ((_retv = test_hfun ( - _jcfg, + _jcfg, _jlog, _hfun)) != __no_error) { return _retv ; } - + # ifdef __use_timers _ttoc = _time.now(); _jlog.push(dump_time(_ttic, _ttoc)); # endif//__use_timers } - + if(!_jcfg._geom_file.empty()) { /*--------------------------------- assemble size-fun */ _jlog.push ( __jloglndv "\n" ) ; _jlog.push ( " Forming HFUN data...\n\n" ) ; - + # ifdef __use_timers _ttic = _time.now(); # endif//__use_timers @@ -804,14 +1713,14 @@ _jlog.push ( " HFUN data summary...\n\n" ) ; - + if ((_retv = echo_hfun ( - _jcfg, + _jcfg, _jlog, _hfun)) != __no_error) { return _retv ; - } - + } + } # ifdef __use_timers @@ -819,10 +1728,10 @@ _jlog.push(dump_time(_ttic, _ttoc)); # endif//__use_timers } - + if(!_jcfg._geom_file.empty()) { - if(_jcfg._rdel_opts.iter() != +0 ) + if(_jcfg._mesh_opts.iter() != +0 ) { /*--------------------------------- call mesh routine */ _jlog.push ( __jloglndv "\n" ) ; @@ -833,7 +1742,8 @@ _ttic = _time.now(); # endif//__use_timers - if ((_retv = make_mesh ( + if ((_retv = + JIGSAW ::mesh_impl ( _jcfg, _jlog , _geom, _mesh , _hfun, _rdel)) != __no_error) @@ -841,13 +1751,13 @@ return _retv ; } -# ifdef __use_timers +# ifdef __use_timers _ttoc = _time.now(); _jlog.push(dump_time(_ttic, _ttoc)); # endif//__use_timers } } - + if(!_jcfg._geom_file.empty() && !_jcfg._tria_file.empty() ) { @@ -861,13 +1771,13 @@ # endif//__use_timers if ((_retv = save_tria ( - _jcfg, + _jcfg, _jlog, _rdel)) != __no_error) { return _retv ; } - -# ifdef __use_timers + +# ifdef __use_timers _ttoc = _time.now(); _jlog.push(dump_time(_ttic, _ttoc)); # endif//__use_timers @@ -875,7 +1785,7 @@ if(!_jcfg._geom_file.empty()) { - if(_jcfg._rdel_opts.iter() != +0 && + if(_jcfg._mesh_opts.iter() != +0 && _jcfg._iter_opts.iter() != +0 ) { /*--------------------------------- call copy routine */ @@ -900,7 +1810,7 @@ # endif//__use_timers } } - + if(!_jcfg._geom_file.empty()) { if(_jcfg._iter_opts.iter() != +0 ) @@ -915,15 +1825,16 @@ # endif//__use_timers if ((_retv = init_mesh ( - _jcfg, + _jcfg, _jlog, _mesh)) != __no_error) { return _retv ; } - if ((_retv = iter_mesh ( + if ((_retv = + JIGSAW ::iter_impl ( _jcfg, _jlog , - _geom, + _geom, _hfun, _mesh)) != __no_error) { return _retv ; @@ -935,7 +1846,7 @@ # endif//__use_timers } } - + if(!_jcfg._geom_file.empty() && !_jcfg._mesh_file.empty() ) { @@ -948,31 +1859,31 @@ _ttic = _time.now(); # endif//__use_timers - if (_jcfg._rdel_opts.iter() != +0 && + if (_jcfg._mesh_opts.iter() != +0 && _jcfg._iter_opts.iter() == +0 ) { - if ((_retv = save_jmsh ( - _jcfg, + if ((_retv = save_rdel ( + _jcfg, _jlog, _rdel)) != __no_error) { return _retv ; } - - } + + } else { - if ((_retv = save_jmsh ( - _jcfg, + if ((_retv = save_mesh ( + _jcfg, _jlog, _mesh)) != __no_error) { return _retv ; } - + } -# ifdef __use_timers +# ifdef __use_timers _ttoc = _time.now(); _jlog.push(dump_time(_ttic, _ttoc)); # endif//__use_timers @@ -982,10 +1893,10 @@ return ( _retv ) ; } - + # endif //__cmd_jigsaw - + # endif //__lib_jigsaw - - - + + + diff --git a/src/libcpp/aabb_tree/aabb_mesh_k.hpp b/src/libcpp/aabb_tree/aabb_mesh_k.hpp index 732a48e..c1f7d5d 100644 --- a/src/libcpp/aabb_tree/aabb_mesh_k.hpp +++ b/src/libcpp/aabb_tree/aabb_mesh_k.hpp @@ -1,45 +1,45 @@ - /* - -------------------------------------------------------- - * AABB-MESH: setup AABB-tree for k-dim. faces. - -------------------------------------------------------- - * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) - * - * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The - * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be - * used at your own risk. - * - -------------------------------------------------------- - * - * Last updated: 11 September, 2017 - * - * Copyright 2013-2017 - * Darren Engwirda - * de2363@columbia.edu - * https://github.com/dengwirda/ - * - -------------------------------------------------------- - */ +/* +------------------------------------------------------------ + * AABB-MESH: setup AABB-tree for k-dim. faces. +------------------------------------------------------------ + * + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) + * + * Disclaimer: Neither I nor: Columbia University, The + * Massachusetts Institute of Technology, The + * University of Sydney, nor The National Aeronautics + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be + * used at your own risk. + * +------------------------------------------------------------ + * + * Last updated: 11 September, 2017 + * + * Copyright 2013-2017 + * Darren Engwirda + * de2363@columbia.edu + * https://github.com/dengwirda/ + * +------------------------------------------------------------ + */ # pragma once @@ -53,18 +53,18 @@ * AABB-MESH: setup AABB-tree for k-dim. faces. -------------------------------------------------------- */ - -# define REAL_TYPE typename node_list \ - ::data_type \ + +# define REAL_TYPE typename tree_type \ + ::item_type \ ::real_type - + # define IPTR_TYPE typename face_list \ ::data_type \ ::iptr_type - + # define FACE_TYPE typename face_list \ ::data_type - + # define TREE_ITEM typename tree_type \ ::item_type @@ -75,30 +75,30 @@ template < typename face_type > - __inline_call + __inline_call bool_type operator() ( face_type const&_fdat ) const - { + { __unreferenced (_fdat) ; - + return ( true ) ; } } ; - - - /* + + + /* -------------------------------------------------------- * AABB-MESH: compute AABB tree for k-face list. -------------------------------------------------------- */ - + template < typename node_list , typename face_list , typename tree_type , typename push_pred = push_aabb , - typename allocator = + typename allocator = allocators::basic_alloc > __normal_call void_type aabb_mesh ( @@ -110,15 +110,15 @@ push_pred _push = push_aabb() ) { - IPTR_TYPE constexpr _nnod = + IPTR_TYPE constexpr _nnod = face_list::data_type::_dims + 1; - IPTR_TYPE constexpr _ndim = + IPTR_TYPE constexpr _ndim = node_list::data_type::_dims + 0; - + containers::block_array < TREE_ITEM, allocator> _bbox; - + /*------------------------- form aabb's for all faces */ IPTR_TYPE _fpos = + 0 ; for (auto _iter = _fset.head() ; @@ -126,7 +126,7 @@ ++_iter, ++_fpos) { if ( !_push(*_iter) ) continue ; - + /*------------------------- calc. current subtree */ REAL_TYPE _xmin[_ndim]; REAL_TYPE _xmax[_ndim]; @@ -134,9 +134,9 @@ /*------------------------- init. aabb at -+ inf. */ for(IPTR_TYPE _idim = _ndim; _idim-- != +0 ; ) { - _xmin[_idim] = + _xmin[_idim] = +std::numeric_limits::infinity(); - _xmax[_idim] = + _xmax[_idim] = -std::numeric_limits::infinity(); } @@ -145,17 +145,17 @@ for(IPTR_TYPE _idim = _ndim; _idim-- != +0 ; ) { IPTR_TYPE _node = _iter->node(_inod) ; - - if (_xmin[_idim] > + + if (_xmin[_idim] > (REAL_TYPE) _nset[_node] .pval (_idim)) { - _xmin[_idim] = + _xmin[_idim] = (REAL_TYPE) _nset[_node] .pval (_idim); } - if (_xmax[_idim] < + if (_xmax[_idim] < (REAL_TYPE) _nset[_node] .pval (_idim)) { - _xmax[_idim] = + _xmax[_idim] = (REAL_TYPE) _nset[_node] .pval (_idim); } } @@ -175,28 +175,28 @@ ->pmin(_idim) = _xmin[_idim] ; _bbox.tail() ->pmax(_idim) = _xmax[_idim] ; - + _bbox.tail() ->ipos() = _fpos ; - } + } } - + /*----------------------------- form tree from aabb's */ _tree.load ( _bbox.head(), _bbox.tend(), _nbox ) ; } - + # undef IPTR_TYPE # undef REAL_TYPE # undef TREE_ITEM # undef FACE_TYPE - - + + } # endif //__AABB_MESH_K__ - - - + + + diff --git a/src/libcpp/aabb_tree/aabb_pred_k.hpp b/src/libcpp/aabb_tree/aabb_pred_k.hpp index b652a8d..56e57a0 100644 --- a/src/libcpp/aabb_tree/aabb_pred_k.hpp +++ b/src/libcpp/aabb_tree/aabb_pred_k.hpp @@ -1,37 +1,37 @@ -/* +/* ------------------------------------------------------------ - * AABB-PRED-K: search pred. for AABB-trees in R^k. + * AABB-PRED-K: search pred. for AABB-trees in R^k. ------------------------------------------------------------ * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * ------------------------------------------------------------ * - * Last updated: 02 March, 2019 + * Last updated: 08 December, 2019 * * Copyright 2013-2019 * Darren Engwirda @@ -47,32 +47,32 @@ # define __AABB_PRED_K__ namespace geom_tree { - - + + template < typename R , - typename I + typename I > class aabb_pred_node_2 { /*---------------------- node-tree intersection predicate */ public : - + typedef R real_type ; typedef I iptr_type ; - + iptr_type static constexpr _dims = 2; private : - + real_type _ppos [ 2] ; public : /*---------------------------------- construct from _src. */ __normal_call aabb_pred_node_2 ( __const_ptr (real_type) _psrc - ) - { + ) + { this->_ppos[0] = _psrc[0]; this->_ppos[1] = _psrc[1]; } @@ -82,7 +82,7 @@ __const_ptr (real_type) _bmin , __const_ptr (real_type) _bmax ) const - { + { /*------------------------------ test if bbox overlap */ if(!geometry::node_rect_2d ( this->_ppos , @@ -96,33 +96,33 @@ return true ; } } - + } ; - + template < typename R , - typename I + typename I > class aabb_pred_node_3 { /*---------------------- node-tree intersection predicate */ public : - + typedef R real_type ; typedef I iptr_type ; - + iptr_type static constexpr _dims = 3; private : - + real_type _ppos [ 3] ; public : /*---------------------------------- construct from _src. */ __normal_call aabb_pred_node_3 ( __const_ptr (real_type) _psrc - ) - { + ) + { this->_ppos[0] = _psrc[0]; this->_ppos[1] = _psrc[1]; this->_ppos[2] = _psrc[2]; @@ -133,7 +133,7 @@ __const_ptr (real_type) _bmin , __const_ptr (real_type) _bmax ) const - { + { /*------------------------------ test if bbox overlap */ if(!geometry::node_rect_3d ( this->_ppos , @@ -147,25 +147,25 @@ return true ; } } - + } ; - + template < typename R , - typename I + typename I > class aabb_pred_rect_2 { /*---------------------- rect-tree intersection predicate */ public : - + typedef R real_type ; typedef I iptr_type ; - + iptr_type static constexpr _dims = 2; private : - + real_type _rmin [ 2] ; real_type _rmax [ 2] ; @@ -174,11 +174,11 @@ __normal_call aabb_pred_rect_2 ( __const_ptr (real_type) _asrc , __const_ptr (real_type) _bsrc - ) - { + ) + { this->_rmin[0] = _asrc[0]; this->_rmin[1] = _asrc[1]; - + this->_rmax[0] = _bsrc[0]; this->_rmax[1] = _bsrc[1]; } @@ -188,7 +188,7 @@ __const_ptr (real_type) _bmin , __const_ptr (real_type) _bmax ) const - { + { /*------------------------------ test if bbox overlap */ if(!geometry::rect_rect_2d ( this->_rmin , @@ -203,25 +203,25 @@ return true ; } } - + } ; - + template < typename R , - typename I + typename I > class aabb_pred_rect_3 { /*---------------------- rect-tree intersection predicate */ public : - + typedef R real_type ; typedef I iptr_type ; - + iptr_type static constexpr _dims = 3; private : - + real_type _rmin [ 3] ; real_type _rmax [ 3] ; @@ -230,12 +230,12 @@ __normal_call aabb_pred_rect_3 ( __const_ptr (real_type) _asrc , __const_ptr (real_type) _bsrc - ) - { + ) + { this->_rmin[0] = _asrc[0]; this->_rmin[1] = _asrc[1]; this->_rmin[2] = _asrc[2]; - + this->_rmax[0] = _bsrc[0]; this->_rmax[1] = _bsrc[1]; this->_rmax[2] = _bsrc[2]; @@ -246,7 +246,7 @@ __const_ptr (real_type) _bmin , __const_ptr (real_type) _bmax ) const - { + { /*------------------------------ test if bbox overlap */ if(!geometry::rect_rect_3d ( this->_rmin , @@ -261,30 +261,30 @@ return true ; } } - + } ; - + template < typename R , - typename I + typename I > class aabb_pred_line_2 { /*---------------------- line-tree intersection predicate */ public : - + typedef R real_type ; typedef I iptr_type ; - + iptr_type static constexpr _dims = 2; private : - + real_type _ipos [ 2] ; real_type _jpos [ 2] ; - real_type _xden [ 2] ; - + real_type _xmul [ 2] ; + real_type _rmin [ 2] ; real_type _rmax [ 2] ; @@ -293,28 +293,28 @@ __normal_call aabb_pred_line_2 ( __const_ptr (real_type) _isrc , __const_ptr (real_type) _jsrc - ) - { + ) + { this->_ipos[0] = _isrc[0]; this->_ipos[1] = _isrc[1]; - + this->_jpos[0] = _jsrc[0]; this->_jpos[1] = _jsrc[1]; - + this->_rmin[0] = std::min( _isrc[0] , _jsrc[0]) ; this->_rmin[1] = std::min( _isrc[1] , _jsrc[1]) ; - + this->_rmax[0] = std::max( _isrc[0] , _jsrc[0]) ; this->_rmax[1] = std::max( _isrc[1] , _jsrc[1]) ; - - this->_xden[0] = _jsrc[0]- - _isrc[0]; - this->_xden[1] = _jsrc[1]- - _isrc[1]; + + this->_xmul[0] = (real_type)1. / + ( _jsrc[0] - _isrc[0]) ; + this->_xmul[1] = (real_type)1. / + ( _jsrc[1] - _isrc[1]) ; } /*---------------------------------- TRUE if intersection */ @@ -322,7 +322,7 @@ __const_ptr (real_type) _bmin , __const_ptr (real_type) _bmax ) const - { + { /*------------------------------ test if bbox overlap */ if(!geometry::rect_rect_2d ( this->_rmin , @@ -330,60 +330,62 @@ _bmin, _bmax)) /*------------------------------ bbox can't intersect */ return false ; - - /*------------------------------ test if line overlap */ + + /*------------------------------ test if line overlap */ real_type _aval, _bval ; _aval = (_bmin[0]-_ipos[0]) - /_xden[0]; + *_xmul[0]; _bval = (_bmax[0]-_ipos[0]) - /_xden[0]; - + *_xmul[0]; + real_type _tmin, _tmax ; - _tmin = + _tmin = std::min( _aval, _bval ) ; - _tmax = + _tmax = std::max( _aval, _bval ) ; - - if (_tmax<_tmin) return false ; - + + if (_tmax<_tmin) return false ; + _aval = (_bmin[1]-_ipos[1]) - /_xden[1]; + *_xmul[1]; _bval = (_bmax[1]-_ipos[1]) - /_xden[1]; - - _tmin = std::max(_tmin, + *_xmul[1]; + + _tmin = std::max(_tmin, std::min( _aval, _bval )) ; - _tmax = std::min(_tmax, + _tmax = std::min(_tmax, std::max( _aval, _bval )) ; - + if (_tmax<_tmin) return false ; - + + if (_tmax< +0.) return false ; + return true ; } - + } ; - + template < typename R , - typename I + typename I > class aabb_pred_line_3 { /*---------------------- line-tree intersection predicate */ public : - + typedef R real_type ; typedef I iptr_type ; - + iptr_type static constexpr _dims = 3; private : - + real_type _ipos [ 3] ; real_type _jpos [ 3] ; - real_type _xden [ 3] ; - + real_type _xmul [ 3] ; + real_type _rmin [ 3] ; real_type _rmax [ 3] ; @@ -392,36 +394,36 @@ __normal_call aabb_pred_line_3 ( __const_ptr (real_type) _isrc , __const_ptr (real_type) _jsrc - ) - { + ) + { this->_ipos[0] = _isrc[0]; this->_ipos[1] = _isrc[1]; this->_ipos[2] = _isrc[2]; - + this->_jpos[0] = _jsrc[0]; this->_jpos[1] = _jsrc[1]; this->_jpos[2] = _jsrc[2]; - + this->_rmin[0] = std::min( _isrc[0] , _jsrc[0]) ; this->_rmin[1] = std::min( _isrc[1] , _jsrc[1]) ; this->_rmin[2] = std::min( _isrc[2] , _jsrc[2]) ; - + this->_rmax[0] = std::max( _isrc[0] , _jsrc[0]) ; this->_rmax[1] = std::max( _isrc[1] , _jsrc[1]) ; this->_rmax[2] = std::max( _isrc[2] , _jsrc[2]) ; - - this->_xden[0] = _jsrc[0]- - _isrc[0]; - this->_xden[1] = _jsrc[1]- - _isrc[1]; - this->_xden[2] = _jsrc[2]- - _isrc[2]; + + this->_xmul[0] = (real_type)1. / + ( _jsrc[0] - _isrc[0]) ; + this->_xmul[1] = (real_type)1. / + ( _jsrc[1] - _isrc[1]) ; + this->_xmul[2] = (real_type)1. / + ( _jsrc[2] - _isrc[2]) ; } /*---------------------------------- TRUE if intersection */ @@ -429,7 +431,7 @@ __const_ptr (real_type) _bmin , __const_ptr (real_type) _bmax ) const - { + { /*------------------------------ test if bbox overlap */ if(!geometry::rect_rect_3d ( this->_rmin , @@ -437,67 +439,69 @@ _bmin, _bmax)) /*------------------------------ bbox can't intersect */ return false ; - - /*------------------------------ test if line overlap */ + + /*------------------------------ test if line overlap */ real_type _aval, _bval ; _aval = (_bmin[0]-_ipos[0]) - /_xden[0]; + *_xmul[0]; _bval = (_bmax[0]-_ipos[0]) - /_xden[0]; - + *_xmul[0]; + real_type _tmin, _tmax ; - _tmin = + _tmin = std::min( _aval, _bval ) ; - _tmax = + _tmax = std::max( _aval, _bval ) ; - - if (_tmax<_tmin) return false ; - + + if (_tmax<_tmin) return false ; + _aval = (_bmin[1]-_ipos[1]) - /_xden[1]; + *_xmul[1]; _bval = (_bmax[1]-_ipos[1]) - /_xden[1]; - - _tmin = std::max(_tmin, + *_xmul[1]; + + _tmin = std::max(_tmin, std::min( _aval, _bval )) ; - _tmax = std::min(_tmax, + _tmax = std::min(_tmax, std::max( _aval, _bval )) ; - + if (_tmax<_tmin) return false ; - + _aval = (_bmin[2]-_ipos[2]) - /_xden[2]; + *_xmul[2]; _bval = (_bmax[2]-_ipos[2]) - /_xden[2]; - - _tmin = std::max(_tmin, + *_xmul[2]; + + _tmin = std::max(_tmin, std::min( _aval, _bval )) ; - _tmax = std::min(_tmax, + _tmax = std::min(_tmax, std::max( _aval, _bval )) ; - + if (_tmax<_tmin) return false ; - + + if (_tmax< +0.) return false ; + return true ; } - + } ; - + template < typename R , - typename I + typename I > class aabb_pred_flat_3 { /*---------------------- flat-tree intersection predicate */ public : - + typedef R real_type ; typedef I iptr_type ; - + iptr_type static constexpr _dims = 3; private : - + real_type _ppos [ 3] ; real_type _vnrm [ 3] ; real_type _vabs [ 3] ; @@ -513,30 +517,30 @@ __const_ptr (real_type) _vsrc , __const_ptr (real_type) _asrc , __const_ptr (real_type) _bsrc - ) - { - this->_dval = + ) + { + this->_dval = geometry::dot_3d(_vsrc, _psrc) ; - + this->_ppos[0] = _psrc[0]; this->_ppos[1] = _psrc[1]; this->_ppos[2] = _psrc[2]; - + this->_vnrm[0] = _vsrc[0]; this->_vnrm[1] = _vsrc[1]; this->_vnrm[2] = _vsrc[2]; - - this->_vabs[0] = + + this->_vabs[0] = std::abs (_vsrc[0]) ; - this->_vabs[1] = + this->_vabs[1] = std::abs (_vsrc[1]) ; - this->_vabs[2] = + this->_vabs[2] = std::abs (_vsrc[2]) ; - + this->_rmin[0] = _asrc[0]; this->_rmin[1] = _asrc[1]; this->_rmin[2] = _asrc[2]; - + this->_rmax[0] = _bsrc[0]; this->_rmax[1] = _bsrc[1]; this->_rmax[2] = _bsrc[2]; @@ -547,19 +551,19 @@ __const_ptr (real_type) _bmin , __const_ptr (real_type) _bmax ) const - { + { /*------------------------------ test if bbox overlap */ if(!geometry::rect_rect_3d ( - this->_rmin , + this->_rmin , this->_rmax , _bmin, _bmax)) /*------------------------------ bbox can't intersect */ return false ; - /*------------------------------ check flat intersect */ + /*------------------------------ check flat intersect */ real_type _bmid[3] = { (real_type) +.5 * _bmin [0] + - (real_type) +.5 * _bmax [0] , + (real_type) +.5 * _bmax [0] , (real_type) +.5 * _bmin [1] + (real_type) +.5 * _bmax [1] , (real_type) +.5 * _bmin [2] + @@ -567,44 +571,44 @@ } ; real_type _blen[3] = { (real_type) +1. * _bmax [0] - - (real_type) +1. * _bmid [0] , + (real_type) +1. * _bmid [0] , (real_type) +1. * _bmax [1] - (real_type) +1. * _bmid [1] , (real_type) +1. * _bmax [2] - (real_type) +1. * _bmid [2] , } ; - - real_type _rval = + + real_type _rval = _blen[0] * this->_vabs [0] + _blen[1] * this->_vabs [1] + _blen[2] * this->_vabs [2] ; - - real_type _sval = - geometry::dot_3d(_vnrm, _bmid) ; - + + real_type _sval = + geometry::dot_3d(_vnrm, _bmid) ; + _sval -= this->_dval; - + return std::abs(_sval)<=_rval; } - + } ; - + template < typename R , - typename I + typename I > class aabb_pred_ball_2 { /*---------------------- ball-tree intersection predicate */ public : - + typedef R real_type ; typedef I iptr_type ; - + iptr_type static constexpr _dims = 2; private : - + real_type _ppos [ 2] ; real_type _rsqr ; @@ -613,12 +617,12 @@ __normal_call aabb_pred_ball_2 ( __const_ptr (real_type) _psrc , real_type _rsrc - ) - { + ) + { this->_ppos[0] = _psrc[0]; this->_ppos[1] = _psrc[1]; - - this->_rsqr = _rsrc * + + this->_rsqr = _rsrc * _rsrc ; } @@ -627,64 +631,64 @@ __const_ptr (real_type) _bmin , __const_ptr (real_type) _bmax ) const - { + { real_type _dsqr = (real_type)+0. ; real_type _diff = (real_type)+0. ; - - /*------------------------------ check ball intersect */ + + /*------------------------------ check ball intersect */ if (this->_ppos[0] < _bmin[0]) { - _diff = _bmin[0] - + _diff = _bmin[0] - this->_ppos[0] ; - + _dsqr += _diff * _diff ; } else if (this->_ppos[0] > _bmax[0]) { - _diff = _bmax[0] - + _diff = _bmax[0] - this->_ppos[0] ; - + _dsqr += _diff * _diff ; } - + if (this->_ppos[1] < _bmin[1]) { - _diff = _bmin[1] - + _diff = _bmin[1] - this->_ppos[1] ; - + _dsqr += _diff * _diff ; } else if (this->_ppos[1] > _bmax[1]) { - _diff = _bmax[1] - + _diff = _bmax[1] - this->_ppos[1] ; - + _dsqr += _diff * _diff ; } - + return _dsqr<= this->_rsqr ; } - + } ; - + template < typename R , - typename I + typename I > class aabb_pred_ball_3 { /*---------------------- ball-tree intersection predicate */ public : - + typedef R real_type ; typedef I iptr_type ; - + iptr_type static constexpr _dims = 3; private : - + real_type _ppos [ 3] ; real_type _rsqr ; @@ -693,13 +697,13 @@ __normal_call aabb_pred_ball_3 ( __const_ptr (real_type) _psrc , real_type _rsrc - ) - { + ) + { this->_ppos[0] = _psrc[0]; this->_ppos[1] = _psrc[1]; this->_ppos[2] = _psrc[2]; - - this->_rsqr = _rsrc * + + this->_rsqr = _rsrc * _rsrc ; } @@ -708,67 +712,67 @@ __const_ptr (real_type) _bmin , __const_ptr (real_type) _bmax ) const - { + { real_type _dsqr = (real_type)+0. ; real_type _diff = (real_type)+0. ; - - /*------------------------------ check ball intersect */ + + /*------------------------------ check ball intersect */ if (this->_ppos[0] < _bmin[0]) { - _diff = _bmin[0] - + _diff = _bmin[0] - this->_ppos[0] ; - + _dsqr += _diff * _diff ; } else if (this->_ppos[0] > _bmax[0]) { - _diff = _bmax[0] - + _diff = _bmax[0] - this->_ppos[0] ; - + _dsqr += _diff * _diff ; } - + if (this->_ppos[1] < _bmin[1]) { - _diff = _bmin[1] - + _diff = _bmin[1] - this->_ppos[1] ; - + _dsqr += _diff * _diff ; } else if (this->_ppos[1] > _bmax[1]) { - _diff = _bmax[1] - + _diff = _bmax[1] - this->_ppos[1] ; - + _dsqr += _diff * _diff ; } - + if (this->_ppos[2] < _bmin[2]) { - _diff = _bmin[2] - + _diff = _bmin[2] - this->_ppos[2] ; - + _dsqr += _diff * _diff ; } else if (this->_ppos[2] > _bmax[2]) { - _diff = _bmax[2] - + _diff = _bmax[2] - this->_ppos[2] ; - + _dsqr += _diff * _diff ; } - + return _dsqr<= this->_rsqr ; } - + } ; - + } - + # endif //__AABB_PRED_K__ diff --git a/src/libcpp/aabb_tree/aabb_tree_k.hpp b/src/libcpp/aabb_tree/aabb_tree_k.hpp index 29874a2..3a393ee 100644 --- a/src/libcpp/aabb_tree/aabb_tree_k.hpp +++ b/src/libcpp/aabb_tree/aabb_tree_k.hpp @@ -1,37 +1,37 @@ -/* +/* ------------------------------------------------------------ - * AABB-TREE-K: AABB-tree construction in R^k. + * AABB-TREE-K: AABB-tree construction in R^k. ------------------------------------------------------------ * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * ------------------------------------------------------------ * - * Last updated: 30 April, 2019 + * Last updated: 10 July, 2019 * * Copyright 2013-2019 * Darren Engwirda @@ -47,7 +47,7 @@ # define __AABB_TREE_K__ namespace geom_tree { - + template < typename I , size_t K , @@ -55,19 +55,19 @@ typename A = allocators::basic_alloc > class aabb_tree - { + { /*---------------------- a static d-dimensional AABB-tree */ public : - + typedef I item_type ; typedef N node_user ; typedef A allocator ; - - typedef typename + + typedef typename item_type::real_type real_type ; - typedef typename + typedef typename item_type::iptr_type iptr_type ; - + iptr_type static constexpr _dims = K * +1 ; typedef geom_tree::aabb_tree < @@ -83,7 +83,7 @@ class node_data ; class node_type : public node_user - { + { /*------------------------------- aabb-tree node type */ public : real_type _pmin[ K] ; @@ -93,9 +93,6 @@ /*------------------------------- tree-based pointers */ node_type *_pptr; node_data *_lptr; - /*------------------------------- marker: search algs */ - iptr_type _mark; - iptr_type _size; /*----------------------------- tree-pointer handlers */ __inline_call item_data* items ( ) const @@ -108,7 +105,7 @@ __inline_call node_type* lower ( iptr_type _ipos ) const - { + { if (this->_lptr != nullptr) /*------------------------------ pointer to child */ return &this->_lptr @@ -119,18 +116,18 @@ } } ; class node_data - { + { /*----------------- keep node-pair together in memory */ public : node_type _node[ 2] ; } ; -/*----------- two-layer pool'd allocator -- items + nodes */ +/*----------- two-layer pool'd allocator -- items + nodes */ typedef allocators::_pool_alloc< allocator> base_pool ; typedef allocators::_wrap_alloc< base_pool> wrap_pool ; - + typedef allocators::_item_alloc< node_data, wrap_pool> node_pool ; @@ -140,7 +137,7 @@ typedef node_type* node_ptrt ; - typedef containers::array < + typedef containers::array < node_ptrt, allocator> work_list ; @@ -155,7 +152,7 @@ /*------------------------------------- pool'd allocators */ base_pool _node_base ; base_pool _item_base ; - + node_pool _node_pool ; item_pool _item_pool ; @@ -163,7 +160,7 @@ iptr_type _imax ; real_type _long ; real_type _vtol ; - + private : /*---------------------- helper - delete a block of nodes */ __inline_call void_type free_node ( @@ -176,13 +173,13 @@ _node_pool.deallocate(_data,1) ; _data = nullptr ; } - + /*---------------------- helper - create a block of nodes */ __inline_call void_type make_node ( node_data*&_data ) { - _data = + _data = this->_node_pool.allocate (1) ; this-> _node_pool.construct (_data) ; @@ -199,15 +196,15 @@ _item_pool.deallocate(_idat,1) ; _idat = nullptr ; } - + /*------------------------------- helper - create an item */ __inline_call void_type make_item ( item_type const&_item, item_data *&_idat ) { - _idat = - this->_item_pool.allocate (1) ; + _idat = + this->_item_pool.allocate (1) ; this->_item_pool.construct( _idat, nullptr, _item); } @@ -222,7 +219,7 @@ _item->_next = _head ; _head = _item ; } - + /*--------------------- helper - _pop an item from a list */ __static_call __inline_call void_type _pop_item ( @@ -235,7 +232,7 @@ { /*---------------------------- re-link in list middle */ _prev-> - _next = _item->_next ; + _next = _item->_next ; } else { @@ -243,12 +240,13 @@ _head = _item->_next ; } } - + public : /*----------------------------------------- default c'tor */ __inline_call aabb_tree ( allocator const&_asrc = allocator() - ) : _root(nullptr) , + ) : _root(nullptr) , + _size( +0) , _work( _asrc) , /*-------------------------------------- "base" pools */ _node_base ( @@ -268,7 +266,7 @@ /*------------- return container count / empty statistics */ __inline_call bool_type empty ( - ) const { return + ) const { return nullptr == this->_root ; } __inline_call iptr_type count ( @@ -280,7 +278,7 @@ node_type *_nptr, node_type *_pptr=nullptr ) - { + { /*------------------------ init nodal aabb at -+ inf. */ for(auto _idim = _dims ; _idim-- != +0; ) { @@ -300,30 +298,30 @@ } } /*------------------ take min/max of item-wise aabb's */ - for(item_data*_iptr = _nptr->_hptr; - _iptr != nullptr; + for(item_data*_iptr = _nptr->_hptr; + _iptr != nullptr; _iptr = _iptr->_next) { for(auto _idim = _dims ; _idim-- != +0; ) { /*------------------------ find max. on each axis */ - if (_nptr->_pmax[_idim] < + if (_nptr->_pmax[_idim] < _iptr->_data.pmax(_idim)) { - _nptr->_pmax[_idim] = + _nptr->_pmax[_idim] = _iptr->_data.pmax(_idim); } /*------------------------ find min. on each axis */ - if (_nptr->_pmin[_idim] > + if (_nptr->_pmin[_idim] > _iptr->_data.pmin(_idim)) { - _nptr->_pmin[_idim] = + _nptr->_pmin[_idim] = _iptr->_data.pmin(_idim); } } } } - + /*------------- helper - calc. best "split" axis for node */ __normal_call void_type find_best_axis ( node_type *_node, @@ -338,58 +336,58 @@ real_type _alen ; iptr_type _axis ; } ; - + class rect_less { /*------------------ helper: sort aabb's by dimension */ public : - __inline_call + __inline_call bool_type operator () ( rect_data const&_xdat , rect_data const&_ydat ) const - { return ( _xdat. _alen < + { return ( _xdat. _alen < _ydat. _alen ) ; } } ; - + /*------------------------------ form aabb dimensions */ - rect_data _rect [_dims]; + rect_data _rect [_dims]; iptr_type _best = 0; for(auto _idim = _dims ; _idim-- != +0; ) { real_type _alen; _alen = _node->_pmax[_idim] - _node->_pmin[_idim]; - + _rect[_idim]._alen = _alen ; - _rect[_idim]._axis = _idim ; + _rect[_idim]._axis = _idim ; } - + /*------------------------------ sort aabb dimensions */ algorithms::ssort ( &_rect[0], &_rect[_dims], rect_less()) ; - + /*------------------------------ scan aabb dimensions */ for(auto _idim = _dims ; _idim-- != +0; ) - { + { iptr_type _axis ; _axis = _rect[_idim]._axis ; - real_type _long ; - _long = _rect[_idim]._alen ; - - _long *= this->_long ; - + real_type _llen ; + _llen = _rect[_idim]._alen ; + + _llen *= this->_long ; + iptr_type _pnum = +0 ; iptr_type _cnum = +0 ; - + /*------------------ partition "long"/inner items */ - for(item_data*_iptr = _node->_hptr; - _iptr != nullptr ; + for(item_data*_iptr = _node->_hptr; + _iptr != nullptr ; _iptr = _iptr->_next) { if (_iptr-> - _data.plen(_axis) >= +_long) + _data.plen(_axis) >= +_llen) { _pnum += +1 ; } @@ -398,19 +396,19 @@ _cnum += +1 ; } } - + /*------------------ keep longest, non-empty dim. */ if (_best < _cnum ) { _best = _cnum ; _bdim = _axis ; - _blen = _long ; - + _blen = _llen ; + if (_pnum == +0) break ; - } + } } } - + /*--- top-down assembly of aabb-tree via recursive splits */ template < typename iter_type @@ -418,19 +416,21 @@ __normal_call void_type load ( iter_type _head , iter_type _tend , - iptr_type _imax = + 32 , - real_type _long = +.75 , - real_type _vtol = +.50 + iptr_type _IMAX = + 32 , + real_type _LONG = +.75 , + real_type _VTOL = +.50 ) { + if (_tend <= _head) return ; + this->_root = &this->_rdat ; this->_size = +1 ; /*------------------------------ set node fill params */ - this->_imax = _imax ; - this->_long = _long ; - this->_vtol = _vtol ; + this->_imax = _IMAX ; + this->_long = _LONG ; + this->_vtol = _VTOL ; /*------------------------------ set null "tree" ptrs */ this->_root->_pptr = nullptr; @@ -441,24 +441,22 @@ item_data *_hptr = nullptr; item_data *_idat = nullptr; { - iptr_type _rsiz = +0 ; - for(; _head != _tend; ++_head, ++_rsiz) + for(; _head != _tend; ++_head) { /*------------------------------ alloc. and push item */ make_item(*_head, _idat); push_item( _hptr, _idat); } this->_root->_hptr = _hptr ; - this->_root->_size = _rsiz ; } - + init_aabb_node (this->_root); - + /*-------------------------- a list of un-split nodes */ this->_work.set_count( +0); this->_work. push_tail(this->_root); - + /*--- refine tree until all nodes satisfy constraints */ for( ; !this->_work.empty() ; ) { @@ -466,33 +464,33 @@ node_data *_ndat = nullptr; node_type *_rnod = nullptr; node_type *_lnod = nullptr; - - real_type _blen ; + + real_type _blen ; iptr_type _bdim = -1 ; iptr_type _pnum = +0 ; iptr_type _cnum = +0 ; iptr_type _lnum = +0 ; iptr_type _rnum = +0 ; - + item_data *_next = nullptr; item_data *_pptr = nullptr; item_data *_cptr = nullptr; item_data *_lptr = nullptr; item_data *_rptr = nullptr; - + /*-------------------------- _pop node from stack */ this->_work._pop_tail(_pnod) ; /*---------- find best "split" axis for this node */ - find_best_axis (_pnod, _bdim , + find_best_axis (_pnod, _bdim , _blen) ; - + if (_bdim == -1) continue ; - + /*---------- partition list - remove "long" items */ for(item_data *_iptr = _pnod-> - _hptr ; - _iptr != nullptr ; + _hptr ; + _iptr != nullptr ; _iptr = _next ) { _next = _iptr->_next ; @@ -505,29 +503,29 @@ } else { - push_item(_cptr,_iptr); + push_item(_cptr,_iptr); _cnum += +1 ; } } - + /*---------- split pos. - mean of non-long aabb's */ real_type _spos = (real_type)+0.; - - for(item_data *_iptr = _cptr ; - _iptr != nullptr ; + + for(item_data *_iptr = _cptr ; + _iptr != nullptr ; _iptr = _next ) { _next = _iptr->_next ; - + _spos +=_iptr-> _data.pmid (_bdim); } - + _spos = _spos / _cnum ; - + /*---------- partition list - split on left|right */ - for(item_data *_iptr = _cptr ; - _iptr != nullptr ; + for(item_data *_iptr = _cptr ; + _iptr != nullptr ; _iptr = _next ) { _next = _iptr->_next ; @@ -535,65 +533,62 @@ if (_iptr->_data .pmid (_bdim) > _spos) { - push_item(_rptr,_iptr); + push_item(_rptr,_iptr); _rnum += +1 ; } else { - push_item(_lptr,_iptr); + push_item(_lptr,_iptr); _lnum += +1 ; } } - + /*-------------------- alloc. new child node data */ make_node(_ndat); _lnod = &_ndat->_node[ 0] ; _rnod = &_ndat->_node[ 1] ; - + this->_size += +2 ; - + _pnod->_hptr = _pptr ; - _pnod->_size = _pnum ; _pnod->_lptr = _ndat ; - + _lnod->_hptr = _lptr ; - _lnod->_size = _lnum ; _lnod->_lptr = nullptr ; _lnod->_pptr = _pnod ; - + _rnod->_hptr = _rptr ; - _rnod->_size = _rnum ; _rnod->_lptr = nullptr ; _rnod->_pptr = _pnod ; - + init_aabb_node (_lnod, _pnod); init_aabb_node (_rnod, _pnod); - + /*------------------ push new children onto stack */ if (_cnum < this->_imax) - { + { real_type _volp, _voll, _volr ; - + _volp = (real_type) +1. ; _voll = (real_type) +1. ; _volr = (real_type) +1. ; - + for (auto _idim = _dims; _idim-- != +0; ) { /*--------------- parent // child (hyper) volumes */ - _volp *= - _pnod->_pmax[_idim] - + _volp *= + _pnod->_pmax[_idim] - _pnod->_pmin[_idim] ; - - _voll *= - _lnod->_pmax[_idim] - + + _voll *= + _lnod->_pmax[_idim] - _lnod->_pmin[_idim] ; - - _volr *= - _rnod->_pmax[_idim] - + + _volr *= + _rnod->_pmax[_idim] - _rnod->_pmin[_idim] ; } - + if (_voll + _volr <= this->_vtol * _volp) { /*--------------- push children due to vol. ratio */ @@ -602,7 +597,7 @@ this->_work .push_tail(_lnod); } - + } else { @@ -610,13 +605,13 @@ this->_work .push_tail(_rnod); this->_work - .push_tail(_lnod); + .push_tail(_lnod); } } - + } - -/*-------- form a biased, spatially-local insertion order */ + +/*-------- form a biased, spatially-local insertion order */ template < typename iptr_list > @@ -624,42 +619,45 @@ iptr_list &_iset ) { - containers::array _next ; - + containers::array _next; + + if (this->_root + == nullptr) return ; + this->_work.set_count( +0) ; this->_work. push_tail(this->_root) ; - + /*---------------------------- init. leading item ptr */ for ( ; !this->_work.empty() ; ) { node_type *_node = nullptr ; this->_work. _pop_tail(_node) ; - + if (_node->items () != nullptr) { _next.push_tail( _node->items () ) ; } - + if (_node->lower(0) != nullptr) { - uint32_t _rsiz = + uint32_t _rsiz = sizeof(real_type) * +K ; - uint32_t _usiz = + uint32_t _usiz = sizeof(uint32_t ) * +1 ; - + uint32_t _hash ; _hash = hash::hashword ( - (uint32_t*)_node->_pmin, + (uint32_t*)_node->_pmin, _rsiz / _usiz, +13) ; - + if (_hash % 2 == +0 ) { this->_work.push_tail ( _node->lower( 0)) ; - + this->_work.push_tail ( _node->lower( 1)) ; } @@ -667,17 +665,17 @@ { this->_work.push_tail ( _node->lower( 1)) ; - + this->_work.push_tail ( _node->lower( 0)) ; } } } - + /*---------------------------- build order from lists */ bool_type _push = true ; - for (auto _imax = +2 ; - _push; _imax *= 4 ) + for (auto _ilim = +2 ; + _push; _ilim *= 4 ) { _push = false; for (auto _iter = _next.head() ; @@ -685,23 +683,23 @@ ++_iter ) { iptr_type _inum = +0 ; - for (auto _ipos = *_iter ; + for (auto _ipos = *_iter ; _ipos != nullptr; _ipos = _ipos->_next ) { _push = true ; - + _iset.push_tail( _ipos->_data.ipos()); - + *_iter = _ipos->_next ; - - if (++_inum>_imax) break; + + if (++_inum>_ilim) break; } } } } - + /*-------- helper: calc. "distance" between pos. and aabb */ __normal_call real_type calc_rect_dist ( real_type *_ppos, @@ -714,26 +712,26 @@ { if (_ppos[_idim] < _bmin[_idim]) { - real_type _dloc = + real_type _dloc = _bmin[_idim] - _ppos[_idim]; - - _dist = + + _dist = std::max (_dist, _dloc); } else if (_ppos[_idim] > _bmax[_idim]) { - real_type _dloc = + real_type _dloc = _ppos[_idim] - _bmax[_idim]; - - _dist = + + _dist = std::max (_dist, _dloc); } } - + return ( _dist * _dist ) ; } - + /*-------- search collection via recursive aabb traversal */ template < typename tree_pred ,// tree intersections @@ -778,7 +776,7 @@ ) this->_work.push_tail ( _node->lower(0)) ; - + if (_pred( _node->lower(1)->_pmin , _node->lower(1)->_pmax ) @@ -787,16 +785,16 @@ _node->lower(1)) ; } } - + return ( _find ) ; } - + /*-------- check for nearsest in collection via traversal */ template < - typename projector - > + typename projector + > __normal_call bool_type near ( - real_type *_ppos , + real_type *_ppos , projector &_proj ) { @@ -807,12 +805,12 @@ real_type _dsqr ; node_type *_node ; } ; - + class node_pred { /*----------------------------- node/dist less for PQ */ public : - __inline_call + __inline_call bool_type operator () ( node_dist const&_adat , node_dist const&_bdat @@ -821,13 +819,13 @@ _bdat. _dsqr ) ; } } ; - + bool_type _find = false; - - if (this->_root + + if (this->_root == nullptr) return _find; - - real_type _dsqr = + + real_type _dsqr = +std::numeric_limits ::infinity() ; @@ -835,15 +833,17 @@ containers::priorityset< node_dist , node_pred > _nnpq ; - + + _nnpq.set_alloc(+64) ; + node_dist _ndat ; _ndat._node = _root ; - _ndat._dsqr = + _ndat._dsqr = calc_rect_dist(_ppos , &_root->_pmin[0], - &_root->_pmax[0]) ; + &_root->_pmax[0]) ; _nnpq.push (_ndat); - + /*----------------- traverse tree while len. reducing */ for ( ; !_nnpq.empty() ; ) { @@ -853,12 +853,12 @@ if (_ndat._dsqr<=_dsqr) { /*------------------------ descend if maybe close */ - + if (_ndat. _node-> _hptr != nullptr) { /*------------------------ leaf: update item-dist */ - _find = true ; + _find = true ; _dsqr = _proj( _ndat._node->_hptr) ; @@ -868,41 +868,41 @@ _node->lower(0) != nullptr) { /*------------------------ traverse into children */ - node_type*_inod = + node_type*_inod = _ndat._node->lower(0) ; - - node_type*_jnod = + + node_type*_jnod = _ndat._node->lower(1) ; - + _ndat._node = _inod ; - _ndat._dsqr = + _ndat._dsqr = calc_rect_dist(_ppos , &_inod->_pmin[ 0], &_inod->_pmax[ 0]) ; _nnpq.push(_ndat) ; - + _ndat._node = _jnod ; - _ndat._dsqr = + _ndat._dsqr = calc_rect_dist(_ppos , &_jnod->_pmin[ 0], &_jnod->_pmax[ 0]) ; - + _nnpq.push(_ndat) ; } - + } } /*---------------------------- must have found a node */ - return ( _find ) ; + return ( _find ) ; } - + } ; - + } - + # endif //__AABB_TREE_K__ diff --git a/src/libcpp/aabb_tree/aabb_type_k.hpp b/src/libcpp/aabb_tree/aabb_type_k.hpp index 5f19665..0c857d1 100644 --- a/src/libcpp/aabb_tree/aabb_type_k.hpp +++ b/src/libcpp/aabb_tree/aabb_type_k.hpp @@ -1,32 +1,32 @@ -/* +/* ------------------------------------------------------------ - * AABB-TYPE-K: data-types for AABB-trees in R^k. + * AABB-TYPE-K: data-types for AABB-trees in R^k. ------------------------------------------------------------ * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * ------------------------------------------------------------ @@ -48,7 +48,7 @@ namespace geom_tree { - + class aabb_node_base_k { /*------------ base-kind for user-defined aabb-node types */ @@ -62,33 +62,33 @@ size_t K > class aabb_item_rect_k - { + { /*------------ k-dim. "rectangle" item type for AABB-tree */ public : - + typedef R real_type; typedef I iptr_type; - + iptr_type static constexpr _dims = K ; - + private : - + iptr_type _ipos ; - + real_type _pmin [ K]; real_type _pmax [ K]; public : /*---------------------------------------- "write" access */ __inline_call real_type& pmin ( - iptr_type _ipos + iptr_type _ppos ) - { return this->_pmin[ _ipos] ; + { return this->_pmin[ _ppos] ; } __inline_call real_type& pmax ( - iptr_type _ipos + iptr_type _ppos ) - { return this->_pmax[ _ipos] ; + { return this->_pmax[ _ppos] ; } __inline_call iptr_type& ipos ( ) @@ -96,14 +96,14 @@ } /*---------------------------------------- "const" access */ __inline_call real_type const& pmin ( - iptr_type _ipos + iptr_type _ppos ) const - { return this->_pmin[ _ipos] ; + { return this->_pmin[ _ppos] ; } __inline_call real_type const& pmax ( - iptr_type _ipos + iptr_type _ppos ) const - { return this->_pmax[ _ipos] ; + { return this->_pmax[ _ppos] ; } __inline_call iptr_type const& ipos ( ) const @@ -111,39 +111,39 @@ } /*--------------------------- calc. centroid, length, etc */ __inline_call real_type pmid ( - iptr_type _ipos + iptr_type _ppos ) const - { return(this->_pmin[ _ipos] + - this->_pmax[ _ipos])* + { return(this->_pmin[ _ppos] + + this->_pmax[ _ppos])* (real_type) +.5 ; } __inline_call real_type plen ( - iptr_type _ipos + iptr_type _ppos ) const - { return this->_pmax[ _ipos] - - this->_pmin[ _ipos] ; + { return this->_pmax[ _ppos] - + this->_pmin[ _ppos] ; } - + } ; - - + + template < typename R, typename I, size_t K > class aabb_item_node_k - { + { /*---------------- k-dim. "point" item type for AABB-tree */ public : - + typedef R real_type; typedef I iptr_type; - + iptr_type static constexpr _dims = K ; - + private : - + iptr_type _ipos ; real_type _pval [ K]; @@ -151,19 +151,19 @@ public : /*---------------------------------------- "write" access */ __inline_call real_type& pval ( - iptr_type _ipos + iptr_type _ppos ) - { return this->_pval[ _ipos] ; + { return this->_pval[ _ppos] ; } __inline_call real_type& pmin ( - iptr_type _ipos + iptr_type _ppos ) - { return this->_pval[ _ipos] ; + { return this->_pval[ _ppos] ; } __inline_call real_type& pmax ( - iptr_type _ipos + iptr_type _ppos ) - { return this->_pval[ _ipos] ; + { return this->_pval[ _ppos] ; } __inline_call iptr_type& ipos ( ) @@ -171,19 +171,19 @@ } /*---------------------------------------- "const" access */ __inline_call real_type const& pval ( - iptr_type _ipos + iptr_type _ppos ) const - { return this->_pval[ _ipos] ; + { return this->_pval[ _ppos] ; } __inline_call real_type const& pmin ( - iptr_type _ipos + iptr_type _ppos ) const - { return this->_pval[ _ipos] ; + { return this->_pval[ _ppos] ; } __inline_call real_type const& pmax ( - iptr_type _ipos + iptr_type _ppos ) const - { return this->_pval[ _ipos] ; + { return this->_pval[ _ppos] ; } __inline_call iptr_type const& ipos ( ) const @@ -191,22 +191,22 @@ } /*--------------------------- calc. centroid, length, etc */ __inline_call real_type const& pmid ( - iptr_type _ipos + iptr_type _ppos ) const - { return this->_pval[ _ipos] ; + { return this->_pval[ _ppos] ; } __inline_call real_type plen ( iptr_type ) const { return (real_type)+0.E+0 ; } - + } ; - - + + } - + # endif //__AABB_TYPE_K__ - - - + + + diff --git a/src/libcpp/aabbtree.hpp b/src/libcpp/aabbtree.hpp index a4d31cd..deac021 100644 --- a/src/libcpp/aabbtree.hpp +++ b/src/libcpp/aabbtree.hpp @@ -1,32 +1,32 @@ -/* +/* ------------------------------------------------------------ - * algorithms for aabb-tree construction in R^d. + * algorithms for aabb-tree construction in R^d. ------------------------------------------------------------ * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * ------------------------------------------------------------ @@ -45,7 +45,7 @@ # ifndef __AABBTREE__ # define __AABBTREE__ - + # include "containers.hpp" # include "aabb_tree/aabb_type_k.hpp" diff --git a/src/libcpp/algorithms.hpp b/src/libcpp/algorithms.hpp index 502d4d9..def461d 100644 --- a/src/libcpp/algorithms.hpp +++ b/src/libcpp/algorithms.hpp @@ -1,58 +1,58 @@ - -/* ------------------------------------------------------------- - * algorithms/operators for container types. ------------------------------------------------------------- - * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) - * - * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The - * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be - * used at your own risk. - * ------------------------------------------------------------- - * - * Last updated: 01 September, 2017 - * - * Copyright 2013-2017 - * Darren Engwirda - * de2363@columbia.edu - * https://github.com/dengwirda/ - * ------------------------------------------------------------- - */ - -# pragma once - -# ifndef __ALGORITHMS__ -# define __ALGORITHMS__ - -# include "libbasic.hpp" - -# include "algorithms/sort.hpp" -# include "algorithms/find.hpp" - - -# endif//__ALGORITHMS__ - - - + +/* +------------------------------------------------------------ + * algorithms/operators for container types. +------------------------------------------------------------ + * + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) + * + * Disclaimer: Neither I nor: Columbia University, The + * Massachusetts Institute of Technology, The + * University of Sydney, nor The National Aeronautics + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be + * used at your own risk. + * +------------------------------------------------------------ + * + * Last updated: 01 September, 2017 + * + * Copyright 2013-2017 + * Darren Engwirda + * de2363@columbia.edu + * https://github.com/dengwirda/ + * +------------------------------------------------------------ + */ + +# pragma once + +# ifndef __ALGORITHMS__ +# define __ALGORITHMS__ + +# include "libbasic.hpp" + +# include "algorithms/sort.hpp" +# include "algorithms/find.hpp" + + +# endif//__ALGORITHMS__ + + + diff --git a/src/libcpp/algorithms/find.hpp b/src/libcpp/algorithms/find.hpp index d488629..7686978 100644 --- a/src/libcpp/algorithms/find.hpp +++ b/src/libcpp/algorithms/find.hpp @@ -1,32 +1,32 @@ - /* + /* -------------------------------------------------------- - * FIND: search-within-sequence algorithms. + * FIND: search-within-sequence algorithms. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- @@ -75,13 +75,13 @@ typename containers:: iterator_traits:: diff_type _step = +0; - + while (_span > +0) { _step = _span / +2; - + _iter = _head + _step; - + if (_less (*_iter, _xval)) { _head = _iter + 1; @@ -91,12 +91,12 @@ { _span = _step + 0; } - + } - - return _head ; + + return _head ; } - + /* -------------------------------------------------------- * UPPER-BOUND: returns uppermost index ">" XVAL. @@ -122,13 +122,13 @@ typename containers:: iterator_traits:: diff_type _step = +0; - + while (_span > +0) { _step = _span / +2; - + _iter = _head + _step; - + if(!_less ( _xval,*_iter)) { _head = _iter + 1; @@ -138,10 +138,10 @@ { _span = _step + 0; } - + } - - return _head ; + + return _head ; } diff --git a/src/libcpp/algorithms/sort.hpp b/src/libcpp/algorithms/sort.hpp index d3822ff..f59d4c9 100644 --- a/src/libcpp/algorithms/sort.hpp +++ b/src/libcpp/algorithms/sort.hpp @@ -1,446 +1,490 @@ - - /* - -------------------------------------------------------- - * SORT: sorting algorithms. - -------------------------------------------------------- - * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) - * - * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The - * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be - * used at your own risk. - * - -------------------------------------------------------- - * - * Last updated: 01 September, 2017 - * - * Copyright 2013-2017 - * Darren Engwirda - * de2363@columbia.edu - * https://github.com/dengwirda/ - * - -------------------------------------------------------- - */ - -# pragma once - -# ifndef __SORT__ -# define __SORT__ - -# include "../containers/iter_base.hpp" - - namespace algorithms { - - /* - -------------------------------------------------------- - * IS-SORTED: returns TRUE if sequence is sorted. - -------------------------------------------------------- - */ - - template < - typename iter_type , - typename pred_type - > - __normal_call bool_type is_sorted ( - iter_type _head , - iter_type _tail , - pred_type _less - ) - { - for ( ; _head+1 != _tail; ++_head ) - { /* check pair ordering */ - if (_less(*(_head+1), *_head)) - { - return ( false ) ; - } - } - - return ( true ) ; - } - - /* - -------------------------------------------------------- - * SORT-N: explicit sort of n-tuples for small n. - -------------------------------------------------------- - */ - - template < - typename iter_type , - typename pred_type - > - __inline_call void_type sort_2 ( // sort 2-tuple - iter_type _ll, - iter_type _rr, - pred_type const&_less - ) - { - if (_less(*_rr, *_ll)) - std::swap(*_ll, *_rr); - } - - template < - typename iter_type , - typename pred_type - > - __inline_call void_type sort_3 ( // sort 3-tuple - iter_type _ll, - iter_type _mm, - iter_type _rr, - pred_type const&_less - ) - { - if (_less(*_mm, *_ll)) - std::swap(*_ll, *_mm); - if (_less(*_rr, *_mm)) - { - std::swap(*_mm, *_rr); - if (_less(*_mm, *_ll)) - std::swap(*_ll, *_mm); - } - } - - /* - -------------------------------------------------------- - * I-SORT: insertion sort. - -------------------------------------------------------- - */ - - template < - typename iter_type , - typename pred_type - > - __normal_call void_type isort ( - iter_type _head, - iter_type _tend, - pred_type _less - ) - { - /*--------------------------- sort small input ranges */ - switch (_tend - _head) - { - /*-------------------------------- quick exit */ - case 0: - case 1: return ; - case 2: - /*-------------------------------- length = 2 */ - { - sort_2(_head+0, _head+1, _less); - return ; - } - case 3: - /*-------------------------------- length = 3 */ - { - sort_3(_head+0, - _head+1, _head+2, _less); - return ; - } - } - - /*-------- scan sequence, find min., swap as sentinel */ - iter_type _mark = _head + 0 ; - for (auto _item = _head + 1 ; - _item != _tend ; ++ _item ) - { - /*-------- _item becomes _mark if new minimum */ - if(_less( *_item,*_mark)) _mark = _item; - } - - if (_mark != _head) - { - /*-------- swap _mark to _head if new minimum */ - std::swap(*_mark, *_head); - } - - /* insertion sort: sift down toward head until sorted */ - for(_head += 2; _head != _tend; ++_head) - { - if (_less( *_head, *(_head-1))) - { - typename containers:: - iterator_traits:: - data_type _temp = - std::move (*_head) ; - - iter_type _item = _head ; - - /*---------- sift pivot into sorted order */ - do - { - *_item = std::move(*(_item-1)) ; - --_item ; - } - while ( _less( _temp, *(_item-1))); - - /*---------- swap pivot into new position */ - *_item = std::move( _temp) ; - } - } - } - - /* - -------------------------------------------------------- - * S-SORT: shell sort. - -------------------------------------------------------- - */ - - template < - typename iter_type , - typename pred_type - > - __normal_call void_type ssort ( - iter_type _head, - iter_type _tend, - pred_type _less - ) - { - /* Niels Pardons, A154393: "Empirically good sequence of - * increments for the shell sort algorithm", 2009, OEIS. - */ - typename containers:: - iterator_traits:: - size_type _finc = _tend - _head; - typename containers:: - iterator_traits:: - size_type _incn = +12 ; - typename containers:: - iterator_traits:: - size_type static constexpr _incv[12] - = { 1, 9, 34, - 182, 836, 4025, - 19001, 90358, 428481, - 2034035, 9651787, 45806244} ; - - /*--------------------------- sort small input ranges */ - switch (_tend - _head) - { - /*-------------------------------- quick exit */ - case 0: - case 1: return ; - case 2: - /*-------------------------------- length = 2 */ - { - sort_2(_head+0, _head+1, _less); - return ; - } - case 3: - /*-------------------------------- length = 3 */ - { - sort_3(_head+0, - _head+1, _head+2, _less); - return ; - } - } - - /* insertion sort: sift down toward head until sorted */ - for ( ; _incn != 0 ; --_incn) - { - if (_finc <= _incv[_incn-1]) continue; - - /* just a pass of insertion sort with stride ival */ - typename containers:: - iterator_traits:: - data_type _temp ; - typename containers:: - iterator_traits:: - size_type _ival ; - - _ival = _incv[_incn - 1]; - - iter_type _ipos =_head + _ival ; - iter_type _iend =_head + _ival ; - iter_type _item ; - for ( ; _ipos < _tend; ++_ipos ) - { - if (_less(*_ipos,*(_ipos-_ival))) - { - _temp = std::move(*_ipos) ; - _item = _ipos ; - /*---------- sift pivot into sorted order */ - do - { - *_item = std::move(*(_item-_ival)) ; - } - while ((_item-=_ival) >= _iend && - _less( _temp, *( _item-_ival))); - - /*---------- swap pivot into new position */ - *_item = std::move(_temp) ; - } - } - } - - } - - /* - -------------------------------------------------------- - * Q-SORT: quick sort. - -------------------------------------------------------- - */ - - template < - typename iter_type , - typename pred_type - > - __inline_call iter_type pivot ( // pivot selection - iter_type _head, - iter_type _tail, - pred_type const&_less - ) - { - typename containers:: - iterator_traits:: - diff_type static constexpr _LONG = 256; - - iter_type _imid = - _head + (_tail - _head) / 2 ; - - if (_tail - _head >= _LONG) - { - /*-------------- median-of-5 choice for pivot element */ - typename containers:: - iterator_traits:: - size_type _step = - (_tail - _head) / 4; - - iter_type _pos1 = - _head + _step * 1 ; - iter_type _pos3 = - _head + _step * 3 ; - - sort_3(_head, _pos1, _imid, _less); - sort_3(_imid, _pos3, _tail, _less); - sort_3(_pos1, _imid, _pos3, _less); - } - else - { - /*-------------- median-of-3 choice for pivot element */ - sort_3(_head, _imid, _tail, _less); - } - - return ( _imid ) ; - } - - template < - typename iter_type , - typename pred_type - > - __normal_call void_type qsort ( // unrolled quick sort - iter_type _head, - iter_type _tend, - pred_type _less - ) - { - typedef containers:: - iterator_traits iter_base ; - - /*------- tiny-list threshold, push to insertion sort */ - typename iter_base:: - diff_type static constexpr _LONG = 16; - - /*------- stack max depth = log2(maxint/sizeof(data)) */ - typename iter_base:: - size_type static constexpr _DEEP = - 8 * sizeof(typename iter_base::size_type); - - class node_type - { - public : - iter_type _obj[2] ; - public : - __inline_call void push ( - iter_type _ll , - iter_type _rr - ) - { _obj[0] = _ll ; - _obj[1] = _rr ; - } - __inline_call void _pop ( - iter_type &_ll, - iter_type &_rr - ) - { _ll = _obj [0] ; - _rr = _obj [1] ; - } - } ; - - node_type _node[_DEEP], *_nptr =_node ; - - _nptr->push( _head, _tend-1); ++_nptr ; - - /*------------ non-recursive quicksort implementation */ - do - { - iter_type _hh, _tt, _mm; - /* _pop next partition bounds from stack */ - ( --_nptr)->_pop(_hh, _tt); - if (_tt - _hh + 1 < _LONG) - { /* leave small partitions */ - continue ; - } - /* find pivot item for current partition */ - _mm = pivot(_hh, _tt, _less); - /* push pivot onto a local copy */ - typename - iter_base::data_type _pp = *_mm; - /* reduce partition around pivot element */ - iter_type _ll = _hh + 1; - iter_type _rr = _tt - 1; - for ( ; _ll < _rr; ) - { - for(;_less(*_ll, _pp);) ++_ll; - for(;_less( _pp, *_rr);) --_rr; - - if (_ll < _rr) - { /* swap elements */ - std::swap(*_ll, - *_rr) ; - } - if (_ll <= _rr) - { /* shrink bounds */ - ++_ll; --_rr ; - } - } - /* push partitions onto stack, big first */ - if (_rr - _hh > _tt - _ll) - { - _nptr->push(_hh, _rr); ++_nptr; - _nptr->push(_ll, _tt); ++_nptr; - } - else - { - _nptr->push(_ll, _tt); ++_nptr; - _nptr->push(_hh, _rr); ++_nptr; - } - } - while (_nptr !=_node) ; - - /*------- sort remaining sequences via insertion sort */ - isort (_head , _tend, _less) ; - } - - - } - -# endif //__SORT__ - - - + + /* + -------------------------------------------------------- + * SORT: sorting algorithms. + -------------------------------------------------------- + * + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) + * + * Disclaimer: Neither I nor: Columbia University, The + * Massachusetts Institute of Technology, The + * University of Sydney, nor The National Aeronautics + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be + * used at your own risk. + * + -------------------------------------------------------- + * + * Last updated: 24 July, 2019 + * + * Copyright 2013-2019 + * Darren Engwirda + * de2363@columbia.edu + * https://github.com/dengwirda/ + * + -------------------------------------------------------- + */ + +# pragma once + +# ifndef __SORT__ +# define __SORT__ + +# include "../containers/iter_base.hpp" + + namespace algorithms { + + /* + -------------------------------------------------------- + * IS-SORTED: returns TRUE if sequence is sorted. + -------------------------------------------------------- + */ + + template < + typename iter_type , + typename pred_type + > + __normal_call bool_type is_sorted ( + iter_type _head , + iter_type _tail , + pred_type _less + ) + { + for ( ; _head+1 != _tail; ++_head ) + { /* check pair ordering */ + if (_less(*(_head+1), *_head)) + { + return ( false ) ; + } + } + + return ( true ) ; + } + + /* + -------------------------------------------------------- + * SORT-N: explicit sort of n-tuples for small n. + -------------------------------------------------------- + */ + + template < + typename iter_type , + typename pred_type + > + __inline_call void_type sort_2 ( // sort 2-tuple + iter_type _aa, + iter_type _bb, + pred_type const&_less + ) + { + if (_less(*_bb, *_aa)) + std::swap(*_aa, *_bb); + } + + template < + typename iter_type , + typename pred_type + > + __inline_call void_type sort_3 ( // sort 3-tuple + iter_type _aa, + iter_type _bb, + iter_type _cc, + pred_type const&_less + ) + { + if (_less(*_bb, *_aa)) + std::swap(*_aa, *_bb); + + if (_less(*_cc, *_bb)) + { + std::swap(*_bb, *_cc); + + if (_less(*_bb, *_aa)) + std::swap(*_aa, *_bb); + } + } + + template < + typename iter_type , + typename pred_type + > + __inline_call void_type sort_4 ( // sort 4-tuple + iter_type _aa, + iter_type _bb, + iter_type _cc, + iter_type _dd, + pred_type const&_less + ) + { + if (_less(*_bb, *_aa)) + std::swap(*_aa, *_bb); + + if (_less(*_dd, *_cc)) + std::swap(*_cc, *_dd); + + if (_less(*_cc, *_aa)) + std::swap(*_aa, *_cc); + + if (_less(*_dd, *_bb)) + std::swap(*_bb, *_dd); + + if (_less(*_cc, *_bb)) + std::swap(*_bb, *_cc); + } + + /* + -------------------------------------------------------- + * I-SORT: insertion sort. + -------------------------------------------------------- + */ + + template < + typename iter_type , + typename pred_type + > + __normal_call void_type isort ( + iter_type _head, + iter_type _tend, + pred_type _less + ) + { + /*--------------------------- sort small input ranges */ + switch (_tend - _head) + { + /*-------------------------------- quick exit */ + case 0: + case 1: return ; + case 2: + /*-------------------------------- length = 2 */ + { + sort_2(_head+0, _head+1, _less); + return ; + } + case 3: + /*-------------------------------- length = 3 */ + { + sort_3(_head+0, + _head+1, _head+2, _less); + return ; + } + case 4: + /*-------------------------------- length = 4 */ + { + sort_4(_head+0, _head+1, + _head+2, _head+3, _less); + return ; + } + } + + /*-------- scan sequence, find min., swap as sentinel */ + iter_type _mark = _head + 0 ; + for (auto _item = _head + 1 ; + _item != _tend ; ++ _item ) + { + /*-------- _item becomes _mark if new minimum */ + if(_less( *_item,*_mark)) _mark = _item; + } + + if (_mark != _head) + { + /*-------- swap _mark to _head if new minimum */ + std::swap(*_mark, *_head); + } + + /* insertion sort: sift down toward head until sorted */ + for(_head += 2; _head != _tend; ++_head) + { + if (_less( *_head, *(_head-1))) + { + typename containers:: + iterator_traits:: + data_type _temp = + std::move (*_head) ; + + iter_type _item = _head ; + + /*---------- sift pivot into sorted order */ + do + { + *_item = std::move(*(_item-1)) ; + --_item ; + } + while ( _less( _temp, *(_item-1))); + + /*---------- swap pivot into new position */ + *_item = std::move( _temp) ; + } + } + } + + /* + -------------------------------------------------------- + * S-SORT: shell sort. + -------------------------------------------------------- + */ + + template < + typename iter_type , + typename pred_type + > + __normal_call void_type ssort ( + iter_type _head, + iter_type _tend, + pred_type _less + ) + { + /*--------------------------- sort small input ranges */ + switch (_tend - _head) + { + /*-------------------------------- quick exit */ + case 0: + case 1: return ; + case 2: + /*-------------------------------- length = 2 */ + { + sort_2(_head+0, _head+1, _less); + return ; + } + case 3: + /*-------------------------------- length = 3 */ + { + sort_3(_head+0, + _head+1, _head+2, _less); + return ; + } + case 4: + /*-------------------------------- length = 4 */ + { + sort_4(_head+0, _head+1, + _head+2, _head+3, _less); + return ; + } + } + + /* Niels Pardons, A154393: "Empirically good sequence of + * increments for the shell sort algorithm", 2009, OEIS. + */ + typename containers:: + iterator_traits:: + size_type _finc = _tend - _head; + typename containers:: + iterator_traits:: + size_type _incn = +12 ; + typename containers:: + iterator_traits:: + size_type static constexpr _incv[12] + = { 1, 9, 34, + 182, 836, 4025, + 19001, 90358, 428481, + 2034035, 9651787, 45806244} ; + + /* insertion sort: sift down toward head until sorted */ + for ( ; _incn != 0 ; --_incn) + { + if (_finc <= _incv[_incn-1]) continue; + + /* just a pass of insertion sort with stride ival */ + typename containers:: + iterator_traits:: + data_type _temp ; + typename containers:: + iterator_traits:: + size_type _ival ; + + _ival = _incv[_incn - 1]; + + iter_type _ipos =_head + _ival ; + iter_type _iend =_head + _ival ; + iter_type _item ; + for ( ; _ipos < _tend; ++_ipos ) + { + if (_less(*_ipos,*(_ipos-_ival))) + { + _temp = std::move(*_ipos) ; + _item = _ipos ; + /*---------- sift pivot into sorted order */ + do + { + *_item = std::move(*(_item-_ival)) ; + } + while ((_item-=_ival) >= _iend && + _less( _temp, *( _item-_ival))); + + /*---------- swap pivot into new position */ + *_item = std::move(_temp) ; + } + } + } + + } + + /* + -------------------------------------------------------- + * Q-SORT: quick sort. + -------------------------------------------------------- + */ + + template < + typename iter_type , + typename pred_type + > + __inline_call iter_type pivot ( // pivot selection + iter_type _head, + iter_type _tail, + pred_type const&_less + ) + { + typename containers:: + iterator_traits:: + diff_type static constexpr _LONG = 256; + + iter_type _imid = + _head + (_tail - _head) / 2 ; + + if (_tail - _head >= _LONG) + { + /*-------------- median-of-5 choice for pivot element */ + typename containers:: + iterator_traits:: + size_type _step = + (_tail - _head) / 4; + + iter_type _pos1 = + _head + _step * 1 ; + iter_type _pos3 = + _head + _step * 3 ; + + sort_3(_head, _pos1, _imid, _less); + sort_3(_imid, _pos3, _tail, _less); + sort_3(_pos1, _imid, _pos3, _less); + } + else + { + /*-------------- median-of-3 choice for pivot element */ + sort_3(_head, _imid, _tail, _less); + } + + return ( _imid ) ; + } + + template < + typename iter_type , + typename pred_type + > + __normal_call void_type qsort ( // unrolled quick sort + iter_type _head, + iter_type _tend, + pred_type _less + ) + { + typedef containers:: + iterator_traits iter_base ; + + /*------- tiny-list threshold, push to insertion sort */ + typename iter_base:: + diff_type static constexpr _LONG = 16; + + /*------- stack max depth = log2(maxint/sizeof(data)) */ + typename iter_base:: + size_type static constexpr _DEEP = + 8 * sizeof(typename iter_base::size_type); + + class node_type + { + public : + iter_type _obj[2] ; + public : + __inline_call void push ( + iter_type _ll , + iter_type _rr + ) + { _obj[0] = _ll ; + _obj[1] = _rr ; + } + __inline_call void _pop ( + iter_type &_ll, + iter_type &_rr + ) + { _ll = _obj [0] ; + _rr = _obj [1] ; + } + } ; + + node_type _node[_DEEP], *_nptr =_node ; + + _nptr->push( _head, _tend-1); ++_nptr ; + + /*------------ non-recursive quicksort implementation */ + do + { + iter_type _hh, _tt, _mm; + /* _pop next partition bounds from stack */ + ( --_nptr)->_pop(_hh, _tt); + if (_tt - _hh + 1 < _LONG) + { /* leave small partitions */ + continue ; + } + /* find pivot item for current partition */ + _mm = pivot(_hh, _tt, _less); + /* push pivot onto a local copy */ + typename + iter_base::data_type _pp = *_mm; + /* reduce partition around pivot element */ + iter_type _ll = _hh + 1; + iter_type _rr = _tt - 1; + for ( ; _ll < _rr; ) + { + for(;_less(*_ll, _pp);) ++_ll; + for(;_less( _pp, *_rr);) --_rr; + + if (_ll < _rr) + { /* swap elements */ + std::swap(*_ll, + *_rr) ; + } + if (_ll <= _rr) + { /* shrink bounds */ + ++_ll; --_rr ; + } + } + /* push partitions onto stack, big first */ + if (_rr - _hh > _tt - _ll) + { + _nptr->push(_hh, _rr); ++_nptr; + _nptr->push(_ll, _tt); ++_nptr; + } + else + { + _nptr->push(_ll, _tt); ++_nptr; + _nptr->push(_hh, _rr); ++_nptr; + } + } + while (_nptr !=_node) ; + + /*------- sort remaining sequences via insertion sort */ + isort (_head , _tend, _less) ; + } + + + } + +# endif //__SORT__ + + + diff --git a/src/libcpp/allocators.hpp b/src/libcpp/allocators.hpp index cb7ae92..55a5298 100644 --- a/src/libcpp/allocators.hpp +++ b/src/libcpp/allocators.hpp @@ -1,61 +1,61 @@ - -/* ------------------------------------------------------------- - * basic allocators, a bit different from std::lib... ------------------------------------------------------------- - * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) - * - * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The - * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be - * used at your own risk. - * ------------------------------------------------------------- - * - * Last updated: 02 May, 2017 - * - * Copyright 2013-2017 - * Darren Engwirda - * de2363@columbia.edu - * https://github.com/dengwirda/ - * ------------------------------------------------------------- - */ - -# pragma once - -# ifndef __ALLOCATORS__ -# define __ALLOCATORS__ - -# include "libbasic.hpp" - -# include "allocators/alloc_base.hpp" -# include "allocators/alloc_pool.hpp" -# include "allocators/alloc_wrap.hpp" - -# include "allocators/alloc_item.hpp" - - -# endif//__ALLOCATORS__ - - - + +/* +------------------------------------------------------------ + * basic allocators, a bit different from std::lib... +------------------------------------------------------------ + * + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) + * + * Disclaimer: Neither I nor: Columbia University, The + * Massachusetts Institute of Technology, The + * University of Sydney, nor The National Aeronautics + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be + * used at your own risk. + * +------------------------------------------------------------ + * + * Last updated: 02 May, 2017 + * + * Copyright 2013-2017 + * Darren Engwirda + * de2363@columbia.edu + * https://github.com/dengwirda/ + * +------------------------------------------------------------ + */ + +# pragma once + +# ifndef __ALLOCATORS__ +# define __ALLOCATORS__ + +# include "libbasic.hpp" + +# include "allocators/alloc_base.hpp" +# include "allocators/alloc_pool.hpp" +# include "allocators/alloc_wrap.hpp" + +# include "allocators/alloc_item.hpp" + + +# endif//__ALLOCATORS__ + + + diff --git a/src/libcpp/allocators/alloc_base.hpp b/src/libcpp/allocators/alloc_base.hpp index 5cc9231..52eb264 100644 --- a/src/libcpp/allocators/alloc_base.hpp +++ b/src/libcpp/allocators/alloc_base.hpp @@ -1,39 +1,39 @@ - /* + /* -------------------------------------------------------- * basic allocator -- wrap "malloc" and friends. -------------------------------------------------------- * * BASIC-ALLOC is a simple wrapper for "c"-style alloc. * via malloc and friends, intended to expose "realloc" - * for c++ containers. This class deals only with bytes + * for c++ containers. This class deals only with bytes * see _ITEM-ALLOC for the treatment of non-POD objects - * + * -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- @@ -63,27 +63,27 @@ { /*-------- raw byte allocator: wrap malloc, realloc, free */ public : - + typedef std::ptrdiff_t diff_type; typedef std::size_t size_type; typedef basic_alloc self_type; public : - + /* -------------------------------------------------------- * ALLOCATE: do buffer allocation. -------------------------------------------------------- */ - + __static_call __inline_call char_type* allocate ( size_type _new_count ) - { + { /*---------------------- delegate to malloc & friends */ - char_type* _addr = + char_type* _addr = (char_type*)std::malloc(_new_count) ; /*------------------------------ throw on alloc fails */ @@ -94,51 +94,51 @@ /*------------------------------ return memory buffer */ return ( _addr ) ; } - + /* -------------------------------------------------------- * REALLOCATE: re-allocate buffer. -------------------------------------------------------- */ - + __static_call __inline_call char_type* reallocate ( char_type*_addr , size_type _old_count, size_type _new_count ) - { + { __unreferenced(_old_count) ; /*---------------------- delegate to malloc & friends */ - char_type* _nptr = + char_type* _nptr = (char_type*)std::realloc(_addr,_new_count) ; /*------------------------------ throw on alloc fails */ if ( _new_count != +0 && nullptr == _nptr ) throw std::bad_alloc (); - + /*------------------------------ return memory buffer */ return ( _nptr ) ; } - + /* -------------------------------------------------------- * DEALLOCATE: de-allocate buffer. -------------------------------------------------------- */ - + __static_call __inline_call void_type deallocate ( char_type*_addr , size_type _old_count ) - { + { __unreferenced(_old_count); /*---------------------- delegate to malloc & friends */ - if (nullptr != _addr) + if (nullptr != _addr) std::free( _addr) ; } diff --git a/src/libcpp/allocators/alloc_item.hpp b/src/libcpp/allocators/alloc_item.hpp index e164b2b..1ff2744 100644 --- a/src/libcpp/allocators/alloc_item.hpp +++ b/src/libcpp/allocators/alloc_item.hpp @@ -1,39 +1,39 @@ - /* + /* -------------------------------------------------------- * "item" allocator -- for general obj. types. -------------------------------------------------------- * - * _ITEM-ALLOC provides a "realloc"-able c++ allocator, + * _ITEM-ALLOC provides a "realloc"-able c++ allocator, * disambiguating between POD and non-POD object types. - * Only POD types benefit from calls through to realloc + * Only POD types benefit from calls through to realloc * non-trivial objects induce alloc/copy/free patterns. * -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- @@ -56,23 +56,23 @@ # include namespace allocators { - - + + template < - typename D , + typename D , typename A - > + > class obj_alloc : public A - { + { /*---------------- typed allocator wrapper for obj. types */ public : - + typedef D data_type ; typedef A allocator ; - typedef typename + typedef typename allocator::size_type size_type ; - typedef typename + typedef typename allocator::diff_type diff_type ; typedef obj_alloc < @@ -80,13 +80,13 @@ allocator > self_type ; public : - + /* -------------------------------------------------------- * OBJ_ALLOC: construct allocator for ITEM obj. -------------------------------------------------------- */ - + __inline_call obj_alloc ( allocator const&_asrc = allocator() ) : allocator( _asrc ) @@ -94,21 +94,21 @@ } __inline_call~obj_alloc () = default; - + __inline_call obj_alloc ( - self_type const& _src + self_type const& _src ) = default; __inline_call obj_alloc ( - self_type && _src + self_type && _src ) = default; - __inline_call + __inline_call self_type& operator = ( - self_type const& _src + self_type const& _src ) = default; - __inline_call + __inline_call self_type& operator = ( - self_type && _src + self_type && _src ) = default; /* @@ -116,20 +116,20 @@ * ALLOCATE: do obj. buffer allocation. -------------------------------------------------------- */ - + __inline_call data_type* allocate ( size_type _new_count ) { return (data_type*)allocator::allocate ( _new_count * sizeof(data_type)); } - + /* -------------------------------------------------------- * REALLOCATE: re-allocate obj. buffer. -------------------------------------------------------- */ - + __inline_call data_type* reallocate ( data_type*_addr, size_type _old_alloc , @@ -138,110 +138,110 @@ ) { /*------------------------- allocate a new raw buffer */ - data_type *_rptr = + data_type *_rptr = (data_type *)allocator:: allocate ( _new_alloc * sizeof(data_type)) ; - + /*------- copy objects to new buffer, free old buffer */ if (_addr != nullptr) { - __write_ptr(data_type) _head = _addr ; - __write_ptr(data_type) _tail ; + __write_ptr(data_type) _head = _addr ; + __write_ptr(data_type) _tail ; __write_ptr(data_type) _item = _rptr ; - + /*--- number of ctor'd items to be moved to _rptr */ size_type _new_count = std::min ( _old_count, _new_alloc); - + /*-------------------- move items between buffers */ _tail = _addr + _new_count; - for ( ; _head != _tail; ++_head, - ++_item) - { + for ( ; _head != _tail; ++_head, + ++_item) + { /*--------- move ctor'd items from _addr to _rptr */ construct(_item, std::move(*_head)) ; _destruct(_head) ; } _tail = _addr + _old_count; - for ( ; _head != _tail; ++_head) - { + for ( ; _head != _tail; ++_head) + { /*-------- _destruct all remaining items in _addr */ _destruct(_head) ; } - - allocator:: deallocate((char_type*)_addr, + + allocator:: deallocate((char_type*)_addr, _old_alloc * sizeof(data_type)) ; } - + return ( _rptr ) ; } - + /* -------------------------------------------------------- * DEALLOCATE: de-allocate obj. buffer. -------------------------------------------------------- */ - + __inline_call void_type deallocate ( data_type*_addr, size_type _old_alloc ) - { + { /*----------------------------- free non-null buffers */ if (_addr != nullptr) allocator::deallocate ( - (char_type*)_addr , + (char_type*)_addr , _old_alloc * sizeof(data_type)) ; } - - + + /* -------------------------------------------------------- * _DESTRUCT: destory allocated object. -------------------------------------------------------- */ - + __static_call __inline_call void_type _destruct ( data_type* _xptr - ) - { + ) + { __unreferenced(_xptr); - - _xptr->~data_type () ; + + _xptr->~data_type () ; } - + /* -------------------------------------------------------- * CONSTRUCT: regular object construction. -------------------------------------------------------- */ - + __static_call __inline_call void_type construct ( // _def c'tor obj. data_type* _xptr - ) - { new(_xptr) data_type ; + ) + { new(_xptr) data_type ; } - + __static_call __inline_call void_type construct ( // copy c'tor obj. data_type* _xptr, data_type const&_xval - ) + ) { new( _xptr)data_type ( __copy(data_type, _xval)) ; } - + __static_call __inline_call void_type construct ( // move c'tor obj. data_type* _xptr, data_type&&_xval - ) + ) { new( _xptr)data_type ( __move(data_type, _xval)) ; } - + template < typename... data_part > @@ -252,25 +252,25 @@ ) { new(_xptr)data_type(_part...) ; } - + } ; - - + + template < - typename D , - typename A - > + typename D , + typename A + > class pod_alloc : public A - { + { /*---------------------- buffer allocator for "pod" types */ public : - + typedef D data_type ; typedef A allocator ; - typedef typename + typedef typename allocator::size_type size_type ; - typedef typename + typedef typename allocator::diff_type diff_type ; typedef pod_alloc < @@ -278,13 +278,13 @@ allocator > self_type ; public : - + /* -------------------------------------------------------- * POD_ALLOC: construct allocator for POD. obj. -------------------------------------------------------- */ - + __inline_call pod_alloc ( allocator const&_asrc = allocator() ) : allocator( _asrc ) @@ -292,21 +292,21 @@ } __inline_call~pod_alloc () = default; - + __inline_call pod_alloc ( - self_type const& _src + self_type const& _src ) = default; __inline_call pod_alloc ( - self_type && _src + self_type && _src ) = default; - __inline_call + __inline_call self_type& operator = ( - self_type const& _src + self_type const& _src ) = default; - __inline_call + __inline_call self_type& operator = ( - self_type && _src + self_type && _src ) = default; /* @@ -314,75 +314,75 @@ * ALLOCATE: do obj. buffer allocation. -------------------------------------------------------- */ - + __inline_call data_type* allocate ( size_type _new_alloc ) { return (data_type *)allocator:: allocate ( _new_alloc * sizeof(data_type)) ; } - + /* -------------------------------------------------------- * REALLOCATE: re-allocate obj. buffer. -------------------------------------------------------- */ - + __inline_call data_type* reallocate ( data_type*_addr, size_type _old_alloc, size_type _new_alloc, - size_type + size_type ) { return (data_type *)allocator::reallocate ( (char_type *)_addr , _old_alloc * sizeof(data_type), - _new_alloc * sizeof(data_type)) ; + _new_alloc * sizeof(data_type)) ; } - + /* -------------------------------------------------------- * DEALLOCATE: de-allocate obj. buffer. -------------------------------------------------------- */ - + __inline_call void_type deallocate ( data_type*_addr, size_type _old_alloc ) - { if (_addr != nullptr) - allocator:: deallocate((char_type*) _addr , + { if (_addr != nullptr) + allocator:: deallocate((char_type*) _addr , _old_alloc * sizeof(data_type)) ; } - + /* -------------------------------------------------------- * _DESTRUCT: destory allocated object. -------------------------------------------------------- */ - + __static_call __inline_call void_type _destruct ( data_type* ) { /* do nothing */ } - + /* -------------------------------------------------------- * CONSTRUCT: regular object construction. -------------------------------------------------------- */ - + __static_call __inline_call void_type construct ( // _def c'tor obj. __write_ptr (data_type) ) {/* do nothing */} - + __static_call __inline_call void_type construct ( // copy c'tor obj. __write_ptr (data_type) _xptr, data_type const&_xval ) { *_xptr = _xval ; } - + __static_call __inline_call void_type construct ( // move c'tor obj. __write_ptr (data_type) _xptr, @@ -399,25 +399,25 @@ ) { new(_xptr)data_type(_part...) ; } - + } ; template < - typename D , - typename A , - bool F + typename D , + typename A , + bool F > class loc_alloc : public obj_alloc - { + { /*----- specialisation to derive from _POD if flag = TRUE */ public : - + typedef D data_type ; typedef A allocator ; typedef obj_alloc < - data_type , + data_type , allocator > base_type ; typedef loc_alloc < @@ -431,7 +431,7 @@ * LOC_ALLOC: construct obj. from _ASRC. -------------------------------------------------------- */ - + __inline_call loc_alloc ( allocator const&_asrc = allocator() ) : base_type( _asrc ) @@ -439,46 +439,46 @@ } __inline_call~loc_alloc () = default; - + __inline_call loc_alloc ( - self_type const& _src + self_type const& _src ) = default; __inline_call loc_alloc ( - self_type && _src + self_type && _src ) = default; - __inline_call + __inline_call self_type& operator = ( - self_type const& _src + self_type const& _src ) = default; - __inline_call + __inline_call self_type& operator = ( - self_type && _src + self_type && _src ) = default; } ; - + template < - typename D , + typename D , typename A > - class loc_alloc : + class loc_alloc : public pod_alloc { /*----- specialisation to derive from _POD if flag = TRUE */ public : - + typedef D data_type ; typedef A allocator ; typedef pod_alloc < - data_type , + data_type , allocator > base_type ; typedef loc_alloc < data_type , - allocator , + allocator , true > self_type ; public : @@ -496,44 +496,44 @@ } __inline_call~loc_alloc () = default; - + __inline_call loc_alloc ( - self_type const& _src + self_type const& _src ) = default; __inline_call loc_alloc ( - self_type && _src + self_type && _src ) = default; - __inline_call + __inline_call self_type& operator = ( - self_type const& _src + self_type const& _src ) = default; - __inline_call + __inline_call self_type& operator = ( - self_type && _src + self_type && _src ) = default; } ; - - + + template < - typename D , + typename D , typename A = basic_alloc > class _item_alloc : public loc_alloc < - D , A , + D , A , std::is_trivially_copyable ::value > - { + { /*-------------- type-aware item alloc - public interface */ public : - + typedef D data_type ; typedef A allocator ; typedef loc_alloc < - data_type , - allocator , - std::is_trivially_copyable ::value > + data_type , + allocator , + std::is_trivially_copyable ::value > base_type ; typedef _item_alloc < @@ -555,26 +555,26 @@ } __inline_call~_item_alloc () = default; - + __inline_call _item_alloc ( - self_type const& _src + self_type const& _src ) = default; __inline_call _item_alloc ( - self_type && _src + self_type && _src ) = default; - __inline_call + __inline_call self_type& operator = ( - self_type const& _src + self_type const& _src ) = default; - __inline_call + __inline_call self_type& operator = ( - self_type && _src + self_type && _src ) = default; } ; - + } # endif //__ALLOC_ITEM__ diff --git a/src/libcpp/allocators/alloc_pool.hpp b/src/libcpp/allocators/alloc_pool.hpp index 652a35a..7708ffd 100644 --- a/src/libcpp/allocators/alloc_pool.hpp +++ b/src/libcpp/allocators/alloc_pool.hpp @@ -1,42 +1,42 @@ - /* + /* -------------------------------------------------------- * "pool'd" allocator -- "node"-based containers... -------------------------------------------------------- * * _POOL-ALLOC provides "pool'd" allocation for "small" - * objects, suitable for use with "node"-based - * containers, including lists, hash-tables, etc. - * Nothing too tricky(!), just a linked list of memory - * slabs, a "free" list of deallocated objects, and a - * fall-back onto the base allocator for alloc.'s of a + * objects, suitable for use with "node"-based + * containers, including lists, hash-tables, etc. + * Nothing too tricky(!), just a linked list of memory + * slabs, a "free" list of deallocated objects, and a + * fall-back onto the base allocator for alloc.'s of a * larger size. * -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- @@ -68,31 +68,31 @@ std::size_t S = 64 * 1024 > class _pool_alloc : public A - { + { /*--- local memory pool: delegate to base alloc otherwise */ public : - + typedef A base_type ; std::size_t static constexpr pool_size = S ; - typedef typename + typedef typename base_type::size_type size_type ; - typedef typename + typedef typename base_type::diff_type diff_type ; typedef _pool_alloc < - base_type , + base_type , pool_size > self_type ; private : - + /*-------------------------------- local allocation lists */ char_type* _alloc ; // pointer to block - char_type* _shift ; // pointer to block + char_type* _shift ; // pointer to block char_type* _block ; char_type* _cache ; // cached item list - + /*-------------------------------- local allocation sizes */ size_type _item_size ; // size of alloc. size_type _slab_size ; // size of buffer @@ -102,47 +102,47 @@ * local helper: access encoded list pointers. -------------------------------------------------------- */ - + #define __nextblock(__block) \ *((char **)(__block + \ this->_slab_size*this->_item_size)) - + #define __nextcache(__cache) \ * (char **)(__cache) - + #define __slabbytes \ this->_slab_size * \ this->_item_size + sizeof (char *) - + /* -------------------------------------------------------- * local helper: allocate and push new buffer. -------------------------------------------------------- */ - + __inline_call void_type push_block ( // push new buffer ) { /*------------------------- allocate new buffer item */ - char_type *_this_slab = + char_type *_this_slab = (char_type *)base_type ::allocate(__slabbytes); - + /*------------------------- push new buffer onto list */ __nextblock(_this_slab)= this->_block; - - this->_alloc = _this_slab + + + this->_alloc = _this_slab + this->_slab_size*this->_item_size; this->_block = _this_slab ; this->_shift = _this_slab ; } - + /* -------------------------------------------------------- * local helper: _pop top buffer and de-alloc. -------------------------------------------------------- */ - + __inline_call void_type _pop_block ( // _pop top buffer ) { @@ -150,71 +150,71 @@ char_type *_tail_slab = this->_block ; this->_block = __nextblock (_tail_slab) ; - + /*------------------------- free top buffer data/item */ base_type::deallocate( _tail_slab, __slabbytes) ; } public : - + /* -------------------------------------------------------- * _POOL_ALLOC: construct pool'd allocator from base. -------------------------------------------------------- */ - + __inline_call _pool_alloc ( // default c'tor size_type const _size = +1 , base_type const&_asrc = base_type() - ) : base_type( _asrc), + ) : base_type( _asrc), /*--------------- construct with empty alloc. buffers */ - _alloc(nullptr) , + _alloc(nullptr) , _shift(nullptr) , - _block(nullptr) , + _block(nullptr) , _cache(nullptr) - { + { /*--------------- construct to force alloc on request */ - this->_item_size = + this->_item_size = std::max(_size, (size_type)sizeof(char*)) ; - this->_slab_size = + this->_slab_size = (size_type)pool_size / this->_item_size; - this->_slab_size = + this->_slab_size = std::max((size_type)+1, this->_slab_size) ; } - + __inline_call~_pool_alloc ( // default d'tor ) - { + { /*--------------- _free items while base alloc. valid */ clear() ; } - + /* -------------------------------------------------------- * CLEAR: de-alloc. and free the allocator. -------------------------------------------------------- */ - + __normal_call void_type clear ( ) { /*-------------- _destruct and deallocate all buffers */ for ( ; this->_block != nullptr; ) _pop_block() ; - + /*-------------- set in "empty" default c'tor'd state */ this->_block = nullptr ; this->_cache = nullptr ; this->_alloc = nullptr ; this->_shift = nullptr ; } - + /* -------------------------------------------------------- * return count/stat.'s for alloc. -------------------------------------------------------- */ - + __normal_call size_type nfree ( ) const { @@ -229,7 +229,7 @@ return ( _size ) ; } - __inline_call size_type nslab ( + __normal_call size_type nslab ( ) const { /*------------------------------- traverse block list */ @@ -243,55 +243,70 @@ return ( _size ) ; } + __inline_call size_type count ( + ) const + { + /*------------------------------- total items alloc'd */ + return nslab()*this->_slab_size ; + } + + __inline_call size_type bytes ( + ) const + { + /*------------------------------- total bytes alloc'd */ + return nslab()*this->_slab_size * + this->_item_size ; + } + /* -------------------------------------------------------- * ALLOCATE: do buffer allocation. -------------------------------------------------------- */ - + __inline_call char_type* allocate ( size_type _new_count ) { /*--------------------- catch any "empty" allocations */ if (_new_count <= +0 ) return ( nullptr ) ; - + /*--------------------- deal with genuine allocations */ char_type *_nptr; if (_new_count <= this->_item_size) { - if((_nptr = this->_cache)!= nullptr ) - { + if((_nptr = this->_cache)!= nullptr ) + { /*--------------- _pop cached item from stack */ this->_cache = __nextcache(_nptr); } else - { + { /*---------------------- alloc new item block */ - if (this->_shift >= this->_alloc) + if (this->_shift >= this->_alloc) push_block() ; _nptr = this->_shift ; - - /*---------------------- inc. offset in block */ + + /*---------------------- inc. offset in block */ this->_shift += this->_item_size ; } } else - { + { /*------------------------ delegate to base allocator */ _nptr = base_type ::allocate(_new_count); } - + return ( _nptr ); } - + /* -------------------------------------------------------- * REALLOCATE: re-allocate buffer. -------------------------------------------------------- */ - + __inline_call char_type* reallocate ( char_type*_addr , size_type _old_count, @@ -299,77 +314,77 @@ ) { /*------------------ catch any first-time allocations */ - if (_addr == nullptr) + if (_addr == nullptr) return self_type::allocate(_new_count); - + /*------------------ deal with genuine reallocations */ char_type *_nptr; - if (_old_count <= this->_item_size) + if (_old_count <= this->_item_size) { /*------------------ current alloc is from local pool */ if (_new_count <= this->_item_size) - { + { /*--- keep current, block is already large enough */ _nptr = _addr ; } else - { + { /*--- deallocate back to pool, allocate from base */ - _nptr = + _nptr = base_type::allocate( _new_count); - + size_type _nnum = std::min( _new_count, _old_count) ; std::memcpy(_nptr, _addr, _nnum); - + self_type:: deallocate(_addr,_old_count); } } - else + else { /*------------------ current alloc is from base alloc */ if (_new_count > this->_item_size) - { + { /*--- re-allocate within base, too large for pool */ _nptr = base_type::reallocate( _addr, _old_count, _new_count) ; } else - { + { /*--- deallocate back to base, allocate from pool */ - _nptr = + _nptr = self_type::allocate( _new_count); - + size_type _nnum = std::min( _new_count, _old_count) ; std::memcpy(_nptr, _addr, _nnum); - + base_type:: deallocate(_addr,_old_count); } } - + return ( _nptr ) ; } - + /* -------------------------------------------------------- * DEALLOCATE: de-allocate buffer. -------------------------------------------------------- */ - + __inline_call void_type deallocate ( char_type*_addr , size_type _old_count ) { if (_old_count <= this->_item_size) - { + { if (_addr != nullptr) { /*------------------------------ cache un-used buffer */ - __nextcache(_addr) = + __nextcache(_addr) = this->_cache ; this->_cache = _addr ; } @@ -387,8 +402,8 @@ #undef __slabbytes } ; - - + + } //} allocators # endif//__ALLOC_POOL__ diff --git a/src/libcpp/allocators/alloc_wrap.hpp b/src/libcpp/allocators/alloc_wrap.hpp index 3c35c90..4aede0f 100644 --- a/src/libcpp/allocators/alloc_wrap.hpp +++ b/src/libcpp/allocators/alloc_wrap.hpp @@ -1,40 +1,40 @@ - /* + /* -------------------------------------------------------- * "wrap" an allocator -- "stateful" allocators... -------------------------------------------------------- * - * _WRAP-ALLOC is a wrapper for so-called "stateful" - * allocators, allowing, for example, _POOL-ALLOC to be - * used within containers without duplication. It just - * maintains a pointer-to-allocator internally, and + * _WRAP-ALLOC is a wrapper for so-called "stateful" + * allocators, allowing, for example, _POOL-ALLOC to be + * used within containers without duplication. It just + * maintains a pointer-to-allocator internally, and * marshals calls through to the base. * -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- @@ -59,18 +59,18 @@ template < typename A - > + > class _wrap_alloc - { + { /*-------- pointer to base allocator: stateful allocators */ public : typedef A allocator ; - + typedef _wrap_alloc self_type ; - typedef typename + typedef typename allocator::size_type size_type ; - typedef typename + typedef typename allocator::diff_type diff_type ; private : @@ -78,61 +78,61 @@ allocator *_aptr ; public : - + /* -------------------------------------------------------- * _WRAP_ALLOC: construct alloc. wrapper. -------------------------------------------------------- */ - + __inline_call _wrap_alloc ( allocator *_asrc = nullptr ) : _aptr( _asrc ) {} __inline_call~_wrap_alloc () = default ; - + __inline_call _wrap_alloc ( - self_type const& _src + self_type const& _src ) = default ; __inline_call _wrap_alloc ( - self_type && _src + self_type && _src ) = default ; - __inline_call + __inline_call self_type& operator = ( - self_type const& _src + self_type const& _src ) = default ; - __inline_call + __inline_call self_type& operator = ( - self_type && _src + self_type && _src ) = default ; - + /* -------------------------------------------------------- * GET/PUT_ALLOCATOR: access to base obj. -------------------------------------------------------- */ - - __inline_call + + __inline_call allocator & put_allocator ( - ) - { + ) + { return *this->_aptr ; } - - __inline_call + + __inline_call allocator const& get_allocator ( )const - { + { return *this->_aptr ; } - + /* -------------------------------------------------------- * ALLOCATE: do buffer allocation. -------------------------------------------------------- */ - + __inline_call char_type* allocate ( size_type _new_count ) const @@ -143,13 +143,13 @@ return this-> _aptr->allocate( _new_count) ; } - + /* -------------------------------------------------------- * REALLOCATE: re-allocate buffer. -------------------------------------------------------- */ - + __inline_call char_type* reallocate ( char_type*_addr , size_type _old_count, @@ -159,17 +159,17 @@ __assert( this->_aptr != nullptr && "_wrap_alloc: null allocator!" ) ; - return this->_aptr->reallocate(_addr, - _old_count, + return this->_aptr->reallocate(_addr, + _old_count, _new_count) ; } - + /* -------------------------------------------------------- * DEALLOCATE: de-allocate buffer. -------------------------------------------------------- */ - + __inline_call void_type deallocate ( char_type*_addr , size_type _old_count @@ -181,10 +181,10 @@ this->_aptr-> deallocate(_addr,_old_count) ; } - + } ; - - + + } # endif //__ALLOC_WRAP__ diff --git a/src/libcpp/containers.hpp b/src/libcpp/containers.hpp index 33903bb..d14b627 100644 --- a/src/libcpp/containers.hpp +++ b/src/libcpp/containers.hpp @@ -1,79 +1,79 @@ - -/* ------------------------------------------------------------- - * std::library-like containers, but not quite... ------------------------------------------------------------- - * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) - * - * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The - * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be - * used at your own risk. - * ------------------------------------------------------------- - * - * Last updated: 21 December, 2018 - * - * Copyright 2013-2018 - * Darren Engwirda - * de2363@columbia.edu - * https://github.com/dengwirda/ - * ------------------------------------------------------------- - */ - -# pragma once - -# ifndef __CONTAINERS__ -# define __CONTAINERS__ - -# include "allocators.hpp" - - namespace containers - { -/*----- buffer reallocation options */ - enum alloc_types - { loose_alloc, // zero manip. - tight_alloc // full manip. - } ; - } // containers - -# include "containers/fixed_array.hpp" -# include "containers/array.hpp" -# include "containers/block_array.hpp" - -# include "containers/single_list.hpp" -# include "containers/double_list.hpp" -# include "containers/basic_stack.hpp" - -# include "containers/arraylist.hpp" - -# include "containers/hashtable.hpp" - -# include "containers/priorityset.hpp" -# include "containers/prioritymap.hpp" - - -# endif//__CONTAINERS__ - - - + +/* +------------------------------------------------------------ + * std::library-like containers, but not quite... +------------------------------------------------------------ + * + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) + * + * Disclaimer: Neither I nor: Columbia University, The + * Massachusetts Institute of Technology, The + * University of Sydney, nor The National Aeronautics + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be + * used at your own risk. + * +------------------------------------------------------------ + * + * Last updated: 21 December, 2018 + * + * Copyright 2013-2018 + * Darren Engwirda + * de2363@columbia.edu + * https://github.com/dengwirda/ + * +------------------------------------------------------------ + */ + +# pragma once + +# ifndef __CONTAINERS__ +# define __CONTAINERS__ + +# include "allocators.hpp" + + namespace containers + { +/*----- buffer reallocation options */ + enum alloc_types + { loose_alloc, // zero manip. + tight_alloc // full manip. + } ; + } // containers + +# include "containers/fixed_array.hpp" +# include "containers/array.hpp" +# include "containers/block_array.hpp" + +# include "containers/single_list.hpp" +# include "containers/double_list.hpp" +# include "containers/basic_stack.hpp" + +# include "containers/arraylist.hpp" + +# include "containers/hashtable.hpp" + +# include "containers/priorityset.hpp" +# include "containers/prioritymap.hpp" + + +# endif//__CONTAINERS__ + + + diff --git a/src/libcpp/containers/array.hpp b/src/libcpp/containers/array.hpp index 6ad11c7..6ea55a1 100644 --- a/src/libcpp/containers/array.hpp +++ b/src/libcpp/containers/array.hpp @@ -1,798 +1,798 @@ - -/* ------------------------------------------------------------- - * a contiguous dynamically allocated buffer. ------------------------------------------------------------- - * - * ARRAY is a dynamically allocated, contiguous array - * object, where the linear array storage is guaranteed - * to consist of a single block, as returned by malloc, - * etc. Provides O(1) random access, amortarised - * O(log(n)) incremental insertion, etc. This is a - * striped-down implementation -- offering only - * "efficient" operations (no insert, delete, etc). - * ------------------------------------------------------------- - * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) - * - * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The - * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be - * used at your own risk. - * ------------------------------------------------------------- - * - * Last updated: 21 August, 2018 - * - * Copyright 2013-2018 - * Darren Engwirda - * de2363@columbia.edu - * https://github.com/dengwirda/ - * ------------------------------------------------------------- - */ - -# pragma once - -# ifndef __ARRAY__ -# define __ARRAY__ - -# include "array_iter.hpp" - - namespace containers { - -# define __cont containers - - template < - typename D , - typename A = - allocators::basic_alloc - > - class array : public - allocators::_item_alloc < D, A > - { -/*------ a dynamically allocated, contiguous array object */ - public : - - typedef D data_type ; - typedef A allocator ; - - typedef typename - allocator::size_type size_type ; - typedef typename - allocator::diff_type diff_type ; - - typedef __cont::array < - data_type, - allocator > self_type ; - - typedef __cont::write_array_iterator < - self_type > _write_it ; - typedef __cont::const_array_iterator < - self_type > _const_it ; - - typedef allocators::_item_alloc < - data_type, - allocator > obj_alloc ; - - private : - - enum {_hptr, _tptr, _lptr} ; - - containers:: - fixed_array<__write_ptr(data_type),+3> _ptrs ; - - private : - -/*------------------------------ helper - construct range */ - - __normal_call void_type ctor_iter ( - _write_it _head, - _write_it _tail - ) - { /* _def construct sequence */ - for ( ; _head != _tail ; ++_head) - { - self_type::construct(&*_head) ; - } - } - __normal_call void_type ctor_iter ( - _write_it _head, - _write_it _tail, - data_type const& _data - ) - { /* copy construct sequence */ - for ( ; _head != _tail ; ++_head) - { - self_type::construct(&*_head, - _data) ; - } - } - -/*------------------------------ helper - _destruct range */ - - __normal_call void_type dtor_iter ( - _write_it _head, - _write_it _tail - ) - { - for ( ; _head != _tail ; ++_head) - { - self_type::_destruct(&*_head) ; - } - } - -/*------------------------------ helper - inc. allocation */ - - __inline_call size_type num_alloc ( - size_type _new_count - ) - { - if (_new_count > (size_type)1024) - { - size_type _num_block = - _new_count / (size_type)1024; - - _new_count = - (_num_block + 1) * +1024; - - return (_new_count * 3) / 2 ; - } - else - if (_new_count > (size_type) +4 ) - { - size_type _num_block = - _new_count / (size_type) +4 ; - - _new_count = - (_num_block + 1) * +4 ; - - return (_new_count * 2) / 1 ; - } - else - { - return _new_count ; - } - } - - __inline_call void_type inc_alloc ( - size_type _new_count - ) - { /* Grow allocation as geometric series */ - if (alloc() < _new_count) - { - set_alloc( - num_alloc(_new_count) ) ; - } - } - -/*------------------------------ helper - copy allocation */ - - __inline_call void_type copy_iter ( - size_type _size , - data_type const&_dsrc, - __cont::null_iterator_kind - ) - { /* copy _data onto object */ - set_count(_size, __cont::tight_alloc, _dsrc) ; - } - - template < - typename iter_type - > - __normal_call void_type copy_iter ( - iter_type _head, - iter_type _tail, - __cont::base_iterator_kind - ) - { /* copy range onto object */ - for(;_head!=_tail;++_head) push_tail(*_head) ; - } - - public : - -/*--------------------------- default c'tor - do nothing! */ - __inline_call array ( - allocator const&_asrc = allocator() - ) : obj_alloc( _asrc ) - { - this->_ptrs[_hptr] = nullptr; - this->_ptrs[_tptr] = nullptr; - this->_ptrs[_lptr] = nullptr; - } - -/*--------------------------- default c'tor - initialisor */ - __inline_call array ( - size_type _size, - data_type const&_dsrc = data_type(), - allocator const&_asrc = allocator() - ) : obj_alloc( _asrc ) - { - this->_ptrs[_hptr] = nullptr; - this->_ptrs[_tptr] = nullptr; - this->_ptrs[_lptr] = nullptr; - - copy_iter(_size,_dsrc, - __cont::null_iterator_kind()) ; - } - -/*--------------------------- default c'tor - initialisor */ - template < - typename iter_type - > - __inline_call array ( - iter_type _head, - iter_type _tail, - allocator const&_asrc = allocator() - ) : obj_alloc( _asrc ) - { - this->_ptrs[_hptr] = nullptr; - this->_ptrs[_tptr] = nullptr; - this->_ptrs[_lptr] = nullptr; - - copy_iter(_head,_tail, - __cont::iter_kind(_head)) ; - } - -/*-------------------------------------------- _def d'tor */ - __inline_call~array ( - ) - {/* _destruct all items while allocator remains valid */ - set_count(+0, __cont::tight_alloc); - } - -/*-------------------------------------------- copy c'tor */ - __inline_call array ( - self_type const& _src - ) : obj_alloc( - __copy(obj_alloc,_src)) - { - this->_ptrs[_hptr] = nullptr; - this->_ptrs[_tptr] = nullptr; - this->_ptrs[_lptr] = nullptr; - /*------------------------------------- alloc storage */ - set_alloc(_src.count()); - /*------------------------------------- copy sequence */ - _const_it _head, _tail ; - _head = _src.head(); - _tail = _src.tend(); - copy_iter(_head,_tail, - __cont::iter_kind(_head)) ; - } - -/*-------------------------------------------- move c'tor */ - __inline_call array ( - self_type &&_src - ) : obj_alloc( - __move(obj_alloc,_src)) - { - this->_ptrs[_hptr] = - _src. _ptrs[_hptr] ; - this->_ptrs[_tptr] = - _src. _ptrs[_tptr] ; - this->_ptrs[_lptr] = - _src. _ptrs[_lptr] ; - _src. _ptrs.fill(nullptr); - } - -/*-------------------------------------------- copy a-op. */ - __inline_call self_type& operator = ( - self_type const&_src - ) - { - if (this != &_src) - { - self_type _copy ( - __copy(self_type , _src)) ; - - using std::swap ; - swap ( - static_cast(*this), - static_cast(_copy) - ) ; - - swap(this->_ptrs[_hptr], - _copy. _ptrs[_hptr]) ; - swap(this->_ptrs[_tptr], - _copy. _ptrs[_tptr]) ; - swap(this->_ptrs[_lptr], - _copy. _ptrs[_lptr]) ; - } - - return ( *this ) ; - } - -/*-------------------------------------------- move a-op. */ - __inline_call self_type &operator = ( - self_type && _src - ) - { - if (this != &_src) - { - self_type _copy ( - __move(self_type , _src)) ; - - using std::swap ; - swap ( - static_cast(*this), - static_cast(_copy) - ) ; - - swap(this->_ptrs[_hptr], - _copy. _ptrs[_hptr]) ; - swap(this->_ptrs[_tptr], - _copy. _ptrs[_tptr]) ; - swap(this->_ptrs[_lptr], - _copy. _ptrs[_lptr]) ; - } - - return ( *this ) ; - } - -/*-------------------------------------- push array alloc */ - __normal_call void_type set_alloc ( - size_type _new_alloc - ) - { - size_type _cur_count = count(); - size_type _cur_alloc = alloc(); - - if (_new_alloc < _cur_count ) - { - /*---------------------------------------- dec. alloc */ - set_count(_new_alloc, - __cont::loose_alloc) ; - - if (_new_alloc > 0 ) - { - this->_ptrs[_hptr] = - self_type::reallocate(this->_ptrs[_hptr], - _cur_alloc, - _new_alloc, - _new_alloc) ; - - this->_ptrs[_tptr] = - this->_ptrs[_hptr] + _new_alloc ; - this->_ptrs[_lptr] = - this->_ptrs[_hptr] + _new_alloc ; - } - else - { - self_type::deallocate(this->_ptrs[_hptr], - _cur_alloc) ; - - this->_ptrs[_hptr] = nullptr ; - this->_ptrs[_tptr] = nullptr ; - this->_ptrs[_lptr] = nullptr ; - } - } - else - if (_new_alloc != _cur_alloc ) - { - /*---------------------------------------- inc. alloc */ - if (_new_alloc > 0 ) - { - this->_ptrs[_hptr] = - self_type::reallocate(this->_ptrs[_hptr], - _cur_alloc, - _new_alloc, - _cur_count) ; - - this->_ptrs[_tptr] = - this->_ptrs[_hptr] + _cur_count ; - this->_ptrs[_lptr] = - this->_ptrs[_hptr] + _new_alloc ; - } - else - { - self_type::deallocate(this->_ptrs[_hptr], - _cur_alloc) ; - - this->_ptrs[_hptr] = nullptr ; - this->_ptrs[_tptr] = nullptr ; - this->_ptrs[_lptr] = nullptr ; - } - } - } - -/*-------------------------------------- trim array alloc */ - __inline_call void_type fix_alloc ( - ) { set_alloc(count()) ; } - -/*---------------------- increment count (_def construct) */ - __normal_call void_type inc_count ( - size_type _inc_count , - __cont::alloc_types _new_alloc = - __cont::loose_alloc - ) - { - /*--------- expand underlying buffer, based on policy */ - size_type _cur_count = count() ; - switch (_new_alloc ) - { - case __cont::loose_alloc : - { inc_alloc(_cur_count + _inc_count); break; } - case __cont::tight_alloc : - { set_alloc(_cur_count + _inc_count); break; } - } - /*--------- update buffer pointers and ctor new items */ - _write_it _head = tend() ; - this->_ptrs[_tptr] += _inc_count ; - ctor_iter(_head , tend()); - } - -/*---------------------- increment count (copy construct) */ - __normal_call void_type inc_count ( - size_type _inc_count , - __cont::alloc_types _new_alloc , - data_type const& _data - ) - { - /*--------- expand underlying buffer, based on policy */ - size_type _cur_count = count() ; - switch (_new_alloc ) - { - case __cont::loose_alloc : - { inc_alloc(_cur_count + _inc_count); break; } - case __cont::tight_alloc : - { set_alloc(_cur_count + _inc_count); break; } - } - /*--------- update buffer pointers and ctor new items */ - _write_it _head = tend(); - this->_ptrs[_tptr] += _inc_count; - ctor_iter(_head , tend(), _data); - } - -/*--------------------------------------- decrement count */ - __normal_call void_type dec_count ( - size_type _dec_count , - __cont::alloc_types _new_alloc = - __cont::loose_alloc - ) - { - /*---- update buffer pointers and _destruct old items */ - size_type _cur_count = count() ; - _write_it _head = tend() - _dec_count; - dtor_iter(_head , tend()); - this->_ptrs[_tptr] -= _dec_count; - /*---- shrink underlying buffer, based on size policy */ - switch (_new_alloc ) - { - case __cont::loose_alloc : - { /* do nothing - preserve buffer */ break; } - case __cont::tight_alloc : - { set_alloc(_cur_count - _dec_count); break; } - } - } - -/*---------------------------- set count (_def construct) */ - __inline_call void_type set_count ( - size_type _new_count , - __cont::alloc_types _new_alloc = - __cont::loose_alloc - ) - { - /*----- manipulate the ctor'd range within the buffer */ - size_type _cur_count = count() ; - if(_new_count > _cur_count) - { - inc_count( - _new_count - _cur_count, _new_alloc) ; - } - else - if(_new_count <=_cur_count) - { - dec_count( - _cur_count - _new_count, _new_alloc) ; - } - } - -/*---------------------------- set count (copy construct) */ - __inline_call void_type set_count ( - size_type _new_count , - __cont::alloc_types _new_alloc , - data_type const&_data - ) - { - /*----- manipulate the ctor'd range within the buffer */ - size_type _cur_count = count() ; - if(_new_count > _cur_count) - { - inc_count( - _new_count - _cur_count, _new_alloc, _data); - } - else - if(_new_count <=_cur_count) - { - dec_count( - _cur_count - _new_count, _new_alloc) ; - } - } - -/*-------------------------------- return container alloc */ - __inline_call allocator get_alloc( - ) const - { return static_cast( *this ) ; - } - -/*-------------------------------- return container count */ - __inline_call size_type count ( - ) const - { /* take pointer difference */ - return ( size_type ) - (this->_ptrs[_tptr] - this->_ptrs[_hptr]); - } - -/*-------------------------------- return container alloc */ - __inline_call size_type alloc ( - ) const - { /* take pointer difference */ - return ( size_type ) - (this->_ptrs[_lptr] - this->_ptrs[_hptr]); - } - -/*-------------------------------- true if sequence empty */ - __inline_call bool_type empty ( - ) const - { /* take pointer difference */ - return - this->_ptrs[_hptr]== this->_ptrs[_tptr] ; - } - -/*-------------------------------- const access iterators */ - __inline_call _const_it head ( - ) const - {/*---- return iterator for list head */ - data_type *_ptr = - this->_ptrs[_hptr] != nullptr ? - this->_ptrs[_hptr] : nullptr ; - self_type *_obj = (self_type *)this ; - return _const_it(_ptr, _obj) ; - } - - __inline_call _const_it tail ( - ) const - {/*---- return iterator for list head */ - data_type *_ptr = - this->_ptrs[_tptr] != nullptr ? - this->_ptrs[_tptr]-1: nullptr ; - self_type *_obj = (self_type *)this ; - return _const_it(_ptr, _obj) ; - } - - __inline_call _const_it hend ( - ) const - {/*------ return iterator "past" head */ - data_type *_ptr = - this->_ptrs[_hptr] != nullptr ? - this->_ptrs[_hptr]-1: nullptr ; - self_type *_obj = (self_type *)this ; - return _const_it(_ptr, _obj) ; - } - - __inline_call _const_it tend ( - ) const - {/*------ return iterator "past" tail */ - data_type *_ptr = - this->_ptrs[_tptr] != nullptr ? - this->_ptrs[_tptr] : nullptr ; - self_type *_obj = (self_type *)this ; - return _const_it(_ptr, _obj) ; - } - -/*-------------------------------- write access iterators */ - __inline_call _write_it head ( - ) - { /* return iterator for list head */ - data_type *_ptr = - this->_ptrs[_hptr] != nullptr ? - this->_ptrs[_hptr] : nullptr ; - self_type *_obj = (self_type *)this ; - return _write_it(_ptr, _obj) ; - } - - __inline_call _write_it tail ( - ) - { /* return iterator for list head */ - data_type *_ptr = - this->_ptrs[_tptr] != nullptr ? - this->_ptrs[_tptr]-1: nullptr ; - self_type *_obj = (self_type *)this ; - return _write_it(_ptr, _obj) ; - } - - __inline_call _write_it hend ( - ) - { /* return iterator "past" head */ - data_type *_ptr = - this->_ptrs[_hptr] != nullptr ? - this->_ptrs[_hptr]-1: nullptr ; - self_type *_obj = (self_type *)this ; - return _write_it(_ptr, _obj) ; - } - - __inline_call _write_it tend ( - ) - { /* return iterator "past" tail */ - data_type *_ptr = - this->_ptrs[_tptr] != nullptr ? - this->_ptrs[_tptr] : nullptr ; - self_type *_obj = (self_type *)this ; - return _write_it(_ptr, _obj) ; - } - -/*-------------------------------------- "free" container */ - __inline_call void_type clear ( - __cont::alloc_types _this_alloc = - __cont::loose_alloc - ) - { - if (_this_alloc == __cont::loose_alloc) - set_count(0, _this_alloc) ; - else - set_count(0, _this_alloc) ; - } - -/*---------------------------- push data (_def construct) */ - __inline_call size_type push_tail ( - ) - {/* default construct obj and increment count */ - size_type result = count(); - if (result != alloc()) - { - self_type::construct( - this->_ptrs[_tptr]++) ; - } - else - { - inc_alloc(result + 1) ; - self_type::construct( - this->_ptrs[_tptr]++) ; - } - return result; - } - -/*---------------------------- push data (copy construct) */ - __inline_call size_type push_tail ( - data_type const&_data - ) - {/* copy data onto object and increment count */ - size_type result = count(); - if (result != alloc()) - { - self_type::construct( - this->_ptrs[_tptr]++, - __copy(data_type,_data)) ; - } - else - { - data_type _temp( - __copy(data_type,_data)) ; - - inc_alloc(result + 1) ; - self_type::construct( - this->_ptrs[_tptr]++, - __move(data_type,_temp)) ; - } - return result; - } - -/*---------------------------- push data (move construct) */ - __inline_call size_type push_tail ( - data_type &&_data - ) - {/* move data onto object and increment count */ - size_type result = count(); - if (result != alloc()) - { - self_type::construct( - this->_ptrs[_tptr]++, - __move(data_type,_data)) ; - } - else - { - data_type _temp( - __move(data_type,_data)) ; - - inc_alloc(result + 1) ; - self_type::construct( - this->_ptrs[_tptr]++, - __move(data_type,_temp)) ; - } - return result; - } - -/*---------------------------- push data (copy obj range) */ - template < - typename iter_type - > - __normal_call void_type push_tail ( - iter_type _head, - iter_type _tend - ) - {/* push full sequence at tail and inc. count */ - for(; _head != _tend; ++_head) - { - self_type::push_tail ( *_head); - } - } - -/*--------------------------------------------- _pop data */ - __inline_call void_type _pop_tail ( - ) - { /* _destruct tail item and dec count */ - __assert ( count() != +0 - && "array._pop_tail: empty") ; - - self_type:: - _destruct(--this->_ptrs[_tptr] ) ; - } - -/*--------------------------------------------- _pop data */ - __inline_call void_type _pop_tail ( - data_type &_data - ) - { /* _destruct tail item and dec count */ - __assert ( count() != +0 - && "array._pop_tail: empty") ; - - _data = - std::move(*(this->_ptrs[_tptr]-1)) ; - self_type:: - _destruct(--this->_ptrs[_tptr] ) ; - } - -/*------------------------------------ operator[] (write) */ - __inline_call data_type &operator[] ( - size_type _pos - ) - { - __assert ( _pos >= +0 && - _pos < count() && - "array[]: out of range!" ) ; - - return *(this->_ptrs[_hptr] + _pos) ; - } - -/*------------------------------------ operator[] (const) */ - __inline_call data_type const&operator[] ( - size_type _pos - ) const - { - __assert ( _pos >= +0 && - _pos < count() && - "array[]: out of range!" ) ; - - return *(this->_ptrs[_hptr] + _pos) ; - } - - } ; - -# undef __cont - - - } - -# endif//__ARRAY__ - - - + +/* +------------------------------------------------------------ + * a contiguous dynamically allocated buffer. +------------------------------------------------------------ + * + * ARRAY is a dynamically allocated, contiguous array + * object, where the linear array storage is guaranteed + * to consist of a single block, as returned by malloc, + * etc. Provides O(1) random access, amortarised + * O(log(n)) incremental insertion, etc. This is a + * striped-down implementation -- offering only + * "efficient" operations (no insert, delete, etc). + * +------------------------------------------------------------ + * + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) + * + * Disclaimer: Neither I nor: Columbia University, The + * Massachusetts Institute of Technology, The + * University of Sydney, nor The National Aeronautics + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be + * used at your own risk. + * +------------------------------------------------------------ + * + * Last updated: 21 August, 2018 + * + * Copyright 2013-2018 + * Darren Engwirda + * de2363@columbia.edu + * https://github.com/dengwirda/ + * +------------------------------------------------------------ + */ + +# pragma once + +# ifndef __ARRAY__ +# define __ARRAY__ + +# include "array_iter.hpp" + + namespace containers { + +# define __cont containers + + template < + typename D , + typename A = + allocators::basic_alloc + > + class array : public + allocators::_item_alloc < D, A > + { +/*------ a dynamically allocated, contiguous array object */ + public : + + typedef D data_type ; + typedef A allocator ; + + typedef typename + allocator::size_type size_type ; + typedef typename + allocator::diff_type diff_type ; + + typedef __cont::array < + data_type, + allocator > self_type ; + + typedef __cont::write_array_iterator < + self_type > _write_it ; + typedef __cont::const_array_iterator < + self_type > _const_it ; + + typedef allocators::_item_alloc < + data_type, + allocator > obj_alloc ; + + private : + + enum {_hptr, _tptr, _lptr} ; + + containers:: + fixed_array<__write_ptr(data_type),+3> _ptrs ; + + private : + +/*------------------------------ helper - construct range */ + + __normal_call void_type ctor_iter ( + _write_it _head, + _write_it _tail + ) + { /* _def construct sequence */ + for ( ; _head != _tail ; ++_head) + { + self_type::construct(&*_head) ; + } + } + __normal_call void_type ctor_iter ( + _write_it _head, + _write_it _tail, + data_type const& _data + ) + { /* copy construct sequence */ + for ( ; _head != _tail ; ++_head) + { + self_type::construct(&*_head, + _data) ; + } + } + +/*------------------------------ helper - _destruct range */ + + __normal_call void_type dtor_iter ( + _write_it _head, + _write_it _tail + ) + { + for ( ; _head != _tail ; ++_head) + { + self_type::_destruct(&*_head) ; + } + } + +/*------------------------------ helper - inc. allocation */ + + __inline_call size_type num_alloc ( + size_type _new_count + ) + { + if (_new_count > (size_type)1024) + { + size_type _num_block = + _new_count / (size_type)1024; + + _new_count = + (_num_block + 1) * +1024; + + return (_new_count * 3) / 2 ; + } + else + if (_new_count > (size_type) +4 ) + { + size_type _num_block = + _new_count / (size_type) +4 ; + + _new_count = + (_num_block + 1) * +4 ; + + return (_new_count * 2) / 1 ; + } + else + { + return _new_count ; + } + } + + __inline_call void_type inc_alloc ( + size_type _new_count + ) + { /* Grow allocation as geometric series */ + if (alloc() < _new_count) + { + set_alloc( + num_alloc(_new_count) ) ; + } + } + +/*------------------------------ helper - copy allocation */ + + __inline_call void_type copy_iter ( + size_type _size , + data_type const&_dsrc, + __cont::null_iterator_kind + ) + { /* copy _data onto object */ + set_count(_size, __cont::tight_alloc, _dsrc) ; + } + + template < + typename iter_type + > + __normal_call void_type copy_iter ( + iter_type _head, + iter_type _tail, + __cont::base_iterator_kind + ) + { /* copy range onto object */ + for(;_head!=_tail;++_head) push_tail(*_head) ; + } + + public : + +/*--------------------------- default c'tor - do nothing! */ + __inline_call array ( + allocator const&_asrc = allocator() + ) : obj_alloc( _asrc ) + { + this->_ptrs[_hptr] = nullptr; + this->_ptrs[_tptr] = nullptr; + this->_ptrs[_lptr] = nullptr; + } + +/*--------------------------- default c'tor - initialisor */ + __inline_call array ( + size_type _size, + data_type const&_dsrc = data_type(), + allocator const&_asrc = allocator() + ) : obj_alloc( _asrc ) + { + this->_ptrs[_hptr] = nullptr; + this->_ptrs[_tptr] = nullptr; + this->_ptrs[_lptr] = nullptr; + + copy_iter(_size,_dsrc, + __cont::null_iterator_kind()) ; + } + +/*--------------------------- default c'tor - initialisor */ + template < + typename iter_type + > + __inline_call array ( + iter_type _head, + iter_type _tail, + allocator const&_asrc = allocator() + ) : obj_alloc( _asrc ) + { + this->_ptrs[_hptr] = nullptr; + this->_ptrs[_tptr] = nullptr; + this->_ptrs[_lptr] = nullptr; + + copy_iter(_head,_tail, + __cont::iter_kind(_head)) ; + } + +/*-------------------------------------------- _def d'tor */ + __inline_call~array ( + ) + {/* _destruct all items while allocator remains valid */ + set_count(+0, __cont::tight_alloc); + } + +/*-------------------------------------------- copy c'tor */ + __inline_call array ( + self_type const& _src + ) : obj_alloc( + __copy(obj_alloc,_src)) + { + this->_ptrs[_hptr] = nullptr; + this->_ptrs[_tptr] = nullptr; + this->_ptrs[_lptr] = nullptr; + /*------------------------------------- alloc storage */ + set_alloc(_src.count()); + /*------------------------------------- copy sequence */ + _const_it _head, _tail ; + _head = _src.head(); + _tail = _src.tend(); + copy_iter(_head,_tail, + __cont::iter_kind(_head)) ; + } + +/*-------------------------------------------- move c'tor */ + __inline_call array ( + self_type &&_src + ) : obj_alloc( + __move(obj_alloc,_src)) + { + this->_ptrs[_hptr] = + _src. _ptrs[_hptr] ; + this->_ptrs[_tptr] = + _src. _ptrs[_tptr] ; + this->_ptrs[_lptr] = + _src. _ptrs[_lptr] ; + _src. _ptrs.fill(nullptr); + } + +/*-------------------------------------------- copy a-op. */ + __inline_call self_type& operator = ( + self_type const&_src + ) + { + if (this != &_src) + { + self_type _copy ( + __copy(self_type , _src)) ; + + using std::swap ; + swap ( + static_cast(*this), + static_cast(_copy) + ) ; + + swap(this->_ptrs[_hptr], + _copy. _ptrs[_hptr]) ; + swap(this->_ptrs[_tptr], + _copy. _ptrs[_tptr]) ; + swap(this->_ptrs[_lptr], + _copy. _ptrs[_lptr]) ; + } + + return ( *this ) ; + } + +/*-------------------------------------------- move a-op. */ + __inline_call self_type &operator = ( + self_type && _src + ) + { + if (this != &_src) + { + self_type _copy ( + __move(self_type , _src)) ; + + using std::swap ; + swap ( + static_cast(*this), + static_cast(_copy) + ) ; + + swap(this->_ptrs[_hptr], + _copy. _ptrs[_hptr]) ; + swap(this->_ptrs[_tptr], + _copy. _ptrs[_tptr]) ; + swap(this->_ptrs[_lptr], + _copy. _ptrs[_lptr]) ; + } + + return ( *this ) ; + } + +/*-------------------------------------- push array alloc */ + __normal_call void_type set_alloc ( + size_type _new_alloc + ) + { + size_type _cur_count = count(); + size_type _cur_alloc = alloc(); + + if (_new_alloc < _cur_count ) + { + /*---------------------------------------- dec. alloc */ + set_count(_new_alloc, + __cont::loose_alloc) ; + + if (_new_alloc > 0 ) + { + this->_ptrs[_hptr] = + self_type::reallocate(this->_ptrs[_hptr], + _cur_alloc, + _new_alloc, + _new_alloc) ; + + this->_ptrs[_tptr] = + this->_ptrs[_hptr] + _new_alloc ; + this->_ptrs[_lptr] = + this->_ptrs[_hptr] + _new_alloc ; + } + else + { + self_type::deallocate(this->_ptrs[_hptr], + _cur_alloc) ; + + this->_ptrs[_hptr] = nullptr ; + this->_ptrs[_tptr] = nullptr ; + this->_ptrs[_lptr] = nullptr ; + } + } + else + if (_new_alloc != _cur_alloc ) + { + /*---------------------------------------- inc. alloc */ + if (_new_alloc > 0 ) + { + this->_ptrs[_hptr] = + self_type::reallocate(this->_ptrs[_hptr], + _cur_alloc, + _new_alloc, + _cur_count) ; + + this->_ptrs[_tptr] = + this->_ptrs[_hptr] + _cur_count ; + this->_ptrs[_lptr] = + this->_ptrs[_hptr] + _new_alloc ; + } + else + { + self_type::deallocate(this->_ptrs[_hptr], + _cur_alloc) ; + + this->_ptrs[_hptr] = nullptr ; + this->_ptrs[_tptr] = nullptr ; + this->_ptrs[_lptr] = nullptr ; + } + } + } + +/*-------------------------------------- trim array alloc */ + __inline_call void_type fix_alloc ( + ) { set_alloc(count()) ; } + +/*---------------------- increment count (_def construct) */ + __normal_call void_type inc_count ( + size_type _inc_count , + __cont::alloc_types _new_alloc = + __cont::loose_alloc + ) + { + /*--------- expand underlying buffer, based on policy */ + size_type _cur_count = count() ; + switch (_new_alloc ) + { + case __cont::loose_alloc : + { inc_alloc(_cur_count + _inc_count); break; } + case __cont::tight_alloc : + { set_alloc(_cur_count + _inc_count); break; } + } + /*--------- update buffer pointers and ctor new items */ + _write_it _head = tend() ; + this->_ptrs[_tptr] += _inc_count ; + ctor_iter(_head , tend()); + } + +/*---------------------- increment count (copy construct) */ + __normal_call void_type inc_count ( + size_type _inc_count , + __cont::alloc_types _new_alloc , + data_type const& _data + ) + { + /*--------- expand underlying buffer, based on policy */ + size_type _cur_count = count() ; + switch (_new_alloc ) + { + case __cont::loose_alloc : + { inc_alloc(_cur_count + _inc_count); break; } + case __cont::tight_alloc : + { set_alloc(_cur_count + _inc_count); break; } + } + /*--------- update buffer pointers and ctor new items */ + _write_it _head = tend(); + this->_ptrs[_tptr] += _inc_count; + ctor_iter(_head , tend(), _data); + } + +/*--------------------------------------- decrement count */ + __normal_call void_type dec_count ( + size_type _dec_count , + __cont::alloc_types _new_alloc = + __cont::loose_alloc + ) + { + /*---- update buffer pointers and _destruct old items */ + size_type _cur_count = count() ; + _write_it _head = tend() - _dec_count; + dtor_iter(_head , tend()); + this->_ptrs[_tptr] -= _dec_count; + /*---- shrink underlying buffer, based on size policy */ + switch (_new_alloc ) + { + case __cont::loose_alloc : + { /* do nothing - preserve buffer */ break; } + case __cont::tight_alloc : + { set_alloc(_cur_count - _dec_count); break; } + } + } + +/*---------------------------- set count (_def construct) */ + __inline_call void_type set_count ( + size_type _new_count , + __cont::alloc_types _new_alloc = + __cont::loose_alloc + ) + { + /*----- manipulate the ctor'd range within the buffer */ + size_type _cur_count = count() ; + if(_new_count > _cur_count) + { + inc_count( + _new_count - _cur_count, _new_alloc) ; + } + else + if(_new_count <=_cur_count) + { + dec_count( + _cur_count - _new_count, _new_alloc) ; + } + } + +/*---------------------------- set count (copy construct) */ + __inline_call void_type set_count ( + size_type _new_count , + __cont::alloc_types _new_alloc , + data_type const&_data + ) + { + /*----- manipulate the ctor'd range within the buffer */ + size_type _cur_count = count() ; + if(_new_count > _cur_count) + { + inc_count( + _new_count - _cur_count, _new_alloc, _data); + } + else + if(_new_count <=_cur_count) + { + dec_count( + _cur_count - _new_count, _new_alloc) ; + } + } + +/*-------------------------------- return container alloc */ + __inline_call allocator get_alloc( + ) const + { return static_cast( *this ) ; + } + +/*-------------------------------- return container count */ + __inline_call size_type count ( + ) const + { /* take pointer difference */ + return ( size_type ) + (this->_ptrs[_tptr] - this->_ptrs[_hptr]); + } + +/*-------------------------------- return container alloc */ + __inline_call size_type alloc ( + ) const + { /* take pointer difference */ + return ( size_type ) + (this->_ptrs[_lptr] - this->_ptrs[_hptr]); + } + +/*-------------------------------- true if sequence empty */ + __inline_call bool_type empty ( + ) const + { /* take pointer difference */ + return + this->_ptrs[_hptr]== this->_ptrs[_tptr] ; + } + +/*-------------------------------- const access iterators */ + __inline_call _const_it head ( + ) const + {/*---- return iterator for list head */ + data_type *_ptr = + this->_ptrs[_hptr] != nullptr ? + this->_ptrs[_hptr] : nullptr ; + self_type *_obj = (self_type *)this ; + return _const_it(_ptr, _obj) ; + } + + __inline_call _const_it tail ( + ) const + {/*---- return iterator for list head */ + data_type *_ptr = + this->_ptrs[_tptr] != nullptr ? + this->_ptrs[_tptr]-1: nullptr ; + self_type *_obj = (self_type *)this ; + return _const_it(_ptr, _obj) ; + } + + __inline_call _const_it hend ( + ) const + {/*------ return iterator "past" head */ + data_type *_ptr = + this->_ptrs[_hptr] != nullptr ? + this->_ptrs[_hptr]-1: nullptr ; + self_type *_obj = (self_type *)this ; + return _const_it(_ptr, _obj) ; + } + + __inline_call _const_it tend ( + ) const + {/*------ return iterator "past" tail */ + data_type *_ptr = + this->_ptrs[_tptr] != nullptr ? + this->_ptrs[_tptr] : nullptr ; + self_type *_obj = (self_type *)this ; + return _const_it(_ptr, _obj) ; + } + +/*-------------------------------- write access iterators */ + __inline_call _write_it head ( + ) + { /* return iterator for list head */ + data_type *_ptr = + this->_ptrs[_hptr] != nullptr ? + this->_ptrs[_hptr] : nullptr ; + self_type *_obj = (self_type *)this ; + return _write_it(_ptr, _obj) ; + } + + __inline_call _write_it tail ( + ) + { /* return iterator for list head */ + data_type *_ptr = + this->_ptrs[_tptr] != nullptr ? + this->_ptrs[_tptr]-1: nullptr ; + self_type *_obj = (self_type *)this ; + return _write_it(_ptr, _obj) ; + } + + __inline_call _write_it hend ( + ) + { /* return iterator "past" head */ + data_type *_ptr = + this->_ptrs[_hptr] != nullptr ? + this->_ptrs[_hptr]-1: nullptr ; + self_type *_obj = (self_type *)this ; + return _write_it(_ptr, _obj) ; + } + + __inline_call _write_it tend ( + ) + { /* return iterator "past" tail */ + data_type *_ptr = + this->_ptrs[_tptr] != nullptr ? + this->_ptrs[_tptr] : nullptr ; + self_type *_obj = (self_type *)this ; + return _write_it(_ptr, _obj) ; + } + +/*-------------------------------------- "free" container */ + __inline_call void_type clear ( + __cont::alloc_types _this_alloc = + __cont::loose_alloc + ) + { + if (_this_alloc == __cont::loose_alloc) + set_count(0, _this_alloc) ; + else + set_count(0, _this_alloc) ; + } + +/*---------------------------- push data (_def construct) */ + __inline_call size_type push_tail ( + ) + {/* default construct obj and increment count */ + size_type result = count(); + if (result != alloc()) + { + self_type::construct( + this->_ptrs[_tptr]++) ; + } + else + { + inc_alloc(result + 1) ; + self_type::construct( + this->_ptrs[_tptr]++) ; + } + return result; + } + +/*---------------------------- push data (copy construct) */ + __inline_call size_type push_tail ( + data_type const&_data + ) + {/* copy data onto object and increment count */ + size_type result = count(); + if (result != alloc()) + { + self_type::construct( + this->_ptrs[_tptr]++, + __copy(data_type,_data)) ; + } + else + { + data_type _temp( + __copy(data_type,_data)) ; + + inc_alloc(result + 1) ; + self_type::construct( + this->_ptrs[_tptr]++, + __move(data_type,_temp)) ; + } + return result; + } + +/*---------------------------- push data (move construct) */ + __inline_call size_type push_tail ( + data_type &&_data + ) + {/* move data onto object and increment count */ + size_type result = count(); + if (result != alloc()) + { + self_type::construct( + this->_ptrs[_tptr]++, + __move(data_type,_data)) ; + } + else + { + data_type _temp( + __move(data_type,_data)) ; + + inc_alloc(result + 1) ; + self_type::construct( + this->_ptrs[_tptr]++, + __move(data_type,_temp)) ; + } + return result; + } + +/*---------------------------- push data (copy obj range) */ + template < + typename iter_type + > + __normal_call void_type push_tail ( + iter_type _head, + iter_type _tend + ) + {/* push full sequence at tail and inc. count */ + for(; _head != _tend; ++_head) + { + self_type::push_tail ( *_head); + } + } + +/*--------------------------------------------- _pop data */ + __inline_call void_type _pop_tail ( + ) + { /* _destruct tail item and dec count */ + __assert ( count() != +0 + && "array._pop_tail: empty") ; + + self_type:: + _destruct(--this->_ptrs[_tptr] ) ; + } + +/*--------------------------------------------- _pop data */ + __inline_call void_type _pop_tail ( + data_type &_data + ) + { /* _destruct tail item and dec count */ + __assert ( count() != +0 + && "array._pop_tail: empty") ; + + _data = + std::move(*(this->_ptrs[_tptr]-1)) ; + self_type:: + _destruct(--this->_ptrs[_tptr] ) ; + } + +/*------------------------------------ operator[] (write) */ + __inline_call data_type &operator[] ( + size_type _pos + ) + { + __assert ( _pos >= +0 && + _pos < count() && + "array[]: out of range!" ) ; + + return *(this->_ptrs[_hptr] + _pos) ; + } + +/*------------------------------------ operator[] (const) */ + __inline_call data_type const&operator[] ( + size_type _pos + ) const + { + __assert ( _pos >= +0 && + _pos < count() && + "array[]: out of range!" ) ; + + return *(this->_ptrs[_hptr] + _pos) ; + } + + } ; + +# undef __cont + + + } + +# endif//__ARRAY__ + + + diff --git a/src/libcpp/containers/array_iter.hpp b/src/libcpp/containers/array_iter.hpp index c5f7112..f899577 100644 --- a/src/libcpp/containers/array_iter.hpp +++ b/src/libcpp/containers/array_iter.hpp @@ -1,418 +1,418 @@ - -/* ------------------------------------------------------------- - * "array" iterator -- for contiguous sequences. ------------------------------------------------------------- - * - * ARRAY is a dynamically allocated, contiguous array - * object, where the linear array storage is guaranteed - * to consist of a single block, as returned by malloc, - * etc. Provides O(1) random access, amortarised - * O(log(n)) incremental insertion, etc. This is a - * striped-down implementation -- offering only - * "efficient" operations (no insert, delete, etc). - * ------------------------------------------------------------- - * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) - * - * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The - * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be - * used at your own risk. - * ------------------------------------------------------------- - * - * Last updated: 03 May, 2017 - * - * Copyright 2013-2017 - * Darren Engwirda - * de2363@columbia.edu - * https://github.com/dengwirda/ - * ------------------------------------------------------------- - */ - -# pragma once - -# ifndef __ARRAY_ITER__ -# define __ARRAY_ITER__ - -# include "iter_base.hpp" - - namespace containers { - - template < - typename C , - typename I - > - class array_iterator_base: - public containers::random_iterator_base - { -/* random access iterator for contiguous array containers */ - public : - - typedef C container ; - typedef I iter_type ; - - typedef typename - container::data_type data_type ; - typedef typename - container::diff_type diff_type ; - typedef typename - container::size_type size_type ; - - typedef array_iterator_base < - container , - iter_type > self_type ; - - public : - -# ifdef _DEBUG - data_type* _ptr; // array item - container* _obj; // array obj. -# else - data_type* _ptr; // array item -# endif - - public : - - __inline_call array_iterator_base ( - data_type *_psrc = nullptr, - container *_osrc = nullptr -# ifdef _DEBUG - ) : _ptr(_psrc), - _obj(_osrc) {} - #else - ) : _ptr(_psrc) { __unreferenced(_osrc) ; } -# endif - - __inline_call~array_iterator_base() = default ; - - __inline_call array_iterator_base ( - self_type const&_src - ) = default ; - __inline_call array_iterator_base ( - self_type && _src - ) = default ; - - __inline_call - self_type & operator = ( - self_type const&_src - ) = default ; - __inline_call - self_type & operator = ( - self_type && _src - ) = default ; - -/*--------------------------------- translation operators */ - - __inline_call iter_type& operator++ ( - ) - { /*----------------- pre-increment */ - ++this->_ptr; - return *(iter_type*)this; - } - __inline_call iter_type& operator-- ( - ) - { /*----------------- pre-decrement */ - --this->_ptr; - return *(iter_type*)this; - } - - __inline_call iter_type& operator+= ( - size_type _off - ) - { /*--------------------- increment */ - this->_ptr += _off ; - return *(iter_type*)this; - } - __inline_call iter_type& operator-= ( - size_type _off - ) - { /*--------------------- decrement */ - this->_ptr -= _off ; - return *(iter_type*)this; - } - - __inline_call - iter_type operator++ ( int ) - { /*---------------- post-increment */ - iter_type _tmp(*(iter_type*)this); - ++*this; - return _tmp; - } - __inline_call - iter_type operator-- ( int ) - { /*---------------- post-decrement */ - iter_type _tmp(*(iter_type*)this); - --*this; - return _tmp; - } - - __inline_call iter_type operator + ( - size_type _off - ) - { /*-------------------- add offset */ - iter_type _tmp(*(iter_type*)this); - return _tmp += _off; - } - __inline_call iter_type operator - ( - size_type _off - ) - { /*-------------------- sub offset */ - iter_type _tmp(*(iter_type*)this); - return _tmp -= _off; - } - - __inline_call diff_type operator - ( - self_type const& _src - ) const - { /*----------- iterator difference */ - return this->_ptr - _src._ptr; - } - -/*--------------------------------- comparative operators */ - - __inline_call bool_type operator== ( - self_type const& _src - ) const - { /*--------------------- equal to */ - return this->_ptr == _src._ptr ; - } - __inline_call bool_type operator!= ( - self_type const& _src - ) const - { /*----------------- not equal to */ - return this->_ptr != _src._ptr ; - } - - __inline_call bool_type operator < ( - self_type const& _src - ) const - { /*-------------------- less than */ - return this->_ptr < _src._ptr ; - } - __inline_call bool_type operator > ( - self_type const& _src - ) const - { /*-------------------- more than */ - return this->_ptr > _src._ptr ; - } - - __inline_call bool_type operator<= ( - self_type const& _src - ) const - { /*-------- less than or equal to */ - return this->_ptr <= _src._ptr ; - } - __inline_call bool_type operator>= ( - self_type const& _src - ) const - { /*-------- more than or equal to */ - return this->_ptr >= _src._ptr ; - } - - } ; - - /* - -------------------------------------------------------- - * "const" iterators for contiguous sequences. - -------------------------------------------------------- - */ - - template < - typename C - > - class const_array_iterator: public - array_iterator_base > - { -/* random access iterator for contiguous array containers */ - public : - - typedef C container ; - - typedef const_array_iterator< - container > self_type ; - typedef array_iterator_base < - container , - self_type > base_type ; - - typedef typename - base_type::data_type data_type ; - typedef typename - base_type::diff_type diff_type ; - typedef typename - base_type::size_type size_type ; - - public : - - __inline_call const_array_iterator ( - data_type *_psrc = nullptr, - container *_osrc = nullptr - ) : base_type(_psrc, _osrc) {} - - __inline_call~const_array_iterator()= default ; - - __inline_call const_array_iterator ( - self_type const&_src - ) = default ; - __inline_call const_array_iterator ( - self_type && _src - ) = default ; - - __inline_call - self_type & operator = ( - self_type const&_src - ) = default ; - __inline_call - self_type & operator = ( - self_type && _src - ) = default ; - -/*-------------------------------- "const" access to data */ - - __inline_call data_type const* operator-> ( - ) const - { return &**this ; - } - - __inline_call data_type const& operator[] ( - size_type _pos - ) const - { return *(*this + _pos); - } - - __inline_call data_type const& operator * ( - ) const - { /* return reference to underlying data */ -# ifdef _DEBUG - __assert ( - this->_ptr != nullptr && - "const_array_iterator: null pointer!" ) ; - __assert ( - this->_ptr >= - this->_obj->head()._ptr && - this->_ptr <= - this->_obj->tail()._ptr && - "const_array_iterator: out of range!" ) ; -# endif - return ( *this->_ptr ); - } - - } ; - - /* - ------------------------------------------------------------ - * "write" iterators for contiguous sequences. - ------------------------------------------------------------ - */ - - template < - typename C - > - class write_array_iterator: public - array_iterator_base > - { -/* random access iterator for contiguous array containers */ - public : - - typedef C container ; - - typedef write_array_iterator< - container > self_type ; - typedef array_iterator_base < - container , - self_type > base_type ; - - typedef typename - base_type::data_type data_type ; - typedef typename - base_type::diff_type diff_type ; - typedef typename - base_type::size_type size_type ; - - public : - - __inline_call write_array_iterator ( - data_type *_psrc = nullptr, - container *_osrc = nullptr - ) : base_type(_psrc, _osrc) {} - - __inline_call~write_array_iterator()= default ; - - __inline_call write_array_iterator ( - self_type const&_src - ) = default ; - __inline_call write_array_iterator ( - self_type && _src - ) = default ; - - __inline_call - self_type & operator = ( - self_type const&_src - ) = default ; - __inline_call - self_type & operator = ( - self_type && _src - ) = default ; - -/*-------------------------------- "write" access to data */ - - __inline_call data_type* operator-> ( - ) const - { return &**this ; - } - - __inline_call data_type& operator[] ( - size_type _pos - ) const - { return *(*this + _pos) ; - } - - __inline_call data_type& operator * ( - ) const - { /* return reference to underlying data */ -# ifdef _DEBUG - __assert ( - this->_ptr != nullptr && - "write_array_iterator: null pointer!" ) ; - __assert ( - this->_ptr >= - this->_obj->head()._ptr && - this->_ptr <= - this->_obj->tail()._ptr && - "write_array_iterator: out of range!" ) ; -# endif - return ( *this->_ptr ) ; - } - - } ; - - - } - -# endif //__ARRAY_ITER__ - - - + +/* +------------------------------------------------------------ + * "array" iterator -- for contiguous sequences. +------------------------------------------------------------ + * + * ARRAY is a dynamically allocated, contiguous array + * object, where the linear array storage is guaranteed + * to consist of a single block, as returned by malloc, + * etc. Provides O(1) random access, amortarised + * O(log(n)) incremental insertion, etc. This is a + * striped-down implementation -- offering only + * "efficient" operations (no insert, delete, etc). + * +------------------------------------------------------------ + * + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) + * + * Disclaimer: Neither I nor: Columbia University, The + * Massachusetts Institute of Technology, The + * University of Sydney, nor The National Aeronautics + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be + * used at your own risk. + * +------------------------------------------------------------ + * + * Last updated: 03 May, 2017 + * + * Copyright 2013-2017 + * Darren Engwirda + * de2363@columbia.edu + * https://github.com/dengwirda/ + * +------------------------------------------------------------ + */ + +# pragma once + +# ifndef __ARRAY_ITER__ +# define __ARRAY_ITER__ + +# include "iter_base.hpp" + + namespace containers { + + template < + typename C , + typename I + > + class array_iterator_base: + public containers::random_iterator_base + { +/* random access iterator for contiguous array containers */ + public : + + typedef C container ; + typedef I iter_type ; + + typedef typename + container::data_type data_type ; + typedef typename + container::diff_type diff_type ; + typedef typename + container::size_type size_type ; + + typedef array_iterator_base < + container , + iter_type > self_type ; + + public : + +# ifdef _DEBUG + data_type* _ptr; // array item + container* _obj; // array obj. +# else + data_type* _ptr; // array item +# endif + + public : + + __inline_call array_iterator_base ( + data_type *_psrc = nullptr, + container *_osrc = nullptr +# ifdef _DEBUG + ) : _ptr(_psrc), + _obj(_osrc) {} + #else + ) : _ptr(_psrc) { __unreferenced(_osrc) ; } +# endif + + __inline_call~array_iterator_base() = default ; + + __inline_call array_iterator_base ( + self_type const&_src + ) = default ; + __inline_call array_iterator_base ( + self_type && _src + ) = default ; + + __inline_call + self_type & operator = ( + self_type const&_src + ) = default ; + __inline_call + self_type & operator = ( + self_type && _src + ) = default ; + +/*--------------------------------- translation operators */ + + __inline_call iter_type& operator++ ( + ) + { /*----------------- pre-increment */ + ++this->_ptr; + return *(iter_type*)this; + } + __inline_call iter_type& operator-- ( + ) + { /*----------------- pre-decrement */ + --this->_ptr; + return *(iter_type*)this; + } + + __inline_call iter_type& operator+= ( + size_type _off + ) + { /*--------------------- increment */ + this->_ptr += _off ; + return *(iter_type*)this; + } + __inline_call iter_type& operator-= ( + size_type _off + ) + { /*--------------------- decrement */ + this->_ptr -= _off ; + return *(iter_type*)this; + } + + __inline_call + iter_type operator++ ( int ) + { /*---------------- post-increment */ + iter_type _tmp(*(iter_type*)this); + ++*this; + return _tmp; + } + __inline_call + iter_type operator-- ( int ) + { /*---------------- post-decrement */ + iter_type _tmp(*(iter_type*)this); + --*this; + return _tmp; + } + + __inline_call iter_type operator + ( + size_type _off + ) + { /*-------------------- add offset */ + iter_type _tmp(*(iter_type*)this); + return _tmp += _off; + } + __inline_call iter_type operator - ( + size_type _off + ) + { /*-------------------- sub offset */ + iter_type _tmp(*(iter_type*)this); + return _tmp -= _off; + } + + __inline_call diff_type operator - ( + self_type const& _src + ) const + { /*----------- iterator difference */ + return this->_ptr - _src._ptr; + } + +/*--------------------------------- comparative operators */ + + __inline_call bool_type operator== ( + self_type const& _src + ) const + { /*--------------------- equal to */ + return this->_ptr == _src._ptr ; + } + __inline_call bool_type operator!= ( + self_type const& _src + ) const + { /*----------------- not equal to */ + return this->_ptr != _src._ptr ; + } + + __inline_call bool_type operator < ( + self_type const& _src + ) const + { /*-------------------- less than */ + return this->_ptr < _src._ptr ; + } + __inline_call bool_type operator > ( + self_type const& _src + ) const + { /*-------------------- more than */ + return this->_ptr > _src._ptr ; + } + + __inline_call bool_type operator<= ( + self_type const& _src + ) const + { /*-------- less than or equal to */ + return this->_ptr <= _src._ptr ; + } + __inline_call bool_type operator>= ( + self_type const& _src + ) const + { /*-------- more than or equal to */ + return this->_ptr >= _src._ptr ; + } + + } ; + + /* + -------------------------------------------------------- + * "const" iterators for contiguous sequences. + -------------------------------------------------------- + */ + + template < + typename C + > + class const_array_iterator: public + array_iterator_base > + { +/* random access iterator for contiguous array containers */ + public : + + typedef C container ; + + typedef const_array_iterator< + container > self_type ; + typedef array_iterator_base < + container , + self_type > base_type ; + + typedef typename + base_type::data_type data_type ; + typedef typename + base_type::diff_type diff_type ; + typedef typename + base_type::size_type size_type ; + + public : + + __inline_call const_array_iterator ( + data_type *_psrc = nullptr, + container *_osrc = nullptr + ) : base_type(_psrc, _osrc) {} + + __inline_call~const_array_iterator()= default ; + + __inline_call const_array_iterator ( + self_type const&_src + ) = default ; + __inline_call const_array_iterator ( + self_type && _src + ) = default ; + + __inline_call + self_type & operator = ( + self_type const&_src + ) = default ; + __inline_call + self_type & operator = ( + self_type && _src + ) = default ; + +/*-------------------------------- "const" access to data */ + + __inline_call data_type const* operator-> ( + ) const + { return &**this ; + } + + __inline_call data_type const& operator[] ( + size_type _pos + ) const + { return *(*this + _pos); + } + + __inline_call data_type const& operator * ( + ) const + { /* return reference to underlying data */ +# ifdef _DEBUG + __assert ( + this->_ptr != nullptr && + "const_array_iterator: null pointer!" ) ; + __assert ( + this->_ptr >= + this->_obj->head()._ptr && + this->_ptr <= + this->_obj->tail()._ptr && + "const_array_iterator: out of range!" ) ; +# endif + return ( *this->_ptr ); + } + + } ; + + /* + ------------------------------------------------------------ + * "write" iterators for contiguous sequences. + ------------------------------------------------------------ + */ + + template < + typename C + > + class write_array_iterator: public + array_iterator_base > + { +/* random access iterator for contiguous array containers */ + public : + + typedef C container ; + + typedef write_array_iterator< + container > self_type ; + typedef array_iterator_base < + container , + self_type > base_type ; + + typedef typename + base_type::data_type data_type ; + typedef typename + base_type::diff_type diff_type ; + typedef typename + base_type::size_type size_type ; + + public : + + __inline_call write_array_iterator ( + data_type *_psrc = nullptr, + container *_osrc = nullptr + ) : base_type(_psrc, _osrc) {} + + __inline_call~write_array_iterator()= default ; + + __inline_call write_array_iterator ( + self_type const&_src + ) = default ; + __inline_call write_array_iterator ( + self_type && _src + ) = default ; + + __inline_call + self_type & operator = ( + self_type const&_src + ) = default ; + __inline_call + self_type & operator = ( + self_type && _src + ) = default ; + +/*-------------------------------- "write" access to data */ + + __inline_call data_type* operator-> ( + ) const + { return &**this ; + } + + __inline_call data_type& operator[] ( + size_type _pos + ) const + { return *(*this + _pos) ; + } + + __inline_call data_type& operator * ( + ) const + { /* return reference to underlying data */ +# ifdef _DEBUG + __assert ( + this->_ptr != nullptr && + "write_array_iterator: null pointer!" ) ; + __assert ( + this->_ptr >= + this->_obj->head()._ptr && + this->_ptr <= + this->_obj->tail()._ptr && + "write_array_iterator: out of range!" ) ; +# endif + return ( *this->_ptr ) ; + } + + } ; + + + } + +# endif //__ARRAY_ITER__ + + + diff --git a/src/libcpp/containers/arraylist.hpp b/src/libcpp/containers/arraylist.hpp index 7cb5e99..6e26d0b 100644 --- a/src/libcpp/containers/arraylist.hpp +++ b/src/libcpp/containers/arraylist.hpp @@ -4,35 +4,35 @@ * an array of linked-lists. ------------------------------------------------------------ * - * ARRAY-LIST is a linear array of singly-linked list - * objects. It's useful as a base-class for HASH-TABLE + * ARRAY-LIST is a linear array of singly-linked list + * objects. It's useful as a base-class for HASH-TABLE * like implementations, amongst other things... * ------------------------------------------------------------ * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * ------------------------------------------------------------ @@ -46,7 +46,7 @@ * ------------------------------------------------------------ */ - + # pragma once # ifndef __ARRAY_LIST__ @@ -63,23 +63,23 @@ typename T , typename A = allocators::basic_alloc > - class array_list : public + class array_list : public allocators::_item_alloc < single_item < T>, A > { /*----------------------- a dynamic array of linked-lists */ - public : - + public : + typedef T data_type ; typedef A allocator ; - - typedef typename + + typedef typename allocator::size_type size_type ; - typedef typename + typedef typename allocator::diff_type diff_type ; typedef containers::array_list < - data_type, + data_type, allocator > self_type ; typedef containers::single_item < @@ -87,12 +87,12 @@ typedef containers::const_single_iterator < self_type > _const_it ; - + typedef containers::write_single_iterator < self_type > _write_it ; typedef allocators::_item_alloc < - item_type, + item_type, allocator > item_pool ; typedef containers::array < @@ -100,52 +100,52 @@ allocator > lptr_list ; public : - + lptr_list _lptr; size_type _size; public : - + /* -------------------------------------------------------- MAKE-ITEM (helper): _new/construct a node. -------------------------------------------------------- */ - + __inline_call void_type make_item (// copy data_type const&_data, item_type *& _item ) { - _item = self_type::allocate(1); + _item = self_type::allocate(1); self_type::construct(_item, - nullptr, //link! + nullptr, //link! __copy(data_type,_data) ) ; } - + __inline_call void_type make_item (// move data_type && _data, item_type *& _item ) { - _item = self_type::allocate(1); + _item = self_type::allocate(1); self_type::construct(_item, - nullptr, //link! + nullptr, //link! __move(data_type,_data) ) ; } - + /* -------------------------------------------------------- FREE-ITEM (helper): _destruct/free a node. -------------------------------------------------------- */ - + __inline_call void_type free_item ( item_type *_item ) { - self_type:: _destruct(_item); + self_type:: _destruct(_item); self_type::deallocate(_item,+1) ; } @@ -154,7 +154,7 @@ PUSH/_POP-ITEM (helper): push/_pop item onto list. -------------------------------------------------------- */ - + __inline_call void_type push_item ( item_type*&_head, item_type *_item @@ -164,7 +164,7 @@ _item->_next = _head; _head =_item ; } - + __inline_call void_type _pop_item ( item_type*&_head, item_type *_item, @@ -173,22 +173,22 @@ { if (_prev != nullptr) /*--------------------------------- relink about item */ - _prev->_next = - _item->_next ; + _prev->_next = + _item->_next ; else /*--------------------------------- relink about head */ - _head = + _head = _item->_next ; } - + public : - + /* -------------------------------------------------------- * container c'tor's/d'tor's/assignment op's etc. -------------------------------------------------------- */ - + __inline_call array_list ( allocator const&_asrc = allocator() /*----------------------------- c'tor alloc from obj. */ @@ -196,46 +196,46 @@ /*----------------------------- c'tor other from obj. */ _lptr(_asrc) , _size(+0) {} - + __inline_call ~array_list ( ) { clear () ; } -/*-------------------------------------------- move c'tor */ +/*-------------------------------------------- move c'tor */ __inline_call array_list ( self_type && _src - ) : item_pool( + ) : item_pool( __move(item_pool,_src)) { - this->_lptr = + this->_lptr = std::move(_src. _lptr); - - this->_size = - _src. _size ; + + this->_size = + _src. _size ; _src. _size = +0 ; } /*-------------------------------------------- copy c'tor */ __inline_call array_list ( self_type const&_src - ) : item_pool( + ) : item_pool( __copy(item_pool,_src)) { /*--------------------------------- build a full copy */ this->_lptr.set_count( _src._lptr.count() , containers::tight_alloc,nullptr); - + size_type _lpos = +0 ; - + typename lptr_list::_const_it _iter = _src._lptr.head(), _tend = _src._lptr.tend(); - for( ; _iter != _tend; + for( ; _iter != _tend; ++_iter, ++_lpos) { /*--------------------------------- if non-empty list */ if (*_iter == nullptr) continue ; - + item_type *_next =*_iter ; item_type *_item = nullptr ; item_type *_head = nullptr ; @@ -245,21 +245,21 @@ { make_item( _next->_data, _item) ; - + if (_prev == nullptr) _head =_item ; else _prev->_next = _item; - - _prev =_item ; + + _prev =_item ; _next =_next-> _next; - + this->_size += 1 ; } this->_lptr[_lpos] = _head ; - } + } } - + /*-------------------------------------------- copy a-op. */ __inline_call self_type& operator = ( self_type const& _src @@ -275,12 +275,12 @@ static_cast(*this), static_cast(_copy)) ; - swap(this->_size, + swap(this->_size, _copy. _size) ; - swap(this->_lptr, + swap(this->_lptr, _copy. _lptr) ; } - + return ( *this ) ; } @@ -299,12 +299,12 @@ static_cast(*this), static_cast(_copy)) ; - swap(this->_size, + swap(this->_size, _copy. _size) ; - swap(this->_lptr, + swap(this->_lptr, _copy. _lptr) ; } - + return ( *this ) ; } @@ -313,7 +313,7 @@ * GET-ALLOC: return container alloc. -------------------------------------------------------- */ - + __inline_call allocator get_alloc( ) const { return static_cast(*this); @@ -324,9 +324,9 @@ * CLEAR: clear container lists + backing array. -------------------------------------------------------- */ - + __normal_call void_type clear ( - containers::alloc_types _kind = + containers::alloc_types _kind = containers::loose_alloc ) { @@ -335,14 +335,14 @@ /*------------------------------ resize backing array */ this->_lptr .clear(_kind) ; } - + __normal_call void_type empty ( - containers::alloc_types _kind = + containers::alloc_types _kind = containers::loose_alloc ) { __unreferenced(_kind); - + /*------------------------------ clear lists of items */ typename lptr_list::_write_it _iter = this->_lptr.head(), @@ -351,87 +351,87 @@ { /*----------------------------- if non-empty list */ if (*_iter == nullptr) continue ; - + item_type*_item =*_iter ; item_type*_next ; /*----------------------------- free current list */ - for(;_item != nullptr; + for(;_item != nullptr; _item = _next) { - _next = _item->_next ; - + _next = _item->_next ; + free_item(_item) ; this->_size -= 1 ; } } } - + /* -------------------------------------------------------- * COUNT: return container count. -------------------------------------------------------- */ - + __inline_call size_type count ( - ) const - { return this->_size ; + ) const + { return this->_size ; } - + __inline_call bool_type empty ( size_type _lpos ) const { return this-> _lptr[_lpos]==nullptr ; } - + /* -------------------------------------------------------- * HEAD/TEND: return iterator range. -------------------------------------------------------- */ - + __inline_call _const_it head ( size_type _lpos ) const { return _const_it(this->_lptr[_lpos], this) ; } - + __inline_call _write_it head ( size_type _lpos ) { return _write_it(this->_lptr[_lpos], this) ; } - + __inline_call _const_it hend ( size_type //_lpos ) const { return _const_it(nullptr , this); } - + __inline_call _write_it hend ( size_type //_lpos ) { return _write_it(nullptr , this); } - + __inline_call _const_it tend ( size_type //_lpos ) const { return _const_it(nullptr , this); } - + __inline_call _write_it tend ( size_type //_lpos ) { return _write_it(nullptr , this); } - + /* -------------------------------------------------------- * _POP: "_pop" data from container. -------------------------------------------------------- */ - + __inline_call void_type _pop ( _write_it _prev, _write_it _item, @@ -440,21 +440,21 @@ { item_type *_iptr=_item.item() ; item_type *_pptr=_prev.item() ; - + this->_size -= +1 ; - + _pop_item(this->_lptr [_lpos] , _iptr, _pptr) ; - + free_item( _iptr) ; } - + /* -------------------------------------------------------- * PUSH: "push" data onto container. -------------------------------------------------------- */ - + __inline_call _write_it push ( // copy data_type const&_data, size_type _lpos @@ -462,17 +462,17 @@ { this->_size += +1 ; if (_lpos >= this->_lptr.count()) - this->_lptr.set_count( _lpos + 1, + this->_lptr.set_count( _lpos + 1, containers::loose_alloc, nullptr) ; - + item_type*_item = nullptr ; make_item(_data , _item); push_item( this-> _lptr[_lpos], _item); - + return _write_it (_item, this) ; } - + __inline_call _write_it push ( // move data_type && _data, size_type _lpos @@ -480,17 +480,17 @@ { this->_size += +1 ; if (_lpos >= this->_lptr.count()) - this->_lptr.set_count( _lpos + 1, + this->_lptr.set_count( _lpos + 1, containers::loose_alloc, nullptr) ; - + item_type*_item = nullptr ; make_item(_data , _item); push_item( this-> _lptr[_lpos], _item); - + return _write_it (_item, this) ; } - + } ; # undef __cont @@ -498,7 +498,7 @@ } -# endif //__ARRAY_LIST__ - - - +# endif //__ARRAY_LIST__ + + + diff --git a/src/libcpp/containers/basic_stack.hpp b/src/libcpp/containers/basic_stack.hpp index a30cb81..64ece32 100644 --- a/src/libcpp/containers/basic_stack.hpp +++ b/src/libcpp/containers/basic_stack.hpp @@ -4,37 +4,37 @@ * a singly-linked list object. ------------------------------------------------------------ * - * BASIC-STACK is a "singly-linked" list type, where - * list items comprise a singly-oriented chain of - * pointers. This variant only supports singly-oriented - * manipulation. Insertion/deletion is O(1), acccess is - * O(N). List count is NOT stored! + * BASIC-STACK is a "singly-linked" list type, where + * list items comprise a singly-oriented chain of + * pointers. This variant only supports singly-oriented + * manipulation. Insertion/deletion is O(1), acccess is + * O(N). List count is NOT stored! * ------------------------------------------------------------ * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * ------------------------------------------------------------ @@ -64,42 +64,42 @@ typename D , typename A = allocators::basic_alloc > - class basic_stack : public + class basic_stack : public allocators::_item_alloc < single_item < D>, A > { /*------ single-ended linked-list for singly-linked items */ public : - + typedef D data_type ; typedef A allocator ; typedef containers::basic_stack < - data_type , + data_type , allocator > self_type ; typedef containers::single_item < data_type > item_type ; typedef allocators::_item_alloc < - item_type , + item_type , allocator > obj_alloc ; typedef containers::const_single_iterator < self_type > _const_it ; typedef containers::write_single_iterator < self_type > _write_it ; - - typedef typename + + typedef typename allocator::size_type size_type ; - typedef typename + typedef typename allocator::diff_type diff_type ; private : item_type* _hptr ; // head/tail pointers - + private : - + /*------------------------------ helper - construct range */ template < typename iter_type @@ -110,10 +110,10 @@ __cont::base_iterator_kind ) { /* push the sequence onto list */ - for ( ; _head != _tend; ++_head) + for ( ; _head != _tend; ++_head) push_tail(*_head) ; } - + __inline_call void_type copy_list ( size_type _size , data_type const& _dsrc, @@ -121,13 +121,13 @@ ) { copy_data(_size, _dsrc); } - + __normal_call void_type copy_data ( size_type _size, data_type const& _dsrc ) { /* push _size copies onto list */ - for ( ; _size-- != 0; ) + for ( ; _size-- != 0; ) push_head(_dsrc); } @@ -164,7 +164,7 @@ copy_list(_head,_tail, __cont::iter_kind(_head)) ; } - + /*-------------------------------------------- _def d'tor */ __inline_call~basic_stack ( ) { clear() ; } @@ -172,7 +172,7 @@ /*-------------------------------------------- copy c'tor */ __inline_call basic_stack ( self_type const& _src - ) : obj_alloc( + ) : obj_alloc( __copy(obj_alloc,_src)) { this->_hptr = nullptr ; @@ -183,18 +183,18 @@ copy_list(_head,_tail, __cont::iter_kind(_head)) ; } - + /*-------------------------------------------- move c'tor */ __inline_call basic_stack ( self_type && _src - ) : obj_alloc( + ) : obj_alloc( __move(obj_alloc,_src)) { /*------------------------------- move data from _src */ this->_hptr = _src._hptr ; _src. _hptr = nullptr ; } - + /*-------------------------------------------- copy a-op. */ __inline_call self_type& operator = ( self_type const& _src @@ -210,13 +210,13 @@ static_cast(*this), static_cast(_copy)) ; - swap(this->_hptr, + swap(this->_hptr, _copy. _hptr) ; } - + return ( *this ) ; } - + /*-------------------------------------------- move a-op. */ __inline_call self_type &operator = ( self_type && _src @@ -232,28 +232,28 @@ static_cast(*this), static_cast(_copy)) ; - swap(this->_hptr, + swap(this->_hptr, _copy. _hptr) ; } - + return ( *this ) ; } - + /*-------------------------------- true if sequence empty */ __inline_call bool_type empty ( ) const { /* return empty status */ return ( nullptr == this->_hptr ) ; } - + /*-------------------------------- return container alloc */ __inline_call allocator get_alloc ( ) const - { - return + { + return static_cast( *this ) ; } - + /*------------------------------ "const" access iterators */ __inline_call _const_it head ( ) const @@ -261,7 +261,7 @@ self_type *_obj = (self_type *)this; return _const_it(this->_hptr, _obj); } - + __inline_call _const_it tend ( ) const {/* return iterator "past" tail, via null terminator! */ @@ -276,24 +276,24 @@ self_type *_obj = (self_type *)this; return _write_it(this->_hptr, _obj); } - + __inline_call _write_it tend ( ) {/* return iterator "past" tail, via null terminator! */ self_type *_obj = (self_type *)this; return _write_it(nullptr, _obj) ; } - + /*-------------------------------------- "free" container */ __normal_call void_type clear ( - ) + ) {/* _pop all items in traversal from head */ _write_it _head = head(); _write_it _tend = tend(); for ( ; _head != _tend; ) { _write_it _prev(_head++) ; - self_type:: + self_type:: _destruct(_prev.item()) ; self_type:: deallocate(_prev.item(),1) ; @@ -305,48 +305,48 @@ __inline_call _write_it push_head ( ) {/* allocate and construct a new raw item */ - item_type *_this_item = - self_type::allocate(1); - self_type::construct(_this_item, + item_type *_this_item = + self_type::allocate(1); + self_type::construct(_this_item, this->_hptr) ; this->_hptr = _this_item ; - return + return _write_it(_this_item,(self_type*)this) ; } - + /*---------------------------- push data (copy construct) */ __inline_call _write_it push_head ( data_type const&_data ) {/* allocate and construct a new raw item */ - item_type *_this_item = - self_type::allocate(1); - self_type::construct(_this_item, - this->_hptr,//link! + item_type *_this_item = + self_type::allocate(1); + self_type::construct(_this_item, + this->_hptr,//link! __copy(data_type,_data)) ; this->_hptr = _this_item ; - - return + + return _write_it(_this_item,(self_type*)this) ; } - + /*---------------------------- push data (move construct) */ __inline_call _write_it push_head ( data_type &&_data ) {/* allocate and construct a new raw item */ - item_type *_this_item = - self_type::allocate(1); - self_type::construct(_this_item, - this->_hptr,//link! + item_type *_this_item = + self_type::allocate(1); + self_type::construct(_this_item, + this->_hptr,//link! __move(data_type,_data)) ; this->_hptr = _this_item ; - - return + + return _write_it(_this_item,(self_type*)this) ; } @@ -357,15 +357,15 @@ __assert( this->_hptr != nullptr && "single_list._pop_head: null ptr"); /* shuffle next item onto list _head */ - item_type *_head_item = + item_type *_head_item = this->_hptr ; this->_hptr = _head_item->next(); /* _destruct and deallocate old head */ - self_type:: _destruct(_head_item) ; + self_type:: _destruct(_head_item) ; self_type::deallocate(_head_item,1) ; } - + /*--------------------------------------------- _pop data */ __inline_call void_type _pop_head ( data_type &_data @@ -386,25 +386,25 @@ ) { item_type *_prev_item, *_next_item ; - if ((_prev_item = + if ((_prev_item = _prev_iter. item()) == nullptr) { /*----- push onto list head */ return push_head() ; } else { /* insert in middle of list */ - item_type *_this_item = - self_type::allocate(1); + item_type *_this_item = + self_type::allocate(1); self_type::construct( _this_item, _next_item); - + _prev_item->next() = _this_item; - + return _write_it( _this_item, (self_type*)this); } } - + /*-------------------------- insert data (copy construct) */ __normal_call _write_it insert_next ( _write_it _prev_iter, @@ -412,7 +412,7 @@ ) { item_type *_prev_item, *_next_item ; - if ((_prev_item = + if ((_prev_item = _prev_iter. item()) == nullptr) { /*----- push onto list head */ return push_head( @@ -420,19 +420,19 @@ } else { /* insert in middle of list */ - item_type *_this_item = - self_type::allocate(1); - self_type::construct(_this_item, + item_type *_this_item = + self_type::allocate(1); + self_type::construct(_this_item, _next_item, //link! __copy(data_type,_data)) ; - + _prev_item->next() = _this_item; - + return _write_it( _this_item, (self_type*)this); } } - + /*-------------------------- insert data (move construct) */ __normal_call _write_it insert_next ( _write_it _prev_iter, @@ -440,7 +440,7 @@ ) { item_type *_prev_item, *_next_item ; - if ((_prev_item = + if ((_prev_item = _prev_iter. item()) == nullptr) { /*----- push onto list head */ return push_head( @@ -448,14 +448,14 @@ } else { /* insert in middle of list */ - item_type *_this_item = - self_type::allocate(1); - self_type::construct(_this_item, + item_type *_this_item = + self_type::allocate(1); + self_type::construct(_this_item, _next_item, //link! __move(data_type,_data)) ; - - _prev_item->next() = _this_item; - + + _prev_item->next() = _this_item; + return _write_it( _this_item, (self_type*)this); } @@ -467,11 +467,11 @@ _write_it _this_iter ) { - __assert ( + __assert ( _this_iter.item() != nullptr && "list.erase: null iterator!"); /* _pop item, re-link, _destruct//deallocate */ - item_type + item_type *_this_item = _this_iter. item() , *_prev_item = _prev_iter. item() , *_prev_next = _prev_item->next() , @@ -479,26 +479,26 @@ if (_prev_item == nullptr) {/* re-link item neighbours at list head */ - __assert ( + __assert ( this->_hptr == _this_item && - "list.erase: _bad iterator!" ) ; + "list.erase: _bad iterator!" ) ; this->_hptr = _next_item ; } - else + else {/* re-link item neighbours in list mid */ - __assert ( + __assert ( _prev_next == _this_item && - "list.erase: _bad iterator!" ) ; - _prev_item->next() + "list.erase: _bad iterator!" ) ; + _prev_item->next() = _next_item ; } - - self_type:: _destruct(_this_item) ; + + self_type:: _destruct(_this_item) ; self_type::deallocate(_this_item,1) ; } } ; - + # undef __cont diff --git a/src/libcpp/containers/block_array.hpp b/src/libcpp/containers/block_array.hpp index 66d4cf2..d97e0bf 100644 --- a/src/libcpp/containers/block_array.hpp +++ b/src/libcpp/containers/block_array.hpp @@ -1,841 +1,840 @@ - -/* ------------------------------------------------------------- - * a dynamically-allocated, "block-wise" array object. ------------------------------------------------------------- - * - * BLOCK-ARRAY is a block-wise array implementation, - * where the linear array storage is broken across - * non-contiguous "blocks" in memory. It is otherwise - * equivalent to a standard array interface. The blocked - * data-structure can be helpful for very large - * dynamically-resizable arrays, since memory is only - * re-alloc'd on the block level. Peformance asymptotics - * are equivalent to the standard arry object, with - * larger constant factors. - * ------------------------------------------------------------- - * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) - * - * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The - * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be - * used at your own risk. - * ------------------------------------------------------------- - * - * Last updated: 03 May, 2017 - * - * Copyright 2013-2017 - * Darren Engwirda - * de2363@columbia.edu - * https://github.com/dengwirda/ - * ------------------------------------------------------------- - */ - -# pragma once - -# ifndef __BLOCK_ARRAY__ -# define __BLOCK_ARRAY__ - -# include "block_iter.hpp" - - namespace containers { - -# define __cont containers - - template < - typename D , - typename A = allocators::basic_alloc - > - class block_array - { -/*------ a dynamically allocated, block-wise array object */ - public : - typedef D data_type ; - typedef A allocator ; - - typedef __cont::block_array < - data_type , - allocator > self_type ; - - typedef typename - allocator::size_type size_type ; - typedef typename - allocator::diff_type diff_type ; - - typedef __cont::const_block_iterator < - self_type > _const_it ; - typedef __cont::write_block_iterator < - self_type > _write_it ; - - typedef __cont::array < - data_type , - allocator > leaf_type ; - typedef __cont::array < - leaf_type , - allocator > root_type ; - - size_type static const _sizt = sizeof(data_type) ; - size_type static const _sizb = (64*1024)/_sizt; - size_type static const _size = (_sizb>4)?_sizb:4 ; - - private : - - root_type _block ; - size_type _count ; - size_type _alloc ; - - /* - -------------------------------------------------------- - * INC-ALLOC: helper - broaden storage. - -------------------------------------------------------- - */ - - __normal_call void_type inc_alloc ( - size_type _new_count - ) - { - if (_new_count <= alloc()) return ; - /*-------------------------- alloc. storage in blocks */ - size_type _new_alloc = alloc(); - if (_new_count <= _size) - { /* grow allocation as multiples of two */ - _new_alloc = - std::max(_new_alloc * 2, _new_count); - } - else - { /* round to the nearest block boundary */ - _new_alloc = - ((_new_count / _size) + 1) * _size ; - } - set_alloc(_new_alloc) ; - } - - /* - -------------------------------------------------------- - * COPY-ITER: helper - construct range. - -------------------------------------------------------- - */ - - template < - typename iter_type - > - __normal_call void_type copy_iter ( - iter_type _head, - iter_type _tail, - __cont::base_iterator_kind - ) - { /* copy range onto object */ - for(; _head != _tail; ++_head) - { - push_tail(*_head) ; - } - } - - __inline_call void_type copy_iter ( - size_type _size, - data_type const& _dsrc, - __cont::null_iterator_kind - ) - { /* copy _data onto object */ - set_count(_size, - __cont::tight_alloc, _dsrc) ; - } - - public : - - /* - -------------------------------------------------------- - * Container c'tor's/d'tor's/assignment op's, etc - -------------------------------------------------------- - */ - - __inline_call block_array ( - allocator const&_asrc = allocator() - ) : _block( _asrc) - { - /*----------------------- default c'tor - do nothing! */ - this->_count = +0; - this->_alloc = +0; - } - - __inline_call block_array ( - size_type _size, - data_type const&_dsrc = data_type(), - allocator const&_asrc = allocator() - ) : _block( _asrc) - { - /*----------------------- default c'tor - initialisor */ - this->_count = +0; - this->_alloc = +0; - copy_iter(_size,_dsrc, - __cont::null_iterator_kind ()) ; - } - - template < - typename iter_type - > - __inline_call block_array ( - iter_type _head, - iter_type _tail, - allocator const&_asrc = allocator() - ) : _block( _asrc) - { - /*----------------------- default c'tor - initialisor */ - this->_count = +0; - this->_alloc = +0; - copy_iter(_head,_tail, - __cont::iter_kind( _head)) ; - } - - __inline_call~block_array ( - ) - /*---------------------------------------- _def d'tor */ - { set_count(0,__cont::tight_alloc) ; - } - -/*-------------------------------------------- copy c'tor */ - __inline_call block_array ( - self_type const&_src - ) = default ; -/*-------------------------------------------- move c'tor */ - __inline_call block_array ( - self_type && _src - ) : _block(std::move(_src._block) ) - { - this->_alloc = - _src. _alloc ; - _src. _alloc = +0u ; - - this->_count = - _src. _count ; - _src. _count = +0u ; - } - -/*-------------------------------------------- copy a-op. */ - __inline_call - self_type & operator = ( - self_type const&_src - ) = default ; -/*-------------------------------------------- move a-op. */ - __inline_call - self_type & operator = ( - self_type && _src - ) - { - if (this != &_src) - { - using std::swap ; - self_type _copy ( - __move(self_type , _src)) ; - - swap(this->_block, - _copy. _block) ; - swap(this->_count, - _copy. _count) ; - swap(this->_alloc, - _copy. _alloc) ; - } - - return ( *this ) ; - } - - /* - -------------------------------------------------------- - * SET-ALLOC: push new array alloc. - -------------------------------------------------------- - */ - - __normal_call void_type set_alloc ( - size_type _new_alloc - ) - { - size_type _cur_count = count(); - size_type _cur_alloc = alloc(); - - size_type _cur_block = +0; - size_type _new_block = +0; - size_type _end_block = +0; - size_type _end_shift = +0; - - size_type _siz_block = _size ; - size_type _nil_block = +0 ; - - if (_new_alloc < _cur_count ) - { - /*--------------- _destruct un-needed range first */ - set_count(_new_alloc, - __cont::loose_alloc) ; - } - - if (_cur_alloc!=+0) - { - /*-------------- calc. block-wise storage offsets */ - _cur_block = - (_cur_alloc - 1) / _size + 0 ; - } - if (_new_alloc!=+0) - { - _new_block = - (_new_alloc - 1) / _size + 0 ; - _end_block = - (_new_alloc - 1) / _size + 1 ; - _end_shift = - (_new_alloc - 1) % _size + 1 ; - } - - if (_new_alloc < _cur_alloc ) - { - /*--------------- _pop old blocks and realloc end */ - size_type _pos_block ; - for(_pos_block=_cur_block; - _pos_block>_new_block; - --_pos_block ) - { - this->_block [_pos_block]. - set_alloc(_nil_block); - } - this->_block [_new_block]. - set_alloc(_end_shift); - - this->_block.set_count ( - _end_block, __cont::loose_alloc) ; - - this->_alloc =_new_alloc ; - } - else - if (_new_alloc > _cur_alloc ) - { - /*--------------- push new blocks and realloc end */ - this->_block.set_count ( - _end_block, __cont::loose_alloc, - leaf_type(this->_block.get_alloc())) ; - - size_type _pos_block ; - for(_pos_block=_cur_block; - _pos_block<_new_block; - ++_pos_block ) - { - this->_block [_pos_block]. - set_alloc(_siz_block); - } - this->_block [_new_block]. - set_alloc(_end_shift); - - this->_alloc =_new_alloc ; - } - } - - /* - -------------------------------------------------------- - * FIX-ALLOC: trim current alloc to count. - -------------------------------------------------------- - */ - - __inline_call void_type fix_alloc ( - ) { set_alloc(count()) ; } - - /* - -------------------------------------------------------- - * INC-COUNT: increment container count. - -------------------------------------------------------- - */ - - __normal_call void_type inc_count ( // _def-construct - size_type _inc_count , - __cont::alloc_types _new_alloc = - __cont::loose_alloc - ) - { - size_type _cur_count = count() ; - size_type _new_count = count() + - _inc_count ; - - size_type _cur_block = +0; - size_type _new_block = +0; - size_type _end_shift = +0; - - size_type _siz_block = _size ; - - /*------------------ calc. block-wise storage offsets */ - if (_cur_count!=+0) - { - _cur_block = - (_cur_count - 1) / _size + 0; - } - if (_new_count!=+0) - { - _new_block = - (_new_count - 1) / _size + 0; - _end_shift = - (_new_count - 1) % _size + 1; - } - - /*--------- expand underlying buffer, based on policy */ - switch (_new_alloc ) - { - case __cont::loose_alloc : - { inc_alloc(_cur_count + _inc_count); break ; } - case __cont::tight_alloc : - { set_alloc(_cur_count + _inc_count); break ; } - } - /*--------- update block structure and ctor new items */ - for(size_type _pos_block = _cur_block; - _pos_block < _new_block; - ++_pos_block ) - { - this->_block [_pos_block].set_count( - _siz_block, __cont::loose_alloc) ; - } - if (_new_count!=+0) - { - this->_block [_new_block].set_count( - _end_shift, __cont::loose_alloc) ; - } - - this->_count =_new_count ; - } - - /* - -------------------------------------------------------- - * INC-COUNT: increment container count. - -------------------------------------------------------- - */ - - __normal_call void_type inc_count ( // copy-construct - size_type _inc_count , - __cont::alloc_types _new_alloc , - data_type const&_data - ) - { - size_type _cur_count = count() ; - size_type _new_count = count() + - _inc_count ; - - size_type _cur_block = +0; - size_type _new_block = +0; - size_type _end_shift = +0; - - size_type _siz_block = _size ; - - /*------------------ calc. block-wise storage offsets */ - if (_cur_count!=+0) - { - _cur_block = - (_cur_count - 1) / _size + 0; - } - if (_new_count!=+0) - { - _new_block = - (_new_count - 1) / _size + 0; - _end_shift = - (_new_count - 1) % _size + 1; - } - - /*--------- expand underlying buffer, based on policy */ - switch (_new_alloc ) - { - case __cont::loose_alloc : - { inc_alloc(_cur_count + _inc_count); break ; } - case __cont::tight_alloc : - { set_alloc(_cur_count + _inc_count); break ; } - } - /*--------- update block structure and ctor new items */ - for(size_type _pos_block = _cur_block ; - _pos_block < _new_block ; - ++_pos_block ) - { - this->_block [_pos_block].set_count( - _siz_block, __cont::loose_alloc, _data) ; - } - if (_new_count!=+0) - { - this->_block [_new_block].set_count( - _end_shift, __cont::loose_alloc, _data) ; - } - - this->_count =_new_count ; - } - - /* - -------------------------------------------------------- - * DEC-COUNT: decrement container count. - -------------------------------------------------------- - */ - - __normal_call void_type dec_count ( - size_type _dec_count, - __cont::alloc_types _new_alloc = - __cont::loose_alloc - ) - { - size_type _cur_count = count() ; - size_type _new_count = count() - - _dec_count ; - - size_type _nil_block = +0; - - size_type _cur_block = +0; - size_type _new_block = +0; - size_type _end_shift = +0; - - /*------------------ calc. block-wise storage offsets */ - if (_cur_count!=+0) - { - _cur_block = - (_cur_count - 1) / _size + 0 ; - } - if (_new_count!=+0) - { - _new_block = - (_new_count - 1) / _size + 0 ; - _end_shift = - (_new_count - 1) % _size + 1 ; - } - - /*--------- update block structure and ctor new items */ - for(size_type _pos_block = _cur_block; - _pos_block > _new_block; - --_pos_block ) - { - this->_block [_pos_block].set_count( - _nil_block, __cont::loose_alloc) ; - } - if (_cur_count!=+0) - { - this->_block [_new_block].set_count( - _end_shift, __cont::loose_alloc) ; - } - - this->_count =_new_count ; - - /*--------- shrink underlying buffer, based on policy */ - switch (_new_alloc ) - { - case __cont::loose_alloc : - { /* do nothing - preserve buffer */ break ; } - case __cont::tight_alloc : - { set_alloc(_cur_count - _dec_count); break ; } - } - } - - /* - -------------------------------------------------------- - * SET-COUNT: set new container count. - -------------------------------------------------------- - */ - - __inline_call void_type set_count ( // _def-construct - size_type _new_count , - __cont::alloc_types _new_alloc = - __cont::loose_alloc - ) - { - /*----- manipulate the ctor'd range within the buffer */ - size_type _cur_count = count() ; - if(_new_count > _cur_count) - { - inc_count( - _new_count - _cur_count, _new_alloc) ; - } - else - if(_new_count <=_cur_count) - { - dec_count( - _cur_count - _new_count, _new_alloc) ; - } - } - - __inline_call void_type set_count ( // copy-construct - size_type _new_count , - __cont::alloc_types _new_alloc , - data_type const&_data - ) - { - /*----- manipulate the ctor'd range within the buffer */ - size_type _cur_count = count() ; - if(_new_count > _cur_count) - { - inc_count( - _new_count - _cur_count, _new_alloc, _data); - } - else - if(_new_count <=_cur_count) - { - dec_count( - _cur_count - _new_count, _new_alloc) ; - } - } - - /* - -------------------------------------------------------- - * GET-STATS: return container statistics. - -------------------------------------------------------- - */ - - __inline_call allocator get_alloc ( // return alloc obj. - ) const - { return static_cast( *this ) ; - } - - __inline_call size_type count (// return container count - ) const { return this->_count ; } - - __inline_call size_type alloc (// return container alloc - ) const { return this->_alloc ; } - - __inline_call bool_type empty (// true if sequence empty - ) const { return this->_count == +0 ; } - - /* - -------------------------------------------------------- - * (const.-access) container iterators. - -------------------------------------------------------- - */ - - __inline_call _const_it head ( - ) const - {/*--- return iterator for list head */ - size_type _off = +0; - root_type *_ptr =(root_type*)&this->_block; - self_type *_obj =(self_type*) this; - return _const_it(_obj, _ptr, _off); - } - - __inline_call _const_it tail ( - ) const - {/*--- return iterator for list tail */ - size_type _off = this->_count -1; - root_type *_ptr =(root_type*)&this->_block; - self_type *_obj =(self_type*) this; - return _const_it(_obj, _ptr, _off); - } - - __inline_call _const_it hend ( - ) const - {/*----- return iterator "past" head */ - size_type _off = -1; - root_type *_ptr =(root_type*)&this->_block; - self_type *_obj =(self_type*) this; - return _const_it(_obj, _ptr, _off); - } - - __inline_call _const_it tend ( - ) const - {/*----- return iterator "past" tail */ - size_type _off = this->_count -0; - root_type *_ptr =(root_type*)&this->_block; - self_type *_obj =(self_type*) this; - return _const_it(_obj, _ptr, _off); - } - - /* - -------------------------------------------------------- - * (write.-access) container iterators. - -------------------------------------------------------- - */ - - __inline_call _write_it head ( - ) - {/*--- return iterator for list head */ - size_type _off = +0; - root_type *_ptr =(root_type*)&this->_block; - self_type *_obj =(self_type*) this; - return _write_it(_obj, _ptr, _off); - } - - __inline_call _write_it tail ( - ) - {/*--- return iterator for list tail */ - size_type _off = this->_count -1; - root_type *_ptr =(root_type*)&this->_block; - self_type *_obj =(self_type*) this; - return _write_it(_obj, _ptr, _off); - } - - __inline_call _write_it hend ( - ) - {/*----- return iterator "past" head */ - size_type _off = -1; - root_type *_ptr =(root_type*)&this->_block; - self_type *_obj =(self_type*) this; - return _write_it(_obj, _ptr, _off); - } - - __inline_call _write_it tend ( - ) - {/*----- return iterator "past" tail */ - size_type _off = this->_count -0; - root_type *_ptr =(root_type*)&this->_block; - self_type *_obj =(self_type*) this; - return _write_it(_obj, _ptr, _off); - } - - /* - -------------------------------------------------------- - * CLEAR: "free" container storage. - -------------------------------------------------------- - */ - - __inline_call void_type clear ( - __cont::alloc_types _this_alloc = - __cont::loose_alloc - ) - { - if (_this_alloc == __cont::loose_alloc) - set_count(0, _this_alloc) ; - else - set_count(0, _this_alloc) ; - } - - /* - -------------------------------------------------------- - * PUSH-TAIL: append data to tail . - -------------------------------------------------------- - */ - - __inline_call size_type push_tail ( // _def-construct - ) - {/* _def construct object and increment count */ - size_type result = count(); - size_type offset = count()/_size ; - - if (result == alloc()) - inc_alloc(result + 1); - - this-> _block[offset].push_tail(); - this-> _count += + 1 ; - - return result ; - } - - __inline_call size_type push_tail ( // copy-construct - data_type const&_data - ) - {/* copy data onto object and increment count */ - size_type result = count(); - size_type offset = count()/_size ; - - if (result == alloc()) - inc_alloc(result + 1); - - this-> _block[offset]. - push_tail(__copy(data_type,_data)) ; - this-> _count += + 1 ; - - return result ; - } - - __inline_call size_type push_tail ( // move-construct - data_type && _data - ) - {/* copy data onto object and increment count */ - size_type result = count(); - size_type offset = count()/_size ; - - if (result == alloc()) - inc_alloc(result + 1); - - this-> _block[offset]. - push_tail(__move(data_type,_data)) ; - this-> _count += + 1 ; - - return result ; - } - - template < - typename iter_type - > - __normal_call void_type push_tail ( // copy obj-range - iter_type _head, - iter_type _tend - ) - {/* push full sequence at tail and inc. count */ - for(; _head != _tend; ++_head) - { - self_type::push_tail ( *_head); - } - } - - /* - -------------------------------------------------------- - * _POP-TAIL: erase data about tail. - -------------------------------------------------------- - */ - - __inline_call void_type _pop_tail ( - ) - { /* _destruct tail item and dec count */ - dec_count(+1, __cont::loose_alloc) ; - } - - __inline_call void_type _pop_tail ( - data_type &_data - ) - { /* _destruct tail item and dec count */ - _data = __move(data_type,*tail()) ; - dec_count(+1, __cont::loose_alloc) ; - } - - /* - -------------------------------------------------------- - * OPERATOR[]: index into container. - -------------------------------------------------------- - */ - - __inline_call data_type &operator[] ( // write - size_type _pos - ) - { /*------------ subscript operator */ - __assert ( _pos >= +0 && - _pos < count() && - "::block_array[]: out of range!" ); - - return this->_block[_pos / _size] - [_pos % _size] ; - } - - __inline_call data_type const&operator[] ( // const - size_type _pos - ) const - { /*------------ subscript operator */ - __assert ( _pos >= +0 && - _pos < count() && - "::block_array[]: out of range!" ); - - return this->_block[_pos / _size] - [_pos % _size] ; - } - - } ; - -# undef __cont - - - } - -#endif //__BLOCK_ARRAY__ - - - + +/* +------------------------------------------------------------ + * a dynamically-allocated, "block-wise" array object. +------------------------------------------------------------ + * + * BLOCK-ARRAY is a block-wise array implementation, + * where the linear array storage is broken across + * non-contiguous "blocks" in memory. It is otherwise + * equivalent to a standard array interface. The blocked + * data-structure can be helpful for very large + * dynamically-resizable arrays, since memory is only + * re-alloc'd on the block level. Peformance asymptotics + * are equivalent to the standard arry object, with + * larger constant factors. + * +------------------------------------------------------------ + * + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) + * + * Disclaimer: Neither I nor: Columbia University, The + * Massachusetts Institute of Technology, The + * University of Sydney, nor The National Aeronautics + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be + * used at your own risk. + * +------------------------------------------------------------ + * + * Last updated: 03 July, 2019 + * + * Copyright 2013-2019 + * Darren Engwirda + * de2363@columbia.edu + * https://github.com/dengwirda/ + * +------------------------------------------------------------ + */ + +# pragma once + +# ifndef __BLOCK_ARRAY__ +# define __BLOCK_ARRAY__ + +# include "block_iter.hpp" + + namespace containers { + +# define __cont containers + + template < + typename D , + typename A = allocators::basic_alloc + > + class block_array + { +/*------ a dynamically allocated, block-wise array object */ + public : + typedef D data_type ; + typedef A allocator ; + + typedef __cont::block_array < + data_type , + allocator > self_type ; + + typedef typename + allocator::size_type size_type ; + typedef typename + allocator::diff_type diff_type ; + + typedef __cont::const_block_iterator < + self_type > _const_it ; + typedef __cont::write_block_iterator < + self_type > _write_it ; + + typedef __cont::array < + data_type , + allocator > leaf_type ; + typedef __cont::array < + leaf_type , + allocator > root_type ; + + size_type static constexpr _pwr2 = + 14 ; + size_type static constexpr _size = +1<<_pwr2 ; + + private : + + root_type _block ; + size_type _count ; + size_type _alloc ; + + /* + -------------------------------------------------------- + * INC-ALLOC: helper - broaden storage. + -------------------------------------------------------- + */ + + __normal_call void_type inc_alloc ( + size_type _new_count + ) + { + if (_new_count <= alloc()) return ; + /*-------------------------- alloc. storage in blocks */ + size_type _new_alloc = alloc(); + if (_new_count <= _size) + { /* grow allocation as multiples of two */ + _new_alloc = + std::max(_new_alloc * 2, _new_count); + } + else + { /* round to the nearest block boundary */ + _new_alloc = + ((_new_count / _size) + 1) * _size ; + } + set_alloc(_new_alloc) ; + } + + /* + -------------------------------------------------------- + * COPY-ITER: helper - construct range. + -------------------------------------------------------- + */ + + template < + typename iter_type + > + __normal_call void_type copy_iter ( + iter_type _head, + iter_type _tail, + __cont::base_iterator_kind + ) + { /* copy range onto object */ + for(; _head != _tail; ++_head) + { + push_tail(*_head) ; + } + } + + __inline_call void_type copy_iter ( + size_type _SIZE, + data_type const& _dsrc, + __cont::null_iterator_kind + ) + { /* copy _data onto object */ + set_count(_SIZE, + __cont::tight_alloc, _dsrc) ; + } + + public : + + /* + -------------------------------------------------------- + * Container c'tor's/d'tor's/assignment op's, etc + -------------------------------------------------------- + */ + + __inline_call block_array ( + allocator const&_asrc = allocator() + ) : _block( _asrc) + { + /*----------------------- default c'tor - do nothing! */ + this->_count = +0; + this->_alloc = +0; + } + + __inline_call block_array ( + size_type _SIZE, + data_type const&_dsrc = data_type(), + allocator const&_asrc = allocator() + ) : _block( _asrc) + { + /*----------------------- default c'tor - initialisor */ + this->_count = +0; + this->_alloc = +0; + copy_iter(_SIZE,_dsrc, + __cont::null_iterator_kind ()) ; + } + + template < + typename iter_type + > + __inline_call block_array ( + iter_type _head, + iter_type _tail, + allocator const&_asrc = allocator() + ) : _block( _asrc) + { + /*----------------------- default c'tor - initialisor */ + this->_count = +0; + this->_alloc = +0; + copy_iter(_head,_tail, + __cont::iter_kind( _head)) ; + } + + __inline_call~block_array ( + ) + /*---------------------------------------- _def d'tor */ + { set_count(0,__cont::tight_alloc) ; + } + +/*-------------------------------------------- copy c'tor */ + __inline_call block_array ( + self_type const&_src + ) = default ; +/*-------------------------------------------- move c'tor */ + __inline_call block_array ( + self_type && _src + ) : _block(std::move(_src._block) ) + { + this->_alloc = + _src. _alloc ; + _src. _alloc = +0u ; + + this->_count = + _src. _count ; + _src. _count = +0u ; + } + +/*-------------------------------------------- copy a-op. */ + __inline_call + self_type & operator = ( + self_type const&_src + ) = default ; +/*-------------------------------------------- move a-op. */ + __inline_call + self_type & operator = ( + self_type && _src + ) + { + if (this != &_src) + { + using std::swap ; + self_type _copy ( + __move(self_type , _src)) ; + + swap(this->_block, + _copy. _block) ; + swap(this->_count, + _copy. _count) ; + swap(this->_alloc, + _copy. _alloc) ; + } + + return ( *this ) ; + } + + /* + -------------------------------------------------------- + * SET-ALLOC: push new array alloc. + -------------------------------------------------------- + */ + + __normal_call void_type set_alloc ( + size_type _new_alloc + ) + { + size_type _cur_count = count(); + size_type _cur_alloc = alloc(); + + size_type _cur_block = +0; + size_type _new_block = +0; + size_type _end_block = +0; + size_type _end_shift = +0; + + size_type _siz_block = _size ; + size_type _nil_block = +0 ; + + if (_new_alloc < _cur_count ) + { + /*--------------- _destruct un-needed range first */ + set_count(_new_alloc, + __cont::loose_alloc) ; + } + + if (_cur_alloc!=+0) + { + /*-------------- calc. block-wise storage offsets */ + _cur_block = + (_cur_alloc - 1) / _size + 0 ; + } + if (_new_alloc!=+0) + { + _new_block = + (_new_alloc - 1) / _size + 0 ; + _end_block = + (_new_alloc - 1) / _size + 1 ; + _end_shift = + (_new_alloc - 1) % _size + 1 ; + } + + if (_new_alloc < _cur_alloc ) + { + /*--------------- _pop old blocks and realloc end */ + size_type _pos_block ; + for(_pos_block=_cur_block; + _pos_block>_new_block; + --_pos_block ) + { + this->_block [_pos_block]. + set_alloc(_nil_block); + } + this->_block [_new_block]. + set_alloc(_end_shift); + + this->_block.set_count ( + _end_block, __cont::loose_alloc) ; + + this->_alloc =_new_alloc ; + } + else + if (_new_alloc > _cur_alloc ) + { + /*--------------- push new blocks and realloc end */ + this->_block.set_count ( + _end_block, __cont::loose_alloc, + leaf_type(this->_block.get_alloc())) ; + + size_type _pos_block ; + for(_pos_block=_cur_block; + _pos_block<_new_block; + ++_pos_block ) + { + this->_block [_pos_block]. + set_alloc(_siz_block); + } + this->_block [_new_block]. + set_alloc(_end_shift); + + this->_alloc =_new_alloc ; + } + } + + /* + -------------------------------------------------------- + * FIX-ALLOC: trim current alloc to count. + -------------------------------------------------------- + */ + + __inline_call void_type fix_alloc ( + ) { set_alloc(count()) ; } + + /* + -------------------------------------------------------- + * INC-COUNT: increment container count. + -------------------------------------------------------- + */ + + __normal_call void_type inc_count ( // _def-construct + size_type _inc_count , + __cont::alloc_types _new_alloc = + __cont::loose_alloc + ) + { + size_type _cur_count = count() ; + size_type _new_count = count() + + _inc_count ; + + size_type _cur_block = +0; + size_type _new_block = +0; + size_type _end_shift = +0; + + size_type _siz_block = _size ; + + /*------------------ calc. block-wise storage offsets */ + if (_cur_count!=+0) + { + _cur_block = + (_cur_count - 1) / _size + 0; + } + if (_new_count!=+0) + { + _new_block = + (_new_count - 1) / _size + 0; + _end_shift = + (_new_count - 1) % _size + 1; + } + + /*--------- expand underlying buffer, based on policy */ + switch (_new_alloc ) + { + case __cont::loose_alloc : + { inc_alloc(_cur_count + _inc_count); break ; } + case __cont::tight_alloc : + { set_alloc(_cur_count + _inc_count); break ; } + } + /*--------- update block structure and ctor new items */ + for(size_type _pos_block = _cur_block; + _pos_block < _new_block; + ++_pos_block ) + { + this->_block [_pos_block].set_count( + _siz_block, __cont::loose_alloc) ; + } + if (_new_count!=+0) + { + this->_block [_new_block].set_count( + _end_shift, __cont::loose_alloc) ; + } + + this->_count =_new_count ; + } + + /* + -------------------------------------------------------- + * INC-COUNT: increment container count. + -------------------------------------------------------- + */ + + __normal_call void_type inc_count ( // copy-construct + size_type _inc_count , + __cont::alloc_types _new_alloc , + data_type const&_data + ) + { + size_type _cur_count = count() ; + size_type _new_count = count() + + _inc_count ; + + size_type _cur_block = +0; + size_type _new_block = +0; + size_type _end_shift = +0; + + size_type _siz_block = _size ; + + /*------------------ calc. block-wise storage offsets */ + if (_cur_count!=+0) + { + _cur_block = + (_cur_count - 1) / _size + 0; + } + if (_new_count!=+0) + { + _new_block = + (_new_count - 1) / _size + 0; + _end_shift = + (_new_count - 1) % _size + 1; + } + + /*--------- expand underlying buffer, based on policy */ + switch (_new_alloc ) + { + case __cont::loose_alloc : + { inc_alloc(_cur_count + _inc_count); break ; } + case __cont::tight_alloc : + { set_alloc(_cur_count + _inc_count); break ; } + } + /*--------- update block structure and ctor new items */ + for(size_type _pos_block = _cur_block ; + _pos_block < _new_block ; + ++_pos_block ) + { + this->_block [_pos_block].set_count( + _siz_block, __cont::loose_alloc, _data) ; + } + if (_new_count!=+0) + { + this->_block [_new_block].set_count( + _end_shift, __cont::loose_alloc, _data) ; + } + + this->_count =_new_count ; + } + + /* + -------------------------------------------------------- + * DEC-COUNT: decrement container count. + -------------------------------------------------------- + */ + + __normal_call void_type dec_count ( + size_type _dec_count, + __cont::alloc_types _new_alloc = + __cont::loose_alloc + ) + { + size_type _cur_count = count() ; + size_type _new_count = count() - + _dec_count ; + + size_type _nil_block = +0; + + size_type _cur_block = +0; + size_type _new_block = +0; + size_type _end_shift = +0; + + /*------------------ calc. block-wise storage offsets */ + if (_cur_count!=+0) + { + _cur_block = + (_cur_count - 1) / _size + 0 ; + } + if (_new_count!=+0) + { + _new_block = + (_new_count - 1) / _size + 0 ; + _end_shift = + (_new_count - 1) % _size + 1 ; + } + + /*--------- update block structure and ctor new items */ + for(size_type _pos_block = _cur_block; + _pos_block > _new_block; + --_pos_block ) + { + this->_block [_pos_block].set_count( + _nil_block, __cont::loose_alloc) ; + } + if (_cur_count!=+0) + { + this->_block [_new_block].set_count( + _end_shift, __cont::loose_alloc) ; + } + + this->_count =_new_count ; + + /*--------- shrink underlying buffer, based on policy */ + switch (_new_alloc ) + { + case __cont::loose_alloc : + { /* do nothing - preserve buffer */ break ; } + case __cont::tight_alloc : + { set_alloc(_cur_count - _dec_count); break ; } + } + } + + /* + -------------------------------------------------------- + * SET-COUNT: set new container count. + -------------------------------------------------------- + */ + + __inline_call void_type set_count ( // _def-construct + size_type _new_count , + __cont::alloc_types _new_alloc = + __cont::loose_alloc + ) + { + /*----- manipulate the ctor'd range within the buffer */ + size_type _cur_count = count() ; + if(_new_count > _cur_count) + { + inc_count( + _new_count - _cur_count, _new_alloc) ; + } + else + if(_new_count <=_cur_count) + { + dec_count( + _cur_count - _new_count, _new_alloc) ; + } + } + + __inline_call void_type set_count ( // copy-construct + size_type _new_count , + __cont::alloc_types _new_alloc , + data_type const&_data + ) + { + /*----- manipulate the ctor'd range within the buffer */ + size_type _cur_count = count() ; + if(_new_count > _cur_count) + { + inc_count( + _new_count - _cur_count, _new_alloc, _data); + } + else + if(_new_count <=_cur_count) + { + dec_count( + _cur_count - _new_count, _new_alloc) ; + } + } + + /* + -------------------------------------------------------- + * GET-STATS: return container statistics. + -------------------------------------------------------- + */ + + __inline_call allocator get_alloc ( // return alloc obj. + ) const + { return static_cast( *this ) ; + } + + __inline_call size_type count (// return container count + ) const { return this->_count ; } + + __inline_call size_type alloc (// return container alloc + ) const { return this->_alloc ; } + + __inline_call bool_type empty (// true if sequence empty + ) const { return this->_count == +0 ; } + + /* + -------------------------------------------------------- + * (const.-access) container iterators. + -------------------------------------------------------- + */ + + __inline_call _const_it head ( + ) const + {/*--- return iterator for list head */ + size_type _off = +0; + root_type *_ptr =(root_type*)&this->_block; + self_type *_obj =(self_type*) this; + return _const_it(_obj, _ptr, _off); + } + + __inline_call _const_it tail ( + ) const + {/*--- return iterator for list tail */ + size_type _off = this->_count -1; + root_type *_ptr =(root_type*)&this->_block; + self_type *_obj =(self_type*) this; + return _const_it(_obj, _ptr, _off); + } + + __inline_call _const_it hend ( + ) const + {/*----- return iterator "past" head */ + size_type _off = -1; + root_type *_ptr =(root_type*)&this->_block; + self_type *_obj =(self_type*) this; + return _const_it(_obj, _ptr, _off); + } + + __inline_call _const_it tend ( + ) const + {/*----- return iterator "past" tail */ + size_type _off = this->_count -0; + root_type *_ptr =(root_type*)&this->_block; + self_type *_obj =(self_type*) this; + return _const_it(_obj, _ptr, _off); + } + + /* + -------------------------------------------------------- + * (write.-access) container iterators. + -------------------------------------------------------- + */ + + __inline_call _write_it head ( + ) + {/*--- return iterator for list head */ + size_type _off = +0; + root_type *_ptr =(root_type*)&this->_block; + self_type *_obj =(self_type*) this; + return _write_it(_obj, _ptr, _off); + } + + __inline_call _write_it tail ( + ) + {/*--- return iterator for list tail */ + size_type _off = this->_count -1; + root_type *_ptr =(root_type*)&this->_block; + self_type *_obj =(self_type*) this; + return _write_it(_obj, _ptr, _off); + } + + __inline_call _write_it hend ( + ) + {/*----- return iterator "past" head */ + size_type _off = -1; + root_type *_ptr =(root_type*)&this->_block; + self_type *_obj =(self_type*) this; + return _write_it(_obj, _ptr, _off); + } + + __inline_call _write_it tend ( + ) + {/*----- return iterator "past" tail */ + size_type _off = this->_count -0; + root_type *_ptr =(root_type*)&this->_block; + self_type *_obj =(self_type*) this; + return _write_it(_obj, _ptr, _off); + } + + /* + -------------------------------------------------------- + * CLEAR: "free" container storage. + -------------------------------------------------------- + */ + + __inline_call void_type clear ( + __cont::alloc_types _this_alloc = + __cont::loose_alloc + ) + { + if (_this_alloc == __cont::loose_alloc) + set_count(0, _this_alloc) ; + else + set_count(0, _this_alloc) ; + } + + /* + -------------------------------------------------------- + * PUSH-TAIL: append data to tail . + -------------------------------------------------------- + */ + + __inline_call size_type push_tail ( // _def-construct + ) + {/* _def construct object and increment count */ + size_type result = count(); + size_type offset = count()>>_pwr2; + + if (result == alloc()) + inc_alloc(result + 1); + + this-> _block[offset].push_tail(); + this-> _count += + 1 ; + + return result ; + } + + __inline_call size_type push_tail ( // copy-construct + data_type const&_data + ) + {/* copy data onto object and increment count */ + size_type result = count(); + size_type offset = count()>>_pwr2; + + if (result == alloc()) + inc_alloc(result + 1); + + this-> _block[offset]. + push_tail(__copy(data_type,_data)) ; + this-> _count += + 1 ; + + return result ; + } + + __inline_call size_type push_tail ( // move-construct + data_type && _data + ) + {/* copy data onto object and increment count */ + size_type result = count(); + size_type offset = count()>>_pwr2; + + if (result == alloc()) + inc_alloc(result + 1); + + this-> _block[offset]. + push_tail(__move(data_type,_data)) ; + this-> _count += + 1 ; + + return result ; + } + + template < + typename iter_type + > + __normal_call void_type push_tail ( // copy obj-range + iter_type _head, + iter_type _tend + ) + {/* push full sequence at tail and inc. count */ + for(; _head != _tend; ++_head) + { + self_type::push_tail ( *_head); + } + } + + /* + -------------------------------------------------------- + * _POP-TAIL: erase data about tail. + -------------------------------------------------------- + */ + + __inline_call void_type _pop_tail ( + ) + { /* _destruct tail item and dec count */ + dec_count(+1, __cont::loose_alloc) ; + } + + __inline_call void_type _pop_tail ( + data_type &_data + ) + { /* _destruct tail item and dec count */ + _data = __move(data_type,*tail()) ; + dec_count(+1, __cont::loose_alloc) ; + } + + /* + -------------------------------------------------------- + * OPERATOR[]: index into container. + -------------------------------------------------------- + */ + + __inline_call data_type &operator[] ( // write + size_type _pos + ) + { /*------------ subscript operator */ + __assert ( _pos >= +0 && + _pos < count() && + "::block_array[]: out of range!" ); + + return this->_block[_pos >>_pwr2] + [_pos &(_size-1)] ; + } + + __inline_call data_type const&operator[] ( // const + size_type _pos + ) const + { /*------------ subscript operator */ + __assert ( _pos >= +0 && + _pos < count() && + "::block_array[]: out of range!" ); + + return this->_block[_pos >>_pwr2] + [_pos &(_size-1)] ; + } + + } ; + +# undef __cont + + + } + +#endif //__BLOCK_ARRAY__ + + + diff --git a/src/libcpp/containers/block_iter.hpp b/src/libcpp/containers/block_iter.hpp index 0aca8bd..216c845 100644 --- a/src/libcpp/containers/block_iter.hpp +++ b/src/libcpp/containers/block_iter.hpp @@ -1,437 +1,437 @@ - -/* ------------------------------------------------------------- - * "block" iterator -- for non-contiguous sequences. ------------------------------------------------------------- - * - * BLOCK-ARRAY is a block-wise array implementation, - * where the linear array storage is broken across - * non-contiguous "blocks" in memory. It is otherwise - * equivalent to a standard array interface. The blocked - * data-structure can be helpful for very large - * dynamically-resizable arrays, since memory is only - * re-alloc'd on the block level. Peformance asymptotics - * are equivalent to the standard arry object, with - * larger constant factors. - * ------------------------------------------------------------- - * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) - * - * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The - * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be - * used at your own risk. - * ------------------------------------------------------------- - * - * Last updated: 03 May, 2017 - * - * Copyright 2013-2017 - * Darren Engwirda - * de2363@columbia.edu - * https://github.com/dengwirda/ - * ------------------------------------------------------------- - */ - -# pragma once - -# ifndef __BLOCK_ITER__ -# define __BLOCK_ITER__ - -# include "iter_base.hpp" - - namespace containers { - - template < - typename C , - typename I - > - class block_iterator_base: - public containers::random_iterator_base - { -/* random access iterator for block-wise array containers */ - public : - - typedef C container ; - typedef I iter_type ; - - typedef typename - container::data_type data_type ; - typedef typename - container::size_type size_type ; - typedef typename - container::diff_type diff_type ; - typedef typename - container::root_type root_type ; - typedef typename - container::leaf_type leaf_type ; - - typedef block_iterator_base < - container , - iter_type > self_type ; - - public : - -# ifdef _DEBUG - root_type *_ptr; // block ptr. - size_type _off; // offset - container *_obj; // block obj. -# else - root_type *_ptr; // block ptr. - size_type _off; // offset -# endif - - public : - - __inline_call block_iterator_base ( - container *_bsrc = nullptr, - root_type *_psrc = nullptr, - size_type _osrc = +0 -# ifdef _DEBUG - ) : _ptr(_psrc) , - _off(_osrc) , - _obj(_bsrc) {} -# else - ) : _ptr(_psrc) , - _off(_osrc) { __unreferenced(_bsrc) ; } -# endif - - __inline_call~block_iterator_base() = default ; - - __inline_call block_iterator_base ( - self_type const&_src - ) = default ; - __inline_call block_iterator_base ( - self_type && _src - ) = default ; - - __inline_call - self_type & operator = ( - self_type const&_src - ) = default ; - __inline_call - self_type & operator = ( - self_type && _src - ) = default ; - -/*--------------------------------- translation operators */ - - __inline_call iter_type& operator++ ( - ) - { /*----------------- pre-increment */ - ++this->_off; - return *(iter_type*)this; - } - __inline_call iter_type& operator-- ( - ) - { /*----------------- pre-decrement */ - --this->_off; - return *(iter_type*)this; - } - - __inline_call - iter_type operator++ ( int ) - { /*---------------- post-increment */ - iter_type _tmp(*(iter_type*)this); - ++*this; - return _tmp; - } - __inline_call - iter_type operator-- ( int ) - { /*---------------- post-decrement */ - iter_type _tmp(*(iter_type*)this); - --*this; - return _tmp; - } - - __inline_call iter_type& operator+= ( - size_type _off - ) - { /*--------------------- increment */ - this->_off += _off; - return *(iter_type*)this; - } - __inline_call iter_type& operator-= ( - size_type _off - ) - { /*--------------------- decrement */ - this->_off -= _off; - return *(iter_type*)this; - } - - __inline_call iter_type operator + ( - size_type _off - ) - { /*-------------------- add offset */ - iter_type _tmp(*(iter_type*)this); - return _tmp += _off; - } - __inline_call iter_type operator - ( - size_type _off - ) - { /*-------------------- sub offset */ - iter_type _tmp(*(iter_type*)this); - return _tmp -= _off; - } - - __inline_call diff_type operator - ( - self_type const&_src - ) const - { /*----------- iterator difference */ - return this->_off - _src._off ; - } - -/*--------------------------------- comparative operators */ - - __inline_call bool_type operator== ( - self_type const&_src - ) const - { /*--------------------- equal to */ - return this->_off == _src._off ; - } - __inline_call bool_type operator!= ( - self_type const&_src - ) const - { /*----------------- not equal to */ - return this->_off != _src._off ; - } - __inline_call bool_type operator < ( - self_type const&_src - ) const - { /*-------------------- less than */ - return this->_off < _src._off ; - } - __inline_call bool_type operator > ( - self_type const&_src - ) const - { /*-------------------- more than */ - return this->_off > _src._off ; - } - __inline_call bool_type operator<= ( - self_type const&_src - ) const - { /*-------- less than or equal to */ - return this->_off <= _src._off ; - } - __inline_call bool_type operator>= ( - self_type const&_src - ) const - { /*-------- more than or equal to */ - return this->_off >= _src._off ; - } - - } ; - - /* - -------------------------------------------------------- - * "const" iterators for contiguous sequences. - -------------------------------------------------------- - */ - - template < - typename C - > - class const_block_iterator: public - block_iterator_base > - { -/* random access iterator for block-wise array containers */ - public : - - typedef C container ; - - typedef const_block_iterator< - container > self_type ; - typedef block_iterator_base < - container , - self_type > base_type ; - - typedef typename - base_type::data_type data_type ; - typedef typename - base_type::size_type size_type ; - typedef typename - base_type::diff_type diff_type ; - typedef typename - base_type::root_type root_type ; - typedef typename - base_type::leaf_type leaf_type ; - - public : - - __inline_call const_block_iterator ( - container *_bsrc = nullptr, - root_type *_psrc = nullptr, - size_type _osrc = 0 - ) : base_type(_bsrc, _psrc, _osrc) {} - - __inline_call~const_block_iterator()= default ; - - __inline_call const_block_iterator ( - self_type const&_src - ) = default ; - __inline_call const_block_iterator ( - self_type && _src - ) = default ; - - __inline_call - self_type & operator = ( - self_type const&_src - ) = default ; - __inline_call - self_type & operator = ( - self_type && _src - ) = default ; - -/*-------------------------------- "const" access to data */ - - __inline_call data_type const* operator-> ( - ) const - { return &**this; - } - - __inline_call data_type const& operator[] ( - size_type _pos - ) const - { return *(*this + _pos); - } - - __inline_call data_type const& operator * ( - ) const - { /* return reference to underlying data */ -# ifdef _DEBUG - __assert ( - this->_ptr != nullptr && - "const_block_iterator: null pointer!" ) ; - __assert ( - this->_off >= 0 && - this->_off < this->_obj->count() && - "const_block_iterator: out of range!" ) ; -# endif - return (*this->_ptr) - [this->_off / container::_size] - [this->_off % container::_size] ; - } - - } ; - - /* - -------------------------------------------------------- - * "write" iterators for contiguous sequences. - -------------------------------------------------------- - */ - - template < - typename C - > - class write_block_iterator: public - block_iterator_base > - { -/* random access iterator for block-wise array containers */ - public : - - typedef C container ; - - typedef write_block_iterator< - container > self_type ; - typedef block_iterator_base < - container , - self_type > base_type ; - - typedef typename - base_type::data_type data_type ; - typedef typename - base_type::size_type size_type ; - typedef typename - base_type::diff_type diff_type ; - typedef typename - base_type::root_type root_type ; - typedef typename - base_type::leaf_type leaf_type ; - - public : - - __inline_call write_block_iterator ( - container *_bsrc = nullptr, - root_type *_psrc = nullptr, - size_type _osrc = 0 - ) : base_type(_bsrc, _psrc, _osrc) {} - - __inline_call~write_block_iterator()= default ; - - __inline_call write_block_iterator ( - self_type const&_src - ) = default ; - __inline_call write_block_iterator ( - self_type && _src - ) = default ; - - __inline_call - self_type & operator = ( - self_type const&_src - ) = default ; - __inline_call - self_type & operator = ( - self_type && _src - ) = default ; - -/*-------------------------------- "write" access to data */ - - __inline_call data_type* operator-> ( - ) const - { return &**this; - } - - __inline_call data_type& operator[] ( - size_type _pos - ) const - { return *(*this + _pos); - } - - __inline_call data_type& operator * ( - ) const - { /* return reference to underlying data */ -# ifdef _DEBUG - __assert ( - this->_ptr != nullptr && - "write_block_iterator: null pointer!" ) ; - __assert ( - this->_off >= 0 && - this->_off < this->_obj->count() && - "write_block_iterator: out of range!" ) ; -# endif - return (*this->_ptr) - [this->_off / container::_size] - [this->_off % container::_size] ; - } - - } ; - - - } - -# endif //__BLOCK_ITER__ - - - + +/* +------------------------------------------------------------ + * "block" iterator -- for non-contiguous sequences. +------------------------------------------------------------ + * + * BLOCK-ARRAY is a block-wise array implementation, + * where the linear array storage is broken across + * non-contiguous "blocks" in memory. It is otherwise + * equivalent to a standard array interface. The blocked + * data-structure can be helpful for very large + * dynamically-resizable arrays, since memory is only + * re-alloc'd on the block level. Peformance asymptotics + * are equivalent to the standard arry object, with + * larger constant factors. + * +------------------------------------------------------------ + * + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) + * + * Disclaimer: Neither I nor: Columbia University, The + * Massachusetts Institute of Technology, The + * University of Sydney, nor The National Aeronautics + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be + * used at your own risk. + * +------------------------------------------------------------ + * + * Last updated: 03 July, 2019 + * + * Copyright 2013-2019 + * Darren Engwirda + * de2363@columbia.edu + * https://github.com/dengwirda/ + * +------------------------------------------------------------ + */ + +# pragma once + +# ifndef __BLOCK_ITER__ +# define __BLOCK_ITER__ + +# include "iter_base.hpp" + + namespace containers { + + template < + typename C , + typename I + > + class block_iterator_base: + public containers::random_iterator_base + { +/* random access iterator for block-wise array containers */ + public : + + typedef C container ; + typedef I iter_type ; + + typedef typename + container::data_type data_type ; + typedef typename + container::size_type size_type ; + typedef typename + container::diff_type diff_type ; + typedef typename + container::root_type root_type ; + typedef typename + container::leaf_type leaf_type ; + + typedef block_iterator_base < + container , + iter_type > self_type ; + + public : + +# ifdef _DEBUG + root_type *_ptr; // block ptr. + size_type _off; // offset + container *_obj; // block obj. +# else + root_type *_ptr; // block ptr. + size_type _off; // offset +# endif + + public : + + __inline_call block_iterator_base ( + container *_bsrc = nullptr, + root_type *_psrc = nullptr, + size_type _osrc = +0 +# ifdef _DEBUG + ) : _ptr(_psrc) , + _off(_osrc) , + _obj(_bsrc) {} +# else + ) : _ptr(_psrc) , + _off(_osrc) { __unreferenced(_bsrc) ; } +# endif + + __inline_call~block_iterator_base() = default ; + + __inline_call block_iterator_base ( + self_type const&_src + ) = default ; + __inline_call block_iterator_base ( + self_type && _src + ) = default ; + + __inline_call + self_type & operator = ( + self_type const&_src + ) = default ; + __inline_call + self_type & operator = ( + self_type && _src + ) = default ; + +/*--------------------------------- translation operators */ + + __inline_call iter_type& operator++ ( + ) + { /*----------------- pre-increment */ + ++this->_off; + return *(iter_type*)this; + } + __inline_call iter_type& operator-- ( + ) + { /*----------------- pre-decrement */ + --this->_off; + return *(iter_type*)this; + } + + __inline_call + iter_type operator++ ( int ) + { /*---------------- post-increment */ + iter_type _tmp(*(iter_type*)this); + ++*this; + return _tmp; + } + __inline_call + iter_type operator-- ( int ) + { /*---------------- post-decrement */ + iter_type _tmp(*(iter_type*)this); + --*this; + return _tmp; + } + + __inline_call iter_type& operator+= ( + size_type _val + ) + { /*--------------------- increment */ + this->_off += _val; + return *(iter_type*)this; + } + __inline_call iter_type& operator-= ( + size_type _val + ) + { /*--------------------- decrement */ + this->_off -= _val; + return *(iter_type*)this; + } + + __inline_call iter_type operator + ( + size_type _val + ) + { /*-------------------- add offset */ + iter_type _tmp(*(iter_type*)this); + return _tmp += _val; + } + __inline_call iter_type operator - ( + size_type _val + ) + { /*-------------------- sub offset */ + iter_type _tmp(*(iter_type*)this); + return _tmp -= _val; + } + + __inline_call diff_type operator - ( + self_type const&_src + ) const + { /*----------- iterator difference */ + return this->_off - _src._off ; + } + +/*--------------------------------- comparative operators */ + + __inline_call bool_type operator== ( + self_type const&_src + ) const + { /*--------------------- equal to */ + return this->_off == _src._off ; + } + __inline_call bool_type operator!= ( + self_type const&_src + ) const + { /*----------------- not equal to */ + return this->_off != _src._off ; + } + __inline_call bool_type operator < ( + self_type const&_src + ) const + { /*-------------------- less than */ + return this->_off < _src._off ; + } + __inline_call bool_type operator > ( + self_type const&_src + ) const + { /*-------------------- more than */ + return this->_off > _src._off ; + } + __inline_call bool_type operator<= ( + self_type const&_src + ) const + { /*-------- less than or equal to */ + return this->_off <= _src._off ; + } + __inline_call bool_type operator>= ( + self_type const&_src + ) const + { /*-------- more than or equal to */ + return this->_off >= _src._off ; + } + + } ; + + /* + -------------------------------------------------------- + * "const" iterators for contiguous sequences. + -------------------------------------------------------- + */ + + template < + typename C + > + class const_block_iterator: public + block_iterator_base > + { +/* random access iterator for block-wise array containers */ + public : + + typedef C container ; + + typedef const_block_iterator< + container > self_type ; + typedef block_iterator_base < + container , + self_type > base_type ; + + typedef typename + base_type::data_type data_type ; + typedef typename + base_type::size_type size_type ; + typedef typename + base_type::diff_type diff_type ; + typedef typename + base_type::root_type root_type ; + typedef typename + base_type::leaf_type leaf_type ; + + public : + + __inline_call const_block_iterator ( + container *_bsrc = nullptr, + root_type *_psrc = nullptr, + size_type _osrc = 0 + ) : base_type(_bsrc, _psrc, _osrc) {} + + __inline_call~const_block_iterator()= default ; + + __inline_call const_block_iterator ( + self_type const&_src + ) = default ; + __inline_call const_block_iterator ( + self_type && _src + ) = default ; + + __inline_call + self_type & operator = ( + self_type const&_src + ) = default ; + __inline_call + self_type & operator = ( + self_type && _src + ) = default ; + +/*-------------------------------- "const" access to data */ + + __inline_call data_type const* operator-> ( + ) const + { return &**this; + } + + __inline_call data_type const& operator[] ( + size_type _pos + ) const + { return *(*this + _pos); + } + + __inline_call data_type const& operator * ( + ) const + { /* return reference to underlying data */ +# ifdef _DEBUG + __assert ( + this->_ptr != nullptr && + "const_block_iterator: null pointer!" ) ; + __assert ( + this->_off >= 0 && + this->_off < this->_obj->count() && + "const_block_iterator: out of range!" ) ; +# endif + return (*this->_ptr) + [this->_off >> container::_pwr2] + [this->_off & (container::_size-1)] ; + } + + } ; + + /* + -------------------------------------------------------- + * "write" iterators for contiguous sequences. + -------------------------------------------------------- + */ + + template < + typename C + > + class write_block_iterator: public + block_iterator_base > + { +/* random access iterator for block-wise array containers */ + public : + + typedef C container ; + + typedef write_block_iterator< + container > self_type ; + typedef block_iterator_base < + container , + self_type > base_type ; + + typedef typename + base_type::data_type data_type ; + typedef typename + base_type::size_type size_type ; + typedef typename + base_type::diff_type diff_type ; + typedef typename + base_type::root_type root_type ; + typedef typename + base_type::leaf_type leaf_type ; + + public : + + __inline_call write_block_iterator ( + container *_bsrc = nullptr, + root_type *_psrc = nullptr, + size_type _osrc = 0 + ) : base_type(_bsrc, _psrc, _osrc) {} + + __inline_call~write_block_iterator()= default ; + + __inline_call write_block_iterator ( + self_type const&_src + ) = default ; + __inline_call write_block_iterator ( + self_type && _src + ) = default ; + + __inline_call + self_type & operator = ( + self_type const&_src + ) = default ; + __inline_call + self_type & operator = ( + self_type && _src + ) = default ; + +/*-------------------------------- "write" access to data */ + + __inline_call data_type* operator-> ( + ) const + { return &**this; + } + + __inline_call data_type& operator[] ( + size_type _pos + ) const + { return *(*this + _pos); + } + + __inline_call data_type& operator * ( + ) const + { /* return reference to underlying data */ +# ifdef _DEBUG + __assert ( + this->_ptr != nullptr && + "write_block_iterator: null pointer!" ) ; + __assert ( + this->_off >= 0 && + this->_off < this->_obj->count() && + "write_block_iterator: out of range!" ) ; +# endif + return (*this->_ptr) + [this->_off >> container::_pwr2] + [this->_off & (container::_size-1)] ; + } + + } ; + + + } + +# endif //__BLOCK_ITER__ + + + diff --git a/src/libcpp/containers/double_list.hpp b/src/libcpp/containers/double_list.hpp index 09acbe3..8114fa9 100644 --- a/src/libcpp/containers/double_list.hpp +++ b/src/libcpp/containers/double_list.hpp @@ -1,1028 +1,1028 @@ - -/* ------------------------------------------------------------- - * a doubly-linked list object. ------------------------------------------------------------- - * - * DOUBLE-LIST is a "doubly-linked" list type, where - * list items comprise a doubly-oriented chain of - * pointers. Insertion/deletion is O(1), acccess is O(N). - * List count is stored explicitly, and is O(1) as a - * result. - * ------------------------------------------------------------- - * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) - * - * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The - * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be - * used at your own risk. - * ------------------------------------------------------------- - * - * Last updated: 03 May, 2017 - * - * Copyright 2013-2017 - * Darren Engwirda - * de2363@columbia.edu - * https://github.com/dengwirda/ - * ------------------------------------------------------------- - */ - -# pragma once - -# ifndef __DOUBLE_LIST__ -# define __DOUBLE_LIST__ - -# include "doubleiter.hpp" - - namespace containers { - -# define __cont containers - - template < - typename D - > - class double_item - { -/*------------------------------- doubly-linked list item */ - public : - - typedef D data_type ; - typedef - __cont::double_item self_type ; - - public : - - self_type *_next ; - self_type *_prev ; - - data_type _data ; - - public : - -/*------------------------------- c'tor/d'tor/assign etc. */ - __inline_call double_item ( - self_type *_nsrc , - self_type *_psrc - ) : _next( _nsrc), - _prev( _psrc) - { /* void construct */ - } - - __inline_call double_item ( - self_type *_nsrc , - self_type *_psrc , - data_type const&_dsrc - ) : _next( _nsrc), - _prev( _psrc), - _data( - __copy(data_type,_dsrc)) - { /* copy construct */ - } - - __inline_call double_item ( - self_type *_nsrc , - self_type *_psrc , - data_type&&_dsrc - ) : _next( _nsrc), - _prev( _psrc), - _data( - __move(data_type,_dsrc)) - { /* move construct */ - } - - __inline_call~double_item() = default ; - - __inline_call double_item ( - self_type const&_src - ) = default ; - __inline_call double_item ( - self_type && _src - ) = default ; - - __inline_call - self_type & operator= ( - self_type const&_src - ) = default ; - __inline_call - self_type & operator= ( - self_type && _src - ) = default ; - -/*------------------------------ access to "next" pointer */ - __inline_call self_type*& next ( - ) - { return ( this->_next ) ; - } - -/*------------------------------ access to "prev" pointer */ - __inline_call self_type*& prev ( - ) - { return ( this->_prev ) ; - } - - } ; - - template < - typename D , - typename A = allocators::basic_alloc - > - class double_list : public - allocators::_item_alloc < - double_item < D>, A > - { -/*------ double-ended linked-list for doubly-linked items */ - public : - - typedef D data_type ; - typedef A allocator ; - - typedef containers::double_list < - data_type , - allocator > self_type ; - - typedef containers::double_item < - data_type > item_type ; - typedef allocators::_item_alloc < - item_type , - allocator > obj_alloc ; - - typedef __cont::const_double_iterator < - self_type > _const_it ; - typedef __cont::write_double_iterator < - self_type > _write_it ; - - typedef typename - allocator::size_type size_type ; - typedef typename - allocator::diff_type diff_type ; - - private : - - item_type *_hptr ; // head/tail pointers - item_type *_tptr ; - size_type _nobj ; - - private : - -/*------------------------------ helper - construct range */ - template < - typename iter_type - > - __normal_call void_type copy_list ( - iter_type _head, - iter_type _tend, - __cont::base_iterator_kind - ) - { /* push the sequence onto list */ - for ( ; _head != _tend; ++_head) - push_tail(*_head) ; - } - - __inline_call void_type copy_list ( - size_type _size , - data_type const& _dsrc, - __cont::null_iterator_kind - ) - { copy_data(_size, _dsrc); - } - - __normal_call void_type copy_data ( - size_type _size, - data_type const& _dsrc - ) - { /* push _size copies onto list */ - for ( ; _size-- != 0; ) - push_head(_dsrc); - } - - public : - -/*--------------------------- default c'tor - do nothing! */ - __inline_call double_list ( - allocator const&_asrc = allocator() - ) : obj_alloc( _asrc ) - { /* construct pointers and allocator */ - this->_nobj = +0 ; - this->_hptr = nullptr ; - this->_tptr = nullptr ; - } - -/*--------------------------- default c'tor - initialisor */ - __inline_call double_list ( - size_type _size , - data_type const&_dsrc = data_type(), - allocator const&_asrc = allocator() - ) : obj_alloc( _asrc ) - { - this->_nobj = +0 ; - this->_hptr = nullptr ; - this->_tptr = nullptr ; - copy_data(_size,_dsrc); - } - -/*--------------------------- default c'tor - initialisor */ - template < - typename iter_type - > - __inline_call double_list ( - iter_type _head, - iter_type _tail, - allocator const&_asrc = allocator() - ) : obj_alloc( _asrc ) - { - this->_nobj = +0 ; - this->_hptr = nullptr ; - this->_tptr = nullptr ; - copy_list(_head,_tail,__cont::iter_kind(_head)) ; - } - -/*-------------------------------------------- _def d'tor */ - __inline_call~double_list ( - ) { clear() ; } - -/*-------------------------------------------- copy c'tor */ - __inline_call double_list ( - self_type const& _src - ) : obj_alloc( - __copy(obj_alloc,_src)) - { - this->_nobj = +0 ; - this->_hptr = nullptr ; - this->_tptr = nullptr ; - /*------------------------------- copy data from _src */ - _const_it _head, _tail; - _head = _src.head(); - _tail = _src.tend(); - copy_list(_head,_tail, - __cont::iter_kind(_head)) ; - } - -/*-------------------------------------------- move c'tor */ - __inline_call double_list ( - self_type && _src - ) : obj_alloc( - __move(obj_alloc,_src)) - { - /*------------------------------- move data from _src */ - this->_nobj = _src._nobj ; - this->_hptr = _src._hptr ; - this->_tptr = _src._tptr ; - _src. _nobj = +0 ; - _src. _hptr = nullptr ; - _src. _tptr = nullptr ; - } - -/*-------------------------------------------- copy a-op. */ - __inline_call self_type& operator = ( - self_type const& _src - ) - { - if (this != &_src) - { - self_type _copy ( - __copy(self_type, _src)) ; - - using std::swap ; - swap ( - static_cast(*this), - static_cast(_copy)) ; - - swap(this->_hptr, - _copy. _hptr) ; - swap(this->_tptr, - _copy. _tptr) ; - swap(this->_nobj, - _copy. _nobj) ; - } - - return ( *this ) ; - } - -/*-------------------------------------------- move a-op. */ - __inline_call self_type &operator = ( - self_type && _src - ) - { - if (this != &_src) - { - self_type _copy ( - __move(self_type, _src)) ; - - using std::swap ; - swap ( - static_cast(*this), - static_cast(_copy)) ; - - swap(this->_hptr, - _copy. _hptr) ; - swap(this->_tptr, - _copy. _tptr) ; - swap(this->_nobj, - _copy. _nobj) ; - } - - return ( *this ) ; - } - -/*-------------------------------- return container count */ - __inline_call size_type count ( - ) const { return ( this->_nobj ) ; } - -/*-------------------------------- true if sequence empty */ - __inline_call bool_type empty ( - ) const - { /* return empty status */ - return ( nullptr ==this->_hptr ) ; - } - -/*-------------------------------- return container alloc */ - __inline_call allocator get_alloc( - ) const - { - return - static_cast ( *this ) ; - } - -/*------------------------------ "const" access iterators */ - __inline_call _const_it head ( - ) const - {/*---- return iterator for list head */ - self_type *_obj = (self_type *)this; - return _const_it(this->_hptr, _obj); - } - - __inline_call _const_it tail ( - ) const - {/*---- return iterator for list tail */ - self_type *_obj = (self_type *)this; - return _const_it(this->_tptr, _obj); - } - - __inline_call _const_it hend ( - ) const - {/* return iterator "past" head, via null terminator! */ - self_type *_obj = (self_type *)this; - return _const_it(nullptr, _obj) ; - } - - __inline_call _const_it tend ( - ) const - {/* return iterator "past" tail, via null terminator! */ - self_type *_obj = (self_type *)this; - return _const_it(nullptr, _obj) ; - } - -/*------------------------------ "write" access iterators */ - __inline_call _write_it head ( - ) - {/*---- return iterator for list head */ - self_type *_obj = (self_type *)this; - return _write_it(this->_hptr, _obj); - } - - __inline_call _write_it tail ( - ) - {/*---- return iterator for list tail */ - self_type *_obj = (self_type *)this; - return _write_it(this->_tptr, _obj); - } - - __inline_call _write_it hend ( - ) - {/* return iterator "past" head, via null terminator! */ - self_type *_obj = (self_type *)this; - return _write_it(nullptr, _obj) ; - } - - __inline_call _write_it tend ( - ) - {/* return iterator "past" tail, via null terminator! */ - self_type *_obj = (self_type *)this; - return _write_it(nullptr, _obj) ; - } - -/*-------------------------------------- "free" container */ - __normal_call void_type clear ( - ) - {/* _pop all items in traversal from head */ - _write_it _head = head(); - _write_it _tend = tend(); - for ( ; _head != _tend; ) - { - _write_it _prev(_head++) ; - self_type:: - _destruct(_prev.item()) ; - self_type:: - deallocate(_prev.item(),1) ; - } - this->_nobj = +0 ; - this->_hptr = nullptr ; - this->_tptr = nullptr ; - } - -/*---------------------------- push data (_def construct) */ - __inline_call _write_it push_head ( - ) - {/* allocate and construct a new raw item */ - item_type *_this_item = - self_type::allocate(1); - - if (this->_hptr != nullptr) - { /* push onto list head only */ - self_type::construct(_this_item, - this->_hptr,//link! - (item_type *)nullptr) ; - - this->_hptr->prev() - = _this_item; - this->_hptr = _this_item; - } - else - { /* push onto list head/tail */ - self_type::construct(_this_item, - (item_type *)nullptr, - (item_type *)nullptr) ; - - this->_hptr = _this_item; - this->_tptr = _this_item; - } - this->_nobj += +1 ; - - return _write_it( - _this_item,(self_type*)this); - } - -/*---------------------------- push data (copy construct) */ - __inline_call _write_it push_head ( - data_type const&_data - ) - {/* allocate and construct a new raw item */ - item_type *_this_item = - self_type::allocate(1); - - if (this->_hptr != nullptr) - { /* push onto list head only */ - self_type::construct(_this_item, - this->_hptr,//link! - (item_type *)nullptr, - __copy(data_type,_data)); - - this->_hptr->prev() - = _this_item; - this->_hptr = _this_item; - } - else - { /* push onto list head/tail */ - self_type::construct(_this_item, - (item_type *)nullptr, - (item_type *)nullptr, - __copy(data_type,_data)); - - this->_hptr = _this_item; - this->_tptr = _this_item; - } - this->_nobj += +1 ; - - return _write_it( - _this_item,(self_type*)this); - } - -/*---------------------------- push data (move construct) */ - __inline_call _write_it push_head ( - data_type &&_data - ) - {/* allocate and construct a new raw item */ - item_type *_this_item = - self_type::allocate(1); - - if (this->_hptr != nullptr) - { /* push onto list head only */ - self_type::construct(_this_item, - this->_hptr,//link! - (item_type *)nullptr, - __move(data_type,_data)); - - this->_hptr->prev() - = _this_item; - this->_hptr = _this_item; - } - else - { /* push onto list head/tail */ - self_type::construct(_this_item, - (item_type *)nullptr, - (item_type *)nullptr, - __move(data_type,_data)); - - this->_hptr = _this_item; - this->_tptr = _this_item; - } - this->_nobj += +1 ; - - return _write_it( - _this_item,(self_type*)this); - } - -/*---------------------------- push data (_def construct) */ - __inline_call _write_it push_tail ( - ) - {/* allocate and construct a new raw item */ - item_type *_this_item = - self_type::allocate(1); - - if (this->_tptr != nullptr) - { /* push onto list tail only */ - self_type::construct(_this_item, - (item_type *)nullptr, - this->_tptr/*link*/) ; - - this->_tptr->next() - = _this_item; - this->_tptr = _this_item; - } - else - { /* push onto list tail/head */ - self_type::construct(_this_item, - (item_type *)nullptr, - (item_type *)nullptr) ; - - this->_hptr = _this_item; - this->_tptr = _this_item; - } - this->_nobj += +1 ; - - return _write_it( - _this_item,(self_type*)this); - } - -/*---------------------------- push data (copy construct) */ - __inline_call _write_it push_tail ( - data_type const&_data - ) - {/* allocate and construct a new raw item */ - item_type *_this_item = - self_type::allocate(1); - - if (this->_tptr != nullptr) - { /* push onto list tail only */ - self_type::construct(_this_item, - (item_type *)nullptr, - this->_tptr,//link! - __copy(data_type,_data)); - - this->_tptr->next() - = _this_item; - this->_tptr = _this_item; - } - else - { /* push onto list tail/head */ - self_type::construct(_this_item, - (item_type *)nullptr, - (item_type *)nullptr, - __copy(data_type,_data)); - - this->_hptr = _this_item; - this->_tptr = _this_item; - } - this->_nobj += +1 ; - - return _write_it( - _this_item,(self_type*)this); - } - -/*---------------------------- push data (move construct) */ - __inline_call _write_it push_tail ( - data_type &&_data - ) - {/* allocate and construct a new raw item */ - item_type *_this_item = - self_type::allocate(1); - - if (this->_tptr != nullptr) - { /* push onto list tail only */ - self_type::construct(_this_item, - (item_type *)nullptr, - this->_tptr,//link! - __move(data_type,_data)); - - this->_tptr->next() - = _this_item; - this->_tptr = _this_item; - } - else - { /* push onto list tail/head */ - self_type::construct(_this_item, - (item_type *)nullptr, - (item_type *)nullptr, - __move(data_type,_data)); - - this->_hptr = _this_item; - this->_tptr = _this_item; - } - this->_nobj += +1 ; - - return _write_it( - _this_item,(self_type*)this); - } - -/*---------------------------- push data (copy obj range) */ - template < - typename iter_type - > - __normal_call void_type push_head ( - iter_type _hend, - iter_type _tail - ) - { /* push a full sequence at tail */ - for(; _tail != _hend; --_tail ) - push_head(*_tail) ; - } - - template < - typename iter_type - > - __normal_call void_type push_tail ( - iter_type _head, - iter_type _tend - ) - { /* push a full sequence at tail */ - for(; _head != _tend; ++_head ) - push_tail(*_head) ; - } - -/*--------------------------------------------- _pop data */ - __inline_call void_type _pop_head ( - ) - { - __assert( this->_hptr != nullptr && - "double_list._pop_head: null ptr"); - /* shuffle next item onto list _head */ - item_type *_head_item = - this->_hptr ; - this->_hptr = _head_item->next() ; - - if (this->_hptr != nullptr) - { /* fix new head item */ - this->_hptr->prev() - = nullptr; - } - else - { /* list became empty */ - this->_tptr = nullptr; - } - this->_nobj -= +1 ; - - /* _destruct and deallocate old head */ - self_type:: _destruct(_head_item) ; - self_type::deallocate(_head_item,1) ; - } - -/*--------------------------------------------- _pop data */ - __inline_call void_type _pop_head ( - data_type &_data - ) - { - __assert( this->_hptr != nullptr && - "double_list._pop_head: null ptr"); - /*-- move data before _pop */ - _data = __move ( - data_type, this->_hptr->_data); - /*-- delegate to _pop impl.*/ - self_type::_pop_head () ; - } - -/*--------------------------------------------- _pop data */ - __inline_call void_type _pop_tail ( - ) - { - __assert( this->_tptr != nullptr && - "double_list._pop_tail: null ptr"); - /* shuffle next item onto list _head */ - item_type *_tail_item = - this->_tptr ; - this->_tptr = _tail_item->prev() ; - - if (this->_tptr != nullptr) - { /* Fix new tail item */ - this->_tptr->next() - = nullptr; - } - else - { /* list became empty */ - this->_hptr = nullptr; - } - this->_nobj -= +1 ; - - /* _destruct and deallocate old head */ - self_type:: _destruct(_tail_item) ; - self_type::deallocate(_tail_item,1) ; - } - -/*--------------------------------------------- _pop data */ - __inline_call void_type _pop_tail ( - data_type &_data - ) - { - __assert( this->_tptr != nullptr && - "double_list._pop_tail: null ptr"); - /*-- move data before _pop */ - _data = __move ( - data_type, this->_tptr->_data); - /*-- delegate to _pop impl.*/ - self_type::_pop_head () ; - } - -/*-------------------------- insert data (_def construct) */ - __normal_call _write_it insert_next ( - _write_it _prev_iter - ) - { - item_type *_prev_item, *_next_item ; - if ((_prev_item = - _prev_iter. item()) == nullptr) - { /* push onto list head */ - return push_head() ; - } - else - if ((_next_item = - _prev_item->next()) == nullptr) - { /* push onto list tail */ - return push_tail() ; - } - else - { /* insert in middle of list */ - item_type *_this_item = - self_type::allocate(1); - self_type::construct( - _this_item, - _next_item, - _prev_item) ; - - _prev_item->next() = _this_item; - _next_item->prev() = _this_item; - this->_nobj += +1 ; - - return _write_it( - _this_item, (self_type*)this) ; - } - } - -/*-------------------------- insert data (copy construct) */ - __normal_call _write_it insert_next ( - _write_it _prev_iter, - data_type const&_data - ) - { - item_type *_prev_item, *_next_item; - if ((_prev_item = - _prev_iter. item()) == nullptr) - { /* push onto list head */ - return push_head( - __copy(data_type,_data)) ; - } - else - if ((_next_item = - _prev_item->next()) == nullptr) - { /* push onto list tail */ - return push_tail( - __copy(data_type,_data)) ; - } - else - { /* insert in middle of list */ - item_type *_this_item = - self_type::allocate(1); - self_type::construct( - _this_item, - _next_item, - _prev_item, - __copy(data_type,_data)) ; - - _prev_item->next() = _this_item; - _next_item->prev() = _this_item; - this->_nobj += +1 ; - - return _write_it( - _this_item, (self_type*)this) ; - } - } - -/*-------------------------- insert data (move construct) */ - __normal_call _write_it insert_next ( - _write_it _prev_iter, - data_type &&_data - ) - { - item_type *_prev_item, *_next_item; - if ((_prev_item = - _prev_iter. item()) == nullptr) - { /* push onto list head */ - return push_head( - __move(data_type,_data)) ; - } - else - if ((_next_item = - _prev_item->next()) == nullptr) - { /* push onto list tail */ - return push_tail( - __move(data_type,_data)) ; - } - else - { /* insert in middle of list */ - item_type *_this_item = - self_type::allocate(1); - self_type::construct( - _this_item, - _next_item, - _prev_item, - __move(data_type,_data)) ; - - _prev_item->next() = _this_item; - _next_item->prev() = _this_item; - this->_nobj += +1 ; - - return _write_it( - _this_item, (self_type*)this) ; - } - } - -/*-------------------------- insert data (_def construct) */ - __normal_call _write_it insert_prev ( - _write_it _next_iter - ) - { - item_type *_prev_item, *_next_item ; - if ((_next_item = - _next_iter. item()) == nullptr) - { /* push onto list tail */ - return push_tail() ; - } - else - if ((_prev_item = - _next_item->prev()) == nullptr) - { /* push onto list head */ - return push_head() ; - } - else - { /* insert in middle of list */ - item_type *_this_item = - self_type::allocate(1); - self_type::construct( - _this_item, - _next_item, - _prev_item) ; - - _prev_item->next() = _this_item; - _next_item->prev() = _this_item; - this->_nobj += +1 ; - - return _write_it( - _this_item, (self_type*)this) ; - } - } - -/*-------------------------- insert data (_def construct) */ - __normal_call _write_it insert_prev ( - _write_it _next_iter, - data_type const&_data - ) - { - item_type *_prev_item, *_next_item; - if ((_next_item = - _next_iter. item()) == nullptr) - { /* push onto list tail */ - return push_tail( - __copy(data_type,_data)) ; - } - else - if ((_prev_item = - _next_item->prev()) == nullptr) - { /* push onto list head */ - return push_head( - __copy(data_type,_data)) ; - } - else - { /* insert in middle of list */ - item_type *_this_item = - self_type::allocate(1); - self_type::construct( - _this_item, - _next_item, - _prev_item, - __copy(data_type,_data)) ; - - _prev_item->next() = _this_item; - _next_item->prev() = _this_item; - this->_nobj += +1 ; - - return _write_it( - _this_item, (self_type*)this) ; - } - } - -/*-------------------------- insert data (move construct) */ - __normal_call _write_it insert_prev ( - _write_it _next_iter, - data_type && _data - ) - { - item_type *_prev_item, *_next_item; - if ((_next_item = - _next_iter. item()) == nullptr) - { /* push onto list tail */ - return push_tail( - __move(data_type,_data)) ; - } - else - if ((_prev_item = - _next_item->prev()) == nullptr) - { /* push onto list head */ - return push_head( - __move(data_type,_data)) ; - } - else - { /* insert in middle of list */ - item_type *_this_item = - self_type::allocate(1); - self_type::construct( - _this_item, - _next_item, - _prev_item, - __move(data_type,_data)) ; - - _prev_item->next() = _this_item; - _next_item->prev() = _this_item; - this->_nobj += +1 ; - - return _write_it( - _this_item, (self_type*)this) ; - } - } - -/*-------------------------------------------- erase item */ - __normal_call void_type erase ( - _write_it _this_iter - ) - { - __assert ( - _this_iter.item() != nullptr && - "list.erase: null iterator!") ; - /* _pop item, re-link, _destruct//deallocate */ - item_type - *_this_item = _this_iter. item() , - *_prev_item = _this_item->prev() , - *_next_item = _this_item->next() ; - - if (_prev_item != nullptr) - { - _prev_item->next() = _next_item ; - } - else - { /* collapse against head */ - this->_hptr = _next_item ; - } - if (_next_item != nullptr) - { - _next_item->prev() = _prev_item ; - } - else - { /* collapse against tail */ - this->_tptr = _prev_item ; - } - this->_nobj -= +1 ; - - self_type:: _destruct(_this_item) ; - self_type::deallocate(_this_item,1) ; - } - - } ; - -# undef __cont - - - } - -# endif //__DOUBLE_LIST__ - - - + +/* +------------------------------------------------------------ + * a doubly-linked list object. +------------------------------------------------------------ + * + * DOUBLE-LIST is a "doubly-linked" list type, where + * list items comprise a doubly-oriented chain of + * pointers. Insertion/deletion is O(1), acccess is O(N). + * List count is stored explicitly, and is O(1) as a + * result. + * +------------------------------------------------------------ + * + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) + * + * Disclaimer: Neither I nor: Columbia University, The + * Massachusetts Institute of Technology, The + * University of Sydney, nor The National Aeronautics + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be + * used at your own risk. + * +------------------------------------------------------------ + * + * Last updated: 03 May, 2017 + * + * Copyright 2013-2017 + * Darren Engwirda + * de2363@columbia.edu + * https://github.com/dengwirda/ + * +------------------------------------------------------------ + */ + +# pragma once + +# ifndef __DOUBLE_LIST__ +# define __DOUBLE_LIST__ + +# include "doubleiter.hpp" + + namespace containers { + +# define __cont containers + + template < + typename D + > + class double_item + { +/*------------------------------- doubly-linked list item */ + public : + + typedef D data_type ; + typedef + __cont::double_item self_type ; + + public : + + self_type *_next ; + self_type *_prev ; + + data_type _data ; + + public : + +/*------------------------------- c'tor/d'tor/assign etc. */ + __inline_call double_item ( + self_type *_nsrc , + self_type *_psrc + ) : _next( _nsrc), + _prev( _psrc) + { /* void construct */ + } + + __inline_call double_item ( + self_type *_nsrc , + self_type *_psrc , + data_type const&_dsrc + ) : _next( _nsrc), + _prev( _psrc), + _data( + __copy(data_type,_dsrc)) + { /* copy construct */ + } + + __inline_call double_item ( + self_type *_nsrc , + self_type *_psrc , + data_type&&_dsrc + ) : _next( _nsrc), + _prev( _psrc), + _data( + __move(data_type,_dsrc)) + { /* move construct */ + } + + __inline_call~double_item() = default ; + + __inline_call double_item ( + self_type const&_src + ) = default ; + __inline_call double_item ( + self_type && _src + ) = default ; + + __inline_call + self_type & operator= ( + self_type const&_src + ) = default ; + __inline_call + self_type & operator= ( + self_type && _src + ) = default ; + +/*------------------------------ access to "next" pointer */ + __inline_call self_type*& next ( + ) + { return ( this->_next ) ; + } + +/*------------------------------ access to "prev" pointer */ + __inline_call self_type*& prev ( + ) + { return ( this->_prev ) ; + } + + } ; + + template < + typename D , + typename A = allocators::basic_alloc + > + class double_list : public + allocators::_item_alloc < + double_item < D>, A > + { +/*------ double-ended linked-list for doubly-linked items */ + public : + + typedef D data_type ; + typedef A allocator ; + + typedef containers::double_list < + data_type , + allocator > self_type ; + + typedef containers::double_item < + data_type > item_type ; + typedef allocators::_item_alloc < + item_type , + allocator > obj_alloc ; + + typedef __cont::const_double_iterator < + self_type > _const_it ; + typedef __cont::write_double_iterator < + self_type > _write_it ; + + typedef typename + allocator::size_type size_type ; + typedef typename + allocator::diff_type diff_type ; + + private : + + item_type *_hptr ; // head/tail pointers + item_type *_tptr ; + size_type _nobj ; + + private : + +/*------------------------------ helper - construct range */ + template < + typename iter_type + > + __normal_call void_type copy_list ( + iter_type _head, + iter_type _tend, + __cont::base_iterator_kind + ) + { /* push the sequence onto list */ + for ( ; _head != _tend; ++_head) + push_tail(*_head) ; + } + + __inline_call void_type copy_list ( + size_type _size , + data_type const& _dsrc, + __cont::null_iterator_kind + ) + { copy_data(_size, _dsrc); + } + + __normal_call void_type copy_data ( + size_type _size, + data_type const& _dsrc + ) + { /* push _size copies onto list */ + for ( ; _size-- != 0; ) + push_head(_dsrc); + } + + public : + +/*--------------------------- default c'tor - do nothing! */ + __inline_call double_list ( + allocator const&_asrc = allocator() + ) : obj_alloc( _asrc ) + { /* construct pointers and allocator */ + this->_nobj = +0 ; + this->_hptr = nullptr ; + this->_tptr = nullptr ; + } + +/*--------------------------- default c'tor - initialisor */ + __inline_call double_list ( + size_type _size , + data_type const&_dsrc = data_type(), + allocator const&_asrc = allocator() + ) : obj_alloc( _asrc ) + { + this->_nobj = +0 ; + this->_hptr = nullptr ; + this->_tptr = nullptr ; + copy_data(_size,_dsrc); + } + +/*--------------------------- default c'tor - initialisor */ + template < + typename iter_type + > + __inline_call double_list ( + iter_type _head, + iter_type _tail, + allocator const&_asrc = allocator() + ) : obj_alloc( _asrc ) + { + this->_nobj = +0 ; + this->_hptr = nullptr ; + this->_tptr = nullptr ; + copy_list(_head,_tail,__cont::iter_kind(_head)) ; + } + +/*-------------------------------------------- _def d'tor */ + __inline_call~double_list ( + ) { clear() ; } + +/*-------------------------------------------- copy c'tor */ + __inline_call double_list ( + self_type const& _src + ) : obj_alloc( + __copy(obj_alloc,_src)) + { + this->_nobj = +0 ; + this->_hptr = nullptr ; + this->_tptr = nullptr ; + /*------------------------------- copy data from _src */ + _const_it _head, _tail; + _head = _src.head(); + _tail = _src.tend(); + copy_list(_head,_tail, + __cont::iter_kind(_head)) ; + } + +/*-------------------------------------------- move c'tor */ + __inline_call double_list ( + self_type && _src + ) : obj_alloc( + __move(obj_alloc,_src)) + { + /*------------------------------- move data from _src */ + this->_nobj = _src._nobj ; + this->_hptr = _src._hptr ; + this->_tptr = _src._tptr ; + _src. _nobj = +0 ; + _src. _hptr = nullptr ; + _src. _tptr = nullptr ; + } + +/*-------------------------------------------- copy a-op. */ + __inline_call self_type& operator = ( + self_type const& _src + ) + { + if (this != &_src) + { + self_type _copy ( + __copy(self_type, _src)) ; + + using std::swap ; + swap ( + static_cast(*this), + static_cast(_copy)) ; + + swap(this->_hptr, + _copy. _hptr) ; + swap(this->_tptr, + _copy. _tptr) ; + swap(this->_nobj, + _copy. _nobj) ; + } + + return ( *this ) ; + } + +/*-------------------------------------------- move a-op. */ + __inline_call self_type &operator = ( + self_type && _src + ) + { + if (this != &_src) + { + self_type _copy ( + __move(self_type, _src)) ; + + using std::swap ; + swap ( + static_cast(*this), + static_cast(_copy)) ; + + swap(this->_hptr, + _copy. _hptr) ; + swap(this->_tptr, + _copy. _tptr) ; + swap(this->_nobj, + _copy. _nobj) ; + } + + return ( *this ) ; + } + +/*-------------------------------- return container count */ + __inline_call size_type count ( + ) const { return ( this->_nobj ) ; } + +/*-------------------------------- true if sequence empty */ + __inline_call bool_type empty ( + ) const + { /* return empty status */ + return ( nullptr ==this->_hptr ) ; + } + +/*-------------------------------- return container alloc */ + __inline_call allocator get_alloc( + ) const + { + return + static_cast ( *this ) ; + } + +/*------------------------------ "const" access iterators */ + __inline_call _const_it head ( + ) const + {/*---- return iterator for list head */ + self_type *_obj = (self_type *)this; + return _const_it(this->_hptr, _obj); + } + + __inline_call _const_it tail ( + ) const + {/*---- return iterator for list tail */ + self_type *_obj = (self_type *)this; + return _const_it(this->_tptr, _obj); + } + + __inline_call _const_it hend ( + ) const + {/* return iterator "past" head, via null terminator! */ + self_type *_obj = (self_type *)this; + return _const_it(nullptr, _obj) ; + } + + __inline_call _const_it tend ( + ) const + {/* return iterator "past" tail, via null terminator! */ + self_type *_obj = (self_type *)this; + return _const_it(nullptr, _obj) ; + } + +/*------------------------------ "write" access iterators */ + __inline_call _write_it head ( + ) + {/*---- return iterator for list head */ + self_type *_obj = (self_type *)this; + return _write_it(this->_hptr, _obj); + } + + __inline_call _write_it tail ( + ) + {/*---- return iterator for list tail */ + self_type *_obj = (self_type *)this; + return _write_it(this->_tptr, _obj); + } + + __inline_call _write_it hend ( + ) + {/* return iterator "past" head, via null terminator! */ + self_type *_obj = (self_type *)this; + return _write_it(nullptr, _obj) ; + } + + __inline_call _write_it tend ( + ) + {/* return iterator "past" tail, via null terminator! */ + self_type *_obj = (self_type *)this; + return _write_it(nullptr, _obj) ; + } + +/*-------------------------------------- "free" container */ + __normal_call void_type clear ( + ) + {/* _pop all items in traversal from head */ + _write_it _head = head(); + _write_it _tend = tend(); + for ( ; _head != _tend; ) + { + _write_it _prev(_head++) ; + self_type:: + _destruct(_prev.item()) ; + self_type:: + deallocate(_prev.item(),1) ; + } + this->_nobj = +0 ; + this->_hptr = nullptr ; + this->_tptr = nullptr ; + } + +/*---------------------------- push data (_def construct) */ + __inline_call _write_it push_head ( + ) + {/* allocate and construct a new raw item */ + item_type *_this_item = + self_type::allocate(1); + + if (this->_hptr != nullptr) + { /* push onto list head only */ + self_type::construct(_this_item, + this->_hptr,//link! + (item_type *)nullptr) ; + + this->_hptr->prev() + = _this_item; + this->_hptr = _this_item; + } + else + { /* push onto list head/tail */ + self_type::construct(_this_item, + (item_type *)nullptr, + (item_type *)nullptr) ; + + this->_hptr = _this_item; + this->_tptr = _this_item; + } + this->_nobj += +1 ; + + return _write_it( + _this_item,(self_type*)this); + } + +/*---------------------------- push data (copy construct) */ + __inline_call _write_it push_head ( + data_type const&_data + ) + {/* allocate and construct a new raw item */ + item_type *_this_item = + self_type::allocate(1); + + if (this->_hptr != nullptr) + { /* push onto list head only */ + self_type::construct(_this_item, + this->_hptr,//link! + (item_type *)nullptr, + __copy(data_type,_data)); + + this->_hptr->prev() + = _this_item; + this->_hptr = _this_item; + } + else + { /* push onto list head/tail */ + self_type::construct(_this_item, + (item_type *)nullptr, + (item_type *)nullptr, + __copy(data_type,_data)); + + this->_hptr = _this_item; + this->_tptr = _this_item; + } + this->_nobj += +1 ; + + return _write_it( + _this_item,(self_type*)this); + } + +/*---------------------------- push data (move construct) */ + __inline_call _write_it push_head ( + data_type &&_data + ) + {/* allocate and construct a new raw item */ + item_type *_this_item = + self_type::allocate(1); + + if (this->_hptr != nullptr) + { /* push onto list head only */ + self_type::construct(_this_item, + this->_hptr,//link! + (item_type *)nullptr, + __move(data_type,_data)); + + this->_hptr->prev() + = _this_item; + this->_hptr = _this_item; + } + else + { /* push onto list head/tail */ + self_type::construct(_this_item, + (item_type *)nullptr, + (item_type *)nullptr, + __move(data_type,_data)); + + this->_hptr = _this_item; + this->_tptr = _this_item; + } + this->_nobj += +1 ; + + return _write_it( + _this_item,(self_type*)this); + } + +/*---------------------------- push data (_def construct) */ + __inline_call _write_it push_tail ( + ) + {/* allocate and construct a new raw item */ + item_type *_this_item = + self_type::allocate(1); + + if (this->_tptr != nullptr) + { /* push onto list tail only */ + self_type::construct(_this_item, + (item_type *)nullptr, + this->_tptr/*link*/) ; + + this->_tptr->next() + = _this_item; + this->_tptr = _this_item; + } + else + { /* push onto list tail/head */ + self_type::construct(_this_item, + (item_type *)nullptr, + (item_type *)nullptr) ; + + this->_hptr = _this_item; + this->_tptr = _this_item; + } + this->_nobj += +1 ; + + return _write_it( + _this_item,(self_type*)this); + } + +/*---------------------------- push data (copy construct) */ + __inline_call _write_it push_tail ( + data_type const&_data + ) + {/* allocate and construct a new raw item */ + item_type *_this_item = + self_type::allocate(1); + + if (this->_tptr != nullptr) + { /* push onto list tail only */ + self_type::construct(_this_item, + (item_type *)nullptr, + this->_tptr,//link! + __copy(data_type,_data)); + + this->_tptr->next() + = _this_item; + this->_tptr = _this_item; + } + else + { /* push onto list tail/head */ + self_type::construct(_this_item, + (item_type *)nullptr, + (item_type *)nullptr, + __copy(data_type,_data)); + + this->_hptr = _this_item; + this->_tptr = _this_item; + } + this->_nobj += +1 ; + + return _write_it( + _this_item,(self_type*)this); + } + +/*---------------------------- push data (move construct) */ + __inline_call _write_it push_tail ( + data_type &&_data + ) + {/* allocate and construct a new raw item */ + item_type *_this_item = + self_type::allocate(1); + + if (this->_tptr != nullptr) + { /* push onto list tail only */ + self_type::construct(_this_item, + (item_type *)nullptr, + this->_tptr,//link! + __move(data_type,_data)); + + this->_tptr->next() + = _this_item; + this->_tptr = _this_item; + } + else + { /* push onto list tail/head */ + self_type::construct(_this_item, + (item_type *)nullptr, + (item_type *)nullptr, + __move(data_type,_data)); + + this->_hptr = _this_item; + this->_tptr = _this_item; + } + this->_nobj += +1 ; + + return _write_it( + _this_item,(self_type*)this); + } + +/*---------------------------- push data (copy obj range) */ + template < + typename iter_type + > + __normal_call void_type push_head ( + iter_type _hend, + iter_type _tail + ) + { /* push a full sequence at tail */ + for(; _tail != _hend; --_tail ) + push_head(*_tail) ; + } + + template < + typename iter_type + > + __normal_call void_type push_tail ( + iter_type _head, + iter_type _tend + ) + { /* push a full sequence at tail */ + for(; _head != _tend; ++_head ) + push_tail(*_head) ; + } + +/*--------------------------------------------- _pop data */ + __inline_call void_type _pop_head ( + ) + { + __assert( this->_hptr != nullptr && + "double_list._pop_head: null ptr"); + /* shuffle next item onto list _head */ + item_type *_head_item = + this->_hptr ; + this->_hptr = _head_item->next() ; + + if (this->_hptr != nullptr) + { /* fix new head item */ + this->_hptr->prev() + = nullptr; + } + else + { /* list became empty */ + this->_tptr = nullptr; + } + this->_nobj -= +1 ; + + /* _destruct and deallocate old head */ + self_type:: _destruct(_head_item) ; + self_type::deallocate(_head_item,1) ; + } + +/*--------------------------------------------- _pop data */ + __inline_call void_type _pop_head ( + data_type &_data + ) + { + __assert( this->_hptr != nullptr && + "double_list._pop_head: null ptr"); + /*-- move data before _pop */ + _data = __move ( + data_type, this->_hptr->_data); + /*-- delegate to _pop impl.*/ + self_type::_pop_head () ; + } + +/*--------------------------------------------- _pop data */ + __inline_call void_type _pop_tail ( + ) + { + __assert( this->_tptr != nullptr && + "double_list._pop_tail: null ptr"); + /* shuffle next item onto list _head */ + item_type *_tail_item = + this->_tptr ; + this->_tptr = _tail_item->prev() ; + + if (this->_tptr != nullptr) + { /* Fix new tail item */ + this->_tptr->next() + = nullptr; + } + else + { /* list became empty */ + this->_hptr = nullptr; + } + this->_nobj -= +1 ; + + /* _destruct and deallocate old head */ + self_type:: _destruct(_tail_item) ; + self_type::deallocate(_tail_item,1) ; + } + +/*--------------------------------------------- _pop data */ + __inline_call void_type _pop_tail ( + data_type &_data + ) + { + __assert( this->_tptr != nullptr && + "double_list._pop_tail: null ptr"); + /*-- move data before _pop */ + _data = __move ( + data_type, this->_tptr->_data); + /*-- delegate to _pop impl.*/ + self_type::_pop_head () ; + } + +/*-------------------------- insert data (_def construct) */ + __normal_call _write_it insert_next ( + _write_it _prev_iter + ) + { + item_type *_prev_item, *_next_item ; + if ((_prev_item = + _prev_iter. item()) == nullptr) + { /* push onto list head */ + return push_head() ; + } + else + if ((_next_item = + _prev_item->next()) == nullptr) + { /* push onto list tail */ + return push_tail() ; + } + else + { /* insert in middle of list */ + item_type *_this_item = + self_type::allocate(1); + self_type::construct( + _this_item, + _next_item, + _prev_item) ; + + _prev_item->next() = _this_item; + _next_item->prev() = _this_item; + this->_nobj += +1 ; + + return _write_it( + _this_item, (self_type*)this) ; + } + } + +/*-------------------------- insert data (copy construct) */ + __normal_call _write_it insert_next ( + _write_it _prev_iter, + data_type const&_data + ) + { + item_type *_prev_item, *_next_item; + if ((_prev_item = + _prev_iter. item()) == nullptr) + { /* push onto list head */ + return push_head( + __copy(data_type,_data)) ; + } + else + if ((_next_item = + _prev_item->next()) == nullptr) + { /* push onto list tail */ + return push_tail( + __copy(data_type,_data)) ; + } + else + { /* insert in middle of list */ + item_type *_this_item = + self_type::allocate(1); + self_type::construct( + _this_item, + _next_item, + _prev_item, + __copy(data_type,_data)) ; + + _prev_item->next() = _this_item; + _next_item->prev() = _this_item; + this->_nobj += +1 ; + + return _write_it( + _this_item, (self_type*)this) ; + } + } + +/*-------------------------- insert data (move construct) */ + __normal_call _write_it insert_next ( + _write_it _prev_iter, + data_type &&_data + ) + { + item_type *_prev_item, *_next_item; + if ((_prev_item = + _prev_iter. item()) == nullptr) + { /* push onto list head */ + return push_head( + __move(data_type,_data)) ; + } + else + if ((_next_item = + _prev_item->next()) == nullptr) + { /* push onto list tail */ + return push_tail( + __move(data_type,_data)) ; + } + else + { /* insert in middle of list */ + item_type *_this_item = + self_type::allocate(1); + self_type::construct( + _this_item, + _next_item, + _prev_item, + __move(data_type,_data)) ; + + _prev_item->next() = _this_item; + _next_item->prev() = _this_item; + this->_nobj += +1 ; + + return _write_it( + _this_item, (self_type*)this) ; + } + } + +/*-------------------------- insert data (_def construct) */ + __normal_call _write_it insert_prev ( + _write_it _next_iter + ) + { + item_type *_prev_item, *_next_item ; + if ((_next_item = + _next_iter. item()) == nullptr) + { /* push onto list tail */ + return push_tail() ; + } + else + if ((_prev_item = + _next_item->prev()) == nullptr) + { /* push onto list head */ + return push_head() ; + } + else + { /* insert in middle of list */ + item_type *_this_item = + self_type::allocate(1); + self_type::construct( + _this_item, + _next_item, + _prev_item) ; + + _prev_item->next() = _this_item; + _next_item->prev() = _this_item; + this->_nobj += +1 ; + + return _write_it( + _this_item, (self_type*)this) ; + } + } + +/*-------------------------- insert data (_def construct) */ + __normal_call _write_it insert_prev ( + _write_it _next_iter, + data_type const&_data + ) + { + item_type *_prev_item, *_next_item; + if ((_next_item = + _next_iter. item()) == nullptr) + { /* push onto list tail */ + return push_tail( + __copy(data_type,_data)) ; + } + else + if ((_prev_item = + _next_item->prev()) == nullptr) + { /* push onto list head */ + return push_head( + __copy(data_type,_data)) ; + } + else + { /* insert in middle of list */ + item_type *_this_item = + self_type::allocate(1); + self_type::construct( + _this_item, + _next_item, + _prev_item, + __copy(data_type,_data)) ; + + _prev_item->next() = _this_item; + _next_item->prev() = _this_item; + this->_nobj += +1 ; + + return _write_it( + _this_item, (self_type*)this) ; + } + } + +/*-------------------------- insert data (move construct) */ + __normal_call _write_it insert_prev ( + _write_it _next_iter, + data_type && _data + ) + { + item_type *_prev_item, *_next_item; + if ((_next_item = + _next_iter. item()) == nullptr) + { /* push onto list tail */ + return push_tail( + __move(data_type,_data)) ; + } + else + if ((_prev_item = + _next_item->prev()) == nullptr) + { /* push onto list head */ + return push_head( + __move(data_type,_data)) ; + } + else + { /* insert in middle of list */ + item_type *_this_item = + self_type::allocate(1); + self_type::construct( + _this_item, + _next_item, + _prev_item, + __move(data_type,_data)) ; + + _prev_item->next() = _this_item; + _next_item->prev() = _this_item; + this->_nobj += +1 ; + + return _write_it( + _this_item, (self_type*)this) ; + } + } + +/*-------------------------------------------- erase item */ + __normal_call void_type erase ( + _write_it _this_iter + ) + { + __assert ( + _this_iter.item() != nullptr && + "list.erase: null iterator!") ; + /* _pop item, re-link, _destruct//deallocate */ + item_type + *_this_item = _this_iter. item() , + *_prev_item = _this_item->prev() , + *_next_item = _this_item->next() ; + + if (_prev_item != nullptr) + { + _prev_item->next() = _next_item ; + } + else + { /* collapse against head */ + this->_hptr = _next_item ; + } + if (_next_item != nullptr) + { + _next_item->prev() = _prev_item ; + } + else + { /* collapse against tail */ + this->_tptr = _prev_item ; + } + this->_nobj -= +1 ; + + self_type:: _destruct(_this_item) ; + self_type::deallocate(_this_item,1) ; + } + + } ; + +# undef __cont + + + } + +# endif //__DOUBLE_LIST__ + + + diff --git a/src/libcpp/containers/doubleiter.hpp b/src/libcpp/containers/doubleiter.hpp index d4a78bf..1aebc32 100644 --- a/src/libcpp/containers/doubleiter.hpp +++ b/src/libcpp/containers/doubleiter.hpp @@ -1,379 +1,379 @@ - -/* ------------------------------------------------------------- - * "double" iterator -- for doubly-linked sequences. ------------------------------------------------------------- - * - * DOUBLE-LIST is a "doubly-linked" list type, where - * list items comprise a doubly-oriented chain of - * pointers. Insertion/deletion is O(1), acccess is O(N). - * List count is stored explicitly, and is O(1) as a - * result. - * ------------------------------------------------------------- - * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) - * - * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The - * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be - * used at your own risk. - * ------------------------------------------------------------- - * - * Last updated: 03 May, 2017 - * - * Copyright 2013-2017 - * Darren Engwirda - * de2363@columbia.edu - * https://github.com/dengwirda/ - * ------------------------------------------------------------- - */ - -# pragma once - -# ifndef __DOUBLE_ITER__ -# define __DOUBLE_ITER__ - -# include "iter_base.hpp" - - namespace containers { - - template < - typename L, - typename I - > - class double_iterator_base_ : - public containers::double_iterator_base - { -/*---------------------- iterator for doubly-linked lists */ - public : - - typedef L list_type ; - typedef I iter_type ; - - typedef typename - list_type::data_type data_type ; - typedef typename - list_type::item_type item_type ; - typedef typename - list_type::size_type size_type ; - typedef typename - list_type::diff_type diff_type ; - - typedef double_iterator_base_ < - list_type , - iter_type > self_type ; - - public : - -# ifdef _DEBUG - item_type* _ptr; // list item - list_type* _obj; // list obj. -# else - item_type* _ptr; // list item -# endif - - public : - - __inline_call double_iterator_base_ ( - item_type *_psrc = nullptr, - list_type *_lsrc = nullptr -# ifdef _DEBUG - ) : _ptr(_psrc) , - _obj(_lsrc) {} -# else - ) : _ptr(_psrc) { __unreferenced(_lsrc) ; } -# endif - - __inline_call~double_iterator_base_ ( - ) = default ; - __inline_call double_iterator_base_ ( - self_type const&_src - ) = default ; - __inline_call double_iterator_base_ ( - self_type && _src - ) = default ; - - __inline_call - self_type & operator = ( - self_type const&_src - ) = default ; - __inline_call - self_type & operator = ( - self_type && _src - ) = default ; - -/*--------------------------------- translation operators */ - - __inline_call iter_type &operator++ ( - ) - { -# ifdef _DEBUG - __assert( this->_ptr != nullptr && - "double_iterator: null link!" ) ; -# endif - this->_ptr = this->_ptr->next() ; - return *(iter_type*)this; - } - __inline_call iter_type &operator-- ( - ) - { -# ifdef _DEBUG - __assert( this->_ptr != nullptr && - "double_iterator: null link!" ) ; -# endif - this->_ptr = this->_ptr->prev() ; - return *(iter_type*)this; - } - - __inline_call - iter_type operator++ ( int ) - { - iter_type _tmp(*(iter_type*)this) ; - ++*this; - return _tmp; - } - __inline_call - iter_type operator-- ( int ) - { - iter_type _tmp(*(iter_type*)this) ; - --*this; - return _tmp; - } - - __inline_call iter_type &operator+= ( - size_type _off - ) - { /* traverse list pointers */ - for ( ; _off > 0; --_off)++*this ; - return *(iter_type*)this ; - } - __inline_call iter_type &operator-= ( - size_type _off - ) - { /* traverse list pointers */ - for ( ; _off > 0; --_off)--*this ; - return *(iter_type*)this ; - } - - __inline_call iter_type operator + ( - size_type _off - ) const - { - iter_type _tmp(*(iter_type*)this) ; - return _tmp += _off; - } - __inline_call iter_type operator - ( - size_type _off - ) const - { - iter_type _tmp(*(iter_type*)this) ; - return _tmp -= _off; - } - -/*--------------------------------- comparative operators */ - - __inline_call bool_type operator == ( - self_type const&_src - ) const - { - return this->_ptr == _src._ptr ; - } - __inline_call bool_type operator != ( - self_type const&_src - ) const - { - return this->_ptr != _src._ptr ; - } - - } ; - - /* - -------------------------------------------------------- - * "const" iterators for doubly-linked sequences. - -------------------------------------------------------- - */ - - template < - typename L - > - class const_double_iterator: public - double_iterator_base_ > - { -/*---------------------- iterator for doubly-linked lists */ - public : - - typedef L list_type ; - - typedef const_double_iterator< - list_type > self_type ; - typedef double_iterator_base_< - list_type , - self_type > base_type ; - - typedef typename - base_type::data_type data_type ; - typedef typename - base_type::item_type item_type ; - typedef typename - base_type::size_type size_type ; - typedef typename - base_type::diff_type diff_type ; - - typedef data_type const& const_ref ; - typedef data_type const* const_ptr ; - - public : - - __inline_call const_double_iterator ( - item_type *_psrc = nullptr, - list_type *_lsrc = nullptr - ) : base_type(_psrc, _lsrc) {} - - __inline_call~const_double_iterator ( - ) = default ; - __inline_call const_double_iterator ( - self_type const&_src - ) = default ; - __inline_call const_double_iterator ( - self_type && _src - ) = default ; - - __inline_call - self_type & operator = ( - self_type const&_src - ) = default ; - __inline_call - self_type & operator = ( - self_type && _src - ) = default ; - -/*-------------------------------- "const" access to data */ - - __inline_call const_ref operator * ( - ) const - { -# ifdef _DEBUG - __assert( this->_ptr != nullptr && - "double_iterator: null pointer!"); -# endif - return this->_ptr->_data; - } - - __inline_call const_ptr operator-> ( - ) const { return &**this ; } - - __inline_call item_type const*item ( - ) const { return this->_ptr; } - - } ; - - /* - -------------------------------------------------------- - * "write" iterators for doubly-linked sequences. - -------------------------------------------------------- - */ - - template < - typename L - > - class write_double_iterator: public - double_iterator_base_ > - { -/*---------------------- iterator for doubly-linked lists */ - public : - - typedef L list_type ; - - typedef write_double_iterator< - list_type > self_type ; - typedef double_iterator_base_< - list_type , - self_type > base_type ; - - typedef typename - base_type::data_type data_type ; - typedef typename - base_type::item_type item_type ; - typedef typename - base_type::size_type size_type ; - typedef typename - base_type::diff_type diff_type ; - - typedef data_type & write_ref ; - typedef data_type * write_ptr ; - - public : - - __inline_call write_double_iterator ( - item_type *_psrc = nullptr, - list_type *_lsrc = nullptr - ) : base_type(_psrc, _lsrc) {} - - __inline_call~write_double_iterator ( - ) = default ; - __inline_call write_double_iterator ( - self_type const&_src - ) = default ; - __inline_call write_double_iterator ( - self_type && _src - ) = default ; - - __inline_call - self_type & operator = ( - self_type const&_src - ) = default ; - __inline_call - self_type & operator = ( - self_type && _src - ) = default ; - -/*-------------------------------- "write" access to data */ - - __inline_call write_ref operator * ( - ) const - { -# ifdef _DEBUG - __assert( this->_ptr != nullptr && - "double_iterator: null pointer!"); -# endif - return this->_ptr->_data; - } - - __inline_call write_ptr operator-> ( - ) const { return &**this ; } - - __inline_call item_type*item ( - ) const { return this->_ptr; } - - } ; - - - } - -# endif //__DOUBLE_ITER__ - - - + +/* +------------------------------------------------------------ + * "double" iterator -- for doubly-linked sequences. +------------------------------------------------------------ + * + * DOUBLE-LIST is a "doubly-linked" list type, where + * list items comprise a doubly-oriented chain of + * pointers. Insertion/deletion is O(1), acccess is O(N). + * List count is stored explicitly, and is O(1) as a + * result. + * +------------------------------------------------------------ + * + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) + * + * Disclaimer: Neither I nor: Columbia University, The + * Massachusetts Institute of Technology, The + * University of Sydney, nor The National Aeronautics + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be + * used at your own risk. + * +------------------------------------------------------------ + * + * Last updated: 03 May, 2017 + * + * Copyright 2013-2017 + * Darren Engwirda + * de2363@columbia.edu + * https://github.com/dengwirda/ + * +------------------------------------------------------------ + */ + +# pragma once + +# ifndef __DOUBLE_ITER__ +# define __DOUBLE_ITER__ + +# include "iter_base.hpp" + + namespace containers { + + template < + typename L, + typename I + > + class double_iterator_base_ : + public containers::double_iterator_base + { +/*---------------------- iterator for doubly-linked lists */ + public : + + typedef L list_type ; + typedef I iter_type ; + + typedef typename + list_type::data_type data_type ; + typedef typename + list_type::item_type item_type ; + typedef typename + list_type::size_type size_type ; + typedef typename + list_type::diff_type diff_type ; + + typedef double_iterator_base_ < + list_type , + iter_type > self_type ; + + public : + +# ifdef _DEBUG + item_type* _ptr; // list item + list_type* _obj; // list obj. +# else + item_type* _ptr; // list item +# endif + + public : + + __inline_call double_iterator_base_ ( + item_type *_psrc = nullptr, + list_type *_lsrc = nullptr +# ifdef _DEBUG + ) : _ptr(_psrc) , + _obj(_lsrc) {} +# else + ) : _ptr(_psrc) { __unreferenced(_lsrc) ; } +# endif + + __inline_call~double_iterator_base_ ( + ) = default ; + __inline_call double_iterator_base_ ( + self_type const&_src + ) = default ; + __inline_call double_iterator_base_ ( + self_type && _src + ) = default ; + + __inline_call + self_type & operator = ( + self_type const&_src + ) = default ; + __inline_call + self_type & operator = ( + self_type && _src + ) = default ; + +/*--------------------------------- translation operators */ + + __inline_call iter_type &operator++ ( + ) + { +# ifdef _DEBUG + __assert( this->_ptr != nullptr && + "double_iterator: null link!" ) ; +# endif + this->_ptr = this->_ptr->next() ; + return *(iter_type*)this; + } + __inline_call iter_type &operator-- ( + ) + { +# ifdef _DEBUG + __assert( this->_ptr != nullptr && + "double_iterator: null link!" ) ; +# endif + this->_ptr = this->_ptr->prev() ; + return *(iter_type*)this; + } + + __inline_call + iter_type operator++ ( int ) + { + iter_type _tmp(*(iter_type*)this) ; + ++*this; + return _tmp; + } + __inline_call + iter_type operator-- ( int ) + { + iter_type _tmp(*(iter_type*)this) ; + --*this; + return _tmp; + } + + __inline_call iter_type &operator+= ( + size_type _off + ) + { /* traverse list pointers */ + for ( ; _off > 0; --_off)++*this ; + return *(iter_type*)this ; + } + __inline_call iter_type &operator-= ( + size_type _off + ) + { /* traverse list pointers */ + for ( ; _off > 0; --_off)--*this ; + return *(iter_type*)this ; + } + + __inline_call iter_type operator + ( + size_type _off + ) const + { + iter_type _tmp(*(iter_type*)this) ; + return _tmp += _off; + } + __inline_call iter_type operator - ( + size_type _off + ) const + { + iter_type _tmp(*(iter_type*)this) ; + return _tmp -= _off; + } + +/*--------------------------------- comparative operators */ + + __inline_call bool_type operator == ( + self_type const&_src + ) const + { + return this->_ptr == _src._ptr ; + } + __inline_call bool_type operator != ( + self_type const&_src + ) const + { + return this->_ptr != _src._ptr ; + } + + } ; + + /* + -------------------------------------------------------- + * "const" iterators for doubly-linked sequences. + -------------------------------------------------------- + */ + + template < + typename L + > + class const_double_iterator: public + double_iterator_base_ > + { +/*---------------------- iterator for doubly-linked lists */ + public : + + typedef L list_type ; + + typedef const_double_iterator< + list_type > self_type ; + typedef double_iterator_base_< + list_type , + self_type > base_type ; + + typedef typename + base_type::data_type data_type ; + typedef typename + base_type::item_type item_type ; + typedef typename + base_type::size_type size_type ; + typedef typename + base_type::diff_type diff_type ; + + typedef data_type const& const_ref ; + typedef data_type const* const_ptr ; + + public : + + __inline_call const_double_iterator ( + item_type *_psrc = nullptr, + list_type *_lsrc = nullptr + ) : base_type(_psrc, _lsrc) {} + + __inline_call~const_double_iterator ( + ) = default ; + __inline_call const_double_iterator ( + self_type const&_src + ) = default ; + __inline_call const_double_iterator ( + self_type && _src + ) = default ; + + __inline_call + self_type & operator = ( + self_type const&_src + ) = default ; + __inline_call + self_type & operator = ( + self_type && _src + ) = default ; + +/*-------------------------------- "const" access to data */ + + __inline_call const_ref operator * ( + ) const + { +# ifdef _DEBUG + __assert( this->_ptr != nullptr && + "double_iterator: null pointer!"); +# endif + return this->_ptr->_data; + } + + __inline_call const_ptr operator-> ( + ) const { return &**this ; } + + __inline_call item_type const*item ( + ) const { return this->_ptr; } + + } ; + + /* + -------------------------------------------------------- + * "write" iterators for doubly-linked sequences. + -------------------------------------------------------- + */ + + template < + typename L + > + class write_double_iterator: public + double_iterator_base_ > + { +/*---------------------- iterator for doubly-linked lists */ + public : + + typedef L list_type ; + + typedef write_double_iterator< + list_type > self_type ; + typedef double_iterator_base_< + list_type , + self_type > base_type ; + + typedef typename + base_type::data_type data_type ; + typedef typename + base_type::item_type item_type ; + typedef typename + base_type::size_type size_type ; + typedef typename + base_type::diff_type diff_type ; + + typedef data_type & write_ref ; + typedef data_type * write_ptr ; + + public : + + __inline_call write_double_iterator ( + item_type *_psrc = nullptr, + list_type *_lsrc = nullptr + ) : base_type(_psrc, _lsrc) {} + + __inline_call~write_double_iterator ( + ) = default ; + __inline_call write_double_iterator ( + self_type const&_src + ) = default ; + __inline_call write_double_iterator ( + self_type && _src + ) = default ; + + __inline_call + self_type & operator = ( + self_type const&_src + ) = default ; + __inline_call + self_type & operator = ( + self_type && _src + ) = default ; + +/*-------------------------------- "write" access to data */ + + __inline_call write_ref operator * ( + ) const + { +# ifdef _DEBUG + __assert( this->_ptr != nullptr && + "double_iterator: null pointer!"); +# endif + return this->_ptr->_data; + } + + __inline_call write_ptr operator-> ( + ) const { return &**this ; } + + __inline_call item_type*item ( + ) const { return this->_ptr; } + + } ; + + + } + +# endif //__DOUBLE_ITER__ + + + diff --git a/src/libcpp/containers/fixed_array.hpp b/src/libcpp/containers/fixed_array.hpp index 27b9fe5..2aac51d 100644 --- a/src/libcpp/containers/fixed_array.hpp +++ b/src/libcpp/containers/fixed_array.hpp @@ -1,290 +1,290 @@ - -/* ------------------------------------------------------------- - * "fixed-array" -- contiguous static buffer. ------------------------------------------------------------- - * - * FIXED-ARRAY is a simple wrapper over a "c"-style - * statically allocated array. Array size is fixed. It - * provides O(1) random access, and that's about it! - * ------------------------------------------------------------- - * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) - * - * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The - * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be - * used at your own risk. - * ------------------------------------------------------------- - * - * Last updated: 03 May, 2017 - * - * Copyright 2013-2017 - * Darren Engwirda - * de2363@columbia.edu - * https://github.com/dengwirda/ - * ------------------------------------------------------------- - */ - -# pragma once - -# ifndef __FIXED_ARRAY__ -# define __FIXED_ARRAY__ - -# include "array_iter.hpp" - - namespace containers { - -# define __cont containers - - template < - typename D, - std::size_t L - > - class fixed_array - { -/*------------ simple wrapper for "c-style" static arrays */ - public : - typedef D data_type ; - - typedef std:: size_t size_type ; - typedef std::ptrdiff_t diff_type ; - - size_type static const _size = L > +0 ? - L : +1 ; - - typedef __cont::fixed_array < - data_type, L > self_type ; - - typedef __cont::const_array_iterator < - self_type > _const_it ; - typedef __cont::write_array_iterator < - self_type > _write_it ; - - private : - - data_type _data[ _size] ; - - private : - -/*-------------------------------- helper - copy sequence */ - __normal_call void_type copy_data ( - size_type _size, - data_type const& _dsrc - ) - { - for (auto _item = head() ; - _size != +0 ; - --_size, ++_item ) - { - *_item = _dsrc ; - } - } - -/*-------------------------------- helper - copy sequence */ - template < - typename iter_type - > - __normal_call void_type copy_iter ( - iter_type _head, - iter_type _tail, - __cont::base_iterator_kind - ) - { - for (auto _item = head() ; - _head != _tail; - ++_item, ++_head ) - { - *_item = *_head ; - } - } - __inline_call void_type copy_iter ( - size_type _size, - data_type const& _dsrc , - __cont::null_iterator_kind - ) - { copy_data(_size, _dsrc); - } - - public : - -/*--------------------------- default c'tor - do nothing! */ - __inline_call fixed_array ( - ) {} - -/*--------------------------- default c'tor - initialisor */ - __inline_call fixed_array ( - size_type _size, - data_type const&_dsrc = data_type () - ) - { copy_data(_size, _dsrc) ; - } - -/*--------------------------- default c'tor - initialisor */ - template < - typename iter_type - > - __inline_call fixed_array ( - iter_type _head, - iter_type _tail - ) - { - copy_iter(_head,_tail , - __cont::iter_kind(_head)) ; - } - -/*--------------------------- default d'tor/copy/move ops */ - __inline_call~fixed_array () = default ; - - __inline_call fixed_array ( - self_type const& _src - ) = default ; - __inline_call fixed_array ( - self_type && _src - ) = default ; - - __inline_call - self_type& operator = ( - self_type const& _src - ) = default ; - __inline_call - self_type& operator = ( - self_type && _src - ) = default ; - -/*-------------------------------------------- fill array */ - __inline_call void_type fill ( - data_type const& _dsrc = data_type() - ) - { copy_data(_size, _dsrc) ; - } - -/*-------------------------------------------- operator[] */ - __inline_call data_type &operator[] ( - size_type _pos - ) - { /*------ index into underlying array */ - __assert ( _pos >= +0 && - _pos < _size && - "fixed_array[]: out of range!") ; - - return this->_data[_pos] ; - } - - __inline_call data_type const&operator[] ( - size_type _pos - ) const - { /*------ index into underlying array */ - __assert ( _pos >= +0 && - _pos < _size && - "fixed_array[]: out of range!") ; - - return this->_data[_pos] ; - } - -/*--------------------------------------- container count */ - __inline_call size_type count ( - ) const { return ( _size ); } - -/*--------------------------------------- container alloc */ - __inline_call size_type alloc ( - ) const { return ( _size ); } - -/*--------------------------------------- write iterators */ - __inline_call _write_it head ( - ) - { /* return iterator to head of array */ - size_type _off = 0; - self_type *_obj = (self_type *)this ; - return _write_it(this->_data + _off, _obj); - } - - __inline_call _write_it tail ( - ) - { /* return iterator to tail of array */ - size_type _off = _size - 1; - self_type *_obj = (self_type *)this ; - return _write_it(this->_data + _off, _obj); - } - - __inline_call _write_it hend ( - ) - { /* return iterator at head - 1 */ - size_type _off = 1; - self_type *_obj = (self_type *)this ; - return _write_it(this->_data + _off, _obj); - } - - __inline_call _write_it tend ( - ) - { /* return iterator at tail + 1 */ - size_type _off = _size - 0; - self_type *_obj = (self_type *)this ; - return _write_it(this->_data + _off, _obj); - } - -/*--------------------------------------- const iterators */ - __inline_call _const_it head ( - ) const - { /* return iterator to head of array */ - size_type _off = 0; - self_type *_obj = (self_type *)this ; - return _const_it(this->_data + _off, _obj); - } - - __inline_call _const_it tail ( - ) const - { /* return iterator to tail of array */ - size_type _off = _size - 1; - self_type *_obj = (self_type *)this ; - return _const_it(this->_data + _off, _obj); - } - - __inline_call _const_it hend ( - ) const - { /* return iterator at head - 1 */ - size_type _off = 1; - self_type *_obj = (self_type *)this ; - return _const_it(this->_data - _off, _obj); - } - - __inline_call _const_it tend ( - ) const - { /* return iterator at tail + 1 */ - size_type _off = _size - 0; - self_type *_obj = (self_type *)this ; - return _const_it(this->_data + _off, _obj); - } - - } ; - -# undef __cont - - - } - -# endif //__FIXED_ARRAY__ - - - + +/* +------------------------------------------------------------ + * "fixed-array" -- contiguous static buffer. +------------------------------------------------------------ + * + * FIXED-ARRAY is a simple wrapper over a "c"-style + * statically allocated array. Array size is fixed. It + * provides O(1) random access, and that's about it! + * +------------------------------------------------------------ + * + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) + * + * Disclaimer: Neither I nor: Columbia University, The + * Massachusetts Institute of Technology, The + * University of Sydney, nor The National Aeronautics + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be + * used at your own risk. + * +------------------------------------------------------------ + * + * Last updated: 03 May, 2017 + * + * Copyright 2013-2017 + * Darren Engwirda + * de2363@columbia.edu + * https://github.com/dengwirda/ + * +------------------------------------------------------------ + */ + +# pragma once + +# ifndef __FIXED_ARRAY__ +# define __FIXED_ARRAY__ + +# include "array_iter.hpp" + + namespace containers { + +# define __cont containers + + template < + typename D, + std::size_t L + > + class fixed_array + { +/*------------ simple wrapper for "c-style" static arrays */ + public : + typedef D data_type ; + + typedef std:: size_t size_type ; + typedef std::ptrdiff_t diff_type ; + + size_type static const _size = L > +0 ? + L : +1 ; + + typedef __cont::fixed_array < + data_type, L > self_type ; + + typedef __cont::const_array_iterator < + self_type > _const_it ; + typedef __cont::write_array_iterator < + self_type > _write_it ; + + private : + + data_type _data[ _size] ; + + private : + +/*-------------------------------- helper - copy sequence */ + __normal_call void_type copy_data ( + size_type _SIZE, + data_type const& _dsrc + ) + { + for (auto _item = head() ; + _SIZE != +0 ; + --_SIZE, ++_item ) + { + *_item = _dsrc ; + } + } + +/*-------------------------------- helper - copy sequence */ + template < + typename iter_type + > + __normal_call void_type copy_iter ( + iter_type _head, + iter_type _tail, + __cont::base_iterator_kind + ) + { + for (auto _item = head() ; + _head != _tail; + ++_item, ++_head ) + { + *_item = *_head ; + } + } + __inline_call void_type copy_iter ( + size_type _SIZE, + data_type const& _dsrc , + __cont::null_iterator_kind + ) + { copy_data(_SIZE, _dsrc); + } + + public : + +/*--------------------------- default c'tor - do nothing! */ + __inline_call fixed_array ( + ) {} + +/*--------------------------- default c'tor - initialisor */ + __inline_call fixed_array ( + size_type _SIZE, + data_type const&_dsrc = data_type () + ) + { copy_data(_SIZE, _dsrc) ; + } + +/*--------------------------- default c'tor - initialisor */ + template < + typename iter_type + > + __inline_call fixed_array ( + iter_type _head, + iter_type _tail + ) + { + copy_iter(_head,_tail , + __cont::iter_kind(_head)) ; + } + +/*--------------------------- default d'tor/copy/move ops */ + __inline_call~fixed_array () = default ; + + __inline_call fixed_array ( + self_type const& _src + ) = default ; + __inline_call fixed_array ( + self_type && _src + ) = default ; + + __inline_call + self_type& operator = ( + self_type const& _src + ) = default ; + __inline_call + self_type& operator = ( + self_type && _src + ) = default ; + +/*-------------------------------------------- fill array */ + __inline_call void_type fill ( + data_type const& _dsrc = data_type() + ) + { copy_data(_size, _dsrc) ; + } + +/*-------------------------------------------- operator[] */ + __inline_call data_type &operator[] ( + size_type _pos + ) + { /*------ index into underlying array */ + __assert ( _pos >= +0 && + _pos < _size && + "fixed_array[]: out of range!") ; + + return this->_data[_pos] ; + } + + __inline_call data_type const&operator[] ( + size_type _pos + ) const + { /*------ index into underlying array */ + __assert ( _pos >= +0 && + _pos < _size && + "fixed_array[]: out of range!") ; + + return this->_data[_pos] ; + } + +/*--------------------------------------- container count */ + __inline_call size_type count ( + ) const { return ( _size ); } + +/*--------------------------------------- container alloc */ + __inline_call size_type alloc ( + ) const { return ( _size ); } + +/*--------------------------------------- write iterators */ + __inline_call _write_it head ( + ) + { /* return iterator to head of array */ + size_type _off = 0; + self_type *_obj = (self_type *)this ; + return _write_it(this->_data + _off, _obj); + } + + __inline_call _write_it tail ( + ) + { /* return iterator to tail of array */ + size_type _off = _size - 1; + self_type *_obj = (self_type *)this ; + return _write_it(this->_data + _off, _obj); + } + + __inline_call _write_it hend ( + ) + { /* return iterator at head - 1 */ + size_type _off = 1; + self_type *_obj = (self_type *)this ; + return _write_it(this->_data + _off, _obj); + } + + __inline_call _write_it tend ( + ) + { /* return iterator at tail + 1 */ + size_type _off = _size - 0; + self_type *_obj = (self_type *)this ; + return _write_it(this->_data + _off, _obj); + } + +/*--------------------------------------- const iterators */ + __inline_call _const_it head ( + ) const + { /* return iterator to head of array */ + size_type _off = 0; + self_type *_obj = (self_type *)this ; + return _const_it(this->_data + _off, _obj); + } + + __inline_call _const_it tail ( + ) const + { /* return iterator to tail of array */ + size_type _off = _size - 1; + self_type *_obj = (self_type *)this ; + return _const_it(this->_data + _off, _obj); + } + + __inline_call _const_it hend ( + ) const + { /* return iterator at head - 1 */ + size_type _off = 1; + self_type *_obj = (self_type *)this ; + return _const_it(this->_data - _off, _obj); + } + + __inline_call _const_it tend ( + ) const + { /* return iterator at tail + 1 */ + size_type _off = _size - 0; + self_type *_obj = (self_type *)this ; + return _const_it(this->_data + _off, _obj); + } + + } ; + +# undef __cont + + + } + +# endif //__FIXED_ARRAY__ + + + diff --git a/src/libcpp/containers/hashtable.hpp b/src/libcpp/containers/hashtable.hpp index 81de10e..37792f4 100644 --- a/src/libcpp/containers/hashtable.hpp +++ b/src/libcpp/containers/hashtable.hpp @@ -1,457 +1,567 @@ - -/* ------------------------------------------------------------- - * a chained hash-table. ------------------------------------------------------------- - * - * HASH-TABLE is a dynamically-sized, chained hash-table - * implementation, essentially a linear array of singly- - * linked hash buckets. - * ------------------------------------------------------------- - * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) - * - * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The - * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be - * used at your own risk. - * ------------------------------------------------------------- - * - * Last updated: 03 May, 2017 - * - * Copyright 2013-2017 - * Darren Engwirda - * de2363@columbia.edu - * https://github.com/dengwirda/ - * ------------------------------------------------------------- - */ - -# pragma once - -# ifndef __HASH_TABLE__ -# define __HASH_TABLE__ - -# include "arraylist.hpp" - - namespace containers { - -# define __cont containers - - template < - typename D , - typename H , - typename P , - typename A = allocators::basic_alloc - > - class hash_table : - public containers::array_list - { -/*------------------------- a dynamic, chained hash-table */ - public : - - typedef D data_type ; - typedef H hash_type ; - typedef P pred_type ; - typedef A allocator ; - - typedef containers::array_list < - data_type , - allocator > base_type ; - - typedef typename - base_type::size_type size_type ; - typedef typename - base_type::diff_type diff_type ; - typedef typename - base_type::item_type item_type ; - typedef typename - base_type::lptr_list lptr_list ; - - typedef typename - base_type::_write_it _write_it ; - typedef typename - base_type::_const_it _const_it ; - - typedef containers::hash_table < - data_type , - hash_type , - pred_type , - allocator > self_type ; - - size_type static const _mini_count = +8 ; - - public : - - hash_type _hash; - pred_type _pred; - - double _load; - - public : - -/*------------------------ update table count and re-hash */ - __normal_call void_type redo_hash ( - ) - { - item_type*_head = nullptr ; - item_type*_tail = nullptr ; - item_type*_next = nullptr ; - /*--------------- splice together a list of all items */ - typename lptr_list::_write_it - _iter = this->_lptr.head(), - _tend = this->_lptr.tend(); - for( ; _iter != _tend; ++_iter) - { - /*--------------------- find first non-empty list */ - if (*_iter != nullptr) - { - _head = *_iter; - _tail = *_iter; - *_iter = nullptr; - _iter++; break; - } - } - for( ; _iter != _tend; ++_iter) - { - /*--------------- splice remaining lists together */ - if (*_iter != nullptr) - { - _tail = *_iter; - for(; nullptr != _tail->_next; ) - { - _tail=_tail->_next ; - } - /*------ re-attach at _tail and jump to _head */ - _tail-> - _next = _head; - _head = *_iter; - *_iter = nullptr ; - } - } - - /*------------------------------- increase table size */ - if (this->_lptr.count() < this->_mini_count) - this->_lptr.set_count ( - this->_mini_count , - containers::loose_alloc, nullptr) ; - else - this->_lptr.set_count ( - this->_lptr.count()*+2, - containers::loose_alloc, nullptr) ; - - /*------------------ re-hash all items onto new table */ - for ( ; _head != nullptr; _head = _next) - { - _next = _head->_next; - /*--------------------------- calc new hash value */ - size_type _hpos = - this->_hash(_head->_data) - % this->_lptr.count() ; - /*--------------------------- push onto new table */ - base_type::push_item( - this->_lptr[_hpos],_head) ; - } - } - - public : - -/*--------------------------- default c'tor - do nothing! */ - __normal_call hash_table ( - hash_type const&_hsrc = hash_type(), - pred_type const&_psrc = pred_type(), - double const&_lsrc = double(+.9), - allocator const&_asrc = allocator() - /*----------------------------- c'tor alloc from obj. */ - ) : base_type( _asrc), - /*----------------------------- c'tor other from obj. */ - _hash(_hsrc) , - _pred(_psrc) , - _load(_lsrc) {} - -/*--------------------------- default d'tor/copy/move ops */ - __inline_call~hash_table () = default ; - - __inline_call hash_table ( - self_type const& _src - ) = default ; - __inline_call hash_table ( - self_type && _src - ) = default ; - - __inline_call - self_type& operator = ( - self_type const& _src - ) = default ; - __inline_call - self_type& operator = ( - self_type && _src - ) = default ; - -/*------------------------------- calc. table load-factor */ - __inline_call double load_fact ( - size_type _iinc = +0 - ) - { return (double)(this->_size +_iinc) / - (double) this->_lptr.count() ; - } - -/*----------------------------- push data onto hash table */ - __normal_call _write_it push ( // copy construct - data_type const&_data - ) - { - /*------------- re-size table if load factor exceeded */ - if (load_fact(1)> this->_load) - redo_hash() ; - /*------------------------------- evaluate hash value */ - size_type _hpos = this->_hash(_data ) - % this->_lptr.count() ; - /*------------------------------- push data onto list */ - return base_type::push( _data,_hpos ) ; - } - -/*----------------------------- push data onto hash table */ - __normal_call _write_it push ( // move construct - data_type && _data - ) - { - /*------------- re-size table if load factor exceeded */ - if (load_fact(1)> this->_load) - redo_hash() ; - /*------------------------------- evaluate hash value */ - size_type _hpos = this->_hash(_data ) - % this->_lptr.count() ; - /*------------------------------- push data onto list */ - return base_type::push( _data,_hpos ) ; - } - -/*-------------------------- scan table for exact matches */ - __normal_call bool_type find ( - data_type const&_data, - item_type *&_same - ) - { - if (this->_lptr.empty()) return false; - - /*------------------------------- evaluate hash value */ - size_type _hpos = this->_hash(_data ) - % this->_lptr.count(); - - /*------------------------------- scan list from head */ - _same = this->_lptr[_hpos]; - /*------------------------------- check exact matches */ - for( ; _same != nullptr; - _same = _same->_next) - { - if (this->_pred(_same->_data,_data)) - { - return true ; - } - } - - /*---------------------------------- no matches found */ - return false ; - } - - __normal_call bool_type find ( - data_type const&_data, - _write_it &_same - ) - { - if (this->_lptr.empty()) return false; - - /*------------------------------- evaluate hash value */ - size_type _hpos = this->_hash(_data ) - % this->_lptr.count(); - - /*------------------------------- scan list from head */ - item_type*_spos = this->_lptr[_hpos] ; - /*------------------------------- check exact matches */ - for( ; _spos != nullptr; - _spos = _spos->_next) - { - if (this->_pred(_spos->_data,_data)) - { - _same = _write_it (_spos, - (base_type*)this) ; - - return true ; - } - } - - /*---------------------------------- no matches found */ - return false ; - } - -/*-------------------------- scan table for exact matches */ - template < - typename list_type - > - __normal_call bool_type find ( - data_type const&_data, - list_type &_list - ) - { - if (this->_lptr.empty()) return false; - - /*------------------------------- evaluate hash value */ - size_type _hpos = this->_hash(_data ) - % this->_lptr.count(); - - /*------------------------------- scan list from head */ - item_type*_same = this->_lptr[_hpos] ; - /*------------------------------- check exact matches */ - for( ; _same != nullptr; - _same = _same->_next) - { - if (this->_pred(_same->_data,_data)) - { - _list.push_tail(_same); - } - } - - /*---------------------------------- no matches found */ - return ( !_list.empty() ); - } - -/*--------------------- _pop any exact matches from table */ - __normal_call bool_type _pop ( - data_type const&_data, - data_type &_same - ) - { - if (this->_lptr.empty()) return false; - - /*------------------------------- evaluate hash value */ - size_type _hpos = this->_hash(_data ) - % this->_lptr.count(); - - /*------------------------------- scan list from head */ - item_type*_prev = nullptr; - item_type*_item = this->_lptr[_hpos] ; - /*------------------------------- check exact matches */ - for( ; _item != nullptr; - _prev = _item, _item = _item->_next) - { - if (this->_pred(_item->_data,_data)) - { - /*-------------------- steal data before _pop */ - _same = std::move(_item->_data); - /*------------------- _pop and _destruct item */ - base_type::_pop( - _write_it(_prev,this), - _write_it(_item,this),_hpos) ; - /*------------------------- exact match found */ - return true ; - } - } - - /*--------------------------------- couldnt find data */ - return false ; - } - -/*------------------- _pop any pointer matches from table */ - __normal_call bool_type _pop ( - item_type *_iptr - ) - { - if (this->_lptr.empty()) return false; - - /*------------------------------- evaluate hash value */ - size_type _hpos = this->_hash(_iptr-> - _data ) - % this->_lptr.count(); - - /*------------------------------- scan list from head */ - item_type*_prev = nullptr; - item_type*_item = this->_lptr[_hpos] ; - /*------------------------------- check exact matches */ - for( ; _item != nullptr; - _prev = _item, _item = _item->_next) - { - if(_iptr == _item) - { - /*------------------- _pop and _destruct item */ - base_type::_pop( - _write_it(_prev,this), - _write_it(_item,this),_hpos) ; - /*------------------------- exact match found */ - return true ; - } - } - - /*--------------------------------- couldnt find data */ - return false ; - } - -/*---------------------- scan table and report statistics */ - __normal_call void_type _get_info ( - size_type &_min_count, - size_type &_max_count, - double &_ave_count - ) - { - _min_count = - std::numeric_limits::max(); - _max_count = - std::numeric_limits::min(); - - _ave_count = (double)+.0; - /*-------------------------- iter. all lists in table */ - typename lptr_list::_write_it - _iter = this->_lptr.head(), - _tend = this->_lptr.tend(); - for( ; _iter != _tend; ++_iter) - { - /*---------------------- count items in each list */ - item_type*_next =*_iter; - size_type _lsiz = +0; - for( ; _next != nullptr; - _next = _next->_next) - { - _lsiz += +1 ; - } - /*----------------------------- update statistics */ - if (_min_count > _lsiz) - _min_count = _lsiz; - if (_max_count < _lsiz) - _max_count = _lsiz; - - _ave_count += (double)_lsiz; - } - - _ave_count /= this->_lptr.count() ; - } - - } ; - -# undef __cont - - - } - -# endif //__HASH_TABLE__ - - - + +/* +------------------------------------------------------------ + * a chained hash-table. +------------------------------------------------------------ + * + * HASH-TABLE is a dynamically-sized, chained hash-table + * implementation, essentially a linear array of singly- + * linked hash buckets. + * +------------------------------------------------------------ + * + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) + * + * Disclaimer: Neither I nor: Columbia University, The + * Massachusetts Institute of Technology, The + * University of Sydney, nor The National Aeronautics + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be + * used at your own risk. + * +------------------------------------------------------------ + * + * Last updated: 05 July, 2019 + * + * Copyright 2013-2019 + * Darren Engwirda + * de2363@columbia.edu + * https://github.com/dengwirda/ + * +------------------------------------------------------------ + */ + +# pragma once + +# ifndef __HASH_TABLE__ +# define __HASH_TABLE__ + +# include "arraylist.hpp" + + namespace containers { + +# define __cont containers + + template < + typename D , + typename H , + typename P , + typename A = allocators::basic_alloc + > + class hash_table : + public containers::array_list + { +/*------------------------- a dynamic, chained hash-table */ + public : + + typedef D data_type ; + typedef H hash_type ; + typedef P pred_type ; + typedef A allocator ; + + typedef containers::array_list < + data_type , + allocator > base_type ; + + typedef typename + base_type::size_type size_type ; + typedef typename + base_type::diff_type diff_type ; + typedef typename + base_type::item_type item_type ; + typedef typename + base_type::lptr_list lptr_list ; + + typedef typename + base_type::_write_it _write_it ; + typedef typename + base_type::_const_it _const_it ; + + typedef containers::hash_table < + data_type , + hash_type , + pred_type , + allocator > self_type ; + + size_type static constexpr _mini_count = +8 ; + + public : + + hash_type const _hash; + pred_type const _pred; + + double _load; + + public : + +/*------------------------ update table count and re-hash */ + __inline_call size_type hash_mask ( + ) const + { return this->_lptr.count() - 1 ; + } + + __static_call + __inline_call bool_type is_pwr2 ( + size_type _xval + ) + { return (_xval & (_xval-1)) == 0 ; + } + + __static_call + __inline_call size_type next_pwr2 ( + size_type _xval + ) + { + if (_xval<= 1) return 1 ; + int _pwr2 = 2; + _xval--; + while (_xval >>= 1) _pwr2 <<= 1 ; + return _pwr2 ; + } + + __static_call + __inline_call size_type prev_pwr2 ( + size_type _xval + ) + { + int _pwr2 = 1; + while (_xval >>= 1) _pwr2 <<= 1 ; + return _pwr2 ; + } + + __normal_call void_type set_slots ( + size_type _slots, + __cont::alloc_types _alloc = + __cont::loose_alloc + ) + { + /*------------------------------- round to next 2^pwr */ + _slots = next_pwr2 (_slots); + + /*------------------------------- inc/dec. table size */ + if (_slots < + this->_mini_count ) + this->_lptr.set_count ( + this->_mini_count , + _alloc , nullptr) ; + else + this->_lptr.set_count ( + _slots, _alloc , nullptr) ; + + /*------------------------------- re-hash all objects */ + redo_hash() ; + } + + __normal_call void_type grow_hash ( + ) + { + /*------------------------------- increase table size */ + if (this->_lptr.count() < + this->_mini_count ) + this->_lptr.set_count ( + this->_mini_count , + containers::tight_alloc, nullptr) ; + else + this->_lptr.set_count ( + this->_lptr.count()*+2, + containers::tight_alloc, nullptr) ; + + /*------------------------------- re-hash all objects */ + redo_hash() ; + } + + __normal_call void_type redo_hash ( + ) + { + if (this->_size == +0) return ; + + __assert ( + is_pwr2(this->_lptr.count() ) && + "hashtable: count must be 2^n!" ) ; + + item_type*_head = nullptr ; + item_type*_tail = nullptr ; + item_type*_next = nullptr ; + /*--------------- splice together a list of all items */ + typename lptr_list::_write_it + _iter = this->_lptr.head(), + _tend = this->_lptr.tend(); + for( ; _iter != _tend; ++_iter) + { + /*--------------------- find first non-empty list */ + if (*_iter != nullptr) + { + _head = *_iter; + _tail = *_iter; + *_iter = nullptr; + _iter++; break; + } + } + for( ; _iter != _tend; ++_iter) + { + /*--------------- splice remaining lists together */ + if (*_iter != nullptr) + { + _tail = *_iter; + for(; nullptr != _tail->_next; ) + { + _tail=_tail->_next ; + } + /*------ re-attach at _tail and jump to _head */ + _tail-> + _next = _head; + _head = *_iter; + *_iter = nullptr ; + } + } + /*------------------ re-hash all items onto new table */ + for ( ; _head != nullptr; _head = _next) + { + _next = _head->_next; + /*--------------------------- calc new hash value */ + size_type _hpos = + this->_hash(_head->_data) + & this-> hash_mask () ; + /*--------------------------- push onto new table */ + base_type::push_item( + this->_lptr[_hpos],_head) ; + } + } + + public : + +/*--------------------------- default c'tor - do nothing! */ + __inline_call hash_table ( + hash_type const&_hsrc = hash_type(), + pred_type const&_psrc = pred_type(), + double const&_lsrc = double(+.8), + allocator const&_asrc = allocator(), + size_type const&_nsrc = size_t(+ 0) + /*----------------------------- c'tor alloc from obj. */ + ) : base_type( _asrc), + /*----------------------------- c'tor other from obj. */ + _hash(_hsrc) , + _pred(_psrc) , + _load(_lsrc) + { + set_slots(_nsrc, + containers::tight_alloc) ; + } + +/*--------------------------- default d'tor/copy/move ops */ + __inline_call~hash_table () = default ; + + __inline_call hash_table ( + self_type const& _src + ) = default ; + __inline_call hash_table ( + self_type && _src + ) = default ; + + __inline_call + self_type& operator = ( + self_type const& _src + ) = default ; + __inline_call + self_type& operator = ( + self_type && _src + ) = default ; + +/*------------------------------- calc. table load-factor */ + __inline_call double load_fact ( + size_type _iinc = +0 + ) + { return (double)(this->_size +_iinc) / + (double) this->_lptr.count() ; + } + +/*----------------------------- push data onto hash table */ + __inline_call _write_it push ( // copy construct + data_type const&_data + ) + { + /*------------- re-size table if load factor exceeded */ + if (load_fact(1)> this->_load) + grow_hash() ; + /*------------------------------- evaluate hash value */ + size_type _hpos = this->_hash(_data ) + & this-> hash_mask () ; + + /*------------------------------- push data onto list */ + return base_type::push( _data,_hpos ) ; + } + +/*----------------------------- push data onto hash table */ + __inline_call _write_it push ( // move construct + data_type && _data + ) + { + /*------------- re-size table if load factor exceeded */ + if (load_fact(1)> this->_load) + grow_hash() ; + /*------------------------------- evaluate hash value */ + size_type _hpos = this->_hash(_data ) + & this-> hash_mask () ; + + /*------------------------------- push data onto list */ + return base_type::push( _data,_hpos ) ; + } + +/*-------------------------- scan table for exact matches */ + __normal_call bool_type find ( + data_type const&_data, + item_type *&_same + ) + { + if (this->_lptr.empty()) return false; + + /*------------------------------- evaluate hash value */ + size_type _hpos = this->_hash(_data ) + & this-> hash_mask (); + + /*------------------------------- scan list from head */ + _same = this->_lptr[_hpos]; + /*------------------------------- check exact matches */ + for( ; _same != nullptr; + _same = _same->_next) + { + if (this->_pred(_same->_data,_data)) + { + return true ; + } + } + + /*---------------------------------- no matches found */ + return false ; + } + + __normal_call bool_type find ( + data_type const&_data, + _write_it &_same + ) + { + if (this->_lptr.empty()) return false; + + /*------------------------------- evaluate hash value */ + size_type _hpos = this->_hash(_data ) + & this-> hash_mask (); + + /*------------------------------- scan list from head */ + item_type*_spos = this->_lptr[_hpos] ; + /*------------------------------- check exact matches */ + for( ; _spos != nullptr; + _spos = _spos->_next) + { + if (this->_pred(_spos->_data,_data)) + { + _same = _write_it (_spos, + (base_type*)this) ; + + return true ; + } + } + + /*---------------------------------- no matches found */ + return false ; + } + +/*-------------------------- scan table for exact matches */ + template < + typename list_type + > + __normal_call bool_type find ( + data_type const&_data, + list_type &_list + ) + { + if (this->_lptr.empty()) return false; + + /*------------------------------- evaluate hash value */ + size_type _hpos = this->_hash(_data ) + & this-> hash_mask (); + + /*------------------------------- scan list from head */ + item_type*_same = this->_lptr[_hpos] ; + /*------------------------------- check exact matches */ + for( ; _same != nullptr; + _same = _same->_next) + { + if (this->_pred(_same->_data,_data)) + { + _list.push_tail(_same); + } + } + + /*---------------------------------- no matches found */ + return ( !_list.empty() ); + } + +/*--------------------- _pop any exact matches from table */ + __normal_call bool_type _pop ( + data_type const&_data, + data_type &_same + ) + { + if (this->_lptr.empty()) return false; + + /*------------------------------- evaluate hash value */ + size_type _hpos = this->_hash(_data ) + & this-> hash_mask (); + + /*------------------------------- scan list from head */ + item_type*_prev = nullptr; + item_type*_item = this->_lptr[_hpos] ; + /*------------------------------- check exact matches */ + for( ; _item != nullptr; + _prev = _item, _item = _item->_next) + { + if (this->_pred(_item->_data,_data)) + { + /*-------------------- steal data before _pop */ + _same = std::move(_item->_data); + /*------------------- _pop and _destruct item */ + base_type::_pop( + _write_it(_prev,this), + _write_it(_item,this),_hpos) ; + /*------------------------- exact match found */ + return true ; + } + } + + /*--------------------------------- couldnt find data */ + return false ; + } + +/*--------------------- _pop any exact matches from table */ + __normal_call bool_type _pop ( + data_type const&_data + ) + { + if (this->_lptr.empty()) return false; + + /*------------------------------- evaluate hash value */ + size_type _hpos = this->_hash(_data ) + & this-> hash_mask () ; + + /*------------------------------- scan list from head */ + item_type*_prev = nullptr; + item_type*_item = this->_lptr[_hpos] ; + /*------------------------------- check exact matches */ + for( ; _item != nullptr; + _prev = _item, _item = _item->_next) + { + if (this->_pred(_item->_data,_data)) + { + /*------------------- _pop and _destruct item */ + base_type::_pop( + _write_it(_prev,this), + _write_it(_item,this),_hpos) ; + /*------------------------- exact match found */ + return true ; + } + } + + /*--------------------------------- couldnt find data */ + return false ; + } + +/*------------------- _pop any pointer matches from table */ + __normal_call bool_type _pop ( + item_type *_iptr + ) + { + if (this->_lptr.empty()) return false; + + /*------------------------------- evaluate hash value */ + size_type _hpos = this->_hash(_iptr-> + _data ) + & this-> hash_mask (); + + /*------------------------------- scan list from head */ + item_type*_prev = nullptr; + item_type*_item = this->_lptr[_hpos] ; + /*------------------------------- check exact matches */ + for( ; _item != nullptr; + _prev = _item, _item = _item->_next) + { + if(_iptr == _item) + { + /*------------------- _pop and _destruct item */ + base_type::_pop( + _write_it(_prev,this), + _write_it(_item,this),_hpos) ; + /*------------------------- exact match found */ + return true ; + } + } + + /*--------------------------------- couldnt find data */ + return false ; + } + +/*---------------------- scan table and report statistics */ + __normal_call void_type _get_info ( + size_type &_min_count, + size_type &_max_count, + double &_ave_count + ) + { + _min_count = + std::numeric_limits::max(); + _max_count = + std::numeric_limits::min(); + + _ave_count = (double)+.0; + /*-------------------------- iter. all lists in table */ + typename lptr_list::_write_it + _iter = this->_lptr.head(), + _tend = this->_lptr.tend(); + for( ; _iter != _tend; ++_iter) + { + /*---------------------- count items in each list */ + item_type*_next =*_iter; + size_type _lsiz = +0; + for( ; _next != nullptr; + _next = _next->_next) + { + _lsiz += +1 ; + } + /*----------------------------- update statistics */ + if (_min_count > _lsiz) + _min_count = _lsiz; + if (_max_count < _lsiz) + _max_count = _lsiz; + + _ave_count += (double)_lsiz; + } + + _ave_count /= this->_lptr.count() ; + } + + } ; + +# undef __cont + + + } + +# endif //__HASH_TABLE__ + + + diff --git a/src/libcpp/containers/iter_base.hpp b/src/libcpp/containers/iter_base.hpp index d70c994..188677d 100644 --- a/src/libcpp/containers/iter_base.hpp +++ b/src/libcpp/containers/iter_base.hpp @@ -1,181 +1,181 @@ - - /* - -------------------------------------------------------- - * a bit of template meta-magic on iterator types. - -------------------------------------------------------- - * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) - * - * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The - * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be - * used at your own risk. - * - -------------------------------------------------------- - * - * Last updated: 03 May, 2017 - * - * Copyright 2013-2017 - * Darren Engwirda - * de2363@columbia.edu - * https://github.com/dengwirda/ - * - -------------------------------------------------------- - */ - -# pragma once - -# ifndef __ITER_BASE__ -# define __ITER_BASE__ - -# include - -# include - - namespace containers { - - /* - -------------------------------------------------------- - * iterator concepts via typedefs and inheritence. - -------------------------------------------------------- - */ - - class null_iterator_kind - { /*------ non-iterator types */ - } ; - class base_iterator_kind - { /*------ all iterator types */ - } ; - class single_iterator_kind - : public base_iterator_kind - { /* unidirectional iterators */ - } ; - class double_iterator_kind - : public single_iterator_kind - { /* bi-directional iterators */ - } ; - class random_iterator_kind - : public double_iterator_kind - { /* random--access iterators */ - } ; - class pointer_iterator_kind - : public random_iterator_kind - { /* iterators as raw pointer */ - } ; - - class iterator_base - { /*--------- "non-iterator" base type */ - public : - typedef null_iterator_kind iter_kind ; - } ; - class single_iterator_base - : public iterator_base - { /* unidirectional iterator base type */ - public : - typedef single_iterator_kind iter_kind ; - } ; - class double_iterator_base - : public iterator_base - { /* bi-directional iterator base type */ - public : - typedef double_iterator_kind iter_kind ; - } ; - class random_iterator_base - : public iterator_base - { /* random--access iterator base type */ - public : - typedef random_iterator_kind iter_kind ; - } ; - - /* - -------------------------------------------------------- - * traits class to distinguish iterator types. - -------------------------------------------------------- - */ - - template < - typename iter_type , - bool flag_kind - > - class iterator_traits_base - { - /*-------------- real iterator types store their kind */ - public : - typedef typename - iter_type::iter_kind iter_kind ; - typedef typename - iter_type::data_type data_type ; - typedef typename - iter_type::diff_type diff_type ; - typedef typename - iter_type::size_type size_type ; - } ; - - template < - typename iter_type - > - class iterator_traits_base - { - /*-------------- noniterator types assigned null kind */ - public : - typedef null_iterator_kind iter_kind ; - typedef typename - std::remove_pointer< - iter_type>::type data_type ; - typedef std::size_t size_type ; - typedef std::ptrdiff_t diff_type ; - } ; - - template < - typename iter_type - > - class iterator_traits: public - iterator_traits_base ::value > - { - /*--------------------------------- just wraps base!! */ - } ; - - /* - -------------------------------------------------------- - * ITER-KIND: traits fun. to return dummy kind. - -------------------------------------------------------- - */ - - template < - typename iter_type - > - __inline_call typename - iterator_traits::iter_kind - iter_kind (iter_type) - { return ( typename - iterator_traits::iter_kind() - ) ; - } - - - } //} containers - -# endif//__ITER_BASE__ - - - + + /* + -------------------------------------------------------- + * a bit of template meta-magic on iterator types. + -------------------------------------------------------- + * + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) + * + * Disclaimer: Neither I nor: Columbia University, The + * Massachusetts Institute of Technology, The + * University of Sydney, nor The National Aeronautics + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be + * used at your own risk. + * + -------------------------------------------------------- + * + * Last updated: 03 May, 2017 + * + * Copyright 2013-2017 + * Darren Engwirda + * de2363@columbia.edu + * https://github.com/dengwirda/ + * + -------------------------------------------------------- + */ + +# pragma once + +# ifndef __ITER_BASE__ +# define __ITER_BASE__ + +# include + +# include + + namespace containers { + + /* + -------------------------------------------------------- + * iterator concepts via typedefs and inheritence. + -------------------------------------------------------- + */ + + class null_iterator_kind + { /*------ non-iterator types */ + } ; + class base_iterator_kind + { /*------ all iterator types */ + } ; + class single_iterator_kind + : public base_iterator_kind + { /* unidirectional iterators */ + } ; + class double_iterator_kind + : public single_iterator_kind + { /* bi-directional iterators */ + } ; + class random_iterator_kind + : public double_iterator_kind + { /* random--access iterators */ + } ; + class pointer_iterator_kind + : public random_iterator_kind + { /* iterators as raw pointer */ + } ; + + class iterator_base + { /*--------- "non-iterator" base type */ + public : + typedef null_iterator_kind iter_kind ; + } ; + class single_iterator_base + : public iterator_base + { /* unidirectional iterator base type */ + public : + typedef single_iterator_kind iter_kind ; + } ; + class double_iterator_base + : public iterator_base + { /* bi-directional iterator base type */ + public : + typedef double_iterator_kind iter_kind ; + } ; + class random_iterator_base + : public iterator_base + { /* random--access iterator base type */ + public : + typedef random_iterator_kind iter_kind ; + } ; + + /* + -------------------------------------------------------- + * traits class to distinguish iterator types. + -------------------------------------------------------- + */ + + template < + typename iter_type , + bool flag_kind + > + class iterator_traits_base + { + /*-------------- real iterator types store their kind */ + public : + typedef typename + iter_type::iter_kind iter_kind ; + typedef typename + iter_type::data_type data_type ; + typedef typename + iter_type::diff_type diff_type ; + typedef typename + iter_type::size_type size_type ; + } ; + + template < + typename iter_type + > + class iterator_traits_base + { + /*-------------- noniterator types assigned null kind */ + public : + typedef null_iterator_kind iter_kind ; + typedef typename + std::remove_pointer< + iter_type>::type data_type ; + typedef std::size_t size_type ; + typedef std::ptrdiff_t diff_type ; + } ; + + template < + typename iter_type + > + class iterator_traits: public + iterator_traits_base ::value > + { + /*--------------------------------- just wraps base!! */ + } ; + + /* + -------------------------------------------------------- + * ITER-KIND: traits fun. to return dummy kind. + -------------------------------------------------------- + */ + + template < + typename iter_type + > + __inline_call typename + iterator_traits::iter_kind + iter_kind (iter_type) + { return ( typename + iterator_traits::iter_kind() + ) ; + } + + + } //} containers + +# endif//__ITER_BASE__ + + + diff --git a/src/libcpp/containers/prioritymap.hpp b/src/libcpp/containers/prioritymap.hpp index bfe9167..48245fb 100644 --- a/src/libcpp/containers/prioritymap.hpp +++ b/src/libcpp/containers/prioritymap.hpp @@ -1,676 +1,676 @@ - -/* ------------------------------------------------------------- - * an "n-ary"-heap based priority queue. ------------------------------------------------------------- - * - * PRIORITY-MAP utilises an "n-ary" heap data-structure, - * designed to maintain sorted precedence in mutable - * collections. This "n-ary" heap simply generalises - * a standard binary heap (i.e. a 2-heap) to trees with - * "n" children per level. - * ------------------------------------------------------------- - * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) - * - * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The - * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be - * used at your own risk. - * ------------------------------------------------------------- - * - * Last updated: 17 August, 2018 - * - * Copyright 2013-2017 - * Darren Engwirda - * de2363@columbia.edu - * https://github.com/dengwirda/ - * ------------------------------------------------------------- - */ - -# pragma once - -# ifndef __PRIORITY_MAP__ -# define __PRIORITY_MAP__ - -# include "array.hpp" - - namespace containers { - -# define __cont containers - - template < - typename T , - typename K - > - class heap_pair - { -/*----------- local data-pair for an indexed "n"-ary heap */ - public : - typedef T data_type ; - typedef K kptr_type ; - - public : - data_type _data ; // heap data - kptr_type _kptr ; // keys iptr - } ; - -# define D heap_pair - - template < - typename T , - typename P = std::less , - typename A = allocators::basic_alloc , - typename C = containers::array - > - class prioritymap - { -/*----------- a dynamic priority queue as an "n"-ary heap */ - public : - - #undef D - - typedef T data_type ; - typedef C container ; - typedef P pred_type ; - typedef A allocator ; - - typedef containers::prioritymap < - data_type , - pred_type , - allocator , - container > self_type ; - - typedef typename - container::data_type pair_type ; - typedef typename - container::size_type size_type ; - - typedef typename - container::_write_it _write_it ; - typedef typename - container::_const_it _const_it ; - - typedef typename - pair_type::kptr_type kptr_type ; - - typedef containers::array < - kptr_type , - allocator > kptr_list ; - - typedef containers::array < - size_type , - allocator > free_list ; - - size_type static const _nfan = +4 ; // fan out - - public : - - container _heap ; - - kptr_list _keys ; - free_list _free ; - - pred_type _pred ; - - private : - -/*------------- helper - push "hole" into sorted position */ - __normal_call _write_it push_upper ( - _write_it _head, - _write_it _ipos, - data_type const&_data - ) - { - for (; _ipos != _head ; ) - { - /*----------------------- find position of parent */ - _write_it _ppos = - _head + (_ipos-_head-1) / _nfan; - /*----------------------- swap parent with "hole" */ - if (this->_pred(_data,_ppos->_data)) - { - /*------------------ update heap-keys mapping */ - _ipos->_data = - std::move(_ppos->_data); - _ipos->_kptr = - std::move(_ppos->_kptr); - /*------------------ update keys-heap mapping */ - this->_keys[_ipos->_kptr] = - _ipos- _head; - /*------------------ traverse to upper levels */ - _ipos =_ppos ; - } - else break ; - } - - return (_ipos) ; - } - -/*------------- helper - push "hole" into sorted position */ - __normal_call _write_it push_lower ( - _write_it _head, - _write_it _tail, - _write_it _ipos, - data_type const&_data - ) - { - if (_head == _tail) return _ipos ; - /*-- find position of root of last partial sub - tree */ - _write_it _cpos ; - _write_it _imin ; - _write_it _iend = _head; - if (_tail - _head > 0) - { - _iend = - _head + (_tail-_head-1) / _nfan ; - } - /*-- push "hole" into sorted position on lower levels */ - for ( ; _ipos < _iend; ) - { - /*---------------------------- pos of right child */ - _cpos = _head + - _nfan * (_ipos - _head) + _nfan ; - /*---------------------------- find minimum child */ - _imin = _cpos; - switch (_nfan) - { - case 8 : - if (this->_pred((--_cpos)->_data , - _imin ->_data)) - _imin=_cpos; // falls through - case 7 : - if (this->_pred((--_cpos)->_data , - _imin ->_data)) - _imin=_cpos; // falls through - case 6 : - if (this->_pred((--_cpos)->_data , - _imin ->_data)) - _imin=_cpos; // falls through - case 5 : - if (this->_pred((--_cpos)->_data , - _imin ->_data)) - _imin=_cpos; // falls through - case 4 : - if (this->_pred((--_cpos)->_data , - _imin ->_data)) - _imin=_cpos; // falls through - case 3 : - if (this->_pred((--_cpos)->_data , - _imin ->_data)) - _imin=_cpos; // falls through - case 2 : - if (this->_pred((--_cpos)->_data , - _imin ->_data)) - _imin=_cpos; // falls through - } - /*---------------------- update heap-keys mapping */ - _ipos->_data = - std::move(_imin->_data); - _ipos->_kptr = - std::move(_imin->_kptr); - /*---------------------- update keys-heap mapping */ - this->_keys[_ipos->_kptr] = - _ipos- _head; - /*---------------------- move onto next child pos */ - _ipos =_imin ; - } - - /*-- deal with special case - last partial sub - tree */ - if (_ipos == _iend) - { - size_type _inum = - _tail-_head-_nfan*(_ipos-_head); - if (_inum > +0) - { - /*---------------------------- pos of right child */ - _cpos = _head + - _nfan * (_ipos -_head) + _inum ; - /*---------------------------- find minimum child */ - _imin = _cpos; - switch (_inum) - { - case 8 : - if (this->_pred((--_cpos)->_data , - _imin ->_data)) - _imin=_cpos; // falls through - case 7 : - if (this->_pred((--_cpos)->_data , - _imin ->_data)) - _imin=_cpos; // falls through - case 6 : - if (this->_pred((--_cpos)->_data , - _imin ->_data)) - _imin=_cpos; // falls through - case 5 : - if (this->_pred((--_cpos)->_data , - _imin ->_data)) - _imin=_cpos; // falls through - case 4 : - if (this->_pred((--_cpos)->_data , - _imin ->_data)) - _imin=_cpos; // falls through - case 3 : - if (this->_pred((--_cpos)->_data , - _imin ->_data)) - _imin=_cpos; // falls through - case 2 : - if (this->_pred((--_cpos)->_data , - _imin ->_data)) - _imin=_cpos; // falls through - } - /*---------------------- update heap-keys mapping */ - _ipos->_data = - std::move(_imin->_data); - _ipos->_kptr = - std::move(_imin->_kptr); - /*---------------------- update keys-heap mapping */ - this->_keys[_ipos->_kptr] = - _ipos- _head; - /*---------------------- move onto next child pos */ - _ipos =_imin ; - } - } - - /*--- push "hole" into final position sorted position */ - return push_upper(_head, _ipos, _data) ; - } - - public : - -/*--------------------------- default c'tor - do nothing! */ - __inline_call prioritymap ( - allocator const&_asrc = allocator(), - pred_type const&_psrc = pred_type() - ) : _heap(_asrc), - _keys(_asrc), - _free(_asrc), - _pred(_psrc) {} - -/*--------------------------- default c'tor - initialisor */ - __inline_call prioritymap ( - pred_type const&_psrc - ) : _heap(allocator()), - _keys(allocator()), - _free(allocator()), - _pred(_psrc) {} - - __inline_call~prioritymap() = default ; - - __inline_call prioritymap ( - self_type const&_src - ) = default ; - __inline_call prioritymap ( - self_type && _src - ) = default ; - - __inline_call - self_type & operator= ( - self_type const&_src - ) = default ; - __inline_call - self_type & operator= ( - self_type && _src - ) = default ; - -/*------------------------------------- peek at heap root */ - - __inline_call data_type const& root ( - ) const - { return this->_heap[ +0 ]._data ; - } - -/*------------------------------------- peek at heap item */ - __inline_call data_type const& peek ( - size_type _hpos = +0 - ) const - { return this->_heap[_hpos]._data ; - } - -/*-------------------------------------------- empty test */ - __inline_call bool_type empty ( - ) const - { return ( this->_heap. empty() ) ; - } - -/*-------------------------------------------- heap count */ - __inline_call size_type count ( - ) const - { return ( this->_heap. count() ) ; - } - -/*-------------------------------------------- heap alloc */ - __inline_call size_type alloc ( - ) const - { return ( this->_heap. alloc() ) ; - } - -/*-------------------------------------------- _set alloc */ - __inline_call size_type set_alloc ( - size_type _asiz - ) - { this->_heap.set_alloc( _asiz) ; - } - -/*------------------------------------- (const) iterators */ - __inline_call _const_it head ( - ) const - { return this->_heap. head() ; - } - __inline_call _const_it tail ( - ) const - { return this->_heap. tail() ; - } - __inline_call _const_it hend ( - ) const - { return this->_heap. hend() ; - } - __inline_call _const_it tend ( - ) const - { return this->_heap. tend() ; - } - - /* - -------------------------------------------------------- - * PUSH: push data onto heap - -------------------------------------------------------- - */ - - __inline_call kptr_type push ( // copy - data_type const&_data - ) - {/*---------------- make room for new item in mapping */ - kptr_type _kptr; - if (this->_free.empty()) - _kptr = this->_keys.push_tail(); - else - this->_free ._pop_tail(_kptr ); - - /*----------------- push _data onto tail of container */ - size_type _tpos = - this->_heap.push_tail() ; - /*----------------- sort corresponding "hole" to pos. */ - _write_it _ipos = push_upper ( - this->_heap.head() , - this->_heap.head() + _tpos , - __copy(data_type, _data)) ; - - /*------------------------- copy new data into "hole" */ - _ipos->_kptr = _kptr ; - _ipos->_data = - __copy(data_type, _data) ; - - /*------------------------- map _item to _data "hole" */ - this->_keys[_kptr] = - _ipos - this->_heap.head() ; - - return ( _kptr ) ; - } - - __inline_call kptr_type push ( // move - data_type && _data - ) - {/*---------------- make room for new item in mapping */ - kptr_type _kptr; - if (this->_free.empty()) - _kptr = this->_keys.push_tail(); - else - this->_free ._pop_tail(_kptr ); - - /*----------------- push _data onto tail of container */ - size_type _tpos = - this->_heap.push_tail() ; - /*----------------- sort corresponding "hole" to pos. */ - _write_it _ipos = push_upper ( - this->_heap.head() , - this->_heap.head() + _tpos , - __copy(data_type, _data)) ; - - /*------------------------- move new data into "hole" */ - _ipos->_kptr = _kptr ; - _ipos->_data = - __move(data_type, _data) ; - - /*------------------------- map _item to _data "hole" */ - this->_keys[_kptr] = - _ipos - this->_heap.head() ; - - return ( _kptr ) ; - } - - /* - -------------------------------------------------------- - * _POP: _pop data from heap - -------------------------------------------------------- - */ - - __inline_call void_type _pop_root ( - ) - { - /*---------------------------- _pop root, cache temp. */ - data_type _temp ; - _pop( +0, _temp); - } - __inline_call void_type _pop_root ( - data_type &_data - ) - { - /*---------------------------- _pop item, return data */ - size_type _hpos = +0 ; - kptr_type _kptr ; - _kptr = this->_heap[_hpos]._kptr ; - _data = - std::move (this->_heap[_hpos]._data); - /*----------------------- push "hole" to lower levels */ - if (this->_heap.head() + _hpos != - this->_heap.tail() ) - { - /*----------- sort "hole" at root to updated position */ - _write_it _ipos = push_lower ( - this->_heap.head() , - this->_heap.tail() - 1 , - this->_heap.head() + _hpos, - this->_heap.tail()-> _data) ; - - /*----------- copy current tail into updated position */ - _ipos->_data = std::move( - this->_heap.tail()-> _data) ; - _ipos->_kptr = std::move( - this->_heap.tail()-> _kptr) ; - - /*---------------------- update mapping for tail item */ - this->_keys[_ipos->_kptr] = - _ipos - this->_heap.head() ; - } - this->_heap._pop_tail(); - - this->_keys[_kptr] = - std::numeric_limits::max() ; - - this-> - _free.push_tail(_kptr) ; - } - - __inline_call void_type _pop ( - kptr_type _kptr - ) - { - /*---------------------------- _pop data, cache temp. */ - data_type _temp ; - _pop(_kptr,_temp); - } - __normal_call void_type _pop ( - kptr_type _kptr , - data_type &_data - ) - { - /*---------------------------- _pop item, return data */ - size_type _hpos = this->_keys[_kptr]; - _data = - std::move (this->_heap[_hpos]._data); - /*----------------------- push "hole" to lower levels */ - if (this->_heap.head() + _hpos != - this->_heap.tail() ) - { - /*----------- sort "hole" at root to updated position */ - _write_it _ipos = push_lower ( - this->_heap.head() , - this->_heap.tail() - 1 , - this->_heap.head() + _hpos, - this->_heap.tail()-> _data) ; - - /*----------- copy current tail into updated position */ - _ipos->_data = std::move( - this->_heap.tail()-> _data) ; - _ipos->_kptr = std::move( - this->_heap.tail()-> _kptr) ; - - /*---------------------- update mapping for tail item */ - this->_keys[_ipos->_kptr] = - _ipos - this->_heap.head() ; - } - this->_heap._pop_tail(); - - this->_keys[_kptr] = - std::numeric_limits::max() ; - - this-> - _free.push_tail(_kptr) ; - } - - /* - -------------------------------------------------------- - * UPDATE: update data in heap - -------------------------------------------------------- - */ - - __normal_call void_type update ( // copy - kptr_type _kptr, - data_type const&_data - ) - {/*------------------ move "hole" to updated position */ - size_type _hpos = - this->_keys[_kptr]; - _write_it _ipos ; - if (this->_pred(_data , - this->_heap[_hpos]. _data)) - /*-------------------- push "hole" to upper level */ - _ipos = push_upper ( - this-> _heap.head(), - this-> _heap.head()+_hpos , - __copy(data_type,_data)) ; - else - /*-------------------- push "hole" to lower level */ - _ipos = push_lower ( - this-> _heap.head(), - this-> _heap.tail(), - this-> _heap.head()+_hpos , - __copy(data_type,_data)) ; - - /*------------------------ copy this data into "hole" */ - _ipos->_kptr = _kptr ; - _ipos->_data = - __copy(data_type,_data) ; - - /*------------------------ copy position into mapping */ - this->_keys[_kptr] = - _ipos - this->_heap.head() ; - } - - __normal_call void_type update ( // move - kptr_type _kptr, - data_type &&_data - ) - {/*------------------ move "hole" to updated position */ - size_type _hpos = - this->_keys[_kptr]; - _write_it _ipos ; - if (this->_pred(_data , - this->_heap[_hpos]. _data)) - /*-------------------- push "hole" to upper level */ - _ipos = push_upper ( - this-> _heap.head(), - this-> _heap.head()+_hpos , - __copy(data_type,_data)) ; - else - /*-------------------- push "hole" to lower level */ - _ipos = push_lower ( - this-> _heap.head(), - this-> _heap.tail(), - this-> _heap.head()+_hpos , - __copy(data_type,_data)) ; - - /*------------------------ copy this data into "hole" */ - _ipos->_kptr = _kptr ; - _ipos->_data = - __move(data_type,_data) ; - - /*------------------------ copy position into mapping */ - this->_keys[_kptr] = - _ipos - this->_heap.head() ; - } - - /* - -------------------------------------------------------- - * test heap validity (debug only!) - -------------------------------------------------------- - */ - - __normal_call bool_type test_heap ( - ) - { -# ifdef _DEBUG - /*------------------ test relationships for all nodes */ - size_type _ipos = +1 ; - size_type _iend = - this->_heap.count () ; - for ( ; _ipos < _iend; ++_ipos) - { - /*------------------ heap is invalid if lower < upper */ - size_type _ppos = - (_ipos - 1)/_nfan ; - - if (this->_pred( - this->_heap[_ipos], - this->_heap[_ppos] - ) ) - return false ; - } -# endif - - /*------------------ must be valid if we got this far */ - return true ; - } - - } ; - -# undef __cont - - - } - -# endif //__PRIORITY_MAP__ - - - + +/* +------------------------------------------------------------ + * an "n-ary"-heap based priority queue. +------------------------------------------------------------ + * + * PRIORITY-MAP utilises an "n-ary" heap data-structure, + * designed to maintain sorted precedence in mutable + * collections. This "n-ary" heap simply generalises + * a standard binary heap (i.e. a 2-heap) to trees with + * "n" children per level. + * +------------------------------------------------------------ + * + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) + * + * Disclaimer: Neither I nor: Columbia University, The + * Massachusetts Institute of Technology, The + * University of Sydney, nor The National Aeronautics + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be + * used at your own risk. + * +------------------------------------------------------------ + * + * Last updated: 17 August, 2018 + * + * Copyright 2013-2017 + * Darren Engwirda + * de2363@columbia.edu + * https://github.com/dengwirda/ + * +------------------------------------------------------------ + */ + +# pragma once + +# ifndef __PRIORITY_MAP__ +# define __PRIORITY_MAP__ + +# include "array.hpp" + + namespace containers { + +# define __cont containers + + template < + typename T , + typename K + > + class heap_pair + { +/*----------- local data-pair for an indexed "n"-ary heap */ + public : + typedef T data_type ; + typedef K kptr_type ; + + public : + data_type _data ; // heap data + kptr_type _kptr ; // keys iptr + } ; + +# define D heap_pair + + template < + typename T , + typename P = std::less , + typename A = allocators::basic_alloc , + typename C = containers::array + > + class prioritymap + { +/*----------- a dynamic priority queue as an "n"-ary heap */ + public : + + #undef D + + typedef T data_type ; + typedef C container ; + typedef P pred_type ; + typedef A allocator ; + + typedef containers::prioritymap < + data_type , + pred_type , + allocator , + container > self_type ; + + typedef typename + container::data_type pair_type ; + typedef typename + container::size_type size_type ; + + typedef typename + container::_write_it _write_it ; + typedef typename + container::_const_it _const_it ; + + typedef typename + pair_type::kptr_type kptr_type ; + + typedef containers::array < + kptr_type , + allocator > kptr_list ; + + typedef containers::array < + size_type , + allocator > free_list ; + + size_type static const _nfan = +4 ; // fan out + + public : + + container _heap ; + + kptr_list _keys ; + free_list _free ; + + pred_type _pred ; + + private : + +/*------------- helper - push "hole" into sorted position */ + __normal_call _write_it push_upper ( + _write_it _head, + _write_it _ipos, + data_type const&_data + ) + { + for (; _ipos != _head ; ) + { + /*----------------------- find position of parent */ + _write_it _ppos = + _head + (_ipos-_head-1) / _nfan; + /*----------------------- swap parent with "hole" */ + if (this->_pred(_data,_ppos->_data)) + { + /*------------------ update heap-keys mapping */ + _ipos->_data = + std::move(_ppos->_data); + _ipos->_kptr = + std::move(_ppos->_kptr); + /*------------------ update keys-heap mapping */ + this->_keys[_ipos->_kptr] = + _ipos- _head; + /*------------------ traverse to upper levels */ + _ipos =_ppos ; + } + else break ; + } + + return (_ipos) ; + } + +/*------------- helper - push "hole" into sorted position */ + __normal_call _write_it push_lower ( + _write_it _head, + _write_it _tail, + _write_it _ipos, + data_type const&_data + ) + { + if (_head == _tail) return _ipos ; + /*-- find position of root of last partial sub - tree */ + _write_it _cpos ; + _write_it _imin ; + _write_it _iend = _head; + if (_tail - _head > 0) + { + _iend = + _head + (_tail-_head-1) / _nfan ; + } + /*-- push "hole" into sorted position on lower levels */ + for ( ; _ipos < _iend; ) + { + /*---------------------------- pos of right child */ + _cpos = _head + + _nfan * (_ipos - _head) + _nfan ; + /*---------------------------- find minimum child */ + _imin = _cpos; + switch (_nfan) + { + case 8 : + if (this->_pred((--_cpos)->_data , + _imin ->_data)) + _imin=_cpos; // falls through + case 7 : + if (this->_pred((--_cpos)->_data , + _imin ->_data)) + _imin=_cpos; // falls through + case 6 : + if (this->_pred((--_cpos)->_data , + _imin ->_data)) + _imin=_cpos; // falls through + case 5 : + if (this->_pred((--_cpos)->_data , + _imin ->_data)) + _imin=_cpos; // falls through + case 4 : + if (this->_pred((--_cpos)->_data , + _imin ->_data)) + _imin=_cpos; // falls through + case 3 : + if (this->_pred((--_cpos)->_data , + _imin ->_data)) + _imin=_cpos; // falls through + case 2 : + if (this->_pred((--_cpos)->_data , + _imin ->_data)) + _imin=_cpos; // falls through + } + /*---------------------- update heap-keys mapping */ + _ipos->_data = + std::move(_imin->_data); + _ipos->_kptr = + std::move(_imin->_kptr); + /*---------------------- update keys-heap mapping */ + this->_keys[_ipos->_kptr] = + _ipos- _head; + /*---------------------- move onto next child pos */ + _ipos =_imin ; + } + + /*-- deal with special case - last partial sub - tree */ + if (_ipos == _iend) + { + size_type _inum = + _tail-_head-_nfan*(_ipos-_head); + if (_inum > +0) + { + /*---------------------------- pos of right child */ + _cpos = _head + + _nfan * (_ipos -_head) + _inum ; + /*---------------------------- find minimum child */ + _imin = _cpos; + switch (_inum) + { + case 8 : + if (this->_pred((--_cpos)->_data , + _imin ->_data)) + _imin=_cpos; // falls through + case 7 : + if (this->_pred((--_cpos)->_data , + _imin ->_data)) + _imin=_cpos; // falls through + case 6 : + if (this->_pred((--_cpos)->_data , + _imin ->_data)) + _imin=_cpos; // falls through + case 5 : + if (this->_pred((--_cpos)->_data , + _imin ->_data)) + _imin=_cpos; // falls through + case 4 : + if (this->_pred((--_cpos)->_data , + _imin ->_data)) + _imin=_cpos; // falls through + case 3 : + if (this->_pred((--_cpos)->_data , + _imin ->_data)) + _imin=_cpos; // falls through + case 2 : + if (this->_pred((--_cpos)->_data , + _imin ->_data)) + _imin=_cpos; // falls through + } + /*---------------------- update heap-keys mapping */ + _ipos->_data = + std::move(_imin->_data); + _ipos->_kptr = + std::move(_imin->_kptr); + /*---------------------- update keys-heap mapping */ + this->_keys[_ipos->_kptr] = + _ipos- _head; + /*---------------------- move onto next child pos */ + _ipos =_imin ; + } + } + + /*--- push "hole" into final position sorted position */ + return push_upper(_head, _ipos, _data) ; + } + + public : + +/*--------------------------- default c'tor - do nothing! */ + __inline_call prioritymap ( + allocator const&_asrc = allocator(), + pred_type const&_psrc = pred_type() + ) : _heap(_asrc), + _keys(_asrc), + _free(_asrc), + _pred(_psrc) {} + +/*--------------------------- default c'tor - initialisor */ + __inline_call prioritymap ( + pred_type const&_psrc + ) : _heap(allocator()), + _keys(allocator()), + _free(allocator()), + _pred(_psrc) {} + + __inline_call~prioritymap() = default ; + + __inline_call prioritymap ( + self_type const&_src + ) = default ; + __inline_call prioritymap ( + self_type && _src + ) = default ; + + __inline_call + self_type & operator= ( + self_type const&_src + ) = default ; + __inline_call + self_type & operator= ( + self_type && _src + ) = default ; + +/*------------------------------------- peek at heap root */ + + __inline_call data_type const& root ( + ) const + { return this->_heap[ +0 ]._data ; + } + +/*------------------------------------- peek at heap item */ + __inline_call data_type const& peek ( + size_type _hpos = +0 + ) const + { return this->_heap[_hpos]._data ; + } + +/*-------------------------------------------- empty test */ + __inline_call bool_type empty ( + ) const + { return ( this->_heap. empty() ) ; + } + +/*-------------------------------------------- heap count */ + __inline_call size_type count ( + ) const + { return ( this->_heap. count() ) ; + } + +/*-------------------------------------------- heap alloc */ + __inline_call size_type alloc ( + ) const + { return ( this->_heap. alloc() ) ; + } + +/*-------------------------------------------- _set alloc */ + __inline_call size_type set_alloc ( + size_type _asiz + ) + { this->_heap.set_alloc( _asiz) ; + } + +/*------------------------------------- (const) iterators */ + __inline_call _const_it head ( + ) const + { return this->_heap. head() ; + } + __inline_call _const_it tail ( + ) const + { return this->_heap. tail() ; + } + __inline_call _const_it hend ( + ) const + { return this->_heap. hend() ; + } + __inline_call _const_it tend ( + ) const + { return this->_heap. tend() ; + } + + /* + -------------------------------------------------------- + * PUSH: push data onto heap + -------------------------------------------------------- + */ + + __inline_call kptr_type push ( // copy + data_type const&_data + ) + {/*---------------- make room for new item in mapping */ + kptr_type _kptr; + if (this->_free.empty()) + _kptr = this->_keys.push_tail(); + else + this->_free ._pop_tail(_kptr ); + + /*----------------- push _data onto tail of container */ + size_type _tpos = + this->_heap.push_tail() ; + /*----------------- sort corresponding "hole" to pos. */ + _write_it _ipos = push_upper ( + this->_heap.head() , + this->_heap.head() + _tpos , + __copy(data_type, _data)) ; + + /*------------------------- copy new data into "hole" */ + _ipos->_kptr = _kptr ; + _ipos->_data = + __copy(data_type, _data) ; + + /*------------------------- map _item to _data "hole" */ + this->_keys[_kptr] = + _ipos - this->_heap.head() ; + + return ( _kptr ) ; + } + + __inline_call kptr_type push ( // move + data_type && _data + ) + {/*---------------- make room for new item in mapping */ + kptr_type _kptr; + if (this->_free.empty()) + _kptr = this->_keys.push_tail(); + else + this->_free ._pop_tail(_kptr ); + + /*----------------- push _data onto tail of container */ + size_type _tpos = + this->_heap.push_tail() ; + /*----------------- sort corresponding "hole" to pos. */ + _write_it _ipos = push_upper ( + this->_heap.head() , + this->_heap.head() + _tpos , + __copy(data_type, _data)) ; + + /*------------------------- move new data into "hole" */ + _ipos->_kptr = _kptr ; + _ipos->_data = + __move(data_type, _data) ; + + /*------------------------- map _item to _data "hole" */ + this->_keys[_kptr] = + _ipos - this->_heap.head() ; + + return ( _kptr ) ; + } + + /* + -------------------------------------------------------- + * _POP: _pop data from heap + -------------------------------------------------------- + */ + + __inline_call void_type _pop_root ( + ) + { + /*---------------------------- _pop root, cache temp. */ + data_type _temp ; + _pop( +0, _temp); + } + __inline_call void_type _pop_root ( + data_type &_data + ) + { + /*---------------------------- _pop item, return data */ + size_type _hpos = +0 ; + kptr_type _kptr ; + _kptr = this->_heap[_hpos]._kptr ; + _data = + std::move (this->_heap[_hpos]._data); + /*----------------------- push "hole" to lower levels */ + if (this->_heap.head() + _hpos != + this->_heap.tail() ) + { + /*----------- sort "hole" at root to updated position */ + _write_it _ipos = push_lower ( + this->_heap.head() , + this->_heap.tail() - 1 , + this->_heap.head() + _hpos, + this->_heap.tail()-> _data) ; + + /*----------- copy current tail into updated position */ + _ipos->_data = std::move( + this->_heap.tail()-> _data) ; + _ipos->_kptr = std::move( + this->_heap.tail()-> _kptr) ; + + /*---------------------- update mapping for tail item */ + this->_keys[_ipos->_kptr] = + _ipos - this->_heap.head() ; + } + this->_heap._pop_tail(); + + this->_keys[_kptr] = + std::numeric_limits::max() ; + + this-> + _free.push_tail(_kptr) ; + } + + __inline_call void_type _pop ( + kptr_type _kptr + ) + { + /*---------------------------- _pop data, cache temp. */ + data_type _temp ; + _pop(_kptr,_temp); + } + __normal_call void_type _pop ( + kptr_type _kptr , + data_type &_data + ) + { + /*---------------------------- _pop item, return data */ + size_type _hpos = this->_keys[_kptr]; + _data = + std::move (this->_heap[_hpos]._data); + /*----------------------- push "hole" to lower levels */ + if (this->_heap.head() + _hpos != + this->_heap.tail() ) + { + /*----------- sort "hole" at root to updated position */ + _write_it _ipos = push_lower ( + this->_heap.head() , + this->_heap.tail() - 1 , + this->_heap.head() + _hpos, + this->_heap.tail()-> _data) ; + + /*----------- copy current tail into updated position */ + _ipos->_data = std::move( + this->_heap.tail()-> _data) ; + _ipos->_kptr = std::move( + this->_heap.tail()-> _kptr) ; + + /*---------------------- update mapping for tail item */ + this->_keys[_ipos->_kptr] = + _ipos - this->_heap.head() ; + } + this->_heap._pop_tail(); + + this->_keys[_kptr] = + std::numeric_limits::max() ; + + this-> + _free.push_tail(_kptr) ; + } + + /* + -------------------------------------------------------- + * UPDATE: update data in heap + -------------------------------------------------------- + */ + + __normal_call void_type update ( // copy + kptr_type _kptr, + data_type const&_data + ) + {/*------------------ move "hole" to updated position */ + size_type _hpos = + this->_keys[_kptr]; + _write_it _ipos ; + if (this->_pred(_data , + this->_heap[_hpos]. _data)) + /*-------------------- push "hole" to upper level */ + _ipos = push_upper ( + this-> _heap.head(), + this-> _heap.head()+_hpos , + __copy(data_type,_data)) ; + else + /*-------------------- push "hole" to lower level */ + _ipos = push_lower ( + this-> _heap.head(), + this-> _heap.tail(), + this-> _heap.head()+_hpos , + __copy(data_type,_data)) ; + + /*------------------------ copy this data into "hole" */ + _ipos->_kptr = _kptr ; + _ipos->_data = + __copy(data_type,_data) ; + + /*------------------------ copy position into mapping */ + this->_keys[_kptr] = + _ipos - this->_heap.head() ; + } + + __normal_call void_type update ( // move + kptr_type _kptr, + data_type &&_data + ) + {/*------------------ move "hole" to updated position */ + size_type _hpos = + this->_keys[_kptr]; + _write_it _ipos ; + if (this->_pred(_data , + this->_heap[_hpos]. _data)) + /*-------------------- push "hole" to upper level */ + _ipos = push_upper ( + this-> _heap.head(), + this-> _heap.head()+_hpos , + __copy(data_type,_data)) ; + else + /*-------------------- push "hole" to lower level */ + _ipos = push_lower ( + this-> _heap.head(), + this-> _heap.tail(), + this-> _heap.head()+_hpos , + __copy(data_type,_data)) ; + + /*------------------------ copy this data into "hole" */ + _ipos->_kptr = _kptr ; + _ipos->_data = + __move(data_type,_data) ; + + /*------------------------ copy position into mapping */ + this->_keys[_kptr] = + _ipos - this->_heap.head() ; + } + + /* + -------------------------------------------------------- + * test heap validity (debug only!) + -------------------------------------------------------- + */ + + __normal_call bool_type test_heap ( + ) + { +# ifdef _DEBUG + /*------------------ test relationships for all nodes */ + size_type _ipos = +1 ; + size_type _iend = + this->_heap.count () ; + for ( ; _ipos < _iend; ++_ipos) + { + /*------------------ heap is invalid if lower < upper */ + size_type _ppos = + (_ipos - 1)/_nfan ; + + if (this->_pred( + this->_heap[_ipos], + this->_heap[_ppos] + ) ) + return false ; + } +# endif + + /*------------------ must be valid if we got this far */ + return true ; + } + + } ; + +# undef __cont + + + } + +# endif //__PRIORITY_MAP__ + + + diff --git a/src/libcpp/containers/priorityset.hpp b/src/libcpp/containers/priorityset.hpp index 9aaf758..f959c7d 100644 --- a/src/libcpp/containers/priorityset.hpp +++ b/src/libcpp/containers/priorityset.hpp @@ -1,461 +1,461 @@ - -/* ------------------------------------------------------------- - * an "n-ary"-heap based priority queue. ------------------------------------------------------------- - * - * PRIORITY-MAP utilises an "n-ary" heap data-structure, - * designed to maintain sorted precedence in mutable - * collections. This "n-ary" heap simply generalises - * a standard binary heap (i.e. a 2-heap) to trees with - * "n" children per level. - * ------------------------------------------------------------- - * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) - * - * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The - * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be - * used at your own risk. - * ------------------------------------------------------------- - * - * Last updated: 03 May, 2017 - * - * Copyright 2013-2017 - * Darren Engwirda - * de2363@columbia.edu - * https://github.com/dengwirda/ - * ------------------------------------------------------------- - */ - -# pragma once - -# ifndef __PRIORITYSET__ -# define __PRIORITYSET__ - -# include "array.hpp" - - namespace containers { - -# define __cont containers - - template < - typename D , - typename P = std::less , - typename A = allocators::basic_alloc , - typename C = containers::array - > - class priorityset - { -/*----------- a dynamic priority queue as an "n"-ary heap */ - public : - - typedef D data_type ; - typedef C container ; - typedef P pred_type ; - typedef A allocator ; - - typedef typename - container::size_type size_type ; - - typedef priorityset < - data_type , - pred_type , - allocator , - container > self_type ; - - typedef typename - container::_write_it _write_it ; - typedef typename - container::_const_it _const_it ; - - size_type static const _nfan = +4; // fan out - - public : - - container _heap ; - - pred_type _pred ; - - private : - - /* - -------------------------------------------------------- - * helper: push "hole" into sorted position - -------------------------------------------------------- - */ - - __normal_call _write_it push_upper ( - _write_it _head, - _write_it _ipos, - data_type const&_data - ) - { - for ( ; _ipos != _head ; ) - { - /*----------------------- find position of parent */ - _write_it _ppos = - _head+(_ipos-_head-1) / _nfan ; - - /*----------------------- swap parent with "hole" */ - if (this->_pred(_data, *_ppos)) - { - *_ipos = std::move( *_ppos); - _ipos = _ppos ; - } - else break; - } - - /*---------------------------- return sorted position */ - return (_ipos); - } - - /* - -------------------------------------------------------- - * helper: push "hole" into sorted position - -------------------------------------------------------- - */ - - __normal_call _write_it push_lower ( - _write_it _head, - _write_it _tail, - _write_it _ipos, - data_type const&_data - ) - { - if (_head == _tail) return _ipos ; - /*-- find position of "root" within trailing sub-tree */ - _write_it _cpos ; - _write_it _imin ; - _write_it _iend = _head; - if (_tail - _head > 0) - { - _iend = - _head + (_tail-_head-1) / _nfan ; - } - /*-- push "hole" into sorted position on lower levels */ - for ( ; _ipos < _iend; ) - { - /*---------------------------- pos of right child */ - _cpos = _head + - _nfan * (_ipos - _head) + _nfan ; - /*---------------------------- find minimum child */ - _imin = _cpos; - switch (_nfan) - { - case 8 : - if (this->_pred(*--_cpos,*_imin)) - _imin=_cpos; // falls through - case 7 : - if (this->_pred(*--_cpos,*_imin)) - _imin=_cpos; // falls through - case 6 : - if (this->_pred(*--_cpos,*_imin)) - _imin=_cpos; // falls through - case 5 : - if (this->_pred(*--_cpos,*_imin)) - _imin=_cpos; // falls through - case 4 : - if (this->_pred(*--_cpos,*_imin)) - _imin=_cpos; // falls through - case 3 : - if (this->_pred(*--_cpos,*_imin)) - _imin=_cpos; // falls through - case 2 : - if (this->_pred(*--_cpos,*_imin)) - _imin=_cpos; // falls through - } - /*------------------------------ swap with "hole" */ - *_ipos = std::move(*_imin) ; - _ipos = _imin ; - } - /*-- deal with special cases - sort trailing sub-tree */ - if (_ipos == _iend) - { - size_type _inum = - _tail-_head-_nfan*(_ipos-_head); - if (_inum > +0) - { - /*---------------------------- pos of right child */ - _cpos = _head + - _nfan * (_ipos -_head) + _inum ; - /*---------------------------- find minimum child */ - _imin = _cpos; - switch (_inum) - { - case 8 : - if (this->_pred(*--_cpos,*_imin)) - _imin=_cpos; // falls through - case 7 : - if (this->_pred(*--_cpos,*_imin)) - _imin=_cpos; // falls through - case 6 : - if (this->_pred(*--_cpos,*_imin)) - _imin=_cpos; // falls through - case 5 : - if (this->_pred(*--_cpos,*_imin)) - _imin=_cpos; // falls through - case 4 : - if (this->_pred(*--_cpos,*_imin)) - _imin=_cpos; // falls through - case 3 : - if (this->_pred(*--_cpos,*_imin)) - _imin=_cpos; // falls through - case 2 : - if (this->_pred(*--_cpos,*_imin)) - _imin=_cpos; // falls through - } - /*------------------------------ swap with "hole" */ - *_ipos = std::move( *_imin) ; - _ipos = _imin ; - } - } - /*------------------ push "hole "into sorted position */ - return push_upper(_head, _ipos, _data) ; - } - - public : - -/*--------------------------- default c'tor - do nothing! */ - __inline_call priorityset ( - allocator const&_asrc = allocator(), - pred_type const&_psrc = pred_type() - ) : _heap(_asrc), - _pred(_psrc) {} -/*--------------------------- default c'tor - initialisor */ - __inline_call priorityset ( - pred_type const&_psrc - ) : _heap(allocator()), - _pred(_psrc) {} - - __inline_call~priorityset() = default ; - - __inline_call priorityset ( - self_type const&_src - ) = default ; - __inline_call priorityset ( - self_type && _src - ) = default ; - - __inline_call - self_type & operator= ( - self_type const&_src - ) = default ; - __inline_call - self_type & operator= ( - self_type && _src - ) = default ; - -/*------------------------------------- peek at heap root */ - __inline_call data_type const& root ( - ) const - { return this->_heap[ +0] ; - } - -/*------------------------------------- peek at heap item */ - __inline_call data_type const& peek ( - size_type _hpos = +0 - ) const - { return this->_heap[_hpos] ; - } - -/*-------------------------------------------- empty test */ - __inline_call bool_type empty ( - ) const - { return ( this->_heap. empty() ) ; - } - -/*-------------------------------------------- heap count */ - __inline_call size_type count ( - ) const - { return ( this->_heap. count() ) ; - } - -/*-------------------------------------------- heap alloc */ - __inline_call size_type alloc ( - ) const - { return ( this->_heap. alloc() ) ; - } - -/*-------------------------------------------- _set alloc */ - __inline_call void_type set_alloc ( - size_type _asiz - ) - { this->_heap.set_alloc( _asiz) ; - } - -/*------------------------------------- (const) iterators */ - __inline_call _const_it head ( - ) const - { return this->_heap. head() ; - } - __inline_call _const_it tail ( - ) const - { return this->_heap. tail() ; - } - __inline_call _const_it hend ( - ) const - { return this->_heap. hend() ; - } - __inline_call _const_it tend ( - ) const - { return this->_heap. tend() ; - } - - /* - -------------------------------------------------------- - * PUSH: push data onto heap - -------------------------------------------------------- - */ - - __inline_call void_type push ( // copy - data_type const&_data - ) - { - /*---------------- push data onto "tail" of container */ - size_type _tpos = - this->_heap.push_tail() ; - /*---------------- sort "hole" for data into position */ - _write_it _ipos = push_upper ( - this->_heap.head() , - this->_heap.head()+_tpos , - __copy(data_type,_data)); - /*---------------- copy new data into sorted position */ - *_ipos = - __copy(data_type,_data) ; - } - - __inline_call void_type push ( // move - data_type &&_data - ) - { - /*---------------- push data onto "tail" of container */ - size_type _tpos = - this->_heap.push_tail() ; - /*---------------- sort "hole" for data into position */ - _write_it _ipos = push_upper ( - this->_heap.head() , - this->_heap.head()+_tpos , - __copy(data_type,_data)); - /*---------------- copy new data into sorted position */ - *_ipos = - __move(data_type,_data) ; - } - - /* - -------------------------------------------------------- - * _POP: _pop data from heap - -------------------------------------------------------- - */ - - __inline_call void_type _pop_root ( - ) - { - /*---------------------------- _pop root, cache temp. */ - data_type _temp ; - _pop( +0, _temp); - } - __inline_call void_type _pop_root ( - data_type &_data - ) - { - /*---------------------------- _pop root, return data */ - _pop( +0, _data); - } - - __inline_call void_type _pop ( - size_type _hpos - ) - { - /*---------------------------- _pop data, cache temp. */ - data_type _temp ; - _pop(_hpos,_temp); - } - __normal_call void_type _pop ( - size_type _hpos, - data_type &_data - ) - { - /*---------------------------- _pop data, return data */ - _data = std::move ( - *(this->_heap.head() + _hpos)); - /*--------- push "hole" at HPOS into updated position */ - if (this->_heap.count() > 1) - { - /*---------- find new position for "hole" at HPOS */ - _write_it _ipos = push_lower ( - this->_heap.head() , - this->_heap.tail()- 1 , - this->_heap.head()+_hpos , - *this->_heap.tail()); - /*---------- copy tail data into updated position */ - *_ipos = - std::move(*this->_heap.tail()); - } - this->_heap._pop_tail() ; - } - - /* - -------------------------------------------------------- - * test heap validity (debug only!) - -------------------------------------------------------- - */ - - __normal_call bool_type test_heap ( - ) - { -# ifdef _DEBUG - /*------------------ test relationships for all nodes */ - size_type _ipos = +1 ; - size_type _iend = - this->_heap.count () ; - for ( ; _ipos < _iend; ++_ipos) - { - /*------------------ heap is invalid if lower < upper */ - size_type _ppos = - (_ipos - 1)/_nfan ; - - if (this->_pred( - this->_heap[_ipos], - this->_heap[_ppos] - ) ) - return false ; - } -# endif - - /*------------------ must be valid if we got this far */ - return true ; - } - - } ; - -# undef __cont - - - } - -# endif//__PRIORITYSET__ - - - + +/* +------------------------------------------------------------ + * an "n-ary"-heap based priority queue. +------------------------------------------------------------ + * + * PRIORITY-MAP utilises an "n-ary" heap data-structure, + * designed to maintain sorted precedence in mutable + * collections. This "n-ary" heap simply generalises + * a standard binary heap (i.e. a 2-heap) to trees with + * "n" children per level. + * +------------------------------------------------------------ + * + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) + * + * Disclaimer: Neither I nor: Columbia University, The + * Massachusetts Institute of Technology, The + * University of Sydney, nor The National Aeronautics + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be + * used at your own risk. + * +------------------------------------------------------------ + * + * Last updated: 03 May, 2017 + * + * Copyright 2013-2017 + * Darren Engwirda + * de2363@columbia.edu + * https://github.com/dengwirda/ + * +------------------------------------------------------------ + */ + +# pragma once + +# ifndef __PRIORITYSET__ +# define __PRIORITYSET__ + +# include "array.hpp" + + namespace containers { + +# define __cont containers + + template < + typename D , + typename P = std::less , + typename A = allocators::basic_alloc , + typename C = containers::array + > + class priorityset + { +/*----------- a dynamic priority queue as an "n"-ary heap */ + public : + + typedef D data_type ; + typedef C container ; + typedef P pred_type ; + typedef A allocator ; + + typedef typename + container::size_type size_type ; + + typedef priorityset < + data_type , + pred_type , + allocator , + container > self_type ; + + typedef typename + container::_write_it _write_it ; + typedef typename + container::_const_it _const_it ; + + size_type static const _nfan = +4; // fan out + + public : + + container _heap ; + + pred_type _pred ; + + private : + + /* + -------------------------------------------------------- + * helper: push "hole" into sorted position + -------------------------------------------------------- + */ + + __normal_call _write_it push_upper ( + _write_it _head, + _write_it _ipos, + data_type const&_data + ) + { + for ( ; _ipos != _head ; ) + { + /*----------------------- find position of parent */ + _write_it _ppos = + _head+(_ipos-_head-1) / _nfan ; + + /*----------------------- swap parent with "hole" */ + if (this->_pred(_data, *_ppos)) + { + *_ipos = std::move( *_ppos); + _ipos = _ppos ; + } + else break; + } + + /*---------------------------- return sorted position */ + return (_ipos); + } + + /* + -------------------------------------------------------- + * helper: push "hole" into sorted position + -------------------------------------------------------- + */ + + __normal_call _write_it push_lower ( + _write_it _head, + _write_it _tail, + _write_it _ipos, + data_type const&_data + ) + { + if (_head == _tail) return _ipos ; + /*-- find position of "root" within trailing sub-tree */ + _write_it _cpos ; + _write_it _imin ; + _write_it _iend = _head; + if (_tail - _head > 0) + { + _iend = + _head + (_tail-_head-1) / _nfan ; + } + /*-- push "hole" into sorted position on lower levels */ + for ( ; _ipos < _iend; ) + { + /*---------------------------- pos of right child */ + _cpos = _head + + _nfan * (_ipos - _head) + _nfan ; + /*---------------------------- find minimum child */ + _imin = _cpos; + switch (_nfan) + { + case 8 : + if (this->_pred(*--_cpos,*_imin)) + _imin=_cpos; // falls through + case 7 : + if (this->_pred(*--_cpos,*_imin)) + _imin=_cpos; // falls through + case 6 : + if (this->_pred(*--_cpos,*_imin)) + _imin=_cpos; // falls through + case 5 : + if (this->_pred(*--_cpos,*_imin)) + _imin=_cpos; // falls through + case 4 : + if (this->_pred(*--_cpos,*_imin)) + _imin=_cpos; // falls through + case 3 : + if (this->_pred(*--_cpos,*_imin)) + _imin=_cpos; // falls through + case 2 : + if (this->_pred(*--_cpos,*_imin)) + _imin=_cpos; // falls through + } + /*------------------------------ swap with "hole" */ + *_ipos = std::move(*_imin) ; + _ipos = _imin ; + } + /*-- deal with special cases - sort trailing sub-tree */ + if (_ipos == _iend) + { + size_type _inum = + _tail-_head-_nfan*(_ipos-_head); + if (_inum > +0) + { + /*---------------------------- pos of right child */ + _cpos = _head + + _nfan * (_ipos -_head) + _inum ; + /*---------------------------- find minimum child */ + _imin = _cpos; + switch (_inum) + { + case 8 : + if (this->_pred(*--_cpos,*_imin)) + _imin=_cpos; // falls through + case 7 : + if (this->_pred(*--_cpos,*_imin)) + _imin=_cpos; // falls through + case 6 : + if (this->_pred(*--_cpos,*_imin)) + _imin=_cpos; // falls through + case 5 : + if (this->_pred(*--_cpos,*_imin)) + _imin=_cpos; // falls through + case 4 : + if (this->_pred(*--_cpos,*_imin)) + _imin=_cpos; // falls through + case 3 : + if (this->_pred(*--_cpos,*_imin)) + _imin=_cpos; // falls through + case 2 : + if (this->_pred(*--_cpos,*_imin)) + _imin=_cpos; // falls through + } + /*------------------------------ swap with "hole" */ + *_ipos = std::move( *_imin) ; + _ipos = _imin ; + } + } + /*------------------ push "hole "into sorted position */ + return push_upper(_head, _ipos, _data) ; + } + + public : + +/*--------------------------- default c'tor - do nothing! */ + __inline_call priorityset ( + allocator const&_asrc = allocator(), + pred_type const&_psrc = pred_type() + ) : _heap(_asrc), + _pred(_psrc) {} +/*--------------------------- default c'tor - initialisor */ + __inline_call priorityset ( + pred_type const&_psrc + ) : _heap(allocator()), + _pred(_psrc) {} + + __inline_call~priorityset() = default ; + + __inline_call priorityset ( + self_type const&_src + ) = default ; + __inline_call priorityset ( + self_type && _src + ) = default ; + + __inline_call + self_type & operator= ( + self_type const&_src + ) = default ; + __inline_call + self_type & operator= ( + self_type && _src + ) = default ; + +/*------------------------------------- peek at heap root */ + __inline_call data_type const& root ( + ) const + { return this->_heap[ +0] ; + } + +/*------------------------------------- peek at heap item */ + __inline_call data_type const& peek ( + size_type _hpos = +0 + ) const + { return this->_heap[_hpos] ; + } + +/*-------------------------------------------- empty test */ + __inline_call bool_type empty ( + ) const + { return ( this->_heap. empty() ) ; + } + +/*-------------------------------------------- heap count */ + __inline_call size_type count ( + ) const + { return ( this->_heap. count() ) ; + } + +/*-------------------------------------------- heap alloc */ + __inline_call size_type alloc ( + ) const + { return ( this->_heap. alloc() ) ; + } + +/*-------------------------------------------- _set alloc */ + __inline_call void_type set_alloc ( + size_type _asiz + ) + { this->_heap.set_alloc( _asiz) ; + } + +/*------------------------------------- (const) iterators */ + __inline_call _const_it head ( + ) const + { return this->_heap. head() ; + } + __inline_call _const_it tail ( + ) const + { return this->_heap. tail() ; + } + __inline_call _const_it hend ( + ) const + { return this->_heap. hend() ; + } + __inline_call _const_it tend ( + ) const + { return this->_heap. tend() ; + } + + /* + -------------------------------------------------------- + * PUSH: push data onto heap + -------------------------------------------------------- + */ + + __inline_call void_type push ( // copy + data_type const&_data + ) + { + /*---------------- push data onto "tail" of container */ + size_type _tpos = + this->_heap.push_tail() ; + /*---------------- sort "hole" for data into position */ + _write_it _ipos = push_upper ( + this->_heap.head() , + this->_heap.head()+_tpos , + __copy(data_type,_data)); + /*---------------- copy new data into sorted position */ + *_ipos = + __copy(data_type,_data) ; + } + + __inline_call void_type push ( // move + data_type &&_data + ) + { + /*---------------- push data onto "tail" of container */ + size_type _tpos = + this->_heap.push_tail() ; + /*---------------- sort "hole" for data into position */ + _write_it _ipos = push_upper ( + this->_heap.head() , + this->_heap.head()+_tpos , + __copy(data_type,_data)); + /*---------------- copy new data into sorted position */ + *_ipos = + __move(data_type,_data) ; + } + + /* + -------------------------------------------------------- + * _POP: _pop data from heap + -------------------------------------------------------- + */ + + __inline_call void_type _pop_root ( + ) + { + /*---------------------------- _pop root, cache temp. */ + data_type _temp ; + _pop( +0, _temp); + } + __inline_call void_type _pop_root ( + data_type &_data + ) + { + /*---------------------------- _pop root, return data */ + _pop( +0, _data); + } + + __inline_call void_type _pop ( + size_type _hpos + ) + { + /*---------------------------- _pop data, cache temp. */ + data_type _temp ; + _pop(_hpos,_temp); + } + __normal_call void_type _pop ( + size_type _hpos, + data_type &_data + ) + { + /*---------------------------- _pop data, return data */ + _data = std::move ( + *(this->_heap.head() + _hpos)); + /*--------- push "hole" at HPOS into updated position */ + if (this->_heap.count() > 1) + { + /*---------- find new position for "hole" at HPOS */ + _write_it _ipos = push_lower ( + this->_heap.head() , + this->_heap.tail()- 1 , + this->_heap.head()+_hpos , + *this->_heap.tail()); + /*---------- copy tail data into updated position */ + *_ipos = + std::move(*this->_heap.tail()); + } + this->_heap._pop_tail() ; + } + + /* + -------------------------------------------------------- + * test heap validity (debug only!) + -------------------------------------------------------- + */ + + __normal_call bool_type test_heap ( + ) + { +# ifdef _DEBUG + /*------------------ test relationships for all nodes */ + size_type _ipos = +1 ; + size_type _iend = + this->_heap.count () ; + for ( ; _ipos < _iend; ++_ipos) + { + /*------------------ heap is invalid if lower < upper */ + size_type _ppos = + (_ipos - 1)/_nfan ; + + if (this->_pred( + this->_heap[_ipos], + this->_heap[_ppos] + ) ) + return false ; + } +# endif + + /*------------------ must be valid if we got this far */ + return true ; + } + + } ; + +# undef __cont + + + } + +# endif//__PRIORITYSET__ + + + diff --git a/src/libcpp/containers/single_list.hpp b/src/libcpp/containers/single_list.hpp index 9716f89..7a05208 100644 --- a/src/libcpp/containers/single_list.hpp +++ b/src/libcpp/containers/single_list.hpp @@ -1,806 +1,806 @@ - -/* ------------------------------------------------------------- - * a singly-linked list object. ------------------------------------------------------------- - * - * SINGLE-LIST is a "singly-linked" list type, where - * list items comprise a singly-oriented chain of - * pointers. This variant maintains both "head" and - * "tail" objects, but only supports singly-oriented - * manipulation. Insertion/deletion is O(1), acccess is - * O(N). List count is stored explicitly, and is O(1) - * as a result. - * ------------------------------------------------------------- - * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) - * - * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The - * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be - * used at your own risk. - * ------------------------------------------------------------- - * - * Last updated: 21 December, 2018 - * - * Copyright 2013-2018 - * Darren Engwirda - * de2363@columbia.edu - * https://github.com/dengwirda/ - * ------------------------------------------------------------- - */ - -# pragma once - -# ifndef __SINGLE_LIST__ -# define __SINGLE_LIST__ - -# include "singleiter.hpp" - - namespace containers { - -# define __cont containers - - template < - typename D - > - class single_item - { -/*------------------------------- singly-linked list item */ - public : - - typedef D data_type ; - typedef - __cont::single_item self_type ; - - public : - - self_type *_next ; - - data_type _data ; - - public : - -/*------------------------------- c'tor/d'tor/assign etc. */ - __inline_call single_item ( - self_type *_nsrc - ) : _next( _nsrc) - { /* void construct */ - } - __inline_call single_item ( - self_type *_nsrc , - data_type const&_dsrc - ) : _next( _nsrc), - _data( - __copy(data_type,_dsrc)) - { /* copy construct */ - } - __inline_call single_item ( - self_type *_nsrc , - data_type&&_dsrc - ) : _next( _nsrc), - _data( - __move(data_type,_dsrc)) - { /* move construct */ - } - - __inline_call~single_item() = default ; - - __inline_call single_item ( - self_type const&_src - ) = default ; - __inline_call single_item ( - self_type && _src - ) = default ; - - __inline_call - self_type & operator= ( - self_type const&_src - ) = default ; - __inline_call - self_type & operator= ( - self_type && _src - ) = default ; - -/*------------------------------ access to "next" pointer */ - __inline_call self_type*& next ( - ) - { return ( this->_next ) ; - } - - } ; - - template < - typename D , - typename A = allocators::basic_alloc - > - class single_list : public - allocators::_item_alloc < - single_item < D>, A > - { -/*------ double-ended linked-list for singly-linked items */ - public : - - typedef D data_type ; - typedef A allocator ; - - typedef containers::single_list < - data_type , - allocator > self_type ; - - typedef containers::single_item < - data_type > item_type ; - typedef allocators::_item_alloc < - item_type , - allocator > obj_alloc ; - - typedef containers::const_single_iterator < - self_type > _const_it ; - typedef containers::write_single_iterator < - self_type > _write_it ; - - typedef typename - allocator::size_type size_type ; - typedef typename - allocator::diff_type diff_type ; - - private : - - item_type* _hptr ; // head/tail pointers - item_type* _tptr ; - - size_type _nobj ; - - private : - -/*------------------------------ helper - construct range */ - template < - typename iter_type - > - __normal_call void_type copy_list ( - iter_type _head, - iter_type _tend, - __cont::base_iterator_kind - ) - { /* push the sequence onto list */ - for ( ; _head != _tend; ++_head) - push_tail(*_head) ; - } - - __inline_call void_type copy_list ( - size_type _size , - data_type const& _dsrc, - __cont::null_iterator_kind - ) - { copy_data(_size, _dsrc); - } - - __normal_call void_type copy_data ( - size_type _size, - data_type const& _dsrc - ) - { /* push _size copies onto list */ - for ( ; _size-- != 0; ) - push_head(_dsrc); - } - - public : - -/*--------------------------- default c'tor - do nothing! */ - __inline_call single_list ( - allocator const&_asrc = allocator() - ) : obj_alloc( _asrc ) - { /* construct pointers and allocator */ - this->_nobj = +0 ; - this->_hptr = nullptr ; - this->_tptr = nullptr ; - } -/*--------------------------- default c'tor - initialisor */ - __inline_call single_list ( - size_type _size , - data_type const&_dsrc = data_type(), - allocator const&_asrc = allocator() - ) : obj_alloc( _asrc ) - { - this->_nobj = +0 ; - this->_hptr = nullptr ; - this->_tptr = nullptr ; - copy_data(_size,_dsrc); - } -/*--------------------------- default c'tor - initialisor */ - template < - typename iter_type - > - __inline_call single_list ( - iter_type _head, - iter_type _tail, - allocator const&_asrc = allocator() - ) : obj_alloc( _asrc ) - { - this->_nobj = +0 ; - this->_hptr = nullptr ; - this->_tptr = nullptr ; - copy_list(_head,_tail, - __cont::iter_kind(_head)) ; - } - -/*-------------------------------------------- _def d'tor */ - __inline_call~single_list ( - ) { clear() ; } - -/*-------------------------------------------- copy c'tor */ - __inline_call single_list ( - self_type const& _src - ) : obj_alloc( - __copy(obj_alloc,_src)) - { - this->_nobj = +0 ; - this->_hptr = nullptr ; - this->_tptr = nullptr ; - /*------------------------------- copy data from _src */ - _const_it _head, _tail; - _head = _src.head(); - _tail = _src.tend(); - copy_list(_head,_tail, - __cont::iter_kind(_head)) ; - } - -/*-------------------------------------------- move c'tor */ - __inline_call single_list ( - self_type && _src - ) : obj_alloc( - __move(obj_alloc,_src)) - { - /*------------------------------- move data from _src */ - this->_nobj = _src._nobj ; - this->_hptr = _src._hptr ; - this->_tptr = _src._tptr ; - _src. _nobj = +0 ; - _src. _hptr = nullptr ; - _src. _tptr = nullptr ; - } - -/*-------------------------------------------- copy a-op. */ - __inline_call self_type& operator = ( - self_type const& _src - ) - { - if (this != &_src) - { - self_type _copy ( - __copy(self_type, _src)) ; - - using std::swap ; - swap ( - static_cast(*this), - static_cast(_copy)) ; - - swap(this->_hptr, - _copy. _hptr) ; - swap(this->_tptr, - _copy. _tptr) ; - swap(this->_nobj, - _copy. _nobj) ; - } - - return ( *this ) ; - } - -/*-------------------------------------------- move a-op. */ - __inline_call self_type &operator = ( - self_type && _src - ) - { - if (this != &_src) - { - self_type _copy ( - __move(self_type, _src)) ; - - using std::swap ; - swap ( - static_cast(*this), - static_cast(_copy)) ; - - swap(this->_hptr, - _copy. _hptr) ; - swap(this->_tptr, - _copy. _tptr) ; - swap(this->_nobj, - _copy. _nobj) ; - } - - return ( *this ) ; - } - -/*-------------------------------- return container count */ - __inline_call size_type count ( - ) const { return ( this->_nobj ) ; } - -/*-------------------------------- true if sequence empty */ - __inline_call bool_type empty ( - ) const - { /* return empty status */ - return ( nullptr ==this->_hptr ) ; - } - -/*-------------------------------- return container alloc */ - __inline_call allocator get_alloc ( - ) const - { - return - static_cast ( *this ) ; - } - -/*------------------------------ "const" access iterators */ - __inline_call _const_it head ( - ) const - {/*---- return iterator for list head */ - self_type *_obj = (self_type *)this; - return _const_it(this->_hptr, _obj); - } - - __inline_call _const_it tail ( - ) const - {/*---- return iterator for list tail */ - self_type *_obj = (self_type *)this; - return _const_it(this->_tptr, _obj); - } - - __inline_call _const_it hend ( - ) const - {/* return iterator "past" head, via null terminator! */ - self_type *_obj = (self_type *)this; - return _const_it(nullptr, _obj) ; - } - - __inline_call _const_it tend ( - ) const - {/* return iterator "past" tail, via null terminator! */ - self_type *_obj = (self_type *)this; - return _const_it(nullptr, _obj) ; - } - -/*------------------------------ "write" access iterators */ - __inline_call _write_it head ( - ) - {/*---- return iterator for list head */ - self_type *_obj = (self_type *)this; - return _write_it(this->_hptr, _obj); - } - - __inline_call _write_it tail ( - ) - {/*---- return iterator for list tail */ - self_type *_obj = (self_type *)this; - return _write_it(this->_tptr, _obj); - } - - __inline_call _write_it hend ( - ) - {/* return iterator "past" head, via null terminator! */ - self_type *_obj = (self_type *)this; - return _write_it(nullptr, _obj) ; - } - - __inline_call _write_it tend ( - ) - {/* return iterator "past" tail, via null terminator! */ - self_type *_obj = (self_type *)this; - return _write_it(nullptr, _obj) ; - } - -/*-------------------------------------- "free" container */ - __normal_call void_type clear ( - ) - {/* _pop all items in traversal from head */ - _write_it _head = head(); - _write_it _tend = tend(); - for ( ; _head != _tend; ) - { - _write_it _prev(_head++) ; - self_type:: - _destruct(_prev.item()) ; - self_type:: - deallocate(_prev.item(),1) ; - } - this->_nobj = +0 ; - this->_hptr = nullptr ; - this->_tptr = nullptr ; - } - -/*---------------------------- push data (_def construct) */ - __inline_call _write_it push_head ( - ) - {/* allocate and construct a new raw item */ - item_type *_this_item = - self_type::allocate(1); - self_type::construct(_this_item, - this->_hptr); - - if (this->_hptr!= nullptr) - {/* push onto list head only */ - this->_hptr = _this_item ; - } - else - {/* push onto list head/tail */ - this->_hptr = _this_item ; - this->_tptr = _this_item ; - } - this->_nobj += +1 ; - - return - _write_it(_this_item,(self_type*)this) ; - } - -/*---------------------------- push data (copy construct) */ - __inline_call _write_it push_head ( - data_type const&_data - ) - {/* allocate and construct a new raw item */ - item_type *_this_item = - self_type::allocate(1); - self_type::construct(_this_item, - this->_hptr,//link! - __copy(data_type,_data)) ; - - if (this->_hptr!= nullptr) - {/* push onto list head only */ - this->_hptr = _this_item ; - } - else - {/* push onto list head/tail */ - this->_hptr = _this_item ; - this->_tptr = _this_item ; - } - this->_nobj += +1 ; - - return - _write_it(_this_item,(self_type*)this) ; - } - -/*---------------------------- push data (move construct) */ - __inline_call _write_it push_head ( - data_type &&_data - ) - {/* allocate and construct a new raw item */ - item_type *_this_item = - self_type::allocate(1); - self_type::construct(_this_item, - this->_hptr,//link! - __move(data_type,_data)) ; - - if (this->_hptr!= nullptr) - {/* push onto list head only */ - this->_hptr = _this_item ; - } - else - {/* push onto list head/tail */ - this->_hptr = _this_item ; - this->_tptr = _this_item ; - } - this->_nobj += +1 ; - - return - _write_it(_this_item,(self_type*)this) ; - } - -/*---------------------------- push data (_def construct) */ - __inline_call _write_it push_tail ( - ) - {/* allocate and construct a new raw item */ - item_type *_this_item = - self_type::allocate(1); - self_type::construct(_this_item , - (item_type *) nullptr) ; - - if (this->_tptr != nullptr) - {/* push onto list tail only */ - this->_tptr->next() - = _this_item ; - this->_tptr = _this_item ; - } - else - {/* push onto list tail/head */ - this->_hptr = _this_item ; - this->_tptr = _this_item ; - } - this->_nobj += +1 ; - - return - _write_it(_this_item,(self_type*)this) ; - } - -/*---------------------------- push data (copy construct) */ - __inline_call _write_it push_tail ( - data_type const&_data - ) - {/* allocate and construct a new raw item */ - item_type *_this_item = - self_type::allocate(1); - self_type::construct(_this_item, - (item_type *)nullptr, - __copy(data_type,_data)) ; - - if (this->_tptr != nullptr) - {/* push onto list tail only */ - this->_tptr->next() - = _this_item ; - this->_tptr = _this_item ; - } - else - {/* push onto list tail/head */ - this->_hptr = _this_item ; - this->_tptr = _this_item ; - } - this->_nobj += +1 ; - - return - _write_it(_this_item,(self_type*)this) ; - } - -/*---------------------------- push data (move construct) */ - __inline_call _write_it push_tail ( - data_type &&_data - ) - {/* allocate and construct a new raw item */ - item_type *_this_item = - self_type::allocate(1); - self_type::construct(_this_item, - (item_type *)nullptr, - __move(data_type,_data)) ; - - if (this->_tptr != nullptr) - {/* push onto list tail only */ - this->_tptr->next() - = _this_item ; - this->_tptr = _this_item ; - } - else - {/* push onto list tail/head */ - this->_hptr = _this_item ; - this->_tptr = _this_item ; - } - this->_nobj += +1 ; - - return - _write_it(_this_item,(self_type*)this) ; - } - -/*---------------------------- push data (copy obj range) */ - template < - typename iter_type - > - __normal_call void_type push_head ( - iter_type _hend, - iter_type _tail - ) - { /* push a full sequence at tail */ - for(; _tail != _hend; --_tail ) - push_head(*_tail) ; - } - - template < - typename iter_type - > - __normal_call void_type push_tail ( - iter_type _head, - iter_type _tend - ) - { /* push a full sequence at tail */ - for(; _head != _tend; ++_head ) - push_tail(*_head) ; - } - -/*--------------------------------------------- _pop data */ - __inline_call void_type _pop_head ( - ) - { - __assert( this->_hptr != nullptr && - "single_list._pop_head: null ptr"); - /* shuffle next item onto list _head */ - item_type *_head_item = - this->_hptr ; - this->_hptr = _head_item->next(); - - if (this->_hptr == nullptr) - { /* list became empty */ - this->_tptr = nullptr; - } - this->_nobj -= 1 ; - - /* _destruct and deallocate old head */ - self_type:: _destruct(_head_item) ; - self_type::deallocate(_head_item,1) ; - } - -/*--------------------------------------------- _pop data */ - __inline_call void_type _pop_head ( - data_type &_data - ) - { - __assert( this->_hptr != nullptr && - "single_list._pop_head: null ptr"); - /*-- move data before _pop */ - _data = __move ( - data_type, this->_hptr->_data); - /*-- delegate to _pop impl.*/ - self_type::_pop_head () ; - } - -/*-------------------------- insert data (_def construct) */ - __normal_call _write_it insert_next ( - _write_it _prev_iter - ) - { - item_type *_prev_item, *_next_item ; - if ((_prev_item = - _prev_iter. item()) == nullptr) - { /*----- push onto list head */ - return push_head() ; - } - else - if ((_next_item = - _prev_item->next()) == nullptr) - { /*----- push onto list tail */ - return push_tail() ; - } - else - { /* insert in middle of list */ - item_type *_this_item = - self_type::allocate(1); - self_type::construct( - _this_item, _next_item); - - _prev_item->next() = _this_item; - this->_nobj += +1 ; - - return _write_it( - _this_item, (self_type*)this); - } - } - -/*-------------------------- insert data (copy construct) */ - __normal_call _write_it insert_next ( - _write_it _prev_iter, - data_type const&_data - ) - { - item_type *_prev_item, *_next_item ; - if ((_prev_item = - _prev_iter. item()) == nullptr) - { /*----- push onto list head */ - return push_head( - __copy(data_type,_data)); - } - else - if ((_next_item = - _prev_item->next()) == nullptr) - { /*----- push onto list tail */ - return push_tail( - __copy(data_type,_data)); - } - else - { /* insert in middle of list */ - item_type *_this_item = - self_type::allocate(1); - self_type::construct(_this_item, - _next_item, //link! - __copy(data_type,_data)) ; - - _prev_item->next() = _this_item; - this->_nobj += +1 ; - - return _write_it( - _this_item, (self_type*)this); - } - } - -/*-------------------------- insert data (move construct) */ - __normal_call _write_it insert_next ( - _write_it _prev_iter, - data_type &&_data - ) - { - item_type *_prev_item, *_next_item ; - if ((_prev_item = - _prev_iter. item()) == nullptr) - { /*----- push onto list head */ - return push_head( - __move(data_type,_data)); - } - else - if ((_next_item = - _prev_item->next()) == nullptr) - { /*----- push onto list tail */ - return push_tail( - __move(data_type,_data)); - } - else - { /* insert in middle of list */ - item_type *_this_item = - self_type::allocate(1); - self_type::construct(_this_item, - _next_item, //link! - __move(data_type,_data)) ; - - _prev_item->next() = _this_item; - this->_nobj += +1 ; - - return _write_it( - _this_item, (self_type*)this); - } - } - -/*-------------------------------------------- erase item */ - __normal_call void_type erase ( - _write_it _prev_iter, - _write_it _this_iter - ) - { - __assert ( - _this_iter.item() != nullptr && - "list.erase: null iterator!"); - /* _pop item, re-link, _destruct//deallocate */ - item_type - *_this_item = _this_iter. item() , - *_prev_item = _prev_iter. item() , - *_prev_next = _prev_item->next() , - *_next_item = _this_item->next() ; - - if (_prev_item == nullptr) - {/* re-link item neighbours at list head */ - __assert ( - this->_hptr == _this_item && - "list.erase: _bad iterator!" ) ; - this->_hptr = _next_item ; - if (_next_item == nullptr) - this->_tptr = _next_item ; - } - else - {/* re-link item neighbours in list mid */ - __assert ( - _prev_next == _this_item && - "list.erase: _bad iterator!" ) ; - _prev_item->next() - = _next_item ; - if (_next_item == nullptr) - this->_tptr = _prev_item ; - } - this->_nobj -= +1 ; - - self_type:: _destruct(_this_item) ; - self_type::deallocate(_this_item,1) ; - } - - } ; - -# undef __cont - - - } - -# endif //__SINGLE_LIST__ - - - + +/* +------------------------------------------------------------ + * a singly-linked list object. +------------------------------------------------------------ + * + * SINGLE-LIST is a "singly-linked" list type, where + * list items comprise a singly-oriented chain of + * pointers. This variant maintains both "head" and + * "tail" objects, but only supports singly-oriented + * manipulation. Insertion/deletion is O(1), acccess is + * O(N). List count is stored explicitly, and is O(1) + * as a result. + * +------------------------------------------------------------ + * + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) + * + * Disclaimer: Neither I nor: Columbia University, The + * Massachusetts Institute of Technology, The + * University of Sydney, nor The National Aeronautics + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be + * used at your own risk. + * +------------------------------------------------------------ + * + * Last updated: 21 December, 2018 + * + * Copyright 2013-2018 + * Darren Engwirda + * de2363@columbia.edu + * https://github.com/dengwirda/ + * +------------------------------------------------------------ + */ + +# pragma once + +# ifndef __SINGLE_LIST__ +# define __SINGLE_LIST__ + +# include "singleiter.hpp" + + namespace containers { + +# define __cont containers + + template < + typename D + > + class single_item + { +/*------------------------------- singly-linked list item */ + public : + + typedef D data_type ; + typedef + __cont::single_item self_type ; + + public : + + self_type *_next ; + + data_type _data ; + + public : + +/*------------------------------- c'tor/d'tor/assign etc. */ + __inline_call single_item ( + self_type *_nsrc + ) : _next( _nsrc) + { /* void construct */ + } + __inline_call single_item ( + self_type *_nsrc , + data_type const&_dsrc + ) : _next( _nsrc), + _data( + __copy(data_type,_dsrc)) + { /* copy construct */ + } + __inline_call single_item ( + self_type *_nsrc , + data_type&&_dsrc + ) : _next( _nsrc), + _data( + __move(data_type,_dsrc)) + { /* move construct */ + } + + __inline_call~single_item() = default ; + + __inline_call single_item ( + self_type const&_src + ) = default ; + __inline_call single_item ( + self_type && _src + ) = default ; + + __inline_call + self_type & operator= ( + self_type const&_src + ) = default ; + __inline_call + self_type & operator= ( + self_type && _src + ) = default ; + +/*------------------------------ access to "next" pointer */ + __inline_call self_type*& next ( + ) + { return ( this->_next ) ; + } + + } ; + + template < + typename D , + typename A = allocators::basic_alloc + > + class single_list : public + allocators::_item_alloc < + single_item < D>, A > + { +/*------ double-ended linked-list for singly-linked items */ + public : + + typedef D data_type ; + typedef A allocator ; + + typedef containers::single_list < + data_type , + allocator > self_type ; + + typedef containers::single_item < + data_type > item_type ; + typedef allocators::_item_alloc < + item_type , + allocator > obj_alloc ; + + typedef containers::const_single_iterator < + self_type > _const_it ; + typedef containers::write_single_iterator < + self_type > _write_it ; + + typedef typename + allocator::size_type size_type ; + typedef typename + allocator::diff_type diff_type ; + + private : + + item_type* _hptr ; // head/tail pointers + item_type* _tptr ; + + size_type _nobj ; + + private : + +/*------------------------------ helper - construct range */ + template < + typename iter_type + > + __normal_call void_type copy_list ( + iter_type _head, + iter_type _tend, + __cont::base_iterator_kind + ) + { /* push the sequence onto list */ + for ( ; _head != _tend; ++_head) + push_tail(*_head) ; + } + + __inline_call void_type copy_list ( + size_type _size , + data_type const& _dsrc, + __cont::null_iterator_kind + ) + { copy_data(_size, _dsrc); + } + + __normal_call void_type copy_data ( + size_type _size, + data_type const& _dsrc + ) + { /* push _size copies onto list */ + for ( ; _size-- != 0; ) + push_head(_dsrc); + } + + public : + +/*--------------------------- default c'tor - do nothing! */ + __inline_call single_list ( + allocator const&_asrc = allocator() + ) : obj_alloc( _asrc ) + { /* construct pointers and allocator */ + this->_nobj = +0 ; + this->_hptr = nullptr ; + this->_tptr = nullptr ; + } +/*--------------------------- default c'tor - initialisor */ + __inline_call single_list ( + size_type _size , + data_type const&_dsrc = data_type(), + allocator const&_asrc = allocator() + ) : obj_alloc( _asrc ) + { + this->_nobj = +0 ; + this->_hptr = nullptr ; + this->_tptr = nullptr ; + copy_data(_size,_dsrc); + } +/*--------------------------- default c'tor - initialisor */ + template < + typename iter_type + > + __inline_call single_list ( + iter_type _head, + iter_type _tail, + allocator const&_asrc = allocator() + ) : obj_alloc( _asrc ) + { + this->_nobj = +0 ; + this->_hptr = nullptr ; + this->_tptr = nullptr ; + copy_list(_head,_tail, + __cont::iter_kind(_head)) ; + } + +/*-------------------------------------------- _def d'tor */ + __inline_call~single_list ( + ) { clear() ; } + +/*-------------------------------------------- copy c'tor */ + __inline_call single_list ( + self_type const& _src + ) : obj_alloc( + __copy(obj_alloc,_src)) + { + this->_nobj = +0 ; + this->_hptr = nullptr ; + this->_tptr = nullptr ; + /*------------------------------- copy data from _src */ + _const_it _head, _tail; + _head = _src.head(); + _tail = _src.tend(); + copy_list(_head,_tail, + __cont::iter_kind(_head)) ; + } + +/*-------------------------------------------- move c'tor */ + __inline_call single_list ( + self_type && _src + ) : obj_alloc( + __move(obj_alloc,_src)) + { + /*------------------------------- move data from _src */ + this->_nobj = _src._nobj ; + this->_hptr = _src._hptr ; + this->_tptr = _src._tptr ; + _src. _nobj = +0 ; + _src. _hptr = nullptr ; + _src. _tptr = nullptr ; + } + +/*-------------------------------------------- copy a-op. */ + __inline_call self_type& operator = ( + self_type const& _src + ) + { + if (this != &_src) + { + self_type _copy ( + __copy(self_type, _src)) ; + + using std::swap ; + swap ( + static_cast(*this), + static_cast(_copy)) ; + + swap(this->_hptr, + _copy. _hptr) ; + swap(this->_tptr, + _copy. _tptr) ; + swap(this->_nobj, + _copy. _nobj) ; + } + + return ( *this ) ; + } + +/*-------------------------------------------- move a-op. */ + __inline_call self_type &operator = ( + self_type && _src + ) + { + if (this != &_src) + { + self_type _copy ( + __move(self_type, _src)) ; + + using std::swap ; + swap ( + static_cast(*this), + static_cast(_copy)) ; + + swap(this->_hptr, + _copy. _hptr) ; + swap(this->_tptr, + _copy. _tptr) ; + swap(this->_nobj, + _copy. _nobj) ; + } + + return ( *this ) ; + } + +/*-------------------------------- return container count */ + __inline_call size_type count ( + ) const { return ( this->_nobj ) ; } + +/*-------------------------------- true if sequence empty */ + __inline_call bool_type empty ( + ) const + { /* return empty status */ + return ( nullptr ==this->_hptr ) ; + } + +/*-------------------------------- return container alloc */ + __inline_call allocator get_alloc ( + ) const + { + return + static_cast ( *this ) ; + } + +/*------------------------------ "const" access iterators */ + __inline_call _const_it head ( + ) const + {/*---- return iterator for list head */ + self_type *_obj = (self_type *)this; + return _const_it(this->_hptr, _obj); + } + + __inline_call _const_it tail ( + ) const + {/*---- return iterator for list tail */ + self_type *_obj = (self_type *)this; + return _const_it(this->_tptr, _obj); + } + + __inline_call _const_it hend ( + ) const + {/* return iterator "past" head, via null terminator! */ + self_type *_obj = (self_type *)this; + return _const_it(nullptr, _obj) ; + } + + __inline_call _const_it tend ( + ) const + {/* return iterator "past" tail, via null terminator! */ + self_type *_obj = (self_type *)this; + return _const_it(nullptr, _obj) ; + } + +/*------------------------------ "write" access iterators */ + __inline_call _write_it head ( + ) + {/*---- return iterator for list head */ + self_type *_obj = (self_type *)this; + return _write_it(this->_hptr, _obj); + } + + __inline_call _write_it tail ( + ) + {/*---- return iterator for list tail */ + self_type *_obj = (self_type *)this; + return _write_it(this->_tptr, _obj); + } + + __inline_call _write_it hend ( + ) + {/* return iterator "past" head, via null terminator! */ + self_type *_obj = (self_type *)this; + return _write_it(nullptr, _obj) ; + } + + __inline_call _write_it tend ( + ) + {/* return iterator "past" tail, via null terminator! */ + self_type *_obj = (self_type *)this; + return _write_it(nullptr, _obj) ; + } + +/*-------------------------------------- "free" container */ + __normal_call void_type clear ( + ) + {/* _pop all items in traversal from head */ + _write_it _head = head(); + _write_it _tend = tend(); + for ( ; _head != _tend; ) + { + _write_it _prev(_head++) ; + self_type:: + _destruct(_prev.item()) ; + self_type:: + deallocate(_prev.item(),1) ; + } + this->_nobj = +0 ; + this->_hptr = nullptr ; + this->_tptr = nullptr ; + } + +/*---------------------------- push data (_def construct) */ + __inline_call _write_it push_head ( + ) + {/* allocate and construct a new raw item */ + item_type *_this_item = + self_type::allocate(1); + self_type::construct(_this_item, + this->_hptr); + + if (this->_hptr!= nullptr) + {/* push onto list head only */ + this->_hptr = _this_item ; + } + else + {/* push onto list head/tail */ + this->_hptr = _this_item ; + this->_tptr = _this_item ; + } + this->_nobj += +1 ; + + return + _write_it(_this_item,(self_type*)this) ; + } + +/*---------------------------- push data (copy construct) */ + __inline_call _write_it push_head ( + data_type const&_data + ) + {/* allocate and construct a new raw item */ + item_type *_this_item = + self_type::allocate(1); + self_type::construct(_this_item, + this->_hptr,//link! + __copy(data_type,_data)) ; + + if (this->_hptr!= nullptr) + {/* push onto list head only */ + this->_hptr = _this_item ; + } + else + {/* push onto list head/tail */ + this->_hptr = _this_item ; + this->_tptr = _this_item ; + } + this->_nobj += +1 ; + + return + _write_it(_this_item,(self_type*)this) ; + } + +/*---------------------------- push data (move construct) */ + __inline_call _write_it push_head ( + data_type &&_data + ) + {/* allocate and construct a new raw item */ + item_type *_this_item = + self_type::allocate(1); + self_type::construct(_this_item, + this->_hptr,//link! + __move(data_type,_data)) ; + + if (this->_hptr!= nullptr) + {/* push onto list head only */ + this->_hptr = _this_item ; + } + else + {/* push onto list head/tail */ + this->_hptr = _this_item ; + this->_tptr = _this_item ; + } + this->_nobj += +1 ; + + return + _write_it(_this_item,(self_type*)this) ; + } + +/*---------------------------- push data (_def construct) */ + __inline_call _write_it push_tail ( + ) + {/* allocate and construct a new raw item */ + item_type *_this_item = + self_type::allocate(1); + self_type::construct(_this_item , + (item_type *) nullptr) ; + + if (this->_tptr != nullptr) + {/* push onto list tail only */ + this->_tptr->next() + = _this_item ; + this->_tptr = _this_item ; + } + else + {/* push onto list tail/head */ + this->_hptr = _this_item ; + this->_tptr = _this_item ; + } + this->_nobj += +1 ; + + return + _write_it(_this_item,(self_type*)this) ; + } + +/*---------------------------- push data (copy construct) */ + __inline_call _write_it push_tail ( + data_type const&_data + ) + {/* allocate and construct a new raw item */ + item_type *_this_item = + self_type::allocate(1); + self_type::construct(_this_item, + (item_type *)nullptr, + __copy(data_type,_data)) ; + + if (this->_tptr != nullptr) + {/* push onto list tail only */ + this->_tptr->next() + = _this_item ; + this->_tptr = _this_item ; + } + else + {/* push onto list tail/head */ + this->_hptr = _this_item ; + this->_tptr = _this_item ; + } + this->_nobj += +1 ; + + return + _write_it(_this_item,(self_type*)this) ; + } + +/*---------------------------- push data (move construct) */ + __inline_call _write_it push_tail ( + data_type &&_data + ) + {/* allocate and construct a new raw item */ + item_type *_this_item = + self_type::allocate(1); + self_type::construct(_this_item, + (item_type *)nullptr, + __move(data_type,_data)) ; + + if (this->_tptr != nullptr) + {/* push onto list tail only */ + this->_tptr->next() + = _this_item ; + this->_tptr = _this_item ; + } + else + {/* push onto list tail/head */ + this->_hptr = _this_item ; + this->_tptr = _this_item ; + } + this->_nobj += +1 ; + + return + _write_it(_this_item,(self_type*)this) ; + } + +/*---------------------------- push data (copy obj range) */ + template < + typename iter_type + > + __normal_call void_type push_head ( + iter_type _hend, + iter_type _tail + ) + { /* push a full sequence at tail */ + for(; _tail != _hend; --_tail ) + push_head(*_tail) ; + } + + template < + typename iter_type + > + __normal_call void_type push_tail ( + iter_type _head, + iter_type _tend + ) + { /* push a full sequence at tail */ + for(; _head != _tend; ++_head ) + push_tail(*_head) ; + } + +/*--------------------------------------------- _pop data */ + __inline_call void_type _pop_head ( + ) + { + __assert( this->_hptr != nullptr && + "single_list._pop_head: null ptr"); + /* shuffle next item onto list _head */ + item_type *_head_item = + this->_hptr ; + this->_hptr = _head_item->next(); + + if (this->_hptr == nullptr) + { /* list became empty */ + this->_tptr = nullptr; + } + this->_nobj -= 1 ; + + /* _destruct and deallocate old head */ + self_type:: _destruct(_head_item) ; + self_type::deallocate(_head_item,1) ; + } + +/*--------------------------------------------- _pop data */ + __inline_call void_type _pop_head ( + data_type &_data + ) + { + __assert( this->_hptr != nullptr && + "single_list._pop_head: null ptr"); + /*-- move data before _pop */ + _data = __move ( + data_type, this->_hptr->_data); + /*-- delegate to _pop impl.*/ + self_type::_pop_head () ; + } + +/*-------------------------- insert data (_def construct) */ + __normal_call _write_it insert_next ( + _write_it _prev_iter + ) + { + item_type *_prev_item, *_next_item ; + if ((_prev_item = + _prev_iter. item()) == nullptr) + { /*----- push onto list head */ + return push_head() ; + } + else + if ((_next_item = + _prev_item->next()) == nullptr) + { /*----- push onto list tail */ + return push_tail() ; + } + else + { /* insert in middle of list */ + item_type *_this_item = + self_type::allocate(1); + self_type::construct( + _this_item, _next_item); + + _prev_item->next() = _this_item; + this->_nobj += +1 ; + + return _write_it( + _this_item, (self_type*)this); + } + } + +/*-------------------------- insert data (copy construct) */ + __normal_call _write_it insert_next ( + _write_it _prev_iter, + data_type const&_data + ) + { + item_type *_prev_item, *_next_item ; + if ((_prev_item = + _prev_iter. item()) == nullptr) + { /*----- push onto list head */ + return push_head( + __copy(data_type,_data)); + } + else + if ((_next_item = + _prev_item->next()) == nullptr) + { /*----- push onto list tail */ + return push_tail( + __copy(data_type,_data)); + } + else + { /* insert in middle of list */ + item_type *_this_item = + self_type::allocate(1); + self_type::construct(_this_item, + _next_item, //link! + __copy(data_type,_data)) ; + + _prev_item->next() = _this_item; + this->_nobj += +1 ; + + return _write_it( + _this_item, (self_type*)this); + } + } + +/*-------------------------- insert data (move construct) */ + __normal_call _write_it insert_next ( + _write_it _prev_iter, + data_type &&_data + ) + { + item_type *_prev_item, *_next_item ; + if ((_prev_item = + _prev_iter. item()) == nullptr) + { /*----- push onto list head */ + return push_head( + __move(data_type,_data)); + } + else + if ((_next_item = + _prev_item->next()) == nullptr) + { /*----- push onto list tail */ + return push_tail( + __move(data_type,_data)); + } + else + { /* insert in middle of list */ + item_type *_this_item = + self_type::allocate(1); + self_type::construct(_this_item, + _next_item, //link! + __move(data_type,_data)) ; + + _prev_item->next() = _this_item; + this->_nobj += +1 ; + + return _write_it( + _this_item, (self_type*)this); + } + } + +/*-------------------------------------------- erase item */ + __normal_call void_type erase ( + _write_it _prev_iter, + _write_it _this_iter + ) + { + __assert ( + _this_iter.item() != nullptr && + "list.erase: null iterator!"); + /* _pop item, re-link, _destruct//deallocate */ + item_type + *_this_item = _this_iter. item() , + *_prev_item = _prev_iter. item() , + *_prev_next = _prev_item->next() , + *_next_item = _this_item->next() ; + + if (_prev_item == nullptr) + {/* re-link item neighbours at list head */ + __assert ( + this->_hptr == _this_item && + "list.erase: _bad iterator!" ) ; + this->_hptr = _next_item ; + if (_next_item == nullptr) + this->_tptr = _next_item ; + } + else + {/* re-link item neighbours in list mid */ + __assert ( + _prev_next == _this_item && + "list.erase: _bad iterator!" ) ; + _prev_item->next() + = _next_item ; + if (_next_item == nullptr) + this->_tptr = _prev_item ; + } + this->_nobj -= +1 ; + + self_type:: _destruct(_this_item) ; + self_type::deallocate(_this_item,1) ; + } + + } ; + +# undef __cont + + + } + +# endif //__SINGLE_LIST__ + + + diff --git a/src/libcpp/containers/singleiter.hpp b/src/libcpp/containers/singleiter.hpp index 04a5597..5919ed9 100644 --- a/src/libcpp/containers/singleiter.hpp +++ b/src/libcpp/containers/singleiter.hpp @@ -1,350 +1,350 @@ - -/* ------------------------------------------------------------- - * "single" iterator -- for singly-linked sequences. ------------------------------------------------------------- - * - * SINGLE-LIST is a "singly-linked" list type, where - * list items comprise a singly-oriented chain of - * pointers. This variant maintains both "head" and - * "tail" objects, but only supports singly-oriented - * manipulation. Insertion/deletion is O(1), acccess is - * O(N). List count is stored explicitly, and is O(1) - * as a result. - * ------------------------------------------------------------- - * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) - * - * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The - * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be - * used at your own risk. - * ------------------------------------------------------------- - * - * Last updated: 03 May, 2017 - * - * Copyright 2013-2017 - * Darren Engwirda - * de2363@columbia.edu - * https://github.com/dengwirda/ - * ------------------------------------------------------------- - */ - -# pragma once - -# ifndef __SINGLE_ITER__ -# define __SINGLE_ITER__ - -# include "iter_base.hpp" - - namespace containers { - - template < - typename L, - typename I - > - class single_iterator_base_ : - public containers::single_iterator_base - { -/*---------------------- iterator for singly-linked lists */ - public : - - typedef L list_type ; - typedef I iter_type ; - - typedef typename - list_type::data_type data_type ; - typedef typename - list_type::item_type item_type ; - typedef typename - list_type::size_type size_type ; - typedef typename - list_type::diff_type diff_type ; - - typedef single_iterator_base_ < - list_type , - iter_type > self_type ; - - public : - -# ifdef _DEBUG - item_type* _ptr; // list item - list_type* _obj; // list obj. -# else - item_type* _ptr; // list item -# endif - - public : - - __inline_call single_iterator_base_ ( - item_type *_psrc = nullptr, - list_type *_lsrc = nullptr -# ifdef _DEBUG - ) : _ptr(_psrc) , - _obj(_lsrc) {} -# else - ) : _ptr(_psrc) { __unreferenced(_lsrc) ; } -# endif - - __inline_call~single_iterator_base_ ( - ) = default ; - __inline_call single_iterator_base_ ( - self_type const&_src - ) = default ; - __inline_call single_iterator_base_ ( - self_type && _src - ) = default ; - - __inline_call - self_type & operator = ( - self_type const&_src - ) = default ; - __inline_call - self_type & operator = ( - self_type && _src - ) = default ; - -/*--------------------------------- translation operators */ - - __inline_call iter_type &operator++ ( - ) - { -# ifdef _DEBUG - __assert( this->_ptr != nullptr && - "single_iterator: null link!" ) ; -# endif - this->_ptr = this->_ptr->next() ; - return *(iter_type*)this ; - } - - __inline_call - iter_type operator++ ( int ) - { - iter_type _tmp(*(iter_type*)this); - ++*this; - return _tmp; - } - - __inline_call iter_type &operator+= ( - size_type _off - ) - { - for ( ; _off > 0; --_off)++*this ; - return *(iter_type*)this ; - } - - __inline_call iter_type operator + ( - size_type _off - ) const - { - iter_type _tmp(*(iter_type*)this); - return _tmp += _off; - } - -/*--------------------------------- comparative operators */ - - __inline_call bool_type operator == ( - self_type const&_src - ) const - { - return this->_ptr == _src._ptr ; - } - __inline_call bool_type operator != ( - self_type const&_src - ) const - { - return this->_ptr != _src._ptr ; - } - - } ; - - /* - -------------------------------------------------------- - * "const" iterators for singly-linked sequences. - -------------------------------------------------------- - */ - - template < - typename L - > - class const_single_iterator: public - single_iterator_base_ > - { -/*---------------------- iterator for singly-linked lists */ - public : - - typedef L list_type ; - - typedef const_single_iterator< - list_type > self_type ; - typedef single_iterator_base_< - list_type , - self_type > base_type ; - - typedef typename - base_type::data_type data_type ; - typedef typename - base_type::item_type item_type ; - typedef typename - base_type::size_type size_type ; - typedef typename - base_type::diff_type diff_type ; - - typedef data_type const& const_ref ; - typedef data_type const* const_ptr ; - - public : - - __inline_call const_single_iterator ( - item_type *_psrc = nullptr, - list_type *_lsrc = nullptr - ) : base_type(_psrc, _lsrc) {} - - __inline_call~const_single_iterator ( - ) = default ; - __inline_call const_single_iterator ( - self_type const&_src - ) = default ; - __inline_call const_single_iterator ( - self_type && _src - ) = default ; - - __inline_call - self_type & operator = ( - self_type const&_src - ) = default ; - __inline_call - self_type & operator = ( - self_type && _src - ) = default ; - -/*-------------------------------- "const" access to data */ - - __inline_call const_ref operator * ( - ) const - { -# ifdef _DEBUG - __assert( this->_ptr != nullptr && - "single_iterator: null pointer!"); -# endif - return this->_ptr->_data; - } - - __inline_call const_ptr operator-> ( - ) const { return &**this ; } - - __inline_call item_type const*item ( - ) const { return this->_ptr; } - - } ; - - /* - -------------------------------------------------------- - * "write" iterators for singly-linked sequences. - -------------------------------------------------------- - */ - - template < - typename L - > - class write_single_iterator: public - single_iterator_base_ > - { -/*---------------------- iterator for singly-linked lists */ - public : - - typedef L list_type ; - - typedef write_single_iterator< - list_type > self_type ; - typedef single_iterator_base_< - list_type , - self_type > base_type ; - - typedef typename - base_type::data_type data_type ; - typedef typename - base_type::item_type item_type ; - typedef typename - base_type::size_type size_type ; - typedef typename - base_type::diff_type diff_type ; - - typedef data_type & write_ref ; - typedef data_type * write_ptr ; - - public : - - __inline_call write_single_iterator ( - item_type *_psrc = nullptr, - list_type *_lsrc = nullptr - ) : base_type(_psrc, _lsrc) {} - - __inline_call~write_single_iterator ( - ) = default ; - __inline_call write_single_iterator ( - self_type const&_src - ) = default ; - __inline_call write_single_iterator ( - self_type && _src - ) = default ; - - __inline_call - self_type & operator = ( - self_type const&_src - ) = default ; - __inline_call - self_type & operator = ( - self_type && _src - ) = default ; - -/*-------------------------------- "write" access to data */ - - __inline_call write_ref operator * ( - ) const - { -# ifdef _DEBUG - __assert( this->_ptr != nullptr && - "single_iterator: null pointer!"); -# endif - return this->_ptr->_data; - } - - __inline_call write_ptr operator-> ( - ) const { return &**this ; } - - __inline_call item_type*item ( - ) const { return this->_ptr; } - - } ; - - - } - -# endif //__SINGLE_ITER__ - - - + +/* +------------------------------------------------------------ + * "single" iterator -- for singly-linked sequences. +------------------------------------------------------------ + * + * SINGLE-LIST is a "singly-linked" list type, where + * list items comprise a singly-oriented chain of + * pointers. This variant maintains both "head" and + * "tail" objects, but only supports singly-oriented + * manipulation. Insertion/deletion is O(1), acccess is + * O(N). List count is stored explicitly, and is O(1) + * as a result. + * +------------------------------------------------------------ + * + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) + * + * Disclaimer: Neither I nor: Columbia University, The + * Massachusetts Institute of Technology, The + * University of Sydney, nor The National Aeronautics + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be + * used at your own risk. + * +------------------------------------------------------------ + * + * Last updated: 03 May, 2017 + * + * Copyright 2013-2017 + * Darren Engwirda + * de2363@columbia.edu + * https://github.com/dengwirda/ + * +------------------------------------------------------------ + */ + +# pragma once + +# ifndef __SINGLE_ITER__ +# define __SINGLE_ITER__ + +# include "iter_base.hpp" + + namespace containers { + + template < + typename L, + typename I + > + class single_iterator_base_ : + public containers::single_iterator_base + { +/*---------------------- iterator for singly-linked lists */ + public : + + typedef L list_type ; + typedef I iter_type ; + + typedef typename + list_type::data_type data_type ; + typedef typename + list_type::item_type item_type ; + typedef typename + list_type::size_type size_type ; + typedef typename + list_type::diff_type diff_type ; + + typedef single_iterator_base_ < + list_type , + iter_type > self_type ; + + public : + +# ifdef _DEBUG + item_type* _ptr; // list item + list_type* _obj; // list obj. +# else + item_type* _ptr; // list item +# endif + + public : + + __inline_call single_iterator_base_ ( + item_type *_psrc = nullptr, + list_type *_lsrc = nullptr +# ifdef _DEBUG + ) : _ptr(_psrc) , + _obj(_lsrc) {} +# else + ) : _ptr(_psrc) { __unreferenced(_lsrc) ; } +# endif + + __inline_call~single_iterator_base_ ( + ) = default ; + __inline_call single_iterator_base_ ( + self_type const&_src + ) = default ; + __inline_call single_iterator_base_ ( + self_type && _src + ) = default ; + + __inline_call + self_type & operator = ( + self_type const&_src + ) = default ; + __inline_call + self_type & operator = ( + self_type && _src + ) = default ; + +/*--------------------------------- translation operators */ + + __inline_call iter_type &operator++ ( + ) + { +# ifdef _DEBUG + __assert( this->_ptr != nullptr && + "single_iterator: null link!" ) ; +# endif + this->_ptr = this->_ptr->next() ; + return *(iter_type*)this ; + } + + __inline_call + iter_type operator++ ( int ) + { + iter_type _tmp(*(iter_type*)this); + ++*this; + return _tmp; + } + + __inline_call iter_type &operator+= ( + size_type _off + ) + { + for ( ; _off > 0; --_off)++*this ; + return *(iter_type*)this ; + } + + __inline_call iter_type operator + ( + size_type _off + ) const + { + iter_type _tmp(*(iter_type*)this); + return _tmp += _off; + } + +/*--------------------------------- comparative operators */ + + __inline_call bool_type operator == ( + self_type const&_src + ) const + { + return this->_ptr == _src._ptr ; + } + __inline_call bool_type operator != ( + self_type const&_src + ) const + { + return this->_ptr != _src._ptr ; + } + + } ; + + /* + -------------------------------------------------------- + * "const" iterators for singly-linked sequences. + -------------------------------------------------------- + */ + + template < + typename L + > + class const_single_iterator: public + single_iterator_base_ > + { +/*---------------------- iterator for singly-linked lists */ + public : + + typedef L list_type ; + + typedef const_single_iterator< + list_type > self_type ; + typedef single_iterator_base_< + list_type , + self_type > base_type ; + + typedef typename + base_type::data_type data_type ; + typedef typename + base_type::item_type item_type ; + typedef typename + base_type::size_type size_type ; + typedef typename + base_type::diff_type diff_type ; + + typedef data_type const& const_ref ; + typedef data_type const* const_ptr ; + + public : + + __inline_call const_single_iterator ( + item_type *_psrc = nullptr, + list_type *_lsrc = nullptr + ) : base_type(_psrc, _lsrc) {} + + __inline_call~const_single_iterator ( + ) = default ; + __inline_call const_single_iterator ( + self_type const&_src + ) = default ; + __inline_call const_single_iterator ( + self_type && _src + ) = default ; + + __inline_call + self_type & operator = ( + self_type const&_src + ) = default ; + __inline_call + self_type & operator = ( + self_type && _src + ) = default ; + +/*-------------------------------- "const" access to data */ + + __inline_call const_ref operator * ( + ) const + { +# ifdef _DEBUG + __assert( this->_ptr != nullptr && + "single_iterator: null pointer!"); +# endif + return this->_ptr->_data; + } + + __inline_call const_ptr operator-> ( + ) const { return &**this ; } + + __inline_call item_type const*item ( + ) const { return this->_ptr; } + + } ; + + /* + -------------------------------------------------------- + * "write" iterators for singly-linked sequences. + -------------------------------------------------------- + */ + + template < + typename L + > + class write_single_iterator: public + single_iterator_base_ > + { +/*---------------------- iterator for singly-linked lists */ + public : + + typedef L list_type ; + + typedef write_single_iterator< + list_type > self_type ; + typedef single_iterator_base_< + list_type , + self_type > base_type ; + + typedef typename + base_type::data_type data_type ; + typedef typename + base_type::item_type item_type ; + typedef typename + base_type::size_type size_type ; + typedef typename + base_type::diff_type diff_type ; + + typedef data_type & write_ref ; + typedef data_type * write_ptr ; + + public : + + __inline_call write_single_iterator ( + item_type *_psrc = nullptr, + list_type *_lsrc = nullptr + ) : base_type(_psrc, _lsrc) {} + + __inline_call~write_single_iterator ( + ) = default ; + __inline_call write_single_iterator ( + self_type const&_src + ) = default ; + __inline_call write_single_iterator ( + self_type && _src + ) = default ; + + __inline_call + self_type & operator = ( + self_type const&_src + ) = default ; + __inline_call + self_type & operator = ( + self_type && _src + ) = default ; + +/*-------------------------------- "write" access to data */ + + __inline_call write_ref operator * ( + ) const + { +# ifdef _DEBUG + __assert( this->_ptr != nullptr && + "single_iterator: null pointer!"); +# endif + return this->_ptr->_data; + } + + __inline_call write_ptr operator-> ( + ) const { return &**this ; } + + __inline_call item_type*item ( + ) const { return this->_ptr; } + + } ; + + + } + +# endif //__SINGLE_ITER__ + + + diff --git a/src/libcpp/geom_base/intersect_k.hpp b/src/libcpp/geom_base/intersect_k.hpp index 5399b7b..b1e2238 100644 --- a/src/libcpp/geom_base/intersect_k.hpp +++ b/src/libcpp/geom_base/intersect_k.hpp @@ -1,37 +1,37 @@ /* -------------------------------------------------------- - * INTERSECT-K: various (robust) intersection tests. + * INTERSECT-K: various (robust) intersection tests. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 30 April, 2019 + * Last updated: 12 August, 2019 * * Copyright 2013-2019 * Darren Engwirda @@ -57,60 +57,6 @@ hits_type face_hits = +3 ; hits_type tria_hits = +4 ; - /* - -------------------------------------------------------- - * helper: solve quadratic equations - -------------------------------------------------------- - */ - - template < - typename data_type - > - __normal_call bool_type polyroots ( - data_type _aa, // aa*xx^2+bb*xx+cc=0 - data_type _bb, - data_type _cc, - __write_ptr (data_type) _xx - ) - { - bool_type _real = false ; - - data_type _sq = _bb * _bb - - (data_type)+4. * _aa * _cc ; - - if (_sq >= (data_type)+0.) // real roots - { - _sq = std::sqrt(_sq) ; - - _real = true; - - _xx[0] = (-_bb + _sq) ; - _xx[1] = (-_bb - _sq) ; - - data_type _xm = std::max ( - std::abs(_xx[0]), - std::abs(_xx[1])) ; - - data_type _rt = - std::numeric_limits::epsilon() ; - - if (_aa >= _xm * _rt) - { - _aa *=(data_type)+2.; - - _xx[0] /= _aa ; - _xx[1] /= _aa ; - } - else - { - _xx[0] = -_cc / _bb ; - _xx[1] = -_cc / _bb ; - } - } - - return _real ; - } - /* -------------------------------------------------------- * BALL-LINE-KD: ball-line intersections @@ -137,45 +83,46 @@ _ca[0] = _pa[0] -_pc[0] ; _ca[1] = _pa[1] -_pc[1] ; - data_type _aa = + data_type _aa = geometry::dot_2d(_vv, _vv) ; - data_type _bb = + data_type _bb = geometry::dot_2d(_vv, _ca) * - (data_type) +2. ; - data_type _cc = + (data_type) +2. ; + data_type _cc = geometry::dot_2d(_ca, _ca) ; _cc -= _rc * _rc ; - - size_t _nn = +0 ; + + size_t _nn = +0 ; data_type _tt[2] ; - if (polyroots(_aa, _bb, _cc, _tt)) + if ( math:: + polyroots(_aa, _bb, _cc, _tt)) { if (_tt[0] >= (data_type)+0. && _tt[0] <= (data_type)+1. ) { /*----------------------- compute 1st-root intersect. */ - data_type _WB = + data_type _WB = (data_type)+0.+_tt[0] ; - - data_type _WA = + + data_type _WA = (data_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 ; - + _PB[1] * _WB ; + if (_nn == 1) { _qa[0]=_QQ[0] ; @@ -189,30 +136,30 @@ } if (_tt[1] >= (data_type)+0. && _tt[1] <= (data_type)+1. ) - { + { /*----------------------- compute 2nd-root intersect. */ - data_type _WB = + data_type _WB = (data_type)+0.+_tt[1] ; - - data_type _WA = + + data_type _WA = (data_type)+1.-_tt[1] ; - + _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 ; - + _PB[1] * _WB ; + if (_nn == 1) { _qa[0]=_QQ[0] ; @@ -251,49 +198,50 @@ _ca[1] = _pa[1] -_pc[1] ; _ca[2] = _pa[2] -_pc[2] ; - data_type _aa = + data_type _aa = geometry::dot_3d(_vv, _vv) ; - data_type _bb = + data_type _bb = geometry::dot_3d(_vv, _ca) * - (data_type) +2. ; - data_type _cc = + (data_type) +2. ; + data_type _cc = geometry::dot_3d(_ca, _ca) ; _cc -= _rc * _rc ; - - size_t _nn = +0 ; + + size_t _nn = +0 ; data_type _tt[2] ; - if (polyroots(_aa, _bb, _cc, _tt)) + if ( math:: + polyroots(_aa, _bb, _cc, _tt)) { if (_tt[0] >= (data_type)+0. && _tt[0] <= (data_type)+1. ) { /*----------------------- compute 1st-root intersect. */ - data_type _WB = + data_type _WB = (data_type)+0.+_tt[0] ; - - data_type _WA = + + data_type _WA = (data_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 ; - + _PB[2] * _WB ; + if (_nn == 1) { _qa[0]=_QQ[0] ; @@ -309,34 +257,34 @@ } if (_tt[1] >= (data_type)+0. && _tt[1] <= (data_type)+1. ) - { + { /*----------------------- compute 2nd-root intersect. */ - data_type _WB = + data_type _WB = (data_type)+0.+_tt[1] ; - - data_type _WA = + + data_type _WA = (data_type)+1.-_tt[1] ; - + _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 ; - + _PB[2] * _WB ; + if (_nn == 1) { _qa[0]=_QQ[0] ; @@ -369,7 +317,7 @@ __const_ptr (data_type) _b0, // min. rect. B __const_ptr (data_type) _b1 // max. ) - { + { if (_pp[0] >= _b0[0] && _pp[0] <= _b1[0] && _pp[1] >= _b0[1] && @@ -391,7 +339,7 @@ __const_ptr (data_type) _b0, // min. rect. B __const_ptr (data_type) _b1 // max. ) - { + { if (_pp[0] >= _b0[0] && _pp[0] <= _b1[0] && _pp[1] >= _b0[1] && @@ -416,7 +364,7 @@ __const_ptr (data_type) _b0, // min. rect. B __const_ptr (data_type) _b1 // max. ) - { + { if (_a0[0] <= _b1[0] && _b0[0] <= _a1[0] && _a0[1] <= _b1[1] && @@ -439,7 +387,7 @@ __const_ptr (data_type) _b0, // min. rect. B __const_ptr (data_type) _b1 // max. ) - { + { if (_a0[0] <= _b1[0] && _b0[0] <= _a1[0] && _a0[1] <= _b1[1] && @@ -467,11 +415,11 @@ > __inline_call void copy_node_2d ( __write_ptr (data_one_) _pa, // copy: A := B - __const_ptr (data_two_) _pb + __const_ptr (data_two_) _pb ) { - _pa [0] = _pb [0] ; - _pa [1] = _pb [1] ; + _pa[0] = (data_one_) _pb[0] ; + _pa[1] = (data_one_) _pb[1] ; } template < @@ -480,12 +428,12 @@ > __inline_call void copy_node_3d ( __write_ptr (data_one_) _pa, // copy: A := B - __const_ptr (data_two_) _pb + __const_ptr (data_two_) _pb ) { - _pa [0] = _pb [0] ; - _pa [1] = _pb [1] ; - _pa [2] = _pb [2] ; + _pa[0] = (data_one_) _pb[0] ; + _pa[1] = (data_one_) _pb[1] ; + _pa[2] = (data_one_) _pb[2] ; } template < @@ -494,11 +442,11 @@ > __inline_call void copy_node_xy ( __write_ptr (data_one_) _pa, // copy: A := B - __const_ptr (data_two_) _pb + __const_ptr (data_two_) _pb ) { - _pa [0] = _pb [0] ; - _pa [1] = _pb [1] ; + _pa[0] = (data_one_) _pb[0] ; + _pa[1] = (data_one_) _pb[1] ; } template < @@ -507,11 +455,11 @@ > __inline_call void copy_node_yz ( __write_ptr (data_one_) _pa, // copy: A := B - __const_ptr (data_two_) _pb + __const_ptr (data_two_) _pb ) { - _pa [0] = _pb [1] ; - _pa [1] = _pb [2] ; + _pa[0] = (data_one_) _pb[1] ; + _pa[1] = (data_one_) _pb[2] ; } template < @@ -520,11 +468,11 @@ > __inline_call void copy_node_xz ( __write_ptr (data_one_) _pa, // copy: A := B - __const_ptr (data_two_) _pb + __const_ptr (data_two_) _pb ) { - _pa [0] = _pb [0] ; - _pa [1] = _pb [2] ; + _pa[0] = (data_one_) _pb[0] ; + _pa[1] = (data_one_) _pb[2] ; } /* @@ -558,7 +506,7 @@ _pp[1] == _pa[1] && _pp[2] == _pa[2] ) { - + _qq[0] = _pa[0] ; _qq[1] = _pa[1] ; _qq[2] = _pa[2] ; @@ -570,7 +518,7 @@ _pp[1] == _pb[1] && _pp[2] == _pb[2] ) { - + _qq[0] = _pb[0] ; _qq[1] = _pb[1] ; _qq[2] = _pb[2] ; @@ -590,19 +538,19 @@ _ap[1] = _pp[1] - _pa[1] ; _ap[2] = _pp[2] - _pa[2] ; - data_type _ep = + 1.0 * + data_type _ep = + 1.0 * std::numeric_limits::epsilon() ; - data_type _d1 = - geometry::dot_3d(_ap, _nv) ; - data_type _d2 = + data_type _d1 = + geometry::dot_3d(_ap, _nv) ; + data_type _d2 = geometry::dot_3d(_ab, _nv) ; if (std::abs(_d2) <= _ep * std::abs(_d1)) return ( false ) ; - + data_type _tt = _d1 / _d2 ; - + if (_bind) { if (_tt < (data_type)+0.) @@ -637,7 +585,7 @@ dd_flt _QQ[3] ; _QQ[0] = _pa[0] ; _QQ[1] = _pa[1] ; - _QQ[2] = _pa[2] ; + _QQ[2] = _pa[2] ; _QQ[0]+= _AB[0] * _tt ; _QQ[1]+= _AB[1] * _tt ; _QQ[2]+= _AB[2] * _tt ; @@ -672,20 +620,20 @@ ) { size_t _ni = +0; - + if (line_flat_3d ( - _pp, _nv, - _pa, _pb, + _pp, _nv, + _pa, _pb, (_ni == +0) ? _qa : _qb)) _ni += +1 ; if (line_flat_3d ( - _pp, _nv, - _pb, _pc, + _pp, _nv, + _pb, _pc, (_ni == +0) ? _qa : _qb)) _ni += +1 ; if (line_flat_3d ( - _pp, _nv, - _pc, _pa, + _pp, _nv, + _pc, _pa, (_ni == +0) ? _qa : _qb)) _ni += +1 ; @@ -708,26 +656,18 @@ real_type &_tt ) { - _tt = (real_type)+0.0 ; - - real_type _ap[2]; + real_type _ap[2] ; _ap[0] = _pp[0] - _pa[0] ; _ap[1] = _pp[1] - _pa[1] ; - - real_type _ep = +1.0 * - std::numeric_limits::epsilon(); - - real_type _d1 = + + real_type _d1 = geometry::dot_2d(_ap, _va) ; - real_type _d2 = + real_type _d2 = geometry::dot_2d(_va, _va) ; - - if (std::abs(_d2) <= _ep * std::abs(_d1) ) - return ( false ) ; _tt = _d1 / _d2 ; - - return ( true ) ; + + return ( true ) ; } template < @@ -745,7 +685,7 @@ _vv[0] = _pb[0] - _pa[0] ; _vv[1] = _pb[1] - _pa[1] ; - if (proj_line_2d(_pp, _pa, + if (proj_line_2d(_pp, _pa, _vv, _tt) ) { if (_tt <= (real_type)+0.) @@ -771,11 +711,11 @@ { _ht = edge_hits; - _qq[0] = + _qq[0] = _pa[0] + _tt*_vv[ 0] ; - _qq[1] = + _qq[1] = _pa[1] + _tt*_vv[ 1] ; - + return ( true ) ; } } @@ -795,27 +735,19 @@ real_type &_tt ) { - _tt = (real_type)+0.0 ; - - real_type _ap[3]; + real_type _ap[3] ; _ap[0] = _pp[0] - _pa[0] ; _ap[1] = _pp[1] - _pa[1] ; _ap[2] = _pp[2] - _pa[2] ; - - real_type _ep = +1.0 * - std::numeric_limits::epsilon(); - - real_type _d1 = + + real_type _d1 = geometry::dot_3d(_ap, _va) ; - real_type _d2 = + real_type _d2 = geometry::dot_3d(_va, _va) ; - - if (std::abs(_d2) <= _ep * std::abs(_d1) ) - return ( false ) ; _tt = _d1 / _d2 ; - - return ( true ) ; + + return ( true ) ; } template < @@ -834,7 +766,7 @@ _vv[1] = _pb[1] - _pa[1] ; _vv[2] = _pb[2] - _pa[2] ; - if (proj_line_3d(_pp, _pa, + if (proj_line_3d(_pp, _pa, _vv, _tt) ) { if (_tt <= (real_type)+0.) @@ -862,13 +794,13 @@ { _ht = edge_hits; - _qq[0] = + _qq[0] = _pa[0] + _tt*_vv[ 0] ; - _qq[1] = + _qq[1] = _pa[1] + _tt*_vv[ 1] ; - _qq[2] = + _qq[2] = _pa[2] + _tt*_vv[ 2] ; - + return ( true ) ; } } @@ -898,33 +830,23 @@ _ip[0] = _pp[0] - _pi[0] ; _ip[1] = _pp[1] - _pi[1] ; _ip[2] = _pp[2] - _pi[2] ; - - _qq[0] = _pi[0] ; - _qq[1] = _pi[1] ; - _qq[2] = _pi[2] ; - - real_type _ep = +1.0 * - std::numeric_limits::epsilon(); - + real_type _tt ; - real_type _d1 = + real_type _d1 = geometry::dot_3d(_ip, _nv) ; - real_type _d2 = + real_type _d2 = geometry::dot_3d(_nv, _nv) ; - - if (std::abs(_d2) <= _ep * std::abs(_d1) ) - return ( false ) ; _tt = _d1/_d2 ; - - _qq[0] = + + _qq[0] = _pi[0] + _tt * _nv[0] ; - _qq[1] = + _qq[1] = _pi[1] + _tt * _nv[1] ; - _qq[2] = + _qq[2] = _pi[2] + _tt * _nv[2] ; - - return ( true ) ; + + return ( true ) ; } template < @@ -961,7 +883,7 @@ /*----------------------- test node-tria intersection */ double _PA[2] ; copy_node_2d(_PA, _pa) ; - + double _PB[2] ; copy_node_2d(_PB, _pb) ; @@ -971,22 +893,22 @@ double _PP[2] ; copy_node_2d(_PP, _pp) ; - double _s1 = + double _s1 = geompred::orient2d ( - (double*)_PA , - (double*)_PB , + (double*)_PA , + (double*)_PB , (double*)_PP ) ; - double _s2 = + double _s2 = geompred::orient2d ( - (double*)_PB , - (double*)_PC , + (double*)_PB , + (double*)_PC , (double*)_PP ) ; - double _s3 = + double _s3 = geompred::orient2d ( - (double*)_PC , - (double*)_PA , + (double*)_PC , + (double*)_PA , (double*)_PP ) ; if (_s1 * _s2 < +0.0 || @@ -1005,7 +927,7 @@ __projface2d(_pa, _pb) ; __projface2d(_pb, _pc) ; __projface2d(_pc, _pa) ; - + return ( true ) ; } else @@ -1076,7 +998,7 @@ /*----------------------- get orientation in xy-plane */ double _TA[2] ; copy_node_xy(_TA, _pa) ; - + double _TB[2] ; copy_node_xy(_TB, _pb) ; @@ -1084,24 +1006,24 @@ copy_node_xy(_TC, _pc) ; double _TP[2] ; - copy_node_xy(_TP, _pp) ; + copy_node_xy(_TP, _pt) ; - _s1[0] = + _s1[0] = geompred::orient2d ( - (double*)_TA , - (double*)_TB , + (double*)_TA , + (double*)_TB , (double*)_TP ) ; - _s2[0] = + _s2[0] = geompred::orient2d ( - (double*)_TB , - (double*)_TC , + (double*)_TB , + (double*)_TC , (double*)_TP ) ; - _s3[0] = + _s3[0] = geompred::orient2d ( - (double*)_TC , - (double*)_TA , + (double*)_TC , + (double*)_TA , (double*)_TP ) ; } @@ -1109,7 +1031,7 @@ /*----------------------- get orientation in xz-plane */ double _TA[2] ; copy_node_xz(_TA, _pa) ; - + double _TB[2] ; copy_node_xz(_TB, _pb) ; @@ -1117,24 +1039,24 @@ copy_node_xz(_TC, _pc) ; double _TP[2] ; - copy_node_xz(_TP, _pp) ; + copy_node_xz(_TP, _pt) ; - _s1[1] = + _s1[1] = geompred::orient2d ( - (double*)_TA , - (double*)_TB , + (double*)_TA , + (double*)_TB , (double*)_TP ) ; - _s2[1] = + _s2[1] = geompred::orient2d ( - (double*)_TB , - (double*)_TC , + (double*)_TB , + (double*)_TC , (double*)_TP ) ; - _s3[1] = + _s3[1] = geompred::orient2d ( - (double*)_TC , - (double*)_TA , + (double*)_TC , + (double*)_TA , (double*)_TP ) ; } @@ -1142,7 +1064,7 @@ /*----------------------- get orientation in yz-plane */ double _TA[2] ; copy_node_yz(_TA, _pa) ; - + double _TB[2] ; copy_node_yz(_TB, _pb) ; @@ -1150,27 +1072,27 @@ copy_node_yz(_TC, _pc) ; double _TP[2] ; - copy_node_yz(_TP, _pp) ; + copy_node_yz(_TP, _pt) ; - _s1[2] = + _s1[2] = geompred::orient2d ( - (double*)_TA , - (double*)_TB , + (double*)_TA , + (double*)_TB , (double*)_TP ) ; - _s2[2] = + _s2[2] = geompred::orient2d ( - (double*)_TB , - (double*)_TC , + (double*)_TB , + (double*)_TC , (double*)_TP ) ; - _s3[2] = + _s3[2] = geompred::orient2d ( - (double*)_TC , - (double*)_TA , + (double*)_TC , + (double*)_TA , (double*)_TP ) ; } - + { /*----------------------- test node-tria intersection */ if ( @@ -1196,7 +1118,7 @@ __projface3d(_pa, _pb) ; __projface3d(_pb, _pc) ; __projface3d(_pc, _pa) ; - + return ( true ) ; } else @@ -1204,12 +1126,12 @@ _ht = face_hits ; - copy_node_3d(_qq, _pp) ; + copy_node_3d(_qq, _pt) ; return ( true ) ; } } - + # undef __projface3d } @@ -1249,7 +1171,7 @@ /*----------------------- test node-tria intersection */ double _PA[3] ; copy_node_3d(_PA, _pa) ; - + double _PB[3] ; copy_node_3d(_PB, _pb) ; @@ -1262,32 +1184,32 @@ double _PP[3] ; copy_node_3d(_PP, _pp) ; - double _s1 = + double _s1 = geompred::orient3d ( - (double*)_PB , + (double*)_PB , (double*)_PD , - (double*)_PC , + (double*)_PC , (double*)_PP ) ; - double _s2 = + double _s2 = geompred::orient3d ( - (double*)_PC , + (double*)_PC , (double*)_PD , - (double*)_PA , + (double*)_PA , (double*)_PP ) ; - double _s3 = + double _s3 = geompred::orient3d ( - (double*)_PA , + (double*)_PA , (double*)_PD , - (double*)_PB , + (double*)_PB , (double*)_PP ) ; - double _s4 = + double _s4 = geompred::orient3d ( - (double*)_PA , + (double*)_PA , (double*)_PB , - (double*)_PC , + (double*)_PC , (double*)_PP ) ; if (_s1 * _s2 < +0.0 || @@ -1314,14 +1236,14 @@ _pa, _pd, _pb) ; __projface3d( _pa, _pb, _pc) ; - + return ( true ) ; } else { _ht = tria_hits ; - + copy_node_3d(_qq, _pp) ; return ( true ) ; @@ -1345,14 +1267,14 @@ { double _ab[2] ; _ab[0] = _pb[0]-_pa[0] ; - _ab[1] = _pb[1]-_pa[1] ; + _ab[1] = _pb[1]-_pa[1] ; double _ap[2] ; _ap[0] = _pp[0]-_pa[0] ; _ap[1] = _pp[1]-_pa[1] ; - double _dp = - _ab[0] * _ap[0] + + double _dp = + _ab[0] * _ap[0] + _ab[1] * _ap[1] ; return _dp ; @@ -1374,7 +1296,7 @@ _ap[1] = _pp[1]-_pa[1] ; _ap[2] = _pp[2]-_pa[2] ; - double _dp = + double _dp = _ab[0] * _ap[0] + _ab[1] * _ap[1] + _ab[2] * _ap[2] ; @@ -1462,7 +1384,7 @@ _pa[1] == _pb[1] ) { /*----------------------- test node-node intersection */ - return + return node_node_2d(_pa, _pp, _qq); } else @@ -1480,23 +1402,23 @@ _PP[0] = _pp[0] ; _PP[1] = _pp[1] ; - double _ss = + double _ss = geompred::orient2d ( - (double*)_PA , - (double*)_PB , + (double*)_PA , + (double*)_PB , (double*)_PP ) ; if (_ss == +0.0) { /*----------------------- orient w.r.t. line endpoint */ double _sa = cleave2d ( - (double*)_PA , - (double*)_PB , + (double*)_PA , + (double*)_PB , (double*)_PP ) ; double _sb = cleave2d ( - (double*)_PB , - (double*)_PA , + (double*)_PB , + (double*)_PA , (double*)_PP ) ; if (_sa*_sb > +0.0) @@ -1510,7 +1432,7 @@ else if (_sa == +0.0) { - /*----------------------- have node-node intersection */ + /*----------------------- have node-node intersection */ _qq[0] = _pa[0] ; _qq[1] = _pa[1] ; @@ -1519,7 +1441,7 @@ else if (_sb == +0.0) { - /*----------------------- have node-node intersection */ + /*----------------------- have node-node intersection */ _qq[0] = _pb[0] ; _qq[1] = _pb[1] ; @@ -1565,7 +1487,7 @@ _pa[2] == _pb[2] ) { /*----------------------- test node-node intersection */ - return + return node_node_3d(_pa, _pp, _qq); } else @@ -1599,10 +1521,10 @@ _P1[0] = _PP[0] ; _P1[1] = _PP[1] ; - double _s1 = + double _s1 = geompred::orient2d ( - (double*)_A1 , - (double*)_B1 , + (double*)_A1 , + (double*)_B1 , (double*)_P1 ) ; /*----------------------- get orientation in xz-plane */ @@ -1618,10 +1540,10 @@ _P2[0] = _PP[0] ; _P2[1] = _PP[2] ; - double _s2 = + double _s2 = geompred::orient2d ( - (double*)_A2 , - (double*)_B2 , + (double*)_A2 , + (double*)_B2 , (double*)_P2 ) ; /*----------------------- get orientation in yz-plane */ @@ -1637,10 +1559,10 @@ _P3[0] = _PP[1] ; _P3[1] = _PP[2] ; - double _s3 = + double _s3 = geompred::orient2d ( - (double*)_A3 , - (double*)_B3 , + (double*)_A3 , + (double*)_B3 , (double*)_P3 ) ; /*----------------------- test intersection hierarchy */ @@ -1650,13 +1572,13 @@ { /*----------------------- orient w.r.t. line endpoint */ double _sa = cleave3d ( - (double*)_PA , - (double*)_PB , + (double*)_PA , + (double*)_PB , (double*)_PP ) ; double _sb = cleave3d ( - (double*)_PB , - (double*)_PA , + (double*)_PB , + (double*)_PA , (double*)_PP ) ; if (_sa*_sb > +0.0) @@ -1671,7 +1593,7 @@ else if (_sa == +0.0) { - /*----------------------- have node-node intersection */ + /*----------------------- have node-node intersection */ _qq[0] = _pa[0] ; _qq[1] = _pa[1] ; _qq[2] = _pa[2] ; @@ -1681,7 +1603,7 @@ else if (_sb == +0.0) { - /*----------------------- have node-node intersection */ + /*----------------------- have node-node intersection */ _qq[0] = _pb[0] ; _qq[1] = _pb[1] ; _qq[2] = _pb[2] ; @@ -1767,41 +1689,41 @@ _PD[1] = _pd[1] ; /*----------------------- orient w.r.t. line endpoint */ - double _sa = + double _sa = geompred::orient2d ( - (double*)_PA , - (double*)_PC , + (double*)_PA , + (double*)_PC , (double*)_PD ) ; - double _sb = + double _sb = geompred::orient2d ( - (double*)_PB , - (double*)_PD , + (double*)_PB , + (double*)_PD , (double*)_PC ) ; if (_bind) { /*----------------------- no intersections: null hits */ - if (_sa * _sb < +0.0 ) + if (_sa * _sb < +0.0 ) return null_hits; } - double _sc = + double _sc = geompred::orient2d ( - (double*)_PC , - (double*)_PA , + (double*)_PC , + (double*)_PA , (double*)_PB ) ; - - double _sd = + + double _sd = geompred::orient2d ( - (double*)_PD , - (double*)_PB , + (double*)_PD , + (double*)_PB , (double*)_PA ) ; if (_bind) { /*----------------------- no intersections: null hits */ - if (_sc * _sd < +0.0 ) + if (_sc * _sd < +0.0 ) return null_hits; } @@ -1821,7 +1743,7 @@ /*----------------------- have node-line intersection */ _qq[0] = _pa[0] ; _qq[1] = _pa[1] ; - + return node_hits ; } else @@ -1830,7 +1752,7 @@ /*----------------------- have node-line intersection */ _qq[0] = _pb[0] ; _qq[1] = _pb[1] ; - + return node_hits ; } else @@ -1839,7 +1761,7 @@ /*----------------------- have node-line intersection */ _qq[0] = _pc[0] ; _qq[1] = _pc[1] ; - + return node_hits ; } else @@ -1848,7 +1770,7 @@ /*----------------------- have node-line intersection */ _qq[0] = _pd[0] ; _qq[1] = _pd[1] ; - + return node_hits ; } else @@ -1861,7 +1783,8 @@ _mm[__ij(1,1,2)] = _PC[1]-_PD[1] ; double _im [2*2] , _dm; - inv_2x2(2, _mm, 2, _im, _dm) ; + math::inv_2x2( + +2, _mm, +2, _im, _dm) ; double _rv [2*1] ; _rv[__ij(0,0,2)] = _PC[0]-_PA[0] ; @@ -1870,21 +1793,21 @@ if (_dm == +0.0) return null_hits ; - double _tu = - _im[__ij(0,0,2)] * _rv [0] + + double _tu = + _im[__ij(0,0,2)] * _rv [0] + _im[__ij(0,1,2)] * _rv [1] ; - double _tv = - _im[__ij(1,0,2)] * _rv [0] + + double _tv = + _im[__ij(1,0,2)] * _rv [0] + _im[__ij(1,1,2)] * _rv [1] ; - _tu /= _dm ; + _tu /= _dm ; _tv /= _dm ; if (_bind) { - _tu = + _tu = std::min(+1.,std::max(+0., _tu)) ; - _tv = + _tv = std::min(+1.,std::max(+0., _tv)) ; } @@ -1937,7 +1860,7 @@ } else { - __assert( false && + __assert( false && "line_line_2d: invalid part!!") ; } @@ -2075,22 +1998,22 @@ _P3[1] = _p3[1] ; /*----------------------- orient w.r.t. tria vertices */ - double _s3 = + double _s3 = geompred::orient2d ( - (double*)_P1 , - (double*)_P2 , + (double*)_P1 , + (double*)_P2 , (double*)_PP ) ; - double _s1 = + double _s1 = geompred::orient2d ( - (double*)_P2 , - (double*)_P3 , + (double*)_P2 , + (double*)_P3 , (double*)_PP ) ; - double _s2 = + double _s2 = geompred::orient2d ( - (double*)_P3 , - (double*)_P1 , + (double*)_P3 , + (double*)_P1 , (double*)_PP ) ; /*----------------------- test intersection hierarchy */ @@ -2242,11 +2165,11 @@ _P3[1] = _p3[1] ; _P3[2] = _p3[2] ; - double _ss = + double _ss = geompred::orient3d ( - (double*)_P1 , - (double*)_P2 , - (double*)_P3 , + (double*)_P1 , + (double*)_P2 , + (double*)_P3 , (double*)_PP ) ; if (_ss == +0.0) @@ -2267,27 +2190,27 @@ double _T3[2] ; _T3[0] = _P3[0] ; _T3[1] = _P3[1] ; - + double _s3[3] ; _s3[0] = geompred::orient2d ( - (double*)_T1 , - (double*)_T2 , + (double*)_T1 , + (double*)_T2 , (double*)_TP ) ; double _s1[3] ; _s1[0] = geompred::orient2d ( - (double*)_T2 , - (double*)_T3 , + (double*)_T2 , + (double*)_T3 , (double*)_TP ) ; double _s2[3] ; _s2[0] = geompred::orient2d ( - (double*)_T3 , - (double*)_T1 , + (double*)_T3 , + (double*)_T1 , (double*)_TP ) ; - if (_s1[0]*_s2[0] < +0.0 || - _s2[0]*_s3[0] < +0.0 || + if (_s1[0]*_s2[0] < +0.0 || + _s2[0]*_s3[0] < +0.0 || _s3[0]*_s1[0] < +0.0 ) { /*----------------------- no intersections: null hits */ @@ -2306,24 +2229,24 @@ _T3[0] = _P3[0] ; _T3[1] = _P3[2] ; - + _s3[1] = geompred::orient2d ( - (double*)_T1 , - (double*)_T2 , + (double*)_T1 , + (double*)_T2 , (double*)_TP ) ; _s1[1] = geompred::orient2d ( - (double*)_T2 , - (double*)_T3 , + (double*)_T2 , + (double*)_T3 , (double*)_TP ) ; _s2[1] = geompred::orient2d ( - (double*)_T3 , - (double*)_T1 , + (double*)_T3 , + (double*)_T1 , (double*)_TP ) ; - if (_s1[1]*_s2[1] < +0.0 || - _s2[1]*_s3[1] < +0.0 || + if (_s1[1]*_s2[1] < +0.0 || + _s2[1]*_s3[1] < +0.0 || _s3[1]*_s1[1] < +0.0 ) { /*----------------------- no intersections: null hits */ @@ -2342,24 +2265,24 @@ _T3[0] = _P3[1] ; _T3[1] = _P3[2] ; - + _s3[2] = geompred::orient2d ( - (double*)_T1 , - (double*)_T2 , + (double*)_T1 , + (double*)_T2 , (double*)_TP ) ; _s1[2] = geompred::orient2d ( - (double*)_T2 , - (double*)_T3 , + (double*)_T2 , + (double*)_T3 , (double*)_TP ) ; _s2[2] = geompred::orient2d ( - (double*)_T3 , - (double*)_T1 , + (double*)_T3 , + (double*)_T1 , (double*)_TP ) ; - if (_s1[2]*_s2[2] < +0.0 || - _s2[2]*_s3[2] < +0.0 || + if (_s1[2]*_s2[2] < +0.0 || + _s2[2]*_s3[2] < +0.0 || _s3[2]*_s1[2] < +0.0 ) { /*----------------------- no intersections: null hits */ @@ -2367,17 +2290,17 @@ } /*----------------------- test intersection hierarchy */ - bool_type _z1 = + bool_type _z1 = _s1[0] == +0.0 && _s1[1] == +0.0 && _s1[2] == +0.0 ; - bool_type _z2 = + bool_type _z2 = _s2[0] == +0.0 && _s2[1] == +0.0 && _s2[2] == +0.0 ; - bool_type _z3 = + bool_type _z3 = _s3[0] == +0.0 && _s3[1] == +0.0 && _s3[2] == +0.0 ; @@ -2557,18 +2480,18 @@ _P3[2] = _p3[2] ; /*----------------------- test if line straddles tria */ - double _sa = + double _sa = geompred::orient3d ( - (double*)_P1 , - (double*)_P2 , - (double*)_P3 , + (double*)_P1 , + (double*)_P2 , + (double*)_P3 , (double*)_PA ) ; - - double _sb = + + double _sb = geompred::orient3d ( - (double*)_P1 , - (double*)_P3 , - (double*)_P2 , + (double*)_P1 , + (double*)_P3 , + (double*)_P2 , (double*)_PB ) ; if (_bind) @@ -2579,25 +2502,25 @@ } /*----------------------- test if tria straddles line */ - double _s1 = + double _s1 = geompred::orient3d ( - (double*)_P1 , + (double*)_P1 , (double*)_P2 , - (double*)_PA , + (double*)_PA , (double*)_PB ) ; - double _s2 = + double _s2 = geompred::orient3d ( - (double*)_P2 , + (double*)_P2 , (double*)_P3 , - (double*)_PA , + (double*)_PA , (double*)_PB ) ; - - double _s3 = + + double _s3 = geompred::orient3d ( - (double*)_P3 , + (double*)_P3 , (double*)_P1 , - (double*)_PA , + (double*)_PA , (double*)_PB ) ; if (_bind) @@ -2608,7 +2531,7 @@ if (_s2*_s3 < 0.0) return null_hits ; - + if (_s3*_s1 < 0.0) return null_hits ; } @@ -2659,11 +2582,11 @@ else if (_s1 == +0.0 ) { - /*----------------------- have line-edge intersection */ + /*----------------------- have line-edge intersection */ double _WS = _s2 + _s3 ; double _W1 = _s2 / _WS ; double _W2 = _s3 / _WS ; - + dd_flt _F1[3] ; _F1[0] = _p1[0] ; _F1[1] = _p1[1] ; @@ -2691,11 +2614,11 @@ else if (_s2 == +0.0 ) { - /*----------------------- have line-edge intersection */ + /*----------------------- have line-edge intersection */ double _WS = _s1 + _s3 ; double _W2 = _s3 / _WS ; double _W3 = _s1 / _WS ; - + dd_flt _F2[3] ; _F2[0] = _p2[0] ; _F2[1] = _p2[1] ; @@ -2723,11 +2646,11 @@ else if (_s3 == +0.0 ) { - /*----------------------- have line-edge intersection */ + /*----------------------- have line-edge intersection */ double _WS = _s1 + _s2 ; double _W3 = _s1 / _WS ; double _W1 = _s2 / _WS ; - + dd_flt _F3[3] ; _F3[0] = _p3[0] ; _F3[1] = _p3[1] ; @@ -2754,12 +2677,12 @@ } else { - /*----------------------- have line-face intersection */ + /*----------------------- have line-face intersection */ double _WS = _s1 + _s2 + _s3 ; double _W1 = _s2 / _WS ; double _W2 = _s3 / _WS ; double _W3 = _s1 / _WS ; - + dd_flt _F1[3] ; _F1[0] = _p1[0] ; _F1[1] = _p1[1] ; diff --git a/src/libcpp/geom_base/matrix_util.hpp b/src/libcpp/geom_base/matrix_util.hpp deleted file mode 100644 index 5dbcd53..0000000 --- a/src/libcpp/geom_base/matrix_util.hpp +++ /dev/null @@ -1,202 +0,0 @@ - - /* - -------------------------------------------------------- - * MATRIX-UTIL: (small) matrix utilities. - -------------------------------------------------------- - * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) - * - * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The - * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be - * used at your own risk. - * - -------------------------------------------------------- - * - * Last updated: 07 January, 2019 - * - * Copyright 2013-2019 - * Darren Engwirda - * de2363@columbia.edu - * https://github.com/dengwirda/ - * - -------------------------------------------------------- - */ - -# pragma once - -# ifndef __MATRIX_UTIL__ -# define __MATRIX_UTIL__ - - namespace geometry - { - - /* - -------------------------------------------------------- - * small matrix utilities. - -------------------------------------------------------- - */ - -# define __ij(__ir , __ic , __nr) \ - ((__ir)+(__ic)*(__nr)) - - template < - typename real_type, - typename size_type - > - __inline_call real_type det_2x2 ( - size_type _la, - __const_ptr (real_type) _aa - ) - { return - _aa[__ij(0,0,_la)] * - _aa[__ij(1,1,_la)] - - _aa[__ij(0,1,_la)] * - _aa[__ij(1,0,_la)] ; - } - - template < - typename real_type, - typename size_type - > - __inline_call real_type det_3x3 ( - size_type _la, - __const_ptr (real_type) _aa - ) - { return - _aa[__ij(0,0,_la)] * ( - _aa[__ij(1,1,_la)] * - _aa[__ij(2,2,_la)] - - _aa[__ij(1,2,_la)] * - _aa[__ij(2,1,_la)] ) - - - _aa[__ij(0,1,_la)] * ( - _aa[__ij(1,0,_la)] * - _aa[__ij(2,2,_la)] - - _aa[__ij(1,2,_la)] * - _aa[__ij(2,0,_la)] ) + - - _aa[__ij(0,2,_la)] * ( - _aa[__ij(1,0,_la)] * - _aa[__ij(2,1,_la)] - - _aa[__ij(1,1,_la)] * - _aa[__ij(2,0,_la)] ) ; - } - - template < - typename real_type, - typename size_type - > - __inline_call void_type inv_2x2 ( - size_type _la, - __const_ptr (real_type) _aa, - size_type _lx, - __write_ptr (real_type) _xx, - real_type &_da - ) - { - _da = det_2x2(_la, _aa) ; - - _xx[__ij(0,0,_lx)] = - _aa[__ij(1,1,_la)] ; - _xx[__ij(1,1,_lx)] = - _aa[__ij(0,0,_la)] ; - _xx[__ij(0,1,_lx)] = - -_aa[__ij(0,1,_la)] ; - _xx[__ij(1,0,_lx)] = - -_aa[__ij(1,0,_la)] ; - } - - template < - typename real_type, - typename size_type - > - __inline_call void_type inv_3x3 ( - size_type _la, - __const_ptr (real_type) _aa, - size_type _lx, - __write_ptr (real_type) _xx, - real_type &_da - ) - { - _da = det_3x3(_la, _aa) ; - - _xx[__ij(0,0,_lx)] = - _aa[__ij(2,2,_la)] * - _aa[__ij(1,1,_la)] - - _aa[__ij(2,1,_la)] * - _aa[__ij(1,2,_la)] ; - - _xx[__ij(0,1,_lx)] = - _aa[__ij(2,1,_la)] * - _aa[__ij(0,2,_la)] - - _aa[__ij(2,2,_la)] * - _aa[__ij(0,1,_la)] ; - - _xx[__ij(0,2,_lx)] = - _aa[__ij(1,2,_la)] * - _aa[__ij(0,1,_la)] - - _aa[__ij(1,1,_la)] * - _aa[__ij(0,2,_la)] ; - - _xx[__ij(1,0,_lx)] = - _aa[__ij(2,0,_la)] * - _aa[__ij(1,2,_la)] - - _aa[__ij(2,2,_la)] * - _aa[__ij(1,0,_la)] ; - - _xx[__ij(1,1,_lx)] = - _aa[__ij(2,2,_la)] * - _aa[__ij(0,0,_la)] - - _aa[__ij(2,0,_la)] * - _aa[__ij(0,2,_la)] ; - - _xx[__ij(1,2,_lx)] = - _aa[__ij(1,0,_la)] * - _aa[__ij(0,2,_la)] - - _aa[__ij(1,2,_la)] * - _aa[__ij(0,0,_la)] ; - - _xx[__ij(2,0,_lx)] = - _aa[__ij(2,1,_la)] * - _aa[__ij(1,0,_la)] - - _aa[__ij(2,0,_la)] * - _aa[__ij(1,1,_la)] ; - - _xx[__ij(2,1,_lx)] = - _aa[__ij(2,0,_la)] * - _aa[__ij(0,1,_la)] - - _aa[__ij(2,1,_la)] * - _aa[__ij(0,0,_la)] ; - - _xx[__ij(2,2,_lx)] = - _aa[__ij(1,1,_la)] * - _aa[__ij(0,0,_la)] - - _aa[__ij(1,0,_la)] * - _aa[__ij(0,1,_la)] ; - } - - - } - -# endif//__MATRIX_UTIL__ - - diff --git a/src/libcpp/geom_base/predicate_k.hpp b/src/libcpp/geom_base/predicate_k.hpp index 4f16982..3423723 100644 --- a/src/libcpp/geom_base/predicate_k.hpp +++ b/src/libcpp/geom_base/predicate_k.hpp @@ -1,3818 +1,3818 @@ -/*****************************************************************************/ -/* */ -/* Routines for Arbitrary Precision Floating-point Arithmetic */ -/* and Fast Robust Geometric Predicates */ -/* (predicates.c) */ -/* */ -/* May 18, 1996 */ -/* */ -/* Placed in the public domain by */ -/* Jonathan Richard Shewchuk */ -/* School of Computer Science */ -/* Carnegie Mellon University */ -/* 5000 Forbes Avenue */ -/* Pittsburgh, Pennsylvania 15213-3891 */ -/* jrs@cs.cmu.edu */ -/* */ -/* This file contains C implementation of algorithms for exact addition */ -/* and multiplication of floating-point numbers, and predicates for */ -/* robustly performing the orientation and incircle tests used in */ -/* computational geometry. The algorithms and underlying theory are */ -/* described in Jonathan Richard Shewchuk. "Adaptive Precision Floating- */ -/* Point Arithmetic and Fast Robust Geometric Predicates." Technical */ -/* Report CMU-CS-96-140, School of Computer Science, Carnegie Mellon */ -/* University, Pittsburgh, Pennsylvania, May 1996. (Submitted to */ -/* Discrete & Computational Geometry.) */ -/* */ -/* This file, the paper listed above, and other information are available */ -/* from the Web page http://www.cs.cmu.edu/~quake/robust.html . */ -/* */ -/*****************************************************************************/ - -/*****************************************************************************/ -/* */ -/* Using this code: */ -/* */ -/* First, read the short or long version of the paper (from the Web page */ -/* above). */ -/* */ -/* Be sure to call exactinit() once, before calling any of the arithmetic */ -/* functions or geometric predicates. Also be sure to turn on the */ -/* optimizer when compiling this file. */ -/* */ -/* */ -/* Several geometric predicates are defined. Their parameters are all */ -/* points. Each point is an array of two, three or four floating-point */ -/* numbers. The geometric predicates, described in the papers, are */ -/* */ -/* orient2d(pa, pb, pc) */ -/* orient3d(pa, pb, pc, pd) */ -/* orient4d(pa, pb, pc, pd, pe) */ -/* incircle(pa, pb, pc, pd) */ -/* insphere(pa, pb, pc, pd, pe) */ -/* regular2(pa, pb, pc, pd) */ -/* regular3(pa, pb, pc, pd, pe) */ -/* */ -/* */ -/* An expansion is represented by an array of floating-point numbers, */ -/* sorted from smallest to largest magnitude (possibly with interspersed */ -/* zeros). The length of each expansion is stored as a separate integer, */ -/* and each arithmetic function returns an integer which is the length */ -/* of the expansion it created. */ -/* */ -/* Several arithmetic functions are defined. Their parameters are */ -/* */ -/* e, f Input expansions */ -/* elen, flen Lengths of input expansions (must be >= 1) */ -/* h Output expansion */ -/* b Input scalar */ -/* */ -/* The arithmetic functions are */ -/* */ -/* grow_expansion(elen, e, b, h) */ -/* grow_expansion_zeroelim(elen, e, b, h) */ -/* expansion_sum(elen, e, flen, f, h) */ -/* expansion_sum_zeroelim1(elen, e, flen, f, h) */ -/* expansion_sum_zeroelim2(elen, e, flen, f, h) */ -/* fast_expansion_sum(elen, e, flen, f, h) */ -/* fast_expansion_sum_zeroelim(elen, e, flen, f, h) */ -/* linear_expansion_sum(elen, e, flen, f, h) */ -/* linear_expansion_sum_zeroelim(elen, e, flen, f, h) */ -/* scale_expansion(elen, e, b, h) */ -/* scale_expansion_zeroelim(elen, e, b, h) */ -/* compress(elen, e, h) */ -/* */ -/* All of these are described in the long version of the paper; some are */ -/* described in the short version. All return an integer that is the */ -/* length of h. Those with suffix _zeroelim perform zero elimination, */ -/* and are recommended over their counterparts. The procedure */ -/* fast_expansion_sum_zeroelim() (or linear_expansion_sum_zeroelim() on */ -/* processors that do not use the round-to-even tiebreaking rule) is */ -/* recommended over expansion_sum_zeroelim(). Each procedure has a */ -/* little note next to it (in the code below) that tells you whether or */ -/* not the output expansion may be the same array as one of the input */ -/* expansions. */ -/* */ -/* */ -/* If you look around below, you'll also find macros for a bunch of */ -/* simple unrolled arithmetic operations, and procedures for printing */ -/* expansions (commented out because they don't work with all C */ -/* compilers) and for generating random floating-point numbers whose */ -/* significand bits are all random. Most of the macros have undocumented */ -/* requirements that certain of their parameters should not be the same */ -/* variable; for safety, better to make sure all the parameters are */ -/* distinct variables. Feel free to send email to jrs@cs.cmu.edu if you */ -/* have questions. */ -/* */ -/*****************************************************************************/ - -#pragma once - -#ifndef __GEOMPRED__ -#define __GEOMPRED__ - -#include -#include -#include - -namespace geompred -{ - -#define REAL double /* float or double */ - -/* Which of the following two methods of finding the absolute values is */ -/* fastest is compiler-dependent. A few compilers can inline and optimize */ -/* the fabs() call; but most will incur the overhead of a function call, */ -/* which is disastrously slow. A faster way on IEEE machines might be to */ -/* mask the appropriate bit, but that's difficult to do in C. */ - -#define Absolute(a) ((a) >= 0.0 ? (a) : -(a)) - -/* Many of the operations are broken up into two pieces, a main part that */ -/* performs an approximate operation, and a "tail" that computes the */ -/* roundoff error of that operation. */ -/* */ -/* The operations Fast_Two_Sum(), Fast_Two_Diff(), Two_Sum(), Two_Diff(), */ -/* Split(), and Two_Product() are all implemented as described in the */ -/* reference. Each of these macros requires certain variables to be */ -/* defined in the calling routine. The variables `bvirt', `c', `abig', */ -/* `_i', `_j', `_k', `_l', `_m', and `_n' are declared `INEXACT' because */ -/* they store the result of an operation that may incur roundoff error. */ -/* The input parameter `x' (or the highest numbered `x_' parameter) must */ -/* also be declared `INEXACT'. */ - -#define Fast_Two_Sum_Tail(a, b, x, y) \ - bvirt = x - a; \ - y = b - bvirt - -#define Fast_Two_Sum(a, b, x, y) \ - x = (REAL) (a + b); \ - Fast_Two_Sum_Tail(a, b, x, y) - -#define Fast_Two_Diff_Tail(a, b, x, y) \ - bvirt = a - x; \ - y = bvirt - b - -#define Fast_Two_Diff(a, b, x, y) \ - x = (REAL) (a - b); \ - Fast_Two_Diff_Tail(a, b, x, y) - -#define Two_Sum_Tail(a, b, x, y) \ - bvirt = (REAL) (x - a); \ - avirt = x - bvirt; \ - bround = b - bvirt; \ - around = a - avirt; \ - y = around + bround - -#define Two_Sum(a, b, x, y) \ - x = (REAL) (a + b); \ - Two_Sum_Tail(a, b, x, y) - -#define Two_Diff_Tail(a, b, x, y) \ - bvirt = (REAL) (a - x); \ - avirt = x + bvirt; \ - bround = bvirt - b; \ - around = a - avirt; \ - y = around + bround - -#define Two_Diff(a, b, x, y) \ - x = (REAL) (a - b); \ - Two_Diff_Tail(a, b, x, y) - -#define Split(a, ahi, alo) \ - c = (REAL) (splitter * a); \ - abig = (REAL) (c - a); \ - ahi = c - abig; \ - alo = a - ahi - -#define Two_Product_Tail(a, b, x, y) \ - Split(a, ahi, alo); \ - Split(b, bhi, blo); \ - err1 = x - (ahi * bhi); \ - err2 = err1 - (alo * bhi); \ - err3 = err2 - (ahi * blo); \ - y = (alo * blo) - err3 - -#define Two_Product(a, b, x, y) \ - x = (REAL) (a * b); \ - Two_Product_Tail(a, b, x, y) - -/* Two_Product_Presplit() is Two_Product() where one of the inputs has */ -/* already been split. Avoids redundant splitting. */ - -#define Two_Product_Presplit(a, b, bhi, blo, x, y) \ - x = (REAL) (a * b); \ - Split(a, ahi, alo); \ - err1 = x - (ahi * bhi); \ - err2 = err1 - (alo * bhi); \ - err3 = err2 - (ahi * blo); \ - y = (alo * blo) - err3 - -/* Two_Product_2Presplit() is Two_Product() where both of the inputs have */ -/* already been split. Avoids redundant splitting. */ - -#define Two_Product_2Presplit(a, ahi, alo, b, bhi, blo, x, y) \ - x = (REAL) (a * b); \ - err1 = x - (ahi * bhi); \ - err2 = err1 - (alo * bhi); \ - err3 = err2 - (ahi * blo); \ - y = (alo * blo) - err3 - -/* Square() can be done more quickly than Two_Product(). */ - -#define Square_Tail(a, x, y) \ - Split(a, ahi, alo); \ - err1 = x - (ahi * ahi); \ - err3 = err1 - ((ahi + ahi) * alo); \ - y = (alo * alo) - err3 - -#define Square(a, x, y) \ - x = (REAL) (a * a); \ - Square_Tail(a, x, y) - -/* Macros for summing expansions of various fixed lengths. These are all */ -/* unrolled versions of Expansion_Sum(). */ - -#define Two_One_Sum(a1, a0, b, x2, x1, x0) \ - Two_Sum(a0, b , _i, x0); \ - Two_Sum(a1, _i, x2, x1) - -#define Two_One_Diff(a1, a0, b, x2, x1, x0) \ - Two_Diff(a0, b , _i, x0); \ - Two_Sum( a1, _i, x2, x1) - -#define Two_Two_Sum(a1, a0, b1, b0, x3, x2, x1, x0) \ - Two_One_Sum(a1, a0, b0, _j, _0, x0); \ - Two_One_Sum(_j, _0, b1, x3, x2, x1) - -#define Two_Two_Diff(a1, a0, b1, b0, x3, x2, x1, x0) \ - Two_One_Diff(a1, a0, b0, _j, _0, x0); \ - Two_One_Diff(_j, _0, b1, x3, x2, x1) - -#define Four_One_Sum(a3, a2, a1, a0, b, x4, x3, x2, x1, x0) \ - Two_One_Sum(a1, a0, b , _j, x1, x0); \ - Two_One_Sum(a3, a2, _j, x4, x3, x2) - -#define Four_Two_Sum(a3, a2, a1, a0, b1, b0, x5, x4, x3, x2, x1, x0) \ - Four_One_Sum(a3, a2, a1, a0, b0, _k, _2, _1, _0, x0); \ - Four_One_Sum(_k, _2, _1, _0, b1, x5, x4, x3, x2, x1) - -#define Four_Four_Sum(a3, a2, a1, a0, b4, b3, b1, b0, x7, x6, x5, x4, x3, x2, \ - x1, x0) \ - Four_Two_Sum(a3, a2, a1, a0, b1, b0, _l, _2, _1, _0, x1, x0); \ - Four_Two_Sum(_l, _2, _1, _0, b4, b3, x7, x6, x5, x4, x3, x2) - -#define Eight_One_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b, x8, x7, x6, x5, x4, \ - x3, x2, x1, x0) \ - Four_One_Sum(a3, a2, a1, a0, b , _j, x3, x2, x1, x0); \ - Four_One_Sum(a7, a6, a5, a4, _j, x8, x7, x6, x5, x4) - -#define Eight_Two_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b1, b0, x9, x8, x7, \ - x6, x5, x4, x3, x2, x1, x0) \ - Eight_One_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b0, _k, _6, _5, _4, _3, _2, \ - _1, _0, x0); \ - Eight_One_Sum(_k, _6, _5, _4, _3, _2, _1, _0, b1, x9, x8, x7, x6, x5, x4, \ - x3, x2, x1) - -#define Eight_Four_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b4, b3, b1, b0, x11, \ - x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, x0) \ - Eight_Two_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b1, b0, _l, _6, _5, _4, _3, \ - _2, _1, _0, x1, x0); \ - Eight_Two_Sum(_l, _6, _5, _4, _3, _2, _1, _0, b4, b3, x11, x10, x9, x8, \ - x7, x6, x5, x4, x3, x2) - -/* Macros for multiplying expansions of various fixed lengths. */ - -#define Two_One_Product(a1, a0, b, x3, x2, x1, x0) \ - Split(b, bhi, blo); \ - Two_Product_Presplit(a0, b, bhi, blo, _i, x0); \ - Two_Product_Presplit(a1, b, bhi, blo, _j, _0); \ - Two_Sum(_i, _0, _k, x1); \ - Fast_Two_Sum(_j, _k, x3, x2) - -#define Four_One_Product(a3, a2, a1, a0, b, x7, x6, x5, x4, x3, x2, x1, x0) \ - Split(b, bhi, blo); \ - Two_Product_Presplit(a0, b, bhi, blo, _i, x0); \ - Two_Product_Presplit(a1, b, bhi, blo, _j, _0); \ - Two_Sum(_i, _0, _k, x1); \ - Fast_Two_Sum(_j, _k, _i, x2); \ - Two_Product_Presplit(a2, b, bhi, blo, _j, _0); \ - Two_Sum(_i, _0, _k, x3); \ - Fast_Two_Sum(_j, _k, _i, x4); \ - Two_Product_Presplit(a3, b, bhi, blo, _j, _0); \ - Two_Sum(_i, _0, _k, x5); \ - Fast_Two_Sum(_j, _k, x7, x6) - -#define Two_Two_Product(a1, a0, b1, b0, x7, x6, x5, x4, x3, x2, x1, x0) \ - Split(a0, a0hi, a0lo); \ - Split(b0, bhi, blo); \ - Two_Product_2Presplit(a0, a0hi, a0lo, b0, bhi, blo, _i, x0); \ - Split(a1, a1hi, a1lo); \ - Two_Product_2Presplit(a1, a1hi, a1lo, b0, bhi, blo, _j, _0); \ - Two_Sum(_i, _0, _k, _1); \ - Fast_Two_Sum(_j, _k, _l, _2); \ - Split(b1, bhi, blo); \ - Two_Product_2Presplit(a0, a0hi, a0lo, b1, bhi, blo, _i, _0); \ - Two_Sum(_1, _0, _k, x1); \ - Two_Sum(_2, _k, _j, _1); \ - Two_Sum(_l, _j, _m, _2); \ - Two_Product_2Presplit(a1, a1hi, a1lo, b1, bhi, blo, _j, _0); \ - Two_Sum(_i, _0, _n, _0); \ - Two_Sum(_1, _0, _i, x2); \ - Two_Sum(_2, _i, _k, _1); \ - Two_Sum(_m, _k, _l, _2); \ - Two_Sum(_j, _n, _k, _0); \ - Two_Sum(_1, _0, _j, x3); \ - Two_Sum(_2, _j, _i, _1); \ - Two_Sum(_l, _i, _m, _2); \ - Two_Sum(_1, _k, _i, x4); \ - Two_Sum(_2, _i, _k, x5); \ - Two_Sum(_m, _k, x7, x6) - -/* An expansion of length two can be squared more quickly than finding the */ -/* product of two different expansions of length two, and the result is */ -/* guaranteed to have no more than six (rather than eight) components. */ - -#define Two_Square(a1, a0, x5, x4, x3, x2, x1, x0) \ - Square(a0, _j, x0); \ - _0 = a0 + a0; \ - Two_Product(a1, _0, _k, _1); \ - Two_One_Sum(_k, _1, _j, _l, _2, x1); \ - Square(a1, _j, _1); \ - Two_Two_Sum(_j, _1, _l, _2, x5, x4, x3, x2) - -REAL splitter; /* = 2^ceiling(p / 2) + 1. Used to split floats in half. */ -REAL epsilon; /* = 2^(-p). Used to estimate roundoff errors. */ -/* A set of coefficients used to calculate maximum roundoff errors. */ -REAL resulterrbound; -REAL o2derrboundA, o2derrboundB, o2derrboundC; -REAL o3derrboundA, o3derrboundB, o3derrboundC; -REAL iccerrboundA, iccerrboundB, iccerrboundC; -REAL isperrboundA, isperrboundB, isperrboundC; - -/*****************************************************************************/ -/* */ -/* exactinit() Initialize the variables used for exact arithmetic. */ -/* */ -/* `epsilon' is the largest power of two such that 1.0 + epsilon = 1.0 in */ -/* floating-point arithmetic. `epsilon' bounds the relative roundoff */ -/* error. It is used for floating-point error analysis. */ -/* */ -/* `splitter' is used to split floating-point numbers into two half- */ -/* length significands for exact multiplication. */ -/* */ -/* I imagine that a highly optimizing compiler might be too smart for its */ -/* own good, and somehow cause this routine to fail, if it pretends that */ -/* floating-point arithmetic is too much like real arithmetic. */ -/* */ -/* Don't change this routine unless you fully understand it. */ -/* */ -/*****************************************************************************/ - -void exactinit() -{ - REAL half; - REAL check, lastcheck; - int every_other; -#ifdef LINUX - int cword; -#endif /* LINUX */ - -#ifdef CPU86 -#ifdef SINGLE - _control87(_PC_24, _MCW_PC); /* Set FPU control word for single precision. */ -#else /* not SINGLE */ - _control87(_PC_53, _MCW_PC); /* Set FPU control word for double precision. */ -#endif /* not SINGLE */ -#endif /* CPU86 */ -#ifdef LINUX -#ifdef SINGLE - /* cword = 4223; */ - cword = 4210; /* set FPU control word for single precision */ -#else /* not SINGLE */ - /* cword = 4735; */ - cword = 4722; /* set FPU control word for double precision */ -#endif /* not SINGLE */ - _FPU_SETCW(cword); -#endif /* LINUX */ - - every_other = 1; - half = 0.5; - epsilon = 1.0; - splitter = 1.0; - check = 1.0; - - /* Repeatedly divide `epsilon' by two until it is too small to add to */ - /* one without causing roundoff. (Also check if the sum is equal to */ - /* the previous sum, for machines that round up instead of using exact */ - /* rounding. Not that these routines will work on such machines.) */ - do { - lastcheck = check; - epsilon *= half; - if (every_other) { - splitter *= 2.0; - } - every_other = !every_other; - check = 1.0 + epsilon; - } while ((check != 1.0) && (check != lastcheck)); - splitter += 1.0; - - /* Error bounds for orientation and insphere tests. */ - resulterrbound = (3.0 + 8.0 * epsilon) * epsilon; - o2derrboundA = (3.0 + 16.0 * epsilon) * epsilon; - o2derrboundB = (2.0 + 12.0 * epsilon) * epsilon; - o2derrboundC = (9.0 + 64.0 * epsilon) * epsilon * epsilon; - o3derrboundA = (7.0 + 56.0 * epsilon) * epsilon; - o3derrboundB = (3.0 + 28.0 * epsilon) * epsilon; - o3derrboundC = (26.0 + 288.0 * epsilon) * epsilon * epsilon; - isperrboundA = (16.0 + 224.0 * epsilon) * epsilon; - isperrboundB = (5.0 + 72.0 * epsilon) * epsilon; - isperrboundC = (71.0 + 1408.0 * epsilon) * epsilon * epsilon; -} - -/*****************************************************************************/ -/* */ -/* grow_expansion() Add a scalar to an expansion. */ -/* */ -/* Sets h = e + b. See the long version of my paper for details. */ -/* */ -/* Maintains the nonoverlapping property. If round-to-even is used (as */ -/* with IEEE 754), maintains the strongly nonoverlapping and nonadjacent */ -/* properties as well. (That is, if e has one of these properties, so */ -/* will h.) */ -/* */ -/*****************************************************************************/ - -int grow_expansion ( - int elen, - __const_ptr(REAL) e , - REAL b , - __write_ptr(REAL) h ) /* e and h can be the same. */ -{ - REAL Q, Qnew; - int eindex; - REAL enow; - REAL bvirt, avirt, bround, around; - - Q = b; - for (eindex = 0; eindex < elen; eindex++) { - enow = e[eindex]; - Two_Sum(Q, enow, Qnew, h[eindex]); - Q = Qnew; - } - h[eindex] = Q; - return eindex + 1; -} - -/*****************************************************************************/ -/* */ -/* grow_expansion_zeroelim() Add a scalar to an expansion, eliminating */ -/* zero components from the output expansion. */ -/* */ -/* Sets h = e + b. See the long version of my paper for details. */ -/* */ -/* Maintains the nonoverlapping property. If round-to-even is used (as */ -/* with IEEE 754), maintains the strongly nonoverlapping and nonadjacent */ -/* properties as well. (That is, if e has one of these properties, so */ -/* will h.) */ -/* */ -/*****************************************************************************/ - -int grow_expansion_zeroelim ( - int elen, - __const_ptr(REAL) e , - REAL b , - __write_ptr(REAL) h ) /* e and h can be the same. */ -{ - REAL Q, hh, Qnew; - int eindex, hindex; - REAL enow; - REAL bvirt, avirt, bround, around; - - hindex = 0; - Q = b; - for (eindex = 0; eindex < elen; eindex++) { - enow = e[eindex]; - Two_Sum(Q, enow, Qnew, hh); - Q = Qnew; - if (hh != 0.0) { - h[hindex++] = hh; - } - } - if ((Q != 0.0) || (hindex == 0)) { - h[hindex++] = Q; - } - return hindex; -} - -/*****************************************************************************/ -/* */ -/* expansion_sum() Sum two expansions. */ -/* */ -/* Sets h = e + f. See the long version of my paper for details. */ -/* */ -/* Maintains the nonoverlapping property. If round-to-even is used (as */ -/* with IEEE 754), maintains the nonadjacent property as well. (That is, */ -/* if e has one of these properties, so will h.) Does NOT maintain the */ -/* strongly nonoverlapping property. */ -/* */ -/*****************************************************************************/ - -int expansion_sum ( - int elen, - __const_ptr(REAL) e , - int flen, - __const_ptr(REAL) f , - __write_ptr(REAL) h ) -/* e and h can be the same, but f and h cannot. */ -{ - REAL Q, Qnew; - int findex, hindex, hlast; - REAL hnow; - REAL bvirt, avirt, bround, around; - - Q = f[0]; - for (hindex = 0; hindex < elen; hindex++) { - hnow = e[hindex]; - Two_Sum(Q, hnow, Qnew, h[hindex]); - Q = Qnew; - } - h[hindex] = Q; - hlast = hindex; - for (findex = 1; findex < flen; findex++) { - Q = f[findex]; - for (hindex = findex; hindex <= hlast; hindex++) { - hnow = h[hindex]; - Two_Sum(Q, hnow, Qnew, h[hindex]); - Q = Qnew; - } - h[++hlast] = Q; - } - return hlast + 1; -} - -/*****************************************************************************/ -/* */ -/* expansion_sum_zeroelim1() Sum two expansions, eliminating zero */ -/* components from the output expansion. */ -/* */ -/* Sets h = e + f. See the long version of my paper for details. */ -/* */ -/* Maintains the nonoverlapping property. If round-to-even is used (as */ -/* with IEEE 754), maintains the nonadjacent property as well. (That is, */ -/* if e has one of these properties, so will h.) Does NOT maintain the */ -/* strongly nonoverlapping property. */ -/* */ -/*****************************************************************************/ - -int expansion_sum_zeroelim1 ( - int elen, - __const_ptr(REAL) e , - int flen, - __const_ptr(REAL) f , - __write_ptr(REAL) h ) -/* e and h can be the same, but f and h cannot. */ -{ - REAL Q, Qnew; - int index, findex, hindex, hlast; - REAL hnow; - REAL bvirt, avirt, bround, around; - - Q = f[0]; - for (hindex = 0; hindex < elen; hindex++) { - hnow = e[hindex]; - Two_Sum(Q, hnow, Qnew, h[hindex]); - Q = Qnew; - } - h[hindex] = Q; - hlast = hindex; - for (findex = 1; findex < flen; findex++) { - Q = f[findex]; - for (hindex = findex; hindex <= hlast; hindex++) { - hnow = h[hindex]; - Two_Sum(Q, hnow, Qnew, h[hindex]); - Q = Qnew; - } - h[++hlast] = Q; - } - hindex = -1; - for (index = 0; index <= hlast; index++) { - hnow = h[index]; - if (hnow != 0.0) { - h[++hindex] = hnow; - } - } - if (hindex == -1) { - return 1; - } else { - return hindex + 1; - } -} - -/*****************************************************************************/ -/* */ -/* expansion_sum_zeroelim2() Sum two expansions, eliminating zero */ -/* components from the output expansion. */ -/* */ -/* Sets h = e + f. See the long version of my paper for details. */ -/* */ -/* Maintains the nonoverlapping property. If round-to-even is used (as */ -/* with IEEE 754), maintains the nonadjacent property as well. (That is, */ -/* if e has one of these properties, so will h.) Does NOT maintain the */ -/* strongly nonoverlapping property. */ -/* */ -/*****************************************************************************/ - -int expansion_sum_zeroelim2 ( - int elen, - __const_ptr(REAL) e , - int flen, - __const_ptr(REAL) f , - __write_ptr(REAL) h ) -/* e and h can be the same, but f and h cannot. */ -{ - REAL Q, hh, Qnew; - int eindex, findex, hindex, hlast; - REAL enow; - REAL bvirt, avirt, bround, around; - - hindex = 0; - Q = f[0]; - for (eindex = 0; eindex < elen; eindex++) { - enow = e[eindex]; - Two_Sum(Q, enow, Qnew, hh); - Q = Qnew; - if (hh != 0.0) { - h[hindex++] = hh; - } - } - h[hindex] = Q; - hlast = hindex; - for (findex = 1; findex < flen; findex++) { - hindex = 0; - Q = f[findex]; - for (eindex = 0; eindex <= hlast; eindex++) { - enow = h[eindex]; - Two_Sum(Q, enow, Qnew, hh); - Q = Qnew; - if (hh != 0) { - h[hindex++] = hh; - } - } - h[hindex] = Q; - hlast = hindex; - } - return hlast + 1; -} - -/*****************************************************************************/ -/* */ -/* fast_expansion_sum() Sum two expansions. */ -/* */ -/* Sets h = e + f. See the long version of my paper for details. */ -/* */ -/* If round-to-even is used (as with IEEE 754), maintains the strongly */ -/* nonoverlapping property. (That is, if e is strongly nonoverlapping, h */ -/* will be also.) Does NOT maintain the nonoverlapping or nonadjacent */ -/* properties. */ -/* */ -/*****************************************************************************/ - -int fast_expansion_sum ( - int elen, - __const_ptr(REAL) e , - int flen, - __const_ptr(REAL) f , - __write_ptr(REAL) h ) /* h cannot be e or f. */ -{ - REAL Q, Qnew; - REAL bvirt, avirt, bround, around; - int eindex, findex, hindex; - REAL enow, fnow; - - enow = e[0]; - fnow = f[0]; - eindex = findex = 0; - if ((fnow > enow) == (fnow > -enow)) { - Q = enow; - enow = e[++eindex]; - } else { - Q = fnow; - fnow = f[++findex]; - } - hindex = 0; - if ((eindex < elen) && (findex < flen)) { - if ((fnow > enow) == (fnow > -enow)) { - Fast_Two_Sum(enow, Q, Qnew, h[0]); - enow = e[++eindex]; - } else { - Fast_Two_Sum(fnow, Q, Qnew, h[0]); - fnow = f[++findex]; - } - Q = Qnew; - hindex = 1; - while ((eindex < elen) && (findex < flen)) { - if ((fnow > enow) == (fnow > -enow)) { - Two_Sum(Q, enow, Qnew, h[hindex]); - enow = e[++eindex]; - } else { - Two_Sum(Q, fnow, Qnew, h[hindex]); - fnow = f[++findex]; - } - Q = Qnew; - hindex++; - } - } - while (eindex < elen) { - Two_Sum(Q, enow, Qnew, h[hindex]); - enow = e[++eindex]; - Q = Qnew; - hindex++; - } - while (findex < flen) { - Two_Sum(Q, fnow, Qnew, h[hindex]); - fnow = f[++findex]; - Q = Qnew; - hindex++; - } - h[hindex] = Q; - return hindex + 1; -} - -/*****************************************************************************/ -/* */ -/* fast_expansion_sum_zeroelim() Sum two expansions, eliminating zero */ -/* components from the output expansion. */ -/* */ -/* Sets h = e + f. See the long version of my paper for details. */ -/* */ -/* If round-to-even is used (as with IEEE 754), maintains the strongly */ -/* nonoverlapping property. (That is, if e is strongly nonoverlapping, h */ -/* will be also.) Does NOT maintain the nonoverlapping or nonadjacent */ -/* properties. */ -/* */ -/*****************************************************************************/ - -int fast_expansion_sum_zeroelim ( - int elen, - __const_ptr(REAL) e , - int flen, - __const_ptr(REAL) f , - __write_ptr(REAL) h ) /* h cannot be e or f. */ -{ - REAL Q, Qnew, hh; - REAL bvirt, avirt, bround, around; - int eindex, findex, hindex; - REAL enow, fnow; - - enow = e[0]; - fnow = f[0]; - eindex = findex = 0; - if ((fnow > enow) == (fnow > -enow)) { - Q = enow; - enow = e[++eindex]; - } else { - Q = fnow; - fnow = f[++findex]; - } - hindex = 0; - if ((eindex < elen) && (findex < flen)) { - if ((fnow > enow) == (fnow > -enow)) { - Fast_Two_Sum(enow, Q, Qnew, hh); - enow = e[++eindex]; - } else { - Fast_Two_Sum(fnow, Q, Qnew, hh); - fnow = f[++findex]; - } - Q = Qnew; - if (hh != 0.0) { - h[hindex++] = hh; - } - while ((eindex < elen) && (findex < flen)) { - if ((fnow > enow) == (fnow > -enow)) { - Two_Sum(Q, enow, Qnew, hh); - enow = e[++eindex]; - } else { - Two_Sum(Q, fnow, Qnew, hh); - fnow = f[++findex]; - } - Q = Qnew; - if (hh != 0.0) { - h[hindex++] = hh; - } - } - } - while (eindex < elen) { - Two_Sum(Q, enow, Qnew, hh); - enow = e[++eindex]; - Q = Qnew; - if (hh != 0.0) { - h[hindex++] = hh; - } - } - while (findex < flen) { - Two_Sum(Q, fnow, Qnew, hh); - fnow = f[++findex]; - Q = Qnew; - if (hh != 0.0) { - h[hindex++] = hh; - } - } - if ((Q != 0.0) || (hindex == 0)) { - h[hindex++] = Q; - } - return hindex; -} - -/*****************************************************************************/ -/* */ -/* linear_expansion_sum() Sum two expansions. */ -/* */ -/* Sets h = e + f. See either version of my paper for details. */ -/* */ -/* Maintains the nonoverlapping property. (That is, if e is */ -/* nonoverlapping, h will be also.) */ -/* */ -/*****************************************************************************/ - -int linear_expansion_sum ( - int elen, - __const_ptr(REAL) e , - int flen, - __const_ptr(REAL) f , - __write_ptr(REAL) h ) /* h cannot be e or f. */ -{ - REAL Q, q, Qnew, R; - REAL bvirt, avirt, bround, around; - int eindex, findex, hindex; - REAL enow, fnow, g0; - - enow = e[0]; - fnow = f[0]; - eindex = findex = 0; - if ((fnow > enow) == (fnow > -enow)) { - g0 = enow; - enow = e[++eindex]; - } else { - g0 = fnow; - fnow = f[++findex]; - } - if ((eindex < elen) && ((findex >= flen) - || ((fnow > enow) == (fnow > -enow)))) { - Fast_Two_Sum(enow, g0, Qnew, q); - enow = e[++eindex]; - } else { - Fast_Two_Sum(fnow, g0, Qnew, q); - fnow = f[++findex]; - } - Q = Qnew; - for (hindex = 0; hindex < elen + flen - 2; hindex++) { - if ((eindex < elen) && ((findex >= flen) - || ((fnow > enow) == (fnow > -enow)))) { - Fast_Two_Sum(enow, q, R, h[hindex]); - enow = e[++eindex]; - } else { - Fast_Two_Sum(fnow, q, R, h[hindex]); - fnow = f[++findex]; - } - Two_Sum(Q, R, Qnew, q); - Q = Qnew; - } - h[hindex] = q; - h[hindex + 1] = Q; - return hindex + 2; -} - -/*****************************************************************************/ -/* */ -/* linear_expansion_sum_zeroelim() Sum two expansions, eliminating zero */ -/* components from the output expansion. */ -/* */ -/* Sets h = e + f. See either version of my paper for details. */ -/* */ -/* Maintains the nonoverlapping property. (That is, if e is */ -/* nonoverlapping, h will be also.) */ -/* */ -/*****************************************************************************/ - -int linear_expansion_sum_zeroelim ( - int elen, - __const_ptr(REAL) e , - int flen, - __const_ptr(REAL) f , - __write_ptr(REAL) h ) /* h cannot be e or f. */ -{ - REAL Q, q, hh, Qnew, R; - REAL bvirt, avirt, bround, around; - int eindex, findex, hindex; - int count; - REAL enow, fnow, g0; - - enow = e[0]; - fnow = f[0]; - eindex = findex = 0; - hindex = 0; - if ((fnow > enow) == (fnow > -enow)) { - g0 = enow; - enow = e[++eindex]; - } else { - g0 = fnow; - fnow = f[++findex]; - } - if ((eindex < elen) && ((findex >= flen) - || ((fnow > enow) == (fnow > -enow)))) { - Fast_Two_Sum(enow, g0, Qnew, q); - enow = e[++eindex]; - } else { - Fast_Two_Sum(fnow, g0, Qnew, q); - fnow = f[++findex]; - } - Q = Qnew; - for (count = 2; count < elen + flen; count++) { - if ((eindex < elen) && ((findex >= flen) - || ((fnow > enow) == (fnow > -enow)))) { - Fast_Two_Sum(enow, q, R, hh); - enow = e[++eindex]; - } else { - Fast_Two_Sum(fnow, q, R, hh); - fnow = f[++findex]; - } - Two_Sum(Q, R, Qnew, q); - Q = Qnew; - if (hh != 0) { - h[hindex++] = hh; - } - } - if (q != 0) { - h[hindex++] = q; - } - if ((Q != 0.0) || (hindex == 0)) { - h[hindex++] = Q; - } - return hindex; -} - -/*****************************************************************************/ -/* */ -/* scale_expansion() Multiply an expansion by a scalar. */ -/* */ -/* Sets h = be. See either version of my paper for details. */ -/* */ -/* Maintains the nonoverlapping property. If round-to-even is used (as */ -/* with IEEE 754), maintains the strongly nonoverlapping and nonadjacent */ -/* properties as well. (That is, if e has one of these properties, so */ -/* will h.) */ -/* */ -/*****************************************************************************/ - -int scale_expansion ( - int elen, - __const_ptr(REAL) e , - REAL b , - __write_ptr(REAL) h ) /* e and h cannot be the same. */ -{ - REAL Q, sum, product1, product0; - int eindex, hindex; - REAL enow; - REAL bvirt, avirt, bround, around; - REAL c, abig, ahi, alo, bhi, blo; - REAL err1, err2, err3; - - Split(b, bhi, blo); - Two_Product_Presplit(e[0], b, bhi, blo, Q, h[0]); - hindex = 1; - for (eindex = 1; eindex < elen; eindex++) { - enow = e[eindex]; - Two_Product_Presplit(enow, b, bhi, blo, product1, product0); - Two_Sum(Q, product0, sum, h[hindex]); - hindex++; - Two_Sum(product1, sum, Q, h[hindex]); - hindex++; - } - h[hindex] = Q; - return elen + elen; -} - -/*****************************************************************************/ -/* */ -/* scale_expansion_zeroelim() Multiply an expansion by a scalar, */ -/* eliminating zero components from the */ -/* output expansion. */ -/* */ -/* Sets h = be. See either version of my paper for details. */ -/* */ -/* Maintains the nonoverlapping property. If round-to-even is used (as */ -/* with IEEE 754), maintains the strongly nonoverlapping and nonadjacent */ -/* properties as well. (That is, if e has one of these properties, so */ -/* will h.) */ -/* */ -/*****************************************************************************/ - -int scale_expansion_zeroelim ( - int elen, - __const_ptr(REAL) e , - REAL b , - __write_ptr(REAL) h ) /* e and h cannot be the same. */ -{ - REAL Q, sum, hh; - REAL product1, product0; - int eindex, hindex; - REAL enow; - REAL bvirt, avirt, bround, around; - REAL c, abig, ahi, alo, bhi, blo; - REAL err1, err2, err3; - - Split(b, bhi, blo); - Two_Product_Presplit(e[0], b, bhi, blo, Q, hh); - hindex = 0; - if (hh != 0) { - h[hindex++] = hh; - } - for (eindex = 1; eindex < elen; eindex++) { - enow = e[eindex]; - Two_Product_Presplit(enow, b, bhi, blo, product1, product0); - Two_Sum(Q, product0, sum, hh); - if (hh != 0) { - h[hindex++] = hh; - } - Fast_Two_Sum(product1, sum, Q, hh); - if (hh != 0) { - h[hindex++] = hh; - } - } - if ((Q != 0.0) || (hindex == 0)) { - h[hindex++] = Q; - } - return hindex; -} - -/*****************************************************************************/ -/* */ -/* compress() Compress an expansion. */ -/* */ -/* See the long version of my paper for details. */ -/* */ -/* Maintains the nonoverlapping property. If round-to-even is used (as */ -/* with IEEE 754), then any nonoverlapping expansion is converted to a */ -/* nonadjacent expansion. */ -/* */ -/*****************************************************************************/ - -int compress ( - int elen, - __const_ptr(REAL) e , - __write_ptr(REAL) h ) /* e and h may be the same. */ -{ - REAL Q, q, Qnew; - int eindex, hindex; - REAL bvirt; - REAL enow, hnow; - int top, bottom; - - bottom = elen - 1; - Q = e[bottom]; - for (eindex = elen - 2; eindex >= 0; eindex--) { - enow = e[eindex]; - Fast_Two_Sum(Q, enow, Qnew, q); - if (q != 0) { - h[bottom--] = Qnew; - Q = q; - } else { - Q = Qnew; - } - } - top = 0; - for (hindex = bottom + 1; hindex < elen; hindex++) { - hnow = h[hindex]; - Fast_Two_Sum(hnow, Q, Qnew, q); - if (q != 0) { - h[top++] = q; - } - Q = Qnew; - } - h[top] = Q; - return top + 1; -} - -/*****************************************************************************/ -/* */ -/* estimate() Produce a one-word estimate of an expansion's value. */ -/* */ -/* See either version of my paper for details. */ -/* */ -/*****************************************************************************/ - -REAL estimate ( - int elen, - __const_ptr(REAL) e ) -{ - REAL Q; - int eindex; - - Q = e[0]; - for (eindex = 1; eindex < elen; eindex++) { - Q += e[eindex]; - } - return Q; -} - -/*****************************************************************************/ -/* */ -/* orient2d() Adaptive exact 2D orientation test. Robust. */ -/* */ -/* Return a positive value if the points pa, pb, and pc occur */ -/* in counterclockwise order; a negative value if they occur */ -/* in clockwise order; and zero if they are collinear. The */ -/* result is also a rough approximation of twice the signed */ -/* area of the triangle defined by the three points. */ -/* */ -/* The last three use exact arithmetic to ensure a correct answer. The */ -/* result returned is the determinant of a matrix. In orient2d() only, */ -/* this determinant is computed adaptively, in the sense that exact */ -/* arithmetic is used only to the degree it is needed to ensure that the */ -/* returned value has the correct sign. Hence, orient2d() is usually quite */ -/* fast, but will run more slowly when the input points are collinear or */ -/* nearly so. */ -/* */ -/*****************************************************************************/ - -REAL orient2dexact ( - __const_ptr(REAL) pa, - __const_ptr(REAL) pb, - __const_ptr(REAL) pc) -{ - REAL axby1, axcy1, bxcy1, bxay1, cxay1, cxby1; - REAL axby0, axcy0, bxcy0, bxay0, cxay0, cxby0; - REAL aterms[4], bterms[4], cterms[4]; - REAL aterms3, bterms3, cterms3; - REAL v[8], w[12]; - int vlength=0, wlength=0; - - REAL bvirt, avirt, bround, around; - REAL c, abig, ahi, alo, bhi, blo; - REAL err1, err2, err3; - REAL _i, _j, _0; - - Two_Product(pa[0], pb[1], axby1, axby0); - Two_Product(pa[0], pc[1], axcy1, axcy0); - Two_Two_Diff(axby1, axby0, axcy1, axcy0, - aterms3, aterms[2], aterms[1], aterms[0]); - aterms[3] = aterms3; - - Two_Product(pb[0], pc[1], bxcy1, bxcy0); - Two_Product(pb[0], pa[1], bxay1, bxay0); - Two_Two_Diff(bxcy1, bxcy0, bxay1, bxay0, - bterms3, bterms[2], bterms[1], bterms[0]); - bterms[3] = bterms3; - - Two_Product(pc[0], pa[1], cxay1, cxay0); - Two_Product(pc[0], pb[1], cxby1, cxby0); - Two_Two_Diff(cxay1, cxay0, cxby1, cxby0, - cterms3, cterms[2], cterms[1], cterms[0]); - cterms[3] = cterms3; - - vlength = fast_expansion_sum_zeroelim(4, aterms, 4, bterms, v); - wlength = fast_expansion_sum_zeroelim(vlength, v, 4, cterms, w); - - return w[wlength - 1]; -} - -REAL orient2dadapt ( - __const_ptr(REAL) pa, - __const_ptr(REAL) pb, - __const_ptr(REAL) pc, - REAL detsum) -{ - REAL acx, acy, bcx, bcy; - REAL acxtail, acytail, bcxtail, bcytail; - REAL detleft, detright; - REAL detlefttail, detrighttail; - REAL det, errbound; - REAL B[4], C1[8], C2[12], D[16]; - REAL B3; - int C1length=0, C2length=0, Dlength=0; - REAL u[4]; - REAL u3, s1, t1, s0, t0; - - REAL bvirt, avirt, bround, around; - REAL c, abig, ahi, alo, bhi, blo; - REAL err1, err2, err3; - REAL _i, _j, _0; - - acx = (REAL) (pa[0] - pc[0]); - bcx = (REAL) (pb[0] - pc[0]); - acy = (REAL) (pa[1] - pc[1]); - bcy = (REAL) (pb[1] - pc[1]); - - Two_Product(acx, bcy, detleft, detlefttail); - Two_Product(acy, bcx, detright, detrighttail); - - Two_Two_Diff(detleft, detlefttail, detright, detrighttail, - B3, B[2], B[1], B[0]); - B[3] = B3; - - det = estimate(4, B); - errbound = o2derrboundB * detsum; - if ((det >= errbound) || (-det >= errbound)) { - return det; - } - - Two_Diff_Tail(pa[0], pc[0], acx, acxtail); - Two_Diff_Tail(pb[0], pc[0], bcx, bcxtail); - Two_Diff_Tail(pa[1], pc[1], acy, acytail); - Two_Diff_Tail(pb[1], pc[1], bcy, bcytail); - - if ((acxtail == 0.0) && (acytail == 0.0) - && (bcxtail == 0.0) && (bcytail == 0.0)) { - return det; - } - - errbound = o2derrboundC * detsum + resulterrbound * Absolute(det); - det += (acx * bcytail + bcy * acxtail) - - (acy * bcxtail + bcx * acytail); - if ((det >= errbound) || (-det >= errbound)) { - return det; - } - - Two_Product(acxtail, bcy, s1, s0); - Two_Product(acytail, bcx, t1, t0); - Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]); - u[3] = u3; - C1length = fast_expansion_sum_zeroelim(4, B, 4, u, C1); - - Two_Product(acx, bcytail, s1, s0); - Two_Product(acy, bcxtail, t1, t0); - Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]); - u[3] = u3; - C2length = fast_expansion_sum_zeroelim(C1length, C1, 4, u, C2); - - Two_Product(acxtail, bcytail, s1, s0); - Two_Product(acytail, bcxtail, t1, t0); - Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]); - u[3] = u3; - Dlength = fast_expansion_sum_zeroelim(C2length, C2, 4, u, D); - - return(D[Dlength - 1]); -} - -REAL orient2d ( - __const_ptr(REAL) pa, - __const_ptr(REAL) pb, - __const_ptr(REAL) pc) -{ - REAL detleft, detright, det; - REAL detsum, errbound; - - detleft = (pa[0] - pc[0]) * (pb[1] - pc[1]); - detright = (pa[1] - pc[1]) * (pb[0] - pc[0]); - det = detleft - detright; - - if (detleft > 0.0) { - if (detright <= 0.0) { - return det; - } else { - detsum = detleft + detright; - } - } else if (detleft < 0.0) { - if (detright >= 0.0) { - return det; - } else { - detsum = -detleft - detright; - } - } else { - return det; - } - - errbound = o2derrboundA * detsum; - if ((det >= errbound) || (-det >= errbound)) { - return det; - } - - return orient2dadapt(pa, pb, pc, detsum); -} - -/*****************************************************************************/ -/* */ -/* orient3d() Adaptive exact 3D orientation test. Robust. */ -/* */ -/* Return a positive value if the point pd lies below the */ -/* plane passing through pa, pb, and pc; "below" is defined so */ -/* that pa, pb, and pc appear in counterclockwise order when */ -/* viewed from above the plane. Returns a negative value if */ -/* pd lies above the plane. Returns zero if the points are */ -/* coplanar. The result is also a rough approximation of six */ -/* times the signed volume of the tetrahedron defined by the */ -/* four points. */ -/* */ -/* The last three use exact arithmetic to ensure a correct answer. The */ -/* result returned is the determinant of a matrix. In orient3d() only, */ -/* this determinant is computed adaptively, in the sense that exact */ -/* arithmetic is used only to the degree it is needed to ensure that the */ -/* returned value has the correct sign. Hence, orient3d() is usually quite */ -/* fast, but will run more slowly when the input points are coplanar or */ -/* nearly so. */ -/* */ -/*****************************************************************************/ - -REAL orient3dexact ( - __const_ptr(REAL) pa, - __const_ptr(REAL) pb, - __const_ptr(REAL) pc, - __const_ptr(REAL) pd) -{ - REAL axby1, bxcy1, cxdy1, dxay1, axcy1, bxdy1; - REAL bxay1, cxby1, dxcy1, axdy1, cxay1, dxby1; - REAL axby0, bxcy0, cxdy0, dxay0, axcy0, bxdy0; - REAL bxay0, cxby0, dxcy0, axdy0, cxay0, dxby0; - REAL ab[4], bc[4], cd[4], da[4], ac[4], bd[4]; - REAL temp8[8]; - int templen=0; - REAL abc[12], bcd[12], cda[12], dab[12]; - int abclen=0, bcdlen=0, cdalen=0, dablen=0; - REAL adet[24], bdet[24], cdet[24], ddet[24]; - int alen=0, blen=0, clen=0, dlen=0; - REAL abdet[48], cddet[48]; - int ablen=0, cdlen=0; - REAL deter[96]; - int deterlen=0; - int i; - - REAL bvirt, avirt, bround, around; - REAL c, abig, ahi, alo, bhi, blo; - REAL err1, err2, err3; - REAL _i, _j, _0; - - Two_Product(pa[0], pb[1], axby1, axby0); - Two_Product(pb[0], pa[1], bxay1, bxay0); - Two_Two_Diff(axby1, axby0, bxay1, bxay0, ab[3], ab[2], ab[1], ab[0]); - - Two_Product(pb[0], pc[1], bxcy1, bxcy0); - Two_Product(pc[0], pb[1], cxby1, cxby0); - Two_Two_Diff(bxcy1, bxcy0, cxby1, cxby0, bc[3], bc[2], bc[1], bc[0]); - - Two_Product(pc[0], pd[1], cxdy1, cxdy0); - Two_Product(pd[0], pc[1], dxcy1, dxcy0); - Two_Two_Diff(cxdy1, cxdy0, dxcy1, dxcy0, cd[3], cd[2], cd[1], cd[0]); - - Two_Product(pd[0], pa[1], dxay1, dxay0); - Two_Product(pa[0], pd[1], axdy1, axdy0); - Two_Two_Diff(dxay1, dxay0, axdy1, axdy0, da[3], da[2], da[1], da[0]); - - Two_Product(pa[0], pc[1], axcy1, axcy0); - Two_Product(pc[0], pa[1], cxay1, cxay0); - Two_Two_Diff(axcy1, axcy0, cxay1, cxay0, ac[3], ac[2], ac[1], ac[0]); - - Two_Product(pb[0], pd[1], bxdy1, bxdy0); - Two_Product(pd[0], pb[1], dxby1, dxby0); - Two_Two_Diff(bxdy1, bxdy0, dxby1, dxby0, bd[3], bd[2], bd[1], bd[0]); - - templen = fast_expansion_sum_zeroelim(4, cd, 4, da, temp8); - cdalen = fast_expansion_sum_zeroelim(templen, temp8, 4, ac, cda); - templen = fast_expansion_sum_zeroelim(4, da, 4, ab, temp8); - dablen = fast_expansion_sum_zeroelim(templen, temp8, 4, bd, dab); - for (i = 0; i < 4; i++) { - bd[i] = -bd[i]; - ac[i] = -ac[i]; - } - templen = fast_expansion_sum_zeroelim(4, ab, 4, bc, temp8); - abclen = fast_expansion_sum_zeroelim(templen, temp8, 4, ac, abc); - templen = fast_expansion_sum_zeroelim(4, bc, 4, cd, temp8); - bcdlen = fast_expansion_sum_zeroelim(templen, temp8, 4, bd, bcd); - - alen = scale_expansion_zeroelim(bcdlen, bcd, pa[2], adet); - blen = scale_expansion_zeroelim(cdalen, cda, -pb[2], bdet); - clen = scale_expansion_zeroelim(dablen, dab, pc[2], cdet); - dlen = scale_expansion_zeroelim(abclen, abc, -pd[2], ddet); - - ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); - cdlen = fast_expansion_sum_zeroelim(clen, cdet, dlen, ddet, cddet); - deterlen = fast_expansion_sum_zeroelim(ablen, abdet, cdlen, cddet, deter); - - return deter[deterlen - 1]; -} - -REAL orient3dadapt ( - __const_ptr(REAL) pa, - __const_ptr(REAL) pb, - __const_ptr(REAL) pc, - __const_ptr(REAL) pd, - REAL permanent) -{ - REAL adx, bdx, cdx, ady, bdy, cdy, adz, bdz, cdz; - REAL det, errbound; - - REAL bdxcdy1, cdxbdy1, cdxady1, adxcdy1, adxbdy1, bdxady1; - REAL bdxcdy0, cdxbdy0, cdxady0, adxcdy0, adxbdy0, bdxady0; - REAL bc[4], ca[4], ab[4]; - REAL bc3, ca3, ab3; - REAL adet[8], bdet[8], cdet[8]; - int alen=0, blen=0, clen=0; - REAL abdet[16]; - int ablen=0; - REAL *finnow, *finother, *finswap; - REAL fin1[192], fin2[192]; - int finlength=0; - - REAL adxtail, bdxtail, cdxtail; - REAL adytail, bdytail, cdytail; - REAL adztail, bdztail, cdztail; - REAL at_blarge, at_clarge; - REAL bt_clarge, bt_alarge; - REAL ct_alarge, ct_blarge; - REAL at_b[4], at_c[4], bt_c[4], bt_a[4], ct_a[4], ct_b[4]; - int at_blen=0, at_clen=0, bt_clen=0; - int bt_alen=0, ct_alen=0, ct_blen=0; - REAL bdxt_cdy1, cdxt_bdy1, cdxt_ady1; - REAL adxt_cdy1, adxt_bdy1, bdxt_ady1; - REAL bdxt_cdy0, cdxt_bdy0, cdxt_ady0; - REAL adxt_cdy0, adxt_bdy0, bdxt_ady0; - REAL bdyt_cdx1, cdyt_bdx1, cdyt_adx1; - REAL adyt_cdx1, adyt_bdx1, bdyt_adx1; - REAL bdyt_cdx0, cdyt_bdx0, cdyt_adx0; - REAL adyt_cdx0, adyt_bdx0, bdyt_adx0; - REAL bct[8], cat[8], abt[8]; - int bctlen=0, catlen=0, abtlen=0; - REAL bdxt_cdyt1, cdxt_bdyt1, cdxt_adyt1; - REAL adxt_cdyt1, adxt_bdyt1, bdxt_adyt1; - REAL bdxt_cdyt0, cdxt_bdyt0, cdxt_adyt0; - REAL adxt_cdyt0, adxt_bdyt0, bdxt_adyt0; - REAL u[4], v[12], w[16]; - REAL u3; - int vlength=0, wlength=0; - REAL negate; - - REAL bvirt, avirt, bround, around; - REAL c, abig, ahi, alo, bhi, blo; - REAL err1, err2, err3; - REAL _i, _j, _k, _0; - - adx = (REAL) (pa[0] - pd[0]); - bdx = (REAL) (pb[0] - pd[0]); - cdx = (REAL) (pc[0] - pd[0]); - ady = (REAL) (pa[1] - pd[1]); - bdy = (REAL) (pb[1] - pd[1]); - cdy = (REAL) (pc[1] - pd[1]); - adz = (REAL) (pa[2] - pd[2]); - bdz = (REAL) (pb[2] - pd[2]); - cdz = (REAL) (pc[2] - pd[2]); - - Two_Product(bdx, cdy, bdxcdy1, bdxcdy0); - Two_Product(cdx, bdy, cdxbdy1, cdxbdy0); - Two_Two_Diff(bdxcdy1, bdxcdy0, cdxbdy1, cdxbdy0, bc3, bc[2], bc[1], bc[0]); - bc[3] = bc3; - alen = scale_expansion_zeroelim(4, bc, adz, adet); - - Two_Product(cdx, ady, cdxady1, cdxady0); - Two_Product(adx, cdy, adxcdy1, adxcdy0); - Two_Two_Diff(cdxady1, cdxady0, adxcdy1, adxcdy0, ca3, ca[2], ca[1], ca[0]); - ca[3] = ca3; - blen = scale_expansion_zeroelim(4, ca, bdz, bdet); - - Two_Product(adx, bdy, adxbdy1, adxbdy0); - Two_Product(bdx, ady, bdxady1, bdxady0); - Two_Two_Diff(adxbdy1, adxbdy0, bdxady1, bdxady0, ab3, ab[2], ab[1], ab[0]); - ab[3] = ab3; - clen = scale_expansion_zeroelim(4, ab, cdz, cdet); - - ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); - finlength = fast_expansion_sum_zeroelim(ablen, abdet, clen, cdet, fin1); - - det = estimate(finlength, fin1); - errbound = o3derrboundB * permanent; - if ((det >= errbound) || (-det >= errbound)) { - return det; - } - - Two_Diff_Tail(pa[0], pd[0], adx, adxtail); - Two_Diff_Tail(pb[0], pd[0], bdx, bdxtail); - Two_Diff_Tail(pc[0], pd[0], cdx, cdxtail); - Two_Diff_Tail(pa[1], pd[1], ady, adytail); - Two_Diff_Tail(pb[1], pd[1], bdy, bdytail); - Two_Diff_Tail(pc[1], pd[1], cdy, cdytail); - Two_Diff_Tail(pa[2], pd[2], adz, adztail); - Two_Diff_Tail(pb[2], pd[2], bdz, bdztail); - Two_Diff_Tail(pc[2], pd[2], cdz, cdztail); - - if ((adxtail == 0.0) && (bdxtail == 0.0) && (cdxtail == 0.0) - && (adytail == 0.0) && (bdytail == 0.0) && (cdytail == 0.0) - && (adztail == 0.0) && (bdztail == 0.0) && (cdztail == 0.0)) { - return det; - } - - errbound = o3derrboundC * permanent + resulterrbound * Absolute(det); - det += (adz * ((bdx * cdytail + cdy * bdxtail) - - (bdy * cdxtail + cdx * bdytail)) - + adztail * (bdx * cdy - bdy * cdx)) - + (bdz * ((cdx * adytail + ady * cdxtail) - - (cdy * adxtail + adx * cdytail)) - + bdztail * (cdx * ady - cdy * adx)) - + (cdz * ((adx * bdytail + bdy * adxtail) - - (ady * bdxtail + bdx * adytail)) - + cdztail * (adx * bdy - ady * bdx)); - if ((det >= errbound) || (-det >= errbound)) { - return det; - } - - finnow = fin1; - finother = fin2; - - if (adxtail == 0.0) { - if (adytail == 0.0) { - at_b[0] = 0.0; - at_blen = 1; - at_c[0] = 0.0; - at_clen = 1; - } else { - negate = -adytail; - Two_Product(negate, bdx, at_blarge, at_b[0]); - at_b[1] = at_blarge; - at_blen = 2; - Two_Product(adytail, cdx, at_clarge, at_c[0]); - at_c[1] = at_clarge; - at_clen = 2; - } - } else { - if (adytail == 0.0) { - Two_Product(adxtail, bdy, at_blarge, at_b[0]); - at_b[1] = at_blarge; - at_blen = 2; - negate = -adxtail; - Two_Product(negate, cdy, at_clarge, at_c[0]); - at_c[1] = at_clarge; - at_clen = 2; - } else { - Two_Product(adxtail, bdy, adxt_bdy1, adxt_bdy0); - Two_Product(adytail, bdx, adyt_bdx1, adyt_bdx0); - Two_Two_Diff(adxt_bdy1, adxt_bdy0, adyt_bdx1, adyt_bdx0, - at_blarge, at_b[2], at_b[1], at_b[0]); - at_b[3] = at_blarge; - at_blen = 4; - Two_Product(adytail, cdx, adyt_cdx1, adyt_cdx0); - Two_Product(adxtail, cdy, adxt_cdy1, adxt_cdy0); - Two_Two_Diff(adyt_cdx1, adyt_cdx0, adxt_cdy1, adxt_cdy0, - at_clarge, at_c[2], at_c[1], at_c[0]); - at_c[3] = at_clarge; - at_clen = 4; - } - } - if (bdxtail == 0.0) { - if (bdytail == 0.0) { - bt_c[0] = 0.0; - bt_clen = 1; - bt_a[0] = 0.0; - bt_alen = 1; - } else { - negate = -bdytail; - Two_Product(negate, cdx, bt_clarge, bt_c[0]); - bt_c[1] = bt_clarge; - bt_clen = 2; - Two_Product(bdytail, adx, bt_alarge, bt_a[0]); - bt_a[1] = bt_alarge; - bt_alen = 2; - } - } else { - if (bdytail == 0.0) { - Two_Product(bdxtail, cdy, bt_clarge, bt_c[0]); - bt_c[1] = bt_clarge; - bt_clen = 2; - negate = -bdxtail; - Two_Product(negate, ady, bt_alarge, bt_a[0]); - bt_a[1] = bt_alarge; - bt_alen = 2; - } else { - Two_Product(bdxtail, cdy, bdxt_cdy1, bdxt_cdy0); - Two_Product(bdytail, cdx, bdyt_cdx1, bdyt_cdx0); - Two_Two_Diff(bdxt_cdy1, bdxt_cdy0, bdyt_cdx1, bdyt_cdx0, - bt_clarge, bt_c[2], bt_c[1], bt_c[0]); - bt_c[3] = bt_clarge; - bt_clen = 4; - Two_Product(bdytail, adx, bdyt_adx1, bdyt_adx0); - Two_Product(bdxtail, ady, bdxt_ady1, bdxt_ady0); - Two_Two_Diff(bdyt_adx1, bdyt_adx0, bdxt_ady1, bdxt_ady0, - bt_alarge, bt_a[2], bt_a[1], bt_a[0]); - bt_a[3] = bt_alarge; - bt_alen = 4; - } - } - if (cdxtail == 0.0) { - if (cdytail == 0.0) { - ct_a[0] = 0.0; - ct_alen = 1; - ct_b[0] = 0.0; - ct_blen = 1; - } else { - negate = -cdytail; - Two_Product(negate, adx, ct_alarge, ct_a[0]); - ct_a[1] = ct_alarge; - ct_alen = 2; - Two_Product(cdytail, bdx, ct_blarge, ct_b[0]); - ct_b[1] = ct_blarge; - ct_blen = 2; - } - } else { - if (cdytail == 0.0) { - Two_Product(cdxtail, ady, ct_alarge, ct_a[0]); - ct_a[1] = ct_alarge; - ct_alen = 2; - negate = -cdxtail; - Two_Product(negate, bdy, ct_blarge, ct_b[0]); - ct_b[1] = ct_blarge; - ct_blen = 2; - } else { - Two_Product(cdxtail, ady, cdxt_ady1, cdxt_ady0); - Two_Product(cdytail, adx, cdyt_adx1, cdyt_adx0); - Two_Two_Diff(cdxt_ady1, cdxt_ady0, cdyt_adx1, cdyt_adx0, - ct_alarge, ct_a[2], ct_a[1], ct_a[0]); - ct_a[3] = ct_alarge; - ct_alen = 4; - Two_Product(cdytail, bdx, cdyt_bdx1, cdyt_bdx0); - Two_Product(cdxtail, bdy, cdxt_bdy1, cdxt_bdy0); - Two_Two_Diff(cdyt_bdx1, cdyt_bdx0, cdxt_bdy1, cdxt_bdy0, - ct_blarge, ct_b[2], ct_b[1], ct_b[0]); - ct_b[3] = ct_blarge; - ct_blen = 4; - } - } - - bctlen = fast_expansion_sum_zeroelim(bt_clen, bt_c, ct_blen, ct_b, bct); - wlength = scale_expansion_zeroelim(bctlen, bct, adz, w); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w, - finother); - finswap = finnow; finnow = finother; finother = finswap; - - catlen = fast_expansion_sum_zeroelim(ct_alen, ct_a, at_clen, at_c, cat); - wlength = scale_expansion_zeroelim(catlen, cat, bdz, w); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w, - finother); - finswap = finnow; finnow = finother; finother = finswap; - - abtlen = fast_expansion_sum_zeroelim(at_blen, at_b, bt_alen, bt_a, abt); - wlength = scale_expansion_zeroelim(abtlen, abt, cdz, w); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w, - finother); - finswap = finnow; finnow = finother; finother = finswap; - - if (adztail != 0.0) { - vlength = scale_expansion_zeroelim(4, bc, adztail, v); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, vlength, v, - finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (bdztail != 0.0) { - vlength = scale_expansion_zeroelim(4, ca, bdztail, v); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, vlength, v, - finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (cdztail != 0.0) { - vlength = scale_expansion_zeroelim(4, ab, cdztail, v); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, vlength, v, - finother); - finswap = finnow; finnow = finother; finother = finswap; - } - - if (adxtail != 0.0) { - if (bdytail != 0.0) { - Two_Product(adxtail, bdytail, adxt_bdyt1, adxt_bdyt0); - Two_One_Product(adxt_bdyt1, adxt_bdyt0, cdz, u3, u[2], u[1], u[0]); - u[3] = u3; - finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, - finother); - finswap = finnow; finnow = finother; finother = finswap; - if (cdztail != 0.0) { - Two_One_Product(adxt_bdyt1, adxt_bdyt0, cdztail, u3, u[2], u[1], u[0]); - u[3] = u3; - finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, - finother); - finswap = finnow; finnow = finother; finother = finswap; - } - } - if (cdytail != 0.0) { - negate = -adxtail; - Two_Product(negate, cdytail, adxt_cdyt1, adxt_cdyt0); - Two_One_Product(adxt_cdyt1, adxt_cdyt0, bdz, u3, u[2], u[1], u[0]); - u[3] = u3; - finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, - finother); - finswap = finnow; finnow = finother; finother = finswap; - if (bdztail != 0.0) { - Two_One_Product(adxt_cdyt1, adxt_cdyt0, bdztail, u3, u[2], u[1], u[0]); - u[3] = u3; - finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, - finother); - finswap = finnow; finnow = finother; finother = finswap; - } - } - } - if (bdxtail != 0.0) { - if (cdytail != 0.0) { - Two_Product(bdxtail, cdytail, bdxt_cdyt1, bdxt_cdyt0); - Two_One_Product(bdxt_cdyt1, bdxt_cdyt0, adz, u3, u[2], u[1], u[0]); - u[3] = u3; - finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, - finother); - finswap = finnow; finnow = finother; finother = finswap; - if (adztail != 0.0) { - Two_One_Product(bdxt_cdyt1, bdxt_cdyt0, adztail, u3, u[2], u[1], u[0]); - u[3] = u3; - finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, - finother); - finswap = finnow; finnow = finother; finother = finswap; - } - } - if (adytail != 0.0) { - negate = -bdxtail; - Two_Product(negate, adytail, bdxt_adyt1, bdxt_adyt0); - Two_One_Product(bdxt_adyt1, bdxt_adyt0, cdz, u3, u[2], u[1], u[0]); - u[3] = u3; - finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, - finother); - finswap = finnow; finnow = finother; finother = finswap; - if (cdztail != 0.0) { - Two_One_Product(bdxt_adyt1, bdxt_adyt0, cdztail, u3, u[2], u[1], u[0]); - u[3] = u3; - finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, - finother); - finswap = finnow; finnow = finother; finother = finswap; - } - } - } - if (cdxtail != 0.0) { - if (adytail != 0.0) { - Two_Product(cdxtail, adytail, cdxt_adyt1, cdxt_adyt0); - Two_One_Product(cdxt_adyt1, cdxt_adyt0, bdz, u3, u[2], u[1], u[0]); - u[3] = u3; - finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, - finother); - finswap = finnow; finnow = finother; finother = finswap; - if (bdztail != 0.0) { - Two_One_Product(cdxt_adyt1, cdxt_adyt0, bdztail, u3, u[2], u[1], u[0]); - u[3] = u3; - finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, - finother); - finswap = finnow; finnow = finother; finother = finswap; - } - } - if (bdytail != 0.0) { - negate = -cdxtail; - Two_Product(negate, bdytail, cdxt_bdyt1, cdxt_bdyt0); - Two_One_Product(cdxt_bdyt1, cdxt_bdyt0, adz, u3, u[2], u[1], u[0]); - u[3] = u3; - finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, - finother); - finswap = finnow; finnow = finother; finother = finswap; - if (adztail != 0.0) { - Two_One_Product(cdxt_bdyt1, cdxt_bdyt0, adztail, u3, u[2], u[1], u[0]); - u[3] = u3; - finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, - finother); - finswap = finnow; finnow = finother; finother = finswap; - } - } - } - - if (adztail != 0.0) { - wlength = scale_expansion_zeroelim(bctlen, bct, adztail, w); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w, - finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (bdztail != 0.0) { - wlength = scale_expansion_zeroelim(catlen, cat, bdztail, w); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w, - finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (cdztail != 0.0) { - wlength = scale_expansion_zeroelim(abtlen, abt, cdztail, w); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w, - finother); - finswap = finnow; finnow = finother; finother = finswap; - } - - return finnow[finlength - 1]; -} - -REAL orient3d ( - __const_ptr(REAL) pa, - __const_ptr(REAL) pb, - __const_ptr(REAL) pc, - __const_ptr(REAL) pd) -{ - REAL adx, bdx, cdx, ady, bdy, cdy, adz, bdz, cdz; - REAL bdxcdy, cdxbdy, cdxady, adxcdy, adxbdy, bdxady; - REAL det; - REAL permanent, errbound; - - adx = pa[0] - pd[0]; - bdx = pb[0] - pd[0]; - cdx = pc[0] - pd[0]; - ady = pa[1] - pd[1]; - bdy = pb[1] - pd[1]; - cdy = pc[1] - pd[1]; - adz = pa[2] - pd[2]; - bdz = pb[2] - pd[2]; - cdz = pc[2] - pd[2]; - - bdxcdy = bdx * cdy; - cdxbdy = cdx * bdy; - - cdxady = cdx * ady; - adxcdy = adx * cdy; - - adxbdy = adx * bdy; - bdxady = bdx * ady; - - det = adz * (bdxcdy - cdxbdy) - + bdz * (cdxady - adxcdy) - + cdz * (adxbdy - bdxady); - - permanent = (Absolute(bdxcdy) + Absolute(cdxbdy)) * Absolute(adz) - + (Absolute(cdxady) + Absolute(adxcdy)) * Absolute(bdz) - + (Absolute(adxbdy) + Absolute(bdxady)) * Absolute(cdz); - errbound = o3derrboundA * permanent; - if ((det > errbound) || (-det > errbound)) { - return det; - } - - return orient3dadapt(pa, pb, pc, pd, permanent); -} - -/*****************************************************************************/ -/* */ -/* incircle() Adaptive exact 2D incircle test. Robust. */ -/* */ -/* Return a positive value if the point pd lies inside the */ -/* circle passing through pa, pb, and pc; a negative value if */ -/* it lies outside; and zero if the four points are cocircular.*/ -/* The points pa, pb, and pc must be in counterclockwise */ -/* order, or the sign of the result will be reversed. */ -/* */ -/* The last three use exact arithmetic to ensure a correct answer. The */ -/* result returned is the determinant of a matrix. In incircle() only, */ -/* this determinant is computed adaptively, in the sense that exact */ -/* arithmetic is used only to the degree it is needed to ensure that the */ -/* returned value has the correct sign. Hence, incircle() is usually quite */ -/* fast, but will run more slowly when the input points are cocircular or */ -/* nearly so. */ -/* */ -/*****************************************************************************/ - -REAL incircleexact ( - __const_ptr(REAL) pa, - __const_ptr(REAL) pb, - __const_ptr(REAL) pc, - __const_ptr(REAL) pd) -{ - REAL axby1, bxcy1, cxdy1, dxay1, axcy1, bxdy1; - REAL bxay1, cxby1, dxcy1, axdy1, cxay1, dxby1; - REAL axby0, bxcy0, cxdy0, dxay0, axcy0, bxdy0; - REAL bxay0, cxby0, dxcy0, axdy0, cxay0, dxby0; - REAL ab[4], bc[4], cd[4], da[4], ac[4], bd[4]; - REAL temp8[8]; - int templen=0; - REAL abc[12], bcd[12], cda[12], dab[12]; - int abclen=0, bcdlen=0, cdalen=0, dablen=0; - REAL det24x[24], det24y[24], det48x[48], det48y[48]; - int xlen=0, ylen=0; - REAL adet[96], bdet[96], cdet[96], ddet[96]; - int alen=0, blen=0, clen=0, dlen=0; - REAL abdet[192], cddet[192]; - int ablen=0, cdlen=0; - REAL deter[384]; - int deterlen=0; - int i; - - REAL bvirt, avirt, bround, around; - REAL c, abig, ahi, alo, bhi, blo; - REAL err1, err2, err3; - REAL _i, _j, _0; - - Two_Product(pa[0], pb[1], axby1, axby0); - Two_Product(pb[0], pa[1], bxay1, bxay0); - Two_Two_Diff(axby1, axby0, bxay1, bxay0, ab[3], ab[2], ab[1], ab[0]); - - Two_Product(pb[0], pc[1], bxcy1, bxcy0); - Two_Product(pc[0], pb[1], cxby1, cxby0); - Two_Two_Diff(bxcy1, bxcy0, cxby1, cxby0, bc[3], bc[2], bc[1], bc[0]); - - Two_Product(pc[0], pd[1], cxdy1, cxdy0); - Two_Product(pd[0], pc[1], dxcy1, dxcy0); - Two_Two_Diff(cxdy1, cxdy0, dxcy1, dxcy0, cd[3], cd[2], cd[1], cd[0]); - - Two_Product(pd[0], pa[1], dxay1, dxay0); - Two_Product(pa[0], pd[1], axdy1, axdy0); - Two_Two_Diff(dxay1, dxay0, axdy1, axdy0, da[3], da[2], da[1], da[0]); - - Two_Product(pa[0], pc[1], axcy1, axcy0); - Two_Product(pc[0], pa[1], cxay1, cxay0); - Two_Two_Diff(axcy1, axcy0, cxay1, cxay0, ac[3], ac[2], ac[1], ac[0]); - - Two_Product(pb[0], pd[1], bxdy1, bxdy0); - Two_Product(pd[0], pb[1], dxby1, dxby0); - Two_Two_Diff(bxdy1, bxdy0, dxby1, dxby0, bd[3], bd[2], bd[1], bd[0]); - - templen = fast_expansion_sum_zeroelim(4, cd, 4, da, temp8); - cdalen = fast_expansion_sum_zeroelim(templen, temp8, 4, ac, cda); - templen = fast_expansion_sum_zeroelim(4, da, 4, ab, temp8); - dablen = fast_expansion_sum_zeroelim(templen, temp8, 4, bd, dab); - for (i = 0; i < 4; i++) { - bd[i] = -bd[i]; - ac[i] = -ac[i]; - } - templen = fast_expansion_sum_zeroelim(4, ab, 4, bc, temp8); - abclen = fast_expansion_sum_zeroelim(templen, temp8, 4, ac, abc); - templen = fast_expansion_sum_zeroelim(4, bc, 4, cd, temp8); - bcdlen = fast_expansion_sum_zeroelim(templen, temp8, 4, bd, bcd); - - xlen = scale_expansion_zeroelim(bcdlen, bcd, pa[0], det24x); - xlen = scale_expansion_zeroelim(xlen, det24x, pa[0], det48x); - ylen = scale_expansion_zeroelim(bcdlen, bcd, pa[1], det24y); - ylen = scale_expansion_zeroelim(ylen, det24y, pa[1], det48y); - alen = fast_expansion_sum_zeroelim(xlen, det48x, ylen, det48y, adet); - - xlen = scale_expansion_zeroelim(cdalen, cda, pb[0], det24x); - xlen = scale_expansion_zeroelim(xlen, det24x, -pb[0], det48x); - ylen = scale_expansion_zeroelim(cdalen, cda, pb[1], det24y); - ylen = scale_expansion_zeroelim(ylen, det24y, -pb[1], det48y); - blen = fast_expansion_sum_zeroelim(xlen, det48x, ylen, det48y, bdet); - - xlen = scale_expansion_zeroelim(dablen, dab, pc[0], det24x); - xlen = scale_expansion_zeroelim(xlen, det24x, pc[0], det48x); - ylen = scale_expansion_zeroelim(dablen, dab, pc[1], det24y); - ylen = scale_expansion_zeroelim(ylen, det24y, pc[1], det48y); - clen = fast_expansion_sum_zeroelim(xlen, det48x, ylen, det48y, cdet); - - xlen = scale_expansion_zeroelim(abclen, abc, pd[0], det24x); - xlen = scale_expansion_zeroelim(xlen, det24x, -pd[0], det48x); - ylen = scale_expansion_zeroelim(abclen, abc, pd[1], det24y); - ylen = scale_expansion_zeroelim(ylen, det24y, -pd[1], det48y); - dlen = fast_expansion_sum_zeroelim(xlen, det48x, ylen, det48y, ddet); - - ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); - cdlen = fast_expansion_sum_zeroelim(clen, cdet, dlen, ddet, cddet); - deterlen = fast_expansion_sum_zeroelim(ablen, abdet, cdlen, cddet, deter); - - return deter[deterlen - 1]; -} - -REAL incircleadapt ( - __const_ptr(REAL) pa, - __const_ptr(REAL) pb, - __const_ptr(REAL) pc, - __const_ptr(REAL) pd, - REAL permanent) -{ - REAL adx, bdx, cdx, ady, bdy, cdy; - REAL det, errbound; - - REAL bdxcdy1, cdxbdy1, cdxady1, adxcdy1, adxbdy1, bdxady1; - REAL bdxcdy0, cdxbdy0, cdxady0, adxcdy0, adxbdy0, bdxady0; - REAL bc[4], ca[4], ab[4]; - REAL bc3, ca3, ab3; - REAL axbc[8], axxbc[16], aybc[8], ayybc[16], adet[32]; - int axbclen=0, axxbclen=0, aybclen=0, ayybclen=0, alen=0; - REAL bxca[8], bxxca[16], byca[8], byyca[16], bdet[32]; - int bxcalen=0, bxxcalen=0, bycalen=0, byycalen=0, blen=0; - REAL cxab[8], cxxab[16], cyab[8], cyyab[16], cdet[32]; - int cxablen=0, cxxablen=0, cyablen=0, cyyablen=0, clen=0; - REAL abdet[64]; - int ablen=0; - REAL fin1[1152], fin2[1152]; - REAL *finnow, *finother, *finswap; - int finlength=0; - - REAL adxtail, bdxtail, cdxtail, adytail, bdytail, cdytail; - REAL adxadx1, adyady1, bdxbdx1, bdybdy1, cdxcdx1, cdycdy1; - REAL adxadx0, adyady0, bdxbdx0, bdybdy0, cdxcdx0, cdycdy0; - REAL aa[4], bb[4], cc[4]; - REAL aa3, bb3, cc3; - REAL ti1, tj1; - REAL ti0, tj0; - REAL u[4], v[4]; - REAL u3, v3; - REAL temp8[8], temp16a[16], temp16b[16], temp16c[16]; - REAL temp32a[32], temp32b[32], temp48[48], temp64[64]; - int temp8len=0, temp16alen=0, temp16blen=0, temp16clen=0; - int temp32alen=0, temp32blen=0, temp48len=0, temp64len=0; - REAL axtbb[8], axtcc[8], aytbb[8], aytcc[8]; - int axtbblen=0, axtcclen=0, aytbblen=0, aytcclen=0; - REAL bxtaa[8], bxtcc[8], bytaa[8], bytcc[8]; - int bxtaalen=0, bxtcclen=0, bytaalen=0, bytcclen=0; - REAL cxtaa[8], cxtbb[8], cytaa[8], cytbb[8]; - int cxtaalen=0, cxtbblen=0, cytaalen=0, cytbblen=0; - REAL axtbc[8], aytbc[8], bxtca[8], bytca[8], cxtab[8], cytab[8]; - int axtbclen=0, aytbclen=0, bxtcalen=0, bytcalen=0, cxtablen=0, cytablen=0; - REAL axtbct[16], aytbct[16], bxtcat[16], bytcat[16], cxtabt[16], cytabt[16]; - int axtbctlen=0, aytbctlen=0; - int bxtcatlen=0, bytcatlen=0; - int cxtabtlen=0, cytabtlen=0; - REAL axtbctt[8], aytbctt[8], bxtcatt[8]; - REAL bytcatt[8], cxtabtt[8], cytabtt[8]; - int axtbcttlen=0, aytbcttlen=0; - int bxtcattlen=0, bytcattlen=0; - int cxtabttlen=0, cytabttlen=0; - REAL abt[8], bct[8], cat[8]; - int abtlen=0, bctlen=0, catlen=0; - REAL abtt[4], bctt[4], catt[4]; - int abttlen=0, bcttlen=0, cattlen=0; - REAL abtt3, bctt3, catt3; - REAL negate; - - REAL bvirt, avirt, bround, around; - REAL c, abig, ahi, alo, bhi, blo; - REAL err1, err2, err3; - REAL _i, _j, _0; - - adx = (REAL) (pa[0] - pd[0]); - bdx = (REAL) (pb[0] - pd[0]); - cdx = (REAL) (pc[0] - pd[0]); - ady = (REAL) (pa[1] - pd[1]); - bdy = (REAL) (pb[1] - pd[1]); - cdy = (REAL) (pc[1] - pd[1]); - - Two_Product(bdx, cdy, bdxcdy1, bdxcdy0); - Two_Product(cdx, bdy, cdxbdy1, cdxbdy0); - Two_Two_Diff(bdxcdy1, bdxcdy0, cdxbdy1, cdxbdy0, bc3, bc[2], bc[1], bc[0]); - bc[3] = bc3; - axbclen = scale_expansion_zeroelim(4, bc, adx, axbc); - axxbclen = scale_expansion_zeroelim(axbclen, axbc, adx, axxbc); - aybclen = scale_expansion_zeroelim(4, bc, ady, aybc); - ayybclen = scale_expansion_zeroelim(aybclen, aybc, ady, ayybc); - alen = fast_expansion_sum_zeroelim(axxbclen, axxbc, ayybclen, ayybc, adet); - - Two_Product(cdx, ady, cdxady1, cdxady0); - Two_Product(adx, cdy, adxcdy1, adxcdy0); - Two_Two_Diff(cdxady1, cdxady0, adxcdy1, adxcdy0, ca3, ca[2], ca[1], ca[0]); - ca[3] = ca3; - bxcalen = scale_expansion_zeroelim(4, ca, bdx, bxca); - bxxcalen = scale_expansion_zeroelim(bxcalen, bxca, bdx, bxxca); - bycalen = scale_expansion_zeroelim(4, ca, bdy, byca); - byycalen = scale_expansion_zeroelim(bycalen, byca, bdy, byyca); - blen = fast_expansion_sum_zeroelim(bxxcalen, bxxca, byycalen, byyca, bdet); - - Two_Product(adx, bdy, adxbdy1, adxbdy0); - Two_Product(bdx, ady, bdxady1, bdxady0); - Two_Two_Diff(adxbdy1, adxbdy0, bdxady1, bdxady0, ab3, ab[2], ab[1], ab[0]); - ab[3] = ab3; - cxablen = scale_expansion_zeroelim(4, ab, cdx, cxab); - cxxablen = scale_expansion_zeroelim(cxablen, cxab, cdx, cxxab); - cyablen = scale_expansion_zeroelim(4, ab, cdy, cyab); - cyyablen = scale_expansion_zeroelim(cyablen, cyab, cdy, cyyab); - clen = fast_expansion_sum_zeroelim(cxxablen, cxxab, cyyablen, cyyab, cdet); - - ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); - finlength = fast_expansion_sum_zeroelim(ablen, abdet, clen, cdet, fin1); - - det = estimate(finlength, fin1); - errbound = iccerrboundB * permanent; - if ((det >= errbound) || (-det >= errbound)) { - return det; - } - - Two_Diff_Tail(pa[0], pd[0], adx, adxtail); - Two_Diff_Tail(pa[1], pd[1], ady, adytail); - Two_Diff_Tail(pb[0], pd[0], bdx, bdxtail); - Two_Diff_Tail(pb[1], pd[1], bdy, bdytail); - Two_Diff_Tail(pc[0], pd[0], cdx, cdxtail); - Two_Diff_Tail(pc[1], pd[1], cdy, cdytail); - if ((adxtail == 0.0) && (bdxtail == 0.0) && (cdxtail == 0.0) - && (adytail == 0.0) && (bdytail == 0.0) && (cdytail == 0.0)) { - return det; - } - - errbound = iccerrboundC * permanent + resulterrbound * Absolute(det); - det += ((adx * adx + ady * ady) * ((bdx * cdytail + cdy * bdxtail) - - (bdy * cdxtail + cdx * bdytail)) - + 2.0 * (adx * adxtail + ady * adytail) * (bdx * cdy - bdy * cdx)) - + ((bdx * bdx + bdy * bdy) * ((cdx * adytail + ady * cdxtail) - - (cdy * adxtail + adx * cdytail)) - + 2.0 * (bdx * bdxtail + bdy * bdytail) * (cdx * ady - cdy * adx)) - + ((cdx * cdx + cdy * cdy) * ((adx * bdytail + bdy * adxtail) - - (ady * bdxtail + bdx * adytail)) - + 2.0 * (cdx * cdxtail + cdy * cdytail) * (adx * bdy - ady * bdx)); - if ((det >= errbound) || (-det >= errbound)) { - return det; - } - - finnow = fin1; - finother = fin2; - - if ((bdxtail != 0.0) || (bdytail != 0.0) - || (cdxtail != 0.0) || (cdytail != 0.0)) { - Square(adx, adxadx1, adxadx0); - Square(ady, adyady1, adyady0); - Two_Two_Sum(adxadx1, adxadx0, adyady1, adyady0, aa3, aa[2], aa[1], aa[0]); - aa[3] = aa3; - } - if ((cdxtail != 0.0) || (cdytail != 0.0) - || (adxtail != 0.0) || (adytail != 0.0)) { - Square(bdx, bdxbdx1, bdxbdx0); - Square(bdy, bdybdy1, bdybdy0); - Two_Two_Sum(bdxbdx1, bdxbdx0, bdybdy1, bdybdy0, bb3, bb[2], bb[1], bb[0]); - bb[3] = bb3; - } - if ((adxtail != 0.0) || (adytail != 0.0) - || (bdxtail != 0.0) || (bdytail != 0.0)) { - Square(cdx, cdxcdx1, cdxcdx0); - Square(cdy, cdycdy1, cdycdy0); - Two_Two_Sum(cdxcdx1, cdxcdx0, cdycdy1, cdycdy0, cc3, cc[2], cc[1], cc[0]); - cc[3] = cc3; - } - - if (adxtail != 0.0) { - axtbclen = scale_expansion_zeroelim(4, bc, adxtail, axtbc); - temp16alen = scale_expansion_zeroelim(axtbclen, axtbc, 2.0 * adx, - temp16a); - - axtcclen = scale_expansion_zeroelim(4, cc, adxtail, axtcc); - temp16blen = scale_expansion_zeroelim(axtcclen, axtcc, bdy, temp16b); - - axtbblen = scale_expansion_zeroelim(4, bb, adxtail, axtbb); - temp16clen = scale_expansion_zeroelim(axtbblen, axtbb, -cdy, temp16c); - - temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp16blen, temp16b, temp32a); - temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, - temp32alen, temp32a, temp48); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, - temp48, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (adytail != 0.0) { - aytbclen = scale_expansion_zeroelim(4, bc, adytail, aytbc); - temp16alen = scale_expansion_zeroelim(aytbclen, aytbc, 2.0 * ady, - temp16a); - - aytbblen = scale_expansion_zeroelim(4, bb, adytail, aytbb); - temp16blen = scale_expansion_zeroelim(aytbblen, aytbb, cdx, temp16b); - - aytcclen = scale_expansion_zeroelim(4, cc, adytail, aytcc); - temp16clen = scale_expansion_zeroelim(aytcclen, aytcc, -bdx, temp16c); - - temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp16blen, temp16b, temp32a); - temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, - temp32alen, temp32a, temp48); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, - temp48, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (bdxtail != 0.0) { - bxtcalen = scale_expansion_zeroelim(4, ca, bdxtail, bxtca); - temp16alen = scale_expansion_zeroelim(bxtcalen, bxtca, 2.0 * bdx, - temp16a); - - bxtaalen = scale_expansion_zeroelim(4, aa, bdxtail, bxtaa); - temp16blen = scale_expansion_zeroelim(bxtaalen, bxtaa, cdy, temp16b); - - bxtcclen = scale_expansion_zeroelim(4, cc, bdxtail, bxtcc); - temp16clen = scale_expansion_zeroelim(bxtcclen, bxtcc, -ady, temp16c); - - temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp16blen, temp16b, temp32a); - temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, - temp32alen, temp32a, temp48); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, - temp48, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (bdytail != 0.0) { - bytcalen = scale_expansion_zeroelim(4, ca, bdytail, bytca); - temp16alen = scale_expansion_zeroelim(bytcalen, bytca, 2.0 * bdy, - temp16a); - - bytcclen = scale_expansion_zeroelim(4, cc, bdytail, bytcc); - temp16blen = scale_expansion_zeroelim(bytcclen, bytcc, adx, temp16b); - - bytaalen = scale_expansion_zeroelim(4, aa, bdytail, bytaa); - temp16clen = scale_expansion_zeroelim(bytaalen, bytaa, -cdx, temp16c); - - temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp16blen, temp16b, temp32a); - temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, - temp32alen, temp32a, temp48); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, - temp48, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (cdxtail != 0.0) { - cxtablen = scale_expansion_zeroelim(4, ab, cdxtail, cxtab); - temp16alen = scale_expansion_zeroelim(cxtablen, cxtab, 2.0 * cdx, - temp16a); - - cxtbblen = scale_expansion_zeroelim(4, bb, cdxtail, cxtbb); - temp16blen = scale_expansion_zeroelim(cxtbblen, cxtbb, ady, temp16b); - - cxtaalen = scale_expansion_zeroelim(4, aa, cdxtail, cxtaa); - temp16clen = scale_expansion_zeroelim(cxtaalen, cxtaa, -bdy, temp16c); - - temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp16blen, temp16b, temp32a); - temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, - temp32alen, temp32a, temp48); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, - temp48, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (cdytail != 0.0) { - cytablen = scale_expansion_zeroelim(4, ab, cdytail, cytab); - temp16alen = scale_expansion_zeroelim(cytablen, cytab, 2.0 * cdy, - temp16a); - - cytaalen = scale_expansion_zeroelim(4, aa, cdytail, cytaa); - temp16blen = scale_expansion_zeroelim(cytaalen, cytaa, bdx, temp16b); - - cytbblen = scale_expansion_zeroelim(4, bb, cdytail, cytbb); - temp16clen = scale_expansion_zeroelim(cytbblen, cytbb, -adx, temp16c); - - temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp16blen, temp16b, temp32a); - temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, - temp32alen, temp32a, temp48); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, - temp48, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - - if ((adxtail != 0.0) || (adytail != 0.0)) { - if ((bdxtail != 0.0) || (bdytail != 0.0) - || (cdxtail != 0.0) || (cdytail != 0.0)) { - Two_Product(bdxtail, cdy, ti1, ti0); - Two_Product(bdx, cdytail, tj1, tj0); - Two_Two_Sum(ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0]); - u[3] = u3; - negate = -bdy; - Two_Product(cdxtail, negate, ti1, ti0); - negate = -bdytail; - Two_Product(cdx, negate, tj1, tj0); - Two_Two_Sum(ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0]); - v[3] = v3; - bctlen = fast_expansion_sum_zeroelim(4, u, 4, v, bct); - - Two_Product(bdxtail, cdytail, ti1, ti0); - Two_Product(cdxtail, bdytail, tj1, tj0); - Two_Two_Diff(ti1, ti0, tj1, tj0, bctt3, bctt[2], bctt[1], bctt[0]); - bctt[3] = bctt3; - bcttlen = 4; - } else { - bct[0] = 0.0; - bctlen = 1; - bctt[0] = 0.0; - bcttlen = 1; - } - - if (adxtail != 0.0) { - temp16alen = scale_expansion_zeroelim(axtbclen, axtbc, adxtail, temp16a); - axtbctlen = scale_expansion_zeroelim(bctlen, bct, adxtail, axtbct); - temp32alen = scale_expansion_zeroelim(axtbctlen, axtbct, 2.0 * adx, - temp32a); - temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp32alen, temp32a, temp48); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, - temp48, finother); - finswap = finnow; finnow = finother; finother = finswap; - if (bdytail != 0.0) { - temp8len = scale_expansion_zeroelim(4, cc, adxtail, temp8); - temp16alen = scale_expansion_zeroelim(temp8len, temp8, bdytail, - temp16a); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, - temp16a, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (cdytail != 0.0) { - temp8len = scale_expansion_zeroelim(4, bb, -adxtail, temp8); - temp16alen = scale_expansion_zeroelim(temp8len, temp8, cdytail, - temp16a); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, - temp16a, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - - temp32alen = scale_expansion_zeroelim(axtbctlen, axtbct, adxtail, - temp32a); - axtbcttlen = scale_expansion_zeroelim(bcttlen, bctt, adxtail, axtbctt); - temp16alen = scale_expansion_zeroelim(axtbcttlen, axtbctt, 2.0 * adx, - temp16a); - temp16blen = scale_expansion_zeroelim(axtbcttlen, axtbctt, adxtail, - temp16b); - temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp16blen, temp16b, temp32b); - temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, - temp32blen, temp32b, temp64); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, - temp64, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (adytail != 0.0) { - temp16alen = scale_expansion_zeroelim(aytbclen, aytbc, adytail, temp16a); - aytbctlen = scale_expansion_zeroelim(bctlen, bct, adytail, aytbct); - temp32alen = scale_expansion_zeroelim(aytbctlen, aytbct, 2.0 * ady, - temp32a); - temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp32alen, temp32a, temp48); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, - temp48, finother); - finswap = finnow; finnow = finother; finother = finswap; - - - temp32alen = scale_expansion_zeroelim(aytbctlen, aytbct, adytail, - temp32a); - aytbcttlen = scale_expansion_zeroelim(bcttlen, bctt, adytail, aytbctt); - temp16alen = scale_expansion_zeroelim(aytbcttlen, aytbctt, 2.0 * ady, - temp16a); - temp16blen = scale_expansion_zeroelim(aytbcttlen, aytbctt, adytail, - temp16b); - temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp16blen, temp16b, temp32b); - temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, - temp32blen, temp32b, temp64); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, - temp64, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - } - if ((bdxtail != 0.0) || (bdytail != 0.0)) { - if ((cdxtail != 0.0) || (cdytail != 0.0) - || (adxtail != 0.0) || (adytail != 0.0)) { - Two_Product(cdxtail, ady, ti1, ti0); - Two_Product(cdx, adytail, tj1, tj0); - Two_Two_Sum(ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0]); - u[3] = u3; - negate = -cdy; - Two_Product(adxtail, negate, ti1, ti0); - negate = -cdytail; - Two_Product(adx, negate, tj1, tj0); - Two_Two_Sum(ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0]); - v[3] = v3; - catlen = fast_expansion_sum_zeroelim(4, u, 4, v, cat); - - Two_Product(cdxtail, adytail, ti1, ti0); - Two_Product(adxtail, cdytail, tj1, tj0); - Two_Two_Diff(ti1, ti0, tj1, tj0, catt3, catt[2], catt[1], catt[0]); - catt[3] = catt3; - cattlen = 4; - } else { - cat[0] = 0.0; - catlen = 1; - catt[0] = 0.0; - cattlen = 1; - } - - if (bdxtail != 0.0) { - temp16alen = scale_expansion_zeroelim(bxtcalen, bxtca, bdxtail, temp16a); - bxtcatlen = scale_expansion_zeroelim(catlen, cat, bdxtail, bxtcat); - temp32alen = scale_expansion_zeroelim(bxtcatlen, bxtcat, 2.0 * bdx, - temp32a); - temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp32alen, temp32a, temp48); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, - temp48, finother); - finswap = finnow; finnow = finother; finother = finswap; - if (cdytail != 0.0) { - temp8len = scale_expansion_zeroelim(4, aa, bdxtail, temp8); - temp16alen = scale_expansion_zeroelim(temp8len, temp8, cdytail, - temp16a); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, - temp16a, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (adytail != 0.0) { - temp8len = scale_expansion_zeroelim(4, cc, -bdxtail, temp8); - temp16alen = scale_expansion_zeroelim(temp8len, temp8, adytail, - temp16a); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, - temp16a, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - - temp32alen = scale_expansion_zeroelim(bxtcatlen, bxtcat, bdxtail, - temp32a); - bxtcattlen = scale_expansion_zeroelim(cattlen, catt, bdxtail, bxtcatt); - temp16alen = scale_expansion_zeroelim(bxtcattlen, bxtcatt, 2.0 * bdx, - temp16a); - temp16blen = scale_expansion_zeroelim(bxtcattlen, bxtcatt, bdxtail, - temp16b); - temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp16blen, temp16b, temp32b); - temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, - temp32blen, temp32b, temp64); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, - temp64, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (bdytail != 0.0) { - temp16alen = scale_expansion_zeroelim(bytcalen, bytca, bdytail, temp16a); - bytcatlen = scale_expansion_zeroelim(catlen, cat, bdytail, bytcat); - temp32alen = scale_expansion_zeroelim(bytcatlen, bytcat, 2.0 * bdy, - temp32a); - temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp32alen, temp32a, temp48); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, - temp48, finother); - finswap = finnow; finnow = finother; finother = finswap; - - - temp32alen = scale_expansion_zeroelim(bytcatlen, bytcat, bdytail, - temp32a); - bytcattlen = scale_expansion_zeroelim(cattlen, catt, bdytail, bytcatt); - temp16alen = scale_expansion_zeroelim(bytcattlen, bytcatt, 2.0 * bdy, - temp16a); - temp16blen = scale_expansion_zeroelim(bytcattlen, bytcatt, bdytail, - temp16b); - temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp16blen, temp16b, temp32b); - temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, - temp32blen, temp32b, temp64); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, - temp64, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - } - if ((cdxtail != 0.0) || (cdytail != 0.0)) { - if ((adxtail != 0.0) || (adytail != 0.0) - || (bdxtail != 0.0) || (bdytail != 0.0)) { - Two_Product(adxtail, bdy, ti1, ti0); - Two_Product(adx, bdytail, tj1, tj0); - Two_Two_Sum(ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0]); - u[3] = u3; - negate = -ady; - Two_Product(bdxtail, negate, ti1, ti0); - negate = -adytail; - Two_Product(bdx, negate, tj1, tj0); - Two_Two_Sum(ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0]); - v[3] = v3; - abtlen = fast_expansion_sum_zeroelim(4, u, 4, v, abt); - - Two_Product(adxtail, bdytail, ti1, ti0); - Two_Product(bdxtail, adytail, tj1, tj0); - Two_Two_Diff(ti1, ti0, tj1, tj0, abtt3, abtt[2], abtt[1], abtt[0]); - abtt[3] = abtt3; - abttlen = 4; - } else { - abt[0] = 0.0; - abtlen = 1; - abtt[0] = 0.0; - abttlen = 1; - } - - if (cdxtail != 0.0) { - temp16alen = scale_expansion_zeroelim(cxtablen, cxtab, cdxtail, temp16a); - cxtabtlen = scale_expansion_zeroelim(abtlen, abt, cdxtail, cxtabt); - temp32alen = scale_expansion_zeroelim(cxtabtlen, cxtabt, 2.0 * cdx, - temp32a); - temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp32alen, temp32a, temp48); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, - temp48, finother); - finswap = finnow; finnow = finother; finother = finswap; - if (adytail != 0.0) { - temp8len = scale_expansion_zeroelim(4, bb, cdxtail, temp8); - temp16alen = scale_expansion_zeroelim(temp8len, temp8, adytail, - temp16a); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, - temp16a, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (bdytail != 0.0) { - temp8len = scale_expansion_zeroelim(4, aa, -cdxtail, temp8); - temp16alen = scale_expansion_zeroelim(temp8len, temp8, bdytail, - temp16a); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, - temp16a, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - - temp32alen = scale_expansion_zeroelim(cxtabtlen, cxtabt, cdxtail, - temp32a); - cxtabttlen = scale_expansion_zeroelim(abttlen, abtt, cdxtail, cxtabtt); - temp16alen = scale_expansion_zeroelim(cxtabttlen, cxtabtt, 2.0 * cdx, - temp16a); - temp16blen = scale_expansion_zeroelim(cxtabttlen, cxtabtt, cdxtail, - temp16b); - temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp16blen, temp16b, temp32b); - temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, - temp32blen, temp32b, temp64); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, - temp64, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (cdytail != 0.0) { - temp16alen = scale_expansion_zeroelim(cytablen, cytab, cdytail, temp16a); - cytabtlen = scale_expansion_zeroelim(abtlen, abt, cdytail, cytabt); - temp32alen = scale_expansion_zeroelim(cytabtlen, cytabt, 2.0 * cdy, - temp32a); - temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp32alen, temp32a, temp48); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, - temp48, finother); - finswap = finnow; finnow = finother; finother = finswap; - - - temp32alen = scale_expansion_zeroelim(cytabtlen, cytabt, cdytail, - temp32a); - cytabttlen = scale_expansion_zeroelim(abttlen, abtt, cdytail, cytabtt); - temp16alen = scale_expansion_zeroelim(cytabttlen, cytabtt, 2.0 * cdy, - temp16a); - temp16blen = scale_expansion_zeroelim(cytabttlen, cytabtt, cdytail, - temp16b); - temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp16blen, temp16b, temp32b); - temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, - temp32blen, temp32b, temp64); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, - temp64, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - } - - return finnow[finlength - 1]; -} - -REAL incircle ( - __const_ptr(REAL) pa, - __const_ptr(REAL) pb, - __const_ptr(REAL) pc, - __const_ptr(REAL) pd) -{ - REAL adx, bdx, cdx, ady, bdy, cdy; - REAL bdxcdy, cdxbdy, cdxady, adxcdy, adxbdy, bdxady; - REAL alift, blift, clift; - REAL det; - REAL permanent, errbound; - - adx = pa[0] - pd[0]; - bdx = pb[0] - pd[0]; - cdx = pc[0] - pd[0]; - ady = pa[1] - pd[1]; - bdy = pb[1] - pd[1]; - cdy = pc[1] - pd[1]; - - bdxcdy = bdx * cdy; - cdxbdy = cdx * bdy; - alift = adx * adx + ady * ady; - - cdxady = cdx * ady; - adxcdy = adx * cdy; - blift = bdx * bdx + bdy * bdy; - - adxbdy = adx * bdy; - bdxady = bdx * ady; - clift = cdx * cdx + cdy * cdy; - - det = alift * (bdxcdy - cdxbdy) - + blift * (cdxady - adxcdy) - + clift * (adxbdy - bdxady); - - permanent = (Absolute(bdxcdy) + Absolute(cdxbdy)) * alift - + (Absolute(cdxady) + Absolute(adxcdy)) * blift - + (Absolute(adxbdy) + Absolute(bdxady)) * clift; - errbound = iccerrboundA * permanent; - if ((det > errbound) || (-det > errbound)) { - return det; - } - - return incircleadapt(pa, pb, pc, pd, permanent); -} - -/*****************************************************************************/ -/* */ -/* insphere() Adaptive exact 3D insphere test. Robust. */ -/* */ -/* Return a positive value if the point pe lies inside the */ -/* sphere passing through pa, pb, pc, and pd; a negative value */ -/* if it lies outside; and zero if the five points are */ -/* cospherical. The points pa, pb, pc, and pd must be ordered */ -/* so that they have a positive orientation (as defined by */ -/* orient3d()), or the sign of the result will be reversed. */ -/* */ -/* The last three use exact arithmetic to ensure a correct answer. The */ -/* result returned is the determinant of a matrix. In insphere() only, */ -/* this determinant is computed adaptively, in the sense that exact */ -/* arithmetic is used only to the degree it is needed to ensure that the */ -/* returned value has the correct sign. Hence, insphere() is usually quite */ -/* fast, but will run more slowly when the input points are cospherical or */ -/* nearly so. */ -/* */ -/*****************************************************************************/ - -REAL insphereexact ( - __const_ptr(REAL) pa, - __const_ptr(REAL) pb, - __const_ptr(REAL) pc, - __const_ptr(REAL) pd, - __const_ptr(REAL) pe) -{ - REAL axby1, bxcy1, cxdy1, dxey1, exay1; - REAL bxay1, cxby1, dxcy1, exdy1, axey1; - REAL axcy1, bxdy1, cxey1, dxay1, exby1; - REAL cxay1, dxby1, excy1, axdy1, bxey1; - REAL axby0, bxcy0, cxdy0, dxey0, exay0; - REAL bxay0, cxby0, dxcy0, exdy0, axey0; - REAL axcy0, bxdy0, cxey0, dxay0, exby0; - REAL cxay0, dxby0, excy0, axdy0, bxey0; - REAL ab[4], bc[4], cd[4], de[4], ea[4]; - REAL ac[4], bd[4], ce[4], da[4], eb[4]; - REAL temp8a[8], temp8b[8], temp16[16]; - int temp8alen=0, temp8blen=0, temp16len=0; - REAL abc[24], bcd[24], cde[24], dea[24], eab[24]; - REAL abd[24], bce[24], cda[24], deb[24], eac[24]; - int abclen=0, bcdlen=0, cdelen=0, dealen=0, eablen=0; - int abdlen=0, bcelen=0, cdalen=0, deblen=0, eaclen=0; - REAL temp48a[48], temp48b[48]; - int temp48alen=0, temp48blen=0; - REAL abcd[96], bcde[96], cdea[96], deab[96], eabc[96]; - int abcdlen=0, bcdelen=0, cdealen=0, deablen=0, eabclen=0; - REAL temp192[192]; - REAL det384x[384], det384y[384], det384z[384]; - int xlen=0, ylen=0, zlen=0; - REAL detxy[768]; - int xylen=0; - REAL adet[1152], bdet[1152], cdet[1152], ddet[1152], edet[1152]; - int alen=0, blen=0, clen=0, dlen=0, elen=0; - REAL abdet[2304], cddet[2304], cdedet[3456]; - int ablen=0, cdlen=0; - REAL deter[5760]; - int deterlen=0; - int i; - - REAL bvirt, avirt, bround, around; - REAL c, abig, ahi, alo, bhi, blo; - REAL err1, err2, err3; - REAL _i, _j, _0; - - Two_Product(pa[0], pb[1], axby1, axby0); - Two_Product(pb[0], pa[1], bxay1, bxay0); - Two_Two_Diff(axby1, axby0, bxay1, bxay0, ab[3], ab[2], ab[1], ab[0]); - - Two_Product(pb[0], pc[1], bxcy1, bxcy0); - Two_Product(pc[0], pb[1], cxby1, cxby0); - Two_Two_Diff(bxcy1, bxcy0, cxby1, cxby0, bc[3], bc[2], bc[1], bc[0]); - - Two_Product(pc[0], pd[1], cxdy1, cxdy0); - Two_Product(pd[0], pc[1], dxcy1, dxcy0); - Two_Two_Diff(cxdy1, cxdy0, dxcy1, dxcy0, cd[3], cd[2], cd[1], cd[0]); - - Two_Product(pd[0], pe[1], dxey1, dxey0); - Two_Product(pe[0], pd[1], exdy1, exdy0); - Two_Two_Diff(dxey1, dxey0, exdy1, exdy0, de[3], de[2], de[1], de[0]); - - Two_Product(pe[0], pa[1], exay1, exay0); - Two_Product(pa[0], pe[1], axey1, axey0); - Two_Two_Diff(exay1, exay0, axey1, axey0, ea[3], ea[2], ea[1], ea[0]); - - Two_Product(pa[0], pc[1], axcy1, axcy0); - Two_Product(pc[0], pa[1], cxay1, cxay0); - Two_Two_Diff(axcy1, axcy0, cxay1, cxay0, ac[3], ac[2], ac[1], ac[0]); - - Two_Product(pb[0], pd[1], bxdy1, bxdy0); - Two_Product(pd[0], pb[1], dxby1, dxby0); - Two_Two_Diff(bxdy1, bxdy0, dxby1, dxby0, bd[3], bd[2], bd[1], bd[0]); - - Two_Product(pc[0], pe[1], cxey1, cxey0); - Two_Product(pe[0], pc[1], excy1, excy0); - Two_Two_Diff(cxey1, cxey0, excy1, excy0, ce[3], ce[2], ce[1], ce[0]); - - Two_Product(pd[0], pa[1], dxay1, dxay0); - Two_Product(pa[0], pd[1], axdy1, axdy0); - Two_Two_Diff(dxay1, dxay0, axdy1, axdy0, da[3], da[2], da[1], da[0]); - - Two_Product(pe[0], pb[1], exby1, exby0); - Two_Product(pb[0], pe[1], bxey1, bxey0); - Two_Two_Diff(exby1, exby0, bxey1, bxey0, eb[3], eb[2], eb[1], eb[0]); - - temp8alen = scale_expansion_zeroelim(4, bc, pa[2], temp8a); - temp8blen = scale_expansion_zeroelim(4, ac, -pb[2], temp8b); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, - temp16); - temp8alen = scale_expansion_zeroelim(4, ab, pc[2], temp8a); - abclen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, - abc); - - temp8alen = scale_expansion_zeroelim(4, cd, pb[2], temp8a); - temp8blen = scale_expansion_zeroelim(4, bd, -pc[2], temp8b); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, - temp16); - temp8alen = scale_expansion_zeroelim(4, bc, pd[2], temp8a); - bcdlen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, - bcd); - - temp8alen = scale_expansion_zeroelim(4, de, pc[2], temp8a); - temp8blen = scale_expansion_zeroelim(4, ce, -pd[2], temp8b); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, - temp16); - temp8alen = scale_expansion_zeroelim(4, cd, pe[2], temp8a); - cdelen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, - cde); - - temp8alen = scale_expansion_zeroelim(4, ea, pd[2], temp8a); - temp8blen = scale_expansion_zeroelim(4, da, -pe[2], temp8b); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, - temp16); - temp8alen = scale_expansion_zeroelim(4, de, pa[2], temp8a); - dealen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, - dea); - - temp8alen = scale_expansion_zeroelim(4, ab, pe[2], temp8a); - temp8blen = scale_expansion_zeroelim(4, eb, -pa[2], temp8b); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, - temp16); - temp8alen = scale_expansion_zeroelim(4, ea, pb[2], temp8a); - eablen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, - eab); - - temp8alen = scale_expansion_zeroelim(4, bd, pa[2], temp8a); - temp8blen = scale_expansion_zeroelim(4, da, pb[2], temp8b); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, - temp16); - temp8alen = scale_expansion_zeroelim(4, ab, pd[2], temp8a); - abdlen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, - abd); - - temp8alen = scale_expansion_zeroelim(4, ce, pb[2], temp8a); - temp8blen = scale_expansion_zeroelim(4, eb, pc[2], temp8b); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, - temp16); - temp8alen = scale_expansion_zeroelim(4, bc, pe[2], temp8a); - bcelen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, - bce); - - temp8alen = scale_expansion_zeroelim(4, da, pc[2], temp8a); - temp8blen = scale_expansion_zeroelim(4, ac, pd[2], temp8b); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, - temp16); - temp8alen = scale_expansion_zeroelim(4, cd, pa[2], temp8a); - cdalen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, - cda); - - temp8alen = scale_expansion_zeroelim(4, eb, pd[2], temp8a); - temp8blen = scale_expansion_zeroelim(4, bd, pe[2], temp8b); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, - temp16); - temp8alen = scale_expansion_zeroelim(4, de, pb[2], temp8a); - deblen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, - deb); - - temp8alen = scale_expansion_zeroelim(4, ac, pe[2], temp8a); - temp8blen = scale_expansion_zeroelim(4, ce, pa[2], temp8b); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, - temp16); - temp8alen = scale_expansion_zeroelim(4, ea, pc[2], temp8a); - eaclen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, - eac); - - temp48alen = fast_expansion_sum_zeroelim(cdelen, cde, bcelen, bce, temp48a); - temp48blen = fast_expansion_sum_zeroelim(deblen, deb, bcdlen, bcd, temp48b); - for (i = 0; i < temp48blen; i++) { - temp48b[i] = -temp48b[i]; - } - bcdelen = fast_expansion_sum_zeroelim(temp48alen, temp48a, - temp48blen, temp48b, bcde); - xlen = scale_expansion_zeroelim(bcdelen, bcde, pa[0], temp192); - xlen = scale_expansion_zeroelim(xlen, temp192, pa[0], det384x); - ylen = scale_expansion_zeroelim(bcdelen, bcde, pa[1], temp192); - ylen = scale_expansion_zeroelim(ylen, temp192, pa[1], det384y); - zlen = scale_expansion_zeroelim(bcdelen, bcde, pa[2], temp192); - zlen = scale_expansion_zeroelim(zlen, temp192, pa[2], det384z); - xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy); - alen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, adet); - - temp48alen = fast_expansion_sum_zeroelim(dealen, dea, cdalen, cda, temp48a); - temp48blen = fast_expansion_sum_zeroelim(eaclen, eac, cdelen, cde, temp48b); - for (i = 0; i < temp48blen; i++) { - temp48b[i] = -temp48b[i]; - } - cdealen = fast_expansion_sum_zeroelim(temp48alen, temp48a, - temp48blen, temp48b, cdea); - xlen = scale_expansion_zeroelim(cdealen, cdea, pb[0], temp192); - xlen = scale_expansion_zeroelim(xlen, temp192, pb[0], det384x); - ylen = scale_expansion_zeroelim(cdealen, cdea, pb[1], temp192); - ylen = scale_expansion_zeroelim(ylen, temp192, pb[1], det384y); - zlen = scale_expansion_zeroelim(cdealen, cdea, pb[2], temp192); - zlen = scale_expansion_zeroelim(zlen, temp192, pb[2], det384z); - xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy); - blen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, bdet); - - temp48alen = fast_expansion_sum_zeroelim(eablen, eab, deblen, deb, temp48a); - temp48blen = fast_expansion_sum_zeroelim(abdlen, abd, dealen, dea, temp48b); - for (i = 0; i < temp48blen; i++) { - temp48b[i] = -temp48b[i]; - } - deablen = fast_expansion_sum_zeroelim(temp48alen, temp48a, - temp48blen, temp48b, deab); - xlen = scale_expansion_zeroelim(deablen, deab, pc[0], temp192); - xlen = scale_expansion_zeroelim(xlen, temp192, pc[0], det384x); - ylen = scale_expansion_zeroelim(deablen, deab, pc[1], temp192); - ylen = scale_expansion_zeroelim(ylen, temp192, pc[1], det384y); - zlen = scale_expansion_zeroelim(deablen, deab, pc[2], temp192); - zlen = scale_expansion_zeroelim(zlen, temp192, pc[2], det384z); - xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy); - clen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, cdet); - - temp48alen = fast_expansion_sum_zeroelim(abclen, abc, eaclen, eac, temp48a); - temp48blen = fast_expansion_sum_zeroelim(bcelen, bce, eablen, eab, temp48b); - for (i = 0; i < temp48blen; i++) { - temp48b[i] = -temp48b[i]; - } - eabclen = fast_expansion_sum_zeroelim(temp48alen, temp48a, - temp48blen, temp48b, eabc); - xlen = scale_expansion_zeroelim(eabclen, eabc, pd[0], temp192); - xlen = scale_expansion_zeroelim(xlen, temp192, pd[0], det384x); - ylen = scale_expansion_zeroelim(eabclen, eabc, pd[1], temp192); - ylen = scale_expansion_zeroelim(ylen, temp192, pd[1], det384y); - zlen = scale_expansion_zeroelim(eabclen, eabc, pd[2], temp192); - zlen = scale_expansion_zeroelim(zlen, temp192, pd[2], det384z); - xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy); - dlen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, ddet); - - temp48alen = fast_expansion_sum_zeroelim(bcdlen, bcd, abdlen, abd, temp48a); - temp48blen = fast_expansion_sum_zeroelim(cdalen, cda, abclen, abc, temp48b); - for (i = 0; i < temp48blen; i++) { - temp48b[i] = -temp48b[i]; - } - abcdlen = fast_expansion_sum_zeroelim(temp48alen, temp48a, - temp48blen, temp48b, abcd); - xlen = scale_expansion_zeroelim(abcdlen, abcd, pe[0], temp192); - xlen = scale_expansion_zeroelim(xlen, temp192, pe[0], det384x); - ylen = scale_expansion_zeroelim(abcdlen, abcd, pe[1], temp192); - ylen = scale_expansion_zeroelim(ylen, temp192, pe[1], det384y); - zlen = scale_expansion_zeroelim(abcdlen, abcd, pe[2], temp192); - zlen = scale_expansion_zeroelim(zlen, temp192, pe[2], det384z); - xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy); - elen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, edet); - - ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); - cdlen = fast_expansion_sum_zeroelim(clen, cdet, dlen, ddet, cddet); - cdelen = fast_expansion_sum_zeroelim(cdlen, cddet, elen, edet, cdedet); - deterlen = fast_expansion_sum_zeroelim(ablen, abdet, cdelen, cdedet, deter); - - return deter[deterlen - 1]; -} - -REAL insphereadapt ( - __const_ptr(REAL) pa, - __const_ptr(REAL) pb, - __const_ptr(REAL) pc, - __const_ptr(REAL) pd, - __const_ptr(REAL) pe, - REAL permanent) -{ - REAL aex, bex, cex, dex, aey, bey, cey, dey, aez, bez, cez, dez; - REAL det, errbound; - - REAL aexbey1, bexaey1, bexcey1, cexbey1; - REAL cexdey1, dexcey1, dexaey1, aexdey1; - REAL aexcey1, cexaey1, bexdey1, dexbey1; - REAL aexbey0, bexaey0, bexcey0, cexbey0; - REAL cexdey0, dexcey0, dexaey0, aexdey0; - REAL aexcey0, cexaey0, bexdey0, dexbey0; - REAL ab[4], bc[4], cd[4], da[4], ac[4], bd[4]; - REAL ab3, bc3, cd3, da3, ac3, bd3; - REAL abeps, bceps, cdeps, daeps, aceps, bdeps; - REAL temp8a[8], temp8b[8], temp8c[8], temp16[16], temp24[24], temp48[48]; - int temp8alen=0, temp8blen=0, temp8clen=0; - int temp16len=0, temp24len=0, temp48len=0; - REAL xdet[96], ydet[96], zdet[96], xydet[192]; - int xlen=0, ylen=0, zlen=0, xylen=0; - REAL adet[288], bdet[288], cdet[288], ddet[288]; - int alen=0, blen=0, clen=0, dlen=0; - REAL abdet[576], cddet[576]; - int ablen=0, cdlen=0; - REAL fin1[1152]; - int finlength=0; - - REAL aextail, bextail, cextail, dextail; - REAL aeytail, beytail, ceytail, deytail; - REAL aeztail, beztail, ceztail, deztail; - - REAL bvirt, avirt, bround, around; - REAL c, abig, ahi, alo, bhi, blo; - REAL err1, err2, err3; - REAL _i, _j, _0; - - aex = (REAL) (pa[0] - pe[0]); - bex = (REAL) (pb[0] - pe[0]); - cex = (REAL) (pc[0] - pe[0]); - dex = (REAL) (pd[0] - pe[0]); - aey = (REAL) (pa[1] - pe[1]); - bey = (REAL) (pb[1] - pe[1]); - cey = (REAL) (pc[1] - pe[1]); - dey = (REAL) (pd[1] - pe[1]); - aez = (REAL) (pa[2] - pe[2]); - bez = (REAL) (pb[2] - pe[2]); - cez = (REAL) (pc[2] - pe[2]); - dez = (REAL) (pd[2] - pe[2]); - - Two_Product(aex, bey, aexbey1, aexbey0); - Two_Product(bex, aey, bexaey1, bexaey0); - Two_Two_Diff(aexbey1, aexbey0, bexaey1, bexaey0, ab3, ab[2], ab[1], ab[0]); - ab[3] = ab3; - - Two_Product(bex, cey, bexcey1, bexcey0); - Two_Product(cex, bey, cexbey1, cexbey0); - Two_Two_Diff(bexcey1, bexcey0, cexbey1, cexbey0, bc3, bc[2], bc[1], bc[0]); - bc[3] = bc3; - - Two_Product(cex, dey, cexdey1, cexdey0); - Two_Product(dex, cey, dexcey1, dexcey0); - Two_Two_Diff(cexdey1, cexdey0, dexcey1, dexcey0, cd3, cd[2], cd[1], cd[0]); - cd[3] = cd3; - - Two_Product(dex, aey, dexaey1, dexaey0); - Two_Product(aex, dey, aexdey1, aexdey0); - Two_Two_Diff(dexaey1, dexaey0, aexdey1, aexdey0, da3, da[2], da[1], da[0]); - da[3] = da3; - - Two_Product(aex, cey, aexcey1, aexcey0); - Two_Product(cex, aey, cexaey1, cexaey0); - Two_Two_Diff(aexcey1, aexcey0, cexaey1, cexaey0, ac3, ac[2], ac[1], ac[0]); - ac[3] = ac3; - - Two_Product(bex, dey, bexdey1, bexdey0); - Two_Product(dex, bey, dexbey1, dexbey0); - Two_Two_Diff(bexdey1, bexdey0, dexbey1, dexbey0, bd3, bd[2], bd[1], bd[0]); - bd[3] = bd3; - - temp8alen = scale_expansion_zeroelim(4, cd, bez, temp8a); - temp8blen = scale_expansion_zeroelim(4, bd, -cez, temp8b); - temp8clen = scale_expansion_zeroelim(4, bc, dez, temp8c); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, - temp8blen, temp8b, temp16); - temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c, - temp16len, temp16, temp24); - temp48len = scale_expansion_zeroelim(temp24len, temp24, aex, temp48); - xlen = scale_expansion_zeroelim(temp48len, temp48, -aex, xdet); - temp48len = scale_expansion_zeroelim(temp24len, temp24, aey, temp48); - ylen = scale_expansion_zeroelim(temp48len, temp48, -aey, ydet); - temp48len = scale_expansion_zeroelim(temp24len, temp24, aez, temp48); - zlen = scale_expansion_zeroelim(temp48len, temp48, -aez, zdet); - xylen = fast_expansion_sum_zeroelim(xlen, xdet, ylen, ydet, xydet); - alen = fast_expansion_sum_zeroelim(xylen, xydet, zlen, zdet, adet); - - temp8alen = scale_expansion_zeroelim(4, da, cez, temp8a); - temp8blen = scale_expansion_zeroelim(4, ac, dez, temp8b); - temp8clen = scale_expansion_zeroelim(4, cd, aez, temp8c); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, - temp8blen, temp8b, temp16); - temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c, - temp16len, temp16, temp24); - temp48len = scale_expansion_zeroelim(temp24len, temp24, bex, temp48); - xlen = scale_expansion_zeroelim(temp48len, temp48, bex, xdet); - temp48len = scale_expansion_zeroelim(temp24len, temp24, bey, temp48); - ylen = scale_expansion_zeroelim(temp48len, temp48, bey, ydet); - temp48len = scale_expansion_zeroelim(temp24len, temp24, bez, temp48); - zlen = scale_expansion_zeroelim(temp48len, temp48, bez, zdet); - xylen = fast_expansion_sum_zeroelim(xlen, xdet, ylen, ydet, xydet); - blen = fast_expansion_sum_zeroelim(xylen, xydet, zlen, zdet, bdet); - - temp8alen = scale_expansion_zeroelim(4, ab, dez, temp8a); - temp8blen = scale_expansion_zeroelim(4, bd, aez, temp8b); - temp8clen = scale_expansion_zeroelim(4, da, bez, temp8c); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, - temp8blen, temp8b, temp16); - temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c, - temp16len, temp16, temp24); - temp48len = scale_expansion_zeroelim(temp24len, temp24, cex, temp48); - xlen = scale_expansion_zeroelim(temp48len, temp48, -cex, xdet); - temp48len = scale_expansion_zeroelim(temp24len, temp24, cey, temp48); - ylen = scale_expansion_zeroelim(temp48len, temp48, -cey, ydet); - temp48len = scale_expansion_zeroelim(temp24len, temp24, cez, temp48); - zlen = scale_expansion_zeroelim(temp48len, temp48, -cez, zdet); - xylen = fast_expansion_sum_zeroelim(xlen, xdet, ylen, ydet, xydet); - clen = fast_expansion_sum_zeroelim(xylen, xydet, zlen, zdet, cdet); - - temp8alen = scale_expansion_zeroelim(4, bc, aez, temp8a); - temp8blen = scale_expansion_zeroelim(4, ac, -bez, temp8b); - temp8clen = scale_expansion_zeroelim(4, ab, cez, temp8c); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, - temp8blen, temp8b, temp16); - temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c, - temp16len, temp16, temp24); - temp48len = scale_expansion_zeroelim(temp24len, temp24, dex, temp48); - xlen = scale_expansion_zeroelim(temp48len, temp48, dex, xdet); - temp48len = scale_expansion_zeroelim(temp24len, temp24, dey, temp48); - ylen = scale_expansion_zeroelim(temp48len, temp48, dey, ydet); - temp48len = scale_expansion_zeroelim(temp24len, temp24, dez, temp48); - zlen = scale_expansion_zeroelim(temp48len, temp48, dez, zdet); - xylen = fast_expansion_sum_zeroelim(xlen, xdet, ylen, ydet, xydet); - dlen = fast_expansion_sum_zeroelim(xylen, xydet, zlen, zdet, ddet); - - ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); - cdlen = fast_expansion_sum_zeroelim(clen, cdet, dlen, ddet, cddet); - finlength = fast_expansion_sum_zeroelim(ablen, abdet, cdlen, cddet, fin1); - - det = estimate(finlength, fin1); - errbound = isperrboundB * permanent; - if ((det >= errbound) || (-det >= errbound)) { - return det; - } - - Two_Diff_Tail(pa[0], pe[0], aex, aextail); - Two_Diff_Tail(pa[1], pe[1], aey, aeytail); - Two_Diff_Tail(pa[2], pe[2], aez, aeztail); - Two_Diff_Tail(pb[0], pe[0], bex, bextail); - Two_Diff_Tail(pb[1], pe[1], bey, beytail); - Two_Diff_Tail(pb[2], pe[2], bez, beztail); - Two_Diff_Tail(pc[0], pe[0], cex, cextail); - Two_Diff_Tail(pc[1], pe[1], cey, ceytail); - Two_Diff_Tail(pc[2], pe[2], cez, ceztail); - Two_Diff_Tail(pd[0], pe[0], dex, dextail); - Two_Diff_Tail(pd[1], pe[1], dey, deytail); - Two_Diff_Tail(pd[2], pe[2], dez, deztail); - if ((aextail == 0.0) && (aeytail == 0.0) && (aeztail == 0.0) - && (bextail == 0.0) && (beytail == 0.0) && (beztail == 0.0) - && (cextail == 0.0) && (ceytail == 0.0) && (ceztail == 0.0) - && (dextail == 0.0) && (deytail == 0.0) && (deztail == 0.0)) { - return det; - } - - errbound = isperrboundC * permanent + resulterrbound * Absolute(det); - abeps = (aex * beytail + bey * aextail) - - (aey * bextail + bex * aeytail); - bceps = (bex * ceytail + cey * bextail) - - (bey * cextail + cex * beytail); - cdeps = (cex * deytail + dey * cextail) - - (cey * dextail + dex * ceytail); - daeps = (dex * aeytail + aey * dextail) - - (dey * aextail + aex * deytail); - aceps = (aex * ceytail + cey * aextail) - - (aey * cextail + cex * aeytail); - bdeps = (bex * deytail + dey * bextail) - - (bey * dextail + dex * beytail); - det += (((bex * bex + bey * bey + bez * bez) - * ((cez * daeps + dez * aceps + aez * cdeps) - + (ceztail * da3 + deztail * ac3 + aeztail * cd3)) - + (dex * dex + dey * dey + dez * dez) - * ((aez * bceps - bez * aceps + cez * abeps) - + (aeztail * bc3 - beztail * ac3 + ceztail * ab3))) - - ((aex * aex + aey * aey + aez * aez) - * ((bez * cdeps - cez * bdeps + dez * bceps) - + (beztail * cd3 - ceztail * bd3 + deztail * bc3)) - + (cex * cex + cey * cey + cez * cez) - * ((dez * abeps + aez * bdeps + bez * daeps) - + (deztail * ab3 + aeztail * bd3 + beztail * da3)))) - + 2.0 * (((bex * bextail + bey * beytail + bez * beztail) - * (cez * da3 + dez * ac3 + aez * cd3) - + (dex * dextail + dey * deytail + dez * deztail) - * (aez * bc3 - bez * ac3 + cez * ab3)) - - ((aex * aextail + aey * aeytail + aez * aeztail) - * (bez * cd3 - cez * bd3 + dez * bc3) - + (cex * cextail + cey * ceytail + cez * ceztail) - * (dez * ab3 + aez * bd3 + bez * da3))); - if ((det >= errbound) || (-det >= errbound)) { - return det; - } - - return insphereexact(pa, pb, pc, pd, pe); -} - -REAL insphere ( - __const_ptr(REAL) pa, - __const_ptr(REAL) pb, - __const_ptr(REAL) pc, - __const_ptr(REAL) pd, - __const_ptr(REAL) pe) -{ - REAL aex, bex, cex, dex; - REAL aey, bey, cey, dey; - REAL aez, bez, cez, dez; - REAL aexbey, bexaey, bexcey, cexbey, cexdey, dexcey, dexaey, aexdey; - REAL aexcey, cexaey, bexdey, dexbey; - REAL alift, blift, clift, dlift; - REAL ab, bc, cd, da, ac, bd; - REAL abc, bcd, cda, dab; - REAL aezplus, bezplus, cezplus, dezplus; - REAL aexbeyplus, bexaeyplus, bexceyplus, cexbeyplus; - REAL cexdeyplus, dexceyplus, dexaeyplus, aexdeyplus; - REAL aexceyplus, cexaeyplus, bexdeyplus, dexbeyplus; - REAL det; - REAL permanent, errbound; - - aex = pa[0] - pe[0]; - bex = pb[0] - pe[0]; - cex = pc[0] - pe[0]; - dex = pd[0] - pe[0]; - aey = pa[1] - pe[1]; - bey = pb[1] - pe[1]; - cey = pc[1] - pe[1]; - dey = pd[1] - pe[1]; - aez = pa[2] - pe[2]; - bez = pb[2] - pe[2]; - cez = pc[2] - pe[2]; - dez = pd[2] - pe[2]; - - aexbey = aex * bey; - bexaey = bex * aey; - ab = aexbey - bexaey; - bexcey = bex * cey; - cexbey = cex * bey; - bc = bexcey - cexbey; - cexdey = cex * dey; - dexcey = dex * cey; - cd = cexdey - dexcey; - dexaey = dex * aey; - aexdey = aex * dey; - da = dexaey - aexdey; - - aexcey = aex * cey; - cexaey = cex * aey; - ac = aexcey - cexaey; - bexdey = bex * dey; - dexbey = dex * bey; - bd = bexdey - dexbey; - - abc = aez * bc - bez * ac + cez * ab; - bcd = bez * cd - cez * bd + dez * bc; - cda = cez * da + dez * ac + aez * cd; - dab = dez * ab + aez * bd + bez * da; - - alift = aex * aex + aey * aey + aez * aez; - blift = bex * bex + bey * bey + bez * bez; - clift = cex * cex + cey * cey + cez * cez; - dlift = dex * dex + dey * dey + dez * dez; - - det = (dlift * abc - clift * dab) + (blift * cda - alift * bcd); - - aezplus = Absolute(aez); - bezplus = Absolute(bez); - cezplus = Absolute(cez); - dezplus = Absolute(dez); - aexbeyplus = Absolute(aexbey); - bexaeyplus = Absolute(bexaey); - bexceyplus = Absolute(bexcey); - cexbeyplus = Absolute(cexbey); - cexdeyplus = Absolute(cexdey); - dexceyplus = Absolute(dexcey); - dexaeyplus = Absolute(dexaey); - aexdeyplus = Absolute(aexdey); - aexceyplus = Absolute(aexcey); - cexaeyplus = Absolute(cexaey); - bexdeyplus = Absolute(bexdey); - dexbeyplus = Absolute(dexbey); - permanent = ((cexdeyplus + dexceyplus) * bezplus - + (dexbeyplus + bexdeyplus) * cezplus - + (bexceyplus + cexbeyplus) * dezplus) - * alift - + ((dexaeyplus + aexdeyplus) * cezplus - + (aexceyplus + cexaeyplus) * dezplus - + (cexdeyplus + dexceyplus) * aezplus) - * blift - + ((aexbeyplus + bexaeyplus) * dezplus - + (bexdeyplus + dexbeyplus) * aezplus - + (dexaeyplus + aexdeyplus) * bezplus) - * clift - + ((bexceyplus + cexbeyplus) * aezplus - + (cexaeyplus + aexceyplus) * bezplus - + (aexbeyplus + bexaeyplus) * cezplus) - * dlift; - errbound = isperrboundA * permanent; - if ((det > errbound) || (-det > errbound)) { - return det; - } - - return insphereadapt(pa, pb, pc, pd, pe, permanent); -} - -/*****************************************************************************/ -/* */ -/* orient4d() Return a positive value if the point pe lies above the */ -/* hyperplane passing through pa, pb, pc, and pd; "above" is */ -/* defined in a manner best found by trial-and-error. Returns */ -/* a negative value if pe lies below the hyperplane. Returns */ -/* zero if the points are co-hyperplanar (not affinely */ -/* independent). The result is also a rough approximation of */ -/* 24 times the signed volume of the 4-simplex defined by the */ -/* five points. */ -/* */ -/* Uses exact arithmetic if necessary to ensure a correct answer. The */ -/* result returned is the determinant of a matrix. This determinant is */ -/* computed adaptively, in the sense that exact arithmetic is used only to */ -/* the degree it is needed to ensure that the returned value has the */ -/* correct sign. Hence, orient4d() is usually quite fast, but will run */ -/* more slowly when the input points are hyper-coplanar or nearly so. */ -/* */ -/* See my Robust Predicates paper for details. */ -/* */ -/*****************************************************************************/ - -REAL orient4dexact ( - __const_ptr(REAL) pa, - __const_ptr(REAL) pb, - __const_ptr(REAL) pc, - __const_ptr(REAL) pd, - __const_ptr(REAL) pe, - REAL aheight, - REAL bheight, - REAL cheight, - REAL dheight, - REAL eheight) -{ - REAL axby1, bxcy1, cxdy1, dxey1, exay1; - REAL bxay1, cxby1, dxcy1, exdy1, axey1; - REAL axcy1, bxdy1, cxey1, dxay1, exby1; - REAL cxay1, dxby1, excy1, axdy1, bxey1; - REAL axby0, bxcy0, cxdy0, dxey0, exay0; - REAL bxay0, cxby0, dxcy0, exdy0, axey0; - REAL axcy0, bxdy0, cxey0, dxay0, exby0; - REAL cxay0, dxby0, excy0, axdy0, bxey0; - REAL ab[4], bc[4], cd[4], de[4], ea[4]; - REAL ac[4], bd[4], ce[4], da[4], eb[4]; - REAL temp8a[8], temp8b[8], temp16[16]; - int temp8alen=0, temp8blen=0, temp16len=0; - REAL abc[24], bcd[24], cde[24], dea[24], eab[24]; - REAL abd[24], bce[24], cda[24], deb[24], eac[24]; - int abclen=0, bcdlen=0, cdelen=0, dealen=0, eablen=0; - int abdlen=0, bcelen=0, cdalen=0, deblen=0, eaclen=0; - REAL temp48a[48], temp48b[48]; - int temp48alen=0, temp48blen=0; - REAL abcd[96], bcde[96], cdea[96], deab[96], eabc[96]; - int abcdlen=0, bcdelen=0, cdealen=0, deablen=0, eabclen=0; - REAL adet[192], bdet[192], cdet[192], ddet[192], edet[192]; - int alen, blen=0, clen=0, dlen=0, elen=0; - REAL abdet[384], cddet[384], cdedet[576]; - int ablen=0, cdlen=0; - REAL deter[960]; - int deterlen=0; - int i; - - REAL bvirt, avirt, bround, around; - REAL c, abig, ahi, alo, bhi, blo; - REAL err1, err2, err3; - REAL _i, _j, _0; - - Two_Product(pa[0], pb[1], axby1, axby0); - Two_Product(pb[0], pa[1], bxay1, bxay0); - Two_Two_Diff(axby1, axby0, bxay1, bxay0, ab[3], ab[2], ab[1], ab[0]); - - Two_Product(pb[0], pc[1], bxcy1, bxcy0); - Two_Product(pc[0], pb[1], cxby1, cxby0); - Two_Two_Diff(bxcy1, bxcy0, cxby1, cxby0, bc[3], bc[2], bc[1], bc[0]); - - Two_Product(pc[0], pd[1], cxdy1, cxdy0); - Two_Product(pd[0], pc[1], dxcy1, dxcy0); - Two_Two_Diff(cxdy1, cxdy0, dxcy1, dxcy0, cd[3], cd[2], cd[1], cd[0]); - - Two_Product(pd[0], pe[1], dxey1, dxey0); - Two_Product(pe[0], pd[1], exdy1, exdy0); - Two_Two_Diff(dxey1, dxey0, exdy1, exdy0, de[3], de[2], de[1], de[0]); - - Two_Product(pe[0], pa[1], exay1, exay0); - Two_Product(pa[0], pe[1], axey1, axey0); - Two_Two_Diff(exay1, exay0, axey1, axey0, ea[3], ea[2], ea[1], ea[0]); - - Two_Product(pa[0], pc[1], axcy1, axcy0); - Two_Product(pc[0], pa[1], cxay1, cxay0); - Two_Two_Diff(axcy1, axcy0, cxay1, cxay0, ac[3], ac[2], ac[1], ac[0]); - - Two_Product(pb[0], pd[1], bxdy1, bxdy0); - Two_Product(pd[0], pb[1], dxby1, dxby0); - Two_Two_Diff(bxdy1, bxdy0, dxby1, dxby0, bd[3], bd[2], bd[1], bd[0]); - - Two_Product(pc[0], pe[1], cxey1, cxey0); - Two_Product(pe[0], pc[1], excy1, excy0); - Two_Two_Diff(cxey1, cxey0, excy1, excy0, ce[3], ce[2], ce[1], ce[0]); - - Two_Product(pd[0], pa[1], dxay1, dxay0); - Two_Product(pa[0], pd[1], axdy1, axdy0); - Two_Two_Diff(dxay1, dxay0, axdy1, axdy0, da[3], da[2], da[1], da[0]); - - Two_Product(pe[0], pb[1], exby1, exby0); - Two_Product(pb[0], pe[1], bxey1, bxey0); - Two_Two_Diff(exby1, exby0, bxey1, bxey0, eb[3], eb[2], eb[1], eb[0]); - - temp8alen = scale_expansion_zeroelim(4, bc, pa[2], temp8a); - temp8blen = scale_expansion_zeroelim(4, ac, -pb[2], temp8b); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, - temp16); - temp8alen = scale_expansion_zeroelim(4, ab, pc[2], temp8a); - abclen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, - abc); - - temp8alen = scale_expansion_zeroelim(4, cd, pb[2], temp8a); - temp8blen = scale_expansion_zeroelim(4, bd, -pc[2], temp8b); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, - temp16); - temp8alen = scale_expansion_zeroelim(4, bc, pd[2], temp8a); - bcdlen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, - bcd); - - temp8alen = scale_expansion_zeroelim(4, de, pc[2], temp8a); - temp8blen = scale_expansion_zeroelim(4, ce, -pd[2], temp8b); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, - temp16); - temp8alen = scale_expansion_zeroelim(4, cd, pe[2], temp8a); - cdelen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, - cde); - - temp8alen = scale_expansion_zeroelim(4, ea, pd[2], temp8a); - temp8blen = scale_expansion_zeroelim(4, da, -pe[2], temp8b); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, - temp16); - temp8alen = scale_expansion_zeroelim(4, de, pa[2], temp8a); - dealen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, - dea); - - temp8alen = scale_expansion_zeroelim(4, ab, pe[2], temp8a); - temp8blen = scale_expansion_zeroelim(4, eb, -pa[2], temp8b); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, - temp16); - temp8alen = scale_expansion_zeroelim(4, ea, pb[2], temp8a); - eablen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, - eab); - - temp8alen = scale_expansion_zeroelim(4, bd, pa[2], temp8a); - temp8blen = scale_expansion_zeroelim(4, da, pb[2], temp8b); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, - temp16); - temp8alen = scale_expansion_zeroelim(4, ab, pd[2], temp8a); - abdlen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, - abd); - - temp8alen = scale_expansion_zeroelim(4, ce, pb[2], temp8a); - temp8blen = scale_expansion_zeroelim(4, eb, pc[2], temp8b); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, - temp16); - temp8alen = scale_expansion_zeroelim(4, bc, pe[2], temp8a); - bcelen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, - bce); - - temp8alen = scale_expansion_zeroelim(4, da, pc[2], temp8a); - temp8blen = scale_expansion_zeroelim(4, ac, pd[2], temp8b); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, - temp16); - temp8alen = scale_expansion_zeroelim(4, cd, pa[2], temp8a); - cdalen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, - cda); - - temp8alen = scale_expansion_zeroelim(4, eb, pd[2], temp8a); - temp8blen = scale_expansion_zeroelim(4, bd, pe[2], temp8b); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, - temp16); - temp8alen = scale_expansion_zeroelim(4, de, pb[2], temp8a); - deblen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, - deb); - - temp8alen = scale_expansion_zeroelim(4, ac, pe[2], temp8a); - temp8blen = scale_expansion_zeroelim(4, ce, pa[2], temp8b); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, - temp16); - temp8alen = scale_expansion_zeroelim(4, ea, pc[2], temp8a); - eaclen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, - eac); - - temp48alen = fast_expansion_sum_zeroelim(cdelen, cde, bcelen, bce, temp48a); - temp48blen = fast_expansion_sum_zeroelim(deblen, deb, bcdlen, bcd, temp48b); - for (i = 0; i < temp48blen; i++) { - temp48b[i] = -temp48b[i]; - } - bcdelen = fast_expansion_sum_zeroelim(temp48alen, temp48a, - temp48blen, temp48b, bcde); - alen = scale_expansion_zeroelim(bcdelen, bcde, aheight, adet); - - temp48alen = fast_expansion_sum_zeroelim(dealen, dea, cdalen, cda, temp48a); - temp48blen = fast_expansion_sum_zeroelim(eaclen, eac, cdelen, cde, temp48b); - for (i = 0; i < temp48blen; i++) { - temp48b[i] = -temp48b[i]; - } - cdealen = fast_expansion_sum_zeroelim(temp48alen, temp48a, - temp48blen, temp48b, cdea); - blen = scale_expansion_zeroelim(cdealen, cdea, bheight, bdet); - - temp48alen = fast_expansion_sum_zeroelim(eablen, eab, deblen, deb, temp48a); - temp48blen = fast_expansion_sum_zeroelim(abdlen, abd, dealen, dea, temp48b); - for (i = 0; i < temp48blen; i++) { - temp48b[i] = -temp48b[i]; - } - deablen = fast_expansion_sum_zeroelim(temp48alen, temp48a, - temp48blen, temp48b, deab); - clen = scale_expansion_zeroelim(deablen, deab, cheight, cdet); - - temp48alen = fast_expansion_sum_zeroelim(abclen, abc, eaclen, eac, temp48a); - temp48blen = fast_expansion_sum_zeroelim(bcelen, bce, eablen, eab, temp48b); - for (i = 0; i < temp48blen; i++) { - temp48b[i] = -temp48b[i]; - } - eabclen = fast_expansion_sum_zeroelim(temp48alen, temp48a, - temp48blen, temp48b, eabc); - dlen = scale_expansion_zeroelim(eabclen, eabc, dheight, ddet); - - temp48alen = fast_expansion_sum_zeroelim(bcdlen, bcd, abdlen, abd, temp48a); - temp48blen = fast_expansion_sum_zeroelim(cdalen, cda, abclen, abc, temp48b); - for (i = 0; i < temp48blen; i++) { - temp48b[i] = -temp48b[i]; - } - abcdlen = fast_expansion_sum_zeroelim(temp48alen, temp48a, - temp48blen, temp48b, abcd); - elen = scale_expansion_zeroelim(abcdlen, abcd, eheight, edet); - - ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); - cdlen = fast_expansion_sum_zeroelim(clen, cdet, dlen, ddet, cddet); - cdelen = fast_expansion_sum_zeroelim(cdlen, cddet, elen, edet, cdedet); - deterlen = fast_expansion_sum_zeroelim(ablen, abdet, cdelen, cdedet, deter); - - return deter[deterlen - 1]; -} - -REAL orient4dadapt ( - __const_ptr(REAL) pa, - __const_ptr(REAL) pb, - __const_ptr(REAL) pc, - __const_ptr(REAL) pd, - __const_ptr(REAL) pe, - REAL aheight, - REAL bheight, - REAL cheight, - REAL dheight, - REAL eheight, - REAL permanent) -{ - REAL aex, bex, cex, dex, aey, bey, cey, dey, aez, bez, cez, dez; - REAL aeheight, beheight, ceheight, deheight; - REAL det, errbound; - - REAL aexbey1, bexaey1, bexcey1, cexbey1; - REAL cexdey1, dexcey1, dexaey1, aexdey1; - REAL aexcey1, cexaey1, bexdey1, dexbey1; - REAL aexbey0, bexaey0, bexcey0, cexbey0; - REAL cexdey0, dexcey0, dexaey0, aexdey0; - REAL aexcey0, cexaey0, bexdey0, dexbey0; - REAL ab[4], bc[4], cd[4], da[4], ac[4], bd[4]; - REAL ab3, bc3, cd3, da3, ac3, bd3; - REAL abeps, bceps, cdeps, daeps, aceps, bdeps; - REAL temp8a[8], temp8b[8], temp8c[8], temp16[16], temp24[24]; - int temp8alen=0, temp8blen=0, temp8clen=0; - int temp16len=0, temp24len=0; - REAL adet[48], bdet[48], cdet[48], ddet[48]; - int alen=0, blen=0, clen=0, dlen=0; - REAL abdet[96], cddet[96]; - int ablen=0, cdlen=0; - REAL fin1[192]; - int finlength=0; - - REAL aextail, bextail, cextail, dextail; - REAL aeytail, beytail, ceytail, deytail; - REAL aeztail, beztail, ceztail, deztail; - REAL aeheighttail, beheighttail, ceheighttail, deheighttail; - - REAL bvirt, avirt, bround, around; - REAL c, abig, ahi, alo, bhi, blo; - REAL err1, err2, err3; - REAL _i, _j, _0; - - aex = (REAL) (pa[0] - pe[0]); - bex = (REAL) (pb[0] - pe[0]); - cex = (REAL) (pc[0] - pe[0]); - dex = (REAL) (pd[0] - pe[0]); - aey = (REAL) (pa[1] - pe[1]); - bey = (REAL) (pb[1] - pe[1]); - cey = (REAL) (pc[1] - pe[1]); - dey = (REAL) (pd[1] - pe[1]); - aez = (REAL) (pa[2] - pe[2]); - bez = (REAL) (pb[2] - pe[2]); - cez = (REAL) (pc[2] - pe[2]); - dez = (REAL) (pd[2] - pe[2]); - aeheight = (REAL) (aheight - eheight); - beheight = (REAL) (bheight - eheight); - ceheight = (REAL) (cheight - eheight); - deheight = (REAL) (dheight - eheight); - - Two_Product(aex, bey, aexbey1, aexbey0); - Two_Product(bex, aey, bexaey1, bexaey0); - Two_Two_Diff(aexbey1, aexbey0, bexaey1, bexaey0, ab3, ab[2], ab[1], ab[0]); - ab[3] = ab3; - - Two_Product(bex, cey, bexcey1, bexcey0); - Two_Product(cex, bey, cexbey1, cexbey0); - Two_Two_Diff(bexcey1, bexcey0, cexbey1, cexbey0, bc3, bc[2], bc[1], bc[0]); - bc[3] = bc3; - - Two_Product(cex, dey, cexdey1, cexdey0); - Two_Product(dex, cey, dexcey1, dexcey0); - Two_Two_Diff(cexdey1, cexdey0, dexcey1, dexcey0, cd3, cd[2], cd[1], cd[0]); - cd[3] = cd3; - - Two_Product(dex, aey, dexaey1, dexaey0); - Two_Product(aex, dey, aexdey1, aexdey0); - Two_Two_Diff(dexaey1, dexaey0, aexdey1, aexdey0, da3, da[2], da[1], da[0]); - da[3] = da3; - - Two_Product(aex, cey, aexcey1, aexcey0); - Two_Product(cex, aey, cexaey1, cexaey0); - Two_Two_Diff(aexcey1, aexcey0, cexaey1, cexaey0, ac3, ac[2], ac[1], ac[0]); - ac[3] = ac3; - - Two_Product(bex, dey, bexdey1, bexdey0); - Two_Product(dex, bey, dexbey1, dexbey0); - Two_Two_Diff(bexdey1, bexdey0, dexbey1, dexbey0, bd3, bd[2], bd[1], bd[0]); - bd[3] = bd3; - - temp8alen = scale_expansion_zeroelim(4, cd, bez, temp8a); - temp8blen = scale_expansion_zeroelim(4, bd, -cez, temp8b); - temp8clen = scale_expansion_zeroelim(4, bc, dez, temp8c); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, - temp8blen, temp8b, temp16); - temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c, - temp16len, temp16, temp24); - alen = scale_expansion_zeroelim(temp24len, temp24, -aeheight, adet); - - temp8alen = scale_expansion_zeroelim(4, da, cez, temp8a); - temp8blen = scale_expansion_zeroelim(4, ac, dez, temp8b); - temp8clen = scale_expansion_zeroelim(4, cd, aez, temp8c); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, - temp8blen, temp8b, temp16); - temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c, - temp16len, temp16, temp24); - blen = scale_expansion_zeroelim(temp24len, temp24, beheight, bdet); - - temp8alen = scale_expansion_zeroelim(4, ab, dez, temp8a); - temp8blen = scale_expansion_zeroelim(4, bd, aez, temp8b); - temp8clen = scale_expansion_zeroelim(4, da, bez, temp8c); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, - temp8blen, temp8b, temp16); - temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c, - temp16len, temp16, temp24); - clen = scale_expansion_zeroelim(temp24len, temp24, -ceheight, cdet); - - temp8alen = scale_expansion_zeroelim(4, bc, aez, temp8a); - temp8blen = scale_expansion_zeroelim(4, ac, -bez, temp8b); - temp8clen = scale_expansion_zeroelim(4, ab, cez, temp8c); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, - temp8blen, temp8b, temp16); - temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c, - temp16len, temp16, temp24); - dlen = scale_expansion_zeroelim(temp24len, temp24, deheight, ddet); - - ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); - cdlen = fast_expansion_sum_zeroelim(clen, cdet, dlen, ddet, cddet); - finlength = fast_expansion_sum_zeroelim(ablen, abdet, cdlen, cddet, fin1); - - det = estimate(finlength, fin1); - errbound = isperrboundB * permanent; - if ((det >= errbound) || (-det >= errbound)) { - return det; - } - - Two_Diff_Tail(pa[0], pe[0], aex, aextail); - Two_Diff_Tail(pa[1], pe[1], aey, aeytail); - Two_Diff_Tail(pa[2], pe[2], aez, aeztail); - Two_Diff_Tail(aheight, eheight, aeheight, aeheighttail); - Two_Diff_Tail(pb[0], pe[0], bex, bextail); - Two_Diff_Tail(pb[1], pe[1], bey, beytail); - Two_Diff_Tail(pb[2], pe[2], bez, beztail); - Two_Diff_Tail(bheight, eheight, beheight, beheighttail); - Two_Diff_Tail(pc[0], pe[0], cex, cextail); - Two_Diff_Tail(pc[1], pe[1], cey, ceytail); - Two_Diff_Tail(pc[2], pe[2], cez, ceztail); - Two_Diff_Tail(cheight, eheight, ceheight, ceheighttail); - Two_Diff_Tail(pd[0], pe[0], dex, dextail); - Two_Diff_Tail(pd[1], pe[1], dey, deytail); - Two_Diff_Tail(pd[2], pe[2], dez, deztail); - Two_Diff_Tail(dheight, eheight, deheight, deheighttail); - if ((aextail == 0.0) && (aeytail == 0.0) && (aeztail == 0.0) - && (bextail == 0.0) && (beytail == 0.0) && (beztail == 0.0) - && (cextail == 0.0) && (ceytail == 0.0) && (ceztail == 0.0) - && (dextail == 0.0) && (deytail == 0.0) && (deztail == 0.0) - && (aeheighttail == 0.0) && (beheighttail == 0.0) - && (ceheighttail == 0.0) && (deheighttail == 0.0)) { - return det; - } - - errbound = isperrboundC * permanent + resulterrbound * Absolute(det); - abeps = (aex * beytail + bey * aextail) - - (aey * bextail + bex * aeytail); - bceps = (bex * ceytail + cey * bextail) - - (bey * cextail + cex * beytail); - cdeps = (cex * deytail + dey * cextail) - - (cey * dextail + dex * ceytail); - daeps = (dex * aeytail + aey * dextail) - - (dey * aextail + aex * deytail); - aceps = (aex * ceytail + cey * aextail) - - (aey * cextail + cex * aeytail); - bdeps = (bex * deytail + dey * bextail) - - (bey * dextail + dex * beytail); - det += ((beheight - * ((cez * daeps + dez * aceps + aez * cdeps) - + (ceztail * da3 + deztail * ac3 + aeztail * cd3)) - + deheight - * ((aez * bceps - bez * aceps + cez * abeps) - + (aeztail * bc3 - beztail * ac3 + ceztail * ab3))) - - (aeheight - * ((bez * cdeps - cez * bdeps + dez * bceps) - + (beztail * cd3 - ceztail * bd3 + deztail * bc3)) - + ceheight - * ((dez * abeps + aez * bdeps + bez * daeps) - + (deztail * ab3 + aeztail * bd3 + beztail * da3)))) - + ((beheighttail * (cez * da3 + dez * ac3 + aez * cd3) - + deheighttail * (aez * bc3 - bez * ac3 + cez * ab3)) - - (aeheighttail * (bez * cd3 - cez * bd3 + dez * bc3) - + ceheighttail * (dez * ab3 + aez * bd3 + bez * da3))); - if ((det >= errbound) || (-det >= errbound)) { - return det; - } - - return orient4dexact(pa, pb, pc, pd, pe, - aheight, bheight, cheight, dheight, eheight); -} - -REAL orient4d ( - __const_ptr(REAL) pa, - __const_ptr(REAL) pb, - __const_ptr(REAL) pc, - __const_ptr(REAL) pd, - __const_ptr(REAL) pe ) -{ - REAL aheight, bheight, cheight, dheight, eheight; - REAL aex, bex, cex, dex; - REAL aey, bey, cey, dey; - REAL aez, bez, cez, dez; - REAL aexbey, bexaey, bexcey, cexbey, cexdey, dexcey, dexaey, aexdey; - REAL aexcey, cexaey, bexdey, dexbey; - REAL aeheight, beheight, ceheight, deheight; - REAL ab, bc, cd, da, ac, bd; - REAL abc, bcd, cda, dab; - REAL aezplus, bezplus, cezplus, dezplus; - REAL aexbeyplus, bexaeyplus, bexceyplus, cexbeyplus; - REAL cexdeyplus, dexceyplus, dexaeyplus, aexdeyplus; - REAL aexceyplus, cexaeyplus, bexdeyplus, dexbeyplus; - REAL det; - REAL permanent, errbound; - - aheight = pa[3]; - bheight = pb[3]; - cheight = pc[3]; - dheight = pd[3]; - eheight = pe[3]; - - aex = pa[0] - pe[0]; - bex = pb[0] - pe[0]; - cex = pc[0] - pe[0]; - dex = pd[0] - pe[0]; - aey = pa[1] - pe[1]; - bey = pb[1] - pe[1]; - cey = pc[1] - pe[1]; - dey = pd[1] - pe[1]; - aez = pa[2] - pe[2]; - bez = pb[2] - pe[2]; - cez = pc[2] - pe[2]; - dez = pd[2] - pe[2]; - aeheight = aheight - eheight; - beheight = bheight - eheight; - ceheight = cheight - eheight; - deheight = dheight - eheight; - - aexbey = aex * bey; - bexaey = bex * aey; - ab = aexbey - bexaey; - bexcey = bex * cey; - cexbey = cex * bey; - bc = bexcey - cexbey; - cexdey = cex * dey; - dexcey = dex * cey; - cd = cexdey - dexcey; - dexaey = dex * aey; - aexdey = aex * dey; - da = dexaey - aexdey; - - aexcey = aex * cey; - cexaey = cex * aey; - ac = aexcey - cexaey; - bexdey = bex * dey; - dexbey = dex * bey; - bd = bexdey - dexbey; - - abc = aez * bc - bez * ac + cez * ab; - bcd = bez * cd - cez * bd + dez * bc; - cda = cez * da + dez * ac + aez * cd; - dab = dez * ab + aez * bd + bez * da; - - det = (deheight * abc - ceheight * dab) + (beheight * cda - aeheight * bcd); - - aezplus = Absolute(aez); - bezplus = Absolute(bez); - cezplus = Absolute(cez); - dezplus = Absolute(dez); - aexbeyplus = Absolute(aexbey); - bexaeyplus = Absolute(bexaey); - bexceyplus = Absolute(bexcey); - cexbeyplus = Absolute(cexbey); - cexdeyplus = Absolute(cexdey); - dexceyplus = Absolute(dexcey); - dexaeyplus = Absolute(dexaey); - aexdeyplus = Absolute(aexdey); - aexceyplus = Absolute(aexcey); - cexaeyplus = Absolute(cexaey); - bexdeyplus = Absolute(bexdey); - dexbeyplus = Absolute(dexbey); - permanent = ((cexdeyplus + dexceyplus) * bezplus - + (dexbeyplus + bexdeyplus) * cezplus - + (bexceyplus + cexbeyplus) * dezplus) - * aeheight - + ((dexaeyplus + aexdeyplus) * cezplus - + (aexceyplus + cexaeyplus) * dezplus - + (cexdeyplus + dexceyplus) * aezplus) - * beheight - + ((aexbeyplus + bexaeyplus) * dezplus - + (bexdeyplus + dexbeyplus) * aezplus - + (dexaeyplus + aexdeyplus) * bezplus) - * ceheight - + ((bexceyplus + cexbeyplus) * aezplus - + (cexaeyplus + aexceyplus) * bezplus - + (aexbeyplus + bexaeyplus) * cezplus) - * deheight; - errbound = isperrboundA * permanent; - if ((det > errbound) || (-det > errbound)) { - return det; - } - - return orient4dadapt(pa, pb, pc, pd, pe, - aheight, bheight, cheight, dheight, eheight, permanent); -} - -/*****************************************************************************/ -/* */ -/* regular_k() Return a positive value if the point pe is incompatible */ -/* with the sphere or hyperplane passing through pa, pb, pc, */ -/* and pd (meaning that pe is inside the sphere or below the */ -/* hyperplane); a negative value if it is compatible; and */ -/* zero if the five points are cospherical/cohyperplanar. */ -/* The points pa, pb, pc, and pd must be ordered so that */ -/* they have a positive orientation (as defined by */ -/* orient3d()), or the sign of the result will be reversed. */ -/* */ -/* Uses exact arithmetic if necessary to ensure a correct answer. The */ -/* result returned is the determinant of a matrix. This determinant is */ -/* computed adaptively, in the sense that exact arithmetic is used only to */ -/* the degree it is needed to ensure that the returned value has the */ -/* correct sign. Hence, orient4d() is usually quite fast, but will run */ -/* more slowly when the input points are hyper-coplanar or nearly so. */ -/* */ -/* See my Robust Predicates paper for details. */ -/* */ -/*****************************************************************************/ - -REAL regular2 ( - __const_ptr(REAL) pa, - __const_ptr(REAL) pb, - __const_ptr(REAL) pc, - __const_ptr(REAL) pd ) -{ - REAL PA[3], PB[3], PC[3], PD[3] ; - - PA[0] = pa[0] ; PA[1] = pa[1] ; - PB[0] = pb[0] ; PB[1] = pb[1] ; - PC[0] = pc[0] ; PC[1] = pc[1] ; - PD[0] = pd[0] ; PD[1] = pd[1] ; - - PA[2] = pa[0] * pa[0] - + pa[1] * pa[1] - pa[2] ; - PB[2] = pb[0] * pb[0] - + pb[1] * pb[1] - pb[2] ; - PC[2] = pc[0] * pc[0] - + pc[1] * pc[1] - pc[2] ; - PD[2] = pd[0] * pd[0] - + pd[1] * pd[1] - pd[2] ; - - return orient3d(PA, PB, PC, PD) ; -} - -REAL regular3 ( - __const_ptr(REAL) pa, - __const_ptr(REAL) pb, - __const_ptr(REAL) pc, - __const_ptr(REAL) pd, - __const_ptr(REAL) pe ) -{ - REAL PA[4], PB[4], PC[4], PD[4], PE[4] ; - - PA[0] = pa[0] ; PA[1] = pa[1] ; PA[2] = pa[2] ; - PB[0] = pb[0] ; PB[1] = pb[1] ; PB[2] = pb[2] ; - PC[0] = pc[0] ; PC[1] = pc[1] ; PC[2] = pc[2] ; - PD[0] = pd[0] ; PD[1] = pd[1] ; PD[2] = pd[2] ; - PE[0] = pe[0] ; PE[1] = pe[1] ; PE[2] = pe[2] ; - - PA[3] = pa[0] * pa[0] - + pa[1] * pa[1] - + pa[2] * pa[2] - pa[3] ; - PB[3] = pb[0] * pb[0] - + pb[1] * pb[1] - + pb[2] * pb[2] - pb[3] ; - PC[3] = pc[0] * pc[0] - + pc[1] * pc[1] - + pc[2] * pc[2] - pc[3] ; - PD[3] = pd[0] * pd[0] - + pd[1] * pd[1] - + pd[2] * pd[2] - pd[3] ; - PE[3] = pe[0] * pe[0] - + pe[1] * pe[1] - + pe[2] * pe[2] - pe[3] ; - - return orient4d(PA, PB, PC, PD, PE) ; -} - -} - -#endif // __GEOMPRED__ - - - +/*****************************************************************************/ +/* */ +/* Routines for Arbitrary Precision Floating-point Arithmetic */ +/* and Fast Robust Geometric Predicates */ +/* (predicates.c) */ +/* */ +/* May 18, 1996 */ +/* */ +/* Placed in the public domain by */ +/* Jonathan Richard Shewchuk */ +/* School of Computer Science */ +/* Carnegie Mellon University */ +/* 5000 Forbes Avenue */ +/* Pittsburgh, Pennsylvania 15213-3891 */ +/* jrs@cs.cmu.edu */ +/* */ +/* This file contains C implementation of algorithms for exact addition */ +/* and multiplication of floating-point numbers, and predicates for */ +/* robustly performing the orientation and incircle tests used in */ +/* computational geometry. The algorithms and underlying theory are */ +/* described in Jonathan Richard Shewchuk. "Adaptive Precision Floating- */ +/* Point Arithmetic and Fast Robust Geometric Predicates." Technical */ +/* Report CMU-CS-96-140, School of Computer Science, Carnegie Mellon */ +/* University, Pittsburgh, Pennsylvania, May 1996. (Submitted to */ +/* Discrete & Computational Geometry.) */ +/* */ +/* This file, the paper listed above, and other information are available */ +/* from the Web page http://www.cs.cmu.edu/~quake/robust.html . */ +/* */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* */ +/* Using this code: */ +/* */ +/* First, read the short or long version of the paper (from the Web page */ +/* above). */ +/* */ +/* Be sure to call exactinit() once, before calling any of the arithmetic */ +/* functions or geometric predicates. Also be sure to turn on the */ +/* optimizer when compiling this file. */ +/* */ +/* */ +/* Several geometric predicates are defined. Their parameters are all */ +/* points. Each point is an array of two, three or four floating-point */ +/* numbers. The geometric predicates, described in the papers, are */ +/* */ +/* orient2d(pa, pb, pc) */ +/* orient3d(pa, pb, pc, pd) */ +/* orient4d(pa, pb, pc, pd, pe) */ +/* incircle(pa, pb, pc, pd) */ +/* insphere(pa, pb, pc, pd, pe) */ +/* regular2(pa, pb, pc, pd) */ +/* regular3(pa, pb, pc, pd, pe) */ +/* */ +/* */ +/* An expansion is represented by an array of floating-point numbers, */ +/* sorted from smallest to largest magnitude (possibly with interspersed */ +/* zeros). The length of each expansion is stored as a separate integer, */ +/* and each arithmetic function returns an integer which is the length */ +/* of the expansion it created. */ +/* */ +/* Several arithmetic functions are defined. Their parameters are */ +/* */ +/* e, f Input expansions */ +/* elen, flen Lengths of input expansions (must be >= 1) */ +/* h Output expansion */ +/* b Input scalar */ +/* */ +/* The arithmetic functions are */ +/* */ +/* grow_expansion(elen, e, b, h) */ +/* grow_expansion_zeroelim(elen, e, b, h) */ +/* expansion_sum(elen, e, flen, f, h) */ +/* expansion_sum_zeroelim1(elen, e, flen, f, h) */ +/* expansion_sum_zeroelim2(elen, e, flen, f, h) */ +/* fast_expansion_sum(elen, e, flen, f, h) */ +/* fast_expansion_sum_zeroelim(elen, e, flen, f, h) */ +/* linear_expansion_sum(elen, e, flen, f, h) */ +/* linear_expansion_sum_zeroelim(elen, e, flen, f, h) */ +/* scale_expansion(elen, e, b, h) */ +/* scale_expansion_zeroelim(elen, e, b, h) */ +/* compress(elen, e, h) */ +/* */ +/* All of these are described in the long version of the paper; some are */ +/* described in the short version. All return an integer that is the */ +/* length of h. Those with suffix _zeroelim perform zero elimination, */ +/* and are recommended over their counterparts. The procedure */ +/* fast_expansion_sum_zeroelim() (or linear_expansion_sum_zeroelim() on */ +/* processors that do not use the round-to-even tiebreaking rule) is */ +/* recommended over expansion_sum_zeroelim(). Each procedure has a */ +/* little note next to it (in the code below) that tells you whether or */ +/* not the output expansion may be the same array as one of the input */ +/* expansions. */ +/* */ +/* */ +/* If you look around below, you'll also find macros for a bunch of */ +/* simple unrolled arithmetic operations, and procedures for printing */ +/* expansions (commented out because they don't work with all C */ +/* compilers) and for generating random floating-point numbers whose */ +/* significand bits are all random. Most of the macros have undocumented */ +/* requirements that certain of their parameters should not be the same */ +/* variable; for safety, better to make sure all the parameters are */ +/* distinct variables. Feel free to send email to jrs@cs.cmu.edu if you */ +/* have questions. */ +/* */ +/*****************************************************************************/ + +#pragma once + +#ifndef __GEOMPRED__ +#define __GEOMPRED__ + +#include +#include +#include + +namespace geompred +{ + +#define REAL double /* float or double */ + +/* Which of the following two methods of finding the absolute values is */ +/* fastest is compiler-dependent. A few compilers can inline and optimize */ +/* the fabs() call; but most will incur the overhead of a function call, */ +/* which is disastrously slow. A faster way on IEEE machines might be to */ +/* mask the appropriate bit, but that's difficult to do in C. */ + +#define Absolute(a) ((a) >= 0.0 ? (a) : -(a)) + +/* Many of the operations are broken up into two pieces, a main part that */ +/* performs an approximate operation, and a "tail" that computes the */ +/* roundoff error of that operation. */ +/* */ +/* The operations Fast_Two_Sum(), Fast_Two_Diff(), Two_Sum(), Two_Diff(), */ +/* Split(), and Two_Product() are all implemented as described in the */ +/* reference. Each of these macros requires certain variables to be */ +/* defined in the calling routine. The variables `bvirt', `c', `abig', */ +/* `_i', `_j', `_k', `_l', `_m', and `_n' are declared `INEXACT' because */ +/* they store the result of an operation that may incur roundoff error. */ +/* The input parameter `x' (or the highest numbered `x_' parameter) must */ +/* also be declared `INEXACT'. */ + +#define Fast_Two_Sum_Tail(a, b, x, y) \ + bvirt = x - a; \ + y = b - bvirt + +#define Fast_Two_Sum(a, b, x, y) \ + x = (REAL) (a + b); \ + Fast_Two_Sum_Tail(a, b, x, y) + +#define Fast_Two_Diff_Tail(a, b, x, y) \ + bvirt = a - x; \ + y = bvirt - b + +#define Fast_Two_Diff(a, b, x, y) \ + x = (REAL) (a - b); \ + Fast_Two_Diff_Tail(a, b, x, y) + +#define Two_Sum_Tail(a, b, x, y) \ + bvirt = (REAL) (x - a); \ + avirt = x - bvirt; \ + bround = b - bvirt; \ + around = a - avirt; \ + y = around + bround + +#define Two_Sum(a, b, x, y) \ + x = (REAL) (a + b); \ + Two_Sum_Tail(a, b, x, y) + +#define Two_Diff_Tail(a, b, x, y) \ + bvirt = (REAL) (a - x); \ + avirt = x + bvirt; \ + bround = bvirt - b; \ + around = a - avirt; \ + y = around + bround + +#define Two_Diff(a, b, x, y) \ + x = (REAL) (a - b); \ + Two_Diff_Tail(a, b, x, y) + +#define Split(a, ahi, alo) \ + c = (REAL) (splitter * a); \ + abig = (REAL) (c - a); \ + ahi = c - abig; \ + alo = a - ahi + +#define Two_Product_Tail(a, b, x, y) \ + Split(a, ahi, alo); \ + Split(b, bhi, blo); \ + err1 = x - (ahi * bhi); \ + err2 = err1 - (alo * bhi); \ + err3 = err2 - (ahi * blo); \ + y = (alo * blo) - err3 + +#define Two_Product(a, b, x, y) \ + x = (REAL) (a * b); \ + Two_Product_Tail(a, b, x, y) + +/* Two_Product_Presplit() is Two_Product() where one of the inputs has */ +/* already been split. Avoids redundant splitting. */ + +#define Two_Product_Presplit(a, b, bhi, blo, x, y) \ + x = (REAL) (a * b); \ + Split(a, ahi, alo); \ + err1 = x - (ahi * bhi); \ + err2 = err1 - (alo * bhi); \ + err3 = err2 - (ahi * blo); \ + y = (alo * blo) - err3 + +/* Two_Product_2Presplit() is Two_Product() where both of the inputs have */ +/* already been split. Avoids redundant splitting. */ + +#define Two_Product_2Presplit(a, ahi, alo, b, bhi, blo, x, y) \ + x = (REAL) (a * b); \ + err1 = x - (ahi * bhi); \ + err2 = err1 - (alo * bhi); \ + err3 = err2 - (ahi * blo); \ + y = (alo * blo) - err3 + +/* Square() can be done more quickly than Two_Product(). */ + +#define Square_Tail(a, x, y) \ + Split(a, ahi, alo); \ + err1 = x - (ahi * ahi); \ + err3 = err1 - ((ahi + ahi) * alo); \ + y = (alo * alo) - err3 + +#define Square(a, x, y) \ + x = (REAL) (a * a); \ + Square_Tail(a, x, y) + +/* Macros for summing expansions of various fixed lengths. These are all */ +/* unrolled versions of Expansion_Sum(). */ + +#define Two_One_Sum(a1, a0, b, x2, x1, x0) \ + Two_Sum(a0, b , _i, x0); \ + Two_Sum(a1, _i, x2, x1) + +#define Two_One_Diff(a1, a0, b, x2, x1, x0) \ + Two_Diff(a0, b , _i, x0); \ + Two_Sum( a1, _i, x2, x1) + +#define Two_Two_Sum(a1, a0, b1, b0, x3, x2, x1, x0) \ + Two_One_Sum(a1, a0, b0, _j, _0, x0); \ + Two_One_Sum(_j, _0, b1, x3, x2, x1) + +#define Two_Two_Diff(a1, a0, b1, b0, x3, x2, x1, x0) \ + Two_One_Diff(a1, a0, b0, _j, _0, x0); \ + Two_One_Diff(_j, _0, b1, x3, x2, x1) + +#define Four_One_Sum(a3, a2, a1, a0, b, x4, x3, x2, x1, x0) \ + Two_One_Sum(a1, a0, b , _j, x1, x0); \ + Two_One_Sum(a3, a2, _j, x4, x3, x2) + +#define Four_Two_Sum(a3, a2, a1, a0, b1, b0, x5, x4, x3, x2, x1, x0) \ + Four_One_Sum(a3, a2, a1, a0, b0, _k, _2, _1, _0, x0); \ + Four_One_Sum(_k, _2, _1, _0, b1, x5, x4, x3, x2, x1) + +#define Four_Four_Sum(a3, a2, a1, a0, b4, b3, b1, b0, x7, x6, x5, x4, x3, x2, \ + x1, x0) \ + Four_Two_Sum(a3, a2, a1, a0, b1, b0, _l, _2, _1, _0, x1, x0); \ + Four_Two_Sum(_l, _2, _1, _0, b4, b3, x7, x6, x5, x4, x3, x2) + +#define Eight_One_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b, x8, x7, x6, x5, x4, \ + x3, x2, x1, x0) \ + Four_One_Sum(a3, a2, a1, a0, b , _j, x3, x2, x1, x0); \ + Four_One_Sum(a7, a6, a5, a4, _j, x8, x7, x6, x5, x4) + +#define Eight_Two_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b1, b0, x9, x8, x7, \ + x6, x5, x4, x3, x2, x1, x0) \ + Eight_One_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b0, _k, _6, _5, _4, _3, _2, \ + _1, _0, x0); \ + Eight_One_Sum(_k, _6, _5, _4, _3, _2, _1, _0, b1, x9, x8, x7, x6, x5, x4, \ + x3, x2, x1) + +#define Eight_Four_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b4, b3, b1, b0, x11, \ + x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, x0) \ + Eight_Two_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b1, b0, _l, _6, _5, _4, _3, \ + _2, _1, _0, x1, x0); \ + Eight_Two_Sum(_l, _6, _5, _4, _3, _2, _1, _0, b4, b3, x11, x10, x9, x8, \ + x7, x6, x5, x4, x3, x2) + +/* Macros for multiplying expansions of various fixed lengths. */ + +#define Two_One_Product(a1, a0, b, x3, x2, x1, x0) \ + Split(b, bhi, blo); \ + Two_Product_Presplit(a0, b, bhi, blo, _i, x0); \ + Two_Product_Presplit(a1, b, bhi, blo, _j, _0); \ + Two_Sum(_i, _0, _k, x1); \ + Fast_Two_Sum(_j, _k, x3, x2) + +#define Four_One_Product(a3, a2, a1, a0, b, x7, x6, x5, x4, x3, x2, x1, x0) \ + Split(b, bhi, blo); \ + Two_Product_Presplit(a0, b, bhi, blo, _i, x0); \ + Two_Product_Presplit(a1, b, bhi, blo, _j, _0); \ + Two_Sum(_i, _0, _k, x1); \ + Fast_Two_Sum(_j, _k, _i, x2); \ + Two_Product_Presplit(a2, b, bhi, blo, _j, _0); \ + Two_Sum(_i, _0, _k, x3); \ + Fast_Two_Sum(_j, _k, _i, x4); \ + Two_Product_Presplit(a3, b, bhi, blo, _j, _0); \ + Two_Sum(_i, _0, _k, x5); \ + Fast_Two_Sum(_j, _k, x7, x6) + +#define Two_Two_Product(a1, a0, b1, b0, x7, x6, x5, x4, x3, x2, x1, x0) \ + Split(a0, a0hi, a0lo); \ + Split(b0, bhi, blo); \ + Two_Product_2Presplit(a0, a0hi, a0lo, b0, bhi, blo, _i, x0); \ + Split(a1, a1hi, a1lo); \ + Two_Product_2Presplit(a1, a1hi, a1lo, b0, bhi, blo, _j, _0); \ + Two_Sum(_i, _0, _k, _1); \ + Fast_Two_Sum(_j, _k, _l, _2); \ + Split(b1, bhi, blo); \ + Two_Product_2Presplit(a0, a0hi, a0lo, b1, bhi, blo, _i, _0); \ + Two_Sum(_1, _0, _k, x1); \ + Two_Sum(_2, _k, _j, _1); \ + Two_Sum(_l, _j, _m, _2); \ + Two_Product_2Presplit(a1, a1hi, a1lo, b1, bhi, blo, _j, _0); \ + Two_Sum(_i, _0, _n, _0); \ + Two_Sum(_1, _0, _i, x2); \ + Two_Sum(_2, _i, _k, _1); \ + Two_Sum(_m, _k, _l, _2); \ + Two_Sum(_j, _n, _k, _0); \ + Two_Sum(_1, _0, _j, x3); \ + Two_Sum(_2, _j, _i, _1); \ + Two_Sum(_l, _i, _m, _2); \ + Two_Sum(_1, _k, _i, x4); \ + Two_Sum(_2, _i, _k, x5); \ + Two_Sum(_m, _k, x7, x6) + +/* An expansion of length two can be squared more quickly than finding the */ +/* product of two different expansions of length two, and the result is */ +/* guaranteed to have no more than six (rather than eight) components. */ + +#define Two_Square(a1, a0, x5, x4, x3, x2, x1, x0) \ + Square(a0, _j, x0); \ + _0 = a0 + a0; \ + Two_Product(a1, _0, _k, _1); \ + Two_One_Sum(_k, _1, _j, _l, _2, x1); \ + Square(a1, _j, _1); \ + Two_Two_Sum(_j, _1, _l, _2, x5, x4, x3, x2) + +REAL splitter; /* = 2^ceiling(p / 2) + 1. Used to split floats in half. */ +REAL epsilon; /* = 2^(-p). Used to estimate roundoff errors. */ +/* A set of coefficients used to calculate maximum roundoff errors. */ +REAL resulterrbound; +REAL o2derrboundA, o2derrboundB, o2derrboundC; +REAL o3derrboundA, o3derrboundB, o3derrboundC; +REAL iccerrboundA, iccerrboundB, iccerrboundC; +REAL isperrboundA, isperrboundB, isperrboundC; + +/*****************************************************************************/ +/* */ +/* exactinit() Initialize the variables used for exact arithmetic. */ +/* */ +/* `epsilon' is the largest power of two such that 1.0 + epsilon = 1.0 in */ +/* floating-point arithmetic. `epsilon' bounds the relative roundoff */ +/* error. It is used for floating-point error analysis. */ +/* */ +/* `splitter' is used to split floating-point numbers into two half- */ +/* length significands for exact multiplication. */ +/* */ +/* I imagine that a highly optimizing compiler might be too smart for its */ +/* own good, and somehow cause this routine to fail, if it pretends that */ +/* floating-point arithmetic is too much like real arithmetic. */ +/* */ +/* Don't change this routine unless you fully understand it. */ +/* */ +/*****************************************************************************/ + +void exactinit() +{ + REAL half; + REAL check, lastcheck; + int every_other; +#ifdef LINUX + int cword; +#endif /* LINUX */ + +#ifdef CPU86 +#ifdef SINGLE + _control87(_PC_24, _MCW_PC); /* Set FPU control word for single precision. */ +#else /* not SINGLE */ + _control87(_PC_53, _MCW_PC); /* Set FPU control word for double precision. */ +#endif /* not SINGLE */ +#endif /* CPU86 */ +#ifdef LINUX +#ifdef SINGLE + /* cword = 4223; */ + cword = 4210; /* set FPU control word for single precision */ +#else /* not SINGLE */ + /* cword = 4735; */ + cword = 4722; /* set FPU control word for double precision */ +#endif /* not SINGLE */ + _FPU_SETCW(cword); +#endif /* LINUX */ + + every_other = 1; + half = 0.5; + epsilon = 1.0; + splitter = 1.0; + check = 1.0; + + /* Repeatedly divide `epsilon' by two until it is too small to add to */ + /* one without causing roundoff. (Also check if the sum is equal to */ + /* the previous sum, for machines that round up instead of using exact */ + /* rounding. Not that these routines will work on such machines.) */ + do { + lastcheck = check; + epsilon *= half; + if (every_other) { + splitter *= 2.0; + } + every_other = !every_other; + check = 1.0 + epsilon; + } while ((check != 1.0) && (check != lastcheck)); + splitter += 1.0; + + /* Error bounds for orientation and insphere tests. */ + resulterrbound = (3.0 + 8.0 * epsilon) * epsilon; + o2derrboundA = (3.0 + 16.0 * epsilon) * epsilon; + o2derrboundB = (2.0 + 12.0 * epsilon) * epsilon; + o2derrboundC = (9.0 + 64.0 * epsilon) * epsilon * epsilon; + o3derrboundA = (7.0 + 56.0 * epsilon) * epsilon; + o3derrboundB = (3.0 + 28.0 * epsilon) * epsilon; + o3derrboundC = (26.0 + 288.0 * epsilon) * epsilon * epsilon; + isperrboundA = (16.0 + 224.0 * epsilon) * epsilon; + isperrboundB = (5.0 + 72.0 * epsilon) * epsilon; + isperrboundC = (71.0 + 1408.0 * epsilon) * epsilon * epsilon; +} + +/*****************************************************************************/ +/* */ +/* grow_expansion() Add a scalar to an expansion. */ +/* */ +/* Sets h = e + b. See the long version of my paper for details. */ +/* */ +/* Maintains the nonoverlapping property. If round-to-even is used (as */ +/* with IEEE 754), maintains the strongly nonoverlapping and nonadjacent */ +/* properties as well. (That is, if e has one of these properties, so */ +/* will h.) */ +/* */ +/*****************************************************************************/ + +int grow_expansion ( + int elen, + __const_ptr(REAL) e , + REAL b , + __write_ptr(REAL) h ) /* e and h can be the same. */ +{ + REAL Q, Qnew; + int eindex; + REAL enow; + REAL bvirt, avirt, bround, around; + + Q = b; + for (eindex = 0; eindex < elen; eindex++) { + enow = e[eindex]; + Two_Sum(Q, enow, Qnew, h[eindex]); + Q = Qnew; + } + h[eindex] = Q; + return eindex + 1; +} + +/*****************************************************************************/ +/* */ +/* grow_expansion_zeroelim() Add a scalar to an expansion, eliminating */ +/* zero components from the output expansion. */ +/* */ +/* Sets h = e + b. See the long version of my paper for details. */ +/* */ +/* Maintains the nonoverlapping property. If round-to-even is used (as */ +/* with IEEE 754), maintains the strongly nonoverlapping and nonadjacent */ +/* properties as well. (That is, if e has one of these properties, so */ +/* will h.) */ +/* */ +/*****************************************************************************/ + +int grow_expansion_zeroelim ( + int elen, + __const_ptr(REAL) e , + REAL b , + __write_ptr(REAL) h ) /* e and h can be the same. */ +{ + REAL Q, hh, Qnew; + int eindex, hindex; + REAL enow; + REAL bvirt, avirt, bround, around; + + hindex = 0; + Q = b; + for (eindex = 0; eindex < elen; eindex++) { + enow = e[eindex]; + Two_Sum(Q, enow, Qnew, hh); + Q = Qnew; + if (hh != 0.0) { + h[hindex++] = hh; + } + } + if ((Q != 0.0) || (hindex == 0)) { + h[hindex++] = Q; + } + return hindex; +} + +/*****************************************************************************/ +/* */ +/* expansion_sum() Sum two expansions. */ +/* */ +/* Sets h = e + f. See the long version of my paper for details. */ +/* */ +/* Maintains the nonoverlapping property. If round-to-even is used (as */ +/* with IEEE 754), maintains the nonadjacent property as well. (That is, */ +/* if e has one of these properties, so will h.) Does NOT maintain the */ +/* strongly nonoverlapping property. */ +/* */ +/*****************************************************************************/ + +int expansion_sum ( + int elen, + __const_ptr(REAL) e , + int flen, + __const_ptr(REAL) f , + __write_ptr(REAL) h ) +/* e and h can be the same, but f and h cannot. */ +{ + REAL Q, Qnew; + int findex, hindex, hlast; + REAL hnow; + REAL bvirt, avirt, bround, around; + + Q = f[0]; + for (hindex = 0; hindex < elen; hindex++) { + hnow = e[hindex]; + Two_Sum(Q, hnow, Qnew, h[hindex]); + Q = Qnew; + } + h[hindex] = Q; + hlast = hindex; + for (findex = 1; findex < flen; findex++) { + Q = f[findex]; + for (hindex = findex; hindex <= hlast; hindex++) { + hnow = h[hindex]; + Two_Sum(Q, hnow, Qnew, h[hindex]); + Q = Qnew; + } + h[++hlast] = Q; + } + return hlast + 1; +} + +/*****************************************************************************/ +/* */ +/* expansion_sum_zeroelim1() Sum two expansions, eliminating zero */ +/* components from the output expansion. */ +/* */ +/* Sets h = e + f. See the long version of my paper for details. */ +/* */ +/* Maintains the nonoverlapping property. If round-to-even is used (as */ +/* with IEEE 754), maintains the nonadjacent property as well. (That is, */ +/* if e has one of these properties, so will h.) Does NOT maintain the */ +/* strongly nonoverlapping property. */ +/* */ +/*****************************************************************************/ + +int expansion_sum_zeroelim1 ( + int elen, + __const_ptr(REAL) e , + int flen, + __const_ptr(REAL) f , + __write_ptr(REAL) h ) +/* e and h can be the same, but f and h cannot. */ +{ + REAL Q, Qnew; + int index, findex, hindex, hlast; + REAL hnow; + REAL bvirt, avirt, bround, around; + + Q = f[0]; + for (hindex = 0; hindex < elen; hindex++) { + hnow = e[hindex]; + Two_Sum(Q, hnow, Qnew, h[hindex]); + Q = Qnew; + } + h[hindex] = Q; + hlast = hindex; + for (findex = 1; findex < flen; findex++) { + Q = f[findex]; + for (hindex = findex; hindex <= hlast; hindex++) { + hnow = h[hindex]; + Two_Sum(Q, hnow, Qnew, h[hindex]); + Q = Qnew; + } + h[++hlast] = Q; + } + hindex = -1; + for (index = 0; index <= hlast; index++) { + hnow = h[index]; + if (hnow != 0.0) { + h[++hindex] = hnow; + } + } + if (hindex == -1) { + return 1; + } else { + return hindex + 1; + } +} + +/*****************************************************************************/ +/* */ +/* expansion_sum_zeroelim2() Sum two expansions, eliminating zero */ +/* components from the output expansion. */ +/* */ +/* Sets h = e + f. See the long version of my paper for details. */ +/* */ +/* Maintains the nonoverlapping property. If round-to-even is used (as */ +/* with IEEE 754), maintains the nonadjacent property as well. (That is, */ +/* if e has one of these properties, so will h.) Does NOT maintain the */ +/* strongly nonoverlapping property. */ +/* */ +/*****************************************************************************/ + +int expansion_sum_zeroelim2 ( + int elen, + __const_ptr(REAL) e , + int flen, + __const_ptr(REAL) f , + __write_ptr(REAL) h ) +/* e and h can be the same, but f and h cannot. */ +{ + REAL Q, hh, Qnew; + int eindex, findex, hindex, hlast; + REAL enow; + REAL bvirt, avirt, bround, around; + + hindex = 0; + Q = f[0]; + for (eindex = 0; eindex < elen; eindex++) { + enow = e[eindex]; + Two_Sum(Q, enow, Qnew, hh); + Q = Qnew; + if (hh != 0.0) { + h[hindex++] = hh; + } + } + h[hindex] = Q; + hlast = hindex; + for (findex = 1; findex < flen; findex++) { + hindex = 0; + Q = f[findex]; + for (eindex = 0; eindex <= hlast; eindex++) { + enow = h[eindex]; + Two_Sum(Q, enow, Qnew, hh); + Q = Qnew; + if (hh != 0) { + h[hindex++] = hh; + } + } + h[hindex] = Q; + hlast = hindex; + } + return hlast + 1; +} + +/*****************************************************************************/ +/* */ +/* fast_expansion_sum() Sum two expansions. */ +/* */ +/* Sets h = e + f. See the long version of my paper for details. */ +/* */ +/* If round-to-even is used (as with IEEE 754), maintains the strongly */ +/* nonoverlapping property. (That is, if e is strongly nonoverlapping, h */ +/* will be also.) Does NOT maintain the nonoverlapping or nonadjacent */ +/* properties. */ +/* */ +/*****************************************************************************/ + +int fast_expansion_sum ( + int elen, + __const_ptr(REAL) e , + int flen, + __const_ptr(REAL) f , + __write_ptr(REAL) h ) /* h cannot be e or f. */ +{ + REAL Q, Qnew; + REAL bvirt, avirt, bround, around; + int eindex, findex, hindex; + REAL enow, fnow; + + enow = e[0]; + fnow = f[0]; + eindex = findex = 0; + if ((fnow > enow) == (fnow > -enow)) { + Q = enow; + enow = e[++eindex]; + } else { + Q = fnow; + fnow = f[++findex]; + } + hindex = 0; + if ((eindex < elen) && (findex < flen)) { + if ((fnow > enow) == (fnow > -enow)) { + Fast_Two_Sum(enow, Q, Qnew, h[0]); + enow = e[++eindex]; + } else { + Fast_Two_Sum(fnow, Q, Qnew, h[0]); + fnow = f[++findex]; + } + Q = Qnew; + hindex = 1; + while ((eindex < elen) && (findex < flen)) { + if ((fnow > enow) == (fnow > -enow)) { + Two_Sum(Q, enow, Qnew, h[hindex]); + enow = e[++eindex]; + } else { + Two_Sum(Q, fnow, Qnew, h[hindex]); + fnow = f[++findex]; + } + Q = Qnew; + hindex++; + } + } + while (eindex < elen) { + Two_Sum(Q, enow, Qnew, h[hindex]); + enow = e[++eindex]; + Q = Qnew; + hindex++; + } + while (findex < flen) { + Two_Sum(Q, fnow, Qnew, h[hindex]); + fnow = f[++findex]; + Q = Qnew; + hindex++; + } + h[hindex] = Q; + return hindex + 1; +} + +/*****************************************************************************/ +/* */ +/* fast_expansion_sum_zeroelim() Sum two expansions, eliminating zero */ +/* components from the output expansion. */ +/* */ +/* Sets h = e + f. See the long version of my paper for details. */ +/* */ +/* If round-to-even is used (as with IEEE 754), maintains the strongly */ +/* nonoverlapping property. (That is, if e is strongly nonoverlapping, h */ +/* will be also.) Does NOT maintain the nonoverlapping or nonadjacent */ +/* properties. */ +/* */ +/*****************************************************************************/ + +int fast_expansion_sum_zeroelim ( + int elen, + __const_ptr(REAL) e , + int flen, + __const_ptr(REAL) f , + __write_ptr(REAL) h ) /* h cannot be e or f. */ +{ + REAL Q, Qnew, hh; + REAL bvirt, avirt, bround, around; + int eindex, findex, hindex; + REAL enow, fnow; + + enow = e[0]; + fnow = f[0]; + eindex = findex = 0; + if ((fnow > enow) == (fnow > -enow)) { + Q = enow; + enow = e[++eindex]; + } else { + Q = fnow; + fnow = f[++findex]; + } + hindex = 0; + if ((eindex < elen) && (findex < flen)) { + if ((fnow > enow) == (fnow > -enow)) { + Fast_Two_Sum(enow, Q, Qnew, hh); + enow = e[++eindex]; + } else { + Fast_Two_Sum(fnow, Q, Qnew, hh); + fnow = f[++findex]; + } + Q = Qnew; + if (hh != 0.0) { + h[hindex++] = hh; + } + while ((eindex < elen) && (findex < flen)) { + if ((fnow > enow) == (fnow > -enow)) { + Two_Sum(Q, enow, Qnew, hh); + enow = e[++eindex]; + } else { + Two_Sum(Q, fnow, Qnew, hh); + fnow = f[++findex]; + } + Q = Qnew; + if (hh != 0.0) { + h[hindex++] = hh; + } + } + } + while (eindex < elen) { + Two_Sum(Q, enow, Qnew, hh); + enow = e[++eindex]; + Q = Qnew; + if (hh != 0.0) { + h[hindex++] = hh; + } + } + while (findex < flen) { + Two_Sum(Q, fnow, Qnew, hh); + fnow = f[++findex]; + Q = Qnew; + if (hh != 0.0) { + h[hindex++] = hh; + } + } + if ((Q != 0.0) || (hindex == 0)) { + h[hindex++] = Q; + } + return hindex; +} + +/*****************************************************************************/ +/* */ +/* linear_expansion_sum() Sum two expansions. */ +/* */ +/* Sets h = e + f. See either version of my paper for details. */ +/* */ +/* Maintains the nonoverlapping property. (That is, if e is */ +/* nonoverlapping, h will be also.) */ +/* */ +/*****************************************************************************/ + +int linear_expansion_sum ( + int elen, + __const_ptr(REAL) e , + int flen, + __const_ptr(REAL) f , + __write_ptr(REAL) h ) /* h cannot be e or f. */ +{ + REAL Q, q, Qnew, R; + REAL bvirt, avirt, bround, around; + int eindex, findex, hindex; + REAL enow, fnow, g0; + + enow = e[0]; + fnow = f[0]; + eindex = findex = 0; + if ((fnow > enow) == (fnow > -enow)) { + g0 = enow; + enow = e[++eindex]; + } else { + g0 = fnow; + fnow = f[++findex]; + } + if ((eindex < elen) && ((findex >= flen) + || ((fnow > enow) == (fnow > -enow)))) { + Fast_Two_Sum(enow, g0, Qnew, q); + enow = e[++eindex]; + } else { + Fast_Two_Sum(fnow, g0, Qnew, q); + fnow = f[++findex]; + } + Q = Qnew; + for (hindex = 0; hindex < elen + flen - 2; hindex++) { + if ((eindex < elen) && ((findex >= flen) + || ((fnow > enow) == (fnow > -enow)))) { + Fast_Two_Sum(enow, q, R, h[hindex]); + enow = e[++eindex]; + } else { + Fast_Two_Sum(fnow, q, R, h[hindex]); + fnow = f[++findex]; + } + Two_Sum(Q, R, Qnew, q); + Q = Qnew; + } + h[hindex] = q; + h[hindex + 1] = Q; + return hindex + 2; +} + +/*****************************************************************************/ +/* */ +/* linear_expansion_sum_zeroelim() Sum two expansions, eliminating zero */ +/* components from the output expansion. */ +/* */ +/* Sets h = e + f. See either version of my paper for details. */ +/* */ +/* Maintains the nonoverlapping property. (That is, if e is */ +/* nonoverlapping, h will be also.) */ +/* */ +/*****************************************************************************/ + +int linear_expansion_sum_zeroelim ( + int elen, + __const_ptr(REAL) e , + int flen, + __const_ptr(REAL) f , + __write_ptr(REAL) h ) /* h cannot be e or f. */ +{ + REAL Q, q, hh, Qnew, R; + REAL bvirt, avirt, bround, around; + int eindex, findex, hindex; + int count; + REAL enow, fnow, g0; + + enow = e[0]; + fnow = f[0]; + eindex = findex = 0; + hindex = 0; + if ((fnow > enow) == (fnow > -enow)) { + g0 = enow; + enow = e[++eindex]; + } else { + g0 = fnow; + fnow = f[++findex]; + } + if ((eindex < elen) && ((findex >= flen) + || ((fnow > enow) == (fnow > -enow)))) { + Fast_Two_Sum(enow, g0, Qnew, q); + enow = e[++eindex]; + } else { + Fast_Two_Sum(fnow, g0, Qnew, q); + fnow = f[++findex]; + } + Q = Qnew; + for (count = 2; count < elen + flen; count++) { + if ((eindex < elen) && ((findex >= flen) + || ((fnow > enow) == (fnow > -enow)))) { + Fast_Two_Sum(enow, q, R, hh); + enow = e[++eindex]; + } else { + Fast_Two_Sum(fnow, q, R, hh); + fnow = f[++findex]; + } + Two_Sum(Q, R, Qnew, q); + Q = Qnew; + if (hh != 0) { + h[hindex++] = hh; + } + } + if (q != 0) { + h[hindex++] = q; + } + if ((Q != 0.0) || (hindex == 0)) { + h[hindex++] = Q; + } + return hindex; +} + +/*****************************************************************************/ +/* */ +/* scale_expansion() Multiply an expansion by a scalar. */ +/* */ +/* Sets h = be. See either version of my paper for details. */ +/* */ +/* Maintains the nonoverlapping property. If round-to-even is used (as */ +/* with IEEE 754), maintains the strongly nonoverlapping and nonadjacent */ +/* properties as well. (That is, if e has one of these properties, so */ +/* will h.) */ +/* */ +/*****************************************************************************/ + +int scale_expansion ( + int elen, + __const_ptr(REAL) e , + REAL b , + __write_ptr(REAL) h ) /* e and h cannot be the same. */ +{ + REAL Q, sum, product1, product0; + int eindex, hindex; + REAL enow; + REAL bvirt, avirt, bround, around; + REAL c, abig, ahi, alo, bhi, blo; + REAL err1, err2, err3; + + Split(b, bhi, blo); + Two_Product_Presplit(e[0], b, bhi, blo, Q, h[0]); + hindex = 1; + for (eindex = 1; eindex < elen; eindex++) { + enow = e[eindex]; + Two_Product_Presplit(enow, b, bhi, blo, product1, product0); + Two_Sum(Q, product0, sum, h[hindex]); + hindex++; + Two_Sum(product1, sum, Q, h[hindex]); + hindex++; + } + h[hindex] = Q; + return elen + elen; +} + +/*****************************************************************************/ +/* */ +/* scale_expansion_zeroelim() Multiply an expansion by a scalar, */ +/* eliminating zero components from the */ +/* output expansion. */ +/* */ +/* Sets h = be. See either version of my paper for details. */ +/* */ +/* Maintains the nonoverlapping property. If round-to-even is used (as */ +/* with IEEE 754), maintains the strongly nonoverlapping and nonadjacent */ +/* properties as well. (That is, if e has one of these properties, so */ +/* will h.) */ +/* */ +/*****************************************************************************/ + +int scale_expansion_zeroelim ( + int elen, + __const_ptr(REAL) e , + REAL b , + __write_ptr(REAL) h ) /* e and h cannot be the same. */ +{ + REAL Q, sum, hh; + REAL product1, product0; + int eindex, hindex; + REAL enow; + REAL bvirt, avirt, bround, around; + REAL c, abig, ahi, alo, bhi, blo; + REAL err1, err2, err3; + + Split(b, bhi, blo); + Two_Product_Presplit(e[0], b, bhi, blo, Q, hh); + hindex = 0; + if (hh != 0) { + h[hindex++] = hh; + } + for (eindex = 1; eindex < elen; eindex++) { + enow = e[eindex]; + Two_Product_Presplit(enow, b, bhi, blo, product1, product0); + Two_Sum(Q, product0, sum, hh); + if (hh != 0) { + h[hindex++] = hh; + } + Fast_Two_Sum(product1, sum, Q, hh); + if (hh != 0) { + h[hindex++] = hh; + } + } + if ((Q != 0.0) || (hindex == 0)) { + h[hindex++] = Q; + } + return hindex; +} + +/*****************************************************************************/ +/* */ +/* compress() Compress an expansion. */ +/* */ +/* See the long version of my paper for details. */ +/* */ +/* Maintains the nonoverlapping property. If round-to-even is used (as */ +/* with IEEE 754), then any nonoverlapping expansion is converted to a */ +/* nonadjacent expansion. */ +/* */ +/*****************************************************************************/ + +int compress ( + int elen, + __const_ptr(REAL) e , + __write_ptr(REAL) h ) /* e and h may be the same. */ +{ + REAL Q, q, Qnew; + int eindex, hindex; + REAL bvirt; + REAL enow, hnow; + int top, bottom; + + bottom = elen - 1; + Q = e[bottom]; + for (eindex = elen - 2; eindex >= 0; eindex--) { + enow = e[eindex]; + Fast_Two_Sum(Q, enow, Qnew, q); + if (q != 0) { + h[bottom--] = Qnew; + Q = q; + } else { + Q = Qnew; + } + } + top = 0; + for (hindex = bottom + 1; hindex < elen; hindex++) { + hnow = h[hindex]; + Fast_Two_Sum(hnow, Q, Qnew, q); + if (q != 0) { + h[top++] = q; + } + Q = Qnew; + } + h[top] = Q; + return top + 1; +} + +/*****************************************************************************/ +/* */ +/* estimate() Produce a one-word estimate of an expansion's value. */ +/* */ +/* See either version of my paper for details. */ +/* */ +/*****************************************************************************/ + +REAL estimate ( + int elen, + __const_ptr(REAL) e ) +{ + REAL Q; + int eindex; + + Q = e[0]; + for (eindex = 1; eindex < elen; eindex++) { + Q += e[eindex]; + } + return Q; +} + +/*****************************************************************************/ +/* */ +/* orient2d() Adaptive exact 2D orientation test. Robust. */ +/* */ +/* Return a positive value if the points pa, pb, and pc occur */ +/* in counterclockwise order; a negative value if they occur */ +/* in clockwise order; and zero if they are collinear. The */ +/* result is also a rough approximation of twice the signed */ +/* area of the triangle defined by the three points. */ +/* */ +/* The last three use exact arithmetic to ensure a correct answer. The */ +/* result returned is the determinant of a matrix. In orient2d() only, */ +/* this determinant is computed adaptively, in the sense that exact */ +/* arithmetic is used only to the degree it is needed to ensure that the */ +/* returned value has the correct sign. Hence, orient2d() is usually quite */ +/* fast, but will run more slowly when the input points are collinear or */ +/* nearly so. */ +/* */ +/*****************************************************************************/ + +REAL orient2dexact ( + __const_ptr(REAL) pa, + __const_ptr(REAL) pb, + __const_ptr(REAL) pc) +{ + REAL axby1, axcy1, bxcy1, bxay1, cxay1, cxby1; + REAL axby0, axcy0, bxcy0, bxay0, cxay0, cxby0; + REAL aterms[4], bterms[4], cterms[4]; + REAL aterms3, bterms3, cterms3; + REAL v[8], w[12]; + int vlength=0, wlength=0; + + REAL bvirt, avirt, bround, around; + REAL c, abig, ahi, alo, bhi, blo; + REAL err1, err2, err3; + REAL _i, _j, _0; + + Two_Product(pa[0], pb[1], axby1, axby0); + Two_Product(pa[0], pc[1], axcy1, axcy0); + Two_Two_Diff(axby1, axby0, axcy1, axcy0, + aterms3, aterms[2], aterms[1], aterms[0]); + aterms[3] = aterms3; + + Two_Product(pb[0], pc[1], bxcy1, bxcy0); + Two_Product(pb[0], pa[1], bxay1, bxay0); + Two_Two_Diff(bxcy1, bxcy0, bxay1, bxay0, + bterms3, bterms[2], bterms[1], bterms[0]); + bterms[3] = bterms3; + + Two_Product(pc[0], pa[1], cxay1, cxay0); + Two_Product(pc[0], pb[1], cxby1, cxby0); + Two_Two_Diff(cxay1, cxay0, cxby1, cxby0, + cterms3, cterms[2], cterms[1], cterms[0]); + cterms[3] = cterms3; + + vlength = fast_expansion_sum_zeroelim(4, aterms, 4, bterms, v); + wlength = fast_expansion_sum_zeroelim(vlength, v, 4, cterms, w); + + return w[wlength - 1]; +} + +REAL orient2dadapt ( + __const_ptr(REAL) pa, + __const_ptr(REAL) pb, + __const_ptr(REAL) pc, + REAL detsum) +{ + REAL acx, acy, bcx, bcy; + REAL acxtail, acytail, bcxtail, bcytail; + REAL detleft, detright; + REAL detlefttail, detrighttail; + REAL det, errbound; + REAL B[4], C1[8], C2[12], D[16]; + REAL B3; + int C1length=0, C2length=0, Dlength=0; + REAL u[4]; + REAL u3, s1, t1, s0, t0; + + REAL bvirt, avirt, bround, around; + REAL c, abig, ahi, alo, bhi, blo; + REAL err1, err2, err3; + REAL _i, _j, _0; + + acx = (REAL) (pa[0] - pc[0]); + bcx = (REAL) (pb[0] - pc[0]); + acy = (REAL) (pa[1] - pc[1]); + bcy = (REAL) (pb[1] - pc[1]); + + Two_Product(acx, bcy, detleft, detlefttail); + Two_Product(acy, bcx, detright, detrighttail); + + Two_Two_Diff(detleft, detlefttail, detright, detrighttail, + B3, B[2], B[1], B[0]); + B[3] = B3; + + det = estimate(4, B); + errbound = o2derrboundB * detsum; + if ((det >= errbound) || (-det >= errbound)) { + return det; + } + + Two_Diff_Tail(pa[0], pc[0], acx, acxtail); + Two_Diff_Tail(pb[0], pc[0], bcx, bcxtail); + Two_Diff_Tail(pa[1], pc[1], acy, acytail); + Two_Diff_Tail(pb[1], pc[1], bcy, bcytail); + + if ((acxtail == 0.0) && (acytail == 0.0) + && (bcxtail == 0.0) && (bcytail == 0.0)) { + return det; + } + + errbound = o2derrboundC * detsum + resulterrbound * Absolute(det); + det += (acx * bcytail + bcy * acxtail) + - (acy * bcxtail + bcx * acytail); + if ((det >= errbound) || (-det >= errbound)) { + return det; + } + + Two_Product(acxtail, bcy, s1, s0); + Two_Product(acytail, bcx, t1, t0); + Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]); + u[3] = u3; + C1length = fast_expansion_sum_zeroelim(4, B, 4, u, C1); + + Two_Product(acx, bcytail, s1, s0); + Two_Product(acy, bcxtail, t1, t0); + Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]); + u[3] = u3; + C2length = fast_expansion_sum_zeroelim(C1length, C1, 4, u, C2); + + Two_Product(acxtail, bcytail, s1, s0); + Two_Product(acytail, bcxtail, t1, t0); + Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]); + u[3] = u3; + Dlength = fast_expansion_sum_zeroelim(C2length, C2, 4, u, D); + + return(D[Dlength - 1]); +} + +REAL orient2d ( + __const_ptr(REAL) pa, + __const_ptr(REAL) pb, + __const_ptr(REAL) pc) +{ + REAL detleft, detright, det; + REAL detsum, errbound; + + detleft = (pa[0] - pc[0]) * (pb[1] - pc[1]); + detright = (pa[1] - pc[1]) * (pb[0] - pc[0]); + det = detleft - detright; + + if (detleft > 0.0) { + if (detright <= 0.0) { + return det; + } else { + detsum = detleft + detright; + } + } else if (detleft < 0.0) { + if (detright >= 0.0) { + return det; + } else { + detsum = -detleft - detright; + } + } else { + return det; + } + + errbound = o2derrboundA * detsum; + if ((det >= errbound) || (-det >= errbound)) { + return det; + } + + return orient2dadapt(pa, pb, pc, detsum); +} + +/*****************************************************************************/ +/* */ +/* orient3d() Adaptive exact 3D orientation test. Robust. */ +/* */ +/* Return a positive value if the point pd lies below the */ +/* plane passing through pa, pb, and pc; "below" is defined so */ +/* that pa, pb, and pc appear in counterclockwise order when */ +/* viewed from above the plane. Returns a negative value if */ +/* pd lies above the plane. Returns zero if the points are */ +/* coplanar. The result is also a rough approximation of six */ +/* times the signed volume of the tetrahedron defined by the */ +/* four points. */ +/* */ +/* The last three use exact arithmetic to ensure a correct answer. The */ +/* result returned is the determinant of a matrix. In orient3d() only, */ +/* this determinant is computed adaptively, in the sense that exact */ +/* arithmetic is used only to the degree it is needed to ensure that the */ +/* returned value has the correct sign. Hence, orient3d() is usually quite */ +/* fast, but will run more slowly when the input points are coplanar or */ +/* nearly so. */ +/* */ +/*****************************************************************************/ + +REAL orient3dexact ( + __const_ptr(REAL) pa, + __const_ptr(REAL) pb, + __const_ptr(REAL) pc, + __const_ptr(REAL) pd) +{ + REAL axby1, bxcy1, cxdy1, dxay1, axcy1, bxdy1; + REAL bxay1, cxby1, dxcy1, axdy1, cxay1, dxby1; + REAL axby0, bxcy0, cxdy0, dxay0, axcy0, bxdy0; + REAL bxay0, cxby0, dxcy0, axdy0, cxay0, dxby0; + REAL ab[4], bc[4], cd[4], da[4], ac[4], bd[4]; + REAL temp8[8]; + int templen=0; + REAL abc[12], bcd[12], cda[12], dab[12]; + int abclen=0, bcdlen=0, cdalen=0, dablen=0; + REAL adet[24], bdet[24], cdet[24], ddet[24]; + int alen=0, blen=0, clen=0, dlen=0; + REAL abdet[48], cddet[48]; + int ablen=0, cdlen=0; + REAL deter[96]; + int deterlen=0; + int i; + + REAL bvirt, avirt, bround, around; + REAL c, abig, ahi, alo, bhi, blo; + REAL err1, err2, err3; + REAL _i, _j, _0; + + Two_Product(pa[0], pb[1], axby1, axby0); + Two_Product(pb[0], pa[1], bxay1, bxay0); + Two_Two_Diff(axby1, axby0, bxay1, bxay0, ab[3], ab[2], ab[1], ab[0]); + + Two_Product(pb[0], pc[1], bxcy1, bxcy0); + Two_Product(pc[0], pb[1], cxby1, cxby0); + Two_Two_Diff(bxcy1, bxcy0, cxby1, cxby0, bc[3], bc[2], bc[1], bc[0]); + + Two_Product(pc[0], pd[1], cxdy1, cxdy0); + Two_Product(pd[0], pc[1], dxcy1, dxcy0); + Two_Two_Diff(cxdy1, cxdy0, dxcy1, dxcy0, cd[3], cd[2], cd[1], cd[0]); + + Two_Product(pd[0], pa[1], dxay1, dxay0); + Two_Product(pa[0], pd[1], axdy1, axdy0); + Two_Two_Diff(dxay1, dxay0, axdy1, axdy0, da[3], da[2], da[1], da[0]); + + Two_Product(pa[0], pc[1], axcy1, axcy0); + Two_Product(pc[0], pa[1], cxay1, cxay0); + Two_Two_Diff(axcy1, axcy0, cxay1, cxay0, ac[3], ac[2], ac[1], ac[0]); + + Two_Product(pb[0], pd[1], bxdy1, bxdy0); + Two_Product(pd[0], pb[1], dxby1, dxby0); + Two_Two_Diff(bxdy1, bxdy0, dxby1, dxby0, bd[3], bd[2], bd[1], bd[0]); + + templen = fast_expansion_sum_zeroelim(4, cd, 4, da, temp8); + cdalen = fast_expansion_sum_zeroelim(templen, temp8, 4, ac, cda); + templen = fast_expansion_sum_zeroelim(4, da, 4, ab, temp8); + dablen = fast_expansion_sum_zeroelim(templen, temp8, 4, bd, dab); + for (i = 0; i < 4; i++) { + bd[i] = -bd[i]; + ac[i] = -ac[i]; + } + templen = fast_expansion_sum_zeroelim(4, ab, 4, bc, temp8); + abclen = fast_expansion_sum_zeroelim(templen, temp8, 4, ac, abc); + templen = fast_expansion_sum_zeroelim(4, bc, 4, cd, temp8); + bcdlen = fast_expansion_sum_zeroelim(templen, temp8, 4, bd, bcd); + + alen = scale_expansion_zeroelim(bcdlen, bcd, pa[2], adet); + blen = scale_expansion_zeroelim(cdalen, cda, -pb[2], bdet); + clen = scale_expansion_zeroelim(dablen, dab, pc[2], cdet); + dlen = scale_expansion_zeroelim(abclen, abc, -pd[2], ddet); + + ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); + cdlen = fast_expansion_sum_zeroelim(clen, cdet, dlen, ddet, cddet); + deterlen = fast_expansion_sum_zeroelim(ablen, abdet, cdlen, cddet, deter); + + return deter[deterlen - 1]; +} + +REAL orient3dadapt ( + __const_ptr(REAL) pa, + __const_ptr(REAL) pb, + __const_ptr(REAL) pc, + __const_ptr(REAL) pd, + REAL permanent) +{ + REAL adx, bdx, cdx, ady, bdy, cdy, adz, bdz, cdz; + REAL det, errbound; + + REAL bdxcdy1, cdxbdy1, cdxady1, adxcdy1, adxbdy1, bdxady1; + REAL bdxcdy0, cdxbdy0, cdxady0, adxcdy0, adxbdy0, bdxady0; + REAL bc[4], ca[4], ab[4]; + REAL bc3, ca3, ab3; + REAL adet[8], bdet[8], cdet[8]; + int alen=0, blen=0, clen=0; + REAL abdet[16]; + int ablen=0; + REAL *finnow, *finother, *finswap; + REAL fin1[192], fin2[192]; + int finlength=0; + + REAL adxtail, bdxtail, cdxtail; + REAL adytail, bdytail, cdytail; + REAL adztail, bdztail, cdztail; + REAL at_blarge, at_clarge; + REAL bt_clarge, bt_alarge; + REAL ct_alarge, ct_blarge; + REAL at_b[4], at_c[4], bt_c[4], bt_a[4], ct_a[4], ct_b[4]; + int at_blen=0, at_clen=0, bt_clen=0; + int bt_alen=0, ct_alen=0, ct_blen=0; + REAL bdxt_cdy1, cdxt_bdy1, cdxt_ady1; + REAL adxt_cdy1, adxt_bdy1, bdxt_ady1; + REAL bdxt_cdy0, cdxt_bdy0, cdxt_ady0; + REAL adxt_cdy0, adxt_bdy0, bdxt_ady0; + REAL bdyt_cdx1, cdyt_bdx1, cdyt_adx1; + REAL adyt_cdx1, adyt_bdx1, bdyt_adx1; + REAL bdyt_cdx0, cdyt_bdx0, cdyt_adx0; + REAL adyt_cdx0, adyt_bdx0, bdyt_adx0; + REAL bct[8], cat[8], abt[8]; + int bctlen=0, catlen=0, abtlen=0; + REAL bdxt_cdyt1, cdxt_bdyt1, cdxt_adyt1; + REAL adxt_cdyt1, adxt_bdyt1, bdxt_adyt1; + REAL bdxt_cdyt0, cdxt_bdyt0, cdxt_adyt0; + REAL adxt_cdyt0, adxt_bdyt0, bdxt_adyt0; + REAL u[4], v[12], w[16]; + REAL u3; + int vlength=0, wlength=0; + REAL negate; + + REAL bvirt, avirt, bround, around; + REAL c, abig, ahi, alo, bhi, blo; + REAL err1, err2, err3; + REAL _i, _j, _k, _0; + + adx = (REAL) (pa[0] - pd[0]); + bdx = (REAL) (pb[0] - pd[0]); + cdx = (REAL) (pc[0] - pd[0]); + ady = (REAL) (pa[1] - pd[1]); + bdy = (REAL) (pb[1] - pd[1]); + cdy = (REAL) (pc[1] - pd[1]); + adz = (REAL) (pa[2] - pd[2]); + bdz = (REAL) (pb[2] - pd[2]); + cdz = (REAL) (pc[2] - pd[2]); + + Two_Product(bdx, cdy, bdxcdy1, bdxcdy0); + Two_Product(cdx, bdy, cdxbdy1, cdxbdy0); + Two_Two_Diff(bdxcdy1, bdxcdy0, cdxbdy1, cdxbdy0, bc3, bc[2], bc[1], bc[0]); + bc[3] = bc3; + alen = scale_expansion_zeroelim(4, bc, adz, adet); + + Two_Product(cdx, ady, cdxady1, cdxady0); + Two_Product(adx, cdy, adxcdy1, adxcdy0); + Two_Two_Diff(cdxady1, cdxady0, adxcdy1, adxcdy0, ca3, ca[2], ca[1], ca[0]); + ca[3] = ca3; + blen = scale_expansion_zeroelim(4, ca, bdz, bdet); + + Two_Product(adx, bdy, adxbdy1, adxbdy0); + Two_Product(bdx, ady, bdxady1, bdxady0); + Two_Two_Diff(adxbdy1, adxbdy0, bdxady1, bdxady0, ab3, ab[2], ab[1], ab[0]); + ab[3] = ab3; + clen = scale_expansion_zeroelim(4, ab, cdz, cdet); + + ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); + finlength = fast_expansion_sum_zeroelim(ablen, abdet, clen, cdet, fin1); + + det = estimate(finlength, fin1); + errbound = o3derrboundB * permanent; + if ((det >= errbound) || (-det >= errbound)) { + return det; + } + + Two_Diff_Tail(pa[0], pd[0], adx, adxtail); + Two_Diff_Tail(pb[0], pd[0], bdx, bdxtail); + Two_Diff_Tail(pc[0], pd[0], cdx, cdxtail); + Two_Diff_Tail(pa[1], pd[1], ady, adytail); + Two_Diff_Tail(pb[1], pd[1], bdy, bdytail); + Two_Diff_Tail(pc[1], pd[1], cdy, cdytail); + Two_Diff_Tail(pa[2], pd[2], adz, adztail); + Two_Diff_Tail(pb[2], pd[2], bdz, bdztail); + Two_Diff_Tail(pc[2], pd[2], cdz, cdztail); + + if ((adxtail == 0.0) && (bdxtail == 0.0) && (cdxtail == 0.0) + && (adytail == 0.0) && (bdytail == 0.0) && (cdytail == 0.0) + && (adztail == 0.0) && (bdztail == 0.0) && (cdztail == 0.0)) { + return det; + } + + errbound = o3derrboundC * permanent + resulterrbound * Absolute(det); + det += (adz * ((bdx * cdytail + cdy * bdxtail) + - (bdy * cdxtail + cdx * bdytail)) + + adztail * (bdx * cdy - bdy * cdx)) + + (bdz * ((cdx * adytail + ady * cdxtail) + - (cdy * adxtail + adx * cdytail)) + + bdztail * (cdx * ady - cdy * adx)) + + (cdz * ((adx * bdytail + bdy * adxtail) + - (ady * bdxtail + bdx * adytail)) + + cdztail * (adx * bdy - ady * bdx)); + if ((det >= errbound) || (-det >= errbound)) { + return det; + } + + finnow = fin1; + finother = fin2; + + if (adxtail == 0.0) { + if (adytail == 0.0) { + at_b[0] = 0.0; + at_blen = 1; + at_c[0] = 0.0; + at_clen = 1; + } else { + negate = -adytail; + Two_Product(negate, bdx, at_blarge, at_b[0]); + at_b[1] = at_blarge; + at_blen = 2; + Two_Product(adytail, cdx, at_clarge, at_c[0]); + at_c[1] = at_clarge; + at_clen = 2; + } + } else { + if (adytail == 0.0) { + Two_Product(adxtail, bdy, at_blarge, at_b[0]); + at_b[1] = at_blarge; + at_blen = 2; + negate = -adxtail; + Two_Product(negate, cdy, at_clarge, at_c[0]); + at_c[1] = at_clarge; + at_clen = 2; + } else { + Two_Product(adxtail, bdy, adxt_bdy1, adxt_bdy0); + Two_Product(adytail, bdx, adyt_bdx1, adyt_bdx0); + Two_Two_Diff(adxt_bdy1, adxt_bdy0, adyt_bdx1, adyt_bdx0, + at_blarge, at_b[2], at_b[1], at_b[0]); + at_b[3] = at_blarge; + at_blen = 4; + Two_Product(adytail, cdx, adyt_cdx1, adyt_cdx0); + Two_Product(adxtail, cdy, adxt_cdy1, adxt_cdy0); + Two_Two_Diff(adyt_cdx1, adyt_cdx0, adxt_cdy1, adxt_cdy0, + at_clarge, at_c[2], at_c[1], at_c[0]); + at_c[3] = at_clarge; + at_clen = 4; + } + } + if (bdxtail == 0.0) { + if (bdytail == 0.0) { + bt_c[0] = 0.0; + bt_clen = 1; + bt_a[0] = 0.0; + bt_alen = 1; + } else { + negate = -bdytail; + Two_Product(negate, cdx, bt_clarge, bt_c[0]); + bt_c[1] = bt_clarge; + bt_clen = 2; + Two_Product(bdytail, adx, bt_alarge, bt_a[0]); + bt_a[1] = bt_alarge; + bt_alen = 2; + } + } else { + if (bdytail == 0.0) { + Two_Product(bdxtail, cdy, bt_clarge, bt_c[0]); + bt_c[1] = bt_clarge; + bt_clen = 2; + negate = -bdxtail; + Two_Product(negate, ady, bt_alarge, bt_a[0]); + bt_a[1] = bt_alarge; + bt_alen = 2; + } else { + Two_Product(bdxtail, cdy, bdxt_cdy1, bdxt_cdy0); + Two_Product(bdytail, cdx, bdyt_cdx1, bdyt_cdx0); + Two_Two_Diff(bdxt_cdy1, bdxt_cdy0, bdyt_cdx1, bdyt_cdx0, + bt_clarge, bt_c[2], bt_c[1], bt_c[0]); + bt_c[3] = bt_clarge; + bt_clen = 4; + Two_Product(bdytail, adx, bdyt_adx1, bdyt_adx0); + Two_Product(bdxtail, ady, bdxt_ady1, bdxt_ady0); + Two_Two_Diff(bdyt_adx1, bdyt_adx0, bdxt_ady1, bdxt_ady0, + bt_alarge, bt_a[2], bt_a[1], bt_a[0]); + bt_a[3] = bt_alarge; + bt_alen = 4; + } + } + if (cdxtail == 0.0) { + if (cdytail == 0.0) { + ct_a[0] = 0.0; + ct_alen = 1; + ct_b[0] = 0.0; + ct_blen = 1; + } else { + negate = -cdytail; + Two_Product(negate, adx, ct_alarge, ct_a[0]); + ct_a[1] = ct_alarge; + ct_alen = 2; + Two_Product(cdytail, bdx, ct_blarge, ct_b[0]); + ct_b[1] = ct_blarge; + ct_blen = 2; + } + } else { + if (cdytail == 0.0) { + Two_Product(cdxtail, ady, ct_alarge, ct_a[0]); + ct_a[1] = ct_alarge; + ct_alen = 2; + negate = -cdxtail; + Two_Product(negate, bdy, ct_blarge, ct_b[0]); + ct_b[1] = ct_blarge; + ct_blen = 2; + } else { + Two_Product(cdxtail, ady, cdxt_ady1, cdxt_ady0); + Two_Product(cdytail, adx, cdyt_adx1, cdyt_adx0); + Two_Two_Diff(cdxt_ady1, cdxt_ady0, cdyt_adx1, cdyt_adx0, + ct_alarge, ct_a[2], ct_a[1], ct_a[0]); + ct_a[3] = ct_alarge; + ct_alen = 4; + Two_Product(cdytail, bdx, cdyt_bdx1, cdyt_bdx0); + Two_Product(cdxtail, bdy, cdxt_bdy1, cdxt_bdy0); + Two_Two_Diff(cdyt_bdx1, cdyt_bdx0, cdxt_bdy1, cdxt_bdy0, + ct_blarge, ct_b[2], ct_b[1], ct_b[0]); + ct_b[3] = ct_blarge; + ct_blen = 4; + } + } + + bctlen = fast_expansion_sum_zeroelim(bt_clen, bt_c, ct_blen, ct_b, bct); + wlength = scale_expansion_zeroelim(bctlen, bct, adz, w); + finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w, + finother); + finswap = finnow; finnow = finother; finother = finswap; + + catlen = fast_expansion_sum_zeroelim(ct_alen, ct_a, at_clen, at_c, cat); + wlength = scale_expansion_zeroelim(catlen, cat, bdz, w); + finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w, + finother); + finswap = finnow; finnow = finother; finother = finswap; + + abtlen = fast_expansion_sum_zeroelim(at_blen, at_b, bt_alen, bt_a, abt); + wlength = scale_expansion_zeroelim(abtlen, abt, cdz, w); + finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w, + finother); + finswap = finnow; finnow = finother; finother = finswap; + + if (adztail != 0.0) { + vlength = scale_expansion_zeroelim(4, bc, adztail, v); + finlength = fast_expansion_sum_zeroelim(finlength, finnow, vlength, v, + finother); + finswap = finnow; finnow = finother; finother = finswap; + } + if (bdztail != 0.0) { + vlength = scale_expansion_zeroelim(4, ca, bdztail, v); + finlength = fast_expansion_sum_zeroelim(finlength, finnow, vlength, v, + finother); + finswap = finnow; finnow = finother; finother = finswap; + } + if (cdztail != 0.0) { + vlength = scale_expansion_zeroelim(4, ab, cdztail, v); + finlength = fast_expansion_sum_zeroelim(finlength, finnow, vlength, v, + finother); + finswap = finnow; finnow = finother; finother = finswap; + } + + if (adxtail != 0.0) { + if (bdytail != 0.0) { + Two_Product(adxtail, bdytail, adxt_bdyt1, adxt_bdyt0); + Two_One_Product(adxt_bdyt1, adxt_bdyt0, cdz, u3, u[2], u[1], u[0]); + u[3] = u3; + finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, + finother); + finswap = finnow; finnow = finother; finother = finswap; + if (cdztail != 0.0) { + Two_One_Product(adxt_bdyt1, adxt_bdyt0, cdztail, u3, u[2], u[1], u[0]); + u[3] = u3; + finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, + finother); + finswap = finnow; finnow = finother; finother = finswap; + } + } + if (cdytail != 0.0) { + negate = -adxtail; + Two_Product(negate, cdytail, adxt_cdyt1, adxt_cdyt0); + Two_One_Product(adxt_cdyt1, adxt_cdyt0, bdz, u3, u[2], u[1], u[0]); + u[3] = u3; + finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, + finother); + finswap = finnow; finnow = finother; finother = finswap; + if (bdztail != 0.0) { + Two_One_Product(adxt_cdyt1, adxt_cdyt0, bdztail, u3, u[2], u[1], u[0]); + u[3] = u3; + finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, + finother); + finswap = finnow; finnow = finother; finother = finswap; + } + } + } + if (bdxtail != 0.0) { + if (cdytail != 0.0) { + Two_Product(bdxtail, cdytail, bdxt_cdyt1, bdxt_cdyt0); + Two_One_Product(bdxt_cdyt1, bdxt_cdyt0, adz, u3, u[2], u[1], u[0]); + u[3] = u3; + finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, + finother); + finswap = finnow; finnow = finother; finother = finswap; + if (adztail != 0.0) { + Two_One_Product(bdxt_cdyt1, bdxt_cdyt0, adztail, u3, u[2], u[1], u[0]); + u[3] = u3; + finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, + finother); + finswap = finnow; finnow = finother; finother = finswap; + } + } + if (adytail != 0.0) { + negate = -bdxtail; + Two_Product(negate, adytail, bdxt_adyt1, bdxt_adyt0); + Two_One_Product(bdxt_adyt1, bdxt_adyt0, cdz, u3, u[2], u[1], u[0]); + u[3] = u3; + finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, + finother); + finswap = finnow; finnow = finother; finother = finswap; + if (cdztail != 0.0) { + Two_One_Product(bdxt_adyt1, bdxt_adyt0, cdztail, u3, u[2], u[1], u[0]); + u[3] = u3; + finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, + finother); + finswap = finnow; finnow = finother; finother = finswap; + } + } + } + if (cdxtail != 0.0) { + if (adytail != 0.0) { + Two_Product(cdxtail, adytail, cdxt_adyt1, cdxt_adyt0); + Two_One_Product(cdxt_adyt1, cdxt_adyt0, bdz, u3, u[2], u[1], u[0]); + u[3] = u3; + finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, + finother); + finswap = finnow; finnow = finother; finother = finswap; + if (bdztail != 0.0) { + Two_One_Product(cdxt_adyt1, cdxt_adyt0, bdztail, u3, u[2], u[1], u[0]); + u[3] = u3; + finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, + finother); + finswap = finnow; finnow = finother; finother = finswap; + } + } + if (bdytail != 0.0) { + negate = -cdxtail; + Two_Product(negate, bdytail, cdxt_bdyt1, cdxt_bdyt0); + Two_One_Product(cdxt_bdyt1, cdxt_bdyt0, adz, u3, u[2], u[1], u[0]); + u[3] = u3; + finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, + finother); + finswap = finnow; finnow = finother; finother = finswap; + if (adztail != 0.0) { + Two_One_Product(cdxt_bdyt1, cdxt_bdyt0, adztail, u3, u[2], u[1], u[0]); + u[3] = u3; + finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, + finother); + finswap = finnow; finnow = finother; finother = finswap; + } + } + } + + if (adztail != 0.0) { + wlength = scale_expansion_zeroelim(bctlen, bct, adztail, w); + finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w, + finother); + finswap = finnow; finnow = finother; finother = finswap; + } + if (bdztail != 0.0) { + wlength = scale_expansion_zeroelim(catlen, cat, bdztail, w); + finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w, + finother); + finswap = finnow; finnow = finother; finother = finswap; + } + if (cdztail != 0.0) { + wlength = scale_expansion_zeroelim(abtlen, abt, cdztail, w); + finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w, + finother); + finswap = finnow; finnow = finother; finother = finswap; + } + + return finnow[finlength - 1]; +} + +REAL orient3d ( + __const_ptr(REAL) pa, + __const_ptr(REAL) pb, + __const_ptr(REAL) pc, + __const_ptr(REAL) pd) +{ + REAL adx, bdx, cdx, ady, bdy, cdy, adz, bdz, cdz; + REAL bdxcdy, cdxbdy, cdxady, adxcdy, adxbdy, bdxady; + REAL det; + REAL permanent, errbound; + + adx = pa[0] - pd[0]; + bdx = pb[0] - pd[0]; + cdx = pc[0] - pd[0]; + ady = pa[1] - pd[1]; + bdy = pb[1] - pd[1]; + cdy = pc[1] - pd[1]; + adz = pa[2] - pd[2]; + bdz = pb[2] - pd[2]; + cdz = pc[2] - pd[2]; + + bdxcdy = bdx * cdy; + cdxbdy = cdx * bdy; + + cdxady = cdx * ady; + adxcdy = adx * cdy; + + adxbdy = adx * bdy; + bdxady = bdx * ady; + + det = adz * (bdxcdy - cdxbdy) + + bdz * (cdxady - adxcdy) + + cdz * (adxbdy - bdxady); + + permanent = (Absolute(bdxcdy) + Absolute(cdxbdy)) * Absolute(adz) + + (Absolute(cdxady) + Absolute(adxcdy)) * Absolute(bdz) + + (Absolute(adxbdy) + Absolute(bdxady)) * Absolute(cdz); + errbound = o3derrboundA * permanent; + if ((det > errbound) || (-det > errbound)) { + return det; + } + + return orient3dadapt(pa, pb, pc, pd, permanent); +} + +/*****************************************************************************/ +/* */ +/* incircle() Adaptive exact 2D incircle test. Robust. */ +/* */ +/* Return a positive value if the point pd lies inside the */ +/* circle passing through pa, pb, and pc; a negative value if */ +/* it lies outside; and zero if the four points are cocircular.*/ +/* The points pa, pb, and pc must be in counterclockwise */ +/* order, or the sign of the result will be reversed. */ +/* */ +/* The last three use exact arithmetic to ensure a correct answer. The */ +/* result returned is the determinant of a matrix. In incircle() only, */ +/* this determinant is computed adaptively, in the sense that exact */ +/* arithmetic is used only to the degree it is needed to ensure that the */ +/* returned value has the correct sign. Hence, incircle() is usually quite */ +/* fast, but will run more slowly when the input points are cocircular or */ +/* nearly so. */ +/* */ +/*****************************************************************************/ + +REAL incircleexact ( + __const_ptr(REAL) pa, + __const_ptr(REAL) pb, + __const_ptr(REAL) pc, + __const_ptr(REAL) pd) +{ + REAL axby1, bxcy1, cxdy1, dxay1, axcy1, bxdy1; + REAL bxay1, cxby1, dxcy1, axdy1, cxay1, dxby1; + REAL axby0, bxcy0, cxdy0, dxay0, axcy0, bxdy0; + REAL bxay0, cxby0, dxcy0, axdy0, cxay0, dxby0; + REAL ab[4], bc[4], cd[4], da[4], ac[4], bd[4]; + REAL temp8[8]; + int templen=0; + REAL abc[12], bcd[12], cda[12], dab[12]; + int abclen=0, bcdlen=0, cdalen=0, dablen=0; + REAL det24x[24], det24y[24], det48x[48], det48y[48]; + int xlen=0, ylen=0; + REAL adet[96], bdet[96], cdet[96], ddet[96]; + int alen=0, blen=0, clen=0, dlen=0; + REAL abdet[192], cddet[192]; + int ablen=0, cdlen=0; + REAL deter[384]; + int deterlen=0; + int i; + + REAL bvirt, avirt, bround, around; + REAL c, abig, ahi, alo, bhi, blo; + REAL err1, err2, err3; + REAL _i, _j, _0; + + Two_Product(pa[0], pb[1], axby1, axby0); + Two_Product(pb[0], pa[1], bxay1, bxay0); + Two_Two_Diff(axby1, axby0, bxay1, bxay0, ab[3], ab[2], ab[1], ab[0]); + + Two_Product(pb[0], pc[1], bxcy1, bxcy0); + Two_Product(pc[0], pb[1], cxby1, cxby0); + Two_Two_Diff(bxcy1, bxcy0, cxby1, cxby0, bc[3], bc[2], bc[1], bc[0]); + + Two_Product(pc[0], pd[1], cxdy1, cxdy0); + Two_Product(pd[0], pc[1], dxcy1, dxcy0); + Two_Two_Diff(cxdy1, cxdy0, dxcy1, dxcy0, cd[3], cd[2], cd[1], cd[0]); + + Two_Product(pd[0], pa[1], dxay1, dxay0); + Two_Product(pa[0], pd[1], axdy1, axdy0); + Two_Two_Diff(dxay1, dxay0, axdy1, axdy0, da[3], da[2], da[1], da[0]); + + Two_Product(pa[0], pc[1], axcy1, axcy0); + Two_Product(pc[0], pa[1], cxay1, cxay0); + Two_Two_Diff(axcy1, axcy0, cxay1, cxay0, ac[3], ac[2], ac[1], ac[0]); + + Two_Product(pb[0], pd[1], bxdy1, bxdy0); + Two_Product(pd[0], pb[1], dxby1, dxby0); + Two_Two_Diff(bxdy1, bxdy0, dxby1, dxby0, bd[3], bd[2], bd[1], bd[0]); + + templen = fast_expansion_sum_zeroelim(4, cd, 4, da, temp8); + cdalen = fast_expansion_sum_zeroelim(templen, temp8, 4, ac, cda); + templen = fast_expansion_sum_zeroelim(4, da, 4, ab, temp8); + dablen = fast_expansion_sum_zeroelim(templen, temp8, 4, bd, dab); + for (i = 0; i < 4; i++) { + bd[i] = -bd[i]; + ac[i] = -ac[i]; + } + templen = fast_expansion_sum_zeroelim(4, ab, 4, bc, temp8); + abclen = fast_expansion_sum_zeroelim(templen, temp8, 4, ac, abc); + templen = fast_expansion_sum_zeroelim(4, bc, 4, cd, temp8); + bcdlen = fast_expansion_sum_zeroelim(templen, temp8, 4, bd, bcd); + + xlen = scale_expansion_zeroelim(bcdlen, bcd, pa[0], det24x); + xlen = scale_expansion_zeroelim(xlen, det24x, pa[0], det48x); + ylen = scale_expansion_zeroelim(bcdlen, bcd, pa[1], det24y); + ylen = scale_expansion_zeroelim(ylen, det24y, pa[1], det48y); + alen = fast_expansion_sum_zeroelim(xlen, det48x, ylen, det48y, adet); + + xlen = scale_expansion_zeroelim(cdalen, cda, pb[0], det24x); + xlen = scale_expansion_zeroelim(xlen, det24x, -pb[0], det48x); + ylen = scale_expansion_zeroelim(cdalen, cda, pb[1], det24y); + ylen = scale_expansion_zeroelim(ylen, det24y, -pb[1], det48y); + blen = fast_expansion_sum_zeroelim(xlen, det48x, ylen, det48y, bdet); + + xlen = scale_expansion_zeroelim(dablen, dab, pc[0], det24x); + xlen = scale_expansion_zeroelim(xlen, det24x, pc[0], det48x); + ylen = scale_expansion_zeroelim(dablen, dab, pc[1], det24y); + ylen = scale_expansion_zeroelim(ylen, det24y, pc[1], det48y); + clen = fast_expansion_sum_zeroelim(xlen, det48x, ylen, det48y, cdet); + + xlen = scale_expansion_zeroelim(abclen, abc, pd[0], det24x); + xlen = scale_expansion_zeroelim(xlen, det24x, -pd[0], det48x); + ylen = scale_expansion_zeroelim(abclen, abc, pd[1], det24y); + ylen = scale_expansion_zeroelim(ylen, det24y, -pd[1], det48y); + dlen = fast_expansion_sum_zeroelim(xlen, det48x, ylen, det48y, ddet); + + ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); + cdlen = fast_expansion_sum_zeroelim(clen, cdet, dlen, ddet, cddet); + deterlen = fast_expansion_sum_zeroelim(ablen, abdet, cdlen, cddet, deter); + + return deter[deterlen - 1]; +} + +REAL incircleadapt ( + __const_ptr(REAL) pa, + __const_ptr(REAL) pb, + __const_ptr(REAL) pc, + __const_ptr(REAL) pd, + REAL permanent) +{ + REAL adx, bdx, cdx, ady, bdy, cdy; + REAL det, errbound; + + REAL bdxcdy1, cdxbdy1, cdxady1, adxcdy1, adxbdy1, bdxady1; + REAL bdxcdy0, cdxbdy0, cdxady0, adxcdy0, adxbdy0, bdxady0; + REAL bc[4], ca[4], ab[4]; + REAL bc3, ca3, ab3; + REAL axbc[8], axxbc[16], aybc[8], ayybc[16], adet[32]; + int axbclen=0, axxbclen=0, aybclen=0, ayybclen=0, alen=0; + REAL bxca[8], bxxca[16], byca[8], byyca[16], bdet[32]; + int bxcalen=0, bxxcalen=0, bycalen=0, byycalen=0, blen=0; + REAL cxab[8], cxxab[16], cyab[8], cyyab[16], cdet[32]; + int cxablen=0, cxxablen=0, cyablen=0, cyyablen=0, clen=0; + REAL abdet[64]; + int ablen=0; + REAL fin1[1152], fin2[1152]; + REAL *finnow, *finother, *finswap; + int finlength=0; + + REAL adxtail, bdxtail, cdxtail, adytail, bdytail, cdytail; + REAL adxadx1, adyady1, bdxbdx1, bdybdy1, cdxcdx1, cdycdy1; + REAL adxadx0, adyady0, bdxbdx0, bdybdy0, cdxcdx0, cdycdy0; + REAL aa[4], bb[4], cc[4]; + REAL aa3, bb3, cc3; + REAL ti1, tj1; + REAL ti0, tj0; + REAL u[4], v[4]; + REAL u3, v3; + REAL temp8[8], temp16a[16], temp16b[16], temp16c[16]; + REAL temp32a[32], temp32b[32], temp48[48], temp64[64]; + int temp8len=0, temp16alen=0, temp16blen=0, temp16clen=0; + int temp32alen=0, temp32blen=0, temp48len=0, temp64len=0; + REAL axtbb[8], axtcc[8], aytbb[8], aytcc[8]; + int axtbblen=0, axtcclen=0, aytbblen=0, aytcclen=0; + REAL bxtaa[8], bxtcc[8], bytaa[8], bytcc[8]; + int bxtaalen=0, bxtcclen=0, bytaalen=0, bytcclen=0; + REAL cxtaa[8], cxtbb[8], cytaa[8], cytbb[8]; + int cxtaalen=0, cxtbblen=0, cytaalen=0, cytbblen=0; + REAL axtbc[8], aytbc[8], bxtca[8], bytca[8], cxtab[8], cytab[8]; + int axtbclen=0, aytbclen=0, bxtcalen=0, bytcalen=0, cxtablen=0, cytablen=0; + REAL axtbct[16], aytbct[16], bxtcat[16], bytcat[16], cxtabt[16], cytabt[16]; + int axtbctlen=0, aytbctlen=0; + int bxtcatlen=0, bytcatlen=0; + int cxtabtlen=0, cytabtlen=0; + REAL axtbctt[8], aytbctt[8], bxtcatt[8]; + REAL bytcatt[8], cxtabtt[8], cytabtt[8]; + int axtbcttlen=0, aytbcttlen=0; + int bxtcattlen=0, bytcattlen=0; + int cxtabttlen=0, cytabttlen=0; + REAL abt[8], bct[8], cat[8]; + int abtlen=0, bctlen=0, catlen=0; + REAL abtt[4], bctt[4], catt[4]; + int abttlen=0, bcttlen=0, cattlen=0; + REAL abtt3, bctt3, catt3; + REAL negate; + + REAL bvirt, avirt, bround, around; + REAL c, abig, ahi, alo, bhi, blo; + REAL err1, err2, err3; + REAL _i, _j, _0; + + adx = (REAL) (pa[0] - pd[0]); + bdx = (REAL) (pb[0] - pd[0]); + cdx = (REAL) (pc[0] - pd[0]); + ady = (REAL) (pa[1] - pd[1]); + bdy = (REAL) (pb[1] - pd[1]); + cdy = (REAL) (pc[1] - pd[1]); + + Two_Product(bdx, cdy, bdxcdy1, bdxcdy0); + Two_Product(cdx, bdy, cdxbdy1, cdxbdy0); + Two_Two_Diff(bdxcdy1, bdxcdy0, cdxbdy1, cdxbdy0, bc3, bc[2], bc[1], bc[0]); + bc[3] = bc3; + axbclen = scale_expansion_zeroelim(4, bc, adx, axbc); + axxbclen = scale_expansion_zeroelim(axbclen, axbc, adx, axxbc); + aybclen = scale_expansion_zeroelim(4, bc, ady, aybc); + ayybclen = scale_expansion_zeroelim(aybclen, aybc, ady, ayybc); + alen = fast_expansion_sum_zeroelim(axxbclen, axxbc, ayybclen, ayybc, adet); + + Two_Product(cdx, ady, cdxady1, cdxady0); + Two_Product(adx, cdy, adxcdy1, adxcdy0); + Two_Two_Diff(cdxady1, cdxady0, adxcdy1, adxcdy0, ca3, ca[2], ca[1], ca[0]); + ca[3] = ca3; + bxcalen = scale_expansion_zeroelim(4, ca, bdx, bxca); + bxxcalen = scale_expansion_zeroelim(bxcalen, bxca, bdx, bxxca); + bycalen = scale_expansion_zeroelim(4, ca, bdy, byca); + byycalen = scale_expansion_zeroelim(bycalen, byca, bdy, byyca); + blen = fast_expansion_sum_zeroelim(bxxcalen, bxxca, byycalen, byyca, bdet); + + Two_Product(adx, bdy, adxbdy1, adxbdy0); + Two_Product(bdx, ady, bdxady1, bdxady0); + Two_Two_Diff(adxbdy1, adxbdy0, bdxady1, bdxady0, ab3, ab[2], ab[1], ab[0]); + ab[3] = ab3; + cxablen = scale_expansion_zeroelim(4, ab, cdx, cxab); + cxxablen = scale_expansion_zeroelim(cxablen, cxab, cdx, cxxab); + cyablen = scale_expansion_zeroelim(4, ab, cdy, cyab); + cyyablen = scale_expansion_zeroelim(cyablen, cyab, cdy, cyyab); + clen = fast_expansion_sum_zeroelim(cxxablen, cxxab, cyyablen, cyyab, cdet); + + ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); + finlength = fast_expansion_sum_zeroelim(ablen, abdet, clen, cdet, fin1); + + det = estimate(finlength, fin1); + errbound = iccerrboundB * permanent; + if ((det >= errbound) || (-det >= errbound)) { + return det; + } + + Two_Diff_Tail(pa[0], pd[0], adx, adxtail); + Two_Diff_Tail(pa[1], pd[1], ady, adytail); + Two_Diff_Tail(pb[0], pd[0], bdx, bdxtail); + Two_Diff_Tail(pb[1], pd[1], bdy, bdytail); + Two_Diff_Tail(pc[0], pd[0], cdx, cdxtail); + Two_Diff_Tail(pc[1], pd[1], cdy, cdytail); + if ((adxtail == 0.0) && (bdxtail == 0.0) && (cdxtail == 0.0) + && (adytail == 0.0) && (bdytail == 0.0) && (cdytail == 0.0)) { + return det; + } + + errbound = iccerrboundC * permanent + resulterrbound * Absolute(det); + det += ((adx * adx + ady * ady) * ((bdx * cdytail + cdy * bdxtail) + - (bdy * cdxtail + cdx * bdytail)) + + 2.0 * (adx * adxtail + ady * adytail) * (bdx * cdy - bdy * cdx)) + + ((bdx * bdx + bdy * bdy) * ((cdx * adytail + ady * cdxtail) + - (cdy * adxtail + adx * cdytail)) + + 2.0 * (bdx * bdxtail + bdy * bdytail) * (cdx * ady - cdy * adx)) + + ((cdx * cdx + cdy * cdy) * ((adx * bdytail + bdy * adxtail) + - (ady * bdxtail + bdx * adytail)) + + 2.0 * (cdx * cdxtail + cdy * cdytail) * (adx * bdy - ady * bdx)); + if ((det >= errbound) || (-det >= errbound)) { + return det; + } + + finnow = fin1; + finother = fin2; + + if ((bdxtail != 0.0) || (bdytail != 0.0) + || (cdxtail != 0.0) || (cdytail != 0.0)) { + Square(adx, adxadx1, adxadx0); + Square(ady, adyady1, adyady0); + Two_Two_Sum(adxadx1, adxadx0, adyady1, adyady0, aa3, aa[2], aa[1], aa[0]); + aa[3] = aa3; + } + if ((cdxtail != 0.0) || (cdytail != 0.0) + || (adxtail != 0.0) || (adytail != 0.0)) { + Square(bdx, bdxbdx1, bdxbdx0); + Square(bdy, bdybdy1, bdybdy0); + Two_Two_Sum(bdxbdx1, bdxbdx0, bdybdy1, bdybdy0, bb3, bb[2], bb[1], bb[0]); + bb[3] = bb3; + } + if ((adxtail != 0.0) || (adytail != 0.0) + || (bdxtail != 0.0) || (bdytail != 0.0)) { + Square(cdx, cdxcdx1, cdxcdx0); + Square(cdy, cdycdy1, cdycdy0); + Two_Two_Sum(cdxcdx1, cdxcdx0, cdycdy1, cdycdy0, cc3, cc[2], cc[1], cc[0]); + cc[3] = cc3; + } + + if (adxtail != 0.0) { + axtbclen = scale_expansion_zeroelim(4, bc, adxtail, axtbc); + temp16alen = scale_expansion_zeroelim(axtbclen, axtbc, 2.0 * adx, + temp16a); + + axtcclen = scale_expansion_zeroelim(4, cc, adxtail, axtcc); + temp16blen = scale_expansion_zeroelim(axtcclen, axtcc, bdy, temp16b); + + axtbblen = scale_expansion_zeroelim(4, bb, adxtail, axtbb); + temp16clen = scale_expansion_zeroelim(axtbblen, axtbb, -cdy, temp16c); + + temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, + temp16blen, temp16b, temp32a); + temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, + temp32alen, temp32a, temp48); + finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, + temp48, finother); + finswap = finnow; finnow = finother; finother = finswap; + } + if (adytail != 0.0) { + aytbclen = scale_expansion_zeroelim(4, bc, adytail, aytbc); + temp16alen = scale_expansion_zeroelim(aytbclen, aytbc, 2.0 * ady, + temp16a); + + aytbblen = scale_expansion_zeroelim(4, bb, adytail, aytbb); + temp16blen = scale_expansion_zeroelim(aytbblen, aytbb, cdx, temp16b); + + aytcclen = scale_expansion_zeroelim(4, cc, adytail, aytcc); + temp16clen = scale_expansion_zeroelim(aytcclen, aytcc, -bdx, temp16c); + + temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, + temp16blen, temp16b, temp32a); + temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, + temp32alen, temp32a, temp48); + finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, + temp48, finother); + finswap = finnow; finnow = finother; finother = finswap; + } + if (bdxtail != 0.0) { + bxtcalen = scale_expansion_zeroelim(4, ca, bdxtail, bxtca); + temp16alen = scale_expansion_zeroelim(bxtcalen, bxtca, 2.0 * bdx, + temp16a); + + bxtaalen = scale_expansion_zeroelim(4, aa, bdxtail, bxtaa); + temp16blen = scale_expansion_zeroelim(bxtaalen, bxtaa, cdy, temp16b); + + bxtcclen = scale_expansion_zeroelim(4, cc, bdxtail, bxtcc); + temp16clen = scale_expansion_zeroelim(bxtcclen, bxtcc, -ady, temp16c); + + temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, + temp16blen, temp16b, temp32a); + temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, + temp32alen, temp32a, temp48); + finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, + temp48, finother); + finswap = finnow; finnow = finother; finother = finswap; + } + if (bdytail != 0.0) { + bytcalen = scale_expansion_zeroelim(4, ca, bdytail, bytca); + temp16alen = scale_expansion_zeroelim(bytcalen, bytca, 2.0 * bdy, + temp16a); + + bytcclen = scale_expansion_zeroelim(4, cc, bdytail, bytcc); + temp16blen = scale_expansion_zeroelim(bytcclen, bytcc, adx, temp16b); + + bytaalen = scale_expansion_zeroelim(4, aa, bdytail, bytaa); + temp16clen = scale_expansion_zeroelim(bytaalen, bytaa, -cdx, temp16c); + + temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, + temp16blen, temp16b, temp32a); + temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, + temp32alen, temp32a, temp48); + finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, + temp48, finother); + finswap = finnow; finnow = finother; finother = finswap; + } + if (cdxtail != 0.0) { + cxtablen = scale_expansion_zeroelim(4, ab, cdxtail, cxtab); + temp16alen = scale_expansion_zeroelim(cxtablen, cxtab, 2.0 * cdx, + temp16a); + + cxtbblen = scale_expansion_zeroelim(4, bb, cdxtail, cxtbb); + temp16blen = scale_expansion_zeroelim(cxtbblen, cxtbb, ady, temp16b); + + cxtaalen = scale_expansion_zeroelim(4, aa, cdxtail, cxtaa); + temp16clen = scale_expansion_zeroelim(cxtaalen, cxtaa, -bdy, temp16c); + + temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, + temp16blen, temp16b, temp32a); + temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, + temp32alen, temp32a, temp48); + finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, + temp48, finother); + finswap = finnow; finnow = finother; finother = finswap; + } + if (cdytail != 0.0) { + cytablen = scale_expansion_zeroelim(4, ab, cdytail, cytab); + temp16alen = scale_expansion_zeroelim(cytablen, cytab, 2.0 * cdy, + temp16a); + + cytaalen = scale_expansion_zeroelim(4, aa, cdytail, cytaa); + temp16blen = scale_expansion_zeroelim(cytaalen, cytaa, bdx, temp16b); + + cytbblen = scale_expansion_zeroelim(4, bb, cdytail, cytbb); + temp16clen = scale_expansion_zeroelim(cytbblen, cytbb, -adx, temp16c); + + temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, + temp16blen, temp16b, temp32a); + temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, + temp32alen, temp32a, temp48); + finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, + temp48, finother); + finswap = finnow; finnow = finother; finother = finswap; + } + + if ((adxtail != 0.0) || (adytail != 0.0)) { + if ((bdxtail != 0.0) || (bdytail != 0.0) + || (cdxtail != 0.0) || (cdytail != 0.0)) { + Two_Product(bdxtail, cdy, ti1, ti0); + Two_Product(bdx, cdytail, tj1, tj0); + Two_Two_Sum(ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0]); + u[3] = u3; + negate = -bdy; + Two_Product(cdxtail, negate, ti1, ti0); + negate = -bdytail; + Two_Product(cdx, negate, tj1, tj0); + Two_Two_Sum(ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0]); + v[3] = v3; + bctlen = fast_expansion_sum_zeroelim(4, u, 4, v, bct); + + Two_Product(bdxtail, cdytail, ti1, ti0); + Two_Product(cdxtail, bdytail, tj1, tj0); + Two_Two_Diff(ti1, ti0, tj1, tj0, bctt3, bctt[2], bctt[1], bctt[0]); + bctt[3] = bctt3; + bcttlen = 4; + } else { + bct[0] = 0.0; + bctlen = 1; + bctt[0] = 0.0; + bcttlen = 1; + } + + if (adxtail != 0.0) { + temp16alen = scale_expansion_zeroelim(axtbclen, axtbc, adxtail, temp16a); + axtbctlen = scale_expansion_zeroelim(bctlen, bct, adxtail, axtbct); + temp32alen = scale_expansion_zeroelim(axtbctlen, axtbct, 2.0 * adx, + temp32a); + temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, + temp32alen, temp32a, temp48); + finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, + temp48, finother); + finswap = finnow; finnow = finother; finother = finswap; + if (bdytail != 0.0) { + temp8len = scale_expansion_zeroelim(4, cc, adxtail, temp8); + temp16alen = scale_expansion_zeroelim(temp8len, temp8, bdytail, + temp16a); + finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, + temp16a, finother); + finswap = finnow; finnow = finother; finother = finswap; + } + if (cdytail != 0.0) { + temp8len = scale_expansion_zeroelim(4, bb, -adxtail, temp8); + temp16alen = scale_expansion_zeroelim(temp8len, temp8, cdytail, + temp16a); + finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, + temp16a, finother); + finswap = finnow; finnow = finother; finother = finswap; + } + + temp32alen = scale_expansion_zeroelim(axtbctlen, axtbct, adxtail, + temp32a); + axtbcttlen = scale_expansion_zeroelim(bcttlen, bctt, adxtail, axtbctt); + temp16alen = scale_expansion_zeroelim(axtbcttlen, axtbctt, 2.0 * adx, + temp16a); + temp16blen = scale_expansion_zeroelim(axtbcttlen, axtbctt, adxtail, + temp16b); + temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, + temp16blen, temp16b, temp32b); + temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, + temp32blen, temp32b, temp64); + finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, + temp64, finother); + finswap = finnow; finnow = finother; finother = finswap; + } + if (adytail != 0.0) { + temp16alen = scale_expansion_zeroelim(aytbclen, aytbc, adytail, temp16a); + aytbctlen = scale_expansion_zeroelim(bctlen, bct, adytail, aytbct); + temp32alen = scale_expansion_zeroelim(aytbctlen, aytbct, 2.0 * ady, + temp32a); + temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, + temp32alen, temp32a, temp48); + finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, + temp48, finother); + finswap = finnow; finnow = finother; finother = finswap; + + + temp32alen = scale_expansion_zeroelim(aytbctlen, aytbct, adytail, + temp32a); + aytbcttlen = scale_expansion_zeroelim(bcttlen, bctt, adytail, aytbctt); + temp16alen = scale_expansion_zeroelim(aytbcttlen, aytbctt, 2.0 * ady, + temp16a); + temp16blen = scale_expansion_zeroelim(aytbcttlen, aytbctt, adytail, + temp16b); + temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, + temp16blen, temp16b, temp32b); + temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, + temp32blen, temp32b, temp64); + finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, + temp64, finother); + finswap = finnow; finnow = finother; finother = finswap; + } + } + if ((bdxtail != 0.0) || (bdytail != 0.0)) { + if ((cdxtail != 0.0) || (cdytail != 0.0) + || (adxtail != 0.0) || (adytail != 0.0)) { + Two_Product(cdxtail, ady, ti1, ti0); + Two_Product(cdx, adytail, tj1, tj0); + Two_Two_Sum(ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0]); + u[3] = u3; + negate = -cdy; + Two_Product(adxtail, negate, ti1, ti0); + negate = -cdytail; + Two_Product(adx, negate, tj1, tj0); + Two_Two_Sum(ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0]); + v[3] = v3; + catlen = fast_expansion_sum_zeroelim(4, u, 4, v, cat); + + Two_Product(cdxtail, adytail, ti1, ti0); + Two_Product(adxtail, cdytail, tj1, tj0); + Two_Two_Diff(ti1, ti0, tj1, tj0, catt3, catt[2], catt[1], catt[0]); + catt[3] = catt3; + cattlen = 4; + } else { + cat[0] = 0.0; + catlen = 1; + catt[0] = 0.0; + cattlen = 1; + } + + if (bdxtail != 0.0) { + temp16alen = scale_expansion_zeroelim(bxtcalen, bxtca, bdxtail, temp16a); + bxtcatlen = scale_expansion_zeroelim(catlen, cat, bdxtail, bxtcat); + temp32alen = scale_expansion_zeroelim(bxtcatlen, bxtcat, 2.0 * bdx, + temp32a); + temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, + temp32alen, temp32a, temp48); + finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, + temp48, finother); + finswap = finnow; finnow = finother; finother = finswap; + if (cdytail != 0.0) { + temp8len = scale_expansion_zeroelim(4, aa, bdxtail, temp8); + temp16alen = scale_expansion_zeroelim(temp8len, temp8, cdytail, + temp16a); + finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, + temp16a, finother); + finswap = finnow; finnow = finother; finother = finswap; + } + if (adytail != 0.0) { + temp8len = scale_expansion_zeroelim(4, cc, -bdxtail, temp8); + temp16alen = scale_expansion_zeroelim(temp8len, temp8, adytail, + temp16a); + finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, + temp16a, finother); + finswap = finnow; finnow = finother; finother = finswap; + } + + temp32alen = scale_expansion_zeroelim(bxtcatlen, bxtcat, bdxtail, + temp32a); + bxtcattlen = scale_expansion_zeroelim(cattlen, catt, bdxtail, bxtcatt); + temp16alen = scale_expansion_zeroelim(bxtcattlen, bxtcatt, 2.0 * bdx, + temp16a); + temp16blen = scale_expansion_zeroelim(bxtcattlen, bxtcatt, bdxtail, + temp16b); + temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, + temp16blen, temp16b, temp32b); + temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, + temp32blen, temp32b, temp64); + finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, + temp64, finother); + finswap = finnow; finnow = finother; finother = finswap; + } + if (bdytail != 0.0) { + temp16alen = scale_expansion_zeroelim(bytcalen, bytca, bdytail, temp16a); + bytcatlen = scale_expansion_zeroelim(catlen, cat, bdytail, bytcat); + temp32alen = scale_expansion_zeroelim(bytcatlen, bytcat, 2.0 * bdy, + temp32a); + temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, + temp32alen, temp32a, temp48); + finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, + temp48, finother); + finswap = finnow; finnow = finother; finother = finswap; + + + temp32alen = scale_expansion_zeroelim(bytcatlen, bytcat, bdytail, + temp32a); + bytcattlen = scale_expansion_zeroelim(cattlen, catt, bdytail, bytcatt); + temp16alen = scale_expansion_zeroelim(bytcattlen, bytcatt, 2.0 * bdy, + temp16a); + temp16blen = scale_expansion_zeroelim(bytcattlen, bytcatt, bdytail, + temp16b); + temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, + temp16blen, temp16b, temp32b); + temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, + temp32blen, temp32b, temp64); + finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, + temp64, finother); + finswap = finnow; finnow = finother; finother = finswap; + } + } + if ((cdxtail != 0.0) || (cdytail != 0.0)) { + if ((adxtail != 0.0) || (adytail != 0.0) + || (bdxtail != 0.0) || (bdytail != 0.0)) { + Two_Product(adxtail, bdy, ti1, ti0); + Two_Product(adx, bdytail, tj1, tj0); + Two_Two_Sum(ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0]); + u[3] = u3; + negate = -ady; + Two_Product(bdxtail, negate, ti1, ti0); + negate = -adytail; + Two_Product(bdx, negate, tj1, tj0); + Two_Two_Sum(ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0]); + v[3] = v3; + abtlen = fast_expansion_sum_zeroelim(4, u, 4, v, abt); + + Two_Product(adxtail, bdytail, ti1, ti0); + Two_Product(bdxtail, adytail, tj1, tj0); + Two_Two_Diff(ti1, ti0, tj1, tj0, abtt3, abtt[2], abtt[1], abtt[0]); + abtt[3] = abtt3; + abttlen = 4; + } else { + abt[0] = 0.0; + abtlen = 1; + abtt[0] = 0.0; + abttlen = 1; + } + + if (cdxtail != 0.0) { + temp16alen = scale_expansion_zeroelim(cxtablen, cxtab, cdxtail, temp16a); + cxtabtlen = scale_expansion_zeroelim(abtlen, abt, cdxtail, cxtabt); + temp32alen = scale_expansion_zeroelim(cxtabtlen, cxtabt, 2.0 * cdx, + temp32a); + temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, + temp32alen, temp32a, temp48); + finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, + temp48, finother); + finswap = finnow; finnow = finother; finother = finswap; + if (adytail != 0.0) { + temp8len = scale_expansion_zeroelim(4, bb, cdxtail, temp8); + temp16alen = scale_expansion_zeroelim(temp8len, temp8, adytail, + temp16a); + finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, + temp16a, finother); + finswap = finnow; finnow = finother; finother = finswap; + } + if (bdytail != 0.0) { + temp8len = scale_expansion_zeroelim(4, aa, -cdxtail, temp8); + temp16alen = scale_expansion_zeroelim(temp8len, temp8, bdytail, + temp16a); + finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, + temp16a, finother); + finswap = finnow; finnow = finother; finother = finswap; + } + + temp32alen = scale_expansion_zeroelim(cxtabtlen, cxtabt, cdxtail, + temp32a); + cxtabttlen = scale_expansion_zeroelim(abttlen, abtt, cdxtail, cxtabtt); + temp16alen = scale_expansion_zeroelim(cxtabttlen, cxtabtt, 2.0 * cdx, + temp16a); + temp16blen = scale_expansion_zeroelim(cxtabttlen, cxtabtt, cdxtail, + temp16b); + temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, + temp16blen, temp16b, temp32b); + temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, + temp32blen, temp32b, temp64); + finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, + temp64, finother); + finswap = finnow; finnow = finother; finother = finswap; + } + if (cdytail != 0.0) { + temp16alen = scale_expansion_zeroelim(cytablen, cytab, cdytail, temp16a); + cytabtlen = scale_expansion_zeroelim(abtlen, abt, cdytail, cytabt); + temp32alen = scale_expansion_zeroelim(cytabtlen, cytabt, 2.0 * cdy, + temp32a); + temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, + temp32alen, temp32a, temp48); + finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, + temp48, finother); + finswap = finnow; finnow = finother; finother = finswap; + + + temp32alen = scale_expansion_zeroelim(cytabtlen, cytabt, cdytail, + temp32a); + cytabttlen = scale_expansion_zeroelim(abttlen, abtt, cdytail, cytabtt); + temp16alen = scale_expansion_zeroelim(cytabttlen, cytabtt, 2.0 * cdy, + temp16a); + temp16blen = scale_expansion_zeroelim(cytabttlen, cytabtt, cdytail, + temp16b); + temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, + temp16blen, temp16b, temp32b); + temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, + temp32blen, temp32b, temp64); + finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, + temp64, finother); + finswap = finnow; finnow = finother; finother = finswap; + } + } + + return finnow[finlength - 1]; +} + +REAL incircle ( + __const_ptr(REAL) pa, + __const_ptr(REAL) pb, + __const_ptr(REAL) pc, + __const_ptr(REAL) pd) +{ + REAL adx, bdx, cdx, ady, bdy, cdy; + REAL bdxcdy, cdxbdy, cdxady, adxcdy, adxbdy, bdxady; + REAL alift, blift, clift; + REAL det; + REAL permanent, errbound; + + adx = pa[0] - pd[0]; + bdx = pb[0] - pd[0]; + cdx = pc[0] - pd[0]; + ady = pa[1] - pd[1]; + bdy = pb[1] - pd[1]; + cdy = pc[1] - pd[1]; + + bdxcdy = bdx * cdy; + cdxbdy = cdx * bdy; + alift = adx * adx + ady * ady; + + cdxady = cdx * ady; + adxcdy = adx * cdy; + blift = bdx * bdx + bdy * bdy; + + adxbdy = adx * bdy; + bdxady = bdx * ady; + clift = cdx * cdx + cdy * cdy; + + det = alift * (bdxcdy - cdxbdy) + + blift * (cdxady - adxcdy) + + clift * (adxbdy - bdxady); + + permanent = (Absolute(bdxcdy) + Absolute(cdxbdy)) * alift + + (Absolute(cdxady) + Absolute(adxcdy)) * blift + + (Absolute(adxbdy) + Absolute(bdxady)) * clift; + errbound = iccerrboundA * permanent; + if ((det > errbound) || (-det > errbound)) { + return det; + } + + return incircleadapt(pa, pb, pc, pd, permanent); +} + +/*****************************************************************************/ +/* */ +/* insphere() Adaptive exact 3D insphere test. Robust. */ +/* */ +/* Return a positive value if the point pe lies inside the */ +/* sphere passing through pa, pb, pc, and pd; a negative value */ +/* if it lies outside; and zero if the five points are */ +/* cospherical. The points pa, pb, pc, and pd must be ordered */ +/* so that they have a positive orientation (as defined by */ +/* orient3d()), or the sign of the result will be reversed. */ +/* */ +/* The last three use exact arithmetic to ensure a correct answer. The */ +/* result returned is the determinant of a matrix. In insphere() only, */ +/* this determinant is computed adaptively, in the sense that exact */ +/* arithmetic is used only to the degree it is needed to ensure that the */ +/* returned value has the correct sign. Hence, insphere() is usually quite */ +/* fast, but will run more slowly when the input points are cospherical or */ +/* nearly so. */ +/* */ +/*****************************************************************************/ + +REAL insphereexact ( + __const_ptr(REAL) pa, + __const_ptr(REAL) pb, + __const_ptr(REAL) pc, + __const_ptr(REAL) pd, + __const_ptr(REAL) pe) +{ + REAL axby1, bxcy1, cxdy1, dxey1, exay1; + REAL bxay1, cxby1, dxcy1, exdy1, axey1; + REAL axcy1, bxdy1, cxey1, dxay1, exby1; + REAL cxay1, dxby1, excy1, axdy1, bxey1; + REAL axby0, bxcy0, cxdy0, dxey0, exay0; + REAL bxay0, cxby0, dxcy0, exdy0, axey0; + REAL axcy0, bxdy0, cxey0, dxay0, exby0; + REAL cxay0, dxby0, excy0, axdy0, bxey0; + REAL ab[4], bc[4], cd[4], de[4], ea[4]; + REAL ac[4], bd[4], ce[4], da[4], eb[4]; + REAL temp8a[8], temp8b[8], temp16[16]; + int temp8alen=0, temp8blen=0, temp16len=0; + REAL abc[24], bcd[24], cde[24], dea[24], eab[24]; + REAL abd[24], bce[24], cda[24], deb[24], eac[24]; + int abclen=0, bcdlen=0, cdelen=0, dealen=0, eablen=0; + int abdlen=0, bcelen=0, cdalen=0, deblen=0, eaclen=0; + REAL temp48a[48], temp48b[48]; + int temp48alen=0, temp48blen=0; + REAL abcd[96], bcde[96], cdea[96], deab[96], eabc[96]; + int abcdlen=0, bcdelen=0, cdealen=0, deablen=0, eabclen=0; + REAL temp192[192]; + REAL det384x[384], det384y[384], det384z[384]; + int xlen=0, ylen=0, zlen=0; + REAL detxy[768]; + int xylen=0; + REAL adet[1152], bdet[1152], cdet[1152], ddet[1152], edet[1152]; + int alen=0, blen=0, clen=0, dlen=0, elen=0; + REAL abdet[2304], cddet[2304], cdedet[3456]; + int ablen=0, cdlen=0; + REAL deter[5760]; + int deterlen=0; + int i; + + REAL bvirt, avirt, bround, around; + REAL c, abig, ahi, alo, bhi, blo; + REAL err1, err2, err3; + REAL _i, _j, _0; + + Two_Product(pa[0], pb[1], axby1, axby0); + Two_Product(pb[0], pa[1], bxay1, bxay0); + Two_Two_Diff(axby1, axby0, bxay1, bxay0, ab[3], ab[2], ab[1], ab[0]); + + Two_Product(pb[0], pc[1], bxcy1, bxcy0); + Two_Product(pc[0], pb[1], cxby1, cxby0); + Two_Two_Diff(bxcy1, bxcy0, cxby1, cxby0, bc[3], bc[2], bc[1], bc[0]); + + Two_Product(pc[0], pd[1], cxdy1, cxdy0); + Two_Product(pd[0], pc[1], dxcy1, dxcy0); + Two_Two_Diff(cxdy1, cxdy0, dxcy1, dxcy0, cd[3], cd[2], cd[1], cd[0]); + + Two_Product(pd[0], pe[1], dxey1, dxey0); + Two_Product(pe[0], pd[1], exdy1, exdy0); + Two_Two_Diff(dxey1, dxey0, exdy1, exdy0, de[3], de[2], de[1], de[0]); + + Two_Product(pe[0], pa[1], exay1, exay0); + Two_Product(pa[0], pe[1], axey1, axey0); + Two_Two_Diff(exay1, exay0, axey1, axey0, ea[3], ea[2], ea[1], ea[0]); + + Two_Product(pa[0], pc[1], axcy1, axcy0); + Two_Product(pc[0], pa[1], cxay1, cxay0); + Two_Two_Diff(axcy1, axcy0, cxay1, cxay0, ac[3], ac[2], ac[1], ac[0]); + + Two_Product(pb[0], pd[1], bxdy1, bxdy0); + Two_Product(pd[0], pb[1], dxby1, dxby0); + Two_Two_Diff(bxdy1, bxdy0, dxby1, dxby0, bd[3], bd[2], bd[1], bd[0]); + + Two_Product(pc[0], pe[1], cxey1, cxey0); + Two_Product(pe[0], pc[1], excy1, excy0); + Two_Two_Diff(cxey1, cxey0, excy1, excy0, ce[3], ce[2], ce[1], ce[0]); + + Two_Product(pd[0], pa[1], dxay1, dxay0); + Two_Product(pa[0], pd[1], axdy1, axdy0); + Two_Two_Diff(dxay1, dxay0, axdy1, axdy0, da[3], da[2], da[1], da[0]); + + Two_Product(pe[0], pb[1], exby1, exby0); + Two_Product(pb[0], pe[1], bxey1, bxey0); + Two_Two_Diff(exby1, exby0, bxey1, bxey0, eb[3], eb[2], eb[1], eb[0]); + + temp8alen = scale_expansion_zeroelim(4, bc, pa[2], temp8a); + temp8blen = scale_expansion_zeroelim(4, ac, -pb[2], temp8b); + temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, + temp16); + temp8alen = scale_expansion_zeroelim(4, ab, pc[2], temp8a); + abclen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, + abc); + + temp8alen = scale_expansion_zeroelim(4, cd, pb[2], temp8a); + temp8blen = scale_expansion_zeroelim(4, bd, -pc[2], temp8b); + temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, + temp16); + temp8alen = scale_expansion_zeroelim(4, bc, pd[2], temp8a); + bcdlen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, + bcd); + + temp8alen = scale_expansion_zeroelim(4, de, pc[2], temp8a); + temp8blen = scale_expansion_zeroelim(4, ce, -pd[2], temp8b); + temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, + temp16); + temp8alen = scale_expansion_zeroelim(4, cd, pe[2], temp8a); + cdelen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, + cde); + + temp8alen = scale_expansion_zeroelim(4, ea, pd[2], temp8a); + temp8blen = scale_expansion_zeroelim(4, da, -pe[2], temp8b); + temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, + temp16); + temp8alen = scale_expansion_zeroelim(4, de, pa[2], temp8a); + dealen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, + dea); + + temp8alen = scale_expansion_zeroelim(4, ab, pe[2], temp8a); + temp8blen = scale_expansion_zeroelim(4, eb, -pa[2], temp8b); + temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, + temp16); + temp8alen = scale_expansion_zeroelim(4, ea, pb[2], temp8a); + eablen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, + eab); + + temp8alen = scale_expansion_zeroelim(4, bd, pa[2], temp8a); + temp8blen = scale_expansion_zeroelim(4, da, pb[2], temp8b); + temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, + temp16); + temp8alen = scale_expansion_zeroelim(4, ab, pd[2], temp8a); + abdlen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, + abd); + + temp8alen = scale_expansion_zeroelim(4, ce, pb[2], temp8a); + temp8blen = scale_expansion_zeroelim(4, eb, pc[2], temp8b); + temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, + temp16); + temp8alen = scale_expansion_zeroelim(4, bc, pe[2], temp8a); + bcelen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, + bce); + + temp8alen = scale_expansion_zeroelim(4, da, pc[2], temp8a); + temp8blen = scale_expansion_zeroelim(4, ac, pd[2], temp8b); + temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, + temp16); + temp8alen = scale_expansion_zeroelim(4, cd, pa[2], temp8a); + cdalen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, + cda); + + temp8alen = scale_expansion_zeroelim(4, eb, pd[2], temp8a); + temp8blen = scale_expansion_zeroelim(4, bd, pe[2], temp8b); + temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, + temp16); + temp8alen = scale_expansion_zeroelim(4, de, pb[2], temp8a); + deblen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, + deb); + + temp8alen = scale_expansion_zeroelim(4, ac, pe[2], temp8a); + temp8blen = scale_expansion_zeroelim(4, ce, pa[2], temp8b); + temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, + temp16); + temp8alen = scale_expansion_zeroelim(4, ea, pc[2], temp8a); + eaclen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, + eac); + + temp48alen = fast_expansion_sum_zeroelim(cdelen, cde, bcelen, bce, temp48a); + temp48blen = fast_expansion_sum_zeroelim(deblen, deb, bcdlen, bcd, temp48b); + for (i = 0; i < temp48blen; i++) { + temp48b[i] = -temp48b[i]; + } + bcdelen = fast_expansion_sum_zeroelim(temp48alen, temp48a, + temp48blen, temp48b, bcde); + xlen = scale_expansion_zeroelim(bcdelen, bcde, pa[0], temp192); + xlen = scale_expansion_zeroelim(xlen, temp192, pa[0], det384x); + ylen = scale_expansion_zeroelim(bcdelen, bcde, pa[1], temp192); + ylen = scale_expansion_zeroelim(ylen, temp192, pa[1], det384y); + zlen = scale_expansion_zeroelim(bcdelen, bcde, pa[2], temp192); + zlen = scale_expansion_zeroelim(zlen, temp192, pa[2], det384z); + xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy); + alen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, adet); + + temp48alen = fast_expansion_sum_zeroelim(dealen, dea, cdalen, cda, temp48a); + temp48blen = fast_expansion_sum_zeroelim(eaclen, eac, cdelen, cde, temp48b); + for (i = 0; i < temp48blen; i++) { + temp48b[i] = -temp48b[i]; + } + cdealen = fast_expansion_sum_zeroelim(temp48alen, temp48a, + temp48blen, temp48b, cdea); + xlen = scale_expansion_zeroelim(cdealen, cdea, pb[0], temp192); + xlen = scale_expansion_zeroelim(xlen, temp192, pb[0], det384x); + ylen = scale_expansion_zeroelim(cdealen, cdea, pb[1], temp192); + ylen = scale_expansion_zeroelim(ylen, temp192, pb[1], det384y); + zlen = scale_expansion_zeroelim(cdealen, cdea, pb[2], temp192); + zlen = scale_expansion_zeroelim(zlen, temp192, pb[2], det384z); + xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy); + blen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, bdet); + + temp48alen = fast_expansion_sum_zeroelim(eablen, eab, deblen, deb, temp48a); + temp48blen = fast_expansion_sum_zeroelim(abdlen, abd, dealen, dea, temp48b); + for (i = 0; i < temp48blen; i++) { + temp48b[i] = -temp48b[i]; + } + deablen = fast_expansion_sum_zeroelim(temp48alen, temp48a, + temp48blen, temp48b, deab); + xlen = scale_expansion_zeroelim(deablen, deab, pc[0], temp192); + xlen = scale_expansion_zeroelim(xlen, temp192, pc[0], det384x); + ylen = scale_expansion_zeroelim(deablen, deab, pc[1], temp192); + ylen = scale_expansion_zeroelim(ylen, temp192, pc[1], det384y); + zlen = scale_expansion_zeroelim(deablen, deab, pc[2], temp192); + zlen = scale_expansion_zeroelim(zlen, temp192, pc[2], det384z); + xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy); + clen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, cdet); + + temp48alen = fast_expansion_sum_zeroelim(abclen, abc, eaclen, eac, temp48a); + temp48blen = fast_expansion_sum_zeroelim(bcelen, bce, eablen, eab, temp48b); + for (i = 0; i < temp48blen; i++) { + temp48b[i] = -temp48b[i]; + } + eabclen = fast_expansion_sum_zeroelim(temp48alen, temp48a, + temp48blen, temp48b, eabc); + xlen = scale_expansion_zeroelim(eabclen, eabc, pd[0], temp192); + xlen = scale_expansion_zeroelim(xlen, temp192, pd[0], det384x); + ylen = scale_expansion_zeroelim(eabclen, eabc, pd[1], temp192); + ylen = scale_expansion_zeroelim(ylen, temp192, pd[1], det384y); + zlen = scale_expansion_zeroelim(eabclen, eabc, pd[2], temp192); + zlen = scale_expansion_zeroelim(zlen, temp192, pd[2], det384z); + xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy); + dlen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, ddet); + + temp48alen = fast_expansion_sum_zeroelim(bcdlen, bcd, abdlen, abd, temp48a); + temp48blen = fast_expansion_sum_zeroelim(cdalen, cda, abclen, abc, temp48b); + for (i = 0; i < temp48blen; i++) { + temp48b[i] = -temp48b[i]; + } + abcdlen = fast_expansion_sum_zeroelim(temp48alen, temp48a, + temp48blen, temp48b, abcd); + xlen = scale_expansion_zeroelim(abcdlen, abcd, pe[0], temp192); + xlen = scale_expansion_zeroelim(xlen, temp192, pe[0], det384x); + ylen = scale_expansion_zeroelim(abcdlen, abcd, pe[1], temp192); + ylen = scale_expansion_zeroelim(ylen, temp192, pe[1], det384y); + zlen = scale_expansion_zeroelim(abcdlen, abcd, pe[2], temp192); + zlen = scale_expansion_zeroelim(zlen, temp192, pe[2], det384z); + xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy); + elen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, edet); + + ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); + cdlen = fast_expansion_sum_zeroelim(clen, cdet, dlen, ddet, cddet); + cdelen = fast_expansion_sum_zeroelim(cdlen, cddet, elen, edet, cdedet); + deterlen = fast_expansion_sum_zeroelim(ablen, abdet, cdelen, cdedet, deter); + + return deter[deterlen - 1]; +} + +REAL insphereadapt ( + __const_ptr(REAL) pa, + __const_ptr(REAL) pb, + __const_ptr(REAL) pc, + __const_ptr(REAL) pd, + __const_ptr(REAL) pe, + REAL permanent) +{ + REAL aex, bex, cex, dex, aey, bey, cey, dey, aez, bez, cez, dez; + REAL det, errbound; + + REAL aexbey1, bexaey1, bexcey1, cexbey1; + REAL cexdey1, dexcey1, dexaey1, aexdey1; + REAL aexcey1, cexaey1, bexdey1, dexbey1; + REAL aexbey0, bexaey0, bexcey0, cexbey0; + REAL cexdey0, dexcey0, dexaey0, aexdey0; + REAL aexcey0, cexaey0, bexdey0, dexbey0; + REAL ab[4], bc[4], cd[4], da[4], ac[4], bd[4]; + REAL ab3, bc3, cd3, da3, ac3, bd3; + REAL abeps, bceps, cdeps, daeps, aceps, bdeps; + REAL temp8a[8], temp8b[8], temp8c[8], temp16[16], temp24[24], temp48[48]; + int temp8alen=0, temp8blen=0, temp8clen=0; + int temp16len=0, temp24len=0, temp48len=0; + REAL xdet[96], ydet[96], zdet[96], xydet[192]; + int xlen=0, ylen=0, zlen=0, xylen=0; + REAL adet[288], bdet[288], cdet[288], ddet[288]; + int alen=0, blen=0, clen=0, dlen=0; + REAL abdet[576], cddet[576]; + int ablen=0, cdlen=0; + REAL fin1[1152]; + int finlength=0; + + REAL aextail, bextail, cextail, dextail; + REAL aeytail, beytail, ceytail, deytail; + REAL aeztail, beztail, ceztail, deztail; + + REAL bvirt, avirt, bround, around; + REAL c, abig, ahi, alo, bhi, blo; + REAL err1, err2, err3; + REAL _i, _j, _0; + + aex = (REAL) (pa[0] - pe[0]); + bex = (REAL) (pb[0] - pe[0]); + cex = (REAL) (pc[0] - pe[0]); + dex = (REAL) (pd[0] - pe[0]); + aey = (REAL) (pa[1] - pe[1]); + bey = (REAL) (pb[1] - pe[1]); + cey = (REAL) (pc[1] - pe[1]); + dey = (REAL) (pd[1] - pe[1]); + aez = (REAL) (pa[2] - pe[2]); + bez = (REAL) (pb[2] - pe[2]); + cez = (REAL) (pc[2] - pe[2]); + dez = (REAL) (pd[2] - pe[2]); + + Two_Product(aex, bey, aexbey1, aexbey0); + Two_Product(bex, aey, bexaey1, bexaey0); + Two_Two_Diff(aexbey1, aexbey0, bexaey1, bexaey0, ab3, ab[2], ab[1], ab[0]); + ab[3] = ab3; + + Two_Product(bex, cey, bexcey1, bexcey0); + Two_Product(cex, bey, cexbey1, cexbey0); + Two_Two_Diff(bexcey1, bexcey0, cexbey1, cexbey0, bc3, bc[2], bc[1], bc[0]); + bc[3] = bc3; + + Two_Product(cex, dey, cexdey1, cexdey0); + Two_Product(dex, cey, dexcey1, dexcey0); + Two_Two_Diff(cexdey1, cexdey0, dexcey1, dexcey0, cd3, cd[2], cd[1], cd[0]); + cd[3] = cd3; + + Two_Product(dex, aey, dexaey1, dexaey0); + Two_Product(aex, dey, aexdey1, aexdey0); + Two_Two_Diff(dexaey1, dexaey0, aexdey1, aexdey0, da3, da[2], da[1], da[0]); + da[3] = da3; + + Two_Product(aex, cey, aexcey1, aexcey0); + Two_Product(cex, aey, cexaey1, cexaey0); + Two_Two_Diff(aexcey1, aexcey0, cexaey1, cexaey0, ac3, ac[2], ac[1], ac[0]); + ac[3] = ac3; + + Two_Product(bex, dey, bexdey1, bexdey0); + Two_Product(dex, bey, dexbey1, dexbey0); + Two_Two_Diff(bexdey1, bexdey0, dexbey1, dexbey0, bd3, bd[2], bd[1], bd[0]); + bd[3] = bd3; + + temp8alen = scale_expansion_zeroelim(4, cd, bez, temp8a); + temp8blen = scale_expansion_zeroelim(4, bd, -cez, temp8b); + temp8clen = scale_expansion_zeroelim(4, bc, dez, temp8c); + temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, + temp8blen, temp8b, temp16); + temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c, + temp16len, temp16, temp24); + temp48len = scale_expansion_zeroelim(temp24len, temp24, aex, temp48); + xlen = scale_expansion_zeroelim(temp48len, temp48, -aex, xdet); + temp48len = scale_expansion_zeroelim(temp24len, temp24, aey, temp48); + ylen = scale_expansion_zeroelim(temp48len, temp48, -aey, ydet); + temp48len = scale_expansion_zeroelim(temp24len, temp24, aez, temp48); + zlen = scale_expansion_zeroelim(temp48len, temp48, -aez, zdet); + xylen = fast_expansion_sum_zeroelim(xlen, xdet, ylen, ydet, xydet); + alen = fast_expansion_sum_zeroelim(xylen, xydet, zlen, zdet, adet); + + temp8alen = scale_expansion_zeroelim(4, da, cez, temp8a); + temp8blen = scale_expansion_zeroelim(4, ac, dez, temp8b); + temp8clen = scale_expansion_zeroelim(4, cd, aez, temp8c); + temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, + temp8blen, temp8b, temp16); + temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c, + temp16len, temp16, temp24); + temp48len = scale_expansion_zeroelim(temp24len, temp24, bex, temp48); + xlen = scale_expansion_zeroelim(temp48len, temp48, bex, xdet); + temp48len = scale_expansion_zeroelim(temp24len, temp24, bey, temp48); + ylen = scale_expansion_zeroelim(temp48len, temp48, bey, ydet); + temp48len = scale_expansion_zeroelim(temp24len, temp24, bez, temp48); + zlen = scale_expansion_zeroelim(temp48len, temp48, bez, zdet); + xylen = fast_expansion_sum_zeroelim(xlen, xdet, ylen, ydet, xydet); + blen = fast_expansion_sum_zeroelim(xylen, xydet, zlen, zdet, bdet); + + temp8alen = scale_expansion_zeroelim(4, ab, dez, temp8a); + temp8blen = scale_expansion_zeroelim(4, bd, aez, temp8b); + temp8clen = scale_expansion_zeroelim(4, da, bez, temp8c); + temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, + temp8blen, temp8b, temp16); + temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c, + temp16len, temp16, temp24); + temp48len = scale_expansion_zeroelim(temp24len, temp24, cex, temp48); + xlen = scale_expansion_zeroelim(temp48len, temp48, -cex, xdet); + temp48len = scale_expansion_zeroelim(temp24len, temp24, cey, temp48); + ylen = scale_expansion_zeroelim(temp48len, temp48, -cey, ydet); + temp48len = scale_expansion_zeroelim(temp24len, temp24, cez, temp48); + zlen = scale_expansion_zeroelim(temp48len, temp48, -cez, zdet); + xylen = fast_expansion_sum_zeroelim(xlen, xdet, ylen, ydet, xydet); + clen = fast_expansion_sum_zeroelim(xylen, xydet, zlen, zdet, cdet); + + temp8alen = scale_expansion_zeroelim(4, bc, aez, temp8a); + temp8blen = scale_expansion_zeroelim(4, ac, -bez, temp8b); + temp8clen = scale_expansion_zeroelim(4, ab, cez, temp8c); + temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, + temp8blen, temp8b, temp16); + temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c, + temp16len, temp16, temp24); + temp48len = scale_expansion_zeroelim(temp24len, temp24, dex, temp48); + xlen = scale_expansion_zeroelim(temp48len, temp48, dex, xdet); + temp48len = scale_expansion_zeroelim(temp24len, temp24, dey, temp48); + ylen = scale_expansion_zeroelim(temp48len, temp48, dey, ydet); + temp48len = scale_expansion_zeroelim(temp24len, temp24, dez, temp48); + zlen = scale_expansion_zeroelim(temp48len, temp48, dez, zdet); + xylen = fast_expansion_sum_zeroelim(xlen, xdet, ylen, ydet, xydet); + dlen = fast_expansion_sum_zeroelim(xylen, xydet, zlen, zdet, ddet); + + ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); + cdlen = fast_expansion_sum_zeroelim(clen, cdet, dlen, ddet, cddet); + finlength = fast_expansion_sum_zeroelim(ablen, abdet, cdlen, cddet, fin1); + + det = estimate(finlength, fin1); + errbound = isperrboundB * permanent; + if ((det >= errbound) || (-det >= errbound)) { + return det; + } + + Two_Diff_Tail(pa[0], pe[0], aex, aextail); + Two_Diff_Tail(pa[1], pe[1], aey, aeytail); + Two_Diff_Tail(pa[2], pe[2], aez, aeztail); + Two_Diff_Tail(pb[0], pe[0], bex, bextail); + Two_Diff_Tail(pb[1], pe[1], bey, beytail); + Two_Diff_Tail(pb[2], pe[2], bez, beztail); + Two_Diff_Tail(pc[0], pe[0], cex, cextail); + Two_Diff_Tail(pc[1], pe[1], cey, ceytail); + Two_Diff_Tail(pc[2], pe[2], cez, ceztail); + Two_Diff_Tail(pd[0], pe[0], dex, dextail); + Two_Diff_Tail(pd[1], pe[1], dey, deytail); + Two_Diff_Tail(pd[2], pe[2], dez, deztail); + if ((aextail == 0.0) && (aeytail == 0.0) && (aeztail == 0.0) + && (bextail == 0.0) && (beytail == 0.0) && (beztail == 0.0) + && (cextail == 0.0) && (ceytail == 0.0) && (ceztail == 0.0) + && (dextail == 0.0) && (deytail == 0.0) && (deztail == 0.0)) { + return det; + } + + errbound = isperrboundC * permanent + resulterrbound * Absolute(det); + abeps = (aex * beytail + bey * aextail) + - (aey * bextail + bex * aeytail); + bceps = (bex * ceytail + cey * bextail) + - (bey * cextail + cex * beytail); + cdeps = (cex * deytail + dey * cextail) + - (cey * dextail + dex * ceytail); + daeps = (dex * aeytail + aey * dextail) + - (dey * aextail + aex * deytail); + aceps = (aex * ceytail + cey * aextail) + - (aey * cextail + cex * aeytail); + bdeps = (bex * deytail + dey * bextail) + - (bey * dextail + dex * beytail); + det += (((bex * bex + bey * bey + bez * bez) + * ((cez * daeps + dez * aceps + aez * cdeps) + + (ceztail * da3 + deztail * ac3 + aeztail * cd3)) + + (dex * dex + dey * dey + dez * dez) + * ((aez * bceps - bez * aceps + cez * abeps) + + (aeztail * bc3 - beztail * ac3 + ceztail * ab3))) + - ((aex * aex + aey * aey + aez * aez) + * ((bez * cdeps - cez * bdeps + dez * bceps) + + (beztail * cd3 - ceztail * bd3 + deztail * bc3)) + + (cex * cex + cey * cey + cez * cez) + * ((dez * abeps + aez * bdeps + bez * daeps) + + (deztail * ab3 + aeztail * bd3 + beztail * da3)))) + + 2.0 * (((bex * bextail + bey * beytail + bez * beztail) + * (cez * da3 + dez * ac3 + aez * cd3) + + (dex * dextail + dey * deytail + dez * deztail) + * (aez * bc3 - bez * ac3 + cez * ab3)) + - ((aex * aextail + aey * aeytail + aez * aeztail) + * (bez * cd3 - cez * bd3 + dez * bc3) + + (cex * cextail + cey * ceytail + cez * ceztail) + * (dez * ab3 + aez * bd3 + bez * da3))); + if ((det >= errbound) || (-det >= errbound)) { + return det; + } + + return insphereexact(pa, pb, pc, pd, pe); +} + +REAL insphere ( + __const_ptr(REAL) pa, + __const_ptr(REAL) pb, + __const_ptr(REAL) pc, + __const_ptr(REAL) pd, + __const_ptr(REAL) pe) +{ + REAL aex, bex, cex, dex; + REAL aey, bey, cey, dey; + REAL aez, bez, cez, dez; + REAL aexbey, bexaey, bexcey, cexbey, cexdey, dexcey, dexaey, aexdey; + REAL aexcey, cexaey, bexdey, dexbey; + REAL alift, blift, clift, dlift; + REAL ab, bc, cd, da, ac, bd; + REAL abc, bcd, cda, dab; + REAL aezplus, bezplus, cezplus, dezplus; + REAL aexbeyplus, bexaeyplus, bexceyplus, cexbeyplus; + REAL cexdeyplus, dexceyplus, dexaeyplus, aexdeyplus; + REAL aexceyplus, cexaeyplus, bexdeyplus, dexbeyplus; + REAL det; + REAL permanent, errbound; + + aex = pa[0] - pe[0]; + bex = pb[0] - pe[0]; + cex = pc[0] - pe[0]; + dex = pd[0] - pe[0]; + aey = pa[1] - pe[1]; + bey = pb[1] - pe[1]; + cey = pc[1] - pe[1]; + dey = pd[1] - pe[1]; + aez = pa[2] - pe[2]; + bez = pb[2] - pe[2]; + cez = pc[2] - pe[2]; + dez = pd[2] - pe[2]; + + aexbey = aex * bey; + bexaey = bex * aey; + ab = aexbey - bexaey; + bexcey = bex * cey; + cexbey = cex * bey; + bc = bexcey - cexbey; + cexdey = cex * dey; + dexcey = dex * cey; + cd = cexdey - dexcey; + dexaey = dex * aey; + aexdey = aex * dey; + da = dexaey - aexdey; + + aexcey = aex * cey; + cexaey = cex * aey; + ac = aexcey - cexaey; + bexdey = bex * dey; + dexbey = dex * bey; + bd = bexdey - dexbey; + + abc = aez * bc - bez * ac + cez * ab; + bcd = bez * cd - cez * bd + dez * bc; + cda = cez * da + dez * ac + aez * cd; + dab = dez * ab + aez * bd + bez * da; + + alift = aex * aex + aey * aey + aez * aez; + blift = bex * bex + bey * bey + bez * bez; + clift = cex * cex + cey * cey + cez * cez; + dlift = dex * dex + dey * dey + dez * dez; + + det = (dlift * abc - clift * dab) + (blift * cda - alift * bcd); + + aezplus = Absolute(aez); + bezplus = Absolute(bez); + cezplus = Absolute(cez); + dezplus = Absolute(dez); + aexbeyplus = Absolute(aexbey); + bexaeyplus = Absolute(bexaey); + bexceyplus = Absolute(bexcey); + cexbeyplus = Absolute(cexbey); + cexdeyplus = Absolute(cexdey); + dexceyplus = Absolute(dexcey); + dexaeyplus = Absolute(dexaey); + aexdeyplus = Absolute(aexdey); + aexceyplus = Absolute(aexcey); + cexaeyplus = Absolute(cexaey); + bexdeyplus = Absolute(bexdey); + dexbeyplus = Absolute(dexbey); + permanent = ((cexdeyplus + dexceyplus) * bezplus + + (dexbeyplus + bexdeyplus) * cezplus + + (bexceyplus + cexbeyplus) * dezplus) + * alift + + ((dexaeyplus + aexdeyplus) * cezplus + + (aexceyplus + cexaeyplus) * dezplus + + (cexdeyplus + dexceyplus) * aezplus) + * blift + + ((aexbeyplus + bexaeyplus) * dezplus + + (bexdeyplus + dexbeyplus) * aezplus + + (dexaeyplus + aexdeyplus) * bezplus) + * clift + + ((bexceyplus + cexbeyplus) * aezplus + + (cexaeyplus + aexceyplus) * bezplus + + (aexbeyplus + bexaeyplus) * cezplus) + * dlift; + errbound = isperrboundA * permanent; + if ((det > errbound) || (-det > errbound)) { + return det; + } + + return insphereadapt(pa, pb, pc, pd, pe, permanent); +} + +/*****************************************************************************/ +/* */ +/* orient4d() Return a positive value if the point pe lies above the */ +/* hyperplane passing through pa, pb, pc, and pd; "above" is */ +/* defined in a manner best found by trial-and-error. Returns */ +/* a negative value if pe lies below the hyperplane. Returns */ +/* zero if the points are co-hyperplanar (not affinely */ +/* independent). The result is also a rough approximation of */ +/* 24 times the signed volume of the 4-simplex defined by the */ +/* five points. */ +/* */ +/* Uses exact arithmetic if necessary to ensure a correct answer. The */ +/* result returned is the determinant of a matrix. This determinant is */ +/* computed adaptively, in the sense that exact arithmetic is used only to */ +/* the degree it is needed to ensure that the returned value has the */ +/* correct sign. Hence, orient4d() is usually quite fast, but will run */ +/* more slowly when the input points are hyper-coplanar or nearly so. */ +/* */ +/* See my Robust Predicates paper for details. */ +/* */ +/*****************************************************************************/ + +REAL orient4dexact ( + __const_ptr(REAL) pa, + __const_ptr(REAL) pb, + __const_ptr(REAL) pc, + __const_ptr(REAL) pd, + __const_ptr(REAL) pe, + REAL aheight, + REAL bheight, + REAL cheight, + REAL dheight, + REAL eheight) +{ + REAL axby1, bxcy1, cxdy1, dxey1, exay1; + REAL bxay1, cxby1, dxcy1, exdy1, axey1; + REAL axcy1, bxdy1, cxey1, dxay1, exby1; + REAL cxay1, dxby1, excy1, axdy1, bxey1; + REAL axby0, bxcy0, cxdy0, dxey0, exay0; + REAL bxay0, cxby0, dxcy0, exdy0, axey0; + REAL axcy0, bxdy0, cxey0, dxay0, exby0; + REAL cxay0, dxby0, excy0, axdy0, bxey0; + REAL ab[4], bc[4], cd[4], de[4], ea[4]; + REAL ac[4], bd[4], ce[4], da[4], eb[4]; + REAL temp8a[8], temp8b[8], temp16[16]; + int temp8alen=0, temp8blen=0, temp16len=0; + REAL abc[24], bcd[24], cde[24], dea[24], eab[24]; + REAL abd[24], bce[24], cda[24], deb[24], eac[24]; + int abclen=0, bcdlen=0, cdelen=0, dealen=0, eablen=0; + int abdlen=0, bcelen=0, cdalen=0, deblen=0, eaclen=0; + REAL temp48a[48], temp48b[48]; + int temp48alen=0, temp48blen=0; + REAL abcd[96], bcde[96], cdea[96], deab[96], eabc[96]; + int abcdlen=0, bcdelen=0, cdealen=0, deablen=0, eabclen=0; + REAL adet[192], bdet[192], cdet[192], ddet[192], edet[192]; + int alen, blen=0, clen=0, dlen=0, elen=0; + REAL abdet[384], cddet[384], cdedet[576]; + int ablen=0, cdlen=0; + REAL deter[960]; + int deterlen=0; + int i; + + REAL bvirt, avirt, bround, around; + REAL c, abig, ahi, alo, bhi, blo; + REAL err1, err2, err3; + REAL _i, _j, _0; + + Two_Product(pa[0], pb[1], axby1, axby0); + Two_Product(pb[0], pa[1], bxay1, bxay0); + Two_Two_Diff(axby1, axby0, bxay1, bxay0, ab[3], ab[2], ab[1], ab[0]); + + Two_Product(pb[0], pc[1], bxcy1, bxcy0); + Two_Product(pc[0], pb[1], cxby1, cxby0); + Two_Two_Diff(bxcy1, bxcy0, cxby1, cxby0, bc[3], bc[2], bc[1], bc[0]); + + Two_Product(pc[0], pd[1], cxdy1, cxdy0); + Two_Product(pd[0], pc[1], dxcy1, dxcy0); + Two_Two_Diff(cxdy1, cxdy0, dxcy1, dxcy0, cd[3], cd[2], cd[1], cd[0]); + + Two_Product(pd[0], pe[1], dxey1, dxey0); + Two_Product(pe[0], pd[1], exdy1, exdy0); + Two_Two_Diff(dxey1, dxey0, exdy1, exdy0, de[3], de[2], de[1], de[0]); + + Two_Product(pe[0], pa[1], exay1, exay0); + Two_Product(pa[0], pe[1], axey1, axey0); + Two_Two_Diff(exay1, exay0, axey1, axey0, ea[3], ea[2], ea[1], ea[0]); + + Two_Product(pa[0], pc[1], axcy1, axcy0); + Two_Product(pc[0], pa[1], cxay1, cxay0); + Two_Two_Diff(axcy1, axcy0, cxay1, cxay0, ac[3], ac[2], ac[1], ac[0]); + + Two_Product(pb[0], pd[1], bxdy1, bxdy0); + Two_Product(pd[0], pb[1], dxby1, dxby0); + Two_Two_Diff(bxdy1, bxdy0, dxby1, dxby0, bd[3], bd[2], bd[1], bd[0]); + + Two_Product(pc[0], pe[1], cxey1, cxey0); + Two_Product(pe[0], pc[1], excy1, excy0); + Two_Two_Diff(cxey1, cxey0, excy1, excy0, ce[3], ce[2], ce[1], ce[0]); + + Two_Product(pd[0], pa[1], dxay1, dxay0); + Two_Product(pa[0], pd[1], axdy1, axdy0); + Two_Two_Diff(dxay1, dxay0, axdy1, axdy0, da[3], da[2], da[1], da[0]); + + Two_Product(pe[0], pb[1], exby1, exby0); + Two_Product(pb[0], pe[1], bxey1, bxey0); + Two_Two_Diff(exby1, exby0, bxey1, bxey0, eb[3], eb[2], eb[1], eb[0]); + + temp8alen = scale_expansion_zeroelim(4, bc, pa[2], temp8a); + temp8blen = scale_expansion_zeroelim(4, ac, -pb[2], temp8b); + temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, + temp16); + temp8alen = scale_expansion_zeroelim(4, ab, pc[2], temp8a); + abclen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, + abc); + + temp8alen = scale_expansion_zeroelim(4, cd, pb[2], temp8a); + temp8blen = scale_expansion_zeroelim(4, bd, -pc[2], temp8b); + temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, + temp16); + temp8alen = scale_expansion_zeroelim(4, bc, pd[2], temp8a); + bcdlen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, + bcd); + + temp8alen = scale_expansion_zeroelim(4, de, pc[2], temp8a); + temp8blen = scale_expansion_zeroelim(4, ce, -pd[2], temp8b); + temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, + temp16); + temp8alen = scale_expansion_zeroelim(4, cd, pe[2], temp8a); + cdelen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, + cde); + + temp8alen = scale_expansion_zeroelim(4, ea, pd[2], temp8a); + temp8blen = scale_expansion_zeroelim(4, da, -pe[2], temp8b); + temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, + temp16); + temp8alen = scale_expansion_zeroelim(4, de, pa[2], temp8a); + dealen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, + dea); + + temp8alen = scale_expansion_zeroelim(4, ab, pe[2], temp8a); + temp8blen = scale_expansion_zeroelim(4, eb, -pa[2], temp8b); + temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, + temp16); + temp8alen = scale_expansion_zeroelim(4, ea, pb[2], temp8a); + eablen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, + eab); + + temp8alen = scale_expansion_zeroelim(4, bd, pa[2], temp8a); + temp8blen = scale_expansion_zeroelim(4, da, pb[2], temp8b); + temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, + temp16); + temp8alen = scale_expansion_zeroelim(4, ab, pd[2], temp8a); + abdlen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, + abd); + + temp8alen = scale_expansion_zeroelim(4, ce, pb[2], temp8a); + temp8blen = scale_expansion_zeroelim(4, eb, pc[2], temp8b); + temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, + temp16); + temp8alen = scale_expansion_zeroelim(4, bc, pe[2], temp8a); + bcelen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, + bce); + + temp8alen = scale_expansion_zeroelim(4, da, pc[2], temp8a); + temp8blen = scale_expansion_zeroelim(4, ac, pd[2], temp8b); + temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, + temp16); + temp8alen = scale_expansion_zeroelim(4, cd, pa[2], temp8a); + cdalen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, + cda); + + temp8alen = scale_expansion_zeroelim(4, eb, pd[2], temp8a); + temp8blen = scale_expansion_zeroelim(4, bd, pe[2], temp8b); + temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, + temp16); + temp8alen = scale_expansion_zeroelim(4, de, pb[2], temp8a); + deblen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, + deb); + + temp8alen = scale_expansion_zeroelim(4, ac, pe[2], temp8a); + temp8blen = scale_expansion_zeroelim(4, ce, pa[2], temp8b); + temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, + temp16); + temp8alen = scale_expansion_zeroelim(4, ea, pc[2], temp8a); + eaclen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, + eac); + + temp48alen = fast_expansion_sum_zeroelim(cdelen, cde, bcelen, bce, temp48a); + temp48blen = fast_expansion_sum_zeroelim(deblen, deb, bcdlen, bcd, temp48b); + for (i = 0; i < temp48blen; i++) { + temp48b[i] = -temp48b[i]; + } + bcdelen = fast_expansion_sum_zeroelim(temp48alen, temp48a, + temp48blen, temp48b, bcde); + alen = scale_expansion_zeroelim(bcdelen, bcde, aheight, adet); + + temp48alen = fast_expansion_sum_zeroelim(dealen, dea, cdalen, cda, temp48a); + temp48blen = fast_expansion_sum_zeroelim(eaclen, eac, cdelen, cde, temp48b); + for (i = 0; i < temp48blen; i++) { + temp48b[i] = -temp48b[i]; + } + cdealen = fast_expansion_sum_zeroelim(temp48alen, temp48a, + temp48blen, temp48b, cdea); + blen = scale_expansion_zeroelim(cdealen, cdea, bheight, bdet); + + temp48alen = fast_expansion_sum_zeroelim(eablen, eab, deblen, deb, temp48a); + temp48blen = fast_expansion_sum_zeroelim(abdlen, abd, dealen, dea, temp48b); + for (i = 0; i < temp48blen; i++) { + temp48b[i] = -temp48b[i]; + } + deablen = fast_expansion_sum_zeroelim(temp48alen, temp48a, + temp48blen, temp48b, deab); + clen = scale_expansion_zeroelim(deablen, deab, cheight, cdet); + + temp48alen = fast_expansion_sum_zeroelim(abclen, abc, eaclen, eac, temp48a); + temp48blen = fast_expansion_sum_zeroelim(bcelen, bce, eablen, eab, temp48b); + for (i = 0; i < temp48blen; i++) { + temp48b[i] = -temp48b[i]; + } + eabclen = fast_expansion_sum_zeroelim(temp48alen, temp48a, + temp48blen, temp48b, eabc); + dlen = scale_expansion_zeroelim(eabclen, eabc, dheight, ddet); + + temp48alen = fast_expansion_sum_zeroelim(bcdlen, bcd, abdlen, abd, temp48a); + temp48blen = fast_expansion_sum_zeroelim(cdalen, cda, abclen, abc, temp48b); + for (i = 0; i < temp48blen; i++) { + temp48b[i] = -temp48b[i]; + } + abcdlen = fast_expansion_sum_zeroelim(temp48alen, temp48a, + temp48blen, temp48b, abcd); + elen = scale_expansion_zeroelim(abcdlen, abcd, eheight, edet); + + ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); + cdlen = fast_expansion_sum_zeroelim(clen, cdet, dlen, ddet, cddet); + cdelen = fast_expansion_sum_zeroelim(cdlen, cddet, elen, edet, cdedet); + deterlen = fast_expansion_sum_zeroelim(ablen, abdet, cdelen, cdedet, deter); + + return deter[deterlen - 1]; +} + +REAL orient4dadapt ( + __const_ptr(REAL) pa, + __const_ptr(REAL) pb, + __const_ptr(REAL) pc, + __const_ptr(REAL) pd, + __const_ptr(REAL) pe, + REAL aheight, + REAL bheight, + REAL cheight, + REAL dheight, + REAL eheight, + REAL permanent) +{ + REAL aex, bex, cex, dex, aey, bey, cey, dey, aez, bez, cez, dez; + REAL aeheight, beheight, ceheight, deheight; + REAL det, errbound; + + REAL aexbey1, bexaey1, bexcey1, cexbey1; + REAL cexdey1, dexcey1, dexaey1, aexdey1; + REAL aexcey1, cexaey1, bexdey1, dexbey1; + REAL aexbey0, bexaey0, bexcey0, cexbey0; + REAL cexdey0, dexcey0, dexaey0, aexdey0; + REAL aexcey0, cexaey0, bexdey0, dexbey0; + REAL ab[4], bc[4], cd[4], da[4], ac[4], bd[4]; + REAL ab3, bc3, cd3, da3, ac3, bd3; + REAL abeps, bceps, cdeps, daeps, aceps, bdeps; + REAL temp8a[8], temp8b[8], temp8c[8], temp16[16], temp24[24]; + int temp8alen=0, temp8blen=0, temp8clen=0; + int temp16len=0, temp24len=0; + REAL adet[48], bdet[48], cdet[48], ddet[48]; + int alen=0, blen=0, clen=0, dlen=0; + REAL abdet[96], cddet[96]; + int ablen=0, cdlen=0; + REAL fin1[192]; + int finlength=0; + + REAL aextail, bextail, cextail, dextail; + REAL aeytail, beytail, ceytail, deytail; + REAL aeztail, beztail, ceztail, deztail; + REAL aeheighttail, beheighttail, ceheighttail, deheighttail; + + REAL bvirt, avirt, bround, around; + REAL c, abig, ahi, alo, bhi, blo; + REAL err1, err2, err3; + REAL _i, _j, _0; + + aex = (REAL) (pa[0] - pe[0]); + bex = (REAL) (pb[0] - pe[0]); + cex = (REAL) (pc[0] - pe[0]); + dex = (REAL) (pd[0] - pe[0]); + aey = (REAL) (pa[1] - pe[1]); + bey = (REAL) (pb[1] - pe[1]); + cey = (REAL) (pc[1] - pe[1]); + dey = (REAL) (pd[1] - pe[1]); + aez = (REAL) (pa[2] - pe[2]); + bez = (REAL) (pb[2] - pe[2]); + cez = (REAL) (pc[2] - pe[2]); + dez = (REAL) (pd[2] - pe[2]); + aeheight = (REAL) (aheight - eheight); + beheight = (REAL) (bheight - eheight); + ceheight = (REAL) (cheight - eheight); + deheight = (REAL) (dheight - eheight); + + Two_Product(aex, bey, aexbey1, aexbey0); + Two_Product(bex, aey, bexaey1, bexaey0); + Two_Two_Diff(aexbey1, aexbey0, bexaey1, bexaey0, ab3, ab[2], ab[1], ab[0]); + ab[3] = ab3; + + Two_Product(bex, cey, bexcey1, bexcey0); + Two_Product(cex, bey, cexbey1, cexbey0); + Two_Two_Diff(bexcey1, bexcey0, cexbey1, cexbey0, bc3, bc[2], bc[1], bc[0]); + bc[3] = bc3; + + Two_Product(cex, dey, cexdey1, cexdey0); + Two_Product(dex, cey, dexcey1, dexcey0); + Two_Two_Diff(cexdey1, cexdey0, dexcey1, dexcey0, cd3, cd[2], cd[1], cd[0]); + cd[3] = cd3; + + Two_Product(dex, aey, dexaey1, dexaey0); + Two_Product(aex, dey, aexdey1, aexdey0); + Two_Two_Diff(dexaey1, dexaey0, aexdey1, aexdey0, da3, da[2], da[1], da[0]); + da[3] = da3; + + Two_Product(aex, cey, aexcey1, aexcey0); + Two_Product(cex, aey, cexaey1, cexaey0); + Two_Two_Diff(aexcey1, aexcey0, cexaey1, cexaey0, ac3, ac[2], ac[1], ac[0]); + ac[3] = ac3; + + Two_Product(bex, dey, bexdey1, bexdey0); + Two_Product(dex, bey, dexbey1, dexbey0); + Two_Two_Diff(bexdey1, bexdey0, dexbey1, dexbey0, bd3, bd[2], bd[1], bd[0]); + bd[3] = bd3; + + temp8alen = scale_expansion_zeroelim(4, cd, bez, temp8a); + temp8blen = scale_expansion_zeroelim(4, bd, -cez, temp8b); + temp8clen = scale_expansion_zeroelim(4, bc, dez, temp8c); + temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, + temp8blen, temp8b, temp16); + temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c, + temp16len, temp16, temp24); + alen = scale_expansion_zeroelim(temp24len, temp24, -aeheight, adet); + + temp8alen = scale_expansion_zeroelim(4, da, cez, temp8a); + temp8blen = scale_expansion_zeroelim(4, ac, dez, temp8b); + temp8clen = scale_expansion_zeroelim(4, cd, aez, temp8c); + temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, + temp8blen, temp8b, temp16); + temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c, + temp16len, temp16, temp24); + blen = scale_expansion_zeroelim(temp24len, temp24, beheight, bdet); + + temp8alen = scale_expansion_zeroelim(4, ab, dez, temp8a); + temp8blen = scale_expansion_zeroelim(4, bd, aez, temp8b); + temp8clen = scale_expansion_zeroelim(4, da, bez, temp8c); + temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, + temp8blen, temp8b, temp16); + temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c, + temp16len, temp16, temp24); + clen = scale_expansion_zeroelim(temp24len, temp24, -ceheight, cdet); + + temp8alen = scale_expansion_zeroelim(4, bc, aez, temp8a); + temp8blen = scale_expansion_zeroelim(4, ac, -bez, temp8b); + temp8clen = scale_expansion_zeroelim(4, ab, cez, temp8c); + temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, + temp8blen, temp8b, temp16); + temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c, + temp16len, temp16, temp24); + dlen = scale_expansion_zeroelim(temp24len, temp24, deheight, ddet); + + ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); + cdlen = fast_expansion_sum_zeroelim(clen, cdet, dlen, ddet, cddet); + finlength = fast_expansion_sum_zeroelim(ablen, abdet, cdlen, cddet, fin1); + + det = estimate(finlength, fin1); + errbound = isperrboundB * permanent; + if ((det >= errbound) || (-det >= errbound)) { + return det; + } + + Two_Diff_Tail(pa[0], pe[0], aex, aextail); + Two_Diff_Tail(pa[1], pe[1], aey, aeytail); + Two_Diff_Tail(pa[2], pe[2], aez, aeztail); + Two_Diff_Tail(aheight, eheight, aeheight, aeheighttail); + Two_Diff_Tail(pb[0], pe[0], bex, bextail); + Two_Diff_Tail(pb[1], pe[1], bey, beytail); + Two_Diff_Tail(pb[2], pe[2], bez, beztail); + Two_Diff_Tail(bheight, eheight, beheight, beheighttail); + Two_Diff_Tail(pc[0], pe[0], cex, cextail); + Two_Diff_Tail(pc[1], pe[1], cey, ceytail); + Two_Diff_Tail(pc[2], pe[2], cez, ceztail); + Two_Diff_Tail(cheight, eheight, ceheight, ceheighttail); + Two_Diff_Tail(pd[0], pe[0], dex, dextail); + Two_Diff_Tail(pd[1], pe[1], dey, deytail); + Two_Diff_Tail(pd[2], pe[2], dez, deztail); + Two_Diff_Tail(dheight, eheight, deheight, deheighttail); + if ((aextail == 0.0) && (aeytail == 0.0) && (aeztail == 0.0) + && (bextail == 0.0) && (beytail == 0.0) && (beztail == 0.0) + && (cextail == 0.0) && (ceytail == 0.0) && (ceztail == 0.0) + && (dextail == 0.0) && (deytail == 0.0) && (deztail == 0.0) + && (aeheighttail == 0.0) && (beheighttail == 0.0) + && (ceheighttail == 0.0) && (deheighttail == 0.0)) { + return det; + } + + errbound = isperrboundC * permanent + resulterrbound * Absolute(det); + abeps = (aex * beytail + bey * aextail) + - (aey * bextail + bex * aeytail); + bceps = (bex * ceytail + cey * bextail) + - (bey * cextail + cex * beytail); + cdeps = (cex * deytail + dey * cextail) + - (cey * dextail + dex * ceytail); + daeps = (dex * aeytail + aey * dextail) + - (dey * aextail + aex * deytail); + aceps = (aex * ceytail + cey * aextail) + - (aey * cextail + cex * aeytail); + bdeps = (bex * deytail + dey * bextail) + - (bey * dextail + dex * beytail); + det += ((beheight + * ((cez * daeps + dez * aceps + aez * cdeps) + + (ceztail * da3 + deztail * ac3 + aeztail * cd3)) + + deheight + * ((aez * bceps - bez * aceps + cez * abeps) + + (aeztail * bc3 - beztail * ac3 + ceztail * ab3))) + - (aeheight + * ((bez * cdeps - cez * bdeps + dez * bceps) + + (beztail * cd3 - ceztail * bd3 + deztail * bc3)) + + ceheight + * ((dez * abeps + aez * bdeps + bez * daeps) + + (deztail * ab3 + aeztail * bd3 + beztail * da3)))) + + ((beheighttail * (cez * da3 + dez * ac3 + aez * cd3) + + deheighttail * (aez * bc3 - bez * ac3 + cez * ab3)) + - (aeheighttail * (bez * cd3 - cez * bd3 + dez * bc3) + + ceheighttail * (dez * ab3 + aez * bd3 + bez * da3))); + if ((det >= errbound) || (-det >= errbound)) { + return det; + } + + return orient4dexact(pa, pb, pc, pd, pe, + aheight, bheight, cheight, dheight, eheight); +} + +REAL orient4d ( + __const_ptr(REAL) pa, + __const_ptr(REAL) pb, + __const_ptr(REAL) pc, + __const_ptr(REAL) pd, + __const_ptr(REAL) pe ) +{ + REAL aheight, bheight, cheight, dheight, eheight; + REAL aex, bex, cex, dex; + REAL aey, bey, cey, dey; + REAL aez, bez, cez, dez; + REAL aexbey, bexaey, bexcey, cexbey, cexdey, dexcey, dexaey, aexdey; + REAL aexcey, cexaey, bexdey, dexbey; + REAL aeheight, beheight, ceheight, deheight; + REAL ab, bc, cd, da, ac, bd; + REAL abc, bcd, cda, dab; + REAL aezplus, bezplus, cezplus, dezplus; + REAL aexbeyplus, bexaeyplus, bexceyplus, cexbeyplus; + REAL cexdeyplus, dexceyplus, dexaeyplus, aexdeyplus; + REAL aexceyplus, cexaeyplus, bexdeyplus, dexbeyplus; + REAL det; + REAL permanent, errbound; + + aheight = pa[3]; + bheight = pb[3]; + cheight = pc[3]; + dheight = pd[3]; + eheight = pe[3]; + + aex = pa[0] - pe[0]; + bex = pb[0] - pe[0]; + cex = pc[0] - pe[0]; + dex = pd[0] - pe[0]; + aey = pa[1] - pe[1]; + bey = pb[1] - pe[1]; + cey = pc[1] - pe[1]; + dey = pd[1] - pe[1]; + aez = pa[2] - pe[2]; + bez = pb[2] - pe[2]; + cez = pc[2] - pe[2]; + dez = pd[2] - pe[2]; + aeheight = aheight - eheight; + beheight = bheight - eheight; + ceheight = cheight - eheight; + deheight = dheight - eheight; + + aexbey = aex * bey; + bexaey = bex * aey; + ab = aexbey - bexaey; + bexcey = bex * cey; + cexbey = cex * bey; + bc = bexcey - cexbey; + cexdey = cex * dey; + dexcey = dex * cey; + cd = cexdey - dexcey; + dexaey = dex * aey; + aexdey = aex * dey; + da = dexaey - aexdey; + + aexcey = aex * cey; + cexaey = cex * aey; + ac = aexcey - cexaey; + bexdey = bex * dey; + dexbey = dex * bey; + bd = bexdey - dexbey; + + abc = aez * bc - bez * ac + cez * ab; + bcd = bez * cd - cez * bd + dez * bc; + cda = cez * da + dez * ac + aez * cd; + dab = dez * ab + aez * bd + bez * da; + + det = (deheight * abc - ceheight * dab) + (beheight * cda - aeheight * bcd); + + aezplus = Absolute(aez); + bezplus = Absolute(bez); + cezplus = Absolute(cez); + dezplus = Absolute(dez); + aexbeyplus = Absolute(aexbey); + bexaeyplus = Absolute(bexaey); + bexceyplus = Absolute(bexcey); + cexbeyplus = Absolute(cexbey); + cexdeyplus = Absolute(cexdey); + dexceyplus = Absolute(dexcey); + dexaeyplus = Absolute(dexaey); + aexdeyplus = Absolute(aexdey); + aexceyplus = Absolute(aexcey); + cexaeyplus = Absolute(cexaey); + bexdeyplus = Absolute(bexdey); + dexbeyplus = Absolute(dexbey); + permanent = ((cexdeyplus + dexceyplus) * bezplus + + (dexbeyplus + bexdeyplus) * cezplus + + (bexceyplus + cexbeyplus) * dezplus) + * aeheight + + ((dexaeyplus + aexdeyplus) * cezplus + + (aexceyplus + cexaeyplus) * dezplus + + (cexdeyplus + dexceyplus) * aezplus) + * beheight + + ((aexbeyplus + bexaeyplus) * dezplus + + (bexdeyplus + dexbeyplus) * aezplus + + (dexaeyplus + aexdeyplus) * bezplus) + * ceheight + + ((bexceyplus + cexbeyplus) * aezplus + + (cexaeyplus + aexceyplus) * bezplus + + (aexbeyplus + bexaeyplus) * cezplus) + * deheight; + errbound = isperrboundA * permanent; + if ((det > errbound) || (-det > errbound)) { + return det; + } + + return orient4dadapt(pa, pb, pc, pd, pe, + aheight, bheight, cheight, dheight, eheight, permanent); +} + +/*****************************************************************************/ +/* */ +/* regular_k() Return a positive value if the point pe is incompatible */ +/* with the sphere or hyperplane passing through pa, pb, pc, */ +/* and pd (meaning that pe is inside the sphere or below the */ +/* hyperplane); a negative value if it is compatible; and */ +/* zero if the five points are cospherical/cohyperplanar. */ +/* The points pa, pb, pc, and pd must be ordered so that */ +/* they have a positive orientation (as defined by */ +/* orient3d()), or the sign of the result will be reversed. */ +/* */ +/* Uses exact arithmetic if necessary to ensure a correct answer. The */ +/* result returned is the determinant of a matrix. This determinant is */ +/* computed adaptively, in the sense that exact arithmetic is used only to */ +/* the degree it is needed to ensure that the returned value has the */ +/* correct sign. Hence, orient4d() is usually quite fast, but will run */ +/* more slowly when the input points are hyper-coplanar or nearly so. */ +/* */ +/* See my Robust Predicates paper for details. */ +/* */ +/*****************************************************************************/ + +REAL regular2 ( + __const_ptr(REAL) pa, + __const_ptr(REAL) pb, + __const_ptr(REAL) pc, + __const_ptr(REAL) pd ) +{ + REAL PA[3], PB[3], PC[3], PD[3] ; + + PA[0] = pa[0] ; PA[1] = pa[1] ; + PB[0] = pb[0] ; PB[1] = pb[1] ; + PC[0] = pc[0] ; PC[1] = pc[1] ; + PD[0] = pd[0] ; PD[1] = pd[1] ; + + PA[2] = pa[0] * pa[0] + + pa[1] * pa[1] - pa[2] ; + PB[2] = pb[0] * pb[0] + + pb[1] * pb[1] - pb[2] ; + PC[2] = pc[0] * pc[0] + + pc[1] * pc[1] - pc[2] ; + PD[2] = pd[0] * pd[0] + + pd[1] * pd[1] - pd[2] ; + + return orient3d(PA, PB, PC, PD) ; +} + +REAL regular3 ( + __const_ptr(REAL) pa, + __const_ptr(REAL) pb, + __const_ptr(REAL) pc, + __const_ptr(REAL) pd, + __const_ptr(REAL) pe ) +{ + REAL PA[4], PB[4], PC[4], PD[4], PE[4] ; + + PA[0] = pa[0] ; PA[1] = pa[1] ; PA[2] = pa[2] ; + PB[0] = pb[0] ; PB[1] = pb[1] ; PB[2] = pb[2] ; + PC[0] = pc[0] ; PC[1] = pc[1] ; PC[2] = pc[2] ; + PD[0] = pd[0] ; PD[1] = pd[1] ; PD[2] = pd[2] ; + PE[0] = pe[0] ; PE[1] = pe[1] ; PE[2] = pe[2] ; + + PA[3] = pa[0] * pa[0] + + pa[1] * pa[1] + + pa[2] * pa[2] - pa[3] ; + PB[3] = pb[0] * pb[0] + + pb[1] * pb[1] + + pb[2] * pb[2] - pb[3] ; + PC[3] = pc[0] * pc[0] + + pc[1] * pc[1] + + pc[2] * pc[2] - pc[3] ; + PD[3] = pd[0] * pd[0] + + pd[1] * pd[1] + + pd[2] * pd[2] - pd[3] ; + PE[3] = pe[0] * pe[0] + + pe[1] * pe[1] + + pe[2] * pe[2] - pe[3] ; + + return orient4d(PA, PB, PC, PD, PE) ; +} + +} + +#endif // __GEOMPRED__ + + + diff --git a/src/libcpp/geom_base/tria_ball_k.hpp b/src/libcpp/geom_base/tria_ball_k.hpp index e93b4e9..3ba816b 100644 --- a/src/libcpp/geom_base/tria_ball_k.hpp +++ b/src/libcpp/geom_base/tria_ball_k.hpp @@ -1,56 +1,56 @@ /* -------------------------------------------------------- - * TRIA-BALL-K: various circumscribing ball calc.'s. + * TRIA-BALL-K: various circumscribing ball calc.'s. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 12 December, 2017 + * Last updated: 10 July, 2019 * - * Copyright 2013-2017 + * Copyright 2013-2019 * Darren Engwirda * de2363@columbia.edu * https://github.com/dengwirda/ * -------------------------------------------------------- */ - + # pragma once # ifndef __TRIA_BALL_K__ # define __TRIA_BALL_K__ namespace geometry { - + /* -------------------------------------------------------- - * MINI-BALL: min. enclosing balls. + * MINI-BALL: min. enclosing balls. -------------------------------------------------------- */ @@ -63,7 +63,7 @@ __const_ptr (real_type) _p2 , bool_type _in = false ) ; - + template < typename real_type > @@ -73,7 +73,7 @@ __const_ptr (real_type) _p2 , bool_type _in = false ) ; - + template < typename real_type > @@ -84,7 +84,7 @@ __const_ptr (real_type) _p3 , bool_type _in = false ) ; - + template < typename real_type > @@ -157,13 +157,13 @@ } \ } \ } while (false) ; - + /* -------------------------------------------------------- - * CIRC-BALL: circumscribing balls. + * CIRC-BALL: circumscribing balls. -------------------------------------------------------- */ - + template < typename data_type > @@ -173,7 +173,7 @@ __const_ptr (data_type) _p3, __write_ptr (data_type) _nv ) ; - + template < typename real_type > @@ -184,9 +184,9 @@ bool_type _in ) { - _cc[0] = + _cc[0] = (real_type).5*(_p1[0]+_p2[0]); - _cc[1] = + _cc[1] = (real_type).5*(_p1[1]+_p2[1]); __unreferenced(_in); @@ -208,11 +208,11 @@ bool_type _in ) { - _cc[0] = + _cc[0] = (real_type).5*(_p1[0]+_p2[0]); - _cc[1] = + _cc[1] = (real_type).5*(_p1[1]+_p2[1]); - _cc[2] = + _cc[2] = (real_type).5*(_p1[2]+_p2[2]); __unreferenced(_in); @@ -223,7 +223,7 @@ _cc[3] = std::max ( _cc[3] , lensqr_3d(_cc, _p2)); } - + template < typename real_type > @@ -245,19 +245,20 @@ real_type _xr[2*1] ; _xr[0] = (real_type)+.5 * ( - _xm[__ij(0,0,2)] * + _xm[__ij(0,0,2)] * _xm[__ij(0,0,2)] + _xm[__ij(0,1,2)] * _xm[__ij(0,1,2)] ) ; - + _xr[1] = (real_type)+.5 * ( - _xm[__ij(1,0,2)] * + _xm[__ij(1,0,2)] * _xm[__ij(1,0,2)] + _xm[__ij(1,1,2)] * _xm[__ij(1,1,2)] ) ; - real_type _dd; - inv_2x2(2, _xm, 2, _xi, _dd) ; + real_type _dd ; + math::inv_2x2 ( + +2, _xm, +2, _xi, _dd ) ; _bb[0] = ( _xi[__ij(0,0,2)] * _xr[0] + _xi[__ij(0,1,2)] * _xr[1] ) ; @@ -266,9 +267,21 @@ _xi[__ij(1,0,2)] * _xr[0] + _xi[__ij(1,1,2)] * _xr[1] ) ; + double _P1[2]; + copy_node_2d (_P1, _p1) ; + + double _P2[2]; + copy_node_2d (_P2, _p2) ; + + double _P3[2]; + copy_node_2d (_P3, _p3) ; + + _dd = +geompred::orient2d ( + _P1, _P2, _P3) ; + _bb[0] /= _dd ; _bb[1] /= _dd ; - + real_type _ee[2*1]; real_type _db[2*1]; for(int _ii = +1; _ii-- != +0; ) @@ -276,15 +289,15 @@ _ee[0] = _xr[0] - ( _xm[__ij(0,0,2)] * _bb[0] + _xm[__ij(0,1,2)] * _bb[1] ) ; - + _ee[1] = _xr[1] - ( _xm[__ij(1,0,2)] * _bb[0] + _xm[__ij(1,1,2)] * _bb[1] ) ; - + _db[0] = ( _xi[__ij(0,0,2)] * _ee[0] + _xi[__ij(0,1,2)] * _ee[1] ) ; - + _db[1] = ( _xi[__ij(1,0,2)] * _ee[0] + _xi[__ij(1,1,2)] * _ee[1] ) ; @@ -297,9 +310,9 @@ _bb[ 0] += _p1[0] ; _bb[ 1] += _p1[1] ; - + if (!_in) return ; - + real_type __bf[3] ; __circface12( _bb, _p1, _p2, _p3); __circface12( _bb, _p2, _p3, _p1); @@ -325,18 +338,18 @@ _xm[__ij(0,0,3)] = _p2[0]-_p1[0] ; _xm[__ij(0,1,3)] = _p2[1]-_p1[1] ; _xm[__ij(0,2,3)] = _p2[2]-_p1[2] ; - + _xm[__ij(1,0,3)] = _p3[0]-_p1[0] ; _xm[__ij(1,1,3)] = _p3[1]-_p1[1] ; _xm[__ij(1,2,3)] = _p3[2]-_p1[2] ; - + _xm[__ij(2,0,3)] = _nv[0] ; _xm[__ij(2,1,3)] = _nv[1] ; _xm[__ij(2,2,3)] = _nv[2] ; real_type _xr[3*1] ; _xr[0] = (real_type)+.5 * ( - _xm[__ij(0,0,3)] * + _xm[__ij(0,0,3)] * _xm[__ij(0,0,3)] + _xm[__ij(0,1,3)] * _xm[__ij(0,1,3)] + @@ -344,22 +357,23 @@ _xm[__ij(0,2,3)] ) ; _xr[1] = (real_type)+.5 * ( - _xm[__ij(1,0,3)] * + _xm[__ij(1,0,3)] * _xm[__ij(1,0,3)] + _xm[__ij(1,1,3)] * _xm[__ij(1,1,3)] + _xm[__ij(1,2,3)] * _xm[__ij(1,2,3)] ) ; - + _xr[2] = (real_type)+.0 ; - real_type _dd; - inv_3x3(3, _xm, 3, _xi, _dd) ; + real_type _dd ; + math::inv_3x3 ( + +3, _xm, +3, _xi, _dd ) ; _bb[0] = ( _xi[__ij(0,0,3)] * _xr[0] + _xi[__ij(0,1,3)] * _xr[1] + _xi[__ij(0,2,3)] * _xr[2] ) ; - + _bb[1] = ( _xi[__ij(1,0,3)] * _xr[0] + _xi[__ij(1,1,3)] * _xr[1] + @@ -382,22 +396,22 @@ _xm[__ij(0,0,3)] * _bb[0] + _xm[__ij(0,1,3)] * _bb[1] + _xm[__ij(0,2,3)] * _bb[2] ) ; - + _ee[1] = _xr[1] - ( _xm[__ij(1,0,3)] * _bb[0] + _xm[__ij(1,1,3)] * _bb[1] + _xm[__ij(1,2,3)] * _bb[2] ) ; - + _ee[2] = _xr[2] - ( _xm[__ij(2,0,3)] * _bb[0] + _xm[__ij(2,1,3)] * _bb[1] + _xm[__ij(2,2,3)] * _bb[2] ) ; - + _db[0] = ( _xi[__ij(0,0,3)] * _ee[0] + _xi[__ij(0,1,3)] * _ee[1] + _xi[__ij(0,2,3)] * _ee[2] ) ; - + _db[1] = ( _xi[__ij(1,0,3)] * _ee[0] + _xi[__ij(1,1,3)] * _ee[1] + @@ -407,10 +421,10 @@ _xi[__ij(2,0,3)] * _ee[0] + _xi[__ij(2,1,3)] * _ee[1] + _xi[__ij(2,2,3)] * _ee[2] ) ; - + _bb[0]+= _db[0] / _dd ; _bb[1]+= _db[1] / _dd ; - _bb[2]+= _db[2] / _dd ; + _bb[2]+= _db[2] / _dd ; } _bb[ 3] = lensqr_3d(_bb) ; @@ -418,9 +432,9 @@ _bb[ 0] += _p1[0] ; _bb[ 1] += _p1[1] ; _bb[ 2] += _p1[2] ; - + if (!_in) return ; - + real_type __bf[4] ; __circface13( _bb, _p1, _p2, _p3); __circface13( _bb, _p2, _p3, _p1); @@ -444,18 +458,18 @@ _xm[__ij(0,0,3)] = _p2[0]-_p1[0] ; _xm[__ij(0,1,3)] = _p2[1]-_p1[1] ; _xm[__ij(0,2,3)] = _p2[2]-_p1[2] ; - + _xm[__ij(1,0,3)] = _p3[0]-_p1[0] ; _xm[__ij(1,1,3)] = _p3[1]-_p1[1] ; _xm[__ij(1,2,3)] = _p3[2]-_p1[2] ; - + _xm[__ij(2,0,3)] = _p4[0]-_p1[0] ; _xm[__ij(2,1,3)] = _p4[1]-_p1[1] ; _xm[__ij(2,2,3)] = _p4[2]-_p1[2] ; real_type _xr[3*1] ; _xr[0] = (real_type)+.5 * ( - _xm[__ij(0,0,3)] * + _xm[__ij(0,0,3)] * _xm[__ij(0,0,3)] + _xm[__ij(0,1,3)] * _xm[__ij(0,1,3)] + @@ -463,7 +477,7 @@ _xm[__ij(0,2,3)] ) ; _xr[1] = (real_type)+.5 * ( - _xm[__ij(1,0,3)] * + _xm[__ij(1,0,3)] * _xm[__ij(1,0,3)] + _xm[__ij(1,1,3)] * _xm[__ij(1,1,3)] + @@ -471,20 +485,21 @@ _xm[__ij(1,2,3)] ) ; _xr[2] = (real_type)+.5 * ( - _xm[__ij(2,0,3)] * + _xm[__ij(2,0,3)] * _xm[__ij(2,0,3)] + _xm[__ij(2,1,3)] * _xm[__ij(2,1,3)] + _xm[__ij(2,2,3)] * _xm[__ij(2,2,3)] ) ; - real_type _dd; - inv_3x3(3, _xm, 3, _xi, _dd) ; + real_type _dd ; + math::inv_3x3 ( + +3, _xm, +3, _xi, _dd ) ; _bb[0] = ( _xi[__ij(0,0,3)] * _xr[0] + _xi[__ij(0,1,3)] * _xr[1] + _xi[__ij(0,2,3)] * _xr[2] ) ; - + _bb[1] = ( _xi[__ij(1,0,3)] * _xr[0] + _xi[__ij(1,1,3)] * _xr[1] + @@ -495,6 +510,21 @@ _xi[__ij(2,1,3)] * _xr[1] + _xi[__ij(2,2,3)] * _xr[2] ) ; + double _P1[3]; + copy_node_3d (_P1, _p1) ; + + double _P2[3]; + copy_node_3d (_P2, _p2) ; + + double _P3[3]; + copy_node_3d (_P3, _p3) ; + + double _P4[3]; + copy_node_3d (_P4, _p4) ; + + _dd = -geompred::orient3d ( + _P1, _P2, _P3, _P4) ; + _bb[0] /= _dd ; _bb[1] /= _dd ; _bb[2] /= _dd ; @@ -507,22 +537,22 @@ _xm[__ij(0,0,3)] * _bb[0] + _xm[__ij(0,1,3)] * _bb[1] + _xm[__ij(0,2,3)] * _bb[2] ) ; - + _ee[1] = _xr[1] - ( _xm[__ij(1,0,3)] * _bb[0] + _xm[__ij(1,1,3)] * _bb[1] + _xm[__ij(1,2,3)] * _bb[2] ) ; - + _ee[2] = _xr[2] - ( _xm[__ij(2,0,3)] * _bb[0] + _xm[__ij(2,1,3)] * _bb[1] + _xm[__ij(2,2,3)] * _bb[2] ) ; - + _db[0] = ( _xi[__ij(0,0,3)] * _ee[0] + _xi[__ij(0,1,3)] * _ee[1] + _xi[__ij(0,2,3)] * _ee[2] ) ; - + _db[1] = ( _xi[__ij(1,0,3)] * _ee[0] + _xi[__ij(1,1,3)] * _ee[1] + @@ -535,7 +565,7 @@ _bb[0]+= _db[0] / _dd ; _bb[1]+= _db[1] / _dd ; - _bb[2]+= _db[2] / _dd ; + _bb[2]+= _db[2] / _dd ; } _bb[ 3] = lensqr_3d(_bb) ; @@ -543,27 +573,27 @@ _bb[ 0] += _p1[0] ; _bb[ 1] += _p1[1] ; _bb[ 2] += _p1[2] ; - + if (!_in) return ; - + real_type __bf[4] ; - __circface23( + __circface23( _bb, _p1, _p2, _p3, _p4) ; - __circface23( + __circface23( _bb, _p1, _p2, _p4, _p3) ; - __circface23( + __circface23( _bb, _p2, _p3, _p4, _p1) ; - __circface23( + __circface23( _bb, _p3, _p1, _p4, _p2) ; } - + #undef __circface12 #undef __circface13 #undef __circface23 - + /* -------------------------------------------------------- - * MINI-BALL: min. enclosing balls. + * MINI-BALL: min. enclosing balls. -------------------------------------------------------- */ @@ -576,7 +606,7 @@ __const_ptr (real_type) _p2 , bool_type _in = false ) ; - + template < typename real_type > @@ -586,7 +616,7 @@ __const_ptr (real_type) _p2 , bool_type _in = false ) ; - + template < typename real_type > @@ -597,7 +627,7 @@ __const_ptr (real_type) _p3 , bool_type _in = false ) ; - + template < typename real_type > @@ -673,13 +703,13 @@ } \ } \ } while (false) ; - + /* -------------------------------------------------------- - * PERP-BALL: perpendicular (orthogonal) balls. + * PERP-BALL: perpendicular (orthogonal) balls. -------------------------------------------------------- */ - + template < typename real_type > @@ -694,38 +724,38 @@ _dd[0] = _p1[0] - _p2[0] ; _dd[1] = _p1[1] - _p2[1] ; _dd[2] = _p1[2] - _p2[2] ; - - real_type _dp = + + real_type _dp = geometry::lensqr_2d(_dd) ; - real_type _tt = - (real_type).5 * + real_type _tt = + (real_type).5 * (_dd[2] + _dp) / _dp ; - + if (_in == true) - { - _tt = + { + _tt = std::min((real_type)1., _tt) ; - _tt = + _tt = std::max((real_type)0., _tt) ; } - - _bb[0] = + + _bb[0] = _p1[0] - _tt * _dd[0] ; - _bb[1] = + _bb[1] = _p1[1] - _tt * _dd[1] ; - - real_type _r1 = + + real_type _r1 = geometry::lensqr_2d(_p1, _bb); - real_type _r2 = + real_type _r2 = geometry::lensqr_2d(_p2, _bb); - + _r1 -= _p1[2] ; _r2 -= _p2[2] ; - + _bb[2] = std::max (_r1, _r2) ; } - + template < typename real_type > @@ -741,40 +771,40 @@ _dd[1] = _p1[1] - _p2[1] ; _dd[2] = _p1[2] - _p2[2] ; _dd[3] = _p1[3] - _p2[3] ; - - real_type _dp = + + real_type _dp = geometry::lensqr_3d(_dd) ; - real_type _tt = - (real_type).5 * + real_type _tt = + (real_type).5 * (_dd[3] + _dp) / _dp ; - + if (_in == true) - { - _tt = + { + _tt = std::min((real_type)1., _tt) ; - _tt = + _tt = std::max((real_type)0., _tt) ; } - - _bb[0] = + + _bb[0] = _p1[0] - _tt * _dd[0] ; - _bb[1] = + _bb[1] = _p1[1] - _tt * _dd[1] ; - _bb[2] = + _bb[2] = _p1[2] - _tt * _dd[2] ; - - real_type _r1 = + + real_type _r1 = geometry::lensqr_3d(_p1, _bb); - real_type _r2 = + real_type _r2 = geometry::lensqr_3d(_p2, _bb); - + _r1 -= _p1[3] ; _r2 -= _p2[3] ; - + _bb[3] = std::max (_r1, _r2) ; } - + template < typename real_type > @@ -796,25 +826,26 @@ real_type _xr[2*1] ; _xr[0] = (real_type)+.5 * ( - _xm[__ij(0,0,2)] * + _xm[__ij(0,0,2)] * _xm[__ij(0,0,2)] + _xm[__ij(0,1,2)] * _xm[__ij(0,1,2)] ) ; - + _xr[1] = (real_type)+.5 * ( - _xm[__ij(1,0,2)] * + _xm[__ij(1,0,2)] * _xm[__ij(1,0,2)] + _xm[__ij(1,1,2)] * _xm[__ij(1,1,2)] ) ; - + real_type _w21 = _p2[2]-_p1[2] ; real_type _w31 = _p3[2]-_p1[2] ; - + _xr[0]-= (real_type)+.5 * _w21 ; - _xr[1]-= (real_type)+.5 * _w31 ; - - real_type _dd; - inv_2x2(2, _xm, 2, _xi, _dd) ; + _xr[1]-= (real_type)+.5 * _w31 ; + + real_type _dd ; + math::inv_2x2 ( + +2, _xm, +2, _xi, _dd ) ; _bb[0] = ( _xi[__ij(0,0,2)] * _xr[0] + _xi[__ij(0,1,2)] * _xr[1] ) ; @@ -823,9 +854,21 @@ _xi[__ij(1,0,2)] * _xr[0] + _xi[__ij(1,1,2)] * _xr[1] ) ; + double _P1[2]; + copy_node_2d (_P1, _p1) ; + + double _P2[2]; + copy_node_2d (_P2, _p2) ; + + double _P3[2]; + copy_node_2d (_P3, _p3) ; + + _dd = +geompred::orient2d ( + _P1, _P2, _P3) ; + _bb[0] /= _dd ; _bb[1] /= _dd ; - + real_type _ee[2*1]; real_type _db[2*1]; for(int _ii = +1; _ii-- != +0; ) @@ -833,15 +876,15 @@ _ee[0] = _xr[0] - ( _xm[__ij(0,0,2)] * _bb[0] + _xm[__ij(0,1,2)] * _bb[1] ) ; - + _ee[1] = _xr[1] - ( _xm[__ij(1,0,2)] * _bb[0] + _xm[__ij(1,1,2)] * _bb[1] ) ; - + _db[0] = ( _xi[__ij(0,0,2)] * _ee[0] + _xi[__ij(0,1,2)] * _ee[1] ) ; - + _db[1] = ( _xi[__ij(1,0,2)] * _ee[0] + _xi[__ij(1,1,2)] * _ee[1] ) ; @@ -852,22 +895,23 @@ _bb[ 0] += _p1[0] ; _bb[ 1] += _p1[1] ; - - real_type _r1 = + + real_type _r1 = geometry::lensqr_2d(_p1, _bb) ; - real_type _r2 = + real_type _r2 = geometry::lensqr_2d(_p2, _bb) ; - real_type _r3 = + real_type _r3 = geometry::lensqr_2d(_p3, _bb) ; - + _r1 -= _p1[2] ; _r2 -= _p2[2] ; _r3 -= _p3[2] ; - - _bb[2] = (_r1+_r2+_r3) / (real_type)3. ; - + + _bb[2] = + (_r1+_r2+_r3) / (real_type)3. ; + if (!_in) return ; - + real_type __bf[3] ; __perpface12(_bb, _p1, _p2, _p3) ; __perpface12(_bb, _p2, _p3, _p1) ; @@ -893,18 +937,18 @@ _xm[__ij(0,0,3)] = _p2[0]-_p1[0] ; _xm[__ij(0,1,3)] = _p2[1]-_p1[1] ; _xm[__ij(0,2,3)] = _p2[2]-_p1[2] ; - + _xm[__ij(1,0,3)] = _p3[0]-_p1[0] ; _xm[__ij(1,1,3)] = _p3[1]-_p1[1] ; _xm[__ij(1,2,3)] = _p3[2]-_p1[2] ; - + _xm[__ij(2,0,3)] = _nv[0] ; _xm[__ij(2,1,3)] = _nv[1] ; _xm[__ij(2,2,3)] = _nv[2] ; real_type _xr[3*1] ; _xr[0] = (real_type)+.5 * ( - _xm[__ij(0,0,3)] * + _xm[__ij(0,0,3)] * _xm[__ij(0,0,3)] + _xm[__ij(0,1,3)] * _xm[__ij(0,1,3)] + @@ -912,28 +956,29 @@ _xm[__ij(0,2,3)] ) ; _xr[1] = (real_type)+.5 * ( - _xm[__ij(1,0,3)] * + _xm[__ij(1,0,3)] * _xm[__ij(1,0,3)] + _xm[__ij(1,1,3)] * _xm[__ij(1,1,3)] + _xm[__ij(1,2,3)] * _xm[__ij(1,2,3)] ) ; - + real_type _w21 = _p2[3]-_p1[3] ; real_type _w31 = _p3[3]-_p1[3] ; - + _xr[0]-= (real_type)+.5 * _w21 ; _xr[1]-= (real_type)+.5 * _w31 ; _xr[2] = (real_type)+.0 ; - real_type _dd; - inv_3x3(3, _xm, 3, _xi, _dd) ; + real_type _dd ; + math::inv_3x3 ( + +3, _xm, +3, _xi, _dd ) ; _bb[0] = ( _xi[__ij(0,0,3)] * _xr[0] + _xi[__ij(0,1,3)] * _xr[1] + _xi[__ij(0,2,3)] * _xr[2] ) ; - + _bb[1] = ( _xi[__ij(1,0,3)] * _xr[0] + _xi[__ij(1,1,3)] * _xr[1] + @@ -956,22 +1001,22 @@ _xm[__ij(0,0,3)] * _bb[0] + _xm[__ij(0,1,3)] * _bb[1] + _xm[__ij(0,2,3)] * _bb[2] ) ; - + _ee[1] = _xr[1] - ( _xm[__ij(1,0,3)] * _bb[0] + _xm[__ij(1,1,3)] * _bb[1] + _xm[__ij(1,2,3)] * _bb[2] ) ; - + _ee[2] = _xr[2] - ( _xm[__ij(2,0,3)] * _bb[0] + _xm[__ij(2,1,3)] * _bb[1] + _xm[__ij(2,2,3)] * _bb[2] ) ; - + _db[0] = ( _xi[__ij(0,0,3)] * _ee[0] + _xi[__ij(0,1,3)] * _ee[1] + _xi[__ij(0,2,3)] * _ee[2] ) ; - + _db[1] = ( _xi[__ij(1,0,3)] * _ee[0] + _xi[__ij(1,1,3)] * _ee[1] + @@ -981,7 +1026,7 @@ _xi[__ij(2,0,3)] * _ee[0] + _xi[__ij(2,1,3)] * _ee[1] + _xi[__ij(2,2,3)] * _ee[2] ) ; - + _bb[0]+= _db[0] / _dd ; _bb[1]+= _db[1] / _dd ; _bb[2]+= _db[2] / _dd ; @@ -990,22 +1035,23 @@ _bb[ 0] += _p1[0] ; _bb[ 1] += _p1[1] ; _bb[ 2] += _p1[2] ; - - real_type _r1 = + + real_type _r1 = geometry::lensqr_3d(_p1, _bb) ; - real_type _r2 = + real_type _r2 = geometry::lensqr_3d(_p2, _bb) ; - real_type _r3 = + real_type _r3 = geometry::lensqr_3d(_p3, _bb) ; - + _r1 -= _p1[3] ; _r2 -= _p2[3] ; _r3 -= _p3[3] ; - - _bb[3] = (_r1+_r2+_r3) / (real_type)3. ; - + + _bb[3] = + (_r1+_r2+_r3) / (real_type)3. ; + if (!_in) return ; - + real_type __bf[4] ; __perpface13(_bb, _p1, _p2, _p3) ; __perpface13(_bb, _p2, _p3, _p1) ; @@ -1029,18 +1075,18 @@ _xm[__ij(0,0,3)] = _p2[0]-_p1[0] ; _xm[__ij(0,1,3)] = _p2[1]-_p1[1] ; _xm[__ij(0,2,3)] = _p2[2]-_p1[2] ; - + _xm[__ij(1,0,3)] = _p3[0]-_p1[0] ; _xm[__ij(1,1,3)] = _p3[1]-_p1[1] ; _xm[__ij(1,2,3)] = _p3[2]-_p1[2] ; - + _xm[__ij(2,0,3)] = _p4[0]-_p1[0] ; _xm[__ij(2,1,3)] = _p4[1]-_p1[1] ; _xm[__ij(2,2,3)] = _p4[2]-_p1[2] ; real_type _xr[3*1] ; _xr[0] = (real_type)+.5 * ( - _xm[__ij(0,0,3)] * + _xm[__ij(0,0,3)] * _xm[__ij(0,0,3)] + _xm[__ij(0,1,3)] * _xm[__ij(0,1,3)] + @@ -1048,7 +1094,7 @@ _xm[__ij(0,2,3)] ) ; _xr[1] = (real_type)+.5 * ( - _xm[__ij(1,0,3)] * + _xm[__ij(1,0,3)] * _xm[__ij(1,0,3)] + _xm[__ij(1,1,3)] * _xm[__ij(1,1,3)] + @@ -1056,20 +1102,21 @@ _xm[__ij(1,2,3)] ) ; _xr[2] = (real_type)+.5 * ( - _xm[__ij(2,0,3)] * + _xm[__ij(2,0,3)] * _xm[__ij(2,0,3)] + _xm[__ij(2,1,3)] * _xm[__ij(2,1,3)] + _xm[__ij(2,2,3)] * _xm[__ij(2,2,3)] ) ; - real_type _dd; - inv_3x3(3, _xm, 3, _xi, _dd) ; + real_type _dd ; + math::inv_3x3 ( + +3, _xm, +3, _xi, _dd ) ; _bb[0] = ( _xi[__ij(0,0,3)] * _xr[0] + _xi[__ij(0,1,3)] * _xr[1] + _xi[__ij(0,2,3)] * _xr[2] ) ; - + _bb[1] = ( _xi[__ij(1,0,3)] * _xr[0] + _xi[__ij(1,1,3)] * _xr[1] + @@ -1080,11 +1127,25 @@ _xi[__ij(2,1,3)] * _xr[1] + _xi[__ij(2,2,3)] * _xr[2] ) ; + double _P1[3]; + copy_node_3d (_P1, _p1) ; + + double _P2[3]; + copy_node_3d (_P2, _p2) ; + + double _P3[3]; + copy_node_3d (_P3, _p3) ; + + double _P4[3]; + copy_node_3d (_P4, _p4) ; + + _dd = -geompred::orient3d ( + _P1, _P2, _P3, _P4) ; + _bb[0] /= _dd ; _bb[1] /= _dd ; _bb[2] /= _dd ; - real_type _ee[3*1]; real_type _db[3*1]; for(int _ii = +1; _ii-- != +0; ) @@ -1093,22 +1154,22 @@ _xm[__ij(0,0,3)] * _bb[0] + _xm[__ij(0,1,3)] * _bb[1] + _xm[__ij(0,2,3)] * _bb[2] ) ; - + _ee[1] = _xr[1] - ( _xm[__ij(1,0,3)] * _bb[0] + _xm[__ij(1,1,3)] * _bb[1] + _xm[__ij(1,2,3)] * _bb[2] ) ; - + _ee[2] = _xr[2] - ( _xm[__ij(2,0,3)] * _bb[0] + _xm[__ij(2,1,3)] * _bb[1] + _xm[__ij(2,2,3)] * _bb[2] ) ; - + _db[0] = ( _xi[__ij(0,0,3)] * _ee[0] + _xi[__ij(0,1,3)] * _ee[1] + _xi[__ij(0,2,3)] * _ee[2] ) ; - + _db[1] = ( _xi[__ij(1,0,3)] * _ee[0] + _xi[__ij(1,1,3)] * _ee[1] + @@ -1121,52 +1182,53 @@ _bb[0]+= _db[0] / _dd ; _bb[1]+= _db[1] / _dd ; - _bb[2]+= _db[2] / _dd ; + _bb[2]+= _db[2] / _dd ; } _bb[ 0] += _p1[0] ; _bb[ 1] += _p1[1] ; _bb[ 2] += _p1[2] ; - - real_type _r1 = + + real_type _r1 = geometry::lensqr_3d(_p1, _bb) ; - real_type _r2 = + real_type _r2 = geometry::lensqr_3d(_p2, _bb) ; - real_type _r3 = + real_type _r3 = geometry::lensqr_3d(_p3, _bb) ; - real_type _r4 = + real_type _r4 = geometry::lensqr_3d(_p4, _bb) ; - + _r1 -= _p1[3] ; _r2 -= _p2[3] ; _r3 -= _p3[3] ; _r4 -= _p4[3] ; - - _bb[3] = (_r1+_r2+_r3+_r4)/(real_type)4. ; - + + _bb[3] = + (_r1+_r2+_r3+_r4)/(real_type)4. ; + if (!_in) return ; - + real_type __bf[4] ; - __perpface23 ( + __perpface23 ( _bb, _p1 , _p2, _p3, _p4) ; - __perpface23 ( + __perpface23 ( _bb, _p1 , _p2, _p4, _p3) ; - __perpface23 ( + __perpface23 ( _bb, _p2 , _p3, _p4, _p1) ; - __perpface23 ( + __perpface23 ( _bb, _p3 , _p1, _p4, _p2) ; } #undef __perpface12 #undef __perpface13 #undef __perpface23 - + /* -------------------------------------------------------- - * MASS-BALL: centre-of-mass balls. + * MASS-BALL: centre-of-mass balls. -------------------------------------------------------- */ - + template < typename data_type > @@ -1179,20 +1241,20 @@ _bb[0] = _p1[0] ; _bb[0]+= _p2[0] ; _bb[0]/= (data_type) +2. ; - + _bb[1] = _p1[1] ; _bb[1]+= _p2[1] ; _bb[1]/= (data_type) +2. ; - - data_type _r1 = + + data_type _r1 = geometry::lensqr_2d(_bb, _p1); - data_type _r2 = + data_type _r2 = geometry::lensqr_2d(_bb, _p2); - _bb[2] = + _bb[2] = (_r1+_r2)/(data_type)+2. ; } - + template < typename data_type > @@ -1205,24 +1267,24 @@ _bb[0] = _p1[0] ; _bb[0]+= _p2[0] ; _bb[0]/= (data_type) +2. ; - + _bb[1] = _p1[1] ; _bb[1]+= _p2[1] ; _bb[1]/= (data_type) +2. ; - + _bb[2] = _p1[2] ; _bb[2]+= _p2[2] ; _bb[2]/= (data_type) +2. ; - data_type _r1 = + data_type _r1 = geometry::lensqr_3d(_bb, _p1); - data_type _r2 = + data_type _r2 = geometry::lensqr_3d(_bb, _p2); - _bb[3] = + _bb[3] = (_r1+_r2)/(data_type)+2. ; } - + template < typename data_type > @@ -1237,24 +1299,24 @@ _bb[0]+= _p2[0] ; _bb[0]+= _p3[0] ; _bb[0]/= (data_type) +3. ; - + _bb[1] = _p1[1] ; _bb[1]+= _p2[1] ; _bb[1]+= _p3[1] ; _bb[1]/= (data_type) +3. ; - - data_type _r1 = + + data_type _r1 = geometry::lensqr_2d(_bb, _p1); - data_type _r2 = + data_type _r2 = geometry::lensqr_2d(_bb, _p2); - data_type _r3 = + data_type _r3 = geometry::lensqr_2d(_bb, _p3); - _bb[2] = std::max ( _r3, + _bb[2] = std::max ( _r3, std::max ( _r1, _r2) ) ; } - + template < typename data_type > @@ -1269,29 +1331,29 @@ _bb[0]+= _p2[0] ; _bb[0]+= _p3[0] ; _bb[0]/= (data_type) +3. ; - + _bb[1] = _p1[1] ; _bb[1]+= _p2[1] ; _bb[1]+= _p3[1] ; _bb[1]/= (data_type) +3. ; - + _bb[2] = _p1[2] ; _bb[2]+= _p2[2] ; _bb[2]+= _p3[2] ; _bb[2]/= (data_type) +3. ; - data_type _r1 = + data_type _r1 = geometry::lensqr_3d(_bb, _p1); - data_type _r2 = + data_type _r2 = geometry::lensqr_3d(_bb, _p2); - data_type _r3 = + data_type _r3 = geometry::lensqr_3d(_bb, _p3); - _bb[3] = std::max ( _r3, + _bb[3] = std::max ( _r3, std::max ( _r1, _r2) ) ; } - + template < typename data_type > @@ -1308,26 +1370,26 @@ _bb[0]+= _p3[0] ; _bb[0]+= _p4[0] ; _bb[0]/= (data_type) +4. ; - + _bb[1] = _p1[1] ; _bb[1]+= _p2[1] ; _bb[1]+= _p3[1] ; _bb[1]+= _p4[1] ; _bb[1]/= (data_type) +4. ; - + _bb[2] = _p1[2] ; _bb[2]+= _p2[2] ; _bb[2]+= _p3[2] ; _bb[2]+= _p4[2] ; _bb[2]/= (data_type) +4. ; - - data_type _r1 = + + data_type _r1 = geometry::lensqr_3d(_bb, _p1); - data_type _r2 = + data_type _r2 = geometry::lensqr_3d(_bb, _p2); - data_type _r3 = + data_type _r3 = geometry::lensqr_3d(_bb, _p3); - data_type _r4 = + data_type _r4 = geometry::lensqr_3d(_bb, _p4); _bb[3] = std::max ( _r4, @@ -1335,9 +1397,9 @@ std::max ( _r1, _r2) ) ) ; } - + } - + # endif //__TRIA_BALL_K__ diff --git a/src/libcpp/geom_base/tria_elem_k.hpp b/src/libcpp/geom_base/tria_elem_k.hpp index d07210d..9f02dce 100644 --- a/src/libcpp/geom_base/tria_elem_k.hpp +++ b/src/libcpp/geom_base/tria_elem_k.hpp @@ -1,560 +1,492 @@ - - /* - -------------------------------------------------------- - * TRIA-ELEM-K: operations on simplexes in R^k. - -------------------------------------------------------- - * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) - * - * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The - * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be - * used at your own risk. - * - -------------------------------------------------------- - * - * Last updated: 29 January, 2019 - * - * Copyright 2013-2019 - * Darren Engwirda - * de2363@columbia.edu - * https://github.com/dengwirda/ - * - -------------------------------------------------------- - */ - -# pragma once - -# ifndef __TRIA_ELEM_K__ -# define __TRIA_ELEM_K__ - - namespace geometry { - - /* - -------------------------------------------------------- - * tria. area/volume/normals/etc. - -------------------------------------------------------- - */ - - template < - typename data_type - > - __normal_call data_type tria_area_2d ( - __const_ptr (data_type) _p1, - __const_ptr (data_type) _p2, - __const_ptr (data_type) _p3 - ) - { - data_type _ev12[2]; - vector_2d(_p1, _p2, _ev12); - - data_type _ev13[2]; - vector_2d(_p1, _p3, _ev13); - - data_type _aval = - _ev12[0] * _ev13[1] - - _ev12[1] * _ev13[0] ; - - _aval *= (data_type)+.5 ; - - return ( _aval ) ; - } - - template < - typename data_type - > - __normal_call data_type tria_area_3d ( - __const_ptr (data_type) _p1, - __const_ptr (data_type) _p2, - __const_ptr (data_type) _p3 - ) - { - data_type _ev12[3], _ev13[3] ; - vector_3d(_p1, _p2, _ev12); - vector_3d(_p1, _p3, _ev13); - - data_type _avec[3] = { - _ev12[1] * _ev13[2] - - _ev12[2] * _ev13[1] , - _ev12[2] * _ev13[0] - - _ev12[0] * _ev13[2] , - _ev12[0] * _ev13[1] - - _ev12[1] * _ev13[0] } ; - - data_type _aval = - geometry::length_3d(_avec) ; - - return (data_type)+.5 * _aval ; - } - - template < - typename data_type - > - __inline_call void_type line_norm_2d ( - __const_ptr (data_type) _p1, - __const_ptr (data_type) _p2, - __write_ptr (data_type) _nv - ) - { - _nv[0] = _p1[1] - _p2[1]; - _nv[1] = _p2[0] - _p1[0]; - } - - template < - typename data_type - > - __inline_call void_type tria_norm_3d ( - __const_ptr (data_type) _p1, - __const_ptr (data_type) _p2, - __const_ptr (data_type) _p3, - __write_ptr (data_type) _nv - ) - { - data_type _ev12[3], _ev13[3] ; - vector_3d(_p1, _p2, _ev12); - vector_3d(_p1, _p3, _ev13); - - _nv[0] = _ev12[1] * _ev13[2] - - _ev12[2] * _ev13[1] ; - _nv[1] = _ev12[2] * _ev13[0] - - _ev12[0] * _ev13[2] ; - _nv[2] = _ev12[0] * _ev13[1] - - _ev12[1] * _ev13[0] ; - } - - template < - typename data_type - > - __inline_call data_type tetra_vol_3d ( - __const_ptr (data_type) _p1, - __const_ptr (data_type) _p2, - __const_ptr (data_type) _p3, - __const_ptr (data_type) _p4 // +ve if CCW from _p4 - ) - { - data_type _v14[3], _v24[3], - _v34[3]; - vector_3d(_p1, _p4, _v14); - vector_3d(_p2, _p4, _v24); - vector_3d(_p3, _p4, _v34); - - data_type _vdet = - + _v14[0] * (_v24[1] * _v34[2] - - _v24[2] * _v34[1] ) - - _v14[1] * (_v24[0] * _v34[2] - - _v24[2] * _v34[0] ) - + _v14[2] * (_v24[0] * _v34[1] - - _v24[1] * _v34[0]); - - return _vdet / (data_type)6. ; - } - - /* - -------------------------------------------------------- - * tria. "quality" scores. - -------------------------------------------------------- - */ - - template < - typename data_type - > - __normal_call - data_type tria_quality_2d ( - __const_ptr (data_type) _p1, - __const_ptr (data_type) _p2, - __const_ptr (data_type) _p3 - ) - { - // mean of condition no. + gradient-error metrics - // see Shewchuk - - // 4. * std::sqrt(3.) - data_type static - constexpr _mulA = - (data_type)+6.928203230275509 ; - - // 4. / std::sqrt(3.) - data_type static - constexpr _mulB = - (data_type)+2.309401076758503 ; - - data_type _len1 = - lensqr_2d(_p1, _p2) ; - data_type _len2 = - lensqr_2d(_p2, _p3) ; - data_type _len3 = - lensqr_2d(_p3, _p1) ; - - data_type _barA = - _len1+_len2+_len3 ; - - data_type _barB = - _len1*_len2*_len3 ; - - _barB = std::pow( - _barB, (data_type)+1./3.); - - data_type _area = - tria_area_2d(_p1, _p2, _p3); - - data_type _scrA ; - if (_barA > (data_type)+0. ) - _scrA = - _mulA * _area / _barA ; - else - _scrA = (data_type)+0. ; - - data_type _scrB ; - if (_barB > (data_type)+0. ) - _scrB = - _mulB * _area / _barB ; - else - _scrB = (data_type)+0. ; - - return - ((data_type)+1.0-.33)*_scrA + - ((data_type)+0.0+.33)*_scrB ; - } - - template < - typename data_type - > - __normal_call - data_type tria_quality_3d ( - __const_ptr (data_type) _p1, - __const_ptr (data_type) _p2, - __const_ptr (data_type) _p3 - ) - { - // mean of condition no. + gradient-error metrics - // see Shewchuk - - // 4. * std::sqrt(3.) - data_type static - constexpr _mulA = - (data_type)+6.928203230275509 ; - - // 4. / std::sqrt(3.) - data_type static - constexpr _mulB = - (data_type)+2.309401076758503 ; - - data_type _len1 = - lensqr_3d(_p1, _p2) ; - data_type _len2 = - lensqr_3d(_p2, _p3) ; - data_type _len3 = - lensqr_3d(_p3, _p1) ; - - data_type _barA = - _len1+_len2+_len3 ; - - data_type _barB = - _len1*_len2*_len3 ; - - _barB = std::pow( - _barB, (data_type)+1./3.); - - data_type _area = - tria_area_3d(_p1, _p2, _p3); - - data_type _scrA ; - if (_barA > (data_type)+0. ) - _scrA = - _mulA * _area / _barA ; - else - _scrA = (data_type)+0. ; - - data_type _scrB ; - if (_barB > (data_type)+0. ) - _scrB = - _mulB * _area / _barB ; - else - _scrB = (data_type)+0. ; - - return - ((data_type)+1.0-.33)*_scrA + - ((data_type)+0.0+.33)*_scrB ; - } - - template < - typename data_type - > - __normal_call - data_type tria_quality_3d ( - __const_ptr (data_type) _p1, - __const_ptr (data_type) _p2, - __const_ptr (data_type) _p3, - __const_ptr (data_type) _p4 - ) - { - // 6. * std::sqrt(2.) - data_type static - constexpr _scal = - (data_type)+8.485281374238571 ; - - data_type _tvol = tetra_vol_3d ( - _p1, _p2, _p3, _p4); - - data_type _lrms = - lensqr_3d(_p1, _p2) + - lensqr_3d(_p2, _p3) + - lensqr_3d(_p3, _p1) + - lensqr_3d(_p1, _p4) + - lensqr_3d(_p2, _p4) + - lensqr_3d(_p3, _p4) ; - - _lrms = _lrms/ (data_type)6.0 ; - _lrms = - std::pow(_lrms, (data_type)1.5); - - return _scal * _tvol / _lrms ; - } - - /* - -------------------------------------------------------- - * voro. "quality" scores. - -------------------------------------------------------- - */ - - template < - typename data_type - > - __normal_call - data_type dual_quality_2d ( - __const_ptr (data_type) _p1, - __const_ptr (data_type) _p2, - __const_ptr (data_type) _p3 - ) - { - data_type _ob[ +3] ; - geometry::perp_ball_2d(_ob, - _p1 , _p2, _p3); - - data_type _o1[ +3] ; - geometry::perp_ball_2d(_o1, - _p1 , _p2) ; - data_type _o2[ +3] ; - geometry::perp_ball_2d(_o2, - _p2 , _p3) ; - data_type _o3[ +3] ; - geometry::perp_ball_2d(_o3, - _p3 , _p1) ; - - data_type _mb[ +3] ; - geometry::mass_ball_2d(_mb, - _p1 , _p2, _p3); - - data_type _m1[ +3] ; - geometry::mass_ball_2d(_m1, - _p1 , _p2) ; - data_type _m2[ +3] ; - geometry::mass_ball_2d(_m2, - _p2 , _p3) ; - data_type _m3[ +3] ; - geometry::mass_ball_2d(_m3, - _p3 , _p1) ; - - data_type _lb = - geometry::lensqr_2d(_ob, _mb) ; - - data_type _l1 = - geometry::lensqr_2d(_o1, _m1) ; - data_type _l2 = - geometry::lensqr_2d(_o2, _m2) ; - data_type _l3 = - geometry::lensqr_2d(_o3, _m3) ; - - data_type _r1 = _m1[2] ; - data_type _r2 = _m2[2] ; - data_type _r3 = _m3[2] ; - - data_type _rb = // chara.-length - (_r1+_r2+_r3) / (data_type)+3. ; - - data_type _qb ; - if (_rb > (data_type)+0. ) - _qb = (data_type)+1. - - _lb / _rb ; - else - _qb = (data_type)+0. ; - - data_type _q1 ; - if (_r1 > (data_type)+0. ) - _q1 = (data_type)+1. - - _l1 / _r1 ; - else - _q1 = (data_type)+0. ; - data_type _q2 ; - if (_r2 > (data_type)+0. ) - _q2 = (data_type)+1. - - _l2 / _r2 ; - else - _q2 = (data_type)+0. ; - data_type _q3 ; - if (_r3 > (data_type)+0. ) - _q3 = (data_type)+1. - - _l3 / _r3 ; - else - _q3 = (data_type)+0. ; - - data_type _qe = // straight mean - (_q1+_q2+_q3) / (data_type)+3. ; - - /* - data_type _qe = // harmonic mean - (data_type)+1. / _q1 + - (data_type)+1. / _q2 + - (data_type)+1. / _q3 ; - _qe = - (data_type)+3. / _qe ; - */ - - data_type _qq = - ((data_type)+1.-.33) * _qb + - ((data_type)+0.+.33) * _qe ; - - return _qq ; - } - - template < - typename data_type - > - __normal_call - data_type dual_quality_3d ( - __const_ptr (data_type) _p1, - __const_ptr (data_type) _p2, - __const_ptr (data_type) _p3 - ) - { - data_type _ob[ +4] ; - geometry::perp_ball_3d(_ob, - _p1 , _p2, _p3); - - data_type _o1[ +4] ; - geometry::perp_ball_3d(_o1, - _p1 , _p2) ; - data_type _o2[ +4] ; - geometry::perp_ball_3d(_o2, - _p2 , _p3) ; - data_type _o3[ +4] ; - geometry::perp_ball_3d(_o3, - _p3 , _p1) ; - - data_type _mb[ +4] ; - geometry::mass_ball_3d(_mb, - _p1 , _p2, _p3); - - data_type _m1[ +4] ; - geometry::mass_ball_3d(_m1, - _p1 , _p2) ; - data_type _m2[ +4] ; - geometry::mass_ball_3d(_m2, - _p2 , _p3) ; - data_type _m3[ +4] ; - geometry::mass_ball_3d(_m3, - _p3 , _p1) ; - - data_type _lb = - geometry::lensqr_3d(_ob, _mb) ; - - data_type _l1 = - geometry::lensqr_3d(_o1, _m1) ; - data_type _l2 = - geometry::lensqr_3d(_o2, _m2) ; - data_type _l3 = - geometry::lensqr_3d(_o3, _m3) ; - - data_type _r1 = _m1[3] ; - data_type _r2 = _m2[3] ; - data_type _r3 = _m3[3] ; - - data_type _rb = // chara.-length - (_r1+_r2+_r3) / (data_type)+3. ; - - data_type _qb ; - if (_rb > (data_type)+0. ) - _qb = (data_type)+1. - - _lb / _rb ; - else - _qb = (data_type)+0. ; - - data_type _q1 ; - if (_r1 > (data_type)+0. ) - _q1 = (data_type)+1. - - _l1 / _r1 ; - else - _q1 = (data_type)+0. ; - data_type _q2 ; - if (_r2 > (data_type)+0. ) - _q2 = (data_type)+1. - - _l2 / _r2 ; - else - _q2 = (data_type)+0. ; - data_type _q3 ; - if (_r3 > (data_type)+0. ) - _q3 = (data_type)+1. - - _l3 / _r3 ; - else - _q3 = (data_type)+0. ; - - data_type _qe = // straight mean - (_q1+_q2+_q3) / (data_type)+3. ; - - /* - data_type _qe = // harmonic mean - (data_type)+1. / _q1 + - (data_type)+1. / _q2 + - (data_type)+1. / _q3 ; - _qe = - (data_type)+3. / _qe ; - */ - - data_type _qq = - ((data_type)+1.-.33) * _qb + - ((data_type)+0.+.33) * _qe ; - - return _qq ; - } - - /* - template < - typename data_type - > - __normal_call - data_type dual_quality_3d ( - __const_ptr (data_type) _p1, - __const_ptr (data_type) _p2, - __const_ptr (data_type) _p3, - __const_ptr (data_type) _p4 - ) - { - //!! to-do... - - return _qq ; - } - */ - - } - -# endif//__TRIA_ELEM_K__ - - + + /* + -------------------------------------------------------- + * TRIA-ELEM-K: operations on simplexes in R^k. + -------------------------------------------------------- + * + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) + * + * Disclaimer: Neither I nor: Columbia University, The + * Massachusetts Institute of Technology, The + * University of Sydney, nor The National Aeronautics + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be + * used at your own risk. + * + -------------------------------------------------------- + * + * Last updated: 30 Aug, 2019 + * + * Copyright 2013-2019 + * Darren Engwirda + * de2363@columbia.edu + * https://github.com/dengwirda/ + * + -------------------------------------------------------- + */ + +# pragma once + +# ifndef __TRIA_ELEM_K__ +# define __TRIA_ELEM_K__ + + namespace geometry { + + /* + -------------------------------------------------------- + * tria. area/volume/normals/etc. + -------------------------------------------------------- + */ + + template < + typename data_type + > + __normal_call data_type tria_area_2d ( + __const_ptr (data_type) _p1, + __const_ptr (data_type) _p2, + __const_ptr (data_type) _p3 + ) + { + data_type _ev12[2]; + vector_2d(_p1, _p2, _ev12); + + data_type _ev13[2]; + vector_2d(_p1, _p3, _ev13); + + data_type _aval = + _ev12[0] * _ev13[1] - + _ev12[1] * _ev13[0] ; + + _aval *= (data_type)+.5 ; + + return ( _aval ) ; + } + + template < + typename data_type + > + __normal_call data_type tria_area_3d ( + __const_ptr (data_type) _p1, + __const_ptr (data_type) _p2, + __const_ptr (data_type) _p3 + ) + { + data_type _ev12[3]; + vector_3d(_p1, _p2, _ev12); + + data_type _ev13[3]; + vector_3d(_p1, _p3, _ev13); + + data_type _avec[3] = { + _ev12[1] * _ev13[2] - + _ev12[2] * _ev13[1] , + _ev12[2] * _ev13[0] - + _ev12[0] * _ev13[2] , + _ev12[0] * _ev13[1] - + _ev12[1] * _ev13[0] } ; + + data_type _aval = + geometry::length_3d(_avec) ; + + return (data_type)+.5 * _aval ; + } + + template < + typename data_type + > + __inline_call void_type line_norm_2d ( + __const_ptr (data_type) _p1, + __const_ptr (data_type) _p2, + __write_ptr (data_type) _nv + ) + { + _nv[0] = _p1[1] - _p2[1]; + _nv[1] = _p2[0] - _p1[0]; + } + + template < + typename data_type + > + __inline_call void_type tria_norm_3d ( + __const_ptr (data_type) _p1, + __const_ptr (data_type) _p2, + __const_ptr (data_type) _p3, + __write_ptr (data_type) _nv + ) + { + data_type _ev12[3], _ev13[3] ; + vector_3d(_p1, _p2, _ev12); + vector_3d(_p1, _p3, _ev13); + + _nv[0] = _ev12[1] * _ev13[2] - + _ev12[2] * _ev13[1] ; + _nv[1] = _ev12[2] * _ev13[0] - + _ev12[0] * _ev13[2] ; + _nv[2] = _ev12[0] * _ev13[1] - + _ev12[1] * _ev13[0] ; + } + + template < + typename data_type + > + __inline_call data_type tetra_vol_3d ( + __const_ptr (data_type) _p1, + __const_ptr (data_type) _p2, + __const_ptr (data_type) _p3, + __const_ptr (data_type) _p4 // +ve if CCW from _p4 + ) + { + data_type _v14[3], _v24[3], + _v34[3]; + vector_3d(_p1, _p4, _v14); + vector_3d(_p2, _p4, _v24); + vector_3d(_p3, _p4, _v34); + + data_type _vdet = + + _v14[0] * (_v24[1] * _v34[2] - + _v24[2] * _v34[1] ) + - _v14[1] * (_v24[0] * _v34[2] - + _v24[2] * _v34[0] ) + + _v14[2] * (_v24[0] * _v34[1] - + _v24[1] * _v34[0]); + + return _vdet / (data_type)6. ; + } + + /* + -------------------------------------------------------- + * tria. "quality" scores. + -------------------------------------------------------- + */ + + template < + typename data_type + > + __normal_call + data_type tria_quality_2d ( + __const_ptr (data_type) _p1, + __const_ptr (data_type) _p2, + __const_ptr (data_type) _p3 + ) + { + // mean of condition no. + gradient-error metrics + // see Shewchuk + + // 4. * std::sqrt(3.) + data_type static + constexpr _mulA = + (data_type)+6.928203230275509 ; + + // 4. / std::sqrt(3.) + data_type static + constexpr _mulB = + (data_type)+2.309401076758503 ; + + data_type _len1 = + lensqr_2d(_p1, _p2) ; + data_type _len2 = + lensqr_2d(_p2, _p3) ; + data_type _len3 = + lensqr_2d(_p3, _p1) ; + + data_type _barA = + _len1+_len2+_len3 ; + + data_type _barB = + _len1*_len2*_len3 ; + + _barB = std::pow( + _barB, (data_type)+1./3.); + + data_type _area = + tria_area_2d(_p1, _p2, _p3); + + data_type _scrA = + _mulA * _area / _barA ; + + data_type _scrB = + _mulB * _area / _barB ; + + return + ((data_type)+1.0-.33)*_scrA + + ((data_type)+0.0+.33)*_scrB ; + } + + template < + typename data_type + > + __normal_call + data_type tria_quality_3d ( + __const_ptr (data_type) _p1, + __const_ptr (data_type) _p2, + __const_ptr (data_type) _p3 + ) + { + // mean of condition no. + gradient-error metrics + // see Shewchuk + + // 4. * std::sqrt(3.) + data_type static + constexpr _mulA = + (data_type)+6.928203230275509 ; + + // 4. / std::sqrt(3.) + data_type static + constexpr _mulB = + (data_type)+2.309401076758503 ; + + data_type _len1 = + lensqr_3d(_p1, _p2) ; + data_type _len2 = + lensqr_3d(_p2, _p3) ; + data_type _len3 = + lensqr_3d(_p3, _p1) ; + + data_type _barA = + _len1+_len2+_len3 ; + + data_type _barB = + _len1*_len2*_len3 ; + + _barB = std::pow( + _barB, (data_type)+1./3.); + + data_type _area = + tria_area_3d(_p1, _p2, _p3); + + data_type _scrA = + _mulA * _area / _barA ; + + data_type _scrB = + _mulB * _area / _barB ; + + return + ((data_type)+1.0-.33)*_scrA + + ((data_type)+0.0+.33)*_scrB ; + } + + template < + typename data_type + > + __normal_call + data_type tria_quality_3d ( + __const_ptr (data_type) _p1, + __const_ptr (data_type) _p2, + __const_ptr (data_type) _p3, + __const_ptr (data_type) _p4 + ) + { + // 6. * std::sqrt(2.) + data_type static + constexpr _scal = + (data_type)+8.485281374238571 ; + + data_type _tvol = tetra_vol_3d ( + _p1, _p2, _p3, _p4); + + data_type _lrms = + lensqr_3d(_p1, _p2) + + lensqr_3d(_p2, _p3) + + lensqr_3d(_p3, _p1) + + lensqr_3d(_p1, _p4) + + lensqr_3d(_p2, _p4) + + lensqr_3d(_p3, _p4) ; + + _lrms = _lrms/ (data_type)6.0 ; + _lrms = + std::pow(_lrms, (data_type)1.5); + + return _scal * _tvol / _lrms ; + } + + /* + -------------------------------------------------------- + * voro. "quality" scores. + -------------------------------------------------------- + */ + + template < + typename data_type + > + __normal_call + data_type dual_quality_2d ( + __const_ptr (data_type) _p1, + __const_ptr (data_type) _p2, + __const_ptr (data_type) _p3 + ) + { + data_type _ob[ +3] ; + geometry::perp_ball_2d(_ob, + _p1 , _p2, _p3); + + data_type _o1[ +3] ; + geometry::perp_ball_2d(_o1, + _p1 , _p2) ; + data_type _o2[ +3] ; + geometry::perp_ball_2d(_o2, + _p2 , _p3) ; + data_type _o3[ +3] ; + geometry::perp_ball_2d(_o3, + _p3 , _p1) ; + + data_type _mb[ +3] ; + geometry::mass_ball_2d(_mb, + _p1 , _p2, _p3); + + data_type _m1[ +3] ; + geometry::mass_ball_2d(_m1, + _p1 , _p2) ; + data_type _m2[ +3] ; + geometry::mass_ball_2d(_m2, + _p2 , _p3) ; + data_type _m3[ +3] ; + geometry::mass_ball_2d(_m3, + _p3 , _p1) ; + + data_type _lb = + geometry::lensqr_2d(_ob, _mb) ; + + data_type _l1 = + geometry::lensqr_2d(_o1, _m1) ; + data_type _l2 = + geometry::lensqr_2d(_o2, _m2) ; + data_type _l3 = + geometry::lensqr_2d(_o3, _m3) ; + + data_type _r1 = _m1[2] ; + data_type _r2 = _m2[2] ; + data_type _r3 = _m3[2] ; + + data_type _rb = // chara.-length + (_r1+_r2+_r3) / (data_type)+3. ; + + data_type _qb = _lb / _rb ; + + data_type _q1 = _l1 / _r1 ; + data_type _q2 = _l2 / _r2 ; + data_type _q3 = _l3 / _r3 ; + + data_type _qe = // straight mean + (_q1+_q2+_q3) / (data_type)+3. ; + + data_type _qq = + ((data_type)+1.-.33) * _qb + + ((data_type)+0.+.33) * _qe ; + + _qq = (data_type)1.- _qq ; + + return _qq ; + } + + template < + typename data_type + > + __normal_call + data_type dual_quality_3d ( + __const_ptr (data_type) _p1, + __const_ptr (data_type) _p2, + __const_ptr (data_type) _p3 + ) + { + data_type _ob[ +4] ; + geometry::perp_ball_3d(_ob, + _p1 , _p2, _p3); + + data_type _o1[ +4] ; + geometry::perp_ball_3d(_o1, + _p1 , _p2) ; + data_type _o2[ +4] ; + geometry::perp_ball_3d(_o2, + _p2 , _p3) ; + data_type _o3[ +4] ; + geometry::perp_ball_3d(_o3, + _p3 , _p1) ; + + data_type _mb[ +4] ; + geometry::mass_ball_3d(_mb, + _p1 , _p2, _p3); + + data_type _m1[ +4] ; + geometry::mass_ball_3d(_m1, + _p1 , _p2) ; + data_type _m2[ +4] ; + geometry::mass_ball_3d(_m2, + _p2 , _p3) ; + data_type _m3[ +4] ; + geometry::mass_ball_3d(_m3, + _p3 , _p1) ; + + data_type _lb = + geometry::lensqr_3d(_ob, _mb) ; + + data_type _l1 = + geometry::lensqr_3d(_o1, _m1) ; + data_type _l2 = + geometry::lensqr_3d(_o2, _m2) ; + data_type _l3 = + geometry::lensqr_3d(_o3, _m3) ; + + data_type _r1 = _m1[3] ; + data_type _r2 = _m2[3] ; + data_type _r3 = _m3[3] ; + + data_type _rb = // chara.-length + (_r1+_r2+_r3) / (data_type)+3. ; + + data_type _qb = _lb / _rb ; + + data_type _q1 = _l1 / _r1 ; + data_type _q2 = _l2 / _r2 ; + data_type _q3 = _l3 / _r3 ; + + data_type _qe = // straight mean + (_q1+_q2+_q3) / (data_type)+3. ; + + data_type _qq = + ((data_type)+1.-.33) * _qb + + ((data_type)+0.+.33) * _qe ; + + _qq = (data_type)1.- _qq ; + + return _qq ; + } + + /* + template < + typename data_type + > + __normal_call + data_type dual_quality_3d ( + __const_ptr (data_type) _p1, + __const_ptr (data_type) _p2, + __const_ptr (data_type) _p3, + __const_ptr (data_type) _p4 + ) + { + //!! to-do... + + return _qq ; + } + */ + + } + +# endif//__TRIA_ELEM_K__ + + diff --git a/src/libcpp/geom_base/vect_base_k.hpp b/src/libcpp/geom_base/vect_base_k.hpp index 8804d2a..cf238be 100644 --- a/src/libcpp/geom_base/vect_base_k.hpp +++ b/src/libcpp/geom_base/vect_base_k.hpp @@ -1,264 +1,264 @@ - - /* - -------------------------------------------------------- - * VECT-BASE-K: basic vector operations in R^2/R^3. - -------------------------------------------------------- - * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) - * - * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The - * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be - * used at your own risk. - * - -------------------------------------------------------- - * - * Last updated: 06 June, 2016 - * - * Copyright 2013-2017 - * Darren Engwirda - * de2363@columbia.edu - * https://github.com/dengwirda/ - * - -------------------------------------------------------- - */ - -# pragma once - -# ifndef __VECT_BASE_K__ -# define __VECT_BASE_K__ - - namespace geometry { - -/*-------------------------------- form vector from coord */ - template < - typename data_type - > - __inline_call void_type vector_2d ( - __const_ptr (data_type) _p1, - __const_ptr (data_type) _p2, - __write_ptr (data_type) _vv - ) - { - _vv[0] = _p2[0] - _p1[0]; - _vv[1] = _p2[1] - _p1[1]; - } - - template < - typename data_type - > - __inline_call void_type vector_3d ( - __const_ptr (data_type) _p1, - __const_ptr (data_type) _p2, - __write_ptr (data_type) _vv - ) - { - _vv[0] = _p2[0] - _p1[0]; - _vv[1] = _p2[1] - _p1[1]; - _vv[2] = _p2[2] - _p1[2]; - } - -/*-------------------------------- calc. (squared) length */ - template < - typename data_type - > - __inline_call data_type lensqr_2d ( - __const_ptr (data_type) _vv - ) - { return _vv[0] * _vv[0] + - _vv[1] * _vv[1] ; - } - - template < - typename data_type - > - __inline_call data_type lensqr_3d ( - __const_ptr (data_type) _vv - ) - { return _vv[0] * _vv[0] + - _vv[1] * _vv[1] + - _vv[2] * _vv[2] ; - } - - template < - typename data_type - > - __inline_call data_type lensqr_2d ( - __const_ptr (data_type) _p1 , - __const_ptr (data_type) _p2 - ) - { - data_type _vv[ +2]; - vector_2d(_p1, _p2, _vv) ; - - return _vv[0] * _vv[0] + - _vv[1] * _vv[1] ; - } - - template < - typename data_type - > - __inline_call data_type lensqr_3d ( - __const_ptr (data_type) _p1 , - __const_ptr (data_type) _p2 - ) - { - data_type _vv[ +3]; - vector_3d(_p1, _p2, _vv) ; - - return _vv[0] * _vv[0] + - _vv[1] * _vv[1] + - _vv[2] * _vv[2] ; - } - -/*-------------------------------- calc. euclidean length */ - template < - typename data_type - > - __inline_call data_type length_2d ( - __const_ptr (data_type) _vv - ) - { return std::sqrt(lensqr_2d(_vv)) ; - } - - template < - typename data_type - > - __inline_call data_type length_2d ( - __const_ptr (data_type) _p1 , - __const_ptr (data_type) _p2 - ) - { return - std::sqrt(lensqr_2d(_p1, _p2)) ; - } - - template < - typename data_type - > - __inline_call data_type length_3d ( - __const_ptr (data_type) _vv - ) - { return std::sqrt(lensqr_3d(_vv)) ; - } - - template < - typename data_type - > - __inline_call data_type length_3d ( - __const_ptr (data_type) _p1 , - __const_ptr (data_type) _p2 - ) - { return - std::sqrt(lensqr_3d(_p1, _p2)) ; - } - -/*-------------------------------- vector "cross" product */ - template < - typename data_type - > - __inline_call void_type cross_2d ( - __const_ptr (data_type) _v1 , - __const_ptr (data_type) _v2 , - data_type &_cp - ) - { _cp = _v1[0] * _v2[1] - - _v1[1] * _v2[0] ; - } - - template < - typename data_type - > - __inline_call void_type cross_3d ( - __const_ptr (data_type) _v1 , - __const_ptr (data_type) _v2 , - __write_ptr (data_type) _cp - ) - { - _cp[0] = _v1[1] * _v2[2] - - _v1[2] * _v2[1] ; - - _cp[1] = _v1[2] * _v2[0] - - _v1[0] * _v2[2] ; - - _cp[2] = _v1[0] * _v2[1] - - _v1[1] * _v2[0] ; - } - -/*-------------------------------- vector "inner" product */ - template < - typename data_type - > - __inline_call data_type dot_2d ( - __const_ptr (data_type) _v1 , - __const_ptr (data_type) _v2 - ) - { return _v1[0] * _v2[0] + - _v1[1] * _v2[1] ; - } - - template < - typename data_type - > - __inline_call data_type dot_3d ( - __const_ptr (data_type) _v1 , - __const_ptr (data_type) _v2 - ) - { return _v1[0] * _v2[0] + - _v1[1] * _v2[1] + - _v1[2] * _v2[2] ; - } - -/*-------------------------------- cosine between vectors */ - template < - typename data_type - > - __inline_call data_type cosine_2d ( - __const_ptr (data_type) _v1, - __const_ptr (data_type) _v2 - ) - { - data_type _ll = length_2d(_v1) * - length_2d(_v2) ; - - return dot_2d(_v1, _v2) / _ll; - } - - template < - typename data_type - > - __inline_call data_type cosine_3d ( - __const_ptr (data_type) _v1, - __const_ptr (data_type) _v2 - ) - { - data_type _ll = length_3d(_v1) * - length_3d(_v2) ; - - return dot_3d(_v1, _v2) / _ll; - } - - - } - -# endif //__VECT_BASE_K__ - - - + + /* + -------------------------------------------------------- + * VECT-BASE-K: basic vector operations in R^2/R^3. + -------------------------------------------------------- + * + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) + * + * Disclaimer: Neither I nor: Columbia University, The + * Massachusetts Institute of Technology, The + * University of Sydney, nor The National Aeronautics + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be + * used at your own risk. + * + -------------------------------------------------------- + * + * Last updated: 06 June, 2016 + * + * Copyright 2013-2017 + * Darren Engwirda + * de2363@columbia.edu + * https://github.com/dengwirda/ + * + -------------------------------------------------------- + */ + +# pragma once + +# ifndef __VECT_BASE_K__ +# define __VECT_BASE_K__ + + namespace geometry { + +/*-------------------------------- form vector from coord */ + template < + typename data_type + > + __inline_call void_type vector_2d ( + __const_ptr (data_type) _p1, + __const_ptr (data_type) _p2, + __write_ptr (data_type) _vv + ) + { + _vv[0] = _p2[0] - _p1[0]; + _vv[1] = _p2[1] - _p1[1]; + } + + template < + typename data_type + > + __inline_call void_type vector_3d ( + __const_ptr (data_type) _p1, + __const_ptr (data_type) _p2, + __write_ptr (data_type) _vv + ) + { + _vv[0] = _p2[0] - _p1[0]; + _vv[1] = _p2[1] - _p1[1]; + _vv[2] = _p2[2] - _p1[2]; + } + +/*-------------------------------- calc. (squared) length */ + template < + typename data_type + > + __inline_call data_type lensqr_2d ( + __const_ptr (data_type) _vv + ) + { return _vv[0] * _vv[0] + + _vv[1] * _vv[1] ; + } + + template < + typename data_type + > + __inline_call data_type lensqr_3d ( + __const_ptr (data_type) _vv + ) + { return _vv[0] * _vv[0] + + _vv[1] * _vv[1] + + _vv[2] * _vv[2] ; + } + + template < + typename data_type + > + __inline_call data_type lensqr_2d ( + __const_ptr (data_type) _p1 , + __const_ptr (data_type) _p2 + ) + { + data_type _vv[ +2]; + vector_2d(_p1, _p2, _vv) ; + + return _vv[0] * _vv[0] + + _vv[1] * _vv[1] ; + } + + template < + typename data_type + > + __inline_call data_type lensqr_3d ( + __const_ptr (data_type) _p1 , + __const_ptr (data_type) _p2 + ) + { + data_type _vv[ +3]; + vector_3d(_p1, _p2, _vv) ; + + return _vv[0] * _vv[0] + + _vv[1] * _vv[1] + + _vv[2] * _vv[2] ; + } + +/*-------------------------------- calc. euclidean length */ + template < + typename data_type + > + __inline_call data_type length_2d ( + __const_ptr (data_type) _vv + ) + { return std::sqrt(lensqr_2d(_vv)) ; + } + + template < + typename data_type + > + __inline_call data_type length_2d ( + __const_ptr (data_type) _p1 , + __const_ptr (data_type) _p2 + ) + { return + std::sqrt(lensqr_2d(_p1, _p2)) ; + } + + template < + typename data_type + > + __inline_call data_type length_3d ( + __const_ptr (data_type) _vv + ) + { return std::sqrt(lensqr_3d(_vv)) ; + } + + template < + typename data_type + > + __inline_call data_type length_3d ( + __const_ptr (data_type) _p1 , + __const_ptr (data_type) _p2 + ) + { return + std::sqrt(lensqr_3d(_p1, _p2)) ; + } + +/*-------------------------------- vector "cross" product */ + template < + typename data_type + > + __inline_call void_type cross_2d ( + __const_ptr (data_type) _v1 , + __const_ptr (data_type) _v2 , + data_type &_cp + ) + { _cp = _v1[0] * _v2[1] - + _v1[1] * _v2[0] ; + } + + template < + typename data_type + > + __inline_call void_type cross_3d ( + __const_ptr (data_type) _v1 , + __const_ptr (data_type) _v2 , + __write_ptr (data_type) _cp + ) + { + _cp[0] = _v1[1] * _v2[2] - + _v1[2] * _v2[1] ; + + _cp[1] = _v1[2] * _v2[0] - + _v1[0] * _v2[2] ; + + _cp[2] = _v1[0] * _v2[1] - + _v1[1] * _v2[0] ; + } + +/*-------------------------------- vector "inner" product */ + template < + typename data_type + > + __inline_call data_type dot_2d ( + __const_ptr (data_type) _v1 , + __const_ptr (data_type) _v2 + ) + { return _v1[0] * _v2[0] + + _v1[1] * _v2[1] ; + } + + template < + typename data_type + > + __inline_call data_type dot_3d ( + __const_ptr (data_type) _v1 , + __const_ptr (data_type) _v2 + ) + { return _v1[0] * _v2[0] + + _v1[1] * _v2[1] + + _v1[2] * _v2[2] ; + } + +/*-------------------------------- cosine between vectors */ + template < + typename data_type + > + __inline_call data_type cosine_2d ( + __const_ptr (data_type) _v1, + __const_ptr (data_type) _v2 + ) + { + data_type _ll = length_2d(_v1) * + length_2d(_v2) ; + + return dot_2d(_v1, _v2) / _ll; + } + + template < + typename data_type + > + __inline_call data_type cosine_3d ( + __const_ptr (data_type) _v1, + __const_ptr (data_type) _v2 + ) + { + data_type _ll = length_3d(_v1) * + length_3d(_v2) ; + + return dot_3d(_v1, _v2) / _ll; + } + + + } + +# endif //__VECT_BASE_K__ + + + diff --git a/src/libcpp/geom_type/geom_base_2.hpp b/src/libcpp/geom_type/geom_base_2.hpp index 3ab57fd..31cbf64 100644 --- a/src/libcpp/geom_type/geom_base_2.hpp +++ b/src/libcpp/geom_type/geom_base_2.hpp @@ -4,34 +4,34 @@ * GEOM-BASE-2: base class for geom. in R^2. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 16 January, 2019 + * Last updated: 09 August, 2019 * * Copyright 2013-2019 * Darren Engwirda @@ -50,14 +50,14 @@ template < typename R , - typename I + typename I > class geom_base_2d { public : - + /*------------------------- base geometry type in R^2 */ - + typedef R real_type ; typedef I iptr_type ; @@ -90,7 +90,7 @@ { __unreferenced(_opts) ; } - + /* -------------------------------------------------------- * HAVE-FEAT: TRUE if has k-dim. FEAT. @@ -101,6 +101,8 @@ iptr_type _fdim ) { + __unreferenced(_fdim) ; + return ( false ) ; } @@ -155,7 +157,7 @@ line_type &_line , hits_func &_hfun ) - { + { __unreferenced(_line) ; __unreferenced(_hfun) ; @@ -175,7 +177,7 @@ ball_type &_ball , hits_func &_hfun ) - { + { __unreferenced(_ball) ; __unreferenced(_hfun) ; @@ -197,6 +199,22 @@ return (iptr_type) -1 ; } + /* + -------------------------------------------------------- + * PROJECTOR: project a point to the geometry. + -------------------------------------------------------- + */ + + __normal_call void_type projector ( + real_type *_ppos, + iptr_type _idim, + real_type *_proj + ) + { + __unreferenced(_ppos) ; + __unreferenced(_idim) ; + __unreferenced(_proj) ; + } } ; diff --git a/src/libcpp/geom_type/geom_base_3.hpp b/src/libcpp/geom_type/geom_base_3.hpp index 317c329..cce2882 100644 --- a/src/libcpp/geom_type/geom_base_3.hpp +++ b/src/libcpp/geom_type/geom_base_3.hpp @@ -4,34 +4,34 @@ * GEOM-BASE-3: base class for geom. in R^3. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 16 January, 2019 + * Last updated: 09 August, 2019 * * Copyright 2013-2019 * Darren Engwirda @@ -50,14 +50,14 @@ template < typename R , - typename I + typename I > class geom_base_3d { public : - + /*------------------------- base geometry type in R^3 */ - + typedef R real_type ; typedef I iptr_type ; @@ -116,6 +116,8 @@ iptr_type _fdim ) { + __unreferenced(_fdim) ; + return ( false ) ; } @@ -170,7 +172,7 @@ line_type &_line , hits_func &_hfun ) - { + { __unreferenced(_line) ; __unreferenced(_hfun) ; @@ -190,7 +192,7 @@ flat_type &_flat , hits_func &_hfun ) - { + { __unreferenced(_flat) ; __unreferenced(_hfun) ; @@ -211,8 +213,9 @@ real_type *_sbal , hits_func &_hfun ) - { + { __unreferenced(_disc) ; + __unreferenced(_sbal) ; __unreferenced(_hfun) ; return ( false ) ; @@ -231,7 +234,7 @@ ball_type &_ball , hits_func &_hfun ) - { + { __unreferenced(_ball) ; __unreferenced(_hfun) ; @@ -253,6 +256,22 @@ return (iptr_type) -1 ; } + /* + -------------------------------------------------------- + * PROJECTOR: project a point to the geometry. + -------------------------------------------------------- + */ + + __normal_call void_type projector ( + real_type *_ppos, + iptr_type _idim, + real_type *_proj + ) + { + __unreferenced(_ppos) ; + __unreferenced(_idim) ; + __unreferenced(_proj) ; + } } ; diff --git a/src/libcpp/geom_type/geom_mesh_ellipsoid_3.hpp b/src/libcpp/geom_type/geom_mesh_ellipsoid_3.hpp index 2673082..a69095d 100644 --- a/src/libcpp/geom_type/geom_mesh_ellipsoid_3.hpp +++ b/src/libcpp/geom_type/geom_mesh_ellipsoid_3.hpp @@ -4,34 +4,34 @@ * GEOM-MESH-ELLIPSOID-3: ellipsoidal geom. in R^3. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 02 March, 2019 + * Last updated: 09 August, 2019 * * Copyright 2013-2019 * Darren Engwirda @@ -53,17 +53,17 @@ typename I , typename A = allocators::basic_alloc > - class geom_mesh_ellipsoid_3d : + class geom_mesh_ellipsoid_3d : public geom_base_3d { public : - + /*-------------- analytic ellipsoidal geometry in R^3 */ - + typedef R real_type ; typedef I iptr_type ; typedef A allocator ; - + typedef geom_mesh_ellipsoid_3d < real_type , iptr_type , @@ -72,27 +72,27 @@ typedef geom_base_3d < real_type , iptr_type > base_type ; - - typedef typename + + typedef typename base_type::line_type line_type ; - typedef typename + typedef typename base_type::flat_type flat_type ; - typedef typename + typedef typename base_type::disc_type disc_type ; - typedef typename + typedef typename base_type::ball_type ball_type ; - - - class node_type: public tria_complex_node_3 + + + class node_type: public mesh_complex_node_3 { /*------------------------------------ loc. node type */ - public : + public : iptr_type _itag ; char_type _fdim ; char_type _feat ; char_type _topo ; - + public : /*------------------------------------ "write" access */ __inline_call iptr_type& itag ( @@ -128,18 +128,18 @@ ) const { return this->_topo ; } - + } ; - - class edge_type: public tria_complex_edge_2 + + class edge_type: public mesh_complex_edge_2 { /*------------------------------------ loc. edge type */ public : iptr_type _itag ; - + char_type _feat ; char_type _topo ; - + public : /*------------------------------------ "write" access */ __inline_call iptr_type& itag ( @@ -167,55 +167,94 @@ ) const { return this->_feat ; } - + } ; - + typedef mesh::tria_complex_1< node_type, edge_type, - allocator > mesh_type ; - + allocator > mesh_type ; + typedef geom_tree::aabb_node_base_k tree_node ; typedef geom_tree::aabb_item_rect_k < - real_type, + float, iptr_type, +3 > tree_item ; - + typedef geom_tree::aabb_tree< tree_item, +3 , tree_node, allocator > tree_type ; iptr_type static constexpr _nbox = +4 ; - + public : - + containers:: - fixed_array _bmin ; + fixed_array _bmin ; containers:: - fixed_array _bmax ; - - mesh_type _mesh ; + fixed_array _bmax ; + + mesh_type _mesh ; + + tree_type _ebox ; - tree_type _ebox ; - /*--------------- (x/a)**2 + (y/b)**2 + (z/c)**2 = 1. */ - - real_type _radA ; - real_type _radB ; - real_type _radC ; - - real_type _rEPS ; + + real_type _radA = 1. ; + real_type _radB = 1. ; + real_type _radC = 1. ; + + real_type _rEPS ; public : - + + __inline_call void_type toR3 ( + __const_ptr(real_type) _apos , + __write_ptr(real_type) _ppos + ) const + { + /*------------ helper: convert from S^2 to R^3 coord. */ + _ppos[0] = this->_radA * + std::cos( _apos[0] ) * + std::cos( _apos[1] ) ; + + _ppos[1] = this->_radB * + std::sin( _apos[0] ) * + std::cos( _apos[1] ) ; + + _ppos[2] = this->_radC * + std::sin( _apos[1] ) ; + } + + __inline_call void_type toS2 ( + __const_ptr(real_type) _ppos , + __write_ptr(real_type) _apos + ) const + { + /*------------ helper: convert from R^3 to S^2 coord. */ + real_type _xmul = + _ppos[0] * this->_radB ; + real_type _ymul = + _ppos[1] * this->_radA ; + real_type _zrat = + _ppos[2] / this->_radC ; + + _zrat = std::min(+1.,_zrat); + _zrat = std::max(-1.,_zrat); + + _apos[0]= std::atan2(_ymul, + _xmul); + _apos[1]= std::asin (_zrat); + } + /* -------------------------------------------------------- * INIT-GEOM: init. geometry data structures. -------------------------------------------------------- */ - + template < typename geom_opts > @@ -229,13 +268,13 @@ this->_bmin[0] = -this->_radA ; this->_bmin[1] = -this->_radB ; this->_bmin[2] = -this->_radC ; - + this->_bmax[0] = +this->_radA ; this->_bmax[1] = +this->_radB ; - this->_bmax[2] = +this->_radC ; - + this->_bmax[2] = +this->_radC ; + /*--------------------------- convert to R^3 coord.'s */ - for (auto _iter = + for (auto _iter = this->_mesh._set1.head() ; _iter != this->_mesh._set1.tend() ; @@ -243,45 +282,41 @@ { if (_iter->mark() < 0) continue ; - - real_type _alon, _alat ; - _alon = _iter->pval(0) ; - _alat = _iter->pval(1) ; - - _iter->pval(0) = - this-> _radA* - std::cos(_alon) * - std::cos(_alat) ; - _iter->pval(1) = - this-> _radB* - std::sin(_alon) * - std::cos(_alat) ; - _iter->pval(2) = - this-> _radC* - std::sin(_alat) ; + + real_type _apos[2]; + real_type _ppos[3]; + + _apos[0] = _iter->pval(0) ; + _apos[1] = _iter->pval(1) ; + + toR3(_apos, _ppos); + + _iter->pval(0) = _ppos[0] ; + _iter->pval(1) = _ppos[1] ; + _iter->pval(2) = _ppos[2] ; } /*--------------------------- form rel.-tol. for prj. */ this->_rEPS = std::sqrt ( std::numeric_limits ::epsilon()) ; - - real_type _rBAR ; + + real_type _rBAR ; _rBAR = (real_type) +0. ; _rBAR += this->_radA ; _rBAR += this->_radB ; _rBAR += this->_radC ; _rBAR /= (real_type) +3. ; - + this->_rEPS *= _rBAR ; - - /*--------------------------- init. AABB for arc-seg. */ + + /*--------------------------- init. AABB for arc-seg. */ containers:: block_array _bbox; - + iptr_type _inum = +0; - - for (auto _iter = + + for (auto _iter = this->_mesh._set2.head() ; _iter != this->_mesh._set2.tend() ; @@ -293,32 +328,32 @@ iptr_type _enod[ +2] ; _enod[0] = _iter->node(0) ; _enod[1] = _iter->node(1) ; - - tree_item _tdat ; + + tree_item _tdat ; _tdat.ipos() = _inum ; - + make_aabb ( - &this->_mesh. - _set1[_enod[0]].pval(0) , - &this->_mesh. - _set1[_enod[1]].pval(0) , - &_tdat .pmin(0), - &_tdat .pmax(0)) ; - + &this->_mesh. + _set1[_enod[ 0 ]].pval(0) , + &this->_mesh. + _set1[_enod[ 1 ]].pval(0) , + &_tdat .pmin( 0 ), + &_tdat .pmax( 0 )) ; + _bbox.push_tail(_tdat) ; } - + this->_ebox.load ( - _bbox.head(), + _bbox.head(), _bbox.tend(),this->_nbox) ; } - + /* -------------------------------------------------------- * HAVE-FEAT: TRUE if has k-dim. FEAT. -------------------------------------------------------- */ - + __inline_call bool_type have_feat ( iptr_type _fdim ) @@ -331,22 +366,22 @@ else return ( false ) ; } - + /* -------------------------------------------------------- * SEED-FEAT: init. "seed" vertex set on geom. -------------------------------------------------------- */ - + template < typename mesh_type , typename geom_opts > __normal_call void_type seed_feat ( - mesh_type &_mesh , + mesh_type &_rdel , geom_opts &_opts ) - { + { __unreferenced(_opts) ; real_type _ppos[3] ; @@ -354,313 +389,312 @@ _ppos[0] = (real_type) +0.0E+0; _ppos[1] = (real_type) +0.0E+0; _ppos[2] = (real_type) +0.0E+0; - _mesh. + _rdel. _tria.push_node(_ppos, _inod) ; - _mesh. + _rdel. _tria.node(_inod)->fdim() = +4; - _mesh. + _rdel. _tria.node(_inod)->feat() = +0; - _mesh. - _tria.node(_inod)->topo() = +0; - } - + _rdel. + _tria.node(_inod)->topo() = +0; + } + /* -------------------------------------------------------- * SEED-MESH: init. "seed" vertex set on geom. -------------------------------------------------------- */ - + template < typename mesh_type , typename geom_opts > __normal_call void_type seed_mesh ( - mesh_type &_mesh , + mesh_type &_rdel , geom_opts &_opts ) - { + { __unreferenced(_opts) ; - real_type _pi = + real_type _pi = (real_type)std::atan(1.0) * 4. ; - - real_type _la = + + real_type _la = (real_type)std::atan(0.5) * 1. ; - - real_type _lo = 2.*_pi / 10. ; - - if (_mesh._tria. + + real_type _lo = 2.*_pi / 10. ; + + if (_rdel._tria. _nset.count() <= +8 ) { /*--------------------------- init. reg.-icosahedron */ real_type _ppos[3] ; iptr_type _inod; - _ppos[0] = this->_radA * + _ppos[0] = this->_radA * std::cos(_pi*(real_type)+0.0) * std::cos(_pi*(real_type)+0.5) ; - _ppos[1] = this->_radB * + _ppos[1] = this->_radB * std::sin(_pi*(real_type)+0.0) * std::cos(_pi*(real_type)+0.5) ; - _ppos[2] = this->_radC * + _ppos[2] = this->_radC * std::sin(_pi*(real_type)+0.5) ; - _mesh. + _rdel. _tria.push_node(_ppos, _inod) ; - _mesh. + _rdel. _tria.node(_inod)->fdim() = +0; - _mesh. + _rdel. _tria.node(_inod)->feat() = +0; - _mesh. + _rdel. _tria.node(_inod)->topo() = +2; - - _ppos[0] = this->_radA * + + _ppos[0] = this->_radA * std::cos(_pi*(real_type)+0.0) * std::cos(_pi*(real_type)-0.5) ; - _ppos[1] = this->_radB * + _ppos[1] = this->_radB * std::sin(_pi*(real_type)+0.0) * std::cos(_pi*(real_type)-0.5) ; - _ppos[2] = this->_radC * + _ppos[2] = this->_radC * std::sin(_pi*(real_type)-0.5) ; - _mesh. + _rdel. _tria.push_node(_ppos, _inod) ; - _mesh. + _rdel. _tria.node(_inod)->fdim() = +0; - _mesh. + _rdel. _tria.node(_inod)->feat() = +0; - _mesh. + _rdel. _tria.node(_inod)->topo() = +2; - - _ppos[0] = this->_radA * + + _ppos[0] = this->_radA * std::cos(_lo*(real_type)+0.0) * std::cos(_la*(real_type)+1.0) ; - _ppos[1] = this->_radB * + _ppos[1] = this->_radB * std::sin(_lo*(real_type)+0.0) * std::cos(_la*(real_type)+1.0) ; - _ppos[2] = this->_radC * + _ppos[2] = this->_radC * std::sin(_la*(real_type)+1.0) ; - _mesh. + _rdel. _tria.push_node(_ppos, _inod) ; - _mesh. + _rdel. _tria.node(_inod)->fdim() = +0; - _mesh. + _rdel. _tria.node(_inod)->feat() = +0; - _mesh. + _rdel. _tria.node(_inod)->topo() = +2; - - _ppos[0] = this->_radA * + + _ppos[0] = this->_radA * std::cos(_lo*(real_type)+1.0) * std::cos(_la*(real_type)-1.0) ; - _ppos[1] = this->_radB * + _ppos[1] = this->_radB * std::sin(_lo*(real_type)+1.0) * std::cos(_la*(real_type)-1.0) ; - _ppos[2] = this->_radC * + _ppos[2] = this->_radC * std::sin(_la*(real_type)-1.0) ; - _mesh. + _rdel. _tria.push_node(_ppos, _inod) ; - _mesh. + _rdel. _tria.node(_inod)->fdim() = +0; - _mesh. + _rdel. _tria.node(_inod)->feat() = +0; - _mesh. + _rdel. _tria.node(_inod)->topo() = +2; - - _ppos[0] = this->_radA * + + _ppos[0] = this->_radA * std::cos(_lo*(real_type)+2.0) * std::cos(_la*(real_type)+1.0) ; - _ppos[1] = this->_radB * + _ppos[1] = this->_radB * std::sin(_lo*(real_type)+2.0) * std::cos(_la*(real_type)+1.0) ; - _ppos[2] = this->_radC * + _ppos[2] = this->_radC * std::sin(_la*(real_type)+1.0) ; - _mesh. + _rdel. _tria.push_node(_ppos, _inod) ; - _mesh. + _rdel. _tria.node(_inod)->fdim() = +0; - _mesh. + _rdel. _tria.node(_inod)->feat() = +0; - _mesh. + _rdel. _tria.node(_inod)->topo() = +2; - - _ppos[0] = this->_radA * + + _ppos[0] = this->_radA * std::cos(_lo*(real_type)+3.0) * std::cos(_la*(real_type)-1.0) ; - _ppos[1] = this->_radB * + _ppos[1] = this->_radB * std::sin(_lo*(real_type)+3.0) * std::cos(_la*(real_type)-1.0) ; - _ppos[2] = this->_radC * + _ppos[2] = this->_radC * std::sin(_la*(real_type)-1.0) ; - _mesh. + _rdel. _tria.push_node(_ppos, _inod) ; - _mesh. + _rdel. _tria.node(_inod)->fdim() = +0; - _mesh. + _rdel. _tria.node(_inod)->feat() = +0; - _mesh. + _rdel. _tria.node(_inod)->topo() = +2; - - _ppos[0] = this->_radA * + + _ppos[0] = this->_radA * std::cos(_lo*(real_type)+4.0) * std::cos(_la*(real_type)+1.0) ; - _ppos[1] = this->_radB * + _ppos[1] = this->_radB * std::sin(_lo*(real_type)+4.0) * std::cos(_la*(real_type)+1.0) ; - _ppos[2] = this->_radC * + _ppos[2] = this->_radC * std::sin(_la*(real_type)+1.0) ; - _mesh. + _rdel. _tria.push_node(_ppos, _inod) ; - _mesh. + _rdel. _tria.node(_inod)->fdim() = +0; - _mesh. + _rdel. _tria.node(_inod)->feat() = +0; - _mesh. + _rdel. _tria.node(_inod)->topo() = +2; - - _ppos[0] = this->_radA * + + _ppos[0] = this->_radA * std::cos(_lo*(real_type)+5.0) * std::cos(_la*(real_type)-1.0) ; - _ppos[1] = this->_radB * + _ppos[1] = this->_radB * std::sin(_lo*(real_type)+5.0) * std::cos(_la*(real_type)-1.0) ; - _ppos[2] = this->_radC * + _ppos[2] = this->_radC * std::sin(_la*(real_type)-1.0) ; - _mesh. + _rdel. _tria.push_node(_ppos, _inod) ; - _mesh. + _rdel. _tria.node(_inod)->fdim() = +0; - _mesh. + _rdel. _tria.node(_inod)->feat() = +0; - _mesh. - _tria.node(_inod)->topo() = +2; - - _ppos[0] = this->_radA * + _rdel. + _tria.node(_inod)->topo() = +2; + + _ppos[0] = this->_radA * std::cos(_lo*(real_type)+6.0) * std::cos(_la*(real_type)+1.0) ; - _ppos[1] = this->_radB * + _ppos[1] = this->_radB * std::sin(_lo*(real_type)+6.0) * std::cos(_la*(real_type)+1.0) ; - _ppos[2] = this->_radC * + _ppos[2] = this->_radC * std::sin(_la*(real_type)+1.0) ; - _mesh. + _rdel. _tria.push_node(_ppos, _inod) ; - _mesh. + _rdel. _tria.node(_inod)->fdim() = +0; - _mesh. + _rdel. _tria.node(_inod)->feat() = +0; - _mesh. - _tria.node(_inod)->topo() = +2; - - _ppos[0] = this->_radA * + _rdel. + _tria.node(_inod)->topo() = +2; + + _ppos[0] = this->_radA * std::cos(_lo*(real_type)+7.0) * std::cos(_la*(real_type)-1.0) ; - _ppos[1] = this->_radB * + _ppos[1] = this->_radB * std::sin(_lo*(real_type)+7.0) * std::cos(_la*(real_type)-1.0) ; - _ppos[2] = this->_radC * + _ppos[2] = this->_radC * std::sin(_la*(real_type)-1.0) ; - _mesh. + _rdel. _tria.push_node(_ppos, _inod) ; - _mesh. + _rdel. _tria.node(_inod)->fdim() = +0; - _mesh. + _rdel. _tria.node(_inod)->feat() = +0; - _mesh. + _rdel. _tria.node(_inod)->topo() = +2; - - _ppos[0] = this->_radA * + + _ppos[0] = this->_radA * std::cos(_lo*(real_type)+8.0) * std::cos(_la*(real_type)+1.0) ; - _ppos[1] = this->_radB * + _ppos[1] = this->_radB * std::sin(_lo*(real_type)+8.0) * std::cos(_la*(real_type)+1.0) ; - _ppos[2] = this->_radC * + _ppos[2] = this->_radC * std::sin(_la*(real_type)+1.0) ; - _mesh. + _rdel. _tria.push_node(_ppos, _inod) ; - _mesh. + _rdel. _tria.node(_inod)->fdim() = +0; - _mesh. + _rdel. _tria.node(_inod)->feat() = +0; - _mesh. + _rdel. _tria.node(_inod)->topo() = +2; - - _ppos[0] = this->_radA * + + _ppos[0] = this->_radA * std::cos(_lo*(real_type)+9.0) * std::cos(_la*(real_type)-1.0) ; - _ppos[1] = this->_radB * + _ppos[1] = this->_radB * std::sin(_lo*(real_type)+9.0) * std::cos(_la*(real_type)-1.0) ; - _ppos[2] = this->_radC * + _ppos[2] = this->_radC * std::sin(_la*(real_type)-1.0) ; - _mesh. + _rdel. _tria.push_node(_ppos, _inod) ; - _mesh. + _rdel. _tria.node(_inod)->fdim() = +0; - _mesh. + _rdel. _tria.node(_inod)->feat() = +0; - _mesh. + _rdel. _tria.node(_inod)->topo() = +2; - + } - + } - + /* -------------------------------------------------------- * HELPERS: predicates for intersection tests. -------------------------------------------------------- */ - + __normal_call void_type make_aabb ( real_type *_apos, real_type *_bpos, - real_type *_rmin, - real_type *_rmax + float *_rmin, + float *_rmax ) { /*- build an AABB that encloses a spheroidal arc-seg. */ - real_type _rEPS = this->_rEPS ; - - _rmin[0] = std::min( + real_type _rTOL = this->_rEPS ; + + _rmin[0] = (float)std::min( _apos[0], _bpos[0]) ; - _rmin[1] = std::min( + _rmin[1] = (float)std::min( _apos[1], _bpos[1]) ; - _rmin[2] = std::min( + _rmin[2] = (float)std::min( _apos[2], _bpos[2]) ; - - _rmax[0] = std::max( + + _rmax[0] = (float)std::max( _apos[0], _bpos[0]) ; - _rmax[1] = std::max( + _rmax[1] = (float)std::max( _apos[1], _bpos[1]) ; - _rmax[2] = std::max( + _rmax[2] = (float)std::max( _apos[2], _bpos[2]) ; - - real_type _rmid[3] = { - (real_type) +.5 * _rmin[0] + - (real_type) +.5 * _rmax[0] , - (real_type) +.5 * _rmin[1] + - (real_type) +.5 * _rmax[1] , - (real_type) +.5 * _rmin[2] + - (real_type) +.5 * _rmax[2] , + + float _rmid[3] = { + (float) +.5 * _rmin[0] + + (float) +.5 * _rmax[0] , + (float) +.5 * _rmin[1] + + (float) +.5 * _rmax[1] , + (float) +.5 * _rmin[2] + + (float) +.5 * _rmax[2] , } ; - - real_type _rlen; - _rlen = (real_type) +0. ; + + float _rlen = +0. ; _rlen = std::max ( _rlen , _rmax[0]-_rmin[0]); _rlen = std::max ( _rlen , _rmax[1]-_rmin[1]); _rlen = std::max ( _rlen , _rmax[2]-_rmin[2]); - - _rlen*= (real_type) +.5 ; - _rlen+= _rEPS ; - + + _rlen*= (float) +.5 ; + _rlen+= (float) _rTOL ; + _rmin[0] = std::min( _rmin[0], _rmid[0]-_rlen) ; _rmin[1] = std::min( _rmin[1], _rmid[1]-_rlen) ; _rmin[2] = std::min( _rmin[2], _rmid[2]-_rlen) ; - + _rmax[0] = std::max( _rmax[0], _rmid[0]+_rlen) ; _rmax[1] = std::max( @@ -668,13 +702,13 @@ _rmax[2] = std::max( _rmax[2], _rmid[2]+_rlen) ; } - + /* -------------------------------------------------------- * HELPERS: predicates for intersection tests. -------------------------------------------------------- */ - + __normal_call bool_type line_surf ( real_type *_ipos , real_type *_jpos , @@ -683,9 +717,9 @@ ) { - /*- calc. intersection of a line & spheroidal surface */ + /*- calc. intersection of a line & spheroidal surface */ bool_type _find = false ; - + real_type _mm[3] = { _jpos[0] * (real_type)+.5 + _ipos[0] * (real_type)+.5 , @@ -701,71 +735,71 @@ _ipos[1] * (real_type)+.5 , _jpos[2] * (real_type)+.5 - _ipos[2] * (real_type)+.5 - } ; - - real_type _ax = + } ; + + real_type _ax = _dd [0] / this->_radA ; - real_type _ay = + real_type _ay = _dd [1] / this->_radB ; - real_type _az = + real_type _az = _dd [2] / this->_radC ; - + real_type _aa = _ax * _ax + _ay * _ay + _az * _az ; - - real_type _bx = - _mm [0] * _dd[0] / + + real_type _bx = + _mm [0] * _dd[0] / (this->_radA * this->_radA) ; - real_type _by = - _mm [1] * _dd[1] / + real_type _by = + _mm [1] * _dd[1] / (this->_radB * this->_radB) ; - real_type _bz = - _mm [2] * _dd[2] / + real_type _bz = + _mm [2] * _dd[2] / (this->_radC * this->_radC) ; - - real_type _bb = + + real_type _bb = _bx * (real_type) +2. + _by * (real_type) +2. + - _bz * (real_type) +2. ; - - real_type _cx = + _bz * (real_type) +2. ; + + real_type _cx = _mm [0] / this->_radA ; - real_type _cy = + real_type _cy = _mm [1] / this->_radB ; - real_type _cz = + real_type _cz = _mm [2] / this->_radC ; - + real_type _cc = _cx * _cx + _cy * _cy - + _cz * _cz + + _cz * _cz - (real_type) 1. ; - - real_type _tsqr = _bb*_bb - + + real_type _tsqr = _bb*_bb - (real_type)4.*_aa*_cc ; - + if (_tsqr >= (real_type)+0.) { _tsqr = std::sqrt(_tsqr) ; _find = true ; - _ttii = (-_bb + _tsqr) / + _ttii = (-_bb + _tsqr) / ((real_type)+2. * _aa) ; - - _ttjj = (-_bb - _tsqr) / + + _ttjj = (-_bb - _tsqr) / ((real_type)+2. * _aa) ; } - + return ( _find ) ; } - + /* -------------------------------------------------------- - * HELPERS: predicates for projection to geom. + * HELPERS: predicates for projection to geom. -------------------------------------------------------- */ - + __normal_call void_type proj_surf ( real_type *_psrc , real_type *_pprj @@ -776,7 +810,7 @@ _zero[0] = (real_type) +.0 ; _zero[1] = (real_type) +.0 ; _zero[2] = (real_type) +.0 ; - + real_type _ttaa, _ttbb ; if (line_surf( _zero, _psrc, _ttaa, _ttbb) ) @@ -797,29 +831,29 @@ _psrc[2] * (real_type) +.5 - _zero[2] * (real_type) +.5 } ; - + if (_ttaa > (real_type)-1.) { - _pprj[0] = + _pprj[0] = _pmid[0] + _ttaa*_pdel[0] ; - _pprj[1] = + _pprj[1] = _pmid[1] + _ttaa*_pdel[1] ; - _pprj[2] = + _pprj[2] = _pmid[2] + _ttaa*_pdel[2] ; } else if (_ttbb > (real_type)-1.) { - _pprj[0] = + _pprj[0] = _pmid[0] + _ttbb*_pdel[0] ; - _pprj[1] = + _pprj[1] = _pmid[1] + _ttbb*_pdel[1] ; - _pprj[2] = + _pprj[2] = _pmid[2] + _ttbb*_pdel[2] ; } } } - + __normal_call void_type proj_curv ( real_type *_psrc , real_type *_pprj , @@ -832,47 +866,47 @@ _zero[0] = (real_type) +.0 ; _zero[1] = (real_type) +.0 ; _zero[2] = (real_type) +.0 ; - + real_type _vnrm[3] ; geometry::tria_norm_3d ( - _zero , _apos, + _zero , _apos, _bpos , _vnrm) ; - + real_type _ptmp[3] ; geometry::proj_flat_3d ( _psrc , _zero, _vnrm , _ptmp) ; - + proj_surf(_ptmp, _pprj); - + real_type _anrm[3] ; real_type _bnrm[3] ; geometry::tria_norm_3d ( - _zero , _apos, + _zero , _apos, _pprj , _anrm) ; - + geometry::tria_norm_3d ( - _zero , _pprj, + _zero , _pprj, _bpos , _bnrm) ; - - real_type _asgn = + + real_type _asgn = geometry::dot_3d(_vnrm, _anrm); - - real_type _bsgn = + + real_type _bsgn = geometry::dot_3d(_vnrm, _bnrm); - + if (_asgn < (real_type)+0.|| _bsgn < (real_type)+0.) { - - real_type _alen = + + real_type _alen = geometry:: lensqr_3d(_apos, _pprj); - - real_type _blen = + + real_type _blen = geometry:: lensqr_3d(_bpos, _pprj); - + if (_alen <= _blen) { _pprj[0] = _apos[0]; @@ -884,10 +918,10 @@ _pprj[0] = _bpos[0]; _pprj[1] = _bpos[1]; _pprj[2] = _bpos[2]; - } - } + } + } } - + /* -------------------------------------------------------- * HELPERS: predicates for intersection tests. @@ -908,25 +942,25 @@ { /*--------------------------- bisect curve about ball */ bool_type _okay = false ; - + real_type _pprj[3] ; - proj_curv( _ball. _pmid , - _pprj, + proj_curv( _ball. _pmid , + _pprj, _apos, _bpos) ; - - _okay = _okay | - ball_kern( _ball, _edge , - _apos, _pprj, 0 , + + _okay = _okay | + ball_kern( _ball, _edge , + _apos, _pprj, 0 , _hfun, _hnum) ; - - _okay = _okay | - ball_kern( _ball, _edge , - _pprj, _bpos, 0 , + + _okay = _okay | + ball_kern( _ball, _edge , + _pprj, _bpos, 0 , _hfun, _hnum) ; - - return _okay ; + + return _okay ; } - + template < typename hits_func > @@ -941,24 +975,24 @@ ) { /*- calc. intersection of a ball & spheroidal arc-seg */ - geometry::hits_type + geometry::hits_type _htmp = geometry::face_hits ; - + if (_call++ > +32) return false ; - + /*--------------------------- call linear intersector */ real_type _ppos[3] ; real_type _qpos[3] ; - iptr_type _inum = + iptr_type _inum = (iptr_type)geometry::ball_line_3d ( - _ball._pmid, - _ball._rrad, - _apos,_bpos, + _ball._pmid, + _ball._rrad, + _apos,_bpos, _ppos,_qpos ) ; - + if (_inum >= (iptr_type) +1) - { - + { + if (_inum == (iptr_type) +1) { /*--------------------------- call hit output functor */ @@ -968,17 +1002,17 @@ real_type _plen = geometry:: lensqr_3d(_ppos, _pprj) ; - - if (_plen < this->_rEPS * + + if (_plen < this->_rEPS * this->_rEPS ) { _hfun(&_pprj[0], _htmp , _edge.feat() , _edge.topo() , _edge.itag() ) ; - + _hnum += +1 ; - + return true ; } } @@ -994,33 +1028,33 @@ real_type _plen = geometry:: lensqr_3d(_ppos, _pprj) ; - + real_type _qlen = geometry:: lensqr_3d(_qpos, _qprj) ; - - real_type _xlen = + + real_type _xlen = std::max (_plen, _qlen) ; - - if (_xlen < this->_rEPS * + + if (_xlen < this->_rEPS * this->_rEPS ) { _hfun(&_pprj[0], _htmp , _edge.feat() , _edge.topo() , _edge.itag() ) ; - + _hfun(&_qprj[0], _htmp , _edge.feat() , _edge.topo() , _edge.itag() ) ; - + _hnum += +2 ; - + return true ; } } - + /*--------------------------- recursive arc bisection */ bool_type _okay = false ; @@ -1034,22 +1068,22 @@ } ; real_type _cprj[3] ; - proj_surf(_cpos, _cprj) ; - - _okay = _okay | - ball_kern( _ball, _edge, - _apos, _cprj, _call, + proj_surf(_cpos, _cprj) ; + + _okay = _okay | + ball_kern( _ball, _edge, + _apos, _cprj, _call, _hfun, _hnum) ; - - _okay = _okay | - ball_kern( _ball, _edge, - _cprj, _bpos, _call, + + _okay = _okay | + ball_kern( _ball, _edge, + _cprj, _bpos, _call, _hfun, _hnum) ; - - return _okay ; - + + return _okay ; + } - + return false ; } @@ -1073,20 +1107,20 @@ ) { /*- calc. intersection of a flat & spheroidal arc-seg */ - geometry::hits_type + geometry::hits_type _htmp = geometry::face_hits ; - + if (_call++ > +32) return false ; - + /*--------------------------- call linear intersector */ real_type _xpos[3] ; if (geometry::line_flat_3d ( - _flat._ppos, - _flat._nvec, - _apos,_bpos, + _flat._ppos, + _flat._nvec, + _apos,_bpos, _xpos, true) ) - { - + { + /*--------------------------- call hit output functor */ real_type _xprj[3] ; proj_surf(_xpos, _xprj) ; @@ -1094,20 +1128,20 @@ real_type _xlen = geometry:: lensqr_3d(_xpos, _xprj) ; - - if (_xlen < this->_rEPS * + + if (_xlen < this->_rEPS * this->_rEPS ) { _hfun(&_xprj[0], _htmp , _edge.feat() , _edge.topo() , _edge.itag() ) ; - + _hnum += +1 ; - + return true ; } - + /*--------------------------- recursive arc bisection */ bool_type _okay = false ; @@ -1121,22 +1155,22 @@ } ; real_type _cprj[3] ; - proj_surf(_cpos, _cprj) ; - - _okay = _okay | - flat_kern( _flat, _edge, - _apos, _cprj, _call, + proj_surf(_cpos, _cprj) ; + + _okay = _okay | + flat_kern( _flat, _edge, + _apos, _cprj, _call, _hfun, _hnum) ; - - _okay = _okay | - flat_kern( _flat, _edge, - _cprj, _bpos, _call, + + _okay = _okay | + flat_kern( _flat, _edge, + _cprj, _bpos, _call, _hfun, _hnum) ; - - return _okay ; - + + return _okay ; + } - + return false ; } @@ -1157,7 +1191,7 @@ hits_func &_hfun ) { - /*- calc. intersection of a disc & spheroidal surface */ + /*- calc. intersection of a disc & spheroidal surface */ if (is_inside(_apos) != is_inside(_bpos) ) { @@ -1171,13 +1205,13 @@ _ldat._jpos[0] = _bpos[0] ; _ldat._jpos[1] = _bpos[1] ; _ldat._jpos[2] = _bpos[2] ; - + return intersect(_ldat, _hfun); - + } else - { - /*--------------------------- recursive arc bisection */ + { + /*--------------------------- recursive arc bisection */ bool_type _okay = false ; real_type _cpos[4] = { @@ -1195,7 +1229,7 @@ _cpos[2] - _disc._pmid[2] , } ; - _cdir[3] = + _cdir[3] = geometry::length_3d(_cdir); _cdir[0]/= _cdir[3] ; _cdir[1]/= _cdir[3] ; @@ -1208,20 +1242,20 @@ _cpos[2] = _disc._pmid[2] + _cdir[2] * _disc._rrad ; - _okay = _okay | - disc_kern( _disc, + _okay = _okay | + disc_kern( _disc, _apos , _cpos, _call, _hfun) ; - - _okay = _okay | - disc_kern( _disc, + + _okay = _okay | + disc_kern( _disc, _cpos , _bpos, _call, _hfun) ; - + return _okay ; - + } } - - return false ; + + return false ; } /* @@ -1239,18 +1273,18 @@ public : geom_type &_geom ; flat_type &_flat ; - + hits_func &_hfun ; - - bool_type _find ; + + bool_type _find ; iptr_type _hnum ; - + public : flat_intersect operator = ( - flat_intersect & + flat_intersect & ) = delete ; flat_intersect operator = ( - flat_intersect&& + flat_intersect&& ) = delete ; public : @@ -1260,7 +1294,7 @@ geom_type &_gsrc , hits_func &_hsrc ) : _geom( _gsrc ) , - _flat( _fsrc ) , + _flat( _fsrc ) , _hfun( _hsrc ) { this->_hnum = + 0 ; @@ -1268,43 +1302,43 @@ } /*----------------------- all intersection about node */ __normal_call void_type operator() ( - typename + typename tree_type::item_data *_iptr ) { - for ( ; _iptr != nullptr; + for ( ; _iptr != nullptr; _iptr = _iptr->_next ) { /*--------------- flat/edge intersection test */ - iptr_type _epos = + iptr_type _epos = _iptr->_data.ipos() ; - + iptr_type _enod[2]; _enod[0] =_geom. _mesh._set2[_epos].node(0) ; _enod[1] =_geom. _mesh._set2[_epos].node(1) ; - + /*--------------- call output function on hit */ - _geom .flat_kern ( + _geom .flat_kern ( this->_flat, this->_geom. _mesh ._set2[_epos] , &this->_geom. - _mesh._set1[_enod[ 0]].pval(0) , + _mesh._set1[_enod[ 0]].pval(0) , &this->_geom. _mesh._set1[_enod[ 1]].pval(0) , + 0 , this->_hfun, this->_hnum) ; - - this->_find = + + this->_find = this->_find | (this->_hnum!=0) ; } } - + } ; - + template < typename hits_func > @@ -1314,21 +1348,21 @@ public : geom_type &_geom ; ball_type &_ball ; - + real_type _rmin[3] ; real_type _rmax[3] ; - + hits_func &_hfun ; - - bool_type _find ; + + bool_type _find ; iptr_type _hnum ; - + public : ball_intersect operator = ( - ball_intersect & + ball_intersect & ) = delete ; ball_intersect operator = ( - ball_intersect&& + ball_intersect&& ) = delete ; public : @@ -1340,64 +1374,64 @@ geom_type &_gsrc , hits_func &_hsrc ) : _geom( _gsrc ) , - _ball( _bsrc ) , + _ball( _bsrc ) , _hfun( _hsrc ) { this->_rmin[0] = _psrc[0] ; this->_rmin[1] = _psrc[1] ; this->_rmin[2] = _psrc[2] ; - + this->_rmax[0] = _qsrc[0] ; this->_rmax[1] = _qsrc[1] ; this->_rmax[2] = _qsrc[2] ; - + this->_hnum = + 0 ; this->_find = false ; } /*----------------------- all intersection about node */ __normal_call void_type operator() ( - typename + typename tree_type::item_data *_iptr ) { - for ( ; _iptr != nullptr; + for ( ; _iptr != nullptr; _iptr = _iptr->_next ) { /*--------------- ball/edge intersection test */ - iptr_type _epos = + iptr_type _epos = _iptr->_data.ipos() ; - + iptr_type _enod[2]; _enod[0] =_geom. _mesh._set2[_epos].node(0) ; _enod[1] =_geom. _mesh._set2[_epos].node(1) ; - + /*--------------- call output function on hit */ - _geom. ball_test ( + _geom. ball_test ( this->_ball, this->_geom. _mesh ._set2[_epos] , &this->_geom. - _mesh._set1[_enod[ 0]].pval(0) , + _mesh._set1[_enod[ 0]].pval(0) , &this->_geom. _mesh._set1[_enod[ 1]].pval(0) , this->_hfun, this->_hnum) ; - - this->_find = + + this->_find = this->_find | (this->_hnum!=0) ; } } - + } ; - + /* -------------------------------------------------------- * INTERSECT: find FLAT/1-GEOM. intersections. -------------------------------------------------------- */ - + template < typename hits_func > @@ -1407,21 +1441,43 @@ ) { /*------------------ tree-flat intersection predicate */ - typedef + typedef geom_tree::aabb_pred_flat_3 < - real_type, - iptr_type > tree_pred ; + float , + iptr_type > tree_pred ; /*------------------ dual-face intersection predicate */ - typedef + typedef flat_intersect < hits_func > hits_pred ; - + + float _PPOS[3] = { + (float) _flat. _ppos[0] , + (float) _flat. _ppos[1] , + (float) _flat. _ppos[2] , + } ; + + float _NVEC[3] = { + (float) _flat. _nvec[0] , + (float) _flat. _nvec[1] , + (float) _flat. _nvec[2] , + } ; + + float _RMIN[3] = { + (float) _flat. _rmin[0] , + (float) _flat. _rmin[1] , + (float) _flat. _rmin[2] , + } ; + + float _RMAX[3] = { + (float) _flat. _rmax[0] , + (float) _flat. _rmax[1] , + (float) _flat. _rmax[2] , + } ; + /*------------------ call actual intersection testing */ - tree_pred _pred(_flat. _ppos, - _flat. _nvec, - _flat. _rmin, - _flat. _rmax) ; + tree_pred _pred(_PPOS, _NVEC, + _RMIN, _RMAX) ; hits_pred _func(_flat, *this, _hfun) ; @@ -1430,13 +1486,13 @@ /*------------------ _TRUE if any intersections found */ return ( _func._find ) ; } - + /* -------------------------------------------------------- * INTERSECT: find BALL/1-GEOM. intersections. -------------------------------------------------------- */ - + template < typename hits_func > @@ -1446,17 +1502,26 @@ ) { /*------------------ tree-ball intersection predicate */ - typedef + typedef geom_tree::aabb_pred_ball_3 < - real_type, - iptr_type > tree_pred ; - + float , + iptr_type > tree_pred ; + /*------------------ ball-line intersection predicate */ - typedef + typedef ball_intersect < hits_func > hits_pred ; - /*------------------ call actual intersection testing */ + float _PMID[3] = { + (float) _ball. _pmid[0] , + (float) _ball. _pmid[1] , + (float) _ball. _pmid[2] , + } ; + + float _RRAD = + (float) _ball. _rrad; + + /*------------------ call actual intersection testing */ real_type _rmin[3] = { _ball._pmid[0] -_ball. _rrad, _ball._pmid[1] -_ball. _rrad, @@ -1467,9 +1532,8 @@ _ball._pmid[1] +_ball. _rrad, _ball._pmid[2] +_ball. _rrad } ; - - tree_pred _pred(_ball. _pmid, - _ball. _rrad) ; + + tree_pred _pred(_PMID, _RRAD) ; hits_pred _func(_ball, _rmin, _rmax, *this, _hfun) ; @@ -1479,13 +1543,13 @@ /*------------------ _TRUE if any intersections found */ return ( _func._find ) ; } - + /* -------------------------------------------------------- * INTERSECT: find LINE/2-GEOM. intersections. -------------------------------------------------------- */ - + template < typename hits_func > @@ -1509,7 +1573,7 @@ real_type _ttaa, _ttbb; if (line_surf(_ipos, _jpos, _ttaa, _ttbb)) { - + real_type _pmid[3] = { _jpos[0] * (real_type)+.5 + _ipos[0] * (real_type)+.5 , @@ -1526,54 +1590,54 @@ _jpos[2] * (real_type)+.5 - _ipos[2] * (real_type)+.5 } ; - + real_type _apos[3] = { _pmid[0] + _ttaa * _pdel[0] , _pmid[1] + _ttaa * _pdel[1] , _pmid[2] + _ttaa * _pdel[2] } ; - + real_type _bpos[3] = { _pmid[0] + _ttbb * _pdel[0] , _pmid[1] + _ttbb * _pdel[1] , _pmid[2] + _ttbb * _pdel[2] } ; - - char_type _hits = + + char_type _hits = geometry::null_hits ; char_type _feat = +2; char_type _topo = +2; iptr_type _itag = +0; - + if (_ttaa >= (real_type)-1.) if (_ttaa <= (real_type)+1.) { - _find = true ; - _hfun ( _apos, _hits , - _feat, _topo , + _find = true ; + _hfun ( _apos, _hits , + _feat, _topo , _itag) ; } - + if (_ttbb >= (real_type)-1.) if (_ttbb <= (real_type)+1.) { - _find = true ; - _hfun ( _bpos, _hits , - _feat, _topo , + _find = true ; + _hfun ( _bpos, _hits , + _feat, _topo , _itag) ; } - + } - + return ( _find ) ; } - + /* -------------------------------------------------------- * INTERSECT: find DISC/2-GEOM. intersections. -------------------------------------------------------- */ - + template < typename hits_func > @@ -1597,107 +1661,133 @@ _disc._pmid[1] - _circ[1] , _disc._pmid[2] - _circ[2] , (real_type) +0. } ; - + real_type _ddir[4] ; geometry::cross_3d( _pdir, _disc._nvec, _ddir) ; - - _pdir[3] = + + _pdir[3] = geometry::length_3d(_pdir) ; _pdir[0]/= _pdir[3] ; _pdir[1]/= _pdir[3] ; _pdir[2]/= _pdir[3] ; - - _ddir[3] = + + _ddir[3] = geometry::length_3d(_ddir) ; _ddir[0]/= _ddir[3] ; _ddir[1]/= _ddir[3] ; _ddir[2]/= _ddir[3] ; - + real_type _apos[3] = { - _disc._pmid[0] - + _disc._pmid[0] - _disc._rrad *_pdir[0] , - _disc._pmid[1] - + _disc._pmid[1] - _disc._rrad *_pdir[1] , - _disc._pmid[2] - - _disc._rrad *_pdir[2] + _disc._pmid[2] - + _disc._rrad *_pdir[2] } ; - + real_type _bpos[3] = { - _disc._pmid[0] + + _disc._pmid[0] + _disc._rrad *_ddir[0] , - _disc._pmid[1] + + _disc._pmid[1] + _disc._rrad *_ddir[1] , - _disc._pmid[2] + - _disc._rrad *_ddir[2] + _disc._pmid[2] + + _disc._rrad *_ddir[2] } ; - + real_type _cpos[3] = { _disc._pmid[0] + _disc._rrad *_pdir[0] , - _disc._pmid[1] + + _disc._pmid[1] + _disc._rrad *_pdir[1] , - _disc._pmid[2] + - _disc._rrad *_pdir[2] + _disc._pmid[2] + + _disc._rrad *_pdir[2] } ; - + real_type _dpos[3] = { - _disc._pmid[0] - + _disc._pmid[0] - _disc._rrad *_ddir[0] , - _disc._pmid[1] - + _disc._pmid[1] - _disc._rrad *_ddir[1] , - _disc._pmid[2] - - _disc._rrad *_ddir[2] + _disc._pmid[2] - + _disc._rrad *_ddir[2] } ; - - _find = _find | - disc_kern(_disc, + + _find = _find | + disc_kern(_disc, _apos , _bpos, +0, _hfun) ; - - _find = _find | - disc_kern(_disc, + + _find = _find | + disc_kern(_disc, _bpos , _cpos, +0, _hfun) ; - - _find = _find | - disc_kern(_disc, + + _find = _find | + disc_kern(_disc, _cpos , _dpos, +0, _hfun) ; - - _find = _find | - disc_kern(_disc, + + _find = _find | + disc_kern(_disc, _dpos , _apos, +0, _hfun) ; - + return _find ; } - + /* -------------------------------------------------------- * IS-INSIDE: TRUE if point is "inside" geometry. -------------------------------------------------------- */ - + __normal_call bool_type is_inside ( real_type *_ppos ) { - real_type _xx = + real_type _xx = _ppos[0] / this->_radA ; - real_type _yy = + real_type _yy = _ppos[1] / this->_radB ; - real_type _zz = + real_type _zz = _ppos[2] / this->_radC ; - - return ( _xx * _xx - + _yy * _yy - + _zz * _zz + + return ( _xx * _xx + + _yy * _yy + + _zz * _zz <= (real_type) +1. ) ; } - + + /* + -------------------------------------------------------- + * PROJECTOR: project a point on to the geometry. + -------------------------------------------------------- + */ + + __normal_call void_type projector ( + real_type *_ppos , + iptr_type _idim , + real_type *_proj + ) + { + if (_idim == +2) + { + /*------------------ project to closest 2-dim feature */ + proj_surf(_ppos, _proj) ; + } + else + { + /*------------------ NULL projection -- return inputs */ + _proj[0] = _ppos[0] ; + _proj[1] = _ppos[1] ; + _proj[2] = _ppos[2] ; + } + } + } ; - - + + } # endif //__GEOM_MESH_ELLIPSOID_3__ - - - + + + diff --git a/src/libcpp/geom_type/geom_mesh_euclidean_2.hpp b/src/libcpp/geom_type/geom_mesh_euclidean_2.hpp index 7a75dd3..223ae2f 100644 --- a/src/libcpp/geom_type/geom_mesh_euclidean_2.hpp +++ b/src/libcpp/geom_type/geom_mesh_euclidean_2.hpp @@ -4,34 +4,34 @@ * GEOM-MESH-EUCLIDEAN-2: euclidean geom. in R^2. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 02 March, 2019 + * Last updated: 08 December, 2019 * * Copyright 2013-2019 * Darren Engwirda @@ -53,13 +53,13 @@ typename I , typename A = allocators::basic_alloc > - class geom_mesh_euclidean_2d : + class geom_mesh_euclidean_2d : public geom_base_2d { public : - + /*---------- discrete geometry in R^2 via nodes/faces */ - + typedef R real_type ; typedef I iptr_type ; typedef A allocator ; @@ -68,27 +68,27 @@ real_type , iptr_type , allocator > geom_type ; - + typedef geom_base_3d < real_type , iptr_type > base_type ; - - typedef typename + + typedef typename base_type::line_type line_type ; - typedef typename + typedef typename base_type::ball_type ball_type ; - - - class node_type: public tria_complex_node_2 + + + class node_type: public mesh_complex_node_2 { /*------------------------------------ loc. node type */ - public : + public : iptr_type _itag ; char_type _fdim ; char_type _feat ; char_type _topo ; - + public : /*------------------------------------ "write" access */ __inline_call iptr_type& itag ( @@ -124,18 +124,18 @@ ) const { return this->_topo ; } - + } ; - - class edge_type: public tria_complex_edge_2 + + class edge_type: public mesh_complex_edge_2 { /*------------------------------------ loc. edge type */ public : iptr_type _itag ; - + char_type _feat ; char_type _topo ; - + public : /*------------------------------------ "write" access */ __inline_call iptr_type& itag ( @@ -163,16 +163,16 @@ ) const { return this->_feat ; } - + } ; - + class part_data { /*------------------------------------ loc. part type */ public : containers::fixed_array < iptr_type, + 3 > _ints ; - + public : /*------------------------------------ "write" access */ __inline_call iptr_type& itag ( @@ -200,12 +200,12 @@ ) const { return this->_ints[2] ; } - + } ; #define __hashscal \ sizeof(iptr_type)/sizeof(uint32_t) - + class part_hash { public : @@ -215,11 +215,11 @@ { /*------------------------------- hash for part index */ return hash::hashword ( - (uint32_t*)&_pdat._ints[+0], + (uint32_t*)&_pdat._ints[+0], +3 * __hashscal, +137) ; } } ; - + class part_same { public : @@ -229,18 +229,18 @@ ) const { /*------------------------------- "equal-to" for part */ - return _idat.itag() == + return _idat.itag() == _jdat.itag() && - _idat.indx() == + _idat.indx() == _jdat.indx() && - _idat.kind() == + _idat.kind() == _jdat.kind() ; } } ; - + #undef __hashscal - iptr_type static + iptr_type static constexpr pool_byte_size = 96 * 1024 ; typedef allocators::_pool_alloc < @@ -250,28 +250,28 @@ pool_base > pool_wrap ; typedef containers::hash_table < - part_data , - part_hash , + part_data , + part_hash , part_same , pool_wrap > part_list ; - - typedef typename + + typedef typename part_list::item_type part_item ; - - iptr_type static constexpr + + iptr_type static constexpr part_bytes = sizeof (part_item); typedef containers::array < iptr_type , allocator > iptr_list ; - + typedef containers::fixed_array < real_type , 2 > bbox_bnds ; - + typedef containers::array < bbox_bnds , allocator > bbox_list ; - + typedef mesh::tria_complex_1< node_type , edge_type , @@ -281,10 +281,10 @@ tree_node ; typedef geom_tree::aabb_item_rect_k < - real_type , + float , iptr_type , node_type::_dims> tree_item ; - + typedef geom_tree::aabb_tree< tree_item , node_type::_dims, @@ -292,38 +292,38 @@ allocator > tree_type ; iptr_type static constexpr _nbox = 4 ; - + public : - + pool_base _pool ; - + part_list _part ; iptr_list _ptag ; - + bbox_list _pmin ; bbox_list _pmax ; - + bbox_bnds _bmin ; bbox_bnds _bmax ; mesh_type _tria ; tree_type _ebox ; - + public : - + /* -------------------------------------------------------- * construct geometry from alloc. etc. -------------------------------------------------------- */ - + __normal_call geom_mesh_euclidean_2d ( allocator const& - _asrc = allocator () + _asrc = allocator () ) : _pool(part_bytes) , - _part(part_hash() , - part_same() , + _part(part_hash() , + part_same() , .8, (pool_wrap(&_pool))) , _ptag( _asrc ) , _pmin( _asrc ) , @@ -332,13 +332,13 @@ _ebox( _asrc ) { } - + /* -------------------------------------------------------- * HAVE-FEAT: TRUE if has k-dim. FEAT. -------------------------------------------------------- - */ - + */ + __inline_call bool_type have_feat ( iptr_type _fdim ) @@ -348,13 +348,13 @@ else return ( false ) ; } - + /* -------------------------------------------------------- * NODE-FEAT: calc. node feature type. -------------------------------------------------------- */ - + template < typename list_type , typename geom_opts @@ -367,28 +367,28 @@ geom_opts &_opts ) { - real_type _DtoR = + real_type _DtoR = (real_type) +3.1415926536 / 180. ; - - real_type _ZERO = -1. + + + real_type _ZERO = -1. + std::numeric_limits ::epsilon(); - - real_type _phi1 = + + real_type _phi1 = (real_type)+180. - _opts.phi1(); - real_type _eta1 = + real_type _eta1 = (real_type)+ 0. + _opts.eta1(); - - real_type _hard = + + real_type _hard = std::cos( _phi1 * _DtoR) ; - real_type _soft = + real_type _soft = std::cos( _eta1 * _DtoR) ; - + __unreferenced(_node) ; - + _feat = null_feat ; _topo = (char_type)_aset.count(); - + for (auto _ipos = _aset.head() ; _ipos != _aset.tend() ; ++_ipos ) @@ -400,13 +400,13 @@ { iptr_type _iedg = * _ipos ; iptr_type _jedg = * _jpos ; - + iptr_type _inod[2] ; _inod[0] = this->_tria. _set2[_iedg]. node(0) ; _inod[1] = this->_tria. _set2[_iedg]. node(1) ; - + iptr_type _jnod[2] ; _jnod[0] = this->_tria. _set2[_jedg]. node(0) ; @@ -420,7 +420,7 @@ &this->_tria. _set1[ _inod[1]].pval(0) , _ivec) ; - + real_type _jvec[2] ; geometry::vector_2d( &this->_tria. @@ -428,30 +428,30 @@ &this->_tria. _set1[ _jnod[1]].pval(0) , _jvec) ; - - real_type _acos = + + real_type _acos = geometry::cosine_2d( _ivec , _jvec) ; - + if (_inod[0] == _jnod[1] || _inod[1] == _jnod[0] ) _acos *= (real_type)+1.; else _acos *= (real_type)-1.; - + if (_acos >= _ZERO) { if (_acos <= _hard) { - _feat = + _feat = std::max(_feat, hard_feat) ; } else if (_acos <= _soft) - { - _feat = + { + _feat = std::max(_feat, soft_feat) ; - } + } } else { @@ -459,13 +459,13 @@ { _topo -= _tbad--; } - } - } - } + } + } + } { if (_topo != + 0 ) if (_topo != + 2 ) - _feat = + _feat = std::max(_feat, soft_feat) ; } } @@ -475,7 +475,7 @@ * FIND-FEAT: scan geometry and find features. -------------------------------------------------------- */ - + template < typename geom_opts > @@ -484,11 +484,11 @@ ) { containers::array _eadj ; - + /*---------------------------------- init. geom feat. */ - for (auto _iter = + for (auto _iter = this->_tria._set1.head() ; - _iter != + _iter != this->_tria._set1.tend() ; ++_iter ) { @@ -499,10 +499,10 @@ _iter->topo () = +2 ; } } - - for (auto _iter = + + for (auto _iter = this->_tria._set2.head() ; - _iter != + _iter != this->_tria._set2.tend() ; ++_iter ) { @@ -512,11 +512,11 @@ _iter->topo () = +2 ; } } - + /*---------------------------------- find sharp feat. */ - for (auto _iter = + for (auto _iter = this->_tria._set1.head() ; - _iter != + _iter != this->_tria._set1.tend() ; ++_iter ) { @@ -528,31 +528,31 @@ { /*---------------------------------- set geo.-defined */ _eadj.set_count (0); - + this->_tria.node_edge ( &_iter->node (0), _eadj) ; - + node_feat ( - &_iter->node (0), + &_iter->node (0), _eadj , _iter->feat () , - _iter->topo () , + _iter->topo () , _opts ) ; - + if (_iter->itag() <= -1) { /*---------------------------------- set user-defined */ - _iter->feat () = - std::max(_iter->feat () , + _iter->feat () = + std::max(_iter->feat () , soft_feat) ; } } } } - - for (auto _iter = + + for (auto _iter = this->_tria._set2.head() ; - _iter != + _iter != this->_tria._set2.tend() ; ++_iter ) { @@ -565,16 +565,16 @@ _iter->node(1)].fdim() = 1 ; } } - - for (auto _iter = + + for (auto _iter = this->_tria._set1.head() ; - _iter != + _iter != this->_tria._set1.tend() ; ++_iter ) { if (_iter->mark() >= +0) { - if (_iter->feat() != + if (_iter->feat() != mesh::null_feat) { /*----------------------------- assign nodes to feat. */ @@ -583,13 +583,13 @@ } } } - + /* -------------------------------------------------------- * INIT-PART: init. enclosed PART within geom. -------------------------------------------------------- */ - + template < typename geom_opts > @@ -598,166 +598,166 @@ ) { containers::array < - typename + typename iptr_list::size_type> _mark ; __unreferenced (_opts) ; - + /*----------------------------- extrema for PART id's */ - iptr_type _imin = + iptr_type _imin = +std::numeric_limits ::infinity() ; - iptr_type _imax = + iptr_type _imax = -std::numeric_limits ::infinity() ; - - for (auto _iter = - this->_part._lptr.head() ; - _iter != + + for (auto _iter = + this->_part._lptr.head() ; + _iter != this->_part._lptr.tend() ; ++_iter ) { typename part_list ::item_type*_next =*_iter; - - for ( ; _next != nullptr ; + + for ( ; _next != nullptr ; _next = _next->_next) { - iptr_type _ppos = + iptr_type _ppos = _next->_data.itag() ; - - _imin = std::min(_imin, + + _imin = std::min(_imin, _ppos) ; - _imax = std::max(_imax, + _imax = std::max(_imax, _ppos) ; } } - + if (_imin < (iptr_type) +0 && _imax < (iptr_type) +0 ) - __assert( _imin >= +0 && + __assert( _imin >= +0 && "GEOM::INIT-PART: -ve part index!") ; - + /*----------------------------- push unique PART id's */ - auto _flag = + auto _flag = std::numeric_limits < - typename + typename iptr_list::size_type>::max(); - - _mark.set_count(_imax+1, + + _mark.set_count(_imax+1, containers::tight_alloc, _flag) ; - - for (auto _iter = - this->_part._lptr.head() ; - _iter != + + for (auto _iter = + this->_part._lptr.head() ; + _iter != this->_part._lptr.tend() ; ++_iter ) { typename part_list ::item_type*_next =*_iter; - - for ( ; _next != nullptr ; + + for ( ; _next != nullptr ; _next = _next->_next) { - iptr_type _ppos = + iptr_type _ppos = _next->_data.itag() ; if (_mark[_ppos] == _flag) { - _mark[_ppos] = + _mark[_ppos] = this-> _ptag.push_tail(_ppos) ; } } } - + /*----------------------------- init. aabb's for PART */ this->_pmin.set_count ( - this->_ptag.count(), + this->_ptag.count(), containers::tight_alloc, _bmax) ; - + this->_pmax.set_count ( - this->_ptag.count(), + this->_ptag.count(), containers::tight_alloc, _bmin) ; - - for (auto _iter = - this->_part._lptr.head() ; - _iter != + + for (auto _iter = + this->_part._lptr.head() ; + _iter != this->_part._lptr.tend() ; ++_iter ) { typename part_list ::item_type*_next =*_iter; - - for ( ; _next != nullptr ; + + for ( ; _next != nullptr ; _next = _next->_next) { - iptr_type _ppos = + iptr_type _ppos = _next->_data.itag () ; - iptr_type _cell = + iptr_type _cell = _next->_data.indx () ; - iptr_type _kind = + iptr_type _kind = _next->_data.kind () ; - + if (_kind == EDGE2_tag) { - /*----------------------------- expand aabb via EDGE2 */ + /*----------------------------- expand aabb via EDGE2 */ auto _inod = this-> _tria._set2[_cell].node(0); auto _jnod = this-> _tria._set2[_cell].node(1); - + auto _iptr = &this-> _tria._set1[_inod]; auto _jptr = &this-> _tria._set1[_jnod]; - - real_type _xmin = + + real_type _xmin = std::min (_iptr->pval(0) , - _jptr->pval(0) + _jptr->pval(0) ) ; - real_type _ymin = + real_type _ymin = std::min (_iptr->pval(1) , - _jptr->pval(1) + _jptr->pval(1) ) ; - - real_type _xmax = + + real_type _xmax = std::max (_iptr->pval(0) , - _jptr->pval(0) + _jptr->pval(0) ) ; - real_type _ymax = + real_type _ymax = std::max (_iptr->pval(1) , - _jptr->pval(1) + _jptr->pval(1) ) ; - + auto _pmap = _mark[_ppos]; - this-> _pmin[_pmap][ 0] = + this-> _pmin[_pmap][ 0] = std::min(_xmin, this-> _pmin[_pmap][ 0]) ; - this-> _pmin[_pmap][ 1] = + this-> _pmin[_pmap][ 1] = std::min(_ymin, this-> _pmin[_pmap][ 1]) ; - - this-> _pmax[_pmap][ 0] = + + this-> _pmax[_pmap][ 0] = std::max(_xmax, this-> _pmax[_pmap][ 0]) ; - this-> _pmax[_pmap][ 1] = + this-> _pmax[_pmap][ 1] = std::max(_ymax, this-> _pmax[_pmap][ 1]) ; - + } } } - + } - + /* -------------------------------------------------------- * INIT-GEOM: init. geometry data structures. -------------------------------------------------------- */ - + template < typename geom_opts > @@ -769,28 +769,28 @@ { /*---------------- TRUE if tree should index edge */ public : - __inline_call + __inline_call bool_type operator () ( edge_type const& _edat ) const { return _edat.mark() >= 0 ; } } ; - + /*----------------------------- init. aabb at -+ inf. */ for(auto _idim = 2; _idim-- != 0 ; ) { - this->_bmin[_idim] = + this->_bmin[_idim] = +std::numeric_limits< real_type>::infinity() ; - - this->_bmax[_idim] = + + this->_bmax[_idim] = -std::numeric_limits< real_type>::infinity() ; } - + /*----------------------------- calc. aabb for inputs */ - for (auto _iter = + for (auto _iter = this->_tria._set1.head() ; _iter != this->_tria._set1.tend() ; @@ -799,45 +799,47 @@ if (_iter->mark() >= +0 ) { this->_bmin[0] = std::min ( - this->_bmin[0] , + this->_bmin[0] , _iter->pval(0) ) ; this->_bmin[1] = std::min ( - this->_bmin[1] , + this->_bmin[1] , _iter->pval(1) ) ; - + this->_bmax[0] = std::max ( - this->_bmax[0] , + this->_bmax[0] , _iter->pval(0) ) ; this->_bmax[1] = std::max ( - this->_bmax[1] , + this->_bmax[1] , _iter->pval(1) ) ; } } - - real_type static const _RTOL = + + float static const _RTOL = std::pow ( - std::numeric_limits - ::epsilon(),(real_type).8) ; - - real_type _BTOL[2] ; - _BTOL[0] =( this->_bmax[ 0] - + std::numeric_limits + ::epsilon(), (float)+.75) ; + + float _BTOL[2] ; + _BTOL[0] = + (float) ( this->_bmax[ 0] - this->_bmin[ 0] ) * _RTOL ; - _BTOL[1] =( this->_bmax[ 1] - - this->_bmin[ 1] ) + _BTOL[1] = + (float) ( this->_bmax[ 1] - + this->_bmin[ 1] ) * _RTOL ; - - /*-------------------- find sharp "features" in geom. */ + + /*-------------------- find sharp "features" in geom. */ find_feat (_opts); - + /*-------------------- indexes for PART def. in geom. */ init_part (_opts); - + /*-------------------- make aabb-tree and init. bbox. */ - aabb_mesh(this->_tria._set1, - this->_tria._set2, + aabb_mesh(this->_tria._set1, + this->_tria._set2, this->_ebox, - _BTOL,this->_nbox, edge_pred () + _BTOL,this->_nbox, edge_pred () ) ; } @@ -846,7 +848,7 @@ * SEED-FEAT: setup initial node set. -------------------------------------------------------- */ - + template < typename mesh_type , typename geom_opts @@ -859,9 +861,9 @@ __unreferenced(_opts) ; /*------------------------- push set of feature nodes */ - for (auto _iter = + for (auto _iter = this->_tria._set1.head() ; - _iter != + _iter != this->_tria._set1.tend() ; ++_iter ) { @@ -875,19 +877,19 @@ &_iter->pval(0), _node)) { _mesh._tria.node - (_node)->fdim() + (_node)->fdim() = _iter->fdim() ; - + _mesh._tria.node - (_node)->feat() + (_node)->feat() = _iter->feat() ; - + _mesh._tria.node - (_node)->topo() + (_node)->topo() = _iter->topo() ; - + _mesh._tria.node - (_node)->part() + (_node)->part() = _iter->itag() ; } } @@ -900,32 +902,32 @@ &_iter->pval(0), _node)) { _mesh._tria.node - (_node)->fdim() + (_node)->fdim() = _iter->fdim() ; - + _mesh._tria.node - (_node)->feat() + (_node)->feat() = _iter->feat() ; - + _mesh._tria.node - (_node)->topo() + (_node)->topo() = _iter->topo() ; - + _mesh._tria.node - (_node)->part() + (_node)->part() = _iter->itag() ; } } } } } - + /* -------------------------------------------------------- * SEED-MESH: setup initial node set. -------------------------------------------------------- */ - + template < typename mesh_type , typename geom_opts @@ -934,41 +936,41 @@ mesh_type &_mesh , geom_opts &_opts ) - { + { /*------------------------- well-distributed sampling */ - while (_mesh._tria._nset.count() + while (_mesh._tria._nset.count() < (std::size_t)_opts.seed() + 3) { typename geom_type:: mesh_type:: node_list::_write_it _best; - + real_type _dmax = (real_type) +.0 ; char_type _fdim ; - + for (_fdim = 1; _fdim != 3; ++_fdim) { - for (auto _ipos = + for (auto _ipos = this->_tria._set1.head() ; - _ipos != + _ipos != this->_tria._set1.tend() ; ++_ipos ) { - if (_ipos->mark() >= 0 && + if (_ipos->mark() >= 0 && _ipos->fdim () == _fdim) { - real_type _dmin = + real_type _dmin = +std::numeric_limits::infinity() ; - for (auto _jpos = + for (auto _jpos = _mesh._tria._nset.head() ; - _jpos != + _jpos != _mesh._tria._nset.tend() ; ++_jpos ) { - real_type _dist = + real_type _dist = geometry::lensqr_2d( - &_ipos->pval(+0), + &_ipos->pval(+0), &_jpos->pval(+0)) ; _dmin = std::min(_dmin, _dist); @@ -983,8 +985,8 @@ } if (_dmax > (real_type)0.) break ; } - - if (_dmax > (real_type)0.) + + if (_dmax > (real_type)0.) { /*------------------------- add current furthest node */ iptr_type _node = -1; @@ -992,20 +994,20 @@ &_best->pval(0), _node) ) { _mesh._tria.node - (_node)->fdim() + (_node)->fdim() = _best->fdim() ; - + _mesh._tria.node - (_node)->feat() + (_node)->feat() = _best->feat() ; - + _mesh._tria.node - (_node)->topo() - = _best->topo() ; + (_node)->topo() + = _best->topo() ; } } else break ; - } + } } /* @@ -1013,7 +1015,7 @@ * HELPERS: predicates for intersection tests. -------------------------------------------------------- */ - + template < typename hits_func > @@ -1023,28 +1025,28 @@ public : real_type _ipos[2] ; real_type _jpos[2] ; - + geom_type &_geom ; - + hits_func &_hfun ; - - bool_type _find ; + + bool_type _find ; iptr_type _hnum ; - + bool_type _exct ; - + geometry:: hits_type _hits ; - + iptr_type _part ; - + public : line_line_pred operator = ( - line_line_pred & + line_line_pred & ) = delete ; line_line_pred operator = ( - line_line_pred&& + line_line_pred&& ) = delete ; public : @@ -1055,73 +1057,73 @@ geom_type &_gsrc , hits_func &_hsrc , iptr_type _psrc = -1 - ) : _geom( _gsrc), + ) : _geom( _gsrc), _hfun( _hsrc) { - this->_hits = + this->_hits = geometry ::null_hits ; - + this->_ipos[0] = _isrc[0]; this->_ipos[1] = _isrc[1]; - + this->_jpos[0] = _jsrc[0]; this->_jpos[1] = _jsrc[1]; - + this->_part = _psrc ; - + this->_exct = false ; - + this->_hnum = + 0 ; this->_find = false ; } - /*----------------------- TRUE if PART is within list */ + /*----------------------- TRUE if PART is within list */ __inline_call bool_type have_part ( iptr_type _epos ) { typename geom_type ::part_list::item_type *_same ; - + typename geom_type ::part_list::data_type _temp ; _temp.itag() = _part ; _temp.indx() = _epos ; - _temp.kind() = + _temp.kind() = mesh:: EDGE2_tag ; - + return this-> _geom._part.find(_temp, _same); } /*----------------------- all intersection about node */ __normal_call void_type operator() ( - typename + typename tree_type::item_data *_iptr ) { - for ( ; _iptr != nullptr; + for ( ; _iptr != nullptr; _iptr = _iptr->_next ) { - geometry::hits_type - _hits = geometry::null_hits; - + geometry::hits_type + _HITS = geometry::null_hits; + /*--------------- line-line intersection test */ - iptr_type _epos = + iptr_type _epos = _iptr->_data.ipos() ; - - if (this->_part >= +0 - && !have_part(_epos) ) + + if (this->_part >= +0 + && !have_part(_epos) ) continue ; - + iptr_type _enod[2]; _enod[0] =_geom. _tria._set2[_epos].node(0) ; _enod[1] =_geom. _tria._set2[_epos].node(1) ; - + real_type _xpos[2]; - _hits = + _HITS = geometry::line_line_2d ( - & this->_ipos[0], + & this->_ipos[0], & this->_jpos[0], &_geom ._tria. _set1 [_enod[0]].pval(0), @@ -1129,30 +1131,30 @@ _set1 [_enod[1]].pval(0), _xpos, true, 2 ) ; - if(_hits != geometry::null_hits) + if(_HITS != geometry::null_hits) { /*--------------- call output function on hit */ - this->_hfun (_xpos, _hits , + this->_hfun (_xpos, _HITS , _geom._tria . _set2[_epos].feat() , _geom._tria . _set2[_epos].topo() , _geom._tria . _set2[_epos].itag() ) ; - + this->_hnum+= +1 ; - + this->_find = true ; - this->_hits =_hits ; - - if (_hits != geometry::edge_hits) + this->_hits =_HITS ; + + if (_HITS != geometry::edge_hits) this->_exct = true ; } } } - + } ; - + template < typename hits_func > @@ -1162,78 +1164,78 @@ public : real_type _ball[2] ; real_type _rsiz ; - + geom_type &_geom ; - + hits_func &_hfun ; - + geometry:: hits_type _hits ; - - bool_type _find ; + + bool_type _find ; iptr_type _hnum ; - + public : ball_line_pred operator = ( - ball_line_pred & + ball_line_pred & ) = delete ; ball_line_pred operator = ( - ball_line_pred&& + ball_line_pred&& ) = delete ; public : /*------------------------------ construct from _src. */ __normal_call ball_line_pred ( real_type *_cmid , - real_type _rsiz , + real_type _rsrc , geom_type &_gsrc , hits_func &_hsrc - ) : _geom( _gsrc), + ) : _geom( _gsrc), _hfun( _hsrc) { this->_hits = geometry ::null_hits ; - + this->_ball[0] = _cmid[0]; this->_ball[1] = _cmid[1]; - + this->_find = false ; this->_hnum = + 0 ; - - this->_rsiz = _rsiz ; + + this->_rsiz = _rsrc ; } /*----------------------- all intersection about node */ __normal_call void_type operator() ( - typename + typename tree_type::item_data*_iptr ) { - for ( ; _iptr != nullptr; + for ( ; _iptr != nullptr; _iptr = _iptr->_next ) { - geometry::hits_type _hits = + geometry::hits_type _HITS = geometry::face_hits ; - + /*--------------- ball_line intersection test */ - iptr_type _epos = + iptr_type _epos = _iptr->_data.ipos() ; - + iptr_type _enod[2]; _enod[0] =_geom. _tria._set2[_epos].node(0) ; _enod[1] =_geom. _tria._set2[_epos].node(1) ; - + real_type _ipos[2]; real_type _jpos[2]; - size_t _nhit = + size_t _nhit = geometry::ball_line_2d ( - this->_ball, - this->_rsiz, + this->_ball, + this->_rsiz, &_geom ._tria. _set1 [_enod[0]].pval(0) , &_geom ._tria. - _set1 [_enod[1]].pval(0) , + _set1 [_enod[1]].pval(0) , _ipos, _jpos ) ; switch (_nhit) @@ -1241,45 +1243,141 @@ case +2 : { /*--------------- call output function on hit */ - this->_hfun (_jpos, _hits , + this->_hfun (_jpos, _HITS , _geom._tria . _set2[_epos].feat() , _geom._tria . _set2[_epos].topo() , _geom._tria . _set2[_epos].itag() ) ; - + this->_hnum += +1; } // falls through - + case +1 : { /*--------------- call output function on hit */ - this->_hfun (_ipos, _hits , + this->_hfun (_ipos, _HITS , _geom._tria . _set2[_epos].feat() , _geom._tria . _set2[_epos].topo() , _geom._tria . _set2[_epos].itag() ) ; - + this->_hnum += +1; - + this->_find = true ; - this->_hits =_hits ; + this->_hits =_HITS ; } // falls through } } } - + } ; - + + class near_edge_pred + { + /*------------------ node-edge "projection" predicate */ + public : + real_type *_ppos ; + real_type *_qpos ; + + real_type _dsqr ; + real_type _dtol ; + + mesh_type *_mesh ; + + bool_type _find ; + iptr_type _epos ; + + public : + + /*------------------------ make a tree-edge predicate */ + __inline_call near_edge_pred( + real_type*_psrc = nullptr , + real_type*_qsrc = nullptr , + mesh_type*_msrc = nullptr , + real_type _near = + (real_type) +0. + ) : _ppos(_psrc) , + _qpos(_qsrc) , + _dsqr(+std::numeric_limits + ::infinity () ) , + _dtol(_near) , + _mesh(_msrc) , + _find(false) , + _epos( -1) { } + + /*------------------------ call pred. on tree matches */ + __inline_call float operator () ( + typename + tree_type::item_data *_iptr + ) + { + if (this->_find) return +0. ; + + real_type _qtmp[+2] = {+0.}; + + for ( ; _iptr != nullptr; + _iptr = _iptr->_next ) + { + geometry::hits_type + _HITS = geometry::null_hits; + + iptr_type _EPOS = + _iptr->_data.ipos() ; + + iptr_type _enod[+2] = { + this->_mesh-> + _set2 [_EPOS ].node(0) , + this->_mesh-> + _set2 [_EPOS ].node(1) , + } ; + + if (geometry::proj_line_2d ( + _ppos, + &this->_mesh-> + _set1 [_enod[0]].pval(0) , + &this->_mesh-> + _set1 [_enod[1]].pval(0) , + _qtmp, _HITS) ) + { + if (_HITS != + geometry::null_hits) + { + /*-------------------- projected match: keep best */ + real_type _dtmp = + geometry::lensqr_2d(_ppos,_qtmp) ; + + if (_dtmp<_dsqr ) + { + _qpos[0] = _qtmp[0] ; + _qpos[1] = _qtmp[1] ; + + this->_find = + this->_dtol * + this->_dtol > _dtmp ; + + this->_dsqr = _dtmp ; + this->_epos = _EPOS ; + } + + } + } + } + + return ( (float)this->_dsqr ) ; + } + + } ; + /* -------------------------------------------------------- * INTERSECT: compute ball-edge intersections. -------------------------------------------------------- */ - + template < typename hits_func > @@ -1289,20 +1387,27 @@ ) { /*------------------ tree-circ intersection predicate */ - typedef + typedef geom_tree::aabb_pred_ball_2 < - real_type, - iptr_type > tree_pred ; - + float , + iptr_type > tree_pred ; + /*------------------ ball-line intersection predicate */ - typedef + typedef ball_line_pred < hits_func > hits_pred ; - /*------------------ call actual intersection testing */ - tree_pred _pred(_ball. _pmid, - _ball. _rrad) ; - hits_pred _func(_ball. _pmid, + float _PMID[2] = { + (float) _ball. _pmid[0] , + (float) _ball. _pmid[1] , + } ; + + float _RRAD = + (float) _ball. _rrad; + + /*------------------ call actual intersection testing */ + tree_pred _pred(_PMID, _RRAD) ; + hits_pred _func(_ball. _pmid, _ball. _rrad, *this, _hfun) ; @@ -1317,7 +1422,7 @@ * INTERSECT: compute line-edge intersections. -------------------------------------------------------- */ - + template < typename hits_func > @@ -1327,21 +1432,30 @@ ) { /*------------------ tree-line intersection predicate */ - typedef + typedef geom_tree::aabb_pred_line_2 < - real_type, - iptr_type > tree_pred ; + float , + iptr_type > tree_pred ; /*------------------ tria-line intersection predicate */ - typedef + typedef line_line_pred < - hits_func > hits_pred ; + hits_func > hits_pred ; - /*------------------ call actual intersection testing */ - tree_pred _pred(_line. _ipos, - _line. _jpos) ; - hits_pred _func(_line. _ipos, - _line. _jpos, + float _IPOS[2] = { + (float) _line. _ipos[0] , + (float) _line. _ipos[1] , + } ; + + float _JPOS[2] = { + (float) _line. _jpos[0] , + (float) _line. _jpos[1] , + } ; + + /*------------------ call actual intersection testing */ + tree_pred _pred(_IPOS, _JPOS) ; + hits_pred _func(_line. _ipos, + _line. _jpos, *this, _hfun) ; this->_ebox.find(_pred,_func) ; @@ -1349,13 +1463,13 @@ /*------------------ _TRUE if any intersections found */ return ( _func._find ) ; } - + /* -------------------------------------------------------- * IS-INSIDE: TRUE if point is "inside" geometry. -------------------------------------------------------- - */ - + */ + class null_pred { /*--------------------------- NULL hits for IS-INSIDE */ @@ -1365,8 +1479,8 @@ char_type _hits, char_type _feat, char_type _topo, - iptr_type _itag - ) + iptr_type _itag + ) { __unreferenced( _ppos) ; __unreferenced( _hits) ; @@ -1375,37 +1489,37 @@ __unreferenced( _itag) ; } } ; - + __normal_call iptr_type is_inside ( real_type *_ppos ) { - /*--------------------------- calc. axis-aligned dir. */ + /*--------------------------- calc. axis-aligned dir. */ iptr_type _vdim = (iptr_type)+0; iptr_type _sign = (iptr_type)+0; - - real_type _vlen = + + real_type _vlen = -std::numeric_limits ::infinity(); - real_type _near = + real_type _near = +std::numeric_limits ::infinity(); for(auto _idim = +2; _idim-- != +0; ) { - real_type _blen = - _bmax[_idim] - + real_type _blen = + _bmax[_idim] - _bmin[_idim] ; - - _vlen = + + _vlen = std::max (_vlen, _blen) ; - + /*------------------------------ distance to bbox */ - real_type _dmin = - _ppos[_idim] - + real_type _dmin = + _ppos[_idim] - _bmin[_idim] ; - real_type _dmax = - _ppos[_idim] - + real_type _dmax = + _ppos[_idim] - _bmax[_idim] ; _dmin = std::abs(_dmin) ; @@ -1431,43 +1545,43 @@ /*--------------------------- calc. "is-inside" state */ if (this->_ptag.empty() ) { - + /*--------------------------- null PART specification */ - + if (_ppos[0] < this->_bmin[0] || _ppos[1] < this->_bmin[1] ) return (iptr_type) -1 ; - + if (_ppos[0] > this->_bmax[0] || _ppos[1] > this->_bmax[1] ) return (iptr_type) -1 ; - + for(auto _iter = +0; _iter++ != +8; ) { real_type _rvec[ 3] ; _rvec[0] = (real_type)+.0 ; _rvec[1] = (real_type)+.0 ; - + /*----------------------- linear search direction */ - _rvec[_vdim] = _sign * + _rvec[_vdim] = _sign * _vlen ; if (_iter > +1) { /*----------------------- random search direction */ - _rvec[0] = + _rvec[0] = ((real_type)std::rand()) / RAND_MAX ; - _rvec[1] = + _rvec[1] = ((real_type)std::rand()) / RAND_MAX ; - + _rvec[0]-= (real_type)+.5 ; _rvec[1]-= (real_type)+.5 ; - - _rvec[2] = + + _rvec[2] = geometry::length_2d(_rvec); - _rvec[0]*= + _rvec[0]*= _vlen /_rvec[ +2] ; - _rvec[1]*= + _rvec[1]*= _vlen /_rvec[ +2] ; } @@ -1476,81 +1590,91 @@ _ppos[1] + _rvec[ +1] } ; /*-------------- tree-line intersection predicate */ - typedef + typedef geom_tree::aabb_pred_line_2 < - real_type, - iptr_type > tree_pred ; + float , + iptr_type > tree_pred ; /*-------------- tria-line intersection predicate */ - typedef + typedef line_line_pred < null_pred > hits_pred ; - tree_pred _pred(_ppos, _rpos) ; - + float _PPOS[2] = { + (float) _ppos[0] , + (float) _ppos[1] , + } ; + + float _RPOS[2] = { + (float) _rpos[0] , + (float) _rpos[1] , + } ; + + tree_pred _pred(_PPOS, _RPOS) ; + null_pred _hfun; - hits_pred _func(_ppos, _rpos, + hits_pred _func(_ppos, _rpos, *this, _hfun) ; this->_ebox.find(_pred,_func) ; if (_func._exct) continue ; - + /*-------------- done if inside - odd no. crosses */ if((_func._hnum % 2) != +0) { return ( (iptr_type) +0 ) ; } } - + } else { - + /*--------------------------- have PART specification */ - - for(auto _pnum = this->_ptag.count(); + + for(auto _pnum = this->_ptag.count(); _pnum-- != +0; ) - { - - if (_ppos[0] < + { + + if (_ppos[0] < this->_pmin[_pnum][0] || - _ppos[1] < + _ppos[1] < this->_pmin[_pnum][1] ) continue ; - - if (_ppos[0] > + + if (_ppos[0] > this->_pmax[_pnum][0] || - _ppos[1] > + _ppos[1] > this->_pmax[_pnum][1] ) continue ; - + for(auto _iter = +0; _iter++ != +8; ) { real_type _rvec[ 3] ; _rvec[0] = (real_type)+.0 ; _rvec[1] = (real_type)+.0 ; - + /*----------------------- linear search direction */ - _rvec[_vdim] = _sign * + _rvec[_vdim] = _sign * _vlen ; if (_iter > +1) { /*----------------------- random search direction */ - _rvec[0] = + _rvec[0] = ((real_type)std::rand()) / RAND_MAX ; - _rvec[1] = + _rvec[1] = ((real_type)std::rand()) / RAND_MAX ; - + _rvec[0]-= (real_type)+.5 ; _rvec[1]-= (real_type)+.5 ; - - _rvec[2] = + + _rvec[2] = geometry::length_2d(_rvec); - _rvec[0]*= + _rvec[0]*= _vlen /_rvec[ +2] ; - _rvec[1]*= + _rvec[1]*= _vlen /_rvec[ +2] ; } @@ -1559,27 +1683,37 @@ _ppos[1] + _rvec[ +1] } ; /*-------------- tree-line intersection predicate */ - typedef + typedef geom_tree::aabb_pred_line_2 < - real_type, - iptr_type > tree_pred ; + float , + iptr_type > tree_pred ; /*-------------- tria-line intersection predicate */ - typedef + typedef line_line_pred < null_pred > hits_pred ; - tree_pred _pred(_ppos, _rpos) ; - + float _PPOS[2] = { + (float) _ppos[0] , + (float) _ppos[1] , + } ; + + float _RPOS[2] = { + (float) _rpos[0] , + (float) _rpos[1] , + } ; + + tree_pred _pred(_PPOS, _RPOS) ; + null_pred _hfun; - hits_pred _func(_ppos, _rpos, + hits_pred _func(_ppos, _rpos, *this, _hfun, this->_ptag[_pnum]) ; this->_ebox.find(_pred,_func) ; if (_func._exct) continue ; - + /*-------------- done if inside - odd no. crosses */ if((_func._hnum % 2) != +0) { @@ -1587,17 +1721,68 @@ } } } - + } return ( (iptr_type) -1) ; } - } ; - - + /* + -------------------------------------------------------- + * PROJECTOR: project a point on to the geometry. + -------------------------------------------------------- + */ + + __normal_call void_type projector ( + real_type *_ppos , + iptr_type _idim , + real_type *_proj + ) + { + if (_idim == +1) + { + /*------------------ project to closest 1-dim feature */ + real_type _PROJ[2] = { + (real_type) _ppos[0] , + (real_type) _ppos[1] } ; + + float _PPOS[2] = { + (float) _ppos[0] , + (float) _ppos[1] } ; + + real_type static const _RTOL= + std::pow ( + std::numeric_limits + ::epsilon(), (real_type)+.75); + + real_type _BTOL = ( + this->_bmax[0] - + this->_bmin[0] + + this->_bmax[1] - + this->_bmin[1] ) * _RTOL; + + near_edge_pred _func ( _ppos, + _PROJ, &this-> _tria, + _BTOL) ; + + this->_ebox.near(_PPOS, _func) ; + + _proj[0] = _PROJ[0] ; + _proj[1] = _PROJ[1] ; + } + else + { + /*------------------ NULL projection -- return inputs */ + _proj[0] = _ppos[0] ; + _proj[1] = _ppos[1] ; + } } - + + } ; + + + } + # endif //__GEOM_MESH_EUCLIDEAN_2__ diff --git a/src/libcpp/geom_type/geom_mesh_euclidean_3.hpp b/src/libcpp/geom_type/geom_mesh_euclidean_3.hpp index 7280556..c1d5095 100644 --- a/src/libcpp/geom_type/geom_mesh_euclidean_3.hpp +++ b/src/libcpp/geom_type/geom_mesh_euclidean_3.hpp @@ -4,34 +4,34 @@ * GEOM-MESH-EUCLIDEAN-3: euclidean geom. in R^3. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 02 March, 2019 + * Last updated: 08 December, 2019 * * Copyright 2013-2019 * Darren Engwirda @@ -47,13 +47,13 @@ # define __GEOM_MESH_EUCLIDEAN_3__ namespace mesh { - + template < typename R , typename I , typename A = allocators::basic_alloc > - class geom_mesh_euclidean_3d : + class geom_mesh_euclidean_3d : public geom_base_3d { public : @@ -70,27 +70,27 @@ typedef geom_base_3d < real_type , iptr_type > base_type ; - - typedef typename + + typedef typename base_type::line_type line_type ; - typedef typename + typedef typename base_type::flat_type flat_type ; - typedef typename + typedef typename base_type::disc_type disc_type ; - typedef typename + typedef typename base_type::ball_type ball_type ; - class node_type: public tria_complex_node_3 + class node_type: public mesh_complex_node_3 { /*------------------------------------ loc. node type */ - public : + public : iptr_type _itag ; char_type _fdim ; char_type _feat ; char_type _topo ; - + public : /*------------------------------------ "write" access */ __inline_call iptr_type& itag ( @@ -126,18 +126,18 @@ ) const { return this->_topo ; } - + } ; - - class edge_type: public tria_complex_edge_2 + + class edge_type: public mesh_complex_edge_2 { /*------------------------------------ loc. edge type */ public : iptr_type _itag ; - + char_type _feat ; char_type _topo ; - + public : /*------------------------------------ "write" access */ __inline_call iptr_type& itag ( @@ -165,18 +165,18 @@ ) const { return this->_feat ; } - + } ; - - class tri3_type: public tria_complex_tria_3 + + class tri3_type: public mesh_complex_tria_3 { /*------------------------------------ loc. face type */ public : iptr_type _itag ; - + char_type _feat ; char_type _topo ; - + public : /*------------------------------------ "write" access */ __inline_call iptr_type& itag ( @@ -204,16 +204,16 @@ ) const { return this->_feat ; } - + } ; - + class part_data { /*------------------------------------ loc. part type */ public : containers::fixed_array < iptr_type, + 3 > _ints ; - + public : /*------------------------------------ "write" access */ __inline_call iptr_type& itag ( @@ -241,12 +241,12 @@ ) const { return this->_ints[2] ; } - + } ; - + #define __hashscal \ sizeof(iptr_type)/sizeof(uint32_t) - + class part_hash { public : @@ -256,11 +256,11 @@ { /*------------------------------- hash for part index */ return hash::hashword ( - (uint32_t*)&_pdat._ints[+0], + (uint32_t*)&_pdat._ints[+0], +3 * __hashscal, +137) ; } } ; - + class part_same { public : @@ -270,18 +270,18 @@ ) const { /*------------------------------- "equal-to" for part */ - return _idat.itag() == + return _idat.itag() == _jdat.itag() && - _idat.indx() == + _idat.indx() == _jdat.indx() && - _idat.kind() == + _idat.kind() == _jdat.kind() ; } } ; - + #undef __hashscal - - iptr_type static + + iptr_type static constexpr pool_byte_size = 96 * 1024 ; typedef allocators::_pool_alloc < @@ -291,28 +291,28 @@ pool_base > pool_wrap ; typedef containers::hash_table < - part_data , - part_hash , + part_data , + part_hash , part_same , pool_wrap > part_list ; - - typedef typename + + typedef typename part_list::item_type part_item ; - - iptr_type static constexpr + + iptr_type static constexpr part_bytes = sizeof (part_item); - + typedef containers::array < iptr_type , allocator > iptr_list ; - + typedef containers::fixed_array < real_type , 3 > bbox_bnds ; - + typedef containers::array < bbox_bnds , allocator > bbox_list ; - + typedef mesh::tria_complex_2< node_type, edge_type, @@ -323,7 +323,7 @@ tree_node ; typedef geom_tree::aabb_item_rect_k < - real_type, + float, iptr_type, node_type:: _dims > tree_item ; @@ -337,15 +337,15 @@ iptr_type static constexpr _nbox = 4 ; public : - + pool_base _pool ; - + part_list _part ; iptr_list _ptag ; - + bbox_list _pmin ; bbox_list _pmax ; - + bbox_bnds _bmin ; bbox_bnds _bmax ; @@ -355,19 +355,19 @@ tree_type _tbox ; public : - + /* -------------------------------------------------------- * construct geometry from alloc. etc. -------------------------------------------------------- */ - + __normal_call geom_mesh_euclidean_3d ( allocator const& - _asrc = allocator () + _asrc = allocator () ) : _pool(part_bytes) , - _part(part_hash() , - part_same() , + _part(part_hash() , + part_same() , .8, (pool_wrap(&_pool))) , _ptag( _asrc ) , _pmin( _asrc ) , @@ -377,13 +377,13 @@ _tbox( _asrc ) { } - + /* -------------------------------------------------------- * HAVE-FEAT: TRUE if has k-dim. FEAT. -------------------------------------------------------- - */ - + */ + __inline_call bool_type have_feat ( iptr_type _fdim ) @@ -396,13 +396,13 @@ else return ( false ) ; } - + /* -------------------------------------------------------- * NODE-FEAT: calc. node feature type. -------------------------------------------------------- */ - + template < typename list_type > @@ -415,17 +415,17 @@ _iter != _lsrc.tend() ; ++_iter ) { - auto _feat = + auto _feat = this-> _tria._set2[ *_iter].feat() ; - + if (_feat != null_feat) { _ldst.push_tail(*_iter) ; } } } - + template < typename list_type , typename geom_opts @@ -438,25 +438,25 @@ geom_opts &_opts ) { - real_type _DtoR = + real_type _DtoR = (real_type) +3.1415926536 / 180.0; - real_type _ZERO = -1. + + real_type _ZERO = -1. + std::numeric_limits ::epsilon(); - - real_type _phi1 = + + real_type _phi1 = (real_type)+180. - _opts.phi1(); - real_type _eta1 = + real_type _eta1 = (real_type)+ 0. + _opts.eta1(); - - real_type _hard = + + real_type _hard = std::cos( _phi1 * _DtoR) ; - real_type _soft = + real_type _soft = std::cos( _eta1 * _DtoR) ; - + __unreferenced(_node) ; - + _feat = null_feat ; _topo = (char_type)_aset.count(); @@ -471,13 +471,13 @@ { iptr_type _iedg = * _ipos ; iptr_type _jedg = * _jpos ; - + iptr_type _inod[2] ; _inod[0] = this->_tria. _set2[_iedg]. node(0) ; _inod[1] = this->_tria. _set2[_iedg]. node(1) ; - + iptr_type _jnod[2] ; _jnod[0] = this->_tria. _set2[_jedg]. node(0) ; @@ -491,7 +491,7 @@ &this->_tria. _set1[ _inod[1]].pval(0) , _ivec) ; - + real_type _jvec[3] ; geometry::vector_3d( &this->_tria. @@ -499,28 +499,28 @@ &this->_tria. _set1[ _jnod[1]].pval(0) , _jvec) ; - - real_type _acos = + + real_type _acos = geometry::cosine_3d( _ivec , _jvec) ; - + if (_inod[0] == _jnod[1] || _inod[1] == _jnod[0] ) _acos *= (real_type)+1.; else _acos *= (real_type)-1.; - + if (_acos >= _ZERO) { if (_acos <= _hard) { - _feat = + _feat = std::max(_feat, hard_feat) ; } else if (_acos <= _soft) - { - _feat = + { + _feat = std::max(_feat, soft_feat) ; } } @@ -530,17 +530,17 @@ { _topo -= _tbad--; } - } + } } } { if (_topo != + 0 ) if (_topo != + 2 ) - _feat = + _feat = std::max(_feat, soft_feat) ; } } - + template < typename list_type , typename geom_opts @@ -553,22 +553,22 @@ ) { char_type _feat = null_feat ; - - real_type _DtoR = + + real_type _DtoR = (real_type) +3.1415926536 / 180.0; - - real_type _phi1 = + + real_type _phi1 = (real_type)+180. - _opts.phi1(); - real_type _eta1 = + real_type _eta1 = (real_type)+ 0. + _opts.eta1(); - - real_type _hard = + + real_type _hard = std::cos( _phi1 * _DtoR) ; - real_type _soft = + real_type _soft = std::cos( _eta1 * _DtoR) ; - + __unreferenced(_node) ; - + for (auto _epos = _eadj.head() ; _epos != _eadj.tend() ; ++_epos ) @@ -578,13 +578,13 @@ { iptr_type _iedg = * _epos ; iptr_type _ifac = * _fpos ; - + iptr_type _enod[2] ; _enod[0] = this->_tria. _set2[_iedg]. node(0) ; _enod[1] = this->_tria. _set2[_iedg]. node(1) ; - + iptr_type _fnod[3] ; _fnod[0] = this->_tria. _fset[_ifac]. node(0) ; @@ -615,41 +615,41 @@ &this->_tria. _set1[ _enod[1]].pval(0) , _evec) ; - + real_type _fvec[3] ; - - + + //!! actually, need to project edge onto tria - - - real_type _acos = + + + real_type _acos = geometry::cosine_3d( _evec , _fvec) ; - + _acos =std::abs(_acos) ; - + if (_acos <= _hard) { - _feat = + _feat = std::max(_feat, hard_feat) ; } else if (_acos <= _soft) - { - _feat = + { + _feat = std::max(_feat, soft_feat) ; - } - } - - return _feat ; + } + } + + return _feat ; } - + /* ------------------------------------------------------------ * EDGE-FEAT: calc. edge feature type. ------------------------------------------------------------ */ - + template < typename list_type , typename geom_opts @@ -662,26 +662,26 @@ geom_opts &_opts ) { - real_type _DtoR = + real_type _DtoR = (real_type) +3.1415926536 / 180.0; - real_type _ZERO = -1. + + real_type _ZERO = -1. + std::numeric_limits ::epsilon(); - - real_type _phi2 = + + real_type _phi2 = (real_type)+180. - _opts.phi2(); - real_type _eta2 = + real_type _eta2 = (real_type)+ 0. + _opts.eta2(); - - real_type _hard = + + real_type _hard = std::cos( _phi2 * _DtoR) ; - real_type _soft = + real_type _soft = std::cos( _eta2 * _DtoR) ; - + _feat = null_feat ; _topo = (char_type)_aset.count(); - + for (auto _ipos = _aset.head() ; _ipos != _aset.tend() ; ++_ipos ) @@ -693,26 +693,26 @@ { iptr_type _itri = * _ipos ; iptr_type _jtri = * _jpos ; - + iptr_type _inod[3]; iptr_type _jnod[3]; - + iptr_type _iloc ; for (_iloc = 3; _iloc-- != 0; ) { tri3_type::face_node ( _inod, _iloc, 2, 1) ; - + _inod[0] = this->_tria. - _set3[_itri]. + _set3[_itri]. node(_inod[0]); _inod[1] = this->_tria. - _set3[_itri]. + _set3[_itri]. node(_inod[1]); _inod[2] = this->_tria. - _set3[_itri]. + _set3[_itri]. node(_inod[2]); - + iptr_type _same = +0 ; if (_inod[0]==_enod[0]) _same += +1 ; @@ -722,26 +722,26 @@ _same += +1 ; if (_inod[1]==_enod[1]) _same += +1 ; - + if (_same == +2 ) break ; } - + iptr_type _jloc ; for (_jloc = 3; _jloc-- != 0; ) { tri3_type::face_node ( _jnod, _jloc, 2, 1) ; - + _jnod[0] = this->_tria. - _set3[_jtri]. + _set3[_jtri]. node(_jnod[0]); _jnod[1] = this->_tria. - _set3[_jtri]. + _set3[_jtri]. node(_jnod[1]); _jnod[2] = this->_tria. - _set3[_jtri]. + _set3[_jtri]. node(_jnod[2]); - + iptr_type _same = +0 ; if (_jnod[0]==_enod[0]) _same += +1 ; @@ -751,10 +751,10 @@ _same += +1 ; if (_jnod[1]==_enod[1]) _same += +1 ; - + if (_same == +2 ) break ; } - + real_type _ivec[3]; geometry::tria_norm_3d ( &this->_tria. @@ -764,7 +764,7 @@ &this->_tria. _set1 [_inod[2]].pval(0) , _ivec) ; - + real_type _jvec[3]; geometry::tria_norm_3d ( &this->_tria. @@ -774,28 +774,28 @@ &this->_tria. _set1 [_jnod[2]].pval(0) , _jvec) ; - - real_type _acos = + + real_type _acos = geometry::cosine_3d( _ivec , _jvec) ; - + if (_inod[0] == _jnod[1] && _inod[1] == _jnod[0] ) _acos *= (real_type)+1.; else _acos *= (real_type)-1.; - + if (_acos >= _ZERO) { if (_acos <= _hard) { - _feat = + _feat = std::max(_feat, hard_feat) ; } else if (_acos <= _soft) - { - _feat = + { + _feat = std::max(_feat, soft_feat) ; } } @@ -811,7 +811,7 @@ { if (_topo != + 0 ) if (_topo != + 2 ) - _feat = + _feat = std::max(_feat, soft_feat) ; } } @@ -821,7 +821,7 @@ * FIND-FEAT: scan geometry and find features. -------------------------------------------------------- */ - + template < typename geom_opts > @@ -835,16 +835,16 @@ array _fadj ; containers:: array _ebnd ; - + containers:: array _nmrk ; containers:: array _emrk ; - + /*---------------------------------- init. geom feat. */ - for (auto _iter = + for (auto _iter = this->_tria._set1.head() ; - _iter != + _iter != this->_tria._set1.tend() ; ++_iter ) { @@ -855,9 +855,9 @@ _iter->topo () = +2 ; } } - for (auto _iter = + for (auto _iter = this->_tria._set2.head() ; - _iter != + _iter != this->_tria._set2.tend() ; ++_iter ) { @@ -867,9 +867,9 @@ _iter->topo () = +2 ; } } - for (auto _iter = + for (auto _iter = this->_tria._set3.head() ; - _iter != + _iter != this->_tria._set3.tend() ; ++_iter ) { @@ -879,22 +879,22 @@ _iter->topo () = +2 ; } } - + /*---------------------------------- find sharp feat. */ _nmrk.set_count ( - this->_tria._set1.count() , + this->_tria._set1.count() , containers::loose_alloc,-1) ; - + _emrk.set_count ( - this->_tria._set2.count() , + this->_tria._set2.count() , containers::loose_alloc,-1) ; - + iptr_type _nnum = +0 ; iptr_type _enum = +0 ; - - for (auto _epos = + + for (auto _epos = this->_tria._set2.head() ; - _epos != + _epos != this->_tria._set2.tend() ; ++_epos, ++_enum) { @@ -907,34 +907,34 @@ { /*---------------------------------- set geo.-defined */ _fadj.set_count (0); - + this->_tria.edge_tri3 ( &_epos->node (0), _fadj) ; - + edge_feat ( - &_epos->node (0), + &_epos->node (0), _fadj , _epos->feat () , - _epos->topo () , + _epos->topo () , _opts ) ; - + if (_epos->itag() <= -1) { /*---------------------------------- set user-defined */ - _epos->feat () = - std::max(_epos->feat () , + _epos->feat () = + std::max(_epos->feat () , soft_feat) ; - + _nmrk[_epos->node(0)] = +1; _nmrk[_epos->node(1)] = +1; } } } } - - for (auto _npos = + + for (auto _npos = this->_tria._set1.head() ; - _npos != + _npos != this->_tria._set1.tend() ; ++_npos, ++_nnum) { @@ -948,10 +948,10 @@ /*---------------------------------- set geo.-defined */ _eadj.set_count (0); _fadj.set_count (0); - + this->_tria.node_edge ( &_npos->node (0), _eadj) ; - + this->_tria.node_tri3 ( &_npos->node (0), _fadj) ; @@ -960,26 +960,26 @@ feat_list (_eadj, _ebnd); node_feat ( - &_npos->node (0), + &_npos->node (0), _ebnd , _npos->feat () , - _npos->topo () , + _npos->topo () , _opts ) ; - + if (_npos->itag () <= -1) { /*---------------------------------- set user-defined */ - _npos->feat () = - std::max(_npos->feat () , + _npos->feat () = + std::max(_npos->feat () , soft_feat) ; } } } } - - for (auto _iter = + + for (auto _iter = this->_tria._set3.head() ; - _iter != + _iter != this->_tria._set3.tend() ; ++_iter ) { @@ -994,10 +994,10 @@ _iter->node(2)].fdim() = 2; } } - - for (auto _iter = + + for (auto _iter = this->_tria._set2.head() ; - _iter != + _iter != this->_tria._set2.tend() ; ++_iter ) { @@ -1013,10 +1013,10 @@ } } } - - for (auto _iter = + + for (auto _iter = this->_tria._set1.head() ; - _iter != + _iter != this->_tria._set1.tend() ; ++_iter ) { @@ -1030,13 +1030,13 @@ } } } - + /* -------------------------------------------------------- * INIT-PART: init. enclosed PART within geom. -------------------------------------------------------- */ - + template < typename geom_opts > @@ -1045,190 +1045,190 @@ ) { containers::array < - typename + typename iptr_list::size_type> _mark ; - + __unreferenced (_opts) ; /*----------------------------- extrema for PART id's */ - iptr_type _imin = + iptr_type _imin = +std::numeric_limits ::infinity() ; - iptr_type _imax = + iptr_type _imax = -std::numeric_limits ::infinity() ; - - for (auto _iter = - this->_part._lptr.head() ; - _iter != + + for (auto _iter = + this->_part._lptr.head() ; + _iter != this->_part._lptr.tend() ; ++_iter ) { typename part_list ::item_type*_next =*_iter; - - for ( ; _next != nullptr ; + + for ( ; _next != nullptr ; _next = _next->_next) { - iptr_type _ppos = + iptr_type _ppos = _next->_data.itag() ; - - _imin = std::min(_imin, + + _imin = std::min(_imin, _ppos) ; - _imax = std::max(_imax, + _imax = std::max(_imax, _ppos) ; } } - + if (_imin < (iptr_type) +0 && _imax < (iptr_type) +0 ) - __assert( _imin >= +0 && + __assert( _imin >= +0 && "GEOM::INIT-PART: -ve part index!") ; - + /*----------------------------- push unique PART id's */ - auto _flag = + auto _flag = std::numeric_limits < - typename + typename iptr_list::size_type>::max(); - - _mark.set_count(_imax+1, + + _mark.set_count(_imax+1, containers::tight_alloc, _flag) ; - - for (auto _iter = - this->_part._lptr.head() ; - _iter != + + for (auto _iter = + this->_part._lptr.head() ; + _iter != this->_part._lptr.tend() ; ++_iter ) { typename part_list ::item_type*_next =*_iter; - - for ( ; _next != nullptr ; + + for ( ; _next != nullptr ; _next = _next->_next) { - iptr_type _ppos = + iptr_type _ppos = _next->_data.itag() ; if (_mark[_ppos] == _flag) { - _mark[_ppos] = + _mark[_ppos] = this-> _ptag.push_tail(_ppos) ; } } } - + /*----------------------------- init. aabb's for PART */ this->_pmin.set_count ( - this->_ptag.count(), + this->_ptag.count(), containers::tight_alloc, _bmax) ; - + this->_pmax.set_count ( - this->_ptag.count(), + this->_ptag.count(), containers::tight_alloc, _bmin) ; - - for (auto _iter = - this->_part._lptr.head() ; - _iter != + + for (auto _iter = + this->_part._lptr.head() ; + _iter != this->_part._lptr.tend() ; ++_iter ) { typename part_list ::item_type*_next =*_iter; - - for ( ; _next != nullptr ; + + for ( ; _next != nullptr ; _next = _next->_next) { - iptr_type _ppos = + iptr_type _ppos = _next->_data.itag () ; - iptr_type _cell = + iptr_type _cell = _next->_data.indx () ; - iptr_type _kind = + iptr_type _kind = _next->_data.kind () ; - + if (_kind == TRIA3_tag) { - /*----------------------------- expand aabb via TRIA3 */ + /*----------------------------- expand aabb via TRIA3 */ auto _inod = this-> _tria._set3[_cell].node(0); auto _jnod = this-> _tria._set3[_cell].node(1); auto _knod = this-> _tria._set3[_cell].node(2); - + auto _iptr = &this-> _tria._set1[_inod]; auto _jptr = &this-> _tria._set1[_jnod]; auto _kptr = &this-> _tria._set1[_knod]; - - real_type _xmin = + + real_type _xmin = std::min (_iptr->pval(0) , std::min (_jptr->pval(0) , - _kptr->pval(0) + _kptr->pval(0) ) ) ; - real_type _ymin = + real_type _ymin = std::min (_iptr->pval(1) , std::min (_jptr->pval(1) , - _kptr->pval(1) + _kptr->pval(1) ) ) ; - real_type _zmin = + real_type _zmin = std::min (_iptr->pval(2) , std::min (_jptr->pval(2) , - _kptr->pval(2) + _kptr->pval(2) ) ) ; - - real_type _xmax = + + real_type _xmax = std::max (_iptr->pval(0) , std::max (_jptr->pval(0) , - _kptr->pval(0) + _kptr->pval(0) ) ) ; - real_type _ymax = + real_type _ymax = std::max (_iptr->pval(1) , std::max (_jptr->pval(1) , - _kptr->pval(1) + _kptr->pval(1) ) ) ; - real_type _zmax = + real_type _zmax = std::max (_iptr->pval(2) , std::max (_jptr->pval(2) , - _kptr->pval(2) + _kptr->pval(2) ) ) ; - + auto _pmap = _mark[_ppos]; - this-> _pmin[_pmap][ 0] = + this-> _pmin[_pmap][ 0] = std::min(_xmin, this-> _pmin[_pmap][ 0]) ; - this-> _pmin[_pmap][ 1] = + this-> _pmin[_pmap][ 1] = std::min(_ymin, this-> _pmin[_pmap][ 1]) ; - this-> _pmin[_pmap][ 2] = + this-> _pmin[_pmap][ 2] = std::min(_zmin, this-> _pmin[_pmap][ 2]) ; - - this-> _pmax[_pmap][ 0] = + + this-> _pmax[_pmap][ 0] = std::max(_xmax, this-> _pmax[_pmap][ 0]) ; - this-> _pmax[_pmap][ 1] = + this-> _pmax[_pmap][ 1] = std::max(_ymax, this-> _pmax[_pmap][ 1]) ; - this-> _pmax[_pmap][ 2] = + this-> _pmax[_pmap][ 2] = std::max(_zmax, this-> _pmax[_pmap][ 2]) ; - + } } } - + } - + /* -------------------------------------------------------- * INIT-GEOM: init. geometry data structures. -------------------------------------------------------- */ - + template < typename geom_opts > @@ -1240,41 +1240,41 @@ { /*---------------- TRUE if tree should index edge */ public : - __inline_call + __inline_call bool_type operator () ( edge_type const& _edat ) const - { return _edat.feat() != 0 + { return _edat.feat() != 0 && _edat.mark() >= 0 ; } } ; - + class tri3_pred { /*---------------- TRUE if tree should index tria */ public : - __inline_call + __inline_call bool_type operator () ( tri3_type const& _tdat ) const { return _tdat.mark() >= 0 ; } } ; - + /*----------------------------- init. aabb at -+ inf. */ for(auto _idim = 3; _idim-- != 0 ; ) { - this->_bmin[_idim] = + this->_bmin[_idim] = +std::numeric_limits< real_type>::infinity() ; - - this->_bmax[_idim] = + + this->_bmax[_idim] = -std::numeric_limits< real_type>::infinity() ; } - + /*----------------------------- calc. aabb for inputs */ - for (auto _iter = + for (auto _iter = this->_tria._set1.head() ; _iter != this->_tria._set1.tend() ; @@ -1283,60 +1283,63 @@ if (_iter->mark() >= +0) { this->_bmin[0] = std::min ( - this->_bmin[0] , + this->_bmin[0] , _iter->pval(0) ) ; this->_bmin[1] = std::min ( - this->_bmin[1] , + this->_bmin[1] , _iter->pval(1) ) ; this->_bmin[2] = std::min ( - this->_bmin[2] , + this->_bmin[2] , _iter->pval(2) ) ; - + this->_bmax[0] = std::max ( - this->_bmax[0] , + this->_bmax[0] , _iter->pval(0) ) ; this->_bmax[1] = std::max ( - this->_bmax[1] , + this->_bmax[1] , _iter->pval(1) ) ; this->_bmax[2] = std::max ( - this->_bmax[2] , + this->_bmax[2] , _iter->pval(2) ) ; } } - - real_type static const _RTOL = + + float static const _RTOL = std::pow ( - std::numeric_limits - ::epsilon(),(real_type).8) ; - - real_type _BTOL[3] ; - _BTOL[0] =( this->_bmax[ 0] - + std::numeric_limits + ::epsilon(), (float)+.75) ; + + float _BTOL[3] ; + _BTOL[0] = + (float) ( this->_bmax[ 0] - this->_bmin[ 0] ) * _RTOL ; - _BTOL[1] =( this->_bmax[ 1] - + _BTOL[1] = + (float) ( this->_bmax[ 1] - this->_bmin[ 1] ) * _RTOL ; - _BTOL[2] =( this->_bmax[ 2] - + _BTOL[2] = + (float) ( this->_bmax[ 2] - this->_bmin[ 2] ) * _RTOL ; - - /*-------------------- find sharp "features" in geom. */ + + /*-------------------- find sharp "features" in geom. */ find_feat (_opts); - + /*-------------------- indexes for PART def. in geom. */ init_part (_opts); - + /*-------------------- make aabb-tree and init. bbox. */ - aabb_mesh(this->_tria._set1, - this->_tria._set2, + aabb_mesh(this->_tria._set1, + this->_tria._set2, this->_ebox, - _BTOL,this->_nbox,edge_pred () + _BTOL,this->_nbox,edge_pred () ) ; - - aabb_mesh(this->_tria._set1, - this->_tria._set3, + + aabb_mesh(this->_tria._set1, + this->_tria._set3, this->_tbox, - _BTOL,this->_nbox,tri3_pred () + _BTOL,this->_nbox,tri3_pred () ) ; } @@ -1345,7 +1348,7 @@ * SEED-FEAT: setup initial node set. -------------------------------------------------------- */ - + template < typename mesh_type , typename geom_opts @@ -1358,9 +1361,9 @@ __unreferenced(_opts) ; /*------------------------- push set of feature nodes */ - for (auto _iter = + for (auto _iter = this->_tria._set1.head() ; - _iter != + _iter != this->_tria._set1.tend() ; ++_iter ) { @@ -1374,19 +1377,19 @@ &_iter->pval(0), _node)) { _mesh._tria.node - (_node)->fdim() + (_node)->fdim() = _iter->fdim() ; - + _mesh._tria.node - (_node)->feat() + (_node)->feat() = _iter->feat() ; - + _mesh._tria.node - (_node)->topo() + (_node)->topo() = _iter->topo() ; - + _mesh._tria.node - (_node)->part() + (_node)->part() = _iter->itag() ; } } @@ -1399,32 +1402,32 @@ &_iter->pval(0), _node)) { _mesh._tria.node - (_node)->fdim() + (_node)->fdim() = _iter->fdim() ; - + _mesh._tria.node - (_node)->feat() + (_node)->feat() = _iter->feat() ; - + _mesh._tria.node - (_node)->topo() + (_node)->topo() = _iter->topo() ; - + _mesh._tria.node - (_node)->part() + (_node)->part() = _iter->itag() ; } } } - } + } } - + /* -------------------------------------------------------- * SEED-MESH: setup initial node set. -------------------------------------------------------- */ - + template < typename mesh_type , typename geom_opts @@ -1435,40 +1438,40 @@ ) { /*------------------------- well-distributed sampling */ - while (_mesh._tria._nset.count() + while (_mesh._tria._nset.count() < (std::size_t)_opts.seed() + 4) { typename geom_type:: mesh_type:: node_list::_write_it _best; - + real_type _dmax = (real_type) +.0 ; char_type _fdim ; - + for (_fdim = 1; _fdim != 4; ++_fdim) { - for (auto _ipos = + for (auto _ipos = this->_tria._set1.head() ; - _ipos != + _ipos != this->_tria._set1.tend() ; ++_ipos ) { - if (_ipos->mark() >= 0 && + if (_ipos->mark() >= 0 && _ipos->fdim () == _fdim) { - real_type _dmin = + real_type _dmin = +std::numeric_limits ::infinity(); - for (auto _jpos = + for (auto _jpos = _mesh._tria._nset.head() ; - _jpos != + _jpos != _mesh._tria._nset.tend() ; ++_jpos ) { - real_type _dist = + real_type _dist = geometry::lensqr_3d( - &_ipos->pval(+0), + &_ipos->pval(+0), &_jpos->pval(+0)) ; _dmin = std::min(_dmin, _dist); @@ -1483,8 +1486,8 @@ } if (_dmax > (real_type)0.) break ; } - - if (_dmax > (real_type)0.) + + if (_dmax > (real_type)0.) { /*------------------------- add current furthest node */ iptr_type _node = -1; @@ -1492,16 +1495,16 @@ &_best->pval(0), _node) ) { _mesh._tria.node - (_node)->fdim() + (_node)->fdim() = _best->fdim() ; - + _mesh._tria.node - (_node)->feat() + (_node)->feat() = _best->feat() ; - + _mesh._tria.node - (_node)->topo() - = _best->topo() ; + (_node)->topo() + = _best->topo() ; } } else break ; @@ -1523,23 +1526,23 @@ public : real_type _pmid[3] ; real_type _nvec[3] ; - + geom_type &_geom ; - + hits_func &_hfun ; - - bool_type _find ; + + bool_type _find ; iptr_type _hnum ; - + geometry:: hits_type _hits ; - + public : flat_line_pred operator = ( - flat_line_pred & + flat_line_pred & ) = delete ; flat_line_pred operator = ( - flat_line_pred&& + flat_line_pred&& ) = delete ; public : @@ -1549,16 +1552,16 @@ real_type *_vsrc , geom_type &_gsrc , hits_func &_hsrc - ) : _geom( _gsrc), + ) : _geom( _gsrc), _hfun( _hsrc) { - this->_hits = + this->_hits = geometry ::null_hits ; this->_pmid[0] = _qsrc[0]; this->_pmid[1] = _qsrc[1]; this->_pmid[2] = _qsrc[2]; - + this->_nvec[0] = _vsrc[0]; this->_nvec[1] = _vsrc[1]; this->_nvec[2] = _vsrc[2]; @@ -1568,56 +1571,56 @@ } /*----------------------- all intersection about node */ __normal_call void_type operator() ( - typename + typename tree_type::item_data *_iptr ) { - for ( ; _iptr != nullptr; + for ( ; _iptr != nullptr; _iptr = _iptr->_next ) { - geometry::hits_type - _hits = geometry::face_hits ; - + geometry::hits_type + _HITS = geometry::face_hits ; + /*--------------- line-tria intersection test */ - iptr_type _epos = + iptr_type _epos = _iptr->_data.ipos() ; - + iptr_type _enod[2]; _enod[0] =_geom. _tria._set2[_epos].node(0) ; _enod[1] =_geom. _tria._set2[_epos].node(1) ; - + real_type _xpos[3]; - bool_type _okay = + bool_type _okay = geometry::line_flat_3d ( - this->_pmid, - this->_nvec, + this->_pmid, + this->_nvec, &this->_geom. - _tria._set1[_enod[0]].pval(0) , + _tria._set1[_enod[0]].pval(0) , &this->_geom. - _tria._set1[_enod[1]].pval(0) , + _tria._set1[_enod[1]].pval(0) , _xpos, true); if (_okay) { /*--------------- call output function on hit */ - this->_hfun (_xpos, _hits , + this->_hfun (_xpos, _HITS , _geom._tria . _set2[_epos].feat() , _geom._tria . _set2[_epos].topo() , _geom._tria . _set2[_epos].itag() ) ; - + this->_hnum+= +1 ; - + this->_find = true ; - this->_hits =_hits ; + this->_hits =_HITS ; } } } - + } ; template < @@ -1629,28 +1632,28 @@ public : real_type _ipos[3] ; real_type _jpos[3] ; - + geom_type &_geom ; - + hits_func &_hfun ; - - bool_type _find ; + + bool_type _find ; iptr_type _hnum ; - + bool_type _exct ; - + geometry:: hits_type _hits ; - + iptr_type _part ; - + public : - + line_tria_pred operator = ( - line_tria_pred & + line_tria_pred & ) = delete ; line_tria_pred operator = ( - line_tria_pred&& + line_tria_pred&& ) = delete ; public : @@ -1661,65 +1664,65 @@ geom_type &_gsrc , hits_func &_hsrc , iptr_type _psrc = -1 - ) : _geom( _gsrc), + ) : _geom( _gsrc), _hfun( _hsrc) { - this->_hits = + this->_hits = geometry ::null_hits ; - + this->_ipos[0] = _isrc[0]; this->_ipos[1] = _isrc[1]; this->_ipos[2] = _isrc[2]; - + this->_jpos[0] = _jsrc[0]; this->_jpos[1] = _jsrc[1]; this->_jpos[2] = _jsrc[2]; - + this->_part = _psrc ; - + this->_exct = false ; - + this->_hnum = + 0 ; this->_find = false ; } - /*----------------------- TRUE if PART is within list */ + /*----------------------- TRUE if PART is within list */ __inline_call bool_type have_part ( iptr_type _tpos ) { typename geom_type ::part_list::item_type *_same ; - + typename geom_type ::part_list::data_type _temp ; _temp.itag() = _part ; _temp.indx() = _tpos ; - _temp.kind() = + _temp.kind() = mesh:: TRIA3_tag ; - + return this-> _geom._part.find(_temp, _same); } /*----------------------- all intersection about node */ __normal_call void_type operator() ( - typename + typename tree_type::item_data *_iptr ) { - for ( ; _iptr != nullptr; + for ( ; _iptr != nullptr; _iptr = _iptr->_next ) { - geometry::hits_type - _hits = geometry::null_hits; - + geometry::hits_type + _HITS = geometry::null_hits; + /*--------------- line-tria intersection test */ - iptr_type _tpos = + iptr_type _tpos = _iptr->_data.ipos() ; - - if (this->_part >= +0 - && !have_part(_tpos) ) + + if (this->_part >= +0 + && !have_part(_tpos) ) continue ; - + iptr_type _tnod[3]; _tnod[0] =_geom. _tria._set3[_tpos].node(0) ; @@ -1727,10 +1730,10 @@ _tria._set3[_tpos].node(1) ; _tnod[2] =_geom. _tria._set3[_tpos].node(2) ; - + real_type _xpos[3]; - _hits = geometry::line_tria_3d ( - & this->_ipos[0], + _HITS = geometry::line_tria_3d ( + & this->_ipos[0], & this->_jpos[0], &_geom ._tria. _set1 [_tnod[0]].pval(0), @@ -1740,28 +1743,28 @@ _set1 [_tnod[2]].pval(0), _xpos, true, 2 ); - if(_hits != geometry::null_hits) + if(_HITS != geometry::null_hits) { /*--------------- call output function on hit */ - this->_hfun (_xpos, _hits , + this->_hfun (_xpos, _HITS , _geom._tria . _set3[_tpos].feat() , _geom._tria . _set3[_tpos].topo() , _geom._tria . _set3[_tpos].itag() ) ; - + this->_hnum+= +1 ; - + this->_find = true ; - this->_hits =_hits ; - - if (_hits != geometry::face_hits) + this->_hits =_HITS ; + + if (_HITS != geometry::face_hits) this->_exct = true ; } } } - + } ; template < @@ -1773,79 +1776,79 @@ public : real_type _ball[3] ; real_type _rsiz ; - + geom_type &_geom ; - + hits_func &_hfun ; - + geometry:: hits_type _hits ; - - bool_type _find ; + + bool_type _find ; iptr_type _hnum ; - + public : ball_line_pred operator = ( - ball_line_pred & + ball_line_pred & ) = delete ; ball_line_pred operator = ( - ball_line_pred&& + ball_line_pred&& ) = delete ; public : /*------------------------------ construct from _src. */ __normal_call ball_line_pred ( real_type *_cmid , - real_type _rsiz , + real_type _rsrc , geom_type &_gsrc , hits_func &_hsrc - ) : _geom( _gsrc), + ) : _geom( _gsrc), _hfun( _hsrc) { this->_hits = geometry ::null_hits ; - + this->_find = false ; this->_hnum = + 0 ; - + this->_ball[0] = _cmid[0]; this->_ball[1] = _cmid[1]; this->_ball[2] = _cmid[2]; - - this->_rsiz = _rsiz ; + + this->_rsiz = _rsrc ; } /*----------------------- all intersection about node */ __normal_call void_type operator() ( - typename + typename tree_type::item_data*_iptr ) { - for ( ; _iptr != nullptr; + for ( ; _iptr != nullptr; _iptr = _iptr->_next ) { - geometry::hits_type _hits = + geometry::hits_type _HITS = geometry::face_hits ; - + /*--------------- ball_line intersection test */ - iptr_type _epos = + iptr_type _epos = _iptr->_data.ipos() ; - + iptr_type _enod[2]; _enod[0] =_geom. _tria._set2[_epos].node(0) ; _enod[1] =_geom. _tria._set2[_epos].node(1) ; - + real_type _ipos[3]; real_type _jpos[3]; - size_t _nhit = + size_t _nhit = geometry::ball_line_3d ( - this->_ball, - this->_rsiz, + this->_ball, + this->_rsiz, &_geom ._tria. _set1 [_enod[0]].pval(0) , &_geom ._tria. - _set1 [_enod[1]].pval(0) , + _set1 [_enod[1]].pval(0) , _ipos, _jpos ) ; switch (_nhit) @@ -1853,38 +1856,38 @@ case +2 : { /*--------------- call output function on hit */ - this->_hfun (_jpos, _hits , + this->_hfun (_jpos, _HITS , _geom._tria . _set2[_epos].feat() , _geom._tria . _set2[_epos].topo() , _geom._tria . _set2[_epos].itag() ) ; - + this->_hnum += +1; } // falls through case +1 : { /*--------------- call output function on hit */ - this->_hfun (_ipos, _hits , + this->_hfun (_ipos, _HITS , _geom._tria . _set2[_epos].feat() , _geom._tria . _set2[_epos].topo() , _geom._tria . _set2[_epos].itag() ) ; - + this->_hnum += +1; - + this->_find = true ; - this->_hits =_hits ; + this->_hits =_HITS ; } // falls through } } } - + } ; - + template < typename hits_func > @@ -1895,19 +1898,19 @@ real_type _cmid[3] ; real_type _nvec[3] ; real_type _rsiz ; - + geom_type &_geom ; - + hits_func &_hfun ; - + bool_type _find ; public : disc_tria_pred operator = ( - disc_tria_pred & + disc_tria_pred & ) = delete ; disc_tria_pred operator = ( - disc_tria_pred&& + disc_tria_pred&& ) = delete ; public : @@ -1918,36 +1921,36 @@ real_type _rsrc , geom_type &_gsrc , hits_func &_hsrc - ) : _geom( _gsrc), - _hfun( _hsrc), + ) : _geom( _gsrc), + _hfun( _hsrc), _find( false) - { + { this->_cmid[0] = _csrc[0]; this->_cmid[1] = _csrc[1]; this->_cmid[2] = _csrc[2]; - + this->_nvec[0] = _nsrc[0]; this->_nvec[1] = _nsrc[1]; this->_nvec[2] = _nsrc[2]; - + this->_rsiz = _rsrc; } /*----------------------- all intersection about node */ __normal_call void_type operator() ( - typename + typename tree_type::item_data*_iptr ) { - for ( ; _iptr != nullptr; + for ( ; _iptr != nullptr; _iptr = _iptr->_next ) { - geometry::hits_type _hits = + geometry::hits_type _HITS = geometry::face_hits ; - + /*--------------- tria-flat intersection test */ - iptr_type _tpos = + iptr_type _tpos = _iptr->_data.ipos() ; - + iptr_type _tnod[3]; _tnod[0] =_geom. _tria._set3[_tpos].node(0) ; @@ -1955,27 +1958,27 @@ _tria._set3[_tpos].node(1) ; _tnod[2] =_geom. _tria._set3[_tpos].node(2) ; - + real_type _apos[3] ; real_type _bpos[3] ; real_type _ipos[3] ; real_type _jpos[3] ; size_t _nh = 0; if (geometry::tria_flat_3d ( - this->_cmid , - this->_nvec , + this->_cmid , + this->_nvec , &_geom ._tria. _set1 [_tnod[0]].pval(0) , &_geom ._tria. _set1 [_tnod[1]].pval(0) , &_geom ._tria. - _set1 [_tnod[2]].pval(0) , + _set1 [_tnod[2]].pval(0) , _apos, _bpos)) /*--------------- circ-tria intersection test */ _nh=geometry::ball_line_3d ( - this->_cmid , - this->_rsiz , - _apos, _bpos , + this->_cmid , + this->_rsiz , + _apos, _bpos , _ipos, _jpos ) ; switch (_nh) @@ -1983,7 +1986,7 @@ case +2 : { /*--------------- call output function on hit */ - this->_hfun (_jpos, _hits , + this->_hfun (_jpos, _HITS , _geom._tria . _set3[_tpos].feat() , _geom._tria . @@ -1994,29 +1997,227 @@ case +1 : { /*--------------- call output function on hit */ - this->_hfun (_ipos, _hits , + this->_hfun (_ipos, _HITS , _geom._tria . _set3[_tpos].feat() , _geom._tria . _set3[_tpos].topo() , _geom._tria . _set3[_tpos].itag() ) ; - + this->_find = true ; } // falls through } } } - + } ; - + class near_edge_pred + { + /*------------------ node-edge "projection" predicate */ + public : + real_type *_ppos ; + real_type *_qpos ; + + real_type _dsqr ; + real_type _dtol ; + + mesh_type *_mesh ; + + bool_type _find ; + iptr_type _epos ; + + public : + + /*------------------------ make a tree-edge predicate */ + __inline_call near_edge_pred( + real_type*_psrc = nullptr , + real_type*_qsrc = nullptr , + mesh_type*_msrc = nullptr , + real_type _near = + (real_type) +0. + ) : _ppos(_psrc) , + _qpos(_qsrc) , + _dsqr(+std::numeric_limits + ::infinity () ) , + _dtol(_near) , + _mesh(_msrc) , + _find(false) , + _epos( -1) { } + + /*------------------------ call pred. on tree matches */ + __inline_call float operator () ( + typename + tree_type::item_data *_iptr + ) + { + if (this->_find) return +0. ; + + real_type _qtmp[+3] = {+0.}; + + for ( ; _iptr != nullptr; + _iptr = _iptr->_next ) + { + geometry::hits_type + _HITS = geometry::null_hits; + + iptr_type _EPOS = + _iptr->_data.ipos() ; + + iptr_type _enod[+2] = { + this->_mesh-> + _set2 [_EPOS ].node(0) , + this->_mesh-> + _set2 [_EPOS ].node(1) , + } ; + + if (geometry::proj_line_3d ( + _ppos, + &this->_mesh-> + _set1 [_enod[0]].pval(0) , + &this->_mesh-> + _set1 [_enod[1]].pval(0) , + _qtmp, _HITS) ) + { + if (_HITS != + geometry::null_hits) + { + /*-------------------- projected match: keep best */ + real_type _dtmp = + geometry::lensqr_3d(_ppos,_qtmp) ; + + if (_dtmp<_dsqr ) + { + _qpos[0] = _qtmp[0] ; + _qpos[1] = _qtmp[1] ; + _qpos[2] = _qtmp[2] ; + + this->_find = + this->_dtol * + this->_dtol > _dtmp ; + + this->_dsqr = _dtmp ; + this->_epos = _EPOS ; + } + + } + } + } + + return ( (float)this->_dsqr ) ; + } + + } ; + + class near_tria_pred + { + /*------------------ node-tria "projection" predicate */ + public : + real_type *_ppos ; + real_type *_qpos ; + + real_type _dsqr ; + real_type _dtol ; + + mesh_type *_mesh ; + + bool_type _find ; + iptr_type _tpos ; + + public : + + /*------------------------ make a tree-edge predicate */ + __inline_call near_tria_pred( + real_type*_psrc = nullptr , + real_type*_qsrc = nullptr , + mesh_type*_msrc = nullptr , + real_type _near = + (real_type) +0. + ) : _ppos(_psrc) , + _qpos(_qsrc) , + _dsqr(+std::numeric_limits + ::infinity () ) , + _dtol(_near) , + _mesh(_msrc) , + _find(false) , + _tpos( -1) { } + + /*------------------------ call pred. on tree matches */ + __inline_call float operator () ( + typename + tree_type::item_data *_iptr + ) + { + if (this->_find) return +0. ; + + real_type _qtmp[+3] = {+0.}; + + for ( ; _iptr != nullptr; + _iptr = _iptr->_next ) + { + geometry::hits_type + _HITS = geometry::null_hits; + + iptr_type _TPOS = + _iptr->_data.ipos() ; + + iptr_type _tnod[+3] = { + this->_mesh-> + _set3 [_TPOS ].node(0) , + this->_mesh-> + _set3 [_TPOS ].node(1) , + this->_mesh-> + _set3 [_TPOS ].node(2) , + } ; + + if (geometry::proj_tria_3d ( + _ppos, + &this->_mesh-> + _set1 [_tnod[0]].pval(0) , + &this->_mesh-> + _set1 [_tnod[1]].pval(0) , + &this->_mesh-> + _set1 [_tnod[2]].pval(0) , + _qtmp, _HITS) ) + { + if (_HITS != + geometry::null_hits) + { + /*-------------------- projected match: keep best */ + real_type _dtmp = + geometry::lensqr_3d(_ppos,_qtmp) ; + + if (_dtmp<_dsqr ) + { + _qpos[0] = _qtmp[0] ; + _qpos[1] = _qtmp[1] ; + _qpos[2] = _qtmp[2] ; + + this->_find = + this->_dtol * + this->_dtol > _dtmp ; + + this->_dsqr = _dtmp ; + this->_tpos = _TPOS ; + } + + } + } + } + + return ( (float)this->_dsqr ) ; + } + + } ; + + /* -------------------------------------------------------- * INTERSECT: find FLAT/1-GEOM. intersections. -------------------------------------------------------- */ - + template < typename hits_func > @@ -2026,22 +2227,44 @@ ) { /*------------------ tree-flat intersection predicate */ - typedef + typedef geom_tree::aabb_pred_flat_3 < - real_type, - iptr_type > tree_pred ; + float , + iptr_type > tree_pred ; /*------------------ dual-face intersection predicate */ - typedef + typedef flat_line_pred < - hits_func > hits_pred ; + hits_func > hits_pred ; + + float _PPOS[3] = { + (float) _flat. _ppos[0] , + (float) _flat. _ppos[1] , + (float) _flat. _ppos[2] , + } ; + + float _NVEC[3] = { + (float) _flat. _nvec[0] , + (float) _flat. _nvec[1] , + (float) _flat. _nvec[2] , + } ; + + float _RMIN[3] = { + (float) _flat. _rmin[0] , + (float) _flat. _rmin[1] , + (float) _flat. _rmin[2] , + } ; + + float _RMAX[3] = { + (float) _flat. _rmax[0] , + (float) _flat. _rmax[1] , + (float) _flat. _rmax[2] , + } ; /*------------------ call actual intersection testing */ - tree_pred _pred(_flat. _ppos, - _flat. _nvec, - _flat. _rmin, - _flat. _rmax) ; - hits_pred _func(_flat. _ppos, + tree_pred _pred(_PPOS, _NVEC, + _RMIN, _RMAX) ; + hits_pred _func(_flat. _ppos, _flat. _nvec, *this, _hfun) ; @@ -2056,7 +2279,7 @@ * INTERSECT: find LINE/2-GEOM. intersections. -------------------------------------------------------- */ - + template < typename hits_func > @@ -2066,21 +2289,32 @@ ) { /*------------------ tree-line intersection predicate */ - typedef + typedef geom_tree::aabb_pred_line_3 < - real_type, + float , iptr_type > tree_pred ; - + /*------------------ tria-line intersection predicate */ - typedef + typedef line_tria_pred < - hits_func > hits_pred ; + hits_func > hits_pred ; + + float _IPOS[3] = { + (float) _line. _ipos[0] , + (float) _line. _ipos[1] , + (float) _line. _ipos[2] , + } ; + + float _JPOS[3] = { + (float) _line. _jpos[0] , + (float) _line. _jpos[1] , + (float) _line. _jpos[2] , + } ; /*------------------ call actual intersection testing */ - tree_pred _pred(_line. _ipos, - _line. _jpos) ; - hits_pred _func(_line. _ipos, - _line. _jpos, + tree_pred _pred(_IPOS, _JPOS) ; + hits_pred _func(_line. _ipos, + _line. _jpos, *this, _hfun) ; this->_tbox.find(_pred,_func) ; @@ -2088,13 +2322,13 @@ /*------------------ _TRUE if any intersections found */ return ( _func._find ) ; } - + /* -------------------------------------------------------- * INTERSECT: find BALL/1-GEOM. intersections. -------------------------------------------------------- */ - + template < typename hits_func > @@ -2104,20 +2338,28 @@ ) { /*------------------ tree-ball intersection predicate */ - typedef + typedef geom_tree::aabb_pred_ball_3 < - real_type, - iptr_type > tree_pred ; - + float , + iptr_type > tree_pred ; + /*------------------ ball-line intersection predicate */ - typedef + typedef ball_line_pred < hits_func > hits_pred ; - /*------------------ call actual intersection testing */ - tree_pred _pred(_ball. _pmid, - _ball. _rrad) ; - hits_pred _func(_ball. _pmid, + float _PMID[3] = { + (float) _ball. _pmid[0] , + (float) _ball. _pmid[1] , + (float) _ball. _pmid[2] , + } ; + + float _RRAD = + (float) _ball. _rrad; + + /*------------------ call actual intersection testing */ + tree_pred _pred(_PMID, _RRAD) ; + hits_pred _func(_ball. _pmid, _ball. _rrad, *this, _hfun) ; @@ -2132,7 +2374,7 @@ * INTERSECT: find DISC/2-GEOM. intersections. -------------------------------------------------------- */ - + template < typename hits_func > @@ -2143,24 +2385,32 @@ ) { /*------------------ tree-ball intersection predicate */ - typedef + typedef geom_tree::aabb_pred_ball_3 < - real_type, - iptr_type > tree_pred ; + float , + iptr_type > tree_pred ; /*------------------ circ_tria intersection predicate */ - typedef + typedef disc_tria_pred < hits_func > hits_pred ; __unreferenced(_sbal) ; - /*------------------ call actual intersection testing */ - tree_pred _pred(_disc. _pmid, - _disc. _rrad) ; - hits_pred _func(_disc. _pmid, - _disc. _nvec, - _disc. _rrad, + float _PMID[3] = { + (float) _disc. _pmid[0] , + (float) _disc. _pmid[1] , + (float) _disc. _pmid[2] , + } ; + + float _RRAD = + (float) _disc. _rrad; + + /*------------------ call actual intersection testing */ + tree_pred _pred(_PMID, _RRAD) ; + hits_pred _func(_disc. _pmid, + _disc. _nvec, + _disc. _rrad, *this, _hfun) ; this->_tbox.find(_pred,_func) ; @@ -2174,7 +2424,7 @@ * IS-INSIDE: TRUE if point is "inside" geometry. -------------------------------------------------------- */ - + class null_pred { public : @@ -2183,8 +2433,8 @@ char_type _hits, char_type _feat, char_type _topo, - iptr_type _itag - ) + iptr_type _itag + ) { __unreferenced( _ppos) ; __unreferenced( _hits) ; @@ -2193,37 +2443,37 @@ __unreferenced( _itag) ; } } ; - + __normal_call iptr_type is_inside ( real_type *_ppos ) { - /*--------------------------- calc. axis-aligned dir. */ + /*--------------------------- calc. axis-aligned dir. */ iptr_type _vdim = (iptr_type)+0; iptr_type _sign = (iptr_type)+0; - - real_type _vlen = + + real_type _vlen = -std::numeric_limits ::infinity(); - real_type _near = + real_type _near = +std::numeric_limits ::infinity(); for(auto _idim = +3; _idim-- != +0; ) { - real_type _blen = - _bmax[_idim] - + real_type _blen = + _bmax[_idim] - _bmin[_idim] ; - - _vlen = + + _vlen = std::max (_vlen, _blen) ; - + /*------------------------------ distance to bbox */ - real_type _dmin = - _ppos[_idim] - + real_type _dmin = + _ppos[_idim] - _bmin[_idim] ; - real_type _dmax = - _ppos[_idim] - + real_type _dmax = + _ppos[_idim] - _bmax[_idim] ; _dmin = std::abs(_dmin) ; @@ -2249,51 +2499,51 @@ /*--------------------------- calc. "is-inside" state */ if (this->_ptag.empty() ) { - + /*--------------------------- null PART specification */ - + if (_ppos[0] < this->_bmin[0] || _ppos[1] < this->_bmin[1] || _ppos[2] < this->_bmin[2] ) return (iptr_type) -1 ; - + if (_ppos[0] > this->_bmax[0] || _ppos[1] > this->_bmax[1] || _ppos[2] > this->_bmax[2] ) return (iptr_type) -1 ; - + for(auto _iter = +0; _iter++ != +8; ) { real_type _rvec[ 4] ; _rvec[0] = (real_type)+.0 ; _rvec[1] = (real_type)+.0 ; _rvec[2] = (real_type)+.0 ; - + /*----------------------- linear search direction */ - _rvec[_vdim] = _sign * + _rvec[_vdim] = _sign * _vlen ; if (_iter > +1) { /*----------------------- random search direction */ - _rvec[0] = + _rvec[0] = ((real_type)std::rand()) / RAND_MAX ; - _rvec[1] = + _rvec[1] = ((real_type)std::rand()) / RAND_MAX ; - _rvec[2] = + _rvec[2] = ((real_type)std::rand()) / RAND_MAX ; - + _rvec[0]-= (real_type)+.5 ; _rvec[1]-= (real_type)+.5 ; _rvec[2]-= (real_type)+.5 ; - - _rvec[3] = + + _rvec[3] = geometry::length_3d(_rvec); - _rvec[0]*= + _rvec[0]*= _vlen /_rvec[ +3] ; - _rvec[1]*= + _rvec[1]*= _vlen /_rvec[ +3] ; - _rvec[2]*= + _rvec[2]*= _vlen /_rvec[ +3] ; } @@ -2303,91 +2553,103 @@ _ppos[2] + _rvec[ +2] } ; /*-------------- tree-line intersection predicate */ - typedef + typedef geom_tree::aabb_pred_line_3 < - real_type, - iptr_type > tree_pred ; + float , + iptr_type > tree_pred ; /*-------------- tria-line intersection predicate */ - typedef + typedef line_tria_pred < null_pred > hits_pred ; - tree_pred _pred(_ppos, _rpos) ; + float _PPOS[3] = { + (float) _ppos[0] , + (float) _ppos[1] , + (float) _ppos[2] , + } ; + + float _RPOS[3] = { + (float) _rpos[0] , + (float) _rpos[1] , + (float) _rpos[2] , + } ; + + tree_pred _pred(_PPOS, _RPOS) ; null_pred _hfun; - hits_pred _func(_ppos, _rpos, + hits_pred _func(_ppos, _rpos, *this, _hfun) ; this->_tbox.find(_pred,_func) ; if (_func._exct) continue ; - + /*-------------- done if inside - odd no. crosses */ if((_func._hnum % 2) != +0) { return ( (iptr_type) +0 ) ; } } - + } else { - + /*--------------------------- have PART specification */ - - for(auto _pnum = this->_ptag.count(); + + for(auto _pnum = this->_ptag.count(); _pnum-- != +0; ) - { - - if (_ppos[0] < + { + + if (_ppos[0] < this->_pmin[_pnum][0] || - _ppos[1] < + _ppos[1] < this->_pmin[_pnum][1] || - _ppos[2] < + _ppos[2] < this->_pmin[_pnum][2] ) continue ; - - if (_ppos[0] > + + if (_ppos[0] > this->_pmax[_pnum][0] || - _ppos[1] > + _ppos[1] > this->_pmax[_pnum][1] || - _ppos[2] > + _ppos[2] > this->_pmax[_pnum][2] ) continue ; - + for(auto _iter = +0; _iter++ != +8; ) { real_type _rvec[ 4] ; _rvec[0] = (real_type)+.0 ; _rvec[1] = (real_type)+.0 ; _rvec[2] = (real_type)+.0 ; - + /*----------------------- linear search direction */ - _rvec[_vdim] = _sign * + _rvec[_vdim] = _sign * _vlen ; if (_iter > +1) { /*----------------------- random search direction */ - _rvec[0] = + _rvec[0] = ((real_type)std::rand()) / RAND_MAX ; - _rvec[1] = + _rvec[1] = ((real_type)std::rand()) / RAND_MAX ; - _rvec[2] = + _rvec[2] = ((real_type)std::rand()) / RAND_MAX ; - + _rvec[0]-= (real_type)+.5 ; _rvec[1]-= (real_type)+.5 ; _rvec[2]-= (real_type)+.5 ; - - _rvec[3] = + + _rvec[3] = geometry::length_3d(_rvec); - _rvec[0]*= + _rvec[0]*= _vlen /_rvec[ +3] ; - _rvec[1]*= + _rvec[1]*= _vlen /_rvec[ +3] ; - _rvec[2]*= + _rvec[2]*= _vlen /_rvec[ +3] ; } @@ -2397,26 +2659,38 @@ _ppos[2] + _rvec[ +2] } ; /*-------------- tree-line intersection predicate */ - typedef + typedef geom_tree::aabb_pred_line_3 < - real_type, - iptr_type > tree_pred ; + float , + iptr_type > tree_pred ; /*-------------- tria-line intersection predicate */ - typedef + typedef line_tria_pred < null_pred > hits_pred ; - tree_pred _pred(_ppos, _rpos) ; + float _PPOS[3] = { + (float) _ppos[0] , + (float) _ppos[1] , + (float) _ppos[2] , + } ; + + float _RPOS[3] = { + (float) _rpos[0] , + (float) _rpos[1] , + (float) _rpos[2] , + } ; + + tree_pred _pred(_PPOS, _RPOS) ; null_pred _hfun; - hits_pred _func(_ppos, _rpos, + hits_pred _func(_ppos, _rpos, *this, _hfun) ; this->_tbox.find(_pred,_func) ; if (_func._exct) continue ; - + /*-------------- done if inside - odd no. crosses */ if((_func._hnum % 2) != +0) { @@ -2424,17 +2698,111 @@ } } } - + } return ( (iptr_type) -1) ; } - + + /* + -------------------------------------------------------- + * PROJECTOR: project a point on to the geometry. + -------------------------------------------------------- + */ + + __normal_call void_type projector ( + real_type *_ppos , + iptr_type _idim , + real_type *_proj + ) + { + if (_idim == +1) + { + /*------------------ project to closest 1-dim feature */ + real_type _PROJ[3] = { + (real_type) _ppos[0] , + (real_type) _ppos[1] , + (real_type) _ppos[2] } ; + + float _PPOS[3] = { + (float) _ppos[0] , + (float) _ppos[1] , + (float) _ppos[2] } ; + + real_type static const _RTOL= + std::pow ( + std::numeric_limits + ::epsilon(), (real_type)+.75); + + real_type _BTOL = ( + this->_bmax[0] - + this->_bmin[0] + + this->_bmax[1] - + this->_bmin[1] + + this->_bmax[2] - + this->_bmin[2] ) * _RTOL; + + near_edge_pred _func ( _ppos, + _PROJ, &this-> _tria, + _BTOL) ; + + this->_ebox.near(_PPOS, _func) ; + + _proj[0] = _PROJ[0] ; + _proj[1] = _PROJ[1] ; + _proj[2] = _PROJ[2] ; + } + else + if (_idim == +2) + { + /*------------------ project to closest 2-dim feature */ + real_type _PROJ[3] = { + (real_type) _ppos[0] , + (real_type) _ppos[1] , + (real_type) _ppos[2] } ; + + float _PPOS[3] = { + (float) _ppos[0] , + (float) _ppos[1] , + (float) _ppos[2] } ; + + real_type static const _RTOL= + std::pow ( + std::numeric_limits + ::epsilon(), (real_type)+.75); + + real_type _BTOL = ( + this->_bmax[0] - + this->_bmin[0] + + this->_bmax[1] - + this->_bmin[1] + + this->_bmax[2] - + this->_bmin[2] ) * _RTOL; + + near_tria_pred _func ( _ppos, + _PROJ, &this-> _tria, + _BTOL) ; + + this->_tbox.near(_PPOS, _func) ; + + _proj[0] = _PROJ[0] ; + _proj[1] = _PROJ[1] ; + _proj[2] = _PROJ[2] ; + } + else + { + /*------------------ NULL projection -- return inputs */ + _proj[0] = _ppos[0] ; + _proj[1] = _ppos[1] ; + _proj[2] = _ppos[2] ; + } + } + } ; - - + + } - + # endif //__GEOM_MESH_EUCLIDEAN_3__ diff --git a/src/libcpp/geometry.hpp b/src/libcpp/geometry.hpp index 7e0c000..ccf9e75 100644 --- a/src/libcpp/geometry.hpp +++ b/src/libcpp/geometry.hpp @@ -1,68 +1,66 @@ - -/* ------------------------------------------------------------- - * general operations/algorithms on geometry. ------------------------------------------------------------- - * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) - * - * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The - * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be - * used at your own risk. - * ------------------------------------------------------------- - * - * Last updated: 01 November, 2017 - * - * Copyright 2013-2017 - * Darren Engwirda - * de2363@columbia.edu - * https://github.com/dengwirda/ - * ------------------------------------------------------------- - */ - -# pragma once - -# ifndef __GEOMETRY__ -# define __GEOMETRY__ - -# include "libbasic.hpp" -# include "mpfloats.hpp" - -# include "geom_base/matrix_util.hpp" - -# include "geom_base/vect_base_k.hpp" - -# include "geom_base/predicate_k.hpp" - -# include "geom_base/intersect_k.hpp" - -# include "geom_base/tria_ball_k.hpp" -# include "geom_base/tria_elem_k.hpp" - -# undef __ij - -# endif //__GEOMETRY__ - - - + +/* +------------------------------------------------------------ + * general operations/algorithms on geometry. +------------------------------------------------------------ + * + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) + * + * Disclaimer: Neither I nor: Columbia University, The + * Massachusetts Institute of Technology, The + * University of Sydney, nor The National Aeronautics + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be + * used at your own risk. + * +------------------------------------------------------------ + * + * Last updated: 01 November, 2017 + * + * Copyright 2013-2017 + * Darren Engwirda + * de2363@columbia.edu + * https://github.com/dengwirda/ + * +------------------------------------------------------------ + */ + +# pragma once + +# ifndef __GEOMETRY__ +# define __GEOMETRY__ + +# include "libbasic.hpp" +# include "mpfloats.hpp" +# include "mathutil.hpp" + +# include "geom_base/vect_base_k.hpp" + +# include "geom_base/predicate_k.hpp" + +# include "geom_base/intersect_k.hpp" + +# include "geom_base/tria_ball_k.hpp" +# include "geom_base/tria_elem_k.hpp" + +# +# endif //__GEOMETRY__ + + + diff --git a/src/libcpp/geomtype.hpp b/src/libcpp/geomtype.hpp index c37d229..5448638 100644 --- a/src/libcpp/geomtype.hpp +++ b/src/libcpp/geomtype.hpp @@ -1,32 +1,32 @@ -/* +/* ------------------------------------------------------------ - * data-structures for geometry rep. in R^d. + * data-structures for geometry rep. in R^d. ------------------------------------------------------------ * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * ------------------------------------------------------------ @@ -45,16 +45,16 @@ # ifndef __GEOMTYPE__ # define __GEOMTYPE__ - + namespace mesh - { -/*-------------------------- classification of mesh feat. */ + { +/*-------------------------- classification of mesh feat. */ char_type null_feat = 0 ; char_type user_feat = 1 ; char_type soft_feat = 2 ; - char_type hard_feat = 3 ; + char_type hard_feat = 3 ; } - + # include "containers.hpp" # include "geometry.hpp" @@ -69,7 +69,7 @@ # include "geom_type/geom_mesh_euclidean_3.hpp" # include "geom_type/geom_mesh_ellipsoid_3.hpp" - + # endif//__GEOMTYPE__ diff --git a/src/libcpp/graph_ops/match_graph.hpp b/src/libcpp/graph_ops/match_graph.hpp deleted file mode 100644 index 2f4f174..0000000 --- a/src/libcpp/graph_ops/match_graph.hpp +++ /dev/null @@ -1,374 +0,0 @@ - - /* - -------------------------------------------------------- - * MATCH-GRAPH: algorithms for graph matching. - -------------------------------------------------------- - * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) - * - * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The - * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be - * used at your own risk. - * - -------------------------------------------------------- - * - * Last updated: 20 August, 2018 - * - * Copyright 2013-2018 - * Darren Engwirda - * de2363@columbia.edu - * https://github.com/dengwirda/ - * - -------------------------------------------------------- - */ - -# pragma once - -# ifndef __MATCH_GRAPH__ -# define __MATCH_GRAPH__ - - namespace graph { - - /*------------------------ base graph node/edge types */ - - class graph_node_base - { - public : - } ; - - template < - typename C, - typename I - > - class graph_edge_base - { - public : - typedef C cost_type ; - typedef I iptr_type ; - - public : - cost_type _cost ; - - iptr_type _inod ; - iptr_type _jnod ; - } ; - - /* - -------------------------------------------------------- - * MATCH-GRAPH: greedy approx. max-weight matching. - -------------------------------------------------------- - */ - - template < - typename E - > - class graph_match - { - public : - typedef E edge_type ; - - typedef typename - edge_type::cost_type cost_type ; - typedef typename - edge_type::iptr_type iptr_type ; - - class edge_comp - { - public : - __inline_call bool_type operator () ( - edge_type const& _idat, - edge_type const& _jdat - ) const - { return _idat._cost > - _jdat._cost ; - } - } ; - - typedef containers:: array_list < - iptr_type > node_sets ; - - typedef containers::prioritymap < - edge_type , - edge_comp > edge_heap ; - - typedef typename - edge_heap::kptr_type hptr_type ; - - typedef containers:: array < - hptr_type > heap_ptrs ; - - typedef containers:: array < - iptr_type > iptr_list ; - - typedef containers:: array < - edge_type > edge_list ; - - /* - -------------------------------------------------------- - * EDGE-COST: calc. current 'cost' for edge. - -------------------------------------------------------- - */ - - __static_call - __normal_call cost_type edge_cost ( - edge_list &_edge, - iptr_list &_mark, - node_sets &_nadj, - iptr_type _enum - ) - { - cost_type _cost = (cost_type)+0 ; - - cost_type _ival = (cost_type)+0 ; - iptr_type _ideg = (iptr_type)+0 ; - - for (auto _epos = _nadj[ - _edge[_enum]._inod].head(); - _epos != _nadj[ - _edge[_enum]._inod].tend(); - ++_epos ) - { - if (_mark[*_epos] >= +0) - { - if (_enum != *_epos) - { - _ideg += +1 ; - _ival -= - _edge[*_epos]._cost ; - } - } - } - - cost_type _jval = (cost_type)+0 ; - iptr_type _jdeg = (iptr_type)+0 ; - - for (auto _epos = _nadj[ - _edge[_enum]._jnod].head(); - _epos != _nadj[ - _edge[_enum]._jnod].tend(); - ++_epos ) - { - if (_mark[*_epos] >= +0) - { - if (_enum != *_epos) - { - _jdeg += +1 ; - _jval -= - _edge[*_epos]._cost ; - } - } - } - - _cost += _ival ; - _cost += _jval ; - - return _cost+_edge[_enum]._cost ; - } - - /* - -------------------------------------------------------- - * GET-MATCH: find approx. max-weight matching. - -------------------------------------------------------- - */ - - __static_call - __normal_call void_type get_match ( - edge_list &_edge, - edge_list &_pair - ) - { - iptr_type _nmax = (iptr_type)0 ; - node_sets _nadj; - edge_heap _heap; - heap_ptrs _hptr; - iptr_list _nmrk, _emrk, _nset; - - _emrk.set_count(_edge.count(), - containers::loose_alloc, +0); - - _hptr.set_count(_edge.count(), - containers::loose_alloc, +0); - - { - iptr_type _enum = (iptr_type)0 ; - for (auto _epos = _edge.head() ; - _epos != _edge.tend() ; - ++_epos, ++_enum ) - { - _nadj.push ( - _enum, _epos->_inod) ; - _nadj.push ( - _enum, _epos->_jnod) ; - - _nmax = std::max ( - _nmax, _epos->_inod) ; - _nmax = std::max ( - _nmax, _epos->_jnod) ; - } - } - - { - iptr_type _enum = (iptr_type)0 ; - for (auto _epos = _edge.head() ; - _epos != _edge.tend() ; - ++_epos, ++_enum ) - { - edge_type _edat; - _edat._inod = _epos->_inod ; - _edat._jnod = _epos->_jnod ; - - _edat._cost = edge_cost( - _edge, _emrk, _nadj, _enum) ; - - _hptr[*_epos] - = _heap.push( _edat) ; - } - } - - iptr_type _pass = (iptr_type)+0 ; - - _nmrk.set_count(_nmax, - containers::loose_alloc, +0); - - for ( ; !_heap.empty() ; ) - { - edge_type _edat; - _heap._pop_root(_edat) ; - - _pair.push_tail(_edat) ; - - _pass += +1 ; - - _mark[_edat._inod] = _pass ; - _mark[_edat._jnod] = _pass ; - - - _nset.set_count ( +0) ; - - for (auto _epos = - _nadj[_edat._inod].head() ; - _epos != - _nadj[_edat._inod].tend() ; - ++_epos ) - { - if (_emrk[*_epos] >= +0) - { - iptr_type _inod = - _edge[*_epos]._inod; - iptr_type _jnod = - _edge[*_epos]._jnod; - - _emrk[*_epos] = - -_emrk[*_epos]) ; - - if (_mark[_inod] != _pass) - { - _mark[_inod] = _pass; - _nset.push_tail(_inod); - } - if (_mark[_jnod] != _pass) - { - _mark[_jnod] = _pass; - _nset.push_tail(_jnod); - } - - _heap._pop(_hptr[*_epos]); - } - } - - for (auto _epos = - _nadj[_edat._jnod].head() ; - _epos != - _nadj[_edat._jnod].tend() ; - ++_epos ) - { - if (_emrk[*_epos] >= +0) - { - iptr_type _inod = - _edge[*_epos]._inod; - iptr_type _jnod = - _edge[*_epos]._jnod; - - _emrk[*_epos] = - -_emrk[*_epos] ; - - if (_mark[_inod] != _pass) - { - _mark[_inod] = _pass; - _nset.push_tail(_inod); - } - if (_mark[_jnod] != _pass) - { - _mark[_jnod] = _pass; - _nset.push_tail(_jnod); - } - - _heap._pop(_hptr[*_epos]); - } - } - - - for (auto _node =_nset.head(); - _node !=_nset.tend(); - ++_node ) - { - for (auto _epos = - _nadj[*_node].head(); - _epos != - _nadj[*_node].tend(); - ++_epos ) - { - if (_emrk[*_epos] != _pass) - { - edge_type _enew ; - _enew._inod = - _edge[*_epos]._inod ; - _enew._jnod = - _edge[*_epos]._jnod ; - - _emrk[*_epos] = _pass ; - - cost_type _cost = - edge_cost ( - _edge, _emrk, _nadj, *_epos); - - _enew._cost = _cost; - - _heap. - update(_hptr[*_epos], _enew); - } - } - } - - } - - } - - } ; - - - } - -# endif //__MATCH_GRAPH__ - - - diff --git a/src/libcpp/graph_ops/match_hyper.hpp b/src/libcpp/graph_ops/match_hyper.hpp deleted file mode 100644 index 440a8b2..0000000 --- a/src/libcpp/graph_ops/match_hyper.hpp +++ /dev/null @@ -1,46 +0,0 @@ - - /* - -------------------------------------------------------- - * MATCH-HYPER: algorithms for hypergraph matching. - -------------------------------------------------------- - * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) - * - * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The - * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be - * used at your own risk. - * - -------------------------------------------------------- - * - * Last updated: 20 August, 2018 - * - * Copyright 2013-2018 - * Darren Engwirda - * de2363@columbia.edu - * https://github.com/dengwirda/ - * - -------------------------------------------------------- - */ - - - - diff --git a/src/libcpp/hashfunc.hpp b/src/libcpp/hashfunc.hpp index 661e261..d412de7 100644 --- a/src/libcpp/hashfunc.hpp +++ b/src/libcpp/hashfunc.hpp @@ -1,782 +1,783 @@ - -/* -------------------------------------------------------------------------------- -lookup3.c, by Bob Jenkins, May 2006, Public Domain. - -These are functions for producing 32-bit hashes for hash table lookup. -hashword(), hashlittle(), hashlittle2(), hashbig(), mix(), and final() -are externally useful functions. Routines to test the hash are included -if SELF_TEST is defined. You can use this free for any purpose. It's in -the public domain. It has no warranty. - -You probably want to use hashlittle(). hashlittle() and hashbig() -hash byte arrays. hashlittle() is is faster than hashbig() on -little-endian machines. Intel and AMD are little-endian machines. -On second thought, you probably want hashlittle2(), which is identical to -hashlittle() except it returns two 32-bit hashes for the price of one. -You could implement hashbig2() if you wanted but I haven't bothered here. - -If you want to find a hash of, say, exactly 7 integers, do - a = i1; b = i2; c = i3; - mix(a,b,c); - a += i4; b += i5; c += i6; - mix(a,b,c); - a += i7; - final(a,b,c); -then use c as the hash value. If you have a variable length array of -4-byte integers to hash, use hashword(). If you have a byte array (like -a character string), use hashlittle(). If you have several byte arrays, or -a mix of things, see the comments above hashlittle(). - -Why is this so big? I read 12 bytes at a time into 3 4-byte integers, -then mix those integers. This is fast (you can do a lot more thorough -mixing with 12*3 instructions on 3 integers than you can with 3 instructions -on 1 byte), but shoehorning those bytes into integers efficiently is messy. -------------------------------------------------------------------------------- -*/ - -#pragma once - -#ifndef __HASHFUNC__ -#define __HASHFUNC__ - -#include "libbasic.hpp" - -namespace hash { - -/* - * My best guess at if you are big-endian or little-endian. This may - * need adjustment. - */ -#if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && \ - __BYTE_ORDER == __LITTLE_ENDIAN) || \ - (defined(i386) || defined(__i386__) || defined(__i486__) || \ - defined(__i586__) || defined(__i686__) || defined(vax) || defined(MIPSEL)) -# define HASH_LITTLE_ENDIAN 1 -# define HASH_BIG_ENDIAN 0 -#elif (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && \ - __BYTE_ORDER == __BIG_ENDIAN) || \ - (defined(sparc) || defined(POWERPC) || defined(mc68000) || defined(sel)) -# define HASH_LITTLE_ENDIAN 0 -# define HASH_BIG_ENDIAN 1 -#else -# define HASH_LITTLE_ENDIAN 0 -# define HASH_BIG_ENDIAN 0 -#endif - -#define hashsize(n) ((uint32_t)1<<(n)) -#define hashmask(n) (hashsize(n)-1) -#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k)))) - -/* -------------------------------------------------------------------------------- -mix -- mix 3 32-bit values reversibly. - -This is reversible, so any information in (a,b,c) before mix() is -still in (a,b,c) after mix(). - -If four pairs of (a,b,c) inputs are run through mix(), or through -mix() in reverse, there are at least 32 bits of the output that -are sometimes the same for one pair and different for another pair. -This was tested for: -* pairs that differed by one bit, by two bits, in any combination - of top bits of (a,b,c), or in any combination of bottom bits of - (a,b,c). -* "differ" is defined as +, -, ^, or ~^. For + and -, I transformed - the output delta to a Gray code (a^(a>>1)) so a string of 1's (as - is commonly produced by subtraction) look like a single 1-bit - difference. -* the base values were pseudorandom, all zero but one bit set, or - all zero plus a counter that starts at zero. - -Some k values for my "a-=c; a^=rot(c,k); c+=b;" arrangement that -satisfy this are - 4 6 8 16 19 4 - 9 15 3 18 27 15 - 14 9 3 7 17 3 -Well, "9 15 3 18 27 15" didn't quite get 32 bits diffing -for "differ" defined as + with a one-bit base and a two-bit delta. I -used http://burtleburtle.net/bob/hash/avalanche.html to choose -the operations, constants, and arrangements of the variables. - -This does not achieve avalanche. There are input bits of (a,b,c) -that fail to affect some output bits of (a,b,c), especially of a. The -most thoroughly mixed value is c, but it doesn't really even achieve -avalanche in c. - -This allows some parallelism. Read-after-writes are good at doubling -the number of bits affected, so the goal of mixing pulls in the opposite -direction as the goal of parallelism. I did what I could. Rotates -seem to cost as much as shifts on every machine I could lay my hands -on, and rotates are much kinder to the top and bottom bits, so I used -rotates. -------------------------------------------------------------------------------- -*/ -#define mix(a,b,c) \ -{ \ - a -= c; a ^= rot(c, 4); c += b; \ - b -= a; b ^= rot(a, 6); a += c; \ - c -= b; c ^= rot(b, 8); b += a; \ - a -= c; a ^= rot(c,16); c += b; \ - b -= a; b ^= rot(a,19); a += c; \ - c -= b; c ^= rot(b, 4); b += a; \ -} - -/* -------------------------------------------------------------------------------- -final -- final mixing of 3 32-bit values (a,b,c) into c - -Pairs of (a,b,c) values differing in only a few bits will usually -produce values of c that look totally different. This was tested for -* pairs that differed by one bit, by two bits, in any combination - of top bits of (a,b,c), or in any combination of bottom bits of - (a,b,c). -* "differ" is defined as +, -, ^, or ~^. For + and -, I transformed - the output delta to a Gray code (a^(a>>1)) so a string of 1's (as - is commonly produced by subtraction) look like a single 1-bit - difference. -* the base values were pseudorandom, all zero but one bit set, or - all zero plus a counter that starts at zero. - -These constants passed: - 14 11 25 16 4 14 24 - 12 14 25 16 4 14 24 -and these came close: - 4 8 15 26 3 22 24 - 10 8 15 26 3 22 24 - 11 8 15 26 3 22 24 -------------------------------------------------------------------------------- -*/ -#define final(a,b,c) \ -{ \ - c ^= b; c -= rot(b,14); \ - a ^= c; a -= rot(c,11); \ - b ^= a; b -= rot(a,25); \ - c ^= b; c -= rot(b,16); \ - a ^= c; a -= rot(c,4); \ - b ^= a; b -= rot(a,14); \ - c ^= b; c -= rot(b,24); \ -} - -/* -------------------------------------------------------------------------------- -This works on all machines. To be useful, it requires --- that the key be an array of uint32_t's, and --- that the length be the number of uint32_t's in the key - -The function hashword() is identical to hashlittle() on little-endian -machines, and identical to hashbig() on big-endian machines, -except that the length has to be measured in uint32_ts rather than in -bytes. hashlittle() is more complicated than hashword() only because -hashlittle() has to dance around fitting the key bytes into registers. -------------------------------------------------------------------------------- -*/ -uint32_t hashword( -const uint32_t *k, /* the key, an array of uint32_t values */ -size_t length, /* the length of the key, in uint32_ts */ -uint32_t initval) /* the previous hash, or an arbitrary value */ -{ - uint32_t a,b,c; - - /* Set up the internal state */ - a = b = c = 0xdeadbeef + (((uint32_t)length)<<2) + initval; - - /*------------------------------------------------- handle most of the key */ - while (length > 3) - { - a += k[0]; - b += k[1]; - c += k[2]; - mix(a,b,c); - length -= 3; - k += 3; - } - - /*------------------------------------------- handle the last 3 uint32_t's */ - switch(length) /* all the case statements fall through */ - { - case 3 : c+=k[2]; /* fall through */ - case 2 : b+=k[1]; /* fall through */ - case 1 : a+=k[0]; /* fall through */ - final(a,b,c); - case 0: /* case 0: nothing left to add */ - break; - } - /*------------------------------------------------------ report the result */ - return c; -} - - -/* -------------------------------------------------------------------------------- -hashword2() -- same as hashword(), but take two seeds and return two -32-bit values. pc and pb must both be nonnull, and *pc and *pb must -both be initialized with seeds. If you pass in (*pb)==0, the output -(*pc) will be the same as the return value from hashword(). -------------------------------------------------------------------------------- -*/ -void hashword2 ( -const uint32_t *k, /* the key, an array of uint32_t values */ -size_t length, /* the length of the key, in uint32_ts */ -uint32_t *pc, /* IN: seed OUT: primary hash value */ -uint32_t *pb) /* IN: more seed OUT: secondary hash value */ -{ - uint32_t a,b,c; - - /* Set up the internal state */ - a = b = c = 0xdeadbeef + ((uint32_t)(length<<2)) + *pc; - c += *pb; - - /*------------------------------------------------- handle most of the key */ - while (length > 3) - { - a += k[0]; - b += k[1]; - c += k[2]; - mix(a,b,c); - length -= 3; - k += 3; - } - - /*------------------------------------------- handle the last 3 uint32_t's */ - switch(length) /* all the case statements fall through */ - { - case 3 : c+=k[2]; /* fall through */ - case 2 : b+=k[1]; /* fall through */ - case 1 : a+=k[0]; /* fall through */ - final(a,b,c); - case 0: /* case 0: nothing left to add */ - break; - } - /*------------------------------------------------------ report the result */ - *pc=c; *pb=b; -} - - -/* -------------------------------------------------------------------------------- -hashlittle() -- hash a variable-length key into a 32-bit value - k : the key (the unaligned variable-length array of bytes) - length : the length of the key, counting by bytes - initval : can be any 4-byte value -Returns a 32-bit value. Every bit of the key affects every bit of -the return value. Two keys differing by one or two bits will have -totally different hash values. - -The best hash table sizes are powers of 2. There is no need to do -mod a prime (mod is sooo slow!). If you need less than 32 bits, -use a bitmask. For example, if you need only 10 bits, do - h = (h & hashmask(10)); -In which case, the hash table should have hashsize(10) elements. - -If you are hashing n strings (uint8_t **)k, do it like this: - for (i=0, h=0; i 12) - { - a += k[0]; - b += k[1]; - c += k[2]; - mix(a,b,c); - length -= 12; - k += 3; - } - - /*----------------------------- handle the last (probably partial) block */ - /* - * "k[2]&0xffffff" actually reads beyond the end of the string, but - * then masks off the part it's not allowed to read. Because the - * string is aligned, the masked-off tail is in the same word as the - * rest of the string. Every machine with memory protection I've seen - * does it on word boundaries, so is OK with this. But VALGRIND will - * still catch it and complain. The masking trick does make the hash - * noticably faster for short strings (like English words). - */ -#ifndef VALGRIND - - switch(length) - { - case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; - case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break; - case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break; - case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break; - case 8 : b+=k[1]; a+=k[0]; break; - case 7 : b+=k[1]&0xffffff; a+=k[0]; break; - case 6 : b+=k[1]&0xffff; a+=k[0]; break; - case 5 : b+=k[1]&0xff; a+=k[0]; break; - case 4 : a+=k[0]; break; - case 3 : a+=k[0]&0xffffff; break; - case 2 : a+=k[0]&0xffff; break; - case 1 : a+=k[0]&0xff; break; - case 0 : return c; /* zero length strings require no mixing */ - } - -#else /* make valgrind happy */ - - k8 = (const uint8_t *)k; - switch(length) - { - case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; - case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ - case 10: c+=((uint32_t)k8[9])<<8; /* fall through */ - case 9 : c+=k8[8]; /* fall through */ - case 8 : b+=k[1]; a+=k[0]; break; - case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ - case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */ - case 5 : b+=k8[4]; /* fall through */ - case 4 : a+=k[0]; break; - case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ - case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */ - case 1 : a+=k8[0]; break; - case 0 : return c; - } - -#endif /* !valgrind */ - - } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) { - const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */ - const uint8_t *k8; - - __unreferenced( k8) ; - - /*--------------- all but last block: aligned reads and different mixing */ - while (length > 12) - { - a += k[0] + (((uint32_t)k[1])<<16); - b += k[2] + (((uint32_t)k[3])<<16); - c += k[4] + (((uint32_t)k[5])<<16); - mix(a,b,c); - length -= 12; - k += 6; - } - - /*----------------------------- handle the last (probably partial) block */ - k8 = (const uint8_t *)k; - switch(length) - { - case 12: c+=k[4]+(((uint32_t)k[5])<<16); - b+=k[2]+(((uint32_t)k[3])<<16); - a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ - case 10: c+=k[4]; - b+=k[2]+(((uint32_t)k[3])<<16); - a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 9 : c+=k8[8]; /* fall through */ - case 8 : b+=k[2]+(((uint32_t)k[3])<<16); - a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ - case 6 : b+=k[2]; - a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 5 : b+=k8[4]; /* fall through */ - case 4 : a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ - case 2 : a+=k[0]; - break; - case 1 : a+=k8[0]; - break; - case 0 : return c; /* zero length requires no mixing */ - } - - } else { /* need to read the key one byte at a time */ - const uint8_t *k = (const uint8_t *)key; - - /*--------------- all but the last block: affect some 32 bits of (a,b,c) */ - while (length > 12) - { - a += k[0]; - a += ((uint32_t)k[1])<<8; - a += ((uint32_t)k[2])<<16; - a += ((uint32_t)k[3])<<24; - b += k[4]; - b += ((uint32_t)k[5])<<8; - b += ((uint32_t)k[6])<<16; - b += ((uint32_t)k[7])<<24; - c += k[8]; - c += ((uint32_t)k[9])<<8; - c += ((uint32_t)k[10])<<16; - c += ((uint32_t)k[11])<<24; - mix(a,b,c); - length -= 12; - k += 12; - } - - /*-------------------------------- last block: affect all 32 bits of (c) */ - switch(length) /* all the case statements fall through */ - { - case 12: c+=((uint32_t)k[11])<<24; /* fall through */ - case 11: c+=((uint32_t)k[10])<<16; /* fall through */ - case 10: c+=((uint32_t)k[9])<<8; /* fall through */ - case 9 : c+=k[8]; /* fall through */ - case 8 : b+=((uint32_t)k[7])<<24; /* fall through */ - case 7 : b+=((uint32_t)k[6])<<16; /* fall through */ - case 6 : b+=((uint32_t)k[5])<<8; /* fall through */ - case 5 : b+=k[4]; /* fall through */ - case 4 : a+=((uint32_t)k[3])<<24; /* fall through */ - case 3 : a+=((uint32_t)k[2])<<16; /* fall through */ - case 2 : a+=((uint32_t)k[1])<<8; /* fall through */ - case 1 : a+=k[0]; - break; - case 0 : return c; - } - } - - final(a,b,c); - return c; -} - - -/* - * hashlittle2: return 2 32-bit hash values - * - * This is identical to hashlittle(), except it returns two 32-bit hash - * values instead of just one. This is good enough for hash table - * lookup with 2^^64 buckets, or if you want a second hash if you're not - * happy with the first, or if you want a probably-unique 64-bit ID for - * the key. *pc is better mixed than *pb, so use *pc first. If you want - * a 64-bit value do something like "*pc + (((uint64_t)*pb)<<32)". - */ -void hashlittle2( - const void *key, /* the key to hash */ - size_t length, /* length of the key */ - uint32_t *pc, /* IN: primary initval, OUT: primary hash */ - uint32_t *pb) /* IN: secondary initval, OUT: secondary hash */ -{ - uint32_t a,b,c; /* internal state */ - union { const void *ptr; size_t i; } u; /* needed for Mac Powerbook G4 */ - - /* Set up the internal state */ - a = b = c = 0xdeadbeef + ((uint32_t)length) + *pc; - c += *pb; - - u.ptr = key; - if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) { - const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */ - const uint8_t *k8; - - __unreferenced( k8) ; - - /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */ - while (length > 12) - { - a += k[0]; - b += k[1]; - c += k[2]; - mix(a,b,c); - length -= 12; - k += 3; - } - - /*----------------------------- handle the last (probably partial) block */ - /* - * "k[2]&0xffffff" actually reads beyond the end of the string, but - * then masks off the part it's not allowed to read. Because the - * string is aligned, the masked-off tail is in the same word as the - * rest of the string. Every machine with memory protection I've seen - * does it on word boundaries, so is OK with this. But VALGRIND will - * still catch it and complain. The masking trick does make the hash - * noticably faster for short strings (like English words). - */ -#ifndef VALGRIND - - switch(length) - { - case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; - case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break; - case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break; - case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break; - case 8 : b+=k[1]; a+=k[0]; break; - case 7 : b+=k[1]&0xffffff; a+=k[0]; break; - case 6 : b+=k[1]&0xffff; a+=k[0]; break; - case 5 : b+=k[1]&0xff; a+=k[0]; break; - case 4 : a+=k[0]; break; - case 3 : a+=k[0]&0xffffff; break; - case 2 : a+=k[0]&0xffff; break; - case 1 : a+=k[0]&0xff; break; - case 0 : *pc=c; *pb=b; return; /* zero length strings require no mixing */ - } - -#else /* make valgrind happy */ - - k8 = (const uint8_t *)k; - switch(length) - { - case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; - case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ - case 10: c+=((uint32_t)k8[9])<<8; /* fall through */ - case 9 : c+=k8[8]; /* fall through */ - case 8 : b+=k[1]; a+=k[0]; break; - case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ - case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */ - case 5 : b+=k8[4]; /* fall through */ - case 4 : a+=k[0]; break; - case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ - case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */ - case 1 : a+=k8[0]; break; - case 0 : *pc=c; *pb=b; return; /* zero length strings require no mixing */ - } - -#endif /* !valgrind */ - - } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) { - const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */ - const uint8_t *k8; - - __unreferenced( k8) ; - - /*--------------- all but last block: aligned reads and different mixing */ - while (length > 12) - { - a += k[0] + (((uint32_t)k[1])<<16); - b += k[2] + (((uint32_t)k[3])<<16); - c += k[4] + (((uint32_t)k[5])<<16); - mix(a,b,c); - length -= 12; - k += 6; - } - - /*----------------------------- handle the last (probably partial) block */ - k8 = (const uint8_t *)k; - switch(length) - { - case 12: c+=k[4]+(((uint32_t)k[5])<<16); - b+=k[2]+(((uint32_t)k[3])<<16); - a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ - case 10: c+=k[4]; - b+=k[2]+(((uint32_t)k[3])<<16); - a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 9 : c+=k8[8]; /* fall through */ - case 8 : b+=k[2]+(((uint32_t)k[3])<<16); - a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ - case 6 : b+=k[2]; - a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 5 : b+=k8[4]; /* fall through */ - case 4 : a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ - case 2 : a+=k[0]; - break; - case 1 : a+=k8[0]; - break; - case 0 : *pc=c; *pb=b; return; /* zero length strings require no mixing */ - } - - } else { /* need to read the key one byte at a time */ - const uint8_t *k = (const uint8_t *)key; - - /*--------------- all but the last block: affect some 32 bits of (a,b,c) */ - while (length > 12) - { - a += k[0]; - a += ((uint32_t)k[1])<<8; - a += ((uint32_t)k[2])<<16; - a += ((uint32_t)k[3])<<24; - b += k[4]; - b += ((uint32_t)k[5])<<8; - b += ((uint32_t)k[6])<<16; - b += ((uint32_t)k[7])<<24; - c += k[8]; - c += ((uint32_t)k[9])<<8; - c += ((uint32_t)k[10])<<16; - c += ((uint32_t)k[11])<<24; - mix(a,b,c); - length -= 12; - k += 12; - } - - /*-------------------------------- last block: affect all 32 bits of (c) */ - switch(length) /* all the case statements fall through */ - { - case 12: c+=((uint32_t)k[11])<<24; /* fall through */ - case 11: c+=((uint32_t)k[10])<<16; /* fall through */ - case 10: c+=((uint32_t)k[9])<<8; /* fall through */ - case 9 : c+=k[8]; /* fall through */ - case 8 : b+=((uint32_t)k[7])<<24; /* fall through */ - case 7 : b+=((uint32_t)k[6])<<16; /* fall through */ - case 6 : b+=((uint32_t)k[5])<<8; /* fall through */ - case 5 : b+=k[4]; /* fall through */ - case 4 : a+=((uint32_t)k[3])<<24; /* fall through */ - case 3 : a+=((uint32_t)k[2])<<16; /* fall through */ - case 2 : a+=((uint32_t)k[1])<<8; /* fall through */ - case 1 : a+=k[0]; - break; - case 0 : *pc=c; *pb=b; return; /* zero length strings require no mixing */ - } - } - - final(a,b,c); - *pc=c; *pb=b; -} - - - -/* - * hashbig(): - * This is the same as hashword() on big-endian machines. It is different - * from hashlittle() on all machines. hashbig() takes advantage of - * big-endian byte ordering. - */ -uint32_t hashbig( const void *key, size_t length, uint32_t initval) -{ - uint32_t a,b,c; - union { const void *ptr; size_t i; } u; /* to cast key to (size_t) happily */ - - /* Set up the internal state */ - a = b = c = 0xdeadbeef + ((uint32_t)length) + initval; - - u.ptr = key; - if (HASH_BIG_ENDIAN && ((u.i & 0x3) == 0)) { - const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */ - const uint8_t *k8; - - __unreferenced( k8) ; - - /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */ - while (length > 12) - { - a += k[0]; - b += k[1]; - c += k[2]; - mix(a,b,c); - length -= 12; - k += 3; - } - - /*----------------------------- handle the last (probably partial) block */ - /* - * "k[2]<<8" actually reads beyond the end of the string, but - * then shifts out the part it's not allowed to read. Because the - * string is aligned, the illegal read is in the same word as the - * rest of the string. Every machine with memory protection I've seen - * does it on word boundaries, so is OK with this. But VALGRIND will - * still catch it and complain. The masking trick does make the hash - * noticably faster for short strings (like English words). - */ -#ifndef VALGRIND - - switch(length) - { - case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; - case 11: c+=k[2]&0xffffff00; b+=k[1]; a+=k[0]; break; - case 10: c+=k[2]&0xffff0000; b+=k[1]; a+=k[0]; break; - case 9 : c+=k[2]&0xff000000; b+=k[1]; a+=k[0]; break; - case 8 : b+=k[1]; a+=k[0]; break; - case 7 : b+=k[1]&0xffffff00; a+=k[0]; break; - case 6 : b+=k[1]&0xffff0000; a+=k[0]; break; - case 5 : b+=k[1]&0xff000000; a+=k[0]; break; - case 4 : a+=k[0]; break; - case 3 : a+=k[0]&0xffffff00; break; - case 2 : a+=k[0]&0xffff0000; break; - case 1 : a+=k[0]&0xff000000; break; - case 0 : return c; /* zero length strings require no mixing */ - } - -#else /* make valgrind happy */ - - k8 = (const uint8_t *)k; - switch(length) /* all the case statements fall through */ - { - case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; - case 11: c+=((uint32_t)k8[10])<<8; /* fall through */ - case 10: c+=((uint32_t)k8[9])<<16; /* fall through */ - case 9 : c+=((uint32_t)k8[8])<<24; /* fall through */ - case 8 : b+=k[1]; a+=k[0]; break; - case 7 : b+=((uint32_t)k8[6])<<8; /* fall through */ - case 6 : b+=((uint32_t)k8[5])<<16; /* fall through */ - case 5 : b+=((uint32_t)k8[4])<<24; /* fall through */ - case 4 : a+=k[0]; break; - case 3 : a+=((uint32_t)k8[2])<<8; /* fall through */ - case 2 : a+=((uint32_t)k8[1])<<16; /* fall through */ - case 1 : a+=((uint32_t)k8[0])<<24; break; - case 0 : return c; - } - -#endif /* !VALGRIND */ - - } else { /* need to read the key one byte at a time */ - const uint8_t *k = (const uint8_t *)key; - - /*--------------- all but the last block: affect some 32 bits of (a,b,c) */ - while (length > 12) - { - a += ((uint32_t)k[0])<<24; - a += ((uint32_t)k[1])<<16; - a += ((uint32_t)k[2])<<8; - a += ((uint32_t)k[3]); - b += ((uint32_t)k[4])<<24; - b += ((uint32_t)k[5])<<16; - b += ((uint32_t)k[6])<<8; - b += ((uint32_t)k[7]); - c += ((uint32_t)k[8])<<24; - c += ((uint32_t)k[9])<<16; - c += ((uint32_t)k[10])<<8; - c += ((uint32_t)k[11]); - mix(a,b,c); - length -= 12; - k += 12; - } - - /*-------------------------------- last block: affect all 32 bits of (c) */ - switch(length) /* all the case statements fall through */ - { - case 12: c+=k[11]; /* fall through */ - case 11: c+=((uint32_t)k[10])<<8; /* fall through */ - case 10: c+=((uint32_t)k[9])<<16; /* fall through */ - case 9 : c+=((uint32_t)k[8])<<24; /* fall through */ - case 8 : b+=k[7]; /* fall through */ - case 7 : b+=((uint32_t)k[6])<<8; /* fall through */ - case 6 : b+=((uint32_t)k[5])<<16; /* fall through */ - case 5 : b+=((uint32_t)k[4])<<24; /* fall through */ - case 4 : a+=k[3]; /* fall through */ - case 3 : a+=((uint32_t)k[2])<<8; /* fall through */ - case 2 : a+=((uint32_t)k[1])<<16; /* fall through */ - case 1 : a+=((uint32_t)k[0])<<24; - break; - case 0 : return c; - } - } - - final(a,b,c); - return c; -} - -} // hash - -#endif//__HASHFUNC__ - - - + +/* +------------------------------------------------------------------------------- +lookup3.c, by Bob Jenkins, May 2006, Public Domain. + +These are functions for producing 32-bit hashes for hash table lookup. +hashword(), hashlittle(), hashlittle2(), hashbig(), mix(), and final() +are externally useful functions. Routines to test the hash are included +if SELF_TEST is defined. You can use this free for any purpose. It's in +the public domain. It has no warranty. + +You probably want to use hashlittle(). hashlittle() and hashbig() +hash byte arrays. hashlittle() is is faster than hashbig() on +little-endian machines. Intel and AMD are little-endian machines. +On second thought, you probably want hashlittle2(), which is identical to +hashlittle() except it returns two 32-bit hashes for the price of one. +You could implement hashbig2() if you wanted but I haven't bothered here. + +If you want to find a hash of, say, exactly 7 integers, do + a = i1; b = i2; c = i3; + mix(a,b,c); + a += i4; b += i5; c += i6; + mix(a,b,c); + a += i7; + final(a,b,c); +then use c as the hash value. If you have a variable length array of +4-byte integers to hash, use hashword(). If you have a byte array (like +a character string), use hashlittle(). If you have several byte arrays, or +a mix of things, see the comments above hashlittle(). + +Why is this so big? I read 12 bytes at a time into 3 4-byte integers, +then mix those integers. This is fast (you can do a lot more thorough +mixing with 12*3 instructions on 3 integers than you can with 3 instructions +on 1 byte), but shoehorning those bytes into integers efficiently is messy. +------------------------------------------------------------------------------- +*/ + +#pragma once + +#ifndef __HASHFUNC__ +#define __HASHFUNC__ + +#include "libbasic.hpp" + +namespace hash { + +/* + * My best guess at if you are big-endian or little-endian. This may + * need adjustment. + */ +#if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && \ + __BYTE_ORDER == __LITTLE_ENDIAN) || \ + (defined(i386) || defined(__i386__) || defined(__i486__) || \ + defined(__i586__) || defined(__i686__) || defined(vax) || defined(MIPSEL)) +# define HASH_LITTLE_ENDIAN 1 +# define HASH_BIG_ENDIAN 0 +#elif (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && \ + __BYTE_ORDER == __BIG_ENDIAN) || \ + (defined(sparc) || defined(POWERPC) || defined(mc68000) || defined(sel)) +# define HASH_LITTLE_ENDIAN 0 +# define HASH_BIG_ENDIAN 1 +#else +# define HASH_LITTLE_ENDIAN 0 +# define HASH_BIG_ENDIAN 0 +#endif + +#define hashsize(n) ((uint32_t)1<<(n)) +#define hashmask(n) (hashsize(n)-1) + +/* +------------------------------------------------------------------------------- +mix -- mix 3 32-bit values reversibly. + +This is reversible, so any information in (a,b,c) before mix() is +still in (a,b,c) after mix(). + +If four pairs of (a,b,c) inputs are run through mix(), or through +mix() in reverse, there are at least 32 bits of the output that +are sometimes the same for one pair and different for another pair. +This was tested for: +* pairs that differed by one bit, by two bits, in any combination + of top bits of (a,b,c), or in any combination of bottom bits of + (a,b,c). +* "differ" is defined as +, -, ^, or ~^. For + and -, I transformed + the output delta to a Gray code (a^(a>>1)) so a string of 1's (as + is commonly produced by subtraction) look like a single 1-bit + difference. +* the base values were pseudorandom, all zero but one bit set, or + all zero plus a counter that starts at zero. + +Some k values for my "a-=c; a^=rot(c,k); c+=b;" arrangement that +satisfy this are + 4 6 8 16 19 4 + 9 15 3 18 27 15 + 14 9 3 7 17 3 +Well, "9 15 3 18 27 15" didn't quite get 32 bits diffing +for "differ" defined as + with a one-bit base and a two-bit delta. I +used http://burtleburtle.net/bob/hash/avalanche.html to choose +the operations, constants, and arrangements of the variables. + +This does not achieve avalanche. There are input bits of (a,b,c) +that fail to affect some output bits of (a,b,c), especially of a. The +most thoroughly mixed value is c, but it doesn't really even achieve +avalanche in c. + +This allows some parallelism. Read-after-writes are good at doubling +the number of bits affected, so the goal of mixing pulls in the opposite +direction as the goal of parallelism. I did what I could. Rotates +seem to cost as much as shifts on every machine I could lay my hands +on, and rotates are much kinder to the top and bottom bits, so I used +rotates. +------------------------------------------------------------------------------- +*/ +#define ROT(x,k) (((x)<<(k)) | ((x)>>(32-(k)))) + +#define MIX(a,b,c) \ +{ \ + a -= c; a ^= ROT(c, 4); c += b; \ + b -= a; b ^= ROT(a, 6); a += c; \ + c -= b; c ^= ROT(b, 8); b += a; \ + a -= c; a ^= ROT(c,16); c += b; \ + b -= a; b ^= ROT(a,19); a += c; \ + c -= b; c ^= ROT(b, 4); b += a; \ +} + +/* +------------------------------------------------------------------------------- +final -- final mixing of 3 32-bit values (a,b,c) into c + +Pairs of (a,b,c) values differing in only a few bits will usually +produce values of c that look totally different. This was tested for +* pairs that differed by one bit, by two bits, in any combination + of top bits of (a,b,c), or in any combination of bottom bits of + (a,b,c). +* "differ" is defined as +, -, ^, or ~^. For + and -, I transformed + the output delta to a Gray code (a^(a>>1)) so a string of 1's (as + is commonly produced by subtraction) look like a single 1-bit + difference. +* the base values were pseudorandom, all zero but one bit set, or + all zero plus a counter that starts at zero. + +These constants passed: + 14 11 25 16 4 14 24 + 12 14 25 16 4 14 24 +and these came close: + 4 8 15 26 3 22 24 + 10 8 15 26 3 22 24 + 11 8 15 26 3 22 24 +------------------------------------------------------------------------------- +*/ +#define FINAL(a,b,c) \ +{ \ + c ^= b; c -= ROT(b,14); \ + a ^= c; a -= ROT(c,11); \ + b ^= a; b -= ROT(a,25); \ + c ^= b; c -= ROT(b,16); \ + a ^= c; a -= ROT(c,4); \ + b ^= a; b -= ROT(a,14); \ + c ^= b; c -= ROT(b,24); \ +} + +/* +------------------------------------------------------------------------------- +This works on all machines. To be useful, it requires +-- that the key be an array of uint32_t's, and +-- that the length be the number of uint32_t's in the key + +The function hashword() is identical to hashlittle() on little-endian +machines, and identical to hashbig() on big-endian machines, +except that the length has to be measured in uint32_ts rather than in +bytes. hashlittle() is more complicated than hashword() only because +hashlittle() has to dance around fitting the key bytes into registers. +------------------------------------------------------------------------------- +*/ +uint32_t hashword ( +__const_ptr(uint32_t) k, /* the key, an array of uint32_t values */ +size_t length, /* the length of the key, in uint32_ts */ +uint32_t initval) /* the previous hash, or an arbitrary value */ +{ + uint32_t a,b,c; + + /* Set up the internal state */ + a = b = c = 0xdeadbeef + (((uint32_t)length)<<2) + initval; + + /*------------------------------------------------- handle most of the key */ + while (length > 3) + { + a += k[0]; + b += k[1]; + c += k[2]; + MIX(a,b,c); + length -= 3; + k += 3; + } + + /*------------------------------------------- handle the last 3 uint32_t's */ + switch(length) /* all the case statements fall through */ + { + case 3 : c+=k[2]; /* fall through */ + case 2 : b+=k[1]; /* fall through */ + case 1 : a+=k[0]; /* fall through */ + FINAL(a,b,c); + case 0: /* case 0: nothing left to add */ + break; + } + /*------------------------------------------------------ report the result */ + return c; +} + + +/* +------------------------------------------------------------------------------- +hashword2() -- same as hashword(), but take two seeds and return two +32-bit values. pc and pb must both be nonnull, and *pc and *pb must +both be initialized with seeds. If you pass in (*pb)==0, the output +(*pc) will be the same as the return value from hashword(). +------------------------------------------------------------------------------- +*/ +void hashword2 ( +__const_ptr(uint32_t) k, /* the key, an array of uint32_t values */ +size_t length, /* the length of the key, in uint32_ts */ +__write_ptr(uint32_t) pc, /* IN: seed OUT: primary hash value */ +__write_ptr(uint32_t) pb) /* IN: more seed OUT: secondary hash value */ +{ + uint32_t a,b,c; + + /* Set up the internal state */ + a = b = c = 0xdeadbeef + ((uint32_t)(length<<2)) + *pc; + c += *pb; + + /*------------------------------------------------- handle most of the key */ + while (length > 3) + { + a += k[0]; + b += k[1]; + c += k[2]; + MIX(a,b,c); + length -= 3; + k += 3; + } + + /*------------------------------------------- handle the last 3 uint32_t's */ + switch(length) /* all the case statements fall through */ + { + case 3 : c+=k[2]; /* fall through */ + case 2 : b+=k[1]; /* fall through */ + case 1 : a+=k[0]; /* fall through */ + FINAL(a,b,c); + case 0: /* case 0: nothing left to add */ + break; + } + /*------------------------------------------------------ report the result */ + *pc=c; *pb=b; +} + + +/* +------------------------------------------------------------------------------- +hashlittle() -- hash a variable-length key into a 32-bit value + k : the key (the unaligned variable-length array of bytes) + length : the length of the key, counting by bytes + initval : can be any 4-byte value +Returns a 32-bit value. Every bit of the key affects every bit of +the return value. Two keys differing by one or two bits will have +totally different hash values. + +The best hash table sizes are powers of 2. There is no need to do +mod a prime (mod is sooo slow!). If you need less than 32 bits, +use a bitmask. For example, if you need only 10 bits, do + h = (h & hashmask(10)); +In which case, the hash table should have hashsize(10) elements. + +If you are hashing n strings (uint8_t **)k, do it like this: + for (i=0, h=0; i 12) + { + a += k[0]; + b += k[1]; + c += k[2]; + MIX(a,b,c); + length -= 12; + k += 3; + } + + /*----------------------------- handle the last (probably partial) block */ + /* + * "k[2]&0xffffff" actually reads beyond the end of the string, but + * then masks off the part it's not allowed to read. Because the + * string is aligned, the masked-off tail is in the same word as the + * rest of the string. Every machine with memory protection I've seen + * does it on word boundaries, so is OK with this. But VALGRIND will + * still catch it and complain. The masking trick does make the hash + * noticably faster for short strings (like English words). + */ +#ifndef VALGRIND + + switch(length) + { + case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; + case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break; + case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break; + case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break; + case 8 : b+=k[1]; a+=k[0]; break; + case 7 : b+=k[1]&0xffffff; a+=k[0]; break; + case 6 : b+=k[1]&0xffff; a+=k[0]; break; + case 5 : b+=k[1]&0xff; a+=k[0]; break; + case 4 : a+=k[0]; break; + case 3 : a+=k[0]&0xffffff; break; + case 2 : a+=k[0]&0xffff; break; + case 1 : a+=k[0]&0xff; break; + case 0 : return c; /* zero length strings require no mixing */ + } + +#else /* make valgrind happy */ + + k8 = (const uint8_t *)k; + switch(length) + { + case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; + case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ + case 10: c+=((uint32_t)k8[9])<<8; /* fall through */ + case 9 : c+=k8[8]; /* fall through */ + case 8 : b+=k[1]; a+=k[0]; break; + case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ + case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */ + case 5 : b+=k8[4]; /* fall through */ + case 4 : a+=k[0]; break; + case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ + case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */ + case 1 : a+=k8[0]; break; + case 0 : return c; + } + +#endif /* !valgrind */ + + } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) { + const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */ + const uint8_t *k8; + + __unreferenced( k8) ; + + /*--------------- all but last block: aligned reads and different mixing */ + while (length > 12) + { + a += k[0] + (((uint32_t)k[1])<<16); + b += k[2] + (((uint32_t)k[3])<<16); + c += k[4] + (((uint32_t)k[5])<<16); + MIX(a,b,c); + length -= 12; + k += 6; + } + + /*----------------------------- handle the last (probably partial) block */ + k8 = (const uint8_t *)k; + switch(length) + { + case 12: c+=k[4]+(((uint32_t)k[5])<<16); + b+=k[2]+(((uint32_t)k[3])<<16); + a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ + case 10: c+=k[4]; + b+=k[2]+(((uint32_t)k[3])<<16); + a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 9 : c+=k8[8]; /* fall through */ + case 8 : b+=k[2]+(((uint32_t)k[3])<<16); + a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ + case 6 : b+=k[2]; + a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 5 : b+=k8[4]; /* fall through */ + case 4 : a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ + case 2 : a+=k[0]; + break; + case 1 : a+=k8[0]; + break; + case 0 : return c; /* zero length requires no mixing */ + } + + } else { /* need to read the key one byte at a time */ + const uint8_t *k = (const uint8_t *)key; + + /*--------------- all but the last block: affect some 32 bits of (a,b,c) */ + while (length > 12) + { + a += k[0]; + a += ((uint32_t)k[1])<<8; + a += ((uint32_t)k[2])<<16; + a += ((uint32_t)k[3])<<24; + b += k[4]; + b += ((uint32_t)k[5])<<8; + b += ((uint32_t)k[6])<<16; + b += ((uint32_t)k[7])<<24; + c += k[8]; + c += ((uint32_t)k[9])<<8; + c += ((uint32_t)k[10])<<16; + c += ((uint32_t)k[11])<<24; + MIX(a,b,c); + length -= 12; + k += 12; + } + + /*-------------------------------- last block: affect all 32 bits of (c) */ + switch(length) /* all the case statements fall through */ + { + case 12: c+=((uint32_t)k[11])<<24; /* fall through */ + case 11: c+=((uint32_t)k[10])<<16; /* fall through */ + case 10: c+=((uint32_t)k[9])<<8; /* fall through */ + case 9 : c+=k[8]; /* fall through */ + case 8 : b+=((uint32_t)k[7])<<24; /* fall through */ + case 7 : b+=((uint32_t)k[6])<<16; /* fall through */ + case 6 : b+=((uint32_t)k[5])<<8; /* fall through */ + case 5 : b+=k[4]; /* fall through */ + case 4 : a+=((uint32_t)k[3])<<24; /* fall through */ + case 3 : a+=((uint32_t)k[2])<<16; /* fall through */ + case 2 : a+=((uint32_t)k[1])<<8; /* fall through */ + case 1 : a+=k[0]; + break; + case 0 : return c; + } + } + + FINAL(a,b,c); + return c; +} + + +/* + * hashlittle2: return 2 32-bit hash values + * + * This is identical to hashlittle(), except it returns two 32-bit hash + * values instead of just one. This is good enough for hash table + * lookup with 2^^64 buckets, or if you want a second hash if you're not + * happy with the first, or if you want a probably-unique 64-bit ID for + * the key. *pc is better mixed than *pb, so use *pc first. If you want + * a 64-bit value do something like "*pc + (((uint64_t)*pb)<<32)". + */ +void hashlittle2( + const void *key, /* the key to hash */ + size_t length, /* length of the key */ + uint32_t *pc, /* IN: primary initval, OUT: primary hash */ + uint32_t *pb) /* IN: secondary initval, OUT: secondary hash */ +{ + uint32_t a,b,c; /* internal state */ + union { const void *ptr; size_t i; } u; /* needed for Mac Powerbook G4 */ + + /* Set up the internal state */ + a = b = c = 0xdeadbeef + ((uint32_t)length) + *pc; + c += *pb; + + u.ptr = key; + if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) { + const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */ + const uint8_t *k8; + + __unreferenced( k8) ; + + /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */ + while (length > 12) + { + a += k[0]; + b += k[1]; + c += k[2]; + MIX(a,b,c); + length -= 12; + k += 3; + } + + /*----------------------------- handle the last (probably partial) block */ + /* + * "k[2]&0xffffff" actually reads beyond the end of the string, but + * then masks off the part it's not allowed to read. Because the + * string is aligned, the masked-off tail is in the same word as the + * rest of the string. Every machine with memory protection I've seen + * does it on word boundaries, so is OK with this. But VALGRIND will + * still catch it and complain. The masking trick does make the hash + * noticably faster for short strings (like English words). + */ +#ifndef VALGRIND + + switch(length) + { + case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; + case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break; + case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break; + case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break; + case 8 : b+=k[1]; a+=k[0]; break; + case 7 : b+=k[1]&0xffffff; a+=k[0]; break; + case 6 : b+=k[1]&0xffff; a+=k[0]; break; + case 5 : b+=k[1]&0xff; a+=k[0]; break; + case 4 : a+=k[0]; break; + case 3 : a+=k[0]&0xffffff; break; + case 2 : a+=k[0]&0xffff; break; + case 1 : a+=k[0]&0xff; break; + case 0 : *pc=c; *pb=b; return; /* zero length strings require no mixing */ + } + +#else /* make valgrind happy */ + + k8 = (const uint8_t *)k; + switch(length) + { + case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; + case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ + case 10: c+=((uint32_t)k8[9])<<8; /* fall through */ + case 9 : c+=k8[8]; /* fall through */ + case 8 : b+=k[1]; a+=k[0]; break; + case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ + case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */ + case 5 : b+=k8[4]; /* fall through */ + case 4 : a+=k[0]; break; + case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ + case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */ + case 1 : a+=k8[0]; break; + case 0 : *pc=c; *pb=b; return; /* zero length strings require no mixing */ + } + +#endif /* !valgrind */ + + } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) { + const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */ + const uint8_t *k8; + + __unreferenced( k8) ; + + /*--------------- all but last block: aligned reads and different mixing */ + while (length > 12) + { + a += k[0] + (((uint32_t)k[1])<<16); + b += k[2] + (((uint32_t)k[3])<<16); + c += k[4] + (((uint32_t)k[5])<<16); + MIX(a,b,c); + length -= 12; + k += 6; + } + + /*----------------------------- handle the last (probably partial) block */ + k8 = (const uint8_t *)k; + switch(length) + { + case 12: c+=k[4]+(((uint32_t)k[5])<<16); + b+=k[2]+(((uint32_t)k[3])<<16); + a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ + case 10: c+=k[4]; + b+=k[2]+(((uint32_t)k[3])<<16); + a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 9 : c+=k8[8]; /* fall through */ + case 8 : b+=k[2]+(((uint32_t)k[3])<<16); + a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ + case 6 : b+=k[2]; + a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 5 : b+=k8[4]; /* fall through */ + case 4 : a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ + case 2 : a+=k[0]; + break; + case 1 : a+=k8[0]; + break; + case 0 : *pc=c; *pb=b; return; /* zero length strings require no mixing */ + } + + } else { /* need to read the key one byte at a time */ + const uint8_t *k = (const uint8_t *)key; + + /*--------------- all but the last block: affect some 32 bits of (a,b,c) */ + while (length > 12) + { + a += k[0]; + a += ((uint32_t)k[1])<<8; + a += ((uint32_t)k[2])<<16; + a += ((uint32_t)k[3])<<24; + b += k[4]; + b += ((uint32_t)k[5])<<8; + b += ((uint32_t)k[6])<<16; + b += ((uint32_t)k[7])<<24; + c += k[8]; + c += ((uint32_t)k[9])<<8; + c += ((uint32_t)k[10])<<16; + c += ((uint32_t)k[11])<<24; + MIX(a,b,c); + length -= 12; + k += 12; + } + + /*-------------------------------- last block: affect all 32 bits of (c) */ + switch(length) /* all the case statements fall through */ + { + case 12: c+=((uint32_t)k[11])<<24; /* fall through */ + case 11: c+=((uint32_t)k[10])<<16; /* fall through */ + case 10: c+=((uint32_t)k[9])<<8; /* fall through */ + case 9 : c+=k[8]; /* fall through */ + case 8 : b+=((uint32_t)k[7])<<24; /* fall through */ + case 7 : b+=((uint32_t)k[6])<<16; /* fall through */ + case 6 : b+=((uint32_t)k[5])<<8; /* fall through */ + case 5 : b+=k[4]; /* fall through */ + case 4 : a+=((uint32_t)k[3])<<24; /* fall through */ + case 3 : a+=((uint32_t)k[2])<<16; /* fall through */ + case 2 : a+=((uint32_t)k[1])<<8; /* fall through */ + case 1 : a+=k[0]; + break; + case 0 : *pc=c; *pb=b; return; /* zero length strings require no mixing */ + } + } + + FINAL(a,b,c); + *pc=c; *pb=b; +} + + + +/* + * hashbig(): + * This is the same as hashword() on big-endian machines. It is different + * from hashlittle() on all machines. hashbig() takes advantage of + * big-endian byte ordering. + */ +uint32_t hashbig( const void *key, size_t length, uint32_t initval) +{ + uint32_t a,b,c; + union { const void *ptr; size_t i; } u; /* to cast key to (size_t) happily */ + + /* Set up the internal state */ + a = b = c = 0xdeadbeef + ((uint32_t)length) + initval; + + u.ptr = key; + if (HASH_BIG_ENDIAN && ((u.i & 0x3) == 0)) { + const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */ + const uint8_t *k8; + + __unreferenced( k8) ; + + /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */ + while (length > 12) + { + a += k[0]; + b += k[1]; + c += k[2]; + MIX(a,b,c); + length -= 12; + k += 3; + } + + /*----------------------------- handle the last (probably partial) block */ + /* + * "k[2]<<8" actually reads beyond the end of the string, but + * then shifts out the part it's not allowed to read. Because the + * string is aligned, the illegal read is in the same word as the + * rest of the string. Every machine with memory protection I've seen + * does it on word boundaries, so is OK with this. But VALGRIND will + * still catch it and complain. The masking trick does make the hash + * noticably faster for short strings (like English words). + */ +#ifndef VALGRIND + + switch(length) + { + case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; + case 11: c+=k[2]&0xffffff00; b+=k[1]; a+=k[0]; break; + case 10: c+=k[2]&0xffff0000; b+=k[1]; a+=k[0]; break; + case 9 : c+=k[2]&0xff000000; b+=k[1]; a+=k[0]; break; + case 8 : b+=k[1]; a+=k[0]; break; + case 7 : b+=k[1]&0xffffff00; a+=k[0]; break; + case 6 : b+=k[1]&0xffff0000; a+=k[0]; break; + case 5 : b+=k[1]&0xff000000; a+=k[0]; break; + case 4 : a+=k[0]; break; + case 3 : a+=k[0]&0xffffff00; break; + case 2 : a+=k[0]&0xffff0000; break; + case 1 : a+=k[0]&0xff000000; break; + case 0 : return c; /* zero length strings require no mixing */ + } + +#else /* make valgrind happy */ + + k8 = (const uint8_t *)k; + switch(length) /* all the case statements fall through */ + { + case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; + case 11: c+=((uint32_t)k8[10])<<8; /* fall through */ + case 10: c+=((uint32_t)k8[9])<<16; /* fall through */ + case 9 : c+=((uint32_t)k8[8])<<24; /* fall through */ + case 8 : b+=k[1]; a+=k[0]; break; + case 7 : b+=((uint32_t)k8[6])<<8; /* fall through */ + case 6 : b+=((uint32_t)k8[5])<<16; /* fall through */ + case 5 : b+=((uint32_t)k8[4])<<24; /* fall through */ + case 4 : a+=k[0]; break; + case 3 : a+=((uint32_t)k8[2])<<8; /* fall through */ + case 2 : a+=((uint32_t)k8[1])<<16; /* fall through */ + case 1 : a+=((uint32_t)k8[0])<<24; break; + case 0 : return c; + } + +#endif /* !VALGRIND */ + + } else { /* need to read the key one byte at a time */ + const uint8_t *k = (const uint8_t *)key; + + /*--------------- all but the last block: affect some 32 bits of (a,b,c) */ + while (length > 12) + { + a += ((uint32_t)k[0])<<24; + a += ((uint32_t)k[1])<<16; + a += ((uint32_t)k[2])<<8; + a += ((uint32_t)k[3]); + b += ((uint32_t)k[4])<<24; + b += ((uint32_t)k[5])<<16; + b += ((uint32_t)k[6])<<8; + b += ((uint32_t)k[7]); + c += ((uint32_t)k[8])<<24; + c += ((uint32_t)k[9])<<16; + c += ((uint32_t)k[10])<<8; + c += ((uint32_t)k[11]); + MIX(a,b,c); + length -= 12; + k += 12; + } + + /*-------------------------------- last block: affect all 32 bits of (c) */ + switch(length) /* all the case statements fall through */ + { + case 12: c+=k[11]; /* fall through */ + case 11: c+=((uint32_t)k[10])<<8; /* fall through */ + case 10: c+=((uint32_t)k[9])<<16; /* fall through */ + case 9 : c+=((uint32_t)k[8])<<24; /* fall through */ + case 8 : b+=k[7]; /* fall through */ + case 7 : b+=((uint32_t)k[6])<<8; /* fall through */ + case 6 : b+=((uint32_t)k[5])<<16; /* fall through */ + case 5 : b+=((uint32_t)k[4])<<24; /* fall through */ + case 4 : a+=k[3]; /* fall through */ + case 3 : a+=((uint32_t)k[2])<<8; /* fall through */ + case 2 : a+=((uint32_t)k[1])<<16; /* fall through */ + case 1 : a+=((uint32_t)k[0])<<24; + break; + case 0 : return c; + } + } + + FINAL(a,b,c); + return c; +} + +} // hash + +#endif//__HASHFUNC__ + + + diff --git a/src/libcpp/hj_solver/hj_solver_2.hpp b/src/libcpp/hj_solver/hj_solver_2.hpp deleted file mode 100644 index 47a5c3a..0000000 --- a/src/libcpp/hj_solver/hj_solver_2.hpp +++ /dev/null @@ -1,41 +0,0 @@ - - template < - typename F - > - class hj_mesh_2 - { - - __static_call - __normal_call void_type limit_edge_2 ( - ) - { - } - - __static_call - __normal_call void_type limit_tria_3 ( - ) - { - } - - __static_call - __normal_call void_type limit_mesh ( - ffun_type &_ffun, - real_type _DFDX - ) - { - - containers::priority_map<> _sort; - - // push nodes onto pq - // pop min at each pass - // limit any cell neighbours - // if a cell is limited, update pq of its nodes - - // that's it! - - } - - } ; - - - diff --git a/src/libcpp/iter_mesh/iter_divs_2.inc b/src/libcpp/iter_mesh/iter_divs_2.inc index c6493aa..bab7e56 100644 --- a/src/libcpp/iter_mesh/iter_divs_2.inc +++ b/src/libcpp/iter_mesh/iter_divs_2.inc @@ -4,34 +4,34 @@ * ITER-DIVS-2: optim. schemes to split edges. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 02 March, 2019 + * Last updated: 27 October, 2019 * * Copyright 2013-2019 * Darren Engwirda @@ -40,25 +40,26 @@ * -------------------------------------------------------- */ - + // from iter_mesh_2.hpp - + /* -------------------------------------------------------- * _DIV-EDGE: try edge split to improve adj. cost-fun. -------------------------------------------------------- */ - + __static_call __normal_call void_type _div_edge ( geom_type &_geom , - mesh_type &_mesh , + mesh_type &_mesh , size_type &_hfun , pred_type &_pred , real_list &_hval , iter_opts &_opts , iptr_type _enum , + char_type _kern , bool_type &_okay , iptr_type &_inew , iptr_list &_tset , @@ -66,41 +67,38 @@ real_list &_tsrc , real_list &_tdst , real_list &_ttmp , - real_list &_dtmp , - real_list &_ddst , real_type _TLIM , - real_type _DLIM , real_type _lmin = (real_type) +1.00E+00 , - real_type _qinc + real_type _qinc = (real_type) +1.00E-02 ) - { + { __unreferenced(_pred) ; // for MSVC... __unreferenced(_opts) ; /*--------------------------------- get edge indexing */ - auto _edge = + auto _edge = _mesh._set2.head() + _enum ; - + iptr_type _enod[2] ; _enod[ 0] = _edge->node(0) ; _enod[ 1] = _edge->node(1) ; - + auto _iptr = _mesh. - _set1.head()+ _edge->node(0) ; + _set1.head()+ _edge->node(0) ; auto _jptr = _mesh. _set1.head()+ _edge->node(1) ; - + _tset.set_count(+0); _tnew.set_count(+0); - + _mesh.edge_tri3(_enum,_tset) ; - + _okay = false ; - + if (_tset.count()!=2) return ; - + /*--------------------------------- get edge h-sizing */ real_type _ipos[_dims] ; real_type _jpos[_dims] ; @@ -113,30 +111,30 @@ _jptr->pval(_idim) ; } - real_type _isiz = + real_type _isiz = _hfun.eval(_ipos, _iptr->hidx ()) ; - real_type _jsiz = + real_type _jsiz = _hfun.eval(_jpos, _jptr->hidx ()) ; - + real_type _lsqr = _pred.length_sq(_ipos, _jpos) ; - real_type _hbar = + real_type _hbar = std::max(_isiz , _jsiz); /*--------------------------------- exit if too small */ if (_lsqr <= _hbar * _lmin * _hbar * _lmin ) return ; - + /*--------------------------------- get adjacent face */ - auto _itri = + auto _itri = _mesh._set3.head()+_tset[0]; - auto _jtri = + auto _jtri = _mesh._set3.head()+_tset[1]; - + _tsrc.set_count(+2) ; - + _tsrc[0] = _pred.cost_tria ( &_mesh._set1[ _itri->node(0)].pval(0), @@ -145,7 +143,7 @@ &_mesh._set1[ _itri->node(2)].pval(0) ) ; - + _tsrc[1] = _pred.cost_tria ( &_mesh._set1[ _jtri->node(0)].pval(0), @@ -154,49 +152,50 @@ &_mesh._set1[ _jtri->node(2)].pval(0) ) ; - + if (_tsrc[1] < _tsrc[0]) std::swap(_itri, _jtri ) ; - + real_type _TMIN = std::min ( _tsrc[0] , _tsrc[1]) ; - + /*--------------------------------- exit if too good! */ - real_type _TSQR = std::sqrt(_TLIM) ; + real_type _TURN = + std::pow(_TLIM, +1./4.) ; + + if (_TMIN>_TURN ) return ; - if (_TMIN>_TSQR ) return ; - /*--------------------------------- get adjacent ball */ real_type _ibal[_dims+1] ; for(_idim = _dims+0; _idim-- != 0; ) { - _ibal[_idim] = + _ibal[_idim] = _mesh._set1[ - _itri->node(0)].pval(_idim) + + _itri->node(0)].pval(_idim) + _mesh._set1[ - _itri->node(1)].pval(_idim) + + _itri->node(1)].pval(_idim) + _mesh._set1[ _itri->node(2)].pval(_idim) ; - - _ibal[_idim]/= + + _ibal[_idim]/= (real_type) +3.0 ; } real_type _jbal[_dims+1] ; for(_idim = _dims+0; _idim-- != 0; ) { - _jbal[_idim] = + _jbal[_idim] = _mesh._set1[ - _jtri->node(0)].pval(_idim) + + _jtri->node(0)].pval(_idim) + _mesh._set1[ - _jtri->node(1)].pval(_idim) + + _jtri->node(1)].pval(_idim) + _mesh._set1[ _jtri->node(2)].pval(_idim) ; - - _jbal[_idim]/= + + _jbal[_idim]/= (real_type) +3.0 ; } - + /*--------------------------------- get adjacent apex */ iptr_type _inod [3] ; iptr_type _jnod [3] ; @@ -205,13 +204,13 @@ mesh_type::tri3_type:: face_node( _inod, _inum, 2, 1) ; - _inod[0] = + _inod[0] = _itri->node(_inod[0]); - _inod[1] = + _inod[1] = _itri->node(_inod[1]); - _inod[2] = + _inod[2] = _itri->node(_inod[2]); - + if (_inod[2] != _enod[0]) if (_inod[2] != _enod[1]) break ; @@ -221,155 +220,148 @@ mesh_type::tri3_type:: face_node( _jnod, _inum, 2, 1) ; - _jnod[0] = + _jnod[0] = _jtri->node(_jnod[0]); - _jnod[1] = + _jnod[1] = _jtri->node(_jnod[1]); - _jnod[2] = + _jnod[2] = _jtri->node(_jnod[2]); - + if (_jnod[2] != _enod[0]) if (_jnod[2] != _enod[1]) break ; } - + /*--------------------------------- push node to mesh */ typename mesh_type ::node_type _ndat ; typename mesh_type ::tri3_type _tdat ; - - _ndat.fdim() = +2; - _ndat.feat() = + + _ndat.fdim() = +2; + _ndat.feat() = mesh::null_feat; - + for(_idim = _dims+0; _idim-- != 0; ) { - _ndat.pval(_idim) + _ndat.pval(_idim) = (real_type) +0.0 ; - _ndat.pval(_idim) += + _ndat.pval(_idim) += _ibal[_idim] ; - _ndat.pval(_idim) += + _ndat.pval(_idim) += _jbal[_idim] ; - + _ndat.pval(_idim) /= (real_type) +2.0 ; - } - + } + _ndat.pval(_dims) = (real_type)0. ; - _ndat.pval(_dims) += + _ndat.pval(_dims) += _iptr->pval(_dims) ; - _ndat.pval(_dims) += + _ndat.pval(_dims) += _jptr->pval(_dims) ; - + _ndat.pval(_dims) /= (real_type)2. ; - - _ndat.hidx() = + + _ndat.hidx() = size_type::null_hint() ; - - iptr_type _nnew = + + iptr_type _nnew = _mesh.push_node(_ndat) ; - + _inew = _nnew ; - - auto _nptr = + + auto _nptr = _mesh._set1.head() + _nnew ; - + _hval.set_count(std::max ( - _nnew + 1, + _nnew + 1, (iptr_type)_hval.count())) ; - + _hval[_nnew] = (real_type)-1. ; - - /*--------------------------------- redo mesh indexes */ + + /*--------------------------------- redo mesh indexes */ _tdat.node(0) = _nnew; _tdat.node(1) = _inod[ 2] ; _tdat.node(2) = _inod[ 0] ; - + _tdat.itag () = _itri->itag() ; _tnew.push_tail( _mesh.push_tri3(_tdat)) ; - + _tdat.node(0) = _nnew; _tdat.node(1) = _inod[ 1] ; _tdat.node(2) = _inod[ 2] ; - + _tdat.itag () = _itri->itag() ; - + _tnew.push_tail( _mesh.push_tri3(_tdat)) ; - + _tdat.node(0) = _nnew; _tdat.node(1) = _jnod[ 1] ; _tdat.node(2) = _jnod[ 2] ; - + _tdat.itag () = _jtri->itag() ; - + _tnew.push_tail( _mesh.push_tri3(_tdat)) ; - + _tdat.node(0) = _nnew; _tdat.node(1) = _jnod[ 2] ; _tdat.node(2) = _jnod[ 0] ; - + _tdat.itag () = _jtri->itag() ; - + _tnew.push_tail( _mesh.push_tri3(_tdat)) ; - + /*--------------------------------- optim. node coord */ - iptr_type static - constexpr _INUM = (iptr_type) +8 ; - - for (auto _iloc = +0; _iloc != _INUM ; + iptr_type static + constexpr _INUM = (iptr_type) +4 ; + + for (auto _iloc = +0; _iloc != _INUM ; ++_iloc ) { iptr_type _move = (iptr_type) -1 ; - + _ttmp.set_count(0) ; - _dtmp.set_count(0) ; - - real_type _minC = - loop_tscr( _mesh, _pred , - _tnew, - _ttmp ) ; - - real_type _minD = - loop_dscr( _mesh, _pred , - _tnew, - _dtmp ) ; - + + real_type _minC = + loop_cost( _mesh, _pred , + _tnew, + _ttmp, + tria_kind() ) ; + move_node( _geom, _mesh , - _hfun, _pred, _hval , - _opts, _nptr, - _odt_kind, - _move, _tnew, + _hfun, _pred, _hval , + _opts, _nptr, _kern, + _move, _tnew, _ttmp, _tdst, - _dtmp, _ddst, - _minC, _TLIM, - _minD, _DLIM ) ; - + _minC, _TLIM ) ; + if (_move <= +0) break ; } - + /*--------------------------------- compare cost scr. */ _tdst.set_count(0) ; - - loop_tscr(_mesh, _pred, _tnew, - _tdst) ; - - move_okay(_tdst, _tsrc, _okay, - _TSQR, + + loop_cost(_mesh, _pred, _tnew, + _tdst, + tria_kind() ) ; + + move_okay(_tdst, _tsrc, _okay, + _TURN, _qinc) ; - + if (_okay) - { - /*--------------------------------- delete old cavity */ + { + /*--------------------------------- delete old cavity */ for (auto _tria = _tset.head() ; _tria != _tset.tend() ; ++_tria ) - { + { _mesh. _pop_tri3(* _tria) ; } @@ -380,16 +372,16 @@ for (auto _tria = _tnew.head() ; _tria != _tnew.tend() ; ++_tria ) - { + { _mesh. _pop_tri3(* _tria) ; } - + _mesh. _pop_node(& _nnew) ; } - + } - - - + + + diff --git a/src/libcpp/iter_mesh/iter_divs_3.inc b/src/libcpp/iter_mesh/iter_divs_3.inc index 79e20ea..7a417e1 100644 --- a/src/libcpp/iter_mesh/iter_divs_3.inc +++ b/src/libcpp/iter_mesh/iter_divs_3.inc @@ -4,29 +4,29 @@ * ITER-DIVS-2: optim. schemes to split edges. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- @@ -40,20 +40,20 @@ * -------------------------------------------------------- */ - + // from iter_mesh_2.hpp - + /* -------------------------------------------------------- * _DIV-EDGE: try edge split to improve adj. cost-fun. -------------------------------------------------------- */ - + __static_call __normal_call void_type _div_edge_3 ( geom_type &_geom , - mesh_type &_mesh , + mesh_type &_mesh , size_type &_hfun , pred_type &_pred , real_list &_hval , @@ -65,33 +65,33 @@ real_list &_cdst , real_type _lmin = (real_type) +0.67E+00, - real_type _good + real_type _good = (real_type) +9.25E-01, - real_type _qinc + real_type _qinc = (real_type) +1.00E-08 ) - { + { __unreferenced(_pred) ; // for MSVC... __unreferenced(_opts) ; /*--------------------------------- get edge indexing */ - auto _edge = + auto _edge = _mesh._set2.head() + _enum ; - + iptr_type _enod[2] ; _enod[ 0] = _edge->node(0) ; _enod[ 1] = _edge->node(1) ; - + auto _iptr = _mesh. - _set1.head()+ _edge->node(0) ; + _set1.head()+ _edge->node(0) ; auto _jptr = _mesh. _set1.head()+ _edge->node(1) ; - + _tset.set_count(+0); _mesh.edge_tri4(_enum, _tset); - + _okay = false ; - + /*--------------------------------- get edge h-sizing */ real_type _ipos[_dims] ; real_type _jpos[_dims] ; @@ -104,27 +104,27 @@ _jptr->pval(_idim) ; } - real_type _isiz = + real_type _isiz = _hfun.eval(_ipos, _iptr->hidx ()) ; - real_type _jsiz = + real_type _jsiz = _hfun.eval(_jpos, _jptr->hidx ()) ; - + real_type _lsqr = _pred.length_sq(_ipos, _jpos) ; - real_type _hbar = + real_type _hbar = std::min(_isiz , _jsiz); /*--------------------------------- exit if too small */ if (_lsqr <= _hbar * _lmin * _hbar * _lmin ) return ; - + /*--------------------------------- get adjacent face */ - - - + + + } - - - + + + diff --git a/src/libcpp/iter_mesh/iter_dual_2.inc b/src/libcpp/iter_mesh/iter_dual_2.inc index e2d35d3..9b9d868 100644 --- a/src/libcpp/iter_mesh/iter_dual_2.inc +++ b/src/libcpp/iter_mesh/iter_dual_2.inc @@ -4,57 +4,57 @@ * ITER-DUAL-2: optim. schemes to reposition dual. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 25 November, 2018 + * Last updated: 27 October, 2019 * - * Copyright 2013-2018 + * Copyright 2013-2019 * Darren Engwirda * de2363@columbia.edu * https://github.com/dengwirda/ * -------------------------------------------------------- */ - + // from iter_mesh_k.hpp - - + + /* -------------------------------------------------------- - * GRAD-DUAL: "local-ascent" weight movement vector. + * DQDW-MOVE: "local-ascent" weight movement vector. -------------------------------------------------------- */ - + template < typename node_iter > __static_call - __normal_call void_type grad_dual_2 ( + __normal_call void_type dqdw_move_2 ( geom_type &_geom , mesh_type &_mesh , size_type &_hfun , @@ -66,126 +66,135 @@ real_type &_wadj ) { - real_type static const _WINC = + real_type static const _WINC = std::pow(std::numeric_limits ::epsilon(), +.50) ; - - real_type static const _RMIN = + + real_type static const _RMIN = std::pow(std::numeric_limits ::epsilon(), +.75) ; - - real_type static const _RMAX = + + real_type static const _RMAX = std::pow(std::numeric_limits ::epsilon(), +.25) ; - + __unreferenced(_geom); __unreferenced(_hfun); - + /*------------------ calc. local characteristic scale */ real_type _qmin = +std::numeric_limits ::infinity(); - + iptr_type _tnum = +0 ; - + _step = (real_type)0.; _wadj = (real_type)0.; - + for (auto _tria = _tset.head(), _tend = _tset.tend(); _tria != _tend; ++_tria, ++_tnum) - { - auto _tptr = - _mesh._set3.head()+*_tria ; - - auto _inod = _mesh. - _set1 .head()+_tptr->node(0) ; - auto _jnod = _mesh. - _set1 .head()+_tptr->node(1) ; - auto _knod = _mesh. - _set1 .head()+_tptr->node(2) ; - + { + auto _tptr = + _mesh._set3.head()+*_tria; + + iptr_type _tnod[3] ; + _tnod[ 0] = _tptr->node( 0) ; + _tnod[ 1] = _tptr->node( 1) ; + _tnod[ 2] = _tptr->node( 2) ; + + algorithms::isort( + &_tnod[0], &_tnod[3], + std::less()) ; + + auto _inod = + _mesh._set1.head()+_tnod[0] ; + auto _jnod = + _mesh._set1.head()+_tnod[1] ; + auto _knod = + _mesh._set1.head()+_tnod[2] ; + _qmin = std::min( _qmin, _cost[_tnum]) ; - + real_type _ball[_dims+1] ; _pred.circ_ball(_ball, &_inod->pval(0), &_jnod->pval(0), - &_knod->pval(0)); - + &_knod->pval(0) ) ; + _wadj += _ball[_dims] ; // ball-rad.^2 } - + _wadj /= _tset.count () ; - + /*------------------ adj. gradients w.r.t. W: dQ / dw */ real_type _qbar, _qlow, _dqdw; _qbar = (real_type) +1. ; _qlow = (real_type) +0. ; _dqdw = (real_type) +0. ; - - iptr_type _lnum = +0 ; - iptr_type _hnum = +1 ; - - real_type _save = + + iptr_type _lnum = +0 ; + iptr_type _hnum = +1 ; + + real_type _save = _node->pval (_dims); - - real_type _qlim = _qmin + - (real_type) +1.0E-003 ; - + + real_type _qlim = _qmin + + (real_type) +1.0E-002 ; + _tnum = (iptr_type) +0 ; for (auto _tria = _tset.head(), _tend = _tset.tend(); _tria != _tend; ++_tria, ++_tnum) - { - auto _tptr = + { + auto _tptr = _mesh._set3.head()+*_tria ; - + real_type _qtri = _cost[_tnum] ; real_type _DQDW ; - + /*-------------- only do gradients for 'poor' set */ if (_qtri <= _qlim) { real_type _hsum = (real_type)0.; - + real_type _wdel = _WINC*_wadj; - + real_type _sdel = (real_type)0.; real_type _sabs = (real_type)0.; real_type _sbar = (real_type)0.; - - /*---------- local iter. on finite-diff. step */ - for (auto _iter = +0; _iter++ != +8; ) + + /*---------- local iter. on finite-diff. step */ + for (auto _iter = +0; _iter++ != +2; ) { - + /*------ centred finite-diff. for dQ / dw */ - _node->pval(_dims) = + _node->pval(_dims) = _save + _wdel; - + _hsum = (real_type)+0.; _hsum += _node-> pval(_dims) - _save; - - real_type _scr1 = + + real_type _scr1 = _pred.cost_dual ( &_mesh._set1[ _tptr->node(0)].pval(0), &_mesh._set1[ _tptr->node(1)].pval(0), &_mesh._set1[ - _tptr->node(2)].pval(0)) ; - - _node->pval(_dims) = + _tptr->node(2)].pval(0)) ; + + _node->pval(_dims) = _save - _wdel; _hsum -= _node-> pval(_dims) - _save; - real_type _scr0 = + real_type _scr0 = _pred.cost_dual ( &_mesh._set1[ _tptr->node(0)].pval(0), @@ -193,44 +202,43 @@ _tptr->node(1)].pval(0), &_mesh._set1[ _tptr->node(2)].pval(0)) ; - - _sbar = std::max( - std::abs(_scr1), - std::abs(_scr0)); - - _sdel =_scr1-_scr0 ; - + + _sbar = _cost[_tnum]; + + _sdel = _scr1-_scr0 ; + + _sbar = std::abs(_sbar) ; _sabs = std::abs(_sdel) ; - + _node->pval(_dims) = _save; - + /*------ try to adjust step on rel. diff. */ if (_sabs > (real_type)0.) - { + { if (_sabs > _RMAX * _sbar) { - _wdel *= + _wdel *= (real_type) +.10 ; - } - else + } + else if (_sabs < _RMIN * _sbar) { - _wdel *= + _wdel *= (real_type) +10. ; } else { break ; } } else { break ; } } - + _node->pval(_dims) = _save ; - + /*---------- finalise gradient and accumulate */ _DQDW = _sdel / _hsum ; - + _dqdw += _DQDW; - + _qlow += _qtri; _lnum += 1 ; } else @@ -239,30 +247,39 @@ _qbar += _qtri; _hnum += 1 ; } } - - if (_tnum > +0) - { - _dqdw /= _lnum ; - _qlow /= _lnum ; - } - if (_hnum > +0) + + if (_tnum > +0) { + _dqdw /= _lnum ; + _qlow /= _lnum ; _qbar /= _hnum ; } - + /*------------------ 1st ord. Taylor-series step est. */ real_type _scal = std::abs (_dqdw) ; - - if (_scal ==(real_type) +0. ) + + if (_scal*_wadj <= _WINC) { _step = (real_type) +0. ; } else - { + { _step = (_qbar-_qlow) / _dqdw ; + + _step*= (real_type)+.50 ; + } + + if (_step > (real_type) +0. ) + { + _step = std::min(_step,+_wadj) ; + } + else + if (_step < (real_type) +0. ) + { + _step = std::max(_step,-_wadj) ; } - + } - - - + + + diff --git a/src/libcpp/iter_mesh/iter_dual_3.inc b/src/libcpp/iter_mesh/iter_dual_3.inc index 3e995b7..bcd80a9 100644 --- a/src/libcpp/iter_mesh/iter_dual_3.inc +++ b/src/libcpp/iter_mesh/iter_dual_3.inc @@ -4,29 +4,29 @@ * ITER-DUAL-3: optim. schemes to reposition dual. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- @@ -40,16 +40,16 @@ * -------------------------------------------------------- */ - + // from iter_mesh_k.hpp - - + + /* -------------------------------------------------------- - * GRAD-DUAL: "local-ascent" weight movement vector. + * GRAD-DUAL: "local-ascent" weight movement vector. -------------------------------------------------------- */ - + template < typename node_iter > @@ -66,46 +66,46 @@ real_type &_ladj ) { - real_type static const _ZERO = + real_type static const _ZERO = std::pow(std::numeric_limits ::epsilon(), +.80) ; - - real_type static const _WINC = + + real_type static const _WINC = std::pow(std::numeric_limits ::epsilon(), +.50) ; - - real_type static const _RMIN = + + real_type static const _RMIN = std::pow(std::numeric_limits ::epsilon(), +.75) ; - - real_type static const _RMAX = + + real_type static const _RMAX = std::pow(std::numeric_limits ::epsilon(), +.25) ; - + real_type _qmin = +std::numeric_limits ::infinity() ; - + __unreferenced(_geom); __unreferenced(_hfun); real_type _dqdw = (real_type)0. ; - + iptr_type _tnum = +0 ; - + _ladj = (real_type)0.; - - real_type _save = + + real_type _save = _node->pval(_dims) ; - + for (auto _tria = _tset.head(), _tend = _tset.tend(); _tria != _tend; ++_tria, ++_tnum) - { - auto _tptr = + { + auto _tptr = _mesh._set4.head()+*_tria ; - + auto _inod = _mesh. _set1 .head()+_tptr->node(0) ; auto _jnod = _mesh. @@ -114,64 +114,64 @@ _set1 .head()+_tptr->node(2) ; auto _lnod = _mesh. _set1 .head()+_tptr->node(3) ; - + _qmin = std::min( _qmin, _cost[_tnum]) ; - + real_type _ball[_dims+1] ; _pred.circ_ball(_ball, &_inod->pval(0), &_jnod->pval(0), &_knod->pval(0), &_lnod->pval(0)) ; - + _ladj += _ball[_dims]; // ball-rad.^2 } - + real_type _qbar , _qlow ; _qbar = (real_type) +1. ; _qlow = (real_type) +0. ; - + iptr_type _lnum = +0 ; iptr_type _hnum = +1 ; - - real_type _qlim = _qmin + + + real_type _qlim = _qmin + (real_type) +1.0E-004 ; - + _ladj /= _tset.count () ; - + _tnum = (iptr_type) +0 ; for (auto _tria = _tset.head(), _tend = _tset.tend(); _tria != _tend; ++_tria, ++_tnum) - { - auto _tptr = + { + auto _tptr = _mesh._set4.head()+*_tria ; - + real_type _qtri = _cost[_tnum] ; real_type _DQDW ; - + if (_qtri <= _qlim) { real_type _hsum = (real_type)0.; - + real_type _wdel = _WINC*_ladj; - + real_type _sdel = (real_type)0.; real_type _sabs = (real_type)0.; real_type _sbar = (real_type)0.; - + for (auto _iter = +0; _iter++ != +8; ) { - _node->pval(_dims) = + _node->pval(_dims) = _save + _wdel; - + _hsum = (real_type)+0.; _hsum += _node-> pval(_dims) - _save; - - real_type _scr1 = + + real_type _scr1 = _pred.cost_dual ( &_mesh._set1[ _tptr->node(0)].pval(0), @@ -181,15 +181,15 @@ _tptr->node(2)].pval(0), &_mesh._set1[ _tptr->node(3)].pval(0) - ) ; - - _node->pval(_dims) = + ) ; + + _node->pval(_dims) = _save - _wdel; _hsum -= _node-> pval(_dims) - _save; - real_type _scr0 = + real_type _scr0 = _pred.cost_dual ( &_mesh._set1[ _tptr->node(0)].pval(0), @@ -200,41 +200,41 @@ &_mesh._set1[ _tptr->node(3)].pval(0) ) ; - + _sdel = _scr1 - _scr0 ; - _sabs = + _sabs = std::abs(_sdel); - + _sbar = std::max( std::abs(_scr1), std::abs(_scr0)) ; - + _node->pval(_dims) =_save; - + if (_sabs > (real_type)0.) - { + { if (_sabs > _RMAX * _sbar) { - _wdel *= + _wdel *= (real_type) +.10 ; - } - else + } + else if (_sabs < _RMIN * _sbar) { - _wdel *= + _wdel *= (real_type) +10. ; } else { break ; } } else { break ; } } - + _DQDW = _sdel / _hsum ; - + _node->pval(_dims) = _save ; - + _dqdw += _DQDW; - + _qlow += _qtri; _lnum += 1 ; } else @@ -242,36 +242,36 @@ _qbar += _qtri; _hnum += 1 ; } } - - if (_tnum > +0) - { + + if (_tnum > +0) + { _dqdw /= _lnum ; - _qlow /= _lnum ; + _qlow /= _lnum ; } if (_hnum > +0) { _qbar /= _hnum ; } - + real_type _scal = std::abs (_dqdw) ; - + if (_scal <= _ZERO * _ladj) { _line = (real_type) +0. ; } else - { + { _line = _dqdw / _scal; - - _scal = (_qbar - _qlow) + + _scal = (_qbar - _qlow) / (_line * _dqdw) ; - + _scal = std::min(_scal, _ladj) ; - + _line *= _scal ; } - + } - - - + + + diff --git a/src/libcpp/iter_mesh/iter_flip_2.inc b/src/libcpp/iter_mesh/iter_flip_2.inc index 10b49e2..8edc2cb 100644 --- a/src/libcpp/iter_mesh/iter_flip_2.inc +++ b/src/libcpp/iter_mesh/iter_flip_2.inc @@ -4,29 +4,29 @@ * ITER-FLIP-2: optim. schemes to "flip" topology. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- @@ -40,16 +40,16 @@ * -------------------------------------------------------- */ - + // from iter_mesh_2.hpp - - + + /* __static_call __normal_call bool_type need_flip_costfunc ( */ - - + + __static_call __normal_call bool_type need_flip_delaunay ( geom_type &_geom , @@ -59,7 +59,7 @@ __const_ptr (iptr_type) _jnod ) { - real_type static const _LTOL = + real_type static const _LTOL = std::pow(std::numeric_limits ::epsilon(), +.80) ; @@ -69,27 +69,27 @@ _iloc[0] = _inod[0] ; _iloc[1] = _inod[1] ; _iloc[2] = _inod[2] ; - + algorithms::isort( - &_iloc[0], &_iloc[3] , + &_iloc[0], &_iloc[3] , std::less()); - + iptr_type _jloc[3] ; _jloc[0] = _jnod[0] ; _jloc[1] = _jnod[1] ; _jloc[2] = _jnod[2] ; - + algorithms::isort( - &_jloc[0], &_jloc[3] , + &_jloc[0], &_jloc[3] , std::less()); - + real_type _ibal[_dims+1] ; _pred.circ_ball(_ibal , &_mesh._set1[_iloc[0]].pval(0), &_mesh._set1[_iloc[1]].pval(0), &_mesh._set1[_iloc[2]].pval(0) ) ; - + real_type _jbal[_dims+1] ; _pred.circ_ball(_jbal , &_mesh._set1[_jloc[0]].pval(0), @@ -102,26 +102,26 @@ _pred. proj_node ( _geom, _null, _ibal) ; - + _pred. proj_node ( _geom, _null, _jbal) ; - real_type _ilen = - _pred.length_sq(_jbal, + real_type _ilen = + _pred.length_sq(_jbal, &_mesh._set1[_inod[2]].pval(0)); - - real_type _jlen = - _pred.length_sq(_ibal, + + real_type _jlen = + _pred.length_sq(_ibal, &_mesh._set1[_jnod[2]].pval(0)); - - real_type _btol = _LTOL * + + real_type _btol = _LTOL * std::max(_ilen, _jlen) ; - - real_type _idel = + + real_type _idel = _ilen - _jbal[_dims] ; - real_type _jdel = + real_type _jdel = _jlen - _ibal[_dims] ; - + if (_idel >= - _btol || _jdel >= - _btol ) { @@ -130,9 +130,9 @@ else { return true ; - } + } } - + __static_call __normal_call bool_type need_flip_weighted ( geom_type &_geom , @@ -142,7 +142,7 @@ __const_ptr (iptr_type) _jnod ) { - real_type static const _LTOL = + real_type static const _LTOL = std::pow(std::numeric_limits ::epsilon(), +.80) ; @@ -152,27 +152,27 @@ _iloc[0] = _inod[0] ; _iloc[1] = _inod[1] ; _iloc[2] = _inod[2] ; - + algorithms::isort( - &_iloc[0], &_iloc[3] , + &_iloc[0], &_iloc[3] , std::less()); - + iptr_type _jloc[3] ; _jloc[0] = _jnod[0] ; _jloc[1] = _jnod[1] ; _jloc[2] = _jnod[2] ; - + algorithms::isort( - &_jloc[0], &_jloc[3] , + &_jloc[0], &_jloc[3] , std::less()); - + real_type _ibal[_dims+1] ; _pred.perp_ball(_ibal , &_mesh._set1[_iloc[0]].pval(0), &_mesh._set1[_iloc[1]].pval(0), &_mesh._set1[_iloc[2]].pval(0) ) ; - + real_type _jbal[_dims+1] ; _pred.perp_ball(_jbal , &_mesh._set1[_jloc[0]].pval(0), @@ -185,35 +185,35 @@ _pred. proj_node ( _geom, _null, _ibal) ; - + _pred. proj_node ( _geom, _null, _jbal) ; - real_type _ilen = - _pred.length_sq(_jbal, + real_type _ilen = + _pred.length_sq(_jbal, &_mesh._set1[_inod[2]].pval( +0)); - - real_type _ipwr = + + real_type _ipwr = _mesh._set1[_inod[2]].pval(_dims) ; - - real_type _jlen = - _pred.length_sq(_ibal, + + real_type _jlen = + _pred.length_sq(_ibal, &_mesh._set1[_jnod[2]].pval( +0)); - - real_type _jpwr = + + real_type _jpwr = _mesh._set1[_jnod[2]].pval(_dims) ; - + _ilen -= _ipwr ; _jlen -= _jpwr ; - - real_type _btol = _LTOL * + + real_type _btol = _LTOL * std::max(_ilen, _jlen) ; - - real_type _idel = + + real_type _idel = _ilen - _jbal[_dims] ; - real_type _jdel = + real_type _jdel = _jlen - _ibal[_dims] ; - + if (_idel >= - _btol || _jdel >= - _btol ) { @@ -222,16 +222,16 @@ else { return true ; - } - } - - + } + } + + /* -------------------------------------------------------- - * FLIP-T2T2: 2-simplex topological flip. + * FLIP-T2T2: 2-simplex topological flip. -------------------------------------------------------- */ - + __static_call __normal_call void_type flip_t2t2 ( geom_type &_geom , @@ -242,7 +242,7 @@ iptr_type _edge , iptr_list &_told , iptr_list &_tnew , - bool_type &_flip , + bool_type &_flip , real_list &_qold , real_list &_qnew ) @@ -250,12 +250,12 @@ __unreferenced( _hfun) ; __unreferenced( _qold) ; __unreferenced( _qnew) ; - + _flip = false ; - - _told.set_count(0) ; + + _told.set_count(0) ; _tnew.set_count(0) ; - + iptr_type _enod[3] ; mesh_type::tri3_type:: face_node(_enod, _edge, 2, 1) ; @@ -263,45 +263,45 @@ _set3[_tria].node(_enod[0]) ; _enod[ 1] = _mesh. _set3[_tria].node(_enod[1]) ; - + iptr_type _epos = -1 ; _mesh.find_edge(_enod, _epos) ; - + if (_epos==-1) return; - - auto _eptr = + + auto _eptr = _mesh._set2.head() + _epos ; - + if (_eptr->self()>=+1) return ; - - _mesh.edge_tri3(_enod, _told) ; - + + _mesh.edge_tri3(_epos, _told) ; + if (_told.count()!=+2) return ; - + iptr_type _itri = _told[0] ; iptr_type _jtri = _told[1] ; - - auto _iptr = + + auto _iptr = _mesh._set3.head() + _itri ; - auto _jptr = + auto _jptr = _mesh._set3.head() + _jtri ; - - if ( _iptr->itag() != + + if ( _iptr->itag() != _jptr->itag() ) return ; - + iptr_type _inod [3] ; iptr_type _jnod [3] ; for(auto _inum = 3; _inum-- != 0; ) { mesh_type::tri3_type:: face_node(_inod, _inum, 2, 1) ; - _inod[0] = + _inod[0] = _iptr->node(_inod[0]); - _inod[1] = + _inod[1] = _iptr->node(_inod[1]); - _inod[2] = + _inod[2] = _iptr->node(_inod[2]); - + if (_inod[2] != _enod[0]) if (_inod[2] != _enod[1]) break ; @@ -310,13 +310,13 @@ { mesh_type::tri3_type:: face_node(_jnod, _inum, 2, 1) ; - _jnod[0] = + _jnod[0] = _jptr->node(_jnod[0]); - _jnod[1] = + _jnod[1] = _jptr->node(_jnod[1]); - _jnod[2] = + _jnod[2] = _jptr->node(_jnod[2]); - + if (_jnod[2] != _enod[0]) if (_jnod[2] != _enod[1]) break ; @@ -327,35 +327,35 @@ "FLIP-T2T2: bad orientation!"); if(!need_flip_weighted ( - _geom, _mesh , - _pred, + _geom, _mesh , + _pred, _inod, _jnod)) return ; - + _mesh._pop_tri3(_itri) ; _mesh._pop_tri3(_jtri) ; - + _flip = true ; - + typename mesh_type ::tri3_type _tdat ; _tdat.node(0) = _inod[0] ; _tdat.node(1) = _jnod[2] ; _tdat.node(2) = _inod[2] ; - + _tdat.itag () = _iptr->itag() ; - + _tnew.push_tail( _mesh.push_tri3(_tdat)) ; - + _tdat.node(0) = _jnod[0] ; _tdat.node(1) = _inod[2] ; _tdat.node(2) = _jnod[2] ; - + _tdat.itag () = _jptr->itag() ; - + _tnew.push_tail( - _mesh.push_tri3(_tdat)) ; + _mesh.push_tri3(_tdat)) ; } - - - + + + diff --git a/src/libcpp/iter_mesh/iter_flip_3.inc b/src/libcpp/iter_mesh/iter_flip_3.inc index 398622a..2dbbc67 100644 --- a/src/libcpp/iter_mesh/iter_flip_3.inc +++ b/src/libcpp/iter_mesh/iter_flip_3.inc @@ -4,29 +4,29 @@ * ITER-FLIP-2: optim. schemes to "flip" topology. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- @@ -40,16 +40,16 @@ * -------------------------------------------------------- */ - + // from iter_mesh_k.hpp - - + + /* __static_call __normal_call bool_type need_flip_costfunc ( */ - - + + __static_call __normal_call bool_type need_flip_delaunay ( geom_type &_geom , @@ -59,7 +59,7 @@ __const_ptr (iptr_type) _jnod ) { - real_type static const _LTOL = + real_type static const _LTOL = std::pow(std::numeric_limits ::epsilon(), +.80) ; @@ -69,27 +69,27 @@ _iloc[0] = _inod[0] ; _iloc[1] = _inod[1] ; _iloc[2] = _inod[2] ; - + algorithms::isort( - &_iloc[0], &_iloc[3] , + &_iloc[0], &_iloc[3] , std::less()); - + iptr_type _jloc[3] ; _jloc[0] = _jnod[0] ; _jloc[1] = _jnod[1] ; _jloc[2] = _jnod[2] ; - + algorithms::isort( - &_jloc[0], &_jloc[3] , + &_jloc[0], &_jloc[3] , std::less()); - + real_type _ibal[_dims+1] ; _pred.circ_ball(_ibal , &_mesh._set1[_iloc[0]].pval(0), &_mesh._set1[_iloc[1]].pval(0), &_mesh._set1[_iloc[2]].pval(0) ) ; - + real_type _jbal[_dims+1] ; _pred.circ_ball(_jbal , &_mesh._set1[_jloc[0]].pval(0), @@ -102,26 +102,26 @@ _pred. proj_node ( _geom, _null, _ibal) ; - + _pred. proj_node ( _geom, _null, _jbal) ; - real_type _ilen = - _pred.length_sq(_jbal, + real_type _ilen = + _pred.length_sq(_jbal, &_mesh._set1[_inod[2]].pval(0)); - - real_type _jlen = - _pred.length_sq(_ibal, + + real_type _jlen = + _pred.length_sq(_ibal, &_mesh._set1[_jnod[2]].pval(0)); - - real_type _btol = _LTOL * + + real_type _btol = _LTOL * std::max(_ilen, _jlen) ; - - real_type _idel = + + real_type _idel = _ilen - _jbal[_dims] ; - real_type _jdel = + real_type _jdel = _jlen - _ibal[_dims] ; - + if (_idel >= - _btol || _jdel >= - _btol ) { @@ -130,9 +130,9 @@ else { return true ; - } + } } - + __static_call __normal_call bool_type need_flip_weighted ( geom_type &_geom , @@ -142,7 +142,7 @@ __const_ptr (iptr_type) _jnod ) { - real_type static const _LTOL = + real_type static const _LTOL = std::pow(std::numeric_limits ::epsilon(), +.80) ; @@ -152,27 +152,27 @@ _iloc[0] = _inod[0] ; _iloc[1] = _inod[1] ; _iloc[2] = _inod[2] ; - + algorithms::isort( - &_iloc[0], &_iloc[3] , + &_iloc[0], &_iloc[3] , std::less()); - + iptr_type _jloc[3] ; _jloc[0] = _jnod[0] ; _jloc[1] = _jnod[1] ; _jloc[2] = _jnod[2] ; - + algorithms::isort( - &_jloc[0], &_jloc[3] , + &_jloc[0], &_jloc[3] , std::less()); - + real_type _ibal[_dims+1] ; _pred.perp_ball(_ibal , &_mesh._set1[_iloc[0]].pval(0), &_mesh._set1[_iloc[1]].pval(0), &_mesh._set1[_iloc[2]].pval(0) ) ; - + real_type _jbal[_dims+1] ; _pred.perp_ball(_jbal , &_mesh._set1[_jloc[0]].pval(0), @@ -185,35 +185,35 @@ _pred. proj_node ( _geom, _null, _ibal) ; - + _pred. proj_node ( _geom, _null, _jbal) ; - real_type _ilen = - _pred.length_sq(_jbal, + real_type _ilen = + _pred.length_sq(_jbal, &_mesh._set1[_inod[2]].pval( +0)); - - real_type _ipwr = + + real_type _ipwr = _mesh._set1[_inod[2]].pval(_dims) ; - - real_type _jlen = - _pred.length_sq(_ibal, + + real_type _jlen = + _pred.length_sq(_ibal, &_mesh._set1[_jnod[2]].pval( +0)); - - real_type _jpwr = + + real_type _jpwr = _mesh._set1[_jnod[2]].pval(_dims) ; - + _ilen -= _ipwr ; _jlen -= _jpwr ; - - real_type _btol = _LTOL * + + real_type _btol = _LTOL * std::max(_ilen, _jlen) ; - - real_type _idel = + + real_type _idel = _ilen - _jbal[_dims] ; - real_type _jdel = + real_type _jdel = _jlen - _ibal[_dims] ; - + if (_idel >= - _btol || _jdel >= - _btol ) { @@ -222,16 +222,16 @@ else { return true ; - } - } - - + } + } + + /* -------------------------------------------------------- - * FLIP-T2T3: 3-simplex topological flip. + * FLIP-T2T3: 3-simplex topological flip. -------------------------------------------------------- */ - + __static_call __normal_call void_type flip_t2t3 ( geom_type &_geom , @@ -242,7 +242,7 @@ iptr_type _face , iptr_list &_told , iptr_list &_tnew , - bool_type &_flip , + bool_type &_flip , real_list &_qold , real_list &_qnew ) @@ -250,20 +250,20 @@ __unreferenced( _hfun) ; __unreferenced( _qold) ; __unreferenced( _qnew) ; - + _flip = false ; - - _told.set_count(0) ; + + _told.set_count(0) ; _tnew.set_count(0) ; - + } - + /* -------------------------------------------------------- - * FLIP-T3T2: 3-simplex topological flip. + * FLIP-T3T2: 3-simplex topological flip. -------------------------------------------------------- */ - + __static_call __normal_call void_type flip_t3t2 ( geom_type &_geom , @@ -274,7 +274,7 @@ iptr_type _edge , iptr_list &_told , iptr_list &_tnew , - bool_type &_flip , + bool_type &_flip , real_list &_qold , real_list &_qnew ) @@ -282,13 +282,13 @@ __unreferenced( _hfun) ; __unreferenced( _qold) ; __unreferenced( _qnew) ; - + _flip = false ; - - _told.set_count(0) ; + + _told.set_count(0) ; _tnew.set_count(0) ; - + } - - - + + + diff --git a/src/libcpp/iter_mesh/iter_mesh_2.hpp b/src/libcpp/iter_mesh/iter_mesh_2.hpp index 3da76d4..a44e3e9 100644 --- a/src/libcpp/iter_mesh/iter_mesh_2.hpp +++ b/src/libcpp/iter_mesh/iter_mesh_2.hpp @@ -4,36 +4,36 @@ * ITER-MESH-2: mesh-optimisation for 2-complexes. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 02 March, 2019 + * Last updated: 25 January, 2020 * - * Copyright 2013-2019 + * Copyright 2013-2020 * Darren Engwirda * de2363@columbia.edu * https://github.com/dengwirda/ @@ -47,7 +47,7 @@ # define __ITER_MESH_2__ namespace mesh { - + /* -------------------------------------------------------- * ITER-MESH-2: hill-climbing surf. iter. @@ -62,48 +62,51 @@ > class iter_mesh_2 { - public : + public : typedef M mesh_type ; typedef G geom_type ; typedef H size_type ; typedef P pred_type ; - typedef typename + typedef typename mesh_type::real_type real_type ; - typedef typename + typedef typename mesh_type::iptr_type iptr_type ; - - iptr_type static + + iptr_type static constexpr _dims = pred_type::_dims ; - - char_type static - constexpr _odt_kind = +1 ; // optimal delaunay - char_type static - constexpr _cvt_kind = +2 ; // centroidal voro. - char_type static - constexpr _sdQ_kind = +3 ; // local cost grad. - + + char_type static + constexpr _odt_kern = +1 ; + char_type static + constexpr _cvt_kern = +2 ; + char_type static + constexpr dqdx_kern = +5 ; + + class tria_kind {} ; // dummy for overloads + class dual_kind {} ; + typedef mesh::iter_params < real_type , iptr_type > iter_opts ; - + typedef mesh::iter_timers < real_type , iptr_type > iter_stat ; - + typedef containers - ::array< iptr_type > iptr_list ; + ::array< iptr_type > iptr_list ; typedef containers ::array< real_type > real_list ; - + public : - + /* -------------------------------------------------------- * FLIP-SIGN: flip tria for +ve iter. cost fn. -------------------------------------------------------- */ - + __static_call __normal_call void_type flip_next ( mesh_type &_mesh , @@ -124,18 +127,18 @@ _set3[_tpos].node(_inod[1]) ; _inod[ 2] = _mesh. _set3[_tpos].node(_inod[2]) ; - + _tset.set_count(0) ; - + _mesh.edge_tri3(_inod, _tset) ; - + if (_tset.count()!=+2) return ; - + if (_tset[0] == _tpos) _tadj = _tset[1] ; else _tadj = _tset[0] ; - + for(_eadj = 3 ; _eadj-- != 0; ) { mesh_type::tri3_type:: @@ -146,12 +149,12 @@ _set3[_tadj].node(_jnod[1]) ; _jnod[ 2] = _mesh. _set3[_tadj].node(_jnod[2]) ; - + if (_jnod[ 2] != _inod[ 0]) if (_jnod[ 2] != _inod[ 1]) - break ; - } - + break ; + } + if (_jnod[ 0] == _inod[ 0] && _jnod[ 1] == _inod[ 1] ) { @@ -160,9 +163,9 @@ _mesh._set3[_tadj].node(1)) ; } } - - /*------------------------- main sign-flip driver fn. */ - + + /*------------------------- main sign-flip driver fn. */ + __static_call __normal_call void_type flip_sign ( mesh_type &_mesh , @@ -170,26 +173,26 @@ ) { iptr_list _tset, _list, _seen ; - + __unreferenced(_pred); // for MSVC... _seen.set_count( _mesh. - _set3.count(), + _set3.count(), containers::tight_alloc , +0) ; - - /*----------- an incremental BFS to correct mesh sign */ + + /*----------- an incremental BFS to correct mesh sign */ iptr_type _tnum = +0 ; - iptr_type _epos = +0 ; - + iptr_type _epos = +0 ; + for (auto _tria = _mesh._set3.head() ; _tria != _mesh._set3.tend() ; ++_tria, ++_tnum ) { if (_tria->mark() < +0) continue ; if (_seen[_tnum ] > +0) continue ; - + /*--------------------- flip seed for +ve quality */ - real_type _cost = + real_type _cost = _pred.cost_tria ( &_mesh._set1[ _tria->node(0)].pval(0), @@ -197,44 +200,43 @@ _tria->node(1)].pval(0), &_mesh._set1[ _tria->node(2)].pval(0)) ; - + if (_cost < (real_type) +0.) { std::swap ( _tria->node(0) , _tria->node(1)); } - + /*--------------------- a BFS from seed via topo. */ _list.push_tail(_tnum) ; _seen [_tnum] = +1; - + for ( ; !_list.empty() ; ) { iptr_type _tpos; _list._pop_tail(_tpos) ; - + for (_epos = +3; _epos-- != +0; ) - { + { iptr_type _tadj = -1 ; iptr_type _eadj = -1 ; - - flip_next( _mesh, _tpos , - _epos, _tadj, _eadj , + + flip_next( _mesh, _tpos , + _epos, _tadj, _eadj , _tset) ; - + if (_tadj == -1) continue ; - + if (_seen[_tadj] == +0 ) - { + { _seen[_tadj] = +1 ; _list.push_tail(_tadj); } } } - } - + } /* @@ -242,140 +244,188 @@ * MOVE-OKAY: TRUE if state sufficiently good. -------------------------------------------------------- */ - + __static_call __inline_call void_type move_okay ( real_list &_cdst , real_list &_csrc , - bool_type &_okay , + bool_type &_okay , real_type _good = +9.25E-01, - real_type _qtol = +1.00E-04 + real_type _qtol = +1.00E-04, + real_type _xdel = +0.00E+00, + real_type _xtol = + std::numeric_limits::infinity() ) { - iptr_type _move; - move_okay(_cdst, _csrc, _move , - _good,_qtol) ; - + iptr_type _move; + move_okay(_cdst, _csrc, _move , + _good,_qtol, + _xdel,_xtol) ; + _okay = ( _move>(iptr_type)0 ); } - + __static_call __normal_call void_type move_okay ( real_list &_cdst , real_list &_csrc , - iptr_type &_move , + iptr_type &_move , real_type _good = +9.25E-01, - real_type _qtol = +1.00E-04 + real_type _qtol = +1.00E-04, + real_type _xdel = +0.00E+00, + real_type _xtol = + std::numeric_limits::infinity() ) { _move = (iptr_type) -1; - + if (_cdst.empty()) return ; if (_csrc.empty()) return ; - + /*--------------------- calc. min. + mean metrics */ - real_type _0src = + real_type _0src = +std::numeric_limits - ::infinity(); - - real_type _0dst = + ::infinity(); + + real_type _0dst = +std::numeric_limits ::infinity(); - - real_type _msrc, _mdst; - _msrc = (real_type) +0. ; + + real_type _msrc, _mdst; + _msrc = (real_type) +0. ; _mdst = (real_type) +0. ; - - for (auto _iter = _csrc.head() ; - _iter != _csrc.tend() ; + + for (auto _iter = _csrc.head(), + _tend = _csrc.tend(); + _iter != _tend; ++_iter ) { - _0src = - std::min(_0src, *_iter); - - _msrc += *_iter ; + _0src = + std::min(_0src, *_iter); + + //_msrc += *_iter ; + + _msrc += + (real_type)1. / *_iter ; } - for (auto _iter = _cdst.head() ; - _iter != _cdst.tend() ; + for (auto _iter = _cdst.head(), + _tend = _cdst.tend(); + _iter != _tend; ++_iter ) { - _0dst = - std::min(_0dst, *_iter); - - _mdst += *_iter ; + _0dst = + std::min(_0dst, *_iter); + + //_mdst += *_iter ; + + _mdst += + (real_type)1. / *_iter ; } - - /*--------------------- prevent element inversion */ + + //_msrc /= _csrc.count() ; + //_mdst /= _cdst.count() ; + + _msrc = + _csrc.count()/_msrc; + _mdst = + _cdst.count()/_mdst; + + /*--------------------- calc. min. + mean rel-tol */ _qtol *= std::max( - _0src, (real_type) +0.0); - - _msrc /= _csrc.count() ; - _mdst /= _cdst.count() ; - - - if ( true ) - { - /*--------------------- okay if all are improving */ - if (_0dst > _0src && - _mdst > _msrc ) + _0src, (real_type) +0.); + + real_type _mtol = _qtol; + real_type _0tol = _qtol; + + _mtol /= _csrc.count() ; + _mtol /= _cdst.count() ; + + /*--------------------- calc. min. + mean delta's */ + real_type _0del , _mdel; + _0del = _0dst - _0src; + _mdel = _mdst - _msrc; + + _0del /= std::min( + _cdst.count(), + _csrc.count()) ; + + _mdel *= std::min( + _cdst.count(), + _csrc.count()) ; + + _0del = + std::max(_0del,-_0tol) ; + _mdel = + std::max(_mdel,-_mtol) ; + + /*---------------------------- test move = 'okay' */ + if (true) + { + /*--------------------- okay if min. is improving */ + if (_0dst > _0src+_0tol) + if (_mdst > _msrc-_0del) _move = +1; - + if (_move > +0) return ; } - - if ( true ) - { - /*--------------------- okay if min. is improving */ - if (_0dst > _0src+_qtol) + + if (_0dst >= + std::pow(_good, +2)) + { + /*--------------------- okay if mean is improving */ + if (_mdst > _msrc+_mtol) + if (_0dst > _0src-_mdel) _move = +1; - else - if (_0dst > _0src) - _move = +0; - + if (_move > +0) return ; } - - _qtol /= _cdst.count() ; - + if (_0dst >= _good) { - /*--------------------- okay if mean is improving */ - if (_mdst > _msrc+_qtol) + /*--------------------- okay if moves unconverged */ + if (_xdel > _xtol) + if (_0dst > _0src-_xdel) _move = +1; - else - if (_mdst > _msrc) - _move = +0; - + + real_type _XDEL = + _xdel/_cdst.count(); + + if (_xdel > _xtol) + if (_mdst > _msrc-_XDEL) + _move = +1; + if (_move > +0) return ; - } - + } + } - + /* -------------------------------------------------------- * LOOP-COST: cost vector for 1-neighbourhood. -------------------------------------------------------- */ - + __static_call - __normal_call real_type loop_tscr ( + __normal_call real_type loop_cost ( mesh_type &_mesh , pred_type &_pred , iptr_list &_tset , - real_list &_cost + real_list &_cost , + tria_kind const& ) { - real_type _qmin = + real_type _qmin = +std::numeric_limits ::infinity(); - + __unreferenced(_pred) ; // for MSVC... - for (auto _tria = _tset.head(); - _tria != _tset.tend(); + for (auto _tria = _tset.head(), + _tend = _tset.tend(); + _tria != _tend; ++_tria ) { - real_type _tscr = + real_type _tscr = _pred.cost_tria ( &_mesh._set1[ _mesh._set3[ @@ -386,35 +436,37 @@ &_mesh._set1[ _mesh._set3[ *_tria].node(2)].pval(0)) ; - - _qmin = + + _qmin = std::min (_qmin, _tscr) ; - + _cost.push_tail (_tscr) ; } - - return ( _qmin ) ; + + return ( _qmin ) ; } - + __static_call - __normal_call real_type loop_dscr ( + __normal_call real_type loop_cost ( mesh_type &_mesh , pred_type &_pred , iptr_list &_tset , - real_list &_cost + real_list &_cost , + dual_kind const& ) { - real_type _qmin = + real_type _qmin = +std::numeric_limits ::infinity(); - + __unreferenced(_pred) ; // for MSVC... - for (auto _tria = _tset.head(); - _tria != _tset.tend(); + for (auto _tria = _tset.head(), + _tend = _tset.tend(); + _tria != _tend; ++_tria ) { - real_type _tscr = + real_type _tscr = _pred.cost_dual ( &_mesh._set1[ _mesh._set3[ @@ -425,24 +477,24 @@ &_mesh._set1[ _mesh._set3[ *_tria].node(2)].pval(0)) ; - - _qmin = + + _qmin = std::min (_qmin, _tscr) ; - + _cost.push_tail (_tscr) ; } - - return ( _qmin ) ; + + return ( _qmin ) ; } - + /* -------------------------------------------------------- * MOVE-NODE: "smart" coord. update for single node. -------------------------------------------------------- */ - + #include "iter_node_2.inc" - + template < typename node_iter > @@ -455,35 +507,35 @@ real_list &_hval , iter_opts &_opts , node_iter _node , - char_type _kind , - bool_type &_okay , + char_type _kern , + iptr_type &_move , iptr_list &_tset , real_list &_told , real_list &_tnew , - real_list &_dold , - real_list &_dnew , real_type _TMIN , - real_type _TLIM , - real_type _DMIN , - real_type _DLIM + real_type _TLIM ) { - iptr_type _move; - move_node( _geom, _mesh, _hfun, - _pred, _hval, _opts, _node, - _kind, _move, _tset, - _told, _tnew, _dold, _dnew, - _TMIN, _TLIM, - _DMIN, _DLIM) ; - - _okay = ( _move>(iptr_type)0 ); + move_kern( _geom, _mesh, _hfun, + _pred, _hval, _opts, _node, + _kern, _move, _tset, _told, + _tnew, _TMIN, _TLIM) ; + + if (_move >= +0 ) return ; + + move_kern( _geom, _mesh, _hfun, + _pred, _hval, _opts, _node, + dqdx_kern, _move, _tset, _told, + _tnew, _TMIN, _TLIM) ; + + if (_move >= +0 ) return ; } - + template < typename node_iter > __static_call - __normal_call void_type move_node ( + __normal_call void_type move_kern ( geom_type &_geom , mesh_type &_mesh , size_type &_hfun , @@ -491,180 +543,158 @@ real_list &_hval , iter_opts &_opts , node_iter _node , - char_type _kind , + char_type _kern , iptr_type &_move , iptr_list &_tset , real_list &_told , real_list &_tnew , - real_list &_dold , - real_list &_dnew , real_type _TMIN , - real_type _TLIM , - real_type _DMIN , - real_type _DLIM + real_type _TLIM ) { - iptr_type static + iptr_type static constexpr _ITER = (iptr_type)+5 ; - - __unreferenced(_DMIN) ; - _move = (iptr_type)+0 ; - + _move = (iptr_type)-1 ; + + /*---------------- calc. line search direction vector */ real_type _line [_dims] = { (real_type) +0.0 } ; real_type _save [_dims] = { (real_type) +0.0 } ; real_type _proj [_dims] = { (real_type) +0.0 } ; - - real_type _ladj = (real_type) + 0.0 ; - - /*---------------- calc. line search direction vector */ - if (_kind == _odt_kind) + + real_type _ladj = (real_type) +0.00 ; + + if (_kern == _odt_kern) { - _odt_move_2 ( - _mesh, _hfun, _pred, - _hval, _tset, _node, + /*--------------------------- ODT-style update vector */ + _odt_move_2 ( + _mesh, _hfun, _pred , + _hval, _tset, _node , _line, _ladj) ; } else - if (_kind == _sdQ_kind) + if (_kern == _cvt_kern) + { + /*--------------------------- CVT-style update vector */ + _cvt_move_2 ( + _mesh, _hfun, _pred , + _hval, _tset, _node , + _line, _ladj) ; + } + else + if (_kern == dqdx_kern) { if (_TMIN<=_TLIM) - { - grad_move_2 ( - _mesh, _hfun, _pred, - _tset, _node, _told, + { + /*--------------------------- d./dx Q^T update vector */ + dqdx_move_2 ( + _mesh, _hfun, _pred , + _tset, _node, _told , _line, _ladj) ; } else { return ; } } /*---------------- scale line search direction vector */ - real_type _llen = std:: - sqrt(_pred.length_sq(_line)) ; + real_type _xtol = // delta_x reltol + (real_type) +5.00E-004 ; - real_type _xtol = - (real_type)+.1 * _opts.qtol() ; + real_type _xeps = // delta_x ~= 0.0 + (real_type)+.01 *_opts.qtol() ; - if (_llen<= - _ladj * _xtol) return; + if (_kern == dqdx_kern) + { + _xtol = (real_type)+1. ; + } + + real_type _lsqr ; + _lsqr = std::pow(_ladj, 2) ; + _xtol = std::pow(_xtol, 2) ; + _xeps = std::pow(_xeps, 2) ; real_type _scal = // overrelaxation - _llen * (real_type)5./3. ; - + (real_type) +5.0 / 4.0 ; + /*---------------- do backtracking line search iter's */ - + for (auto _idim = _dims; _idim-- != +0; ) { - _save[_idim] = + _save[_idim] = _node->pval(_idim) ; - - _line[_idim] /= _llen ; + + //_line[_idim] /= _llen ; } - for (auto _iter = +0 ; - _iter != _ITER; ++_iter) + for (auto _iter = +0 ; + _iter != _ITER ; ++_iter) { + _tnew.set_count(0) ; + + /*---------------- push update along search direction */ for (auto _idim = _dims; _idim-- != +0; ) { - _proj[_idim] = - _save[_idim] + - _scal * _line[_idim] ; + _proj[_idim] = + _save[_idim] + + _scal * _line[_idim]; } - + _pred.proj_node ( _geom, _save, _proj) ; - + for (auto _idim = _dims; _idim-- != +0; ) { - _node->pval(_idim) + _node->pval(_idim) = _proj[_idim] ; } - - //!! do I need to check the normals here too?? - + + real_type _XTOL = _xtol * _scal ; + real_type _XEPS = _xeps * _scal ; + + real_type _lmov = _pred. + length_sq(_save , _proj)/ _lsqr ; + + if (_lmov <= _XEPS) break ; + + //_move = +1 ; return ; + _scal *= (real_type).5 ; - - _tnew.set_count(0) ; - _dnew.set_count(0) ; - - /*---------------- test quasi-monotonicity w.r.t. Q^T */ - loop_tscr( _mesh, _pred , - _tset, - _tnew) ; - - move_okay( _tnew, + + /*---------------- test quasi-monotonicity w.r.t. Q^T */ + loop_cost( _mesh, _pred, + _tset, + _tnew, + tria_kind()) ; + + move_okay( _tnew, _told, _move, - std::sqrt( _TLIM) , _opts.qtol()) ; - - if (_move < 0) continue ; - - if ( _TMIN>=_TLIM) - { - /*---------------- test quasi-monotonicity w.r.t. Q^D */ - loop_dscr( _mesh, _pred , - _tset, - _dnew) ; - - move_okay( _dnew, - _dold, _move, - std::sqrt( _DLIM) , _opts.qtol()) ; - } - - if (_move >= +0) break ; + _TLIM, _opts.qtol(), + _lmov, _XTOL) ; + + if (_move > 0) break ; } - + if (_move <= (iptr_type)0) { for (auto _idim = _dims; _idim-- != +0; ) { - _node->pval(_idim) + _node->pval(_idim) = _save[_idim] ; } } - + } - + /* -------------------------------------------------------- * MOVE-DUAL: "smart" weight update for single node. -------------------------------------------------------- */ - + #include "iter_dual_2.inc" - - template < - typename node_iter - > - __static_call - __inline_call void_type move_dual ( - geom_type &_geom , - mesh_type &_mesh , - size_type &_hfun , - pred_type &_pred , - real_list &_hval , - iter_opts &_opts , - node_iter _node , - bool_type &_okay , - iptr_list &_tset , - real_list &_dold , - real_list &_dnew , - real_type _DMIN , - real_type _DLIM - ) - { - iptr_type _move; - move_dual( _geom, _mesh, _hfun, - _pred, _hval, _opts, _node, - _move, _tset, - _dold, _dnew, - _DMIN, _DLIM) ; - - _okay = ( _move>(iptr_type)0 ); - } - + template < typename node_iter > @@ -681,83 +711,91 @@ iptr_list &_tset , real_list &_dold , real_list &_dnew , - real_type _DMIN , + real_type _DMIN , real_type _DLIM ) { - iptr_type static + iptr_type static constexpr _ITER = (iptr_type)+5 ; - + __unreferenced(_hval); + __unreferenced(_DMIN); + + _move = (iptr_type)-1; + + real_type _wadj, _step, _save; - _move = (iptr_type)+0; - - real_type _wadj, _line, _save ; - /*---------------- calc. line search direction vector */ - if(_DMIN < _DLIM) - { - grad_dual_2 ( - _geom, _mesh, _hfun, - _pred, _tset, _node, - _dold, _line, _wadj) ; + if (true) // (_DMIN < _DLIM) + { + dqdw_move_2 ( + _geom, _mesh, _hfun, + _pred, _tset, _node, + _dold, _step, _wadj) ; } else { return ; } - + /*---------------- scale line search direction vector */ - real_type - _llen = std::abs(_line ) ; - - real_type _xtol = - (real_type)+.1 * _opts.qtol() ; - - if (_llen<= - _wadj * _xtol) return; - + real_type _xeps = // delta_w ~= 0.0 + (real_type)+.01 *_opts.qtol() ; + real_type _scal = // overrelaxation - _llen * (real_type)5./3. ; - - _line /= _llen ; - - _save = _node->pval(_dims) ; - + (real_type) +5.0 / 4.0 ; + + _save = _node->pval(_dims) ; + /*---------------- do backtracking line search iter's */ - - for (auto _iter = +0 ; + + for (auto _iter = +0 ; _iter != _ITER; ++_iter ) { - _node->pval(_dims) = - _save + _scal*_line ; - - _dnew.set_count(0) ; - - _scal *= (real_type)+.5 ; - + _node->pval(_dims) = + _save + _scal * _step ; + + _node->pval(_dims) = // not too large! + std::max(-_wadj, + _node->pval(_dims)); + _node->pval(_dims) = + std::min(+_wadj, + _node->pval(_dims)); + + real_type _wmov = + std::abs (_save + - _node->pval(_dims)); + + if (_wmov <= + _xeps * _scal * _wadj) break; + + _dnew.set_count(0); + + _scal *= (real_type).5 ; + /*---------------- test quasi-monotonicity w.r.t. Q^D */ - loop_dscr( _mesh, _pred , - _tset, - _dnew) ; - - move_okay( _dnew, - _dold, _move, - std::sqrt( _DLIM) , _opts.qtol()) ; - - if (_move >= +0) break ; + loop_cost( _mesh, _pred, + _tset, + _dnew, + dual_kind()) ; + + move_okay( _dnew, + _dold, _move, + _DLIM, _opts.qtol()) ; + + if (_move > 0) break ; } - + if (_move <= (iptr_type) +0) { _node->pval(_dims) = _save ; } - + } - + /* -------------------------------------------------------- * SORT-NODE: permutations for node optimisation. -------------------------------------------------------- */ - + __static_call void_type sort_node ( geom_type &_geom , mesh_type &_mesh , @@ -769,7 +807,7 @@ iptr_list &_aset , iptr_list &_amrk , iptr_list &_nmrk , - iptr_type _iout , + iptr_type _iout , iptr_type _isub , iter_opts &_opts , real_type _TLIM , @@ -781,61 +819,71 @@ public : /*------------------------ tuple for node re-ordering */ iptr_type _node ; - real_type _cost ; + float _cost ; } ; - + class cost_less { public : /*------------------------ less-than op. for cost-tup */ - __inline_call + __inline_call bool_type operator () ( cost_pair const&_idat , cost_pair const&_jdat - ) const - { return + ) const + { return _idat._cost < _jdat._cost ; } } ; - + typedef containers:: arraycost_list ; - + iptr_list _eset ; cost_list _sset ; - + __unreferenced(_geom) ; __unreferenced(_hfun) ; __unreferenced(_pred) ; __unreferenced(_hval) ; __unreferenced(_opts) ; __unreferenced(_DLIM) ; - - if (_isub == (iptr_type) +0) + + if (_isub == (iptr_type) +0 ) { /*-------------------- 1ST SUB-ITER: build full init. */ + for (auto _iter = _qscr.head(); + _iter != _qscr.tend(); + ++_iter ) + { + *_iter = (real_type) +1.; + } + for (auto _tria = _mesh._set3.head(); _tria != _mesh._set3.tend(); ++_tria ) { - if (_tria->mark() >= +0) + if (_tria->mark() >= +0 ) { /*-------------------- calc. min. scores at nodes */ iptr_type _inod, _jnod, _knod; _inod = _tria->node(0); _jnod = _tria->node(1); _knod = _tria->node(2); - - real_type _cost = + + real_type _cost = _pred.cost_tria ( &_mesh._set1[_inod].pval(0), &_mesh._set1[_jnod].pval(0), &_mesh._set1[_knod].pval(0) ) ; - + iptr_type _flag = _iout-2 ; - - if (_cost <= _TLIM || + + real_type _TURN = + std::pow(_TLIM, 1./4.); + + if (_cost <= _TURN || std::abs( _nmrk[_inod])>= _flag || std::abs( @@ -843,7 +891,7 @@ std::abs( _nmrk[_knod])>= _flag ) { - + if (_amrk[_inod] != _isub ) { _amrk[_inod] = _isub ; @@ -851,7 +899,7 @@ _sset.tail()-> _node = _inod ; } - + if (_amrk[_jnod] != _isub ) { _amrk[_jnod] = _isub ; @@ -859,7 +907,7 @@ _sset.tail()-> _node = _jnod ; } - + if (_amrk[_knod] != _isub ) { _amrk[_knod] = _isub ; @@ -867,33 +915,33 @@ _sset.tail()-> _node = _knod ; } - + } - + _qscr[_inod] = std::min ( _cost,_qscr[_inod]) ; - + _qscr[_jnod] = std::min ( _cost,_qscr[_jnod]) ; - + _qscr[_knod] = std::min ( _cost,_qscr[_knod]) ; } } - + for (auto _iter = _sset.head() ; _iter != _sset.tend() ; ++_iter ) { /*------------------------ assign min.-cost for nodes */ - _iter->_cost = - _qscr[_iter->_node]; + _iter->_cost = + (float)_qscr[_iter->_node]; } - - algorithms::qsort( _sset.head() , - _sset.tend() , + + algorithms::qsort( _sset.head() , + _sset.tend() , cost_less () ) ; - + for (auto _iter = _sset.head() ; _iter != _sset.tend() ; ++_iter ) @@ -901,7 +949,7 @@ /*------------------------ push sorted wrt. min.-cost */ _aset.push_tail(_iter->_node) ; } - + } else { @@ -909,68 +957,62 @@ for (auto _iter = _nset.head() ; _iter != _nset.tend() ; ++_iter ) - { + { + _amrk[*_iter] = _isub; + _aset.push_tail(*_iter) ; + } + + for (auto _iter = _nset.head() ; + _iter != _nset.tend() ; + ++_iter ) + { _eset.set_count(0) ; - + _mesh.node_edge ( &*_iter, _eset) ; - + for (auto _edge = _eset.head(); _edge != _eset.tend(); ++_edge ) { - auto _eptr = + auto _eptr = _mesh._set2.head() + *_edge; - + iptr_type _inod, _jnod; _inod = _eptr->node(0); _jnod = _eptr->node(1); - + if (_amrk[_inod] != _isub) { _amrk[_inod] = _isub; _aset.push_tail(_inod) ; } - + if (_amrk[_jnod] != _isub) { _amrk[_jnod] = _isub; _aset.push_tail(_jnod) ; } - } - } - - /*-------------------- weak, stochastic randomisation */ - for (auto _iter = _aset.head(); - _iter != _aset.tend(); - ++_iter ) - { - auto _sift = std::min ( - (size_t) + 8, - (size_t) (_aset.tend()-_iter) ) ; - - auto _next = _iter + - std::rand() % _sift ; - - std::swap(*_iter,*_next); + } } - + } - + } - + /* -------------------------------------------------------- * MOVE-NODE: do a single node smoothing pass. -------------------------------------------------------- */ - - __static_call + + __static_call __normal_call void_type move_node ( geom_type &_geom , mesh_type &_mesh , size_type &_hfun , pred_type &_pred , + char_type _kern , real_list &_hval , real_list &_qscr , iptr_list &_nset , @@ -978,72 +1020,76 @@ iptr_list &_nmrk , iptr_list &_emrk , iptr_list &_tmrk , - iptr_type _iout , + iptr_type _iout , iptr_type _isub , iter_opts &_opts , - iptr_type &_nmov , + iptr_type &_nmov , real_type _TLIM , real_type _DLIM ) { iptr_list _aset, _tset; - real_list _told, _tnew; - real_list _dold, _dnew; + real_list _told, _tnew, _dold, _dnew; __unreferenced ( _emrk) ; __unreferenced ( _tmrk) ; - _nmov = (iptr_type) +0 ; - + _nmov = (iptr_type) +0 ; + /*-------------------- permute nodes for optimisation */ - sort_node( _geom, _mesh, _hfun, - _pred, _hval, _qscr, - _nset, _aset, - _amrk, _nmrk, _iout, _isub, + sort_node( _geom, _mesh, _hfun, + _pred, _hval, _qscr, + _nset, _aset, + _amrk, _nmrk, _iout, _isub, _opts, _TLIM, _DLIM ) ; - - /*-------------------- GAUSS-SEIDEL iteration on DUAL */ - if (_opts .dual()) + + /*-------------------- GAUSS-SEIDEL iteration on TRIA */ + if (_opts .tria()) { for (auto _apos = _aset.head() ; _apos != _aset.tend() ; ++_apos ) { - auto _node = + auto _node = _mesh._set1.head() + *_apos ; - + _tset.set_count( +0); - + /*---------------- assemble a local tria. stencil */ _mesh.node_tri3( &_node->node(+0), _tset); if (_tset.empty()) continue ; - - /*---------------- attempt to optimise DUAL geom. */ - _dold.set_count( +0); - _dnew.set_count( +0); - - real_type _DMIN = - loop_dscr( _mesh, - _pred, _tset, _dold); - - bool_type _okay = false; - - if(!_okay) + + if (_nmrk[*_apos] >= +0) { - /*---------------- attempt a GRAD-based smoothing */ - move_dual( _geom, _mesh , - _hfun, _pred, _hval , - _opts, _node, - _okay, _tset, - _dold, _dnew, - _DMIN, _DLIM ) ; - } - - if (_okay) + /*---------------- attempt to optimise TRIA geom. */ + _told.set_count( +0); + _tnew.set_count( +0); + + real_type _TMIN = + loop_cost( _mesh, + _pred, _tset, + _told, tria_kind()); + + iptr_type _move = -1; + + if(_move < +0) + { + /*---------------- do optimisation of node coord. */ + move_node( _geom, _mesh , + _hfun, _pred, _hval , + _opts, _node, _kern , + _move, _tset, + _told, _tnew, + _TMIN, _TLIM ) ; + } + + if (_move > +0) { /*---------------- update when state is improving */ + _hval[*_apos] = (real_type)-1. ; + if (std::abs( _nmrk[*_apos]) != _iout) { @@ -1051,83 +1097,59 @@ _nmrk[*_apos] = +_iout; else _nmrk[*_apos] = -_iout; - + _nset.push_tail(*_apos) ; } - + _nmov += +1 ; } + } } } - - /*-------------------- GAUSS-SEIDEL iteration on TRIA */ - if (_opts .tria()) + + /*-------------------- GAUSS-SEIDEL iteration on DUAL */ + if (_opts .dual()) { for (auto _apos = _aset.head() ; _apos != _aset.tend() ; ++_apos ) { - auto _node = + auto _node = _mesh._set1.head() + *_apos ; - + _tset.set_count( +0); - + /*---------------- assemble a local tria. stencil */ _mesh.node_tri3( &_node->node(+0), _tset); if (_tset.empty()) continue ; - if (_nmrk[*_apos] >= +0) - { - /*---------------- attempt to optimise TRIA geom. */ - _told.set_count( +0); - _tnew.set_count( +0); + /*---------------- attempt to optimise DUAL geom. */ _dold.set_count( +0); _dnew.set_count( +0); - - real_type _TMIN = - loop_tscr( _mesh, - _pred, _tset, _told); - real_type _DMIN = - loop_dscr( _mesh, - _pred, _tset, _dold); + real_type _DMIN = + loop_cost( _mesh, + _pred, _tset, + _dold, dual_kind()); - bool_type _okay = false; + iptr_type _move = -1; - if(!_okay) + if(_move < +0) { - /*---------------- attempt a CCVT-style smoothing */ - move_node( _geom, _mesh , - _hfun, _pred, _hval , - _opts, _node, - _odt_kind, - _okay, _tset, - _told, _tnew, - _dold, _dnew, - _TMIN, _TLIM, - _DMIN, _DLIM ) ; - } - if(!_okay) - { - /*---------------- attempt a GRAD-based smoothing */ - move_node( _geom, _mesh , - _hfun, _pred, _hval , - _opts, _node, - _sdQ_kind, - _okay, _tset, - _told, _tnew, - _dold, _dnew, - _TMIN, _TLIM, + /*---------------- do optimisation of node weight */ + move_dual( _geom, _mesh , + _hfun, _pred, _hval , + _opts, _node, + _move, _tset, + _dold, _dnew, _DMIN, _DLIM ) ; } - - if (_okay) + + if (_move > +0) { /*---------------- update when state is improving */ - _hval[*_apos] = (real_type)-1. ; - if (std::abs( _nmrk[*_apos]) != _iout) { @@ -1135,26 +1157,25 @@ _nmrk[*_apos] = +_iout; else _nmrk[*_apos] = -_iout; - + _nset.push_tail(*_apos) ; } - + _nmov += +1 ; } - } - } } - + } + } - + /* -------------------------------------------------------- * FLIP-MESH: "flip" mesh topology. -------------------------------------------------------- */ - + #include "iter_flip_2.inc" - + __static_call __inline_call void_type flip_tria ( geom_type &_geom , @@ -1162,7 +1183,7 @@ size_type &_hfun , pred_type &_pred , iptr_type _tria , - bool_type &_flip , + bool_type &_flip , iptr_list &_told , iptr_list &_tnew , real_list &_qold , @@ -1170,31 +1191,31 @@ ) { _flip = false ; - - auto + + auto _coin = std::rand() % +3 ; - + if (_coin == +0) { /*--------------------------------- flip edges: 0,1,2 */ - flip_t2t2( _geom, _mesh , - _hfun, _pred, + flip_t2t2( _geom, _mesh , + _hfun, _pred, _tria, +0 , - _told, _tnew, _flip , + _told, _tnew, _flip , _qold, _qnew) ; if (_flip) return ; - - flip_t2t2( _geom, _mesh , - _hfun, _pred, + + flip_t2t2( _geom, _mesh , + _hfun, _pred, _tria, +1 , - _told, _tnew, _flip , + _told, _tnew, _flip , _qold, _qnew) ; if (_flip) return ; - - flip_t2t2( _geom, _mesh , - _hfun, _pred, + + flip_t2t2( _geom, _mesh , + _hfun, _pred, _tria, +2 , - _told, _tnew, _flip , + _told, _tnew, _flip , _qold, _qnew) ; if (_flip) return ; } @@ -1202,60 +1223,60 @@ if (_coin == +1) { /*--------------------------------- flip edges: 1,2,0 */ - flip_t2t2( _geom, _mesh , - _hfun, _pred, + flip_t2t2( _geom, _mesh , + _hfun, _pred, _tria, +1 , - _told, _tnew, _flip , + _told, _tnew, _flip , _qold, _qnew) ; if (_flip) return ; - - flip_t2t2( _geom, _mesh , - _hfun, _pred, + + flip_t2t2( _geom, _mesh , + _hfun, _pred, _tria, +2 , - _told, _tnew, _flip , + _told, _tnew, _flip , _qold, _qnew) ; if (_flip) return ; - - flip_t2t2( _geom, _mesh , - _hfun, _pred, + + flip_t2t2( _geom, _mesh , + _hfun, _pred, _tria, +0 , - _told, _tnew, _flip , + _told, _tnew, _flip , _qold, _qnew) ; if (_flip) return ; } else { /*--------------------------------- flip edges: 2,0,1 */ - flip_t2t2( _geom, _mesh , - _hfun, _pred, + flip_t2t2( _geom, _mesh , + _hfun, _pred, _tria, +2 , - _told, _tnew, _flip , + _told, _tnew, _flip , _qold, _qnew) ; if (_flip) return ; - - flip_t2t2( _geom, _mesh , - _hfun, _pred, + + flip_t2t2( _geom, _mesh , + _hfun, _pred, _tria, +0 , - _told, _tnew, _flip , + _told, _tnew, _flip , _qold, _qnew) ; if (_flip) return ; - - flip_t2t2( _geom, _mesh , - _hfun, _pred, + + flip_t2t2( _geom, _mesh , + _hfun, _pred, _tria, +1 , - _told, _tnew, _flip , + _told, _tnew, _flip , _qold, _qnew) ; if (_flip) return ; } - + } - + __static_call __normal_call void_type flip_mesh ( geom_type &_geom , mesh_type &_mesh , size_type &_hfun , - pred_type &_pred , + pred_type &_pred , iptr_list &_nset , iptr_list &_nmrk , iptr_list &_emrk , @@ -1264,25 +1285,26 @@ iptr_type &_nflp ) { - init_mark(_mesh, _nmrk, _emrk, _tmrk, + init_mark(_mesh, _nmrk, _emrk, _tmrk, std::max(+0, _imrk - 1)) ; - + /*--------------------- init. flip stack as ADJ(NSET) */ iptr_list _tset, _next; iptr_list _told, _tnew; real_list _qold, _qnew; - + for (auto _iter = _nset.head(); _iter != _nset.tend(); ++_iter ) { - if (_mesh._set1[*_iter].mark()>=+0) - { + if ( _mesh. + _set1[*_iter].mark() >= +0) + { _tnew.set_count(+0); - + _mesh.node_tri3( &*_iter, _tnew); - + for (auto _tadj = _tnew.head(); _tadj != _tnew.tend(); ++_tadj ) @@ -1295,26 +1317,27 @@ } } } - - /*--------------------- exhaustive, incremental flips */ + + /*--------------------- exhaustive, incremental flips */ _nflp = +0 ; - + for ( ; !_tset.empty() ; ) { for (auto _tria = _tset.head(); _tria != _tset.tend(); ++_tria ) { - if (_mesh._set3[*_tria].mark()>=+0) - { + if ( _mesh. + _set3[*_tria].mark() >= +0) + { bool_type _flip = false ; - flip_tria( _geom, _mesh, + flip_tria( _geom, _mesh, _hfun, _pred, - *_tria, _flip, - _told, _tnew, + *_tria, _flip, + _told, _tnew, _qold, _qnew ); if (_flip) _nflp += +1 ; - + for (auto _iter = _tnew.head(); _iter != _tnew.tend(); ++_iter ) @@ -1325,24 +1348,25 @@ } _tset = std::move(_next) ; } - + } - + /* -------------------------------------------------------- * _ZIP-MESH: edge merge/split operations. -------------------------------------------------------- */ - + #include "iter_zips_2.inc" #include "iter_divs_2.inc" - + __static_call __normal_call void_type _zip_mesh ( geom_type &_geom , - mesh_type &_mesh , + mesh_type &_mesh , size_type &_hfun , - pred_type &_pred , + pred_type &_pred , + char_type _kern , real_list &_hval , iptr_list &_nset , iptr_list &_nmrk , @@ -1356,108 +1380,167 @@ iptr_type &_ndiv ) { - iptr_type static - constexpr _DEG_MIN = (iptr_type) +5 ; - iptr_type static - constexpr _DEG_MAX = (iptr_type) +8 ; - + class sort_pair + { + public : + /*------------------------ tuple for edge re-ordering */ + iptr_type _edge ; + float _cost ; + } ; + + class sort_less + { + public : + /*------------------------ less-than op. for cost-tup */ + __inline_call + bool_type operator () ( + sort_pair const&_idat , + sort_pair const&_jdat + ) const + { return + _idat._cost < _jdat._cost ; + } + } ; + # define __marknode \ init_mark( _mesh, _nmrk, _emrk, \ - _tmrk, std::max(_imrk - 0, +0) ) ; \ + _tmrk, std::max(_imrk-1, +0)) ; \ if (std::abs( \ - _nmrk[_nnew])!= _imrk) \ + _nmrk[_nnew])!= _imrk+1) \ { \ if (_nmrk[_nnew] >= +0) \ { \ - _nmrk[_nnew] = +_imrk; \ + _nmrk[_nnew] = +_imrk+1; \ } \ else \ { \ - _nmrk[_nnew] = -_imrk; \ + _nmrk[_nnew] = -_imrk-1; \ } \ _nset.push_tail(_nnew) ; \ } \ - - + + iptr_type static + constexpr _DEG_MIN = (iptr_type) +5 ; + iptr_type static + constexpr _DEG_MAX = (iptr_type) +7 ; + + typedef containers:: + arraysort_list ; + + __unreferenced (_DLIM) ; + _nzip = +0 ; _ndiv = +0 ; - + + sort_list _sort; + iptr_list _aset, _bset, _cset ; iptr_list _eset, _done; iptr_list _iset, _jset; real_list _told, _tnew, _ttmp ; - real_list _dold, _dnew; - - for (auto _node = + + for (auto _node = _mesh._set1.count() ; _node-- != +0; ) { /*--------------------- scan nodes and zip//div edges */ if ( _mesh. - _set1[_node].mark () >= +0 && + _set1[_node].mark () >= +0 && std::abs ( _nmrk[_node]) >= _imrk - 2 ) { - typename - iptr_list::_write_it _head ; - typename - iptr_list::_write_it _tend ; - typename - iptr_list::diff_type _einc ; - _eset.set_count(+0) ; + _sort.set_count(+0) ; _mesh.node_edge( - (iptr_type)_node, _eset) ; - - /*------------------- "weak" stochastic order */ - if (std::rand() % +2 == +0 ) + (iptr_type) _node, _eset) ; + + for (auto _eadj = _eset.head(); + _eadj != _eset.tend(); + ++_eadj ) { - _head = _eset.head() ; - _tend = _eset.tend() ; - _einc = +1 ; + auto _eptr = + _mesh._set2.head() + *_eadj; + + auto _iptr = _mesh. + _set1.head()+ _eptr->node(0) ; + auto _jptr = _mesh. + _set1.head()+ _eptr->node(1) ; + + real_type _line[_dims] ; + iptr_type _idim=_dims; + + for ( ; _idim-- != +0; ) + { + _line[_idim] = + _jptr->pval(_idim) - + _iptr->pval(_idim) ; + } + + float _lsqr = (float) + _pred.length_sq(_line) ; + + sort_pair _pair; + _pair._cost = _lsqr ; + _pair._edge =*_eadj ; + + _sort.push_tail(_pair) ; } - else + + if (_sort.empty()) continue; + + /*------------------- scan local edges by len */ + algorithms::isort ( + _sort.head(), + _sort.tend(), sort_less()) ; + + bool_type _move = false ; + + for (auto _iter = _sort.tail(); + _iter != _sort.hend(); + --_iter ) { - _head = _eset.tail() ; - _tend = _eset.hend() ; - _einc = -1 ; - } - - /*------------------- scan list of adj. edges */ - for (auto _eadj = _head ; - _eadj != _tend ; - _eadj += _einc ) - { - auto _eptr = - _mesh._set2.head() + *_eadj; - - iptr_type _enod[2] ; + auto _eadj = _iter->_edge; + + auto _eptr = + _mesh._set2.head() + _eadj; + + iptr_type _enod[2] ; _enod[0] = _eptr->node(0); _enod[1] = _eptr->node(1); - - bool_type _move = false; - + + if (std::abs( + _nmrk[_enod[0]]) > _imrk || + std::abs( + _nmrk[_enod[1]]) > _imrk ) + continue ; + /*------------------- try to "div" local edge */ - if (_eptr->self() == +0) + if (_nmrk[_enod[0]] >= 0 && + _nmrk[_enod[1]] >= 0 ) { if (_eset.count() > _DEG_MAX) { - real_type _qinc = - (real_type) -0.500 ; - real_type _ltol = - (real_type) +0.500 ; - + real_type _qinc = + (real_type) -1./9. ; + real_type _ltol = + (real_type) +8./9. ; + + _qinc *= + _eset.count() - 6; + + _qinc /= // don't ping-pong w zip + std::sqrt (_imrk); + iptr_type _nnew = -1; - + if (_opts.div_()) - _div_edge( _geom, _mesh, - _hfun, _pred, - _hval, _opts,*_eadj, - _move, _nnew, + _div_edge( _geom, _mesh, + _hfun, _pred, + _hval, _opts, _eadj, + _kern, _move, _nnew, _iset, _jset, - _told, _tnew, _ttmp, - _dold, _dnew, - _TLIM, _DLIM, - _ltol, _qinc) ; - + _told, _tnew, + _ttmp, _TLIM, + _ltol, _qinc) ; + if (_move) { __marknode; _ndiv += +1; break ; @@ -1466,105 +1549,141 @@ else { iptr_type _nnew = -1; - + if (_opts.div_()) - _div_edge( _geom, _mesh, - _hfun, _pred, - _hval, _opts,*_eadj, - _move, _nnew, + _div_edge( _geom, _mesh, + _hfun, _pred, + _hval, _opts, _eadj, + _kern, _move, _nnew, _iset, _jset, - _told, _tnew, _ttmp, - _dold, _dnew, - _TLIM, _DLIM) ; - + _told, _tnew, + _ttmp, _TLIM) ; + if (_move) { __marknode; _ndiv += +1; break ; } } } - + } + + if (_move) continue ; + + /*------------------- scan local edges by len */ + for (auto _iter = _sort.head(); + _iter != _sort.tend(); + ++_iter ) + { + auto _eadj = _iter->_edge; + + auto _eptr = + _mesh._set2.head() + _eadj; + + iptr_type _enod[2] ; + _enod[0] = _eptr->node(0); + _enod[1] = _eptr->node(1); + + if (std::abs( + _nmrk[_enod[0]]) > _imrk || + std::abs( + _nmrk[_enod[1]]) > _imrk ) + continue ; + /*------------------- try to "zip" local edge */ if (_nmrk[_enod[0]] >= 0 && _nmrk[_enod[1]] >= 0 ) { if (_eset.count() < _DEG_MIN) { - real_type _qinc = - (real_type) -0.500 ; - real_type _ltol = - (real_type) +2.000 ; - + real_type _qinc = + (real_type) -1./9. ; + real_type _ltol = + (real_type) +9./8. ; + + _qinc /= // don't ping-pong w div + std::sqrt (_imrk); + iptr_type _nnew = -1; - + if (_opts.zip_()) - _zip_edge( _geom, _mesh, - _hfun, _pred, - _hval, _opts,*_eadj, - _move, _nnew, + _zip_edge( _geom, _mesh, + _hfun, _pred, + _hval, _opts, _eadj, + _kern, _move, _nnew, _iset, _jset, _aset, _bset, _cset, - _told, _tnew, _ttmp, - _dold, _dnew, - _TLIM, _DLIM, + _told, _tnew, + _ttmp, _TLIM, _ltol, _qinc) ; - + if (_move) - { + { __marknode; _nzip += +1; break ; - } + } } else - { + { iptr_type _nnew = -1; - + if (_opts.zip_()) - _zip_edge( _geom, _mesh, - _hfun, _pred, - _hval, _opts,*_eadj, - _move, _nnew, + _zip_edge( _geom, _mesh, + _hfun, _pred, + _hval, _opts, _eadj, + _kern, _move, _nnew, _iset, _jset, _aset, _bset, _cset, - _told, _tnew, _ttmp, - _dold, _dnew, - _TLIM, _DLIM) ; - + _told, _tnew, + _ttmp, _TLIM) ; + if (_move) - { + { __marknode; _nzip += +1; break ; } - } } - + } } - + + if (_move) continue ; + } } - + + for (auto _iter = _nmrk.head() ; + _iter != _nmrk.tend() ; + ++_iter ) + { + /*--------------------- undo local inc. on node flags */ + if (*_iter > + _imrk) + *_iter = + _imrk; + else + if (*_iter < - _imrk) + *_iter = - _imrk; + } + # undef __marknode - + } - + /*------------------------------ helper: init. marker */ - - __static_call + + __static_call __normal_call void_type init_mark ( mesh_type &_mesh , iptr_list &_nmrk , iptr_list &_emrk , - iptr_list &_tmrk , + iptr_list &_tmrk , iptr_type _flag = +0 ) { - iptr_type _nmax = + iptr_type _nmax = (iptr_type)std::max( _nmrk.count() , _mesh._set1.count() ) ; - iptr_type _emax = + iptr_type _emax = (iptr_type)std::max( _emrk.count() , _mesh._set2.count() ) ; - iptr_type _tmax = + iptr_type _tmax = (iptr_type)std::max( _tmrk.count() , _mesh._set3.count() ) ; @@ -1579,13 +1698,13 @@ containers:: loose_alloc, _flag) ; } - + /* -------------------------------------------------------- * ITER-MESH: "hill-climbing" type mesh optimisation. -------------------------------------------------------- */ - + template < typename text_dump > @@ -1594,20 +1713,24 @@ geom_type &_geom , size_type &_hfun , mesh_type &_mesh , + char_type _kern , pred_type &_pred , iter_opts &_opts , text_dump &_dump ) { iter_stat _tcpu ; - + /*------------------------------ push log-file header */ - _dump.push ( + if (_opts.verb() >= 0 ) + { + _dump.push( "#------------------------------------------------------------\n" "# |MOVE.| |FLIP.| |MERGE| |SPLIT| \n" "#------------------------------------------------------------\n" - ) ; - + ) ; + } + # ifdef __use_timers typename std ::chrono:: high_resolution_clock:: @@ -1620,33 +1743,33 @@ __unreferenced(_time) ; // why does MSVC need this?? # endif//__use_timers - - /*------------------------------ ensure deterministic */ + + /*------------------------------ ensure deterministic */ std::srand( +1 ) ; - - /*------------------------------ push boundary marker */ - iptr_list _nmrk, _emrk, _tmrk, + + /*------------------------------ push boundary marker */ + iptr_list _nmrk, _emrk, _tmrk, _nset, _tset; - + init_mark(_mesh, _nmrk, _emrk, _tmrk) ; - + iptr_type _nnum = +0 ; iptr_type _enum = +0 ; - + for (auto _node = _mesh._set1.head() ; _node != _mesh._set1.tend() ; ++_node, ++_nnum ) { if (_node->mark() >= +0) { - if (_node->feat() + if (_node->feat() != mesh::null_feat) { _nmrk[_nnum] = -1; } } } - + for (auto _edge = _mesh._set2.head() ; _edge != _mesh._set2.tend() ; ++_edge, ++_enum ) @@ -1661,10 +1784,10 @@ else { _tset.set_count(0) ; - + _mesh.edge_tri3 ( &_edge->node(0), _tset) ; - + if (_tset.count() != +2) { _nmrk[_edge->node(0)] = -1 ; @@ -1673,147 +1796,179 @@ } } } - - flip_sign(_mesh , _pred) ; - + + flip_sign (_mesh, _pred) ; + /*------------------------------ do optimisation loop */ iptr_type static constexpr - ITER_MIN_ = + 3 ; + ITER_MIN_ = + 4 ; iptr_type static constexpr ITER_MAX_ = + 8 ; - + bool_type static constexpr ITER_FLIP = true ; - - real_type _TLIM = _opts.qlim() ; - - //real_type _DLIM = + 0.99250 ; - real_type _DLIM = - std::pow(_TLIM, +1./8.) ; - - for (auto _iter = +1 ; + + real_type _QMIN = (real_type) +1. ; + + for (auto _tria = _mesh._set3.head() ; + _tria != _mesh._set3.tend() ; + ++_tria ) + { + if (_tria->mark() >= +0 ) + { + /*--------------------- test initial cell quality */ + real_type _cost = + _pred.cost_tria ( + &_mesh._set1[ + _tria->node(0)].pval(0), + &_mesh._set1[ + _tria->node(1)].pval(0), + &_mesh._set1[ + _tria->node(2)].pval(0) + ) ; + + _QMIN = std::min (_QMIN, _cost) ; + } + } + + for (auto _iter = +1 ; _iter <= _opts.iter(); ++_iter) { /*-------------------------- set-up current iter. */ - init_mark(_mesh, _nmrk, + init_mark(_mesh, _nmrk, _emrk, _tmrk, std::max(_iter-1, +0)); - + real_list _hval, _qmin; _hval.set_count( - _mesh._set1.count(), + _mesh._set1.count(), containers::tight_alloc, (real_type)-1.); - + _qmin.set_count( - _mesh._set1.count(), + _mesh._set1.count(), containers::tight_alloc, (real_type)+1.); - + iptr_list _amrk; _amrk.set_count( - _mesh._set1.count(), + _mesh._set1.count(), containers::tight_alloc, (iptr_type)-1 ); - + _nset.set_count( +0); - + iptr_type _nmov = +0 ; iptr_type _nflp = +0 ; iptr_type _nzip = +0 ; iptr_type _ndiv = +0 ; - + /*------------------------------ scale quality thresh */ iptr_type _nsub = _iter + 0 ; - + _nsub = std::min( ITER_MAX_, _nsub) ; _nsub = std::max( ITER_MIN_, _nsub) ; - + + real_type _TLIM = + (real_type).750*_opts.qlim() + + (real_type).075*_iter; + + _TLIM = std::max( _TLIM, + _QMIN) ; + _TLIM = std::min( + _opts.qlim(), _TLIM) ; + + real_type _DLIM = + (real_type)(1. - + 1. * std::pow(1.-_TLIM, 2)) ; + /*------------------------------ update mesh geometry */ # ifdef __use_timers _ttic = _time.now() ; # endif//__use_timers - - for (auto _isub = + 0 ; + + for (auto _isub = + 0 ; _isub != _nsub; ++_isub ) { if (_opts.verb() >= +3) _dump.push( " CALL MOVE-NODE...\n") ; - + iptr_type _nloc; move_node( _geom, _mesh , - _hfun, _pred, - _hval, _qmin, + _hfun, _pred, _kern , + _hval, _qmin, _nset, _amrk, - _nmrk, _emrk, _tmrk , - _iter, _isub, - _opts, _nloc, + _nmrk, _emrk, _tmrk , + _iter, _isub, + _opts, _nloc, _TLIM, _DLIM) ; - - _nmov = std::max (_nmov , - _nloc ) ; + + _nmov = std::max (_nmov , + _nloc ) ; } - + # ifdef __use_timers _ttoc = _time.now() ; - - _tcpu._move_full += + + _tcpu._move_full += _tcpu.time_span(_ttic, _ttoc); # endif//__use_timers - + /*------------------------------ update mesh topology */ - # ifdef __use_timers + # ifdef __use_timers _ttic = _time.now() ; # endif//__use_timers - + if (ITER_FLIP) { if (_opts.verb() >= +3) _dump.push( " CALL FLIP-MESH...\n") ; - - flip_mesh( _geom, _mesh , + + flip_mesh( _geom, _mesh , _hfun, _pred, _nset , - _nmrk, _emrk, _tmrk , + _nmrk, _emrk, _tmrk , _iter, _nflp) ; } - - # ifdef __use_timers + + # ifdef __use_timers _ttoc = _time.now() ; - - _tcpu._topo_full += + + _tcpu._topo_full += _tcpu.time_span(_ttic, _ttoc); # endif//__use_timers - + /*------------------------------ zip/div mesh subface */ - # ifdef __use_timers + # ifdef __use_timers _ttic = _time.now() ; # endif//__use_timers - + if (_iter < _opts.iter() ) - if (_opts.zip_() || + if (_opts.zip_() || _opts.div_() ) { if (_opts.verb() >= +3) _dump.push( " CALL _ZIP-MESH...\n") ; - - _zip_mesh( _geom, _mesh , - _hfun, _pred, - _hval, _nset, - _nmrk, _emrk, _tmrk , + + _zip_mesh( _geom, _mesh , + _hfun, _pred, _kern , + _hval, _nset, + _nmrk, _emrk, _tmrk , _iter, _opts, _TLIM, _DLIM, _nzip, _ndiv) ; } - # ifdef __use_timers + # ifdef __use_timers _ttoc = _time.now() ; - - _tcpu._zips_full += + + _tcpu._zips_full += _tcpu.time_span(_ttic, _ttoc); # endif//__use_timers - + /*------------------------------ dump optim. progress */ + if (_opts.verb() >= 0) + { std::stringstream _sstr ; _sstr << std::setw(11) << _nmov << std::setw(13) << _nflp @@ -1821,49 +1976,50 @@ << std::setw(13) << _ndiv << "\n" ; _dump.push(_sstr.str()) ; - + } + /*------------------------------ has iter. converged? */ - if (_nset.count() == 0) break ; + if (_nset.count() == 0) break ; if (_nmov == +0 && _nzip == +0 && _ndiv == +0 && _nflp == +0 ) break ; } - + if (_opts.verb() >= +2) { /*------------------------------ print method metrics */ _dump.push("\n"); - + _dump.push(" MOVE-FULL: "); _dump.push( std::to_string(_tcpu._move_full)) ; _dump.push("\n"); - + _dump.push(" TOPO-FULL: "); _dump.push( std::to_string(_tcpu._topo_full)) ; _dump.push("\n"); - + _dump.push(" ZIPS-FULL: "); _dump.push( std::to_string(_tcpu._zips_full)) ; _dump.push("\n"); - + _dump.push("\n"); } else { _dump.push("\n"); - } + } } - + } ; - - + + } - + # endif //__ITER_MESH_2__ - - - + + + diff --git a/src/libcpp/iter_mesh/iter_mesh_3.hpp b/src/libcpp/iter_mesh/iter_mesh_3.hpp index 08bc64c..b8951e5 100644 --- a/src/libcpp/iter_mesh/iter_mesh_3.hpp +++ b/src/libcpp/iter_mesh/iter_mesh_3.hpp @@ -4,29 +4,29 @@ * ITER-MESH-3: mesh-optimisation for 3-complexes. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- @@ -47,7 +47,7 @@ # define __ITER_MESH_3__ namespace mesh { - + /* -------------------------------------------------------- * ITER-MESH-3: hill-climbing surf. iter. @@ -62,42 +62,42 @@ > class iter_mesh_3 { - public : + public : typedef M mesh_type ; typedef G geom_type ; typedef H size_type ; typedef P pred_type ; - typedef typename + typedef typename mesh_type::real_type real_type ; - typedef typename + typedef typename mesh_type::iptr_type iptr_type ; - - iptr_type static + + iptr_type static constexpr _dims = pred_type::_dims ; - + typedef mesh::iter_params < real_type , iptr_type > iter_opts ; - + typedef mesh::iter_timers < real_type , iptr_type > iter_stat ; - + typedef containers - ::array< iptr_type > iptr_list ; + ::array< iptr_type > iptr_list ; typedef containers ::array< real_type > real_list ; - + public : - - - + + + } ; - + } - + # endif //__ITER_MESH_3__ - - - + + + diff --git a/src/libcpp/iter_mesh/iter_mesh_euclidean_2.hpp b/src/libcpp/iter_mesh/iter_mesh_euclidean_2.hpp index 5c372ec..4148e99 100644 --- a/src/libcpp/iter_mesh/iter_mesh_euclidean_2.hpp +++ b/src/libcpp/iter_mesh/iter_mesh_euclidean_2.hpp @@ -4,29 +4,29 @@ * ITER-MESH-EUCLIDEAN-2: mesh obj. for ITER-MESH-2. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- @@ -55,35 +55,35 @@ class iter_mesh_euclidean_2d { public : - + /*-------------------- euclidean mesh for ITER-MESH-2 */ - + typedef R real_type ; typedef I iptr_type ; - - typedef mesh::tria_complex_edge_2 < + + typedef mesh::mesh_complex_edge_2 < iptr_type > edge_base ; - - typedef mesh::tria_complex_tria_3 < + + typedef mesh::mesh_complex_tria_3 < iptr_type > tria_base ; - - typedef mesh::tria_complex_node_3 < - iptr_type , + + typedef mesh::mesh_complex_node_3 < + iptr_type , real_type > node_base ; - + class node_type : public node_base { /*------------------------- node type for ITER-MESH-2 */ public : - + iptr_type _hidx ; iptr_type _itag ; - + char_type _fdim ; char_type _feat ; - + public : - + __inline_call iptr_type & hidx ( ) { return this->_hidx ; @@ -103,7 +103,7 @@ __inline_call char_type & fdim ( ) { return this->_fdim ; - } + } __inline_call char_type const& fdim ( ) const { return this->_fdim ; @@ -111,22 +111,22 @@ __inline_call char_type & feat ( ) { return this->_feat ; - } + } __inline_call char_type const& feat ( ) const { return this->_feat ; } } ; - + class edge_type : public edge_base { /*------------------------- edge type for ITER-MESH-2 */ public : - + iptr_type _itag ; - + public : - + __inline_call iptr_type & itag ( ) { return this->_itag ; @@ -136,16 +136,16 @@ { return this->_itag ; } } ; - + class tria_type : public tria_base { /*------------------------- tria type for ITER-MESH-2 */ public : - + iptr_type _itag ; - + public : - + __inline_call iptr_type & itag ( ) { return this->_itag ; @@ -155,21 +155,21 @@ { return this->_itag ; } } ; - + typedef mesh::tria_complex_2 < node_type , edge_type , tria_type > mesh_type ; - + public : - + mesh_type _mesh ; - + } ; - + } - + # endif //__ITER_MESH_EUCLIDEAN_2__ diff --git a/src/libcpp/iter_mesh/iter_mesh_euclidean_3.hpp b/src/libcpp/iter_mesh/iter_mesh_euclidean_3.hpp index 4426200..c3dc972 100644 --- a/src/libcpp/iter_mesh/iter_mesh_euclidean_3.hpp +++ b/src/libcpp/iter_mesh/iter_mesh_euclidean_3.hpp @@ -4,29 +4,29 @@ * ITER-MESH-EUCLIDEAN-3: mesh obj. for ITER-MESH-3. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- @@ -55,38 +55,38 @@ template < class iter_mesh_euclidean_3d { public : - + /*-------------------- euclidean mesh for ITER-MESH-3 */ - + typedef R real_type ; typedef I iptr_type ; - - typedef mesh::tria_complex_edge_2 < + + typedef mesh::mesh_complex_edge_2 < iptr_type > edge_base ; - - typedef mesh::tria_complex_tria_3 < + + typedef mesh::mesh_complex_tria_3 < iptr_type > face_base ; - - typedef mesh::tria_complex_tria_4 < + + typedef mesh::mesh_complex_tria_4 < iptr_type > tria_base ; - - typedef mesh::tria_complex_node_4 < - iptr_type , + + typedef mesh::mesh_complex_node_4 < + iptr_type , real_type > node_base ; - + class node_type : public node_base { /*------------------------- node type for ITER-MESH-3 */ public : - + iptr_type _hidx ; iptr_type _itag ; - + char_type _fdim ; char_type _feat ; - + public : - + __inline_call iptr_type & hidx ( ) { return this->_hidx ; @@ -106,7 +106,7 @@ template < __inline_call char_type & fdim ( ) { return this->_fdim ; - } + } __inline_call char_type const& fdim ( ) const { return this->_fdim ; @@ -114,22 +114,22 @@ template < __inline_call char_type & feat ( ) { return this->_feat ; - } + } __inline_call char_type const& feat ( ) const { return this->_feat ; } } ; - + class edge_type : public edge_base { - /*------------------------- edge type for ITER-MESH-2 */ + /*------------------------- edge type for ITER-MESH-3 */ public : - + iptr_type _itag ; - + public : - + __inline_call iptr_type & itag ( ) { return this->_itag ; @@ -139,16 +139,16 @@ template < { return this->_itag ; } } ; - + class face_type : public face_base { - /*------------------------- face type for ITER-MESH-2 */ + /*------------------------- face type for ITER-MESH-3 */ public : - + iptr_type _itag ; - + public : - + __inline_call iptr_type & itag ( ) { return this->_itag ; @@ -158,16 +158,16 @@ template < { return this->_itag ; } } ; - + class tria_type : public tria_base { - /*------------------------- tria type for ITER-MESH-2 */ + /*------------------------- tria type for ITER-MESH-3 */ public : - + iptr_type _itag ; - + public : - + __inline_call iptr_type & itag ( ) { return this->_itag ; @@ -177,22 +177,22 @@ template < { return this->_itag ; } } ; - + typedef mesh::tria_complex_3 < node_type , edge_type , face_type , tria_type > mesh_type ; - + public : - + mesh_type _mesh ; - + } ; - - + + } - + # endif //__ITER_MESH_EUCLIDEAN_3__ diff --git a/src/libcpp/iter_mesh/iter_node_1.inc b/src/libcpp/iter_mesh/iter_node_1.inc index e14f8c1..a993f98 100644 --- a/src/libcpp/iter_mesh/iter_node_1.inc +++ b/src/libcpp/iter_mesh/iter_node_1.inc @@ -4,29 +4,29 @@ * ITER-NODE-1: optim. schemes to reposition nodes. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- @@ -40,16 +40,16 @@ * -------------------------------------------------------- */ - + // from iter_mesh_k.hpp - - + + /* -------------------------------------------------------- - * SPRG-MOVE: "spring"-based node movement vector. + * SPRG-MOVE: "spring"-based node movement vector. -------------------------------------------------------- */ - + template < typename node_iter > @@ -58,7 +58,7 @@ mesh_type &_mesh , size_type &_hfun , pred_type &_pred , - real_list &_hval , + real_list &_hval , iptr_list &_eset , node_iter _node , real_type *_line , @@ -68,43 +68,43 @@ real_type _move[_dims] = { (real_type) +0.0 } ; - _ladj = + _ladj = (real_type) +0.0 ; - - real_type _wval = + + real_type _wval = +std::numeric_limits::epsilon(); - real_type _wsum = + real_type _wsum = +std::numeric_limits::epsilon(); - + iptr_type _enum = (iptr_type)+0 ; real_type _smin = (real_type)-1. ; real_type _smax = (real_type)+1. ; - + for (auto _edge = _eset.head(), _eend = _eset.tend(); - _edge != _eend; + _edge != _eend; ++_edge, ++_enum ) - { - auto _eptr = + { + auto _eptr = _mesh._set2.head()+*_edge ; - + iptr_type _enod[2] ; _enod[0] = _eptr->node(0) == _node->node(0) ? _eptr->node(0) : _eptr->node(1) ; - + _enod[1] = _eptr->node(0) == _node->node(0) ? _eptr->node(1) : _eptr->node(0) ; - - auto _inod = + + auto _inod = _mesh._set1.head()+_enod[0] ; - auto _jnod = + auto _jnod = _mesh._set1.head()+_enod[1] ; - + real_type _ipos [_dims] ; real_type _jpos [_dims] ; real_type _evec [_dims] ; @@ -115,73 +115,73 @@ pval(_idim) ; _jpos[_idim] =_jnod-> pval(_idim) ; - + _evec[_idim] =_ipos[_idim] - _jpos[_idim] ; } - - real_type _elen = + + real_type _elen = std::sqrt(_pred.length_sq(_evec)); - - if (_hval[_enod[0]] + + if (_hval[_enod[0]] < (real_type)+0.) { - _hval[_enod[0]] = + _hval[_enod[0]] = _hfun.eval(_ipos, _inod->hidx()) ; - } - - if (_hval[_enod[1]] + } + + if (_hval[_enod[1]] < (real_type)+0.) { - _hval[_enod[1]] = + _hval[_enod[1]] = _hfun.eval(_jpos, _jnod->hidx()) ; } - + _ladj += _elen ; - real_type _hbar = + real_type _hbar = (real_type) +.5 * _hval[_enod[0]] + (real_type) +.5 * _hval[_enod[1]] ; - - real_type _scal = + + real_type _scal = (_hbar - _elen) / _elen ; - - _scal = std::max(_scal, + + _scal = std::max(_scal, _smin) ; - _scal = std::min(_scal, + _scal = std::min(_scal, _smax) ; - + //_wval = std::abs(_scal) ; //_wval = (real_type) +1. ; - _wval = + _wval = std::sqrt(std::abs(_scal)) ; - + _wsum += _wval ; - + for (auto _idim = _dims; _idim-- != +0; ) { - _proj[_idim] = - _ipos[_idim] + + _proj[_idim] = + _ipos[_idim] + _scal * _evec[_idim] ; - - _move[_idim]+= + + _move[_idim]+= _wval * _proj[_idim] ; } } - + if (_enum > +0) { for (auto _idim = _dims; _idim-- != +0; ) { - _line[_idim] = + _line[_idim] = _move[_idim] / _wsum - - _node->pval(_idim) ; + - _node->pval(_idim) ; } - + _ladj /= _enum ; } } - - - + + + diff --git a/src/libcpp/iter_mesh/iter_node_2.inc b/src/libcpp/iter_mesh/iter_node_2.inc index 0d51696..8917dbe 100644 --- a/src/libcpp/iter_mesh/iter_node_2.inc +++ b/src/libcpp/iter_mesh/iter_node_2.inc @@ -4,62 +4,66 @@ * ITER-NODE-2: optim. schemes to reposition nodes. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 23 November, 2018 + * Last updated: 27 October, 2019 * - * Copyright 2013-2018 + * Copyright 2013-2019 * Darren Engwirda * de2363@columbia.edu * https://github.com/dengwirda/ * -------------------------------------------------------- */ - + // from iter_mesh_k.hpp - + /* -------------------------------------------------------- - * _PVT-MOVE: point-wise voro. tessellation update. + * _ODT-MOVE: optimal delaunay tessellation update. -------------------------------------------------------- */ - + // Shift node to weighted mean of adj. dual vertex - // positions... Like ODT, but sans |t_i| terms? - - // xnew = xold + SUM(1.0/h_i * c_i) / SUM(1.0/h_i) - + // positions... + + // xnew <=== SUM( |t_i|_r * c_i ) / SUM( |t_i|_r ) + // + // with |t_i|_r = INT|i rho(x) dA + // + // ~ |t_i| / (h_i)^3 + template < typename node_iter > __static_call - __normal_call void_type _pvt_move_2 ( + __normal_call void_type _odt_move_2 ( mesh_type &_mesh , size_type &_hfun , pred_type &_pred , @@ -73,119 +77,154 @@ real_type _move[_dims] = { (real_type) +0.0 } ; - _ladj = + _ladj = (real_type) +0.0 ; - + __unreferenced (_pred) ; // for MSVC... - real_type _wval = + real_type _wsum = +std::numeric_limits::epsilon() ; - real_type _wsum = - +std::numeric_limits::epsilon() ; - + iptr_type _tnum = +0 ; - + for (auto _tria = _tset.head() , _tend = _tset.tend() ; - _tria != _tend ; + _tria != _tend ; ++_tria, ++_tnum ) - { - auto _tptr = + { + auto _tptr = _mesh._set3.head()+*_tria ; - + iptr_type _tnod[3] ; _tnod[ 0] = _tptr->node( 0) ; _tnod[ 1] = _tptr->node( 1) ; _tnod[ 2] = _tptr->node( 2) ; - - auto _inod = + + algorithms::isort( + &_tnod[0], &_tnod[3], + std::less()) ; + + auto _inod = _mesh._set1.head()+_tnod[0] ; - auto _jnod = + auto _jnod = _mesh._set1.head()+_tnod[1] ; - auto _knod = + auto _knod = _mesh._set1.head()+_tnod[2] ; - + real_type _ball [_dims + 1] ; - _pred.perp_ball (_ball , - &_inod->pval(0), - &_jnod->pval(0), - &_knod->pval(0), true) ; - + real_type _kpos [_dims + 1] ; + real_type _jpos [_dims + 1] ; + real_type _ipos [_dims + 1] ; + + _ipos[_dims] = + (real_type)+.75 * + _inod->pval (_dims) ; + _jpos[_dims] = + (real_type)+.75 * + _jnod->pval (_dims) ; + _kpos[_dims] = + (real_type)+.75 * + _knod->pval (_dims) ; + + for (auto _idim = _dims; _idim-- != +0; ) + { + _ipos[_idim] = + _inod->pval (_idim) ; + _jpos[_idim] = + _jnod->pval (_idim) ; + _kpos[_idim] = + _knod->pval (_idim) ; + } + + _pred.perp_ball (_ball , + &_ipos [+0] , + &_jpos [+0] , + &_kpos [+0] , true); + + real_type _tmag = + _pred.mass_tria ( + &_ipos [+0] , + &_jpos [+0] , + &_kpos [+0] ) ; + + _tmag = std::abs(_tmag); + if (_hval[_tnod[0]] < (real_type)+0.) { _hval[_tnod[0]] = _hfun.eval ( - &_inod->pval(0) , + &_inod->pval(0) , _inod->hidx()) ; - } - + } + if (_hval[_tnod[1]] < (real_type)+0.) { _hval[_tnod[1]] = _hfun.eval ( - &_jnod->pval(0) , + &_jnod->pval(0) , _jnod->hidx()) ; } - + if (_hval[_tnod[2]] < (real_type)+0.) { _hval[_tnod[2]] = _hfun.eval ( - &_knod->pval(0) , + &_knod->pval(0) , _knod->hidx()) ; } - + real_type _tsqr = std::max( (real_type) +0., _ball[_dims]); - - real_type _hbar = _hval[_tnod[0]] + - _hval[_tnod[1]] + - _hval[_tnod[2]] ; - _hbar /= (real_type) +3.0 ; - - _wval = (real_type) +1.0 / _hbar ; - + + real_type _irho = (real_type)+1. + / _hval[_tnod[0]] ; + real_type _jrho = (real_type)+1. + / _hval[_tnod[1]] ; + real_type _krho = (real_type)+1. + / _hval[_tnod[2]] ; + + real_type _rbar = + (_irho+_jrho+_krho) / (real_type)+3. ; + + real_type _wval = + _tmag * std::pow(_rbar, +3) ; + for (auto _idim = _dims; _idim-- != +0; ) { - _move[_idim] + _move[_idim] += _wval * _ball [_idim] ; } - + _wsum += _wval ; _ladj += _tsqr ; } - + if (_tnum > +0) { for (auto _idim = _dims; _idim-- != +0; ) { - _line[_idim] = + _line[_idim] = _move[_idim] / _wsum - _node->pval(_idim) ; } - + _ladj = std::sqrt(_ladj / _tnum) ; } - + } - + /* -------------------------------------------------------- - * _ODT-MOVE: optimal delaunay tessellation update. + * _CVT-MOVE: centroidal voronoi tessellation move. -------------------------------------------------------- */ - - // Shift node to weighted mean of adj. dual vertex - // positions... - - // xnew = xold + SUM(|t_i|_r * c_i) / SUM(|t_i|_r) - // - // where |t_i|_r = INT|i rho(x) dA - // - // ~ |t_i| / (h_i)^2 - + + // Shift vertex to weighted mean of adj. dual cell + + // xnew <=== INT|i rho(x) * x dA / INT|i rho(x) dA + template < typename node_iter > __static_call - __normal_call void_type _odt_move_2 ( + __normal_call void_type _cvt_move_2 ( mesh_type &_mesh , size_type &_hfun , pred_type &_pred , @@ -199,123 +238,206 @@ real_type _move[_dims] = { (real_type) +0.0 } ; - _ladj = + _ladj = (real_type) +0.0 ; - + __unreferenced (_pred) ; // for MSVC... - real_type _wsum = + real_type _wsum = +std::numeric_limits::epsilon() ; - + iptr_type _tnum = +0 ; - + for (auto _tria = _tset.head() , _tend = _tset.tend() ; - _tria != _tend ; + _tria != _tend ; ++_tria, ++_tnum ) - { - auto _tptr = + { + auto _tptr = _mesh._set3.head()+*_tria ; - + iptr_type _tnod[3] ; _tnod[ 0] = _tptr->node( 0) ; _tnod[ 1] = _tptr->node( 1) ; _tnod[ 2] = _tptr->node( 2) ; - - auto _inod = + + algorithms::isort( + &_tnod[0], &_tnod[3], + std::less()) ; + + auto _inod = _mesh._set1.head()+_tnod[0] ; - auto _jnod = + auto _jnod = _mesh._set1.head()+_tnod[1] ; - auto _knod = + auto _knod = _mesh._set1.head()+_tnod[2] ; - - real_type _ball [_dims + 1] ; - _pred.perp_ball (_ball , - &_inod->pval(0), - &_jnod->pval(0), - &_knod->pval(0), true) ; - - real_type _tmag = - _pred.mass_tria ( - &_inod->pval(0), - &_jnod->pval(0), - &_knod->pval(0) ) ; - + if (_hval[_tnod[0]] < (real_type)+0.) { _hval[_tnod[0]] = _hfun.eval ( - &_inod->pval(0) , + &_inod->pval(0) , _inod->hidx()) ; - } - + } + if (_hval[_tnod[1]] < (real_type)+0.) { _hval[_tnod[1]] = _hfun.eval ( - &_jnod->pval(0) , + &_jnod->pval(0) , _jnod->hidx()) ; } - + if (_hval[_tnod[2]] < (real_type)+0.) { _hval[_tnod[2]] = _hfun.eval ( - &_knod->pval(0) , + &_knod->pval(0) , _knod->hidx()) ; } - - real_type _tsqr = std::max( - (real_type) +0., _ball[_dims]); - - real_type _irho = (real_type)+1. + + real_type _irho = (real_type)+1. / _hval[_tnod[0]] ; - real_type _jrho = (real_type)+1. + real_type _jrho = (real_type)+1. / _hval[_tnod[1]] ; - real_type _krho = (real_type)+1. + real_type _krho = (real_type)+1. / _hval[_tnod[2]] ; - - _irho = _irho * _irho ; - _jrho = _jrho * _jrho ; - _krho = _krho * _krho ; - - real_type _rbar = - (_irho+_jrho+_krho) / (real_type)+3. ; - - real_type _wval = _tmag* _rbar ; - + + node_iter _anod, _bnod, _cnod; + real_type _arho, _brho, _crho; + + if (_inod == _node) + { + _anod = _inod; _arho = _irho; + _bnod = _jnod; _brho = _jrho; + _cnod = _knod; _crho = _krho; + } + else + if (_jnod == _node) + { + _anod = _jnod; _arho = _jrho; + _bnod = _knod; _brho = _krho; + _cnod = _inod; _crho = _irho; + } + else + // (_knod == _node) + { + _anod = _knod; _arho = _krho; + _bnod = _inod; _brho = _irho; + _cnod = _jnod; _crho = _jrho; + } + + real_type _cpos [_dims + 1] ; + real_type _bpos [_dims + 1] ; + real_type _apos [_dims + 1] ; + + _apos[_dims] = + (real_type)+.75 * + _anod->pval (_dims) ; + _bpos[_dims] = + (real_type)+.75 * + _bnod->pval (_dims) ; + _cpos[_dims] = + (real_type)+.75 * + _cnod->pval (_dims) ; + for (auto _idim = _dims; _idim-- != +0; ) { - _move[_idim] - += _wval * _ball [_idim] ; + _apos[_idim] = + _anod->pval (_idim) ; + _bpos[_idim] = + _bnod->pval (_idim) ; + _cpos[_idim] = + _cnod->pval (_idim) ; } - - _wsum += _wval ; - _ladj += _tsqr ; + + real_type _0bal [_dims + 1] ; + _pred.perp_ball (_0bal , + &_apos [+0] , + &_bpos [+0] , + &_cpos [+0] , true); + + real_type _1bal [_dims + 1] ; + real_type _2bal [_dims + 1] ; + _pred.perp_ball (_1bal , + &_apos [+0] , + &_bpos [+0] , true); + + _pred.perp_ball (_2bal , + &_apos [+0] , + &_cpos [+0] , true); + + real_type _1mag = + std::abs(_pred.mass_tria ( + &_apos [+0] , + &_1bal [+0] , + &_0bal [+0] ) ) ; + + real_type _2mag = + std::abs(_pred.mass_tria ( + &_apos [+0] , + &_0bal [+0] , + &_2bal [+0] ) ) ; + + real_type _0rho = + (_arho+_brho+_crho) / (real_type)+3. ; + + real_type _1rho = + (_arho+_brho) / (real_type)+2. ; + real_type _2rho = + (_arho+_crho) / (real_type)+2. ; + + _0rho = std::pow(_0rho, +3) ; + _1rho = std::pow(_1rho, +3) ; + _2rho = std::pow(_2rho, +3) ; + _arho = std::pow(_arho, +3) ; + + real_type _tsqr = std::max( + (real_type)+0., _0bal[_dims]) ; + + + for (auto _idim = _dims; _idim-- != +0; ) + { + _move[_idim] += + // 1st sub-tria in voro. cell + _1mag*_0rho * _0bal[_idim] + + _1mag*_1rho * _1bal[_idim] + + _1mag*_arho * _apos[_idim] + + + // 2nd sub-tria in voro. cell + _2mag*_0rho * _0bal[_idim] + + _2mag*_2rho * _2bal[_idim] + + _2mag*_arho * _apos[_idim] ; + } + + _wsum += _1mag*(_0rho+_1rho+_arho) ; + _wsum += _2mag*(_0rho+_2rho+_arho) ; + + _ladj += _tsqr ; } - + if (_tnum > +0) { for (auto _idim = _dims; _idim-- != +0; ) { - _line[_idim] = + _line[_idim] = _move[_idim] / _wsum - _node->pval(_idim) ; } - + _ladj = std::sqrt(_ladj / _tnum) ; } - + } - + /* -------------------------------------------------------- - * GRAD-MOVE: "local-ascent" node movement vector. + * DQDX-MOVE: "local-ascent" node movement vector. -------------------------------------------------------- */ - + template < typename node_iter > __static_call - __normal_call void_type grad_move_2 ( + __normal_call void_type dqdx_move_2 ( mesh_type &_mesh , size_type &_hfun , pred_type &_pred , @@ -326,26 +448,26 @@ real_type &_ladj ) { - real_type static const _HINC = + real_type static const _HINC = std::pow(std::numeric_limits ::epsilon(), +.50) ; - - real_type static const _RMIN = + + real_type static const _RMIN = std::pow(std::numeric_limits ::epsilon(), +.75) ; - - real_type static const _RMAX = + + real_type static const _RMAX = std::pow(std::numeric_limits ::epsilon(), +.25) ; - + __unreferenced(_hfun); __unreferenced(_pred); // for MSVC... - + /*------------------ calc. local characteristic scale */ real_type _qmin = +std::numeric_limits ::infinity(); - + real_type _bmin[_dims] = { +std::numeric_limits ::infinity() @@ -354,72 +476,81 @@ -std::numeric_limits ::infinity() } ; - + iptr_type _tnum = +0 ; - + _ladj = (real_type)0.; - + real_type _dqdx[_dims] = { (real_type) +0.0 } ; - + real_type _save [_dims] ; for (auto _idim = _dims; _idim-- != +0; ) { - _save[_idim] = + _save[_idim] = _node->pval(_idim) ; } - + for (auto _tria = _tset.head(), _tend = _tset.tend(); _tria != _tend; ++_tria, ++_tnum) - { - auto _tptr = + { + auto _tptr = _mesh._set3.head()+*_tria ; - - auto _inod = _mesh. - _set1 .head()+_tptr->node(0) ; - auto _jnod = _mesh. - _set1 .head()+_tptr->node(1) ; - auto _knod = _mesh. - _set1 .head()+_tptr->node(2) ; - + + iptr_type _tnod[3] ; + _tnod[ 0] = _tptr->node( 0) ; + _tnod[ 1] = _tptr->node( 1) ; + _tnod[ 2] = _tptr->node( 2) ; + + algorithms::isort( + &_tnod[0], &_tnod[3], + std::less()) ; + + auto _inod = + _mesh._set1.head()+_tnod[0] ; + auto _jnod = + _mesh._set1.head()+_tnod[1] ; + auto _knod = + _mesh._set1.head()+_tnod[2] ; + _qmin = std::min( _qmin, _cost[_tnum]) ; - + real_type _pmid[_dims] = { (real_type) +0.0 } ; - + for (auto _idim = _dims; _idim-- != +0; ) { - _pmid[_idim] += + _pmid[_idim] += _inod->pval(_idim) ; - _pmid[_idim] += + _pmid[_idim] += _jnod->pval(_idim) ; - _pmid[_idim] += + _pmid[_idim] += _knod->pval(_idim) ; } for (auto _idim = _dims; _idim-- != +0; ) { - _pmid[_idim] + _pmid[_idim] /= (real_type) +3. ; } - + for (auto _idim = _dims; _idim-- != +0; ) { _bmin[_idim] = std::min( - _bmin[_idim], + _bmin[_idim], _pmid[_idim]) ; - + _bmax[_idim] = std::max( - _bmax[_idim], + _bmax[_idim], _pmid[_idim]) ; } - - real_type _lsqr = + + real_type _lsqr = _pred.length_sq ( _pmid, &_node->pval(0)) ; - + _ladj += _lsqr ; } @@ -429,54 +560,54 @@ real_type _qbar , _qlow ; _qbar = (real_type) +1. ; _qlow = (real_type) +0. ; - - iptr_type _lnum = +0 ; - iptr_type _hnum = +1 ; - - real_type _qlim = _qmin + - (real_type) +1.0E-003 ; + + iptr_type _lnum = +0 ; + iptr_type _hnum = +1 ; + + real_type _qlim = _qmin + + (real_type) +1.0E-002 ; _tnum = (iptr_type) +0 ; for (auto _tria = _tset.head() , _tend = _tset.tend() ; _tria != _tend; ++_tria, ++_tnum) - { - auto _tptr = + { + auto _tptr = _mesh._set3.head()+*_tria ; - + real_type _qtri = _cost[_tnum]; - + /*-------------- only do gradients for 'poor' set */ if (_qtri <= _qlim) { - for (auto _idim = _dims ; + for (auto _idim = _dims ; _idim-- != 0; ) { - /*---------- local iter. on finite-diff. step */ + /*---------- local iter. on finite-diff. step */ real_type _binc = _bmax[_idim] - _bmin[_idim] ; - + real_type _hdel = _HINC*_binc; - + real_type _hsum = (real_type)0.; - + real_type _sdel = (real_type)0.; real_type _sabs = (real_type)0.; real_type _sbar = (real_type)0.; - - for (auto _iter = +0; _iter++ != +8; ) + + for (auto _iter = +0; _iter++ != +2; ) { - + /*------ centred finite-diff. for dQ / dw */ - _node->pval(_idim) = + _node->pval(_idim) = _save[_idim] + _hdel; - + _hsum = (real_type)0. ; _hsum += _node-> pval(_idim) - _save[_idim] ; - real_type _scr1 = + real_type _scr1 = _pred .cost_tria ( &_mesh._set1[ _tptr->node(0)].pval(0), @@ -485,14 +616,14 @@ &_mesh._set1[ _tptr->node(2)].pval(0) ) ; - - _node->pval(_idim) = + + _node->pval(_idim) = _save[_idim] - _hdel; _hsum -= _node-> pval(_idim) - _save[_idim] ; - real_type _scr0 = + real_type _scr0 = _pred .cost_tria ( &_mesh._set1[ _tptr->node(0)].pval(0), @@ -501,99 +632,95 @@ &_mesh._set1[ _tptr->node(2)].pval(0) ) ; - - _sbar = std::max( - std::abs(_scr1), - std::abs(_scr0)); - - _sdel =_scr1-_scr0 ; - + + _sbar = _cost[_tnum]; + + _sdel = _scr1-_scr0 ; + + _sbar = std::abs(_sbar) ; _sabs = std::abs(_sdel) ; - - _node->pval(_idim) + + _node->pval(_idim) = _save[_idim] ; - + /*------ try to adjust step on rel. diff. */ if (_sabs > (real_type)0.) - { + { if (_sabs > _RMAX * _sbar) { - _hdel *= + _hdel *= (real_type) +.10 ; - } + } else if (_sabs < _RMIN * _sbar) { - _hdel *= + _hdel *= (real_type) +10. ; } else { break ; } } else { break ; } } - + /*---------- finalise gradient and accumulate */ _dqdx[_idim]+= _sdel / _hsum ; - + } - + _qlow += _qtri ; _lnum += +1 ; - } else { /*---------- accumulate metrics in 'good' set */ - _qbar += _qtri ; _hnum += +1 ; + _qbar += _qtri ; _hnum += +1 ; } } - - if (_lnum > +0) + + if (_lnum > +0) { for (auto _idim = _dims; _idim-- != +0; ) { _dqdx[_idim] /= _lnum ; } - - _qlow /= _lnum ; - } - if (_hnum > +0) - { + _qlow /= _lnum ; _qbar /= _hnum ; } - + /*------------------ 1st ord. Taylor-series step est. */ - real_type _scal = + real_type _scal = std::sqrt(_pred.length_sq(_dqdx)) ; - - if (_scal == (real_type) +0. ) + + if (_scal*_ladj <= _HINC) { for (auto _idim = _dims; _idim-- != +0; ) { - _line[_idim] + _line[_idim] = (real_type) +0. ; } } else - { + { for (auto _idim = _dims; _idim-- != +0; ) { - _line[_idim] = + _line[_idim] = _dqdx[_idim] / _scal ; } - + _scal = (_qbar - _qlow) / _pred .innerprod(_line, _dqdx) ; - + + _scal*= (real_type)+.50 ; + _scal = std::min(_scal, _ladj) ; - + for (auto _idim = _dims; _idim-- != +0; ) { _line[_idim] *= _scal ; } } - + } - - - + + + diff --git a/src/libcpp/iter_mesh/iter_node_3.inc b/src/libcpp/iter_mesh/iter_node_3.inc index cfb3e3f..ca9a08b 100644 --- a/src/libcpp/iter_mesh/iter_node_3.inc +++ b/src/libcpp/iter_mesh/iter_node_3.inc @@ -4,29 +4,29 @@ * ITER-NODE-3: optim. schemes to reposition nodes. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- @@ -40,25 +40,25 @@ * -------------------------------------------------------- */ - + // from iter_mesh_k.hpp - + /* -------------------------------------------------------- * _ODT-MOVE: optimal delaunay tessellation update. -------------------------------------------------------- */ - + // Shift node to weighted mean of adj. dual vertex // positions... - + // xnew = xold + SUM(|t_i|_r * c_i) / SUM(|t_i|_r) // // where |t_i|_r = INT|i rho(x) dA // // ~ |t_i| / (h_i)^2 - + template < typename node_iter > @@ -77,133 +77,133 @@ real_type _move[_dims] = { (real_type) +0.0 } ; - _ladj = + _ladj = (real_type) +0.0 ; - + __unreferenced (_pred) ; // for MSVC... - real_type _wsum = + real_type _wsum = +std::numeric_limits::epsilon() ; - + iptr_type _tnum = +0 ; - + for (auto _tria = _tset.head() , _tend = _tset.tend() ; - _tria != _tend ; + _tria != _tend ; ++_tria, ++_tnum ) - { - auto _tptr = + { + auto _tptr = _mesh._set4.head()+*_tria ; - + iptr_type _tnod[4] ; _tnod[ 0] = _tptr->node( 0) ; _tnod[ 1] = _tptr->node( 1) ; _tnod[ 2] = _tptr->node( 2) ; _tnod[ 3] = _tptr->node( 3) ; - - auto _inod = + + auto _inod = _mesh._set1.head()+_tnod[0] ; - auto _jnod = + auto _jnod = _mesh._set1.head()+_tnod[1] ; - auto _knod = + auto _knod = _mesh._set1.head()+_tnod[2] ; - auto _lnod = + auto _lnod = _mesh._set1.head()+_tnod[3] ; - + real_type _ball [_dims + 1] ; - _pred.perp_ball (_ball , + _pred.perp_ball (_ball , &_inod->pval(0), &_jnod->pval(0), - &_knod->pval(0), + &_knod->pval(0), &_lnod->pval(0), true) ; - - real_type _tmag = + + real_type _tmag = _pred.mass_tria ( &_inod->pval(0), &_jnod->pval(0), &_knod->pval(0) &_lnod->pval(0) ) ; - + if (_hval[_tnod[0]] < (real_type)+0.) { _hval[_tnod[0]] = _hfun.eval ( - &_inod->pval(0) , + &_inod->pval(0) , _inod->hidx()) ; - } - + } + if (_hval[_tnod[1]] < (real_type)+0.) { _hval[_tnod[1]] = _hfun.eval ( - &_jnod->pval(0) , + &_jnod->pval(0) , _jnod->hidx()) ; } - + if (_hval[_tnod[2]] < (real_type)+0.) { _hval[_tnod[2]] = _hfun.eval ( - &_knod->pval(0) , + &_knod->pval(0) , _knod->hidx()) ; } - + if (_hval[_tnod[3]] < (real_type)+0.) { _hval[_tnod[3]] = _hfun.eval ( - &_knod->pval(0) , + &_knod->pval(0) , _knod->hidx()) ; } - + real_type _tsqr = std::max( (real_type) +0., _ball[_dims]); - - real_type _irho = (real_type)+1. + + real_type _irho = (real_type)+1. / _hval[_tnod[0]] ; - real_type _jrho = (real_type)+1. + real_type _jrho = (real_type)+1. / _hval[_tnod[1]] ; - real_type _krho = (real_type)+1. + real_type _krho = (real_type)+1. / _hval[_tnod[2]] ; - real_type _lrho = (real_type)+1. + real_type _lrho = (real_type)+1. / _hval[_tnod[3]] ; - + _irho = _irho * _irho ; _jrho = _jrho * _jrho ; _krho = _krho * _krho ; _lrho = _lrho * _lrho ; - - real_type _rbar = + + real_type _rbar = (_irho+_jrho+_krho+_lrho) / (real_type)4. ; - + real_type _wval = _tmag* _rbar ; - + for (auto _idim = _dims; _idim-- != +0; ) { - _move[_idim] + _move[_idim] += _wval * _ball [_idim] ; } - + _wsum += _wval ; _ladj += _tsqr ; } - + if (_tnum > +0) { for (auto _idim = _dims; _idim-- != +0; ) { - _line[_idim] = + _line[_idim] = _move[_idim] / _wsum - _node->pval(_idim) ; } - + _ladj = std::sqrt(_ladj / _tnum) ; } - + } - + /* -------------------------------------------------------- - * GRAD-MOVE: "local-ascent" node movement vector. + * GRAD-MOVE: "local-ascent" node movement vector. -------------------------------------------------------- */ - + template < typename node_iter > @@ -219,33 +219,33 @@ real_type &_ladj ) { - real_type static const _ZERO = + real_type static const _ZERO = std::pow(std::numeric_limits ::epsilon(), +.80) ; - - real_type static const _HINC = + + real_type static const _HINC = std::pow(std::numeric_limits ::epsilon(), +.50) ; - - real_type static const _RMIN = + + real_type static const _RMIN = std::pow(std::numeric_limits ::epsilon(), +.75) ; - - real_type static const _RMAX = + + real_type static const _RMAX = std::pow(std::numeric_limits ::epsilon(), +.25) ; - + real_type _qmin = +std::numeric_limits ::infinity() ; - + __unreferenced(_hfun); __unreferenced(_pred); // for MSVC... iptr_type _tnum = +0 ; - + _ladj = (real_type)0.; - + real_type _bmin[_dims] = { +std::numeric_limits ::infinity() @@ -254,25 +254,25 @@ -std::numeric_limits ::infinity() } ; - + real_type _dqdx[_dims] = { (real_type) +0.0 } ; - + real_type _save [_dims] ; for (auto _idim = _dims; _idim-- != +0; ) { - _save[_idim] = + _save[_idim] = _node->pval(_idim) ; } - + for (auto _tria = _tset.head(), _tend = _tset.tend(); _tria != _tend; ++_tria, ++_tnum) - { - auto _tptr = + { + auto _tptr = _mesh._set4.head()+*_tria ; - + auto _inod = _mesh. _set1 .head()+_tptr->node(0) ; auto _jnod = _mesh. @@ -281,56 +281,56 @@ _set1 .head()+_tptr->node(2) ; auto _lnod = _mesh. _set1 .head()+_tptr->node(3) ; - + _qmin = std::min( _qmin, _cost[_tnum]) ; - + real_type _pmid[_dims] = { (real_type) +0.0 } ; - + for (auto _idim = _dims; _idim-- != +0; ) { - _pmid[_idim] += + _pmid[_idim] += _inod->pval(_idim) ; - _pmid[_idim] += + _pmid[_idim] += _jnod->pval(_idim) ; - _pmid[_idim] += + _pmid[_idim] += _knod->pval(_idim) ; - _pmid[_idim] += + _pmid[_idim] += _lnod->pval(_idim) ; } for (auto _idim = _dims; _idim-- != +0; ) { - _pmid[_idim] + _pmid[_idim] /= (real_type) +4. ; } - + for (auto _idim = _dims; _idim-- != +0; ) { _bmin[_idim] = std::min( - _bmin[_idim], + _bmin[_idim], _pmid[_idim]) ; - + _bmax[_idim] = std::max( - _bmax[_idim], + _bmax[_idim], _pmid[_idim]) ; } - - real_type _llen = + + real_type _llen = std::sqrt(_pred.length_sq ( _pmid, &_node->pval(0))) ; - + _ladj += _llen ; } real_type _qbar , _qlow ; _qbar = (real_type) +1. ; _qlow = (real_type) +0. ; - + iptr_type _lnum = +0 ; iptr_type _hnum = +1 ; - - real_type _qlim = _qmin + + + real_type _qlim = _qmin + (real_type) +1.0E-004 ; _tnum = (iptr_type) +0 ; @@ -338,38 +338,38 @@ _tend = _tset.tend() ; _tria != _tend; ++_tria, ++_tnum) - { - auto _tptr = + { + auto _tptr = _mesh._set4.head()+*_tria ; - + real_type _qtri = _cost[_tnum]; - + if (_qtri <= _qlim) { - for (auto _idim = _dims ; + for (auto _idim = _dims ; _idim-- != 0; ) - { + { real_type _binc = _bmax[_idim] - _bmin[_idim] ; - + real_type _hdel = _HINC*_binc; - + real_type _hsum = (real_type)0.; - + real_type _sdel = (real_type)0.; real_type _sabs = (real_type)0.; real_type _sbar = (real_type)0.; - + for (auto _iter = +0; _iter++ != +8; ) { - _node->pval(_idim) = + _node->pval(_idim) = _save[_idim] + _hdel; - + _hsum = (real_type)0. ; _hsum += _node-> pval(_idim) - _save[_idim] ; - real_type _scr1 = + real_type _scr1 = _pred .cost_tria ( &_mesh._set1[ _tptr->node(0)].pval(0), @@ -380,14 +380,14 @@ &_mesh._set1[ _tptr->node(3)].pval(0) ) ; - - _node->pval(_idim) = + + _node->pval(_idim) = _save[_idim] - _hdel; _hsum -= _node-> pval(_idim) - _save[_idim] ; - real_type _scr0 = + real_type _scr0 = _pred .cost_tria ( &_mesh._set1[ _tptr->node(0)].pval(0), @@ -398,56 +398,56 @@ &_mesh._set1[ _tptr->node(3)].pval(0) ) ; - + _sdel = _scr1 - _scr0 ; - _sabs = + _sabs = std::abs(_sdel); - + _sbar = std::max( std::abs(_scr1), std::abs(_scr0)) ; - - _node->pval(_idim) + + _node->pval(_idim) = _save[_idim] ; - + if (_sabs > (real_type)0.) - { + { if (_sabs > _RMAX * _sbar) { - _hdel *= + _hdel *= (real_type) +.10 ; - } + } else if (_sabs < _RMIN * _sbar) { - _hdel *= + _hdel *= (real_type) +10. ; } else { break ; } } else { break ; } } - + _dqdx[_idim]+= _sdel / _hsum ; - + } - + _qlow += _qtri ; _lnum += +1 ; - + } else { - _qbar += _qtri ; _hnum += +1 ; + _qbar += _qtri ; _hnum += +1 ; } } - - if (_tnum > +0) + + if (_tnum > +0) { for (auto _idim = _dims; _idim-- != +0; ) { _dqdx[_idim] /= _lnum ; } - + _qlow /= _lnum ; _ladj /= _tnum ; } @@ -456,38 +456,38 @@ { _qbar /= _hnum ; } - - real_type _scal = + + real_type _scal = std::sqrt(_pred.length_sq(_dqdx)) ; - + if (_scal <= _ZERO * _ladj) { for (auto _idim = _dims; _idim-- != +0; ) { - _line[_idim] + _line[_idim] = (real_type) +0. ; } } else - { + { for (auto _idim = _dims; _idim-- != +0; ) { - _line[_idim] = + _line[_idim] = _dqdx[_idim] / _scal ; } - + _scal = (_qbar - _qlow) / _pred .length_sq(_line, _dqdx) ; - + _scal = std::min(_scal, _ladj) ; - + for (auto _idim = _dims; _idim-- != +0; ) { _line[_idim] *= _scal ; } } - + } - - - + + + diff --git a/src/libcpp/iter_mesh/iter_pred_ellipsoid_3.hpp b/src/libcpp/iter_mesh/iter_pred_ellipsoid_3.hpp index c2b6af1..3e1fee3 100644 --- a/src/libcpp/iter_mesh/iter_pred_ellipsoid_3.hpp +++ b/src/libcpp/iter_mesh/iter_pred_ellipsoid_3.hpp @@ -4,29 +4,29 @@ * ITER-PRED-ELLIPSOID-3: predicates for MESH-ITER-2. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- @@ -50,8 +50,8 @@ //_pred.vnrm(); //_pred.vcos(); - - + + template < typename R , typename I @@ -59,14 +59,14 @@ class iter_pred_ellipsoid_3d { public : - + typedef R real_type ; typedef I iptr_type ; - - iptr_type static constexpr _dims = +3 ; - + + iptr_type static constexpr _dims = +3 ; + public : - + __static_call __inline_call real_type mass_tria ( __const_ptr(real_type) _ipos , @@ -77,7 +77,19 @@ ::tria_area_3d ( _ipos, _jpos, _kpos) ; } - + + __static_call + __inline_call void_type circ_ball ( + __write_ptr(real_type) _ball , + __const_ptr(real_type) _ipos , + __const_ptr(real_type) _jpos , + bool_type _bind = false + ) + { return geometry + ::circ_ball_3d ( + _ball, _ipos, _jpos, _bind) ; + } + __static_call __inline_call void_type circ_ball ( __write_ptr(real_type) _ball , @@ -90,7 +102,19 @@ ::circ_ball_3d ( _ball, _ipos, _jpos, _kpos, _bind) ; } - + + __static_call + __inline_call void_type perp_ball ( + __write_ptr(real_type) _ball , + __const_ptr(real_type) _ipos , + __const_ptr(real_type) _jpos , + bool_type _bind = false + ) + { return geometry + ::perp_ball_3d ( + _ball, _ipos, _jpos, _bind) ; + } + __static_call __inline_call void_type perp_ball ( __write_ptr(real_type) _ball , @@ -103,7 +127,7 @@ ::perp_ball_3d ( _ball, _ipos, _jpos, _kpos, _bind) ; } - + __static_call __inline_call real_type cost_tria ( __const_ptr(real_type) _ipos , @@ -114,7 +138,7 @@ ::tria_quality_3d ( _ipos, _jpos, _kpos) ; } - + __static_call __inline_call real_type cost_dual ( __const_ptr(real_type) _ipos , @@ -125,7 +149,7 @@ ::dual_quality_3d ( _ipos, _jpos, _kpos) ; } - + __static_call __inline_call real_type innerprod ( __const_ptr(real_type) _avec , @@ -134,7 +158,7 @@ { return geometry ::dot_3d (_avec, _bvec) ; } - + __static_call __inline_call real_type length_sq ( __const_ptr(real_type) _ipos , @@ -143,15 +167,15 @@ { return geometry:: lensqr_3d(_ipos, _jpos) ; } - + __static_call __inline_call real_type length_sq ( __const_ptr(real_type) _vvec ) - { return + { return geometry::lensqr_3d (_vvec) ; } - + template < typename geom_type > @@ -163,12 +187,12 @@ ) { __unreferenced(_save); - + real_type _zero[3] ; _zero[0] = (real_type) +.0 ; _zero[1] = (real_type) +.0 ; _zero[2] = (real_type) +.0 ; - + real_type _ttaa, _ttbb ; if (_geom.line_surf( _zero, _proj, _ttaa, _ttbb) ) @@ -189,29 +213,29 @@ _proj[2] * (real_type) +.5 - _zero[2] * (real_type) +.5 } ; - + if (_ttaa > (real_type)-1.) { - _proj[0] = + _proj[0] = _pmid[0] + _ttaa*_pdel[0] ; - _proj[1] = + _proj[1] = _pmid[1] + _ttaa*_pdel[1] ; - _proj[2] = + _proj[2] = _pmid[2] + _ttaa*_pdel[2] ; } else if (_ttbb > (real_type)-1.) { - _proj[0] = + _proj[0] = _pmid[0] + _ttbb*_pdel[0] ; - _proj[1] = + _proj[1] = _pmid[1] + _ttbb*_pdel[1] ; - _proj[2] = + _proj[2] = _pmid[2] + _ttbb*_pdel[2] ; } } } - + } ; diff --git a/src/libcpp/iter_mesh/iter_pred_euclidean_2.hpp b/src/libcpp/iter_mesh/iter_pred_euclidean_2.hpp index 1062172..3a0a2eb 100644 --- a/src/libcpp/iter_mesh/iter_pred_euclidean_2.hpp +++ b/src/libcpp/iter_mesh/iter_pred_euclidean_2.hpp @@ -4,29 +4,29 @@ * ITER-PRED-EUCLIDEAN-2: predicates for MESH-ITER-2. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- @@ -50,8 +50,8 @@ //_pred.vnrm(); //_pred.vcos(); - - + + template < typename R , typename I @@ -61,11 +61,11 @@ public : typedef R real_type ; typedef I iptr_type ; - - iptr_type static constexpr _dims = +2 ; - + + iptr_type static constexpr _dims = +2 ; + public : - + __static_call __inline_call real_type mass_tria ( __const_ptr(real_type) _ipos , @@ -76,7 +76,19 @@ ::tria_area_2d ( _ipos, _jpos, _kpos) ; } - + + __static_call + __inline_call void_type circ_ball ( + __write_ptr(real_type) _ball , + __const_ptr(real_type) _ipos , + __const_ptr(real_type) _jpos , + bool_type _bind = false + ) + { return geometry + ::circ_ball_2d ( + _ball, _ipos, _jpos, _bind) ; + } + __static_call __inline_call void_type circ_ball ( __write_ptr(real_type) _ball , @@ -89,7 +101,19 @@ ::circ_ball_2d ( _ball, _ipos, _jpos, _kpos, _bind) ; } - + + __static_call + __inline_call void_type perp_ball ( + __write_ptr(real_type) _ball , + __const_ptr(real_type) _ipos , + __const_ptr(real_type) _jpos , + bool_type _bind = false + ) + { return geometry + ::perp_ball_2d ( + _ball, _ipos, _jpos, _bind) ; + } + __static_call __inline_call void_type perp_ball ( __write_ptr(real_type) _ball , @@ -102,7 +126,7 @@ ::perp_ball_2d ( _ball, _ipos, _jpos, _kpos, _bind) ; } - + __static_call __inline_call real_type cost_tria ( __const_ptr(real_type) _ipos , @@ -113,7 +137,7 @@ ::tria_quality_2d ( _ipos, _jpos, _kpos) ; } - + __static_call __inline_call real_type cost_dual ( __const_ptr(real_type) _ipos , @@ -124,7 +148,7 @@ ::dual_quality_2d ( _ipos, _jpos, _kpos) ; } - + __static_call __inline_call real_type innerprod ( __const_ptr(real_type) _avec , @@ -133,7 +157,7 @@ { return geometry ::dot_2d (_avec, _bvec) ; } - + __static_call __inline_call real_type length_sq ( __const_ptr(real_type) _ipos , @@ -142,15 +166,15 @@ { return geometry:: lensqr_2d(_ipos, _jpos) ; } - + __static_call __inline_call real_type length_sq ( __const_ptr(real_type) _vvec ) - { return + { return geometry::lensqr_2d (_vvec) ; } - + template < typename geom_type > @@ -165,7 +189,7 @@ __unreferenced(_save) ; __unreferenced(_proj) ; } - + } ; } diff --git a/src/libcpp/iter_mesh/iter_pred_euclidean_3.hpp b/src/libcpp/iter_mesh/iter_pred_euclidean_3.hpp index 816fab3..0490b51 100644 --- a/src/libcpp/iter_mesh/iter_pred_euclidean_3.hpp +++ b/src/libcpp/iter_mesh/iter_pred_euclidean_3.hpp @@ -4,29 +4,29 @@ * ITER-PRED-EUCLIDEAN-3: predicates for MESH-ITER-3. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- @@ -50,8 +50,8 @@ //_pred.vnrm(); //_pred.vcos(); - - + + template < typename R , typename I @@ -61,11 +61,11 @@ public : typedef R real_type ; typedef I iptr_type ; - - iptr_type static constexpr _dims = +3 ; - + + iptr_type static constexpr _dims = +3 ; + public : - + __static_call __inline_call real_type mass_tria ( __const_ptr(real_type) _ipos , @@ -76,7 +76,7 @@ ::tria_area_3d ( _ipos, _jpos, _kpos) ; } - + __static_call __inline_call real_type mass_tria ( __const_ptr(real_type) _ipos , @@ -88,7 +88,7 @@ ::tetra_vol_3d ( _ipos, _jpos, _kpos, _lpos) ; } - + __static_call __inline_call void_type circ_ball ( __write_ptr(real_type) _ball , @@ -101,7 +101,7 @@ ::circ_ball_3d ( _ball, _ipos, _jpos, _kpos, _bind) ; } - + __static_call __inline_call void_type circ_ball ( __write_ptr(real_type) _ball , @@ -112,10 +112,10 @@ bool_type _bind = false ) { return geometry - ::circ_ball_3d ( _ball, + ::circ_ball_3d ( _ball, _ipos, _jpos, _kpos, _lpos, _bind) ; } - + __static_call __inline_call void_type perp_ball ( __write_ptr(real_type) _ball , @@ -128,7 +128,7 @@ ::perp_ball_3d ( _ball, _ipos, _jpos, _kpos, _bind) ; } - + __static_call __inline_call void_type perp_ball ( __write_ptr(real_type) _ball , @@ -139,10 +139,10 @@ bool_type _bind = false ) { return geometry - ::perp_ball_3d ( _ball, + ::perp_ball_3d ( _ball, _ipos, _jpos, _kpos, _lpos, _bind) ; } - + __static_call __inline_call real_type cost_tria ( __const_ptr(real_type) _ipos , @@ -153,7 +153,7 @@ ::tria_quality_3d ( _ipos, _jpos, _kpos) ; } - + __static_call __inline_call real_type cost_tria ( __const_ptr(real_type) _ipos , @@ -165,7 +165,7 @@ ::tria_quality_3d ( _ipos, _jpos, _kpos, _lpos) ; } - + __static_call __inline_call real_type cost_dual ( __const_ptr(real_type) _ipos , @@ -176,7 +176,7 @@ ::dual_quality_3d ( _ipos, _jpos, _kpos) ; } - + __static_call __inline_call real_type cost_dual ( __const_ptr(real_type) _ipos , @@ -188,7 +188,7 @@ ::dual_quality_3d ( _ipos, _jpos, _kpos, _lpos) ; } - + __static_call __inline_call real_type innerprod ( __const_ptr(real_type) _avec , @@ -197,7 +197,7 @@ { return geometry ::dot_3d (_avec, _bvec) ; } - + __static_call __inline_call real_type length_sq ( __const_ptr(real_type) _ipos , @@ -206,15 +206,15 @@ { return geometry:: lensqr_3d(_ipos, _jpos) ; } - + __static_call __inline_call real_type length_sq ( __const_ptr(real_type) _vvec ) - { return + { return geometry::lensqr_3d (_vvec) ; } - + template < typename geom_type > @@ -229,7 +229,7 @@ __unreferenced(_save) ; __unreferenced(_proj) ; } - + } ; } diff --git a/src/libcpp/iter_mesh/iter_timers.hpp b/src/libcpp/iter_mesh/iter_timers.hpp index 72865ea..3720676 100644 --- a/src/libcpp/iter_mesh/iter_timers.hpp +++ b/src/libcpp/iter_mesh/iter_timers.hpp @@ -4,29 +4,29 @@ * ITER-TIMERS: timers for ITER-MESH-K. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- @@ -47,38 +47,38 @@ # define __ITER_TIMERS__ namespace mesh { - + /* -------------------------------------------------------- * ITER-TIMERS: cpu timers for ITER-MESH-K -------------------------------------------------------- */ - + template < - typename R , + typename R , typename I > class iter_timers { public : - + typedef R real_type ; typedef I iptr_type ; - + typedef iter_timers self_type ; - + real_type _iter_full = (real_type) +0. ; - + real_type _move_full = (real_type) +0. ; real_type _topo_full = (real_type) +0. ; real_type _zips_full = (real_type) +0. ; - + public : - + /*-------------------------------------- elapsed time */ - + # ifdef __use_timers - + __inline_call double time_span ( typename std:: chrono::high_resolution_clock @@ -95,7 +95,7 @@ } # endif//__use_timers - + } ; } diff --git a/src/libcpp/iter_mesh/iter_zips_2.inc b/src/libcpp/iter_mesh/iter_zips_2.inc index f619d66..a143f76 100644 --- a/src/libcpp/iter_mesh/iter_zips_2.inc +++ b/src/libcpp/iter_mesh/iter_zips_2.inc @@ -4,34 +4,34 @@ * ITER-ZIPS-2: optim. schemes to merge nodes. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 02 March, 2019 + * Last updated: 27 October, 2019 * * Copyright 2013-2019 * Darren Engwirda @@ -40,25 +40,26 @@ * -------------------------------------------------------- */ - + // from iter_mesh_2.hpp - + /* -------------------------------------------------------- * _ZIP-EDGE: try edge merge to improve adj. cost-fun. -------------------------------------------------------- */ - - __static_call + + __static_call __normal_call void_type _zip_edge ( geom_type &_geom , - mesh_type &_mesh , + mesh_type &_mesh , size_type &_hfun , pred_type &_pred , real_list &_hval , iter_opts &_opts , iptr_type _edge , + char_type _kern , bool_type &_okay , iptr_type &_nnew , iptr_list &_iset , @@ -69,54 +70,49 @@ real_list &_tsrc , real_list &_tdst , real_list &_ttmp , - real_list &_dtmp , - real_list &_ddst , real_type _TLIM , - real_type _DLIM , - real_type _lmax - = (real_type) +8.00E-01 , - real_type _qinc + real_type _lmax + = (real_type) +8.25E-01 , + real_type _qinc = (real_type) +1.00E-02 ) { __unreferenced(_pred) ; // for MSVC... - + /*--------------------------------- get edge indexing */ - auto _eptr = + auto _eptr = _mesh._set2.head() + _edge; - + typename mesh_type:: edge_type _edat(*_eptr) ; - - iptr_type _inod, _jnod ; + + iptr_type _inod, _jnod ; _inod = _eptr->node(0) ; _jnod = _eptr->node(1) ; - + auto _iptr = _mesh. - _set1.head()+ _eptr->node(0); + _set1.head()+ _eptr->node(0); auto _jptr = _mesh. _set1.head()+ _eptr->node(1); - + _okay = false ; - + _iset.set_count(+0) ; _jset.set_count(+0) ; _aset.set_count(+0) ; _bset.set_count(+0) ; _cset.set_count(+0) ; - + _tsrc.set_count(+0) ; _tdst.set_count(+0) ; _ttmp.set_count(+0) ; - _dtmp.set_count(+0) ; - _ddst.set_count(+0) ; - - /*--------------------------------- exit if FEAT node */ + + /*--------------------------------- exit if FEAT node */ if (_iptr->feat() != mesh::null_feat) return ; if (_jptr->feat() != mesh::null_feat) return ; - + /*--------------------------------- get edge h-sizing */ real_type _ipos[_dims + 1] ; real_type _jpos[_dims + 1] ; @@ -129,28 +125,28 @@ _jptr->pval(_idim) ; } - real_type _isiz = + real_type _isiz = _hfun.eval(_ipos, _iptr->hidx ()) ; - real_type _jsiz = + real_type _jsiz = _hfun.eval(_jpos, _jptr->hidx ()) ; - + real_type _lsqr = _pred.length_sq(_ipos, _jpos) ; - real_type _hbar = + real_type _hbar = std::min(_isiz , _jsiz); /*--------------------------------- exit if too large */ if (_lsqr >= _hbar * _lmax * _hbar * _lmax ) return ; - + /*--------------------------------- get adjacent face */ - _mesh.node_tri3(_eptr->node (0), + _mesh.node_tri3(_eptr->node (0), _iset) ; - _mesh.node_tri3(_eptr->node (1), + _mesh.node_tri3(_eptr->node (1), _jset) ; - + /*--------------------------------- exit if poor topo */ if (_iset.count() <= +1 || _jset.count() <= +1 ) @@ -158,18 +154,47 @@ if (_iset.count() >= +6 && _jset.count() >= +6 ) return ; - if (_iset.count() + - _jset.count() > +12 ) + if (_iset.count() + + _jset.count() >= 12 ) return ; - + + /*--------------------------------- calc. local topo. */ + auto _ideg = _iset.count() ; + auto _jdeg = _jset.count() ; + + auto _ndeg = _iset.count() + + _jset.count() + - 4 ; + + auto _ierr = std::abs( + (iptr_type)(+6-_ideg)) ; + auto _jerr = std::abs( + (iptr_type)(+6-_jdeg)) ; + + auto _nerr = std::abs( + (iptr_type)(+6-_ndeg)) ; + + // bail-out early if the topological defect would be + // made worse if the zip is done + + if (_nerr > + std::max(_ierr,_jerr)) + return ; + + // if more regular topo. is constructed via the edge + // zip, make it easier to do so! + + //if (2*_nerr < _ierr+_jerr) + //_qinc = std::min(0.,_qinc) ; + /*--------------------------------- get disjoint face */ for (auto _tria = _iset.head(); _tria != _iset.tend(); ++_tria ) { - auto _tptr = + auto _tptr = _mesh._set3.head()+*_tria ; - + iptr_type _same = +0 ; if (_tptr->node(0) == _eptr->node(0) ) @@ -190,17 +215,17 @@ _eptr->node(1) ) _same += +1 ; if (_same >= +2) continue ; - + _aset.push_tail(*_tria) ; } - + for (auto _tria = _jset.head(); _tria != _jset.tend(); ++_tria ) { - auto _tptr = + auto _tptr = _mesh._set3.head()+*_tria ; - + iptr_type _same = +0 ; if (_tptr->node(0) == _eptr->node(0) ) @@ -221,269 +246,265 @@ _eptr->node(1) ) _same += +1 ; if (_same >= +2) continue ; - + _bset.push_tail(*_tria) ; } - + /*--------------------------------- get adjacent cost */ real_type _minA = - loop_tscr(_mesh, _pred , - _iset, - _tsrc) ; - real_type _minB = - loop_tscr(_mesh, _pred , - _bset, - _tsrc) ; - - real_type _TMIN = + loop_cost(_mesh, _pred , + _iset, + _tsrc, + tria_kind()) ; + real_type _minB = + loop_cost(_mesh, _pred , + _bset, + _tsrc, + tria_kind()) ; + + real_type _TMIN = std::min( _minA, _minB); - - real_type _TSQR = std::sqrt(_TLIM) ; - if (_TMIN>_TSQR) return; - + real_type _TURN = + std::pow(_TLIM, +1./4.) ; + + if (_TMIN>_TURN) return; + /*--------------------------------- get adjacent ball */ - real_type _pbal[_dims+1] = { + real_type _pbal[_dims+1] = { (real_type) +0.000 } ; - + for (auto _tria = _iset.head(); _tria != _iset.tend(); ++_tria ) { real_type _ball[_dims]; - for(_idim = _dims; + for(_idim = _dims; _idim-- != +0 ; ) { - _ball[_idim] = + _ball[_idim] = _mesh._set1[ _mesh._set3[ - *_tria].node(0)].pval(_idim) + + *_tria].node(0)].pval(_idim) + _mesh._set1[ _mesh._set3[ - *_tria].node(1)].pval(_idim) + + *_tria].node(1)].pval(_idim) + _mesh._set1[ _mesh._set3[ *_tria].node(2)].pval(_idim) ; - - _ball[_idim]/= + + _ball[_idim]/= (real_type)+3.; } - - for(_idim = _dims; + + for(_idim = _dims; _idim-- != +0 ; ) { _pbal [_idim] += _ball [_idim] ; } } - + for (auto _tria = _jset.head(); _tria != _jset.tend(); ++_tria ) { real_type _ball[_dims]; - for(_idim = _dims; + for(_idim = _dims; _idim-- != +0 ; ) { - _ball[_idim] = + _ball[_idim] = _mesh._set1[ _mesh._set3[ - *_tria].node(0)].pval(_idim) + + *_tria].node(0)].pval(_idim) + _mesh._set1[ _mesh._set3[ - *_tria].node(1)].pval(_idim) + + *_tria].node(1)].pval(_idim) + _mesh._set1[ _mesh._set3[ *_tria].node(2)].pval(_idim) ; - - _ball[_idim]/= + + _ball[_idim]/= (real_type)+3.; } - - for(_idim = _dims; + + for(_idim = _dims; _idim-- != +0 ; ) { _pbal [_idim] += _ball [_idim] ; } } - + for(_idim = _dims+0; _idim-- != 0; ) { - _pbal[_idim] /= (_iset.count() + + _pbal[_idim] /= (_iset.count() + _jset.count() ) ; } - + _pbal[_dims] = (real_type)+0. ; - _pbal[_dims] += + _pbal[_dims] += _iptr->pval(_dims) ; - _pbal[_dims] += + _pbal[_dims] += _jptr->pval(_dims) ; - + _pbal[_dims] /= (real_type)+2. ; - + /*--------------------------------- try to merge edge */ typename mesh_type ::node_type _ndat ; typename mesh_type ::tri3_type _tdat ; - + _ndat.fdim() = +2 ; - _ndat.feat() = + _ndat.feat() = mesh::null_feat ; - + for(_idim =_dims+1; _idim-- != 0 ; ) { _ndat.pval(_idim) = _pbal[_idim] ; } - - _ndat.hidx() = + + _ndat.hidx() = size_type::null_hint() ; - + iptr_type _inew = _mesh.push_node(_ndat) ; - + _nnew = _inew ; - - auto _nptr = + + auto _nptr = _mesh._set1.head() + _inew ; - + _hval.set_count(std::max ( - _inew + 1, + _inew + 1, (iptr_type)_hval.count())) ; - + _hval[_inew] = (real_type)-1. ; - + /*--------------------------------- push a new cavity */ for (auto _tria = _aset.head(); _tria != _aset.tend(); ++_tria ) - { - auto _tptr = + { + auto _tptr = _mesh._set3.head()+*_tria ; - - _tdat.node(0) = + + _tdat.node(0) = _tptr->node(0) ; - _tdat.node(1) = + _tdat.node(1) = _tptr->node(1) ; - _tdat.node(2) = + _tdat.node(2) = _tptr->node(2) ; - - _tdat.itag () = + + _tdat.itag () = _tptr->itag () ; - - if (_tdat. node(0) == - _edat. node(0) ) + + if (_tdat. node(0) == + _edat. node(0) ) _tdat. node(0) = _inew ; - - if (_tdat. node(1) == - _edat. node(0) ) + + if (_tdat. node(1) == + _edat. node(0) ) _tdat. node(1) = _inew ; - - if (_tdat. node(2) == - _edat. node(0) ) - _tdat. node(2) = _inew ; - - _cset.push_tail( + + if (_tdat. node(2) == + _edat. node(0) ) + _tdat. node(2) = _inew ; + + _cset.push_tail( _mesh.push_tri3(_tdat)) ; } - + for (auto _tria = _bset.head(); _tria != _bset.tend(); ++_tria ) - { - auto _tptr = + { + auto _tptr = _mesh._set3.head()+*_tria ; - - _tdat.node(0) = + + _tdat.node(0) = _tptr->node(0) ; - _tdat.node(1) = + _tdat.node(1) = _tptr->node(1) ; - _tdat.node(2) = + _tdat.node(2) = _tptr->node(2) ; - - _tdat.itag () = + + _tdat.itag () = _tptr->itag () ; - - if (_tdat. node(0) == - _edat. node(1) ) + + if (_tdat. node(0) == + _edat. node(1) ) _tdat. node(0) = _inew ; - - if (_tdat. node(1) == - _edat. node(1) ) + + if (_tdat. node(1) == + _edat. node(1) ) _tdat. node(1) = _inew ; - - if (_tdat. node(2) == - _edat. node(1) ) - _tdat. node(2) = _inew ; - + + if (_tdat. node(2) == + _edat. node(1) ) + _tdat. node(2) = _inew ; + _cset.push_tail( _mesh.push_tri3(_tdat)) ; } - + /*--------------------------------- optim. node coord */ - iptr_type static - constexpr _INUM = (iptr_type) +8 ; - - for (auto _iloc = +0; _iloc != _INUM ; + iptr_type static + constexpr _INUM = (iptr_type) +4 ; + + for (auto _iloc = +0; _iloc != _INUM ; ++_iloc ) { iptr_type _move = (iptr_type) -1 ; - + _ttmp.set_count(0) ; - _dtmp.set_count(0) ; - - real_type _minC = - loop_tscr( _mesh, _pred , - _cset, - _ttmp ) ; - - real_type _minD = - loop_dscr( _mesh, _pred , - _cset, - _dtmp ) ; - + + real_type _minC = + loop_cost( _mesh, _pred , + _cset, + _ttmp, + tria_kind() ) ; + move_node( _geom, _mesh , - _hfun, _pred, _hval , - _opts, _nptr, - _odt_kind, - _move, _cset, + _hfun, _pred, _hval , + _opts, _nptr, _kern , + _move, _cset, _ttmp, _tdst, - _dtmp, _ddst, - _minC, _TLIM, - _minD, _DLIM ) ; - + _minC, _TLIM ) ; + if (_move <= +0) break ; } - + /*--------------------------------- compare cost scr. */ _tdst.set_count(0) ; - - loop_tscr(_mesh, _pred, _cset, - _tdst) ; - - move_okay(_tdst, _tsrc, _okay, - _TSQR, + + loop_cost(_mesh, _pred, _cset, + _tdst, + tria_kind() ) ; + + move_okay(_tdst, _tsrc, _okay, + _TURN, _qinc) ; - + if (_okay) - { - /*--------------------------------- delete old cavity */ + { + /*--------------------------------- delete old cavity */ for (auto _tria = _aset.head(); _tria != _aset.tend(); ++_tria ) - { + { _mesh. _pop_tri3(* _tria) ; } for (auto _tria = _jset.head(); _tria != _jset.tend(); ++_tria ) - { + { _mesh. _pop_tri3(* _tria) ; - } - + } + _mesh. _pop_node(& _inod) ; _mesh. @@ -495,16 +516,16 @@ for (auto _tria = _cset.head(); _tria != _cset.tend(); ++_tria ) - { + { _mesh. _pop_tri3(* _tria) ; } - + _mesh. _pop_node(& _inew) ; } - + } - - - + + + diff --git a/src/libcpp/iter_mesh/iter_zips_3.inc b/src/libcpp/iter_mesh/iter_zips_3.inc index 8123034..af31b8b 100644 --- a/src/libcpp/iter_mesh/iter_zips_3.inc +++ b/src/libcpp/iter_mesh/iter_zips_3.inc @@ -4,29 +4,29 @@ * ITER-ZIPS-3: optim. schemes to merge nodes. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- @@ -40,9 +40,9 @@ * -------------------------------------------------------- */ - + // from iter_mesh_3.hpp - + /* -------------------------------------------------------- @@ -51,7 +51,7 @@ */ /* - __static_call + __static_call __normal_call void_type _zip_face_3 ( */ @@ -61,11 +61,11 @@ * _ZIP-EDGE: try edge merge to improve adj. cost-fun. -------------------------------------------------------- */ - - __static_call + + __static_call __normal_call void_type _zip_edge_3 ( geom_type &_geom , - mesh_type &_mesh , + mesh_type &_mesh , size_type &_hfun , pred_type &_pred , real_list &_hval , @@ -82,52 +82,52 @@ real_list &_ttmp , real_list &_dsrc , real_list &_ddst , - real_type _lmax + real_type _lmax = (real_type) +0.80E+00 , - real_type _good + real_type _good = (real_type) +9.25E-01 , - real_type _qinc + real_type _qinc = (real_type) +1.00E-08 ) { __unreferenced(_pred) ; // for MSVC... - + /*--------------------------------- get edge indexing */ - auto _eptr = + auto _eptr = _mesh._set2.head() + _edge; - + typename mesh_type:: edge_type _edat(*_eptr) ; - - iptr_type _inod, _jnod ; + + iptr_type _inod, _jnod ; _inod = _eptr->node(0) ; _jnod = _eptr->node(1) ; - + auto _iptr = _mesh. - _set1.head()+ _eptr->node(0); + _set1.head()+ _eptr->node(0); auto _jptr = _mesh. _set1.head()+ _eptr->node(1); - + _okay = false ; - + _iset.set_count(+0) ; _jset.set_count(+0) ; _aset.set_count(+0) ; _bset.set_count(+0) ; _cset.set_count(+0) ; - + _tsrc.set_count(+0) ; _tdst.set_count(+0) ; _ttmp.set_count(+0) ; _dsrc.set_count(+0) ; _ddst.set_count(+0) ; - - /*--------------------------------- exit if FEAT node */ + + /*--------------------------------- exit if FEAT node */ if (_iptr->feat() != mesh::null_feat) return ; if (_jptr->feat() != mesh::null_feat) return ; - + /*--------------------------------- get edge h-sizing */ real_type _ipos[_dims + 1] ; real_type _jpos[_dims + 1] ; @@ -140,28 +140,28 @@ _jptr->pval(_idim) ; } - real_type _isiz = + real_type _isiz = _hfun.eval(_ipos, _iptr->hidx ()) ; - real_type _jsiz = + real_type _jsiz = _hfun.eval(_jpos, _jptr->hidx ()) ; - + real_type _lsqr = _pred.length_sq(_ipos, _jpos) ; - real_type _hbar = + real_type _hbar = std::min(_isiz , _jsiz); /*--------------------------------- exit if too large */ if (_lsqr >= _hbar * _lmax * _hbar * _lmax ) return ; - + /*--------------------------------- get adjacent cell */ - _mesh.node_tri4(_eptr->node (0), + _mesh.node_tri4(_eptr->node (0), _iset) ; - _mesh.node_tri4(_eptr->node (1), + _mesh.node_tri4(_eptr->node (1), _jset) ; - + /*--------------------------------- exit if poor topo */ /* if (_iset.count() <= +1 || @@ -174,15 +174,15 @@ _jset.count() > +12 ) return ; */ - + /*--------------------------------- get disjoint face */ for (auto _tria = _iset.head(); _tria != _iset.tend(); ++_tria ) { - auto _tptr = + auto _tptr = _mesh._set4.head()+*_tria ; - + iptr_type _same = +0 ; if (_tptr->node(0) == _eptr->node(0) ) @@ -209,17 +209,17 @@ _eptr->node(1) ) _same += +1 ; if (_same >= +2) continue ; - + _aset.push_tail(*_tria) ; } - + for (auto _tria = _jset.head(); _tria != _jset.tend(); ++_tria ) { - auto _tptr = + auto _tptr = _mesh._set4.head()+*_tria ; - + iptr_type _same = +0 ; if (_tptr->node(0) == _eptr->node(0) ) @@ -246,29 +246,29 @@ _eptr->node(1) ) _same += +1 ; if (_same >= +2) continue ; - + _bset.push_tail(*_tria) ; } - + /*--------------------------------- get adjacent cost */ real_type _minA = - loop_tscr(_mesh, _pred , - _iset, + loop_tscr(_mesh, _pred , + _iset, _tsrc) ; - real_type _minB = - loop_tscr(_mesh, _pred , - _bset, + real_type _minB = + loop_tscr(_mesh, _pred , + _bset, _tsrc) ; - - real_type _TMIN = + + real_type _TMIN = std::min( _minA, _minB); - + if (_TMIN>_good) return; - + /*--------------------------------- get adjacent ball */ - real_type _pbal[_dims+1] = { + real_type _pbal[_dims+1] = { (real_type) +0.000 } ; - + for (auto _tria = _iset.head(); _tria != _iset.tend(); ++_tria ) @@ -288,15 +288,15 @@ _mesh._set4[ *_tria].node(3)].pval(0), true ) ; - - for(_idim = _dims; + + for(_idim = _dims; _idim-- != +0 ; ) { _pbal [_idim] += _ball [_idim] ; } } - + for (auto _tria = _jset.head(); _tria != _jset.tend(); ++_tria ) @@ -316,203 +316,203 @@ _mesh._set4[ *_tria].node(3)].pval(0), true ) ; - - for(_idim = _dims; + + for(_idim = _dims; _idim-- != +0 ; ) { _pbal [_idim] += _ball [_idim] ; } } - + for(_idim = _dims+0; _idim-- != 0; ) { - _pbal[_idim] /= (_iset.count() + + _pbal[_idim] /= (_iset.count() + _jset.count() ) ; } - + _pbal[_dims+0] = (real_type) +0. ; - + /*--------------------------------- try to merge edge */ typename mesh_type ::node_type _ndat ; typename mesh_type ::tri4_type _tdat ; - - _ndat.hidx() = + + _ndat.hidx() = size_type::null_hint() ; - + _ndat.fdim() = +3; - _ndat.feat() = + _ndat.feat() = mesh::null_feat; - + for(_idim = _dims+1; _idim-- != 0; ) { - _ndat.pval(_idim) = + _ndat.pval(_idim) = _pbal[_idim] ; } - - /*--------------------------------- push node at PBAL */ + + /*--------------------------------- push node at PBAL */ iptr_type _inew = _mesh.push_node(_ndat) ; - - auto _nptr = + + auto _nptr = _mesh._set1.head() + _inew ; - + _hval.set_count(std::max ( - _inew + 1, + _inew + 1, (iptr_type)_hval.count())) ; - + _hval[_inew] = (real_type)-1. ; - + /*--------------------------------- push a new cavity */ for (auto _tria = _aset.head(); _tria != _aset.tend(); ++_tria ) - { - auto _tptr = + { + auto _tptr = _mesh._set4.head() +*_tria ; - - _tdat.node(0) = + + _tdat.node(0) = _tptr->node(0) ; - _tdat.node(1) = + _tdat.node(1) = _tptr->node(1) ; - _tdat.node(2) = + _tdat.node(2) = _tptr->node(2) ; - _tdat.node(3) = + _tdat.node(3) = _tptr->node(3) ; - - if (_tdat. node(0) == - _edat. node(0) ) + + if (_tdat. node(0) == + _edat. node(0) ) _tdat. node(0) = _inew ; - - if (_tdat. node(1) == - _edat. node(0) ) + + if (_tdat. node(1) == + _edat. node(0) ) _tdat. node(1) = _inew ; - - if (_tdat. node(2) == - _edat. node(0) ) + + if (_tdat. node(2) == + _edat. node(0) ) _tdat. node(2) = _inew ; - - if (_tdat. node(3) == - _edat. node(0) ) - _tdat. node(3) = _inew ; - - _cset.push_tail( + + if (_tdat. node(3) == + _edat. node(0) ) + _tdat. node(3) = _inew ; + + _cset.push_tail( _mesh.push_tri4(_tdat)) ; } - + for (auto _tria = _bset.head(); _tria != _bset.tend(); ++_tria ) - { - auto _tptr = + { + auto _tptr = _mesh._set4.head() +*_tria ; - - _tdat.node(0) = + + _tdat.node(0) = _tptr->node(0) ; - _tdat.node(1) = + _tdat.node(1) = _tptr->node(1) ; - _tdat.node(2) = + _tdat.node(2) = _tptr->node(2) ; - _tdat.node(3) = + _tdat.node(3) = _tptr->node(3) ; - - if (_tdat. node(0) == - _edat. node(1) ) + + if (_tdat. node(0) == + _edat. node(1) ) _tdat. node(0) = _inew ; - - if (_tdat. node(1) == - _edat. node(1) ) + + if (_tdat. node(1) == + _edat. node(1) ) _tdat. node(1) = _inew ; - - if (_tdat. node(2) == - _edat. node(1) ) + + if (_tdat. node(2) == + _edat. node(1) ) _tdat. node(2) = _inew ; - - if (_tdat. node(3) == - _edat. node(1) ) - _tdat. node(3) = _inew ; - + + if (_tdat. node(3) == + _edat. node(1) ) + _tdat. node(3) = _inew ; + _cset.push_tail( _mesh.push_tri4(_tdat)) ; } - + /*--------------------------------- optim. node coord */ - iptr_type static + iptr_type static constexpr _INUM = (iptr_type) +8 ; - - for (auto _iloc = +0; _iloc != _INUM ; + + for (auto _iloc = +0; _iloc != _INUM ; ++_iloc ) { bool_type _move = false ; - + _ttmp.set_count(0) ; _dsrc.set_count(0) ; - - real_type _minC = - loop_tscr( _mesh, _pred , - _cset, + + real_type _minC = + loop_tscr( _mesh, _pred , + _cset, _ttmp ) ; - - real_type _minD = - loop_dscr( _mesh, _pred , - _cset, + + real_type _minD = + loop_dscr( _mesh, _pred , + _cset, _dsrc ) ; - + move_node( _geom, _mesh , - _hfun, _pred, _hval , - _opts, _nptr, +1 , - _move, _cset, + _hfun, _pred, _hval , + _opts, _nptr, +1 , + _move, _cset, _ttmp, _tdst, - _dsrc, _ddst, + _dsrc, _ddst, _minC, _good, _minD, _good ) ; - + if (_move) continue; - + move_node( _geom, _mesh , - _hfun, _pred, _hval , - _opts, _nptr, +2 , - _move, _cset, + _hfun, _pred, _hval , + _opts, _nptr, +2 , + _move, _cset, _ttmp, _tdst, - _dsrc, _ddst, + _dsrc, _ddst, _minC, _good, _minD, _good ) ; - + if (_move) continue; - + break ; } - + /*--------------------------------- compare cost scr. */ _tdst.set_count(0) ; - - loop_tscr(_mesh, _pred, _cset, + + loop_tscr(_mesh, _pred, _cset, _tdst) ; - - move_okay(_tdst, _tsrc, _okay, + + move_okay(_tdst, _tsrc, _okay, _good, _qinc) ; - + if (_okay) - { - /*--------------------------------- delete old cavity */ + { + /*--------------------------------- delete old cavity */ for (auto _tria = _aset.head(); _tria != _aset.tend(); ++_tria ) - { + { _mesh. _pop_tri4(* _tria) ; } for (auto _tria = _jset.head(); _tria != _jset.tend(); ++_tria ) - { + { _mesh. _pop_tri4(* _tria) ; - } - + } + _mesh. _pop_node(& _inod) ; _mesh. @@ -524,16 +524,16 @@ for (auto _tria = _cset.head(); _tria != _cset.tend(); ++_tria ) - { + { _mesh. _pop_tri4(* _tria) ; } - + _mesh. _pop_node(& _inew) ; } - + } - - - + + + diff --git a/src/libcpp/iter_mesh/tria_cavity_optimal_2.hpp b/src/libcpp/iter_mesh/tria_cavity_optimal_2.hpp deleted file mode 100644 index 786738c..0000000 --- a/src/libcpp/iter_mesh/tria_cavity_optimal_2.hpp +++ /dev/null @@ -1,65 +0,0 @@ - - - template < - typename tria_type , - typename tria_list , - typename iptr_list , - typename pred_type - > - __normal_call void_type cavity_inflate ( - tria_type &_tria , - iptr_type _nnew , - iptr_list &_tset , - tria_list &_tnew , - iptr_list &_tpop , - pred_type &_pred - ) - { - - while (true) - { - - } - - } - - template < - typename tria_type , - typename tria_list , - typename iptr_list , - typename pred_type - > - __normal_call void_type cavity_deflate ( - tria_type &_tria , - iptr_type _nnew , - iptr_list &_tset , - tria_list &_tnew , - iptr_list &_tpop , - pred_type &_pred - ) - { - } - - template < - typename tria_type , - typename tria_list , - typename iptr_list , - typename pred_type - > - __normal_call void_type cavity_optimal ( - tria_type &_tria , - iptr_type _star , - iptr_list &_tset , - tria_list &_tnew , - iptr_list &_tpop , - pred_type &_pred - ) - { - - cavity_deflate(_tria, _star, _tset); - - - } - - - diff --git a/src/libcpp/iter_mesh/tria_cavity_optimal_3.hpp b/src/libcpp/iter_mesh/tria_cavity_optimal_3.hpp deleted file mode 100644 index 786738c..0000000 --- a/src/libcpp/iter_mesh/tria_cavity_optimal_3.hpp +++ /dev/null @@ -1,65 +0,0 @@ - - - template < - typename tria_type , - typename tria_list , - typename iptr_list , - typename pred_type - > - __normal_call void_type cavity_inflate ( - tria_type &_tria , - iptr_type _nnew , - iptr_list &_tset , - tria_list &_tnew , - iptr_list &_tpop , - pred_type &_pred - ) - { - - while (true) - { - - } - - } - - template < - typename tria_type , - typename tria_list , - typename iptr_list , - typename pred_type - > - __normal_call void_type cavity_deflate ( - tria_type &_tria , - iptr_type _nnew , - iptr_list &_tset , - tria_list &_tnew , - iptr_list &_tpop , - pred_type &_pred - ) - { - } - - template < - typename tria_type , - typename tria_list , - typename iptr_list , - typename pred_type - > - __normal_call void_type cavity_optimal ( - tria_type &_tria , - iptr_type _star , - iptr_list &_tset , - tria_list &_tnew , - iptr_list &_tpop , - pred_type &_pred - ) - { - - cavity_deflate(_tria, _star, _tset); - - - } - - - diff --git a/src/libcpp/itermesh.hpp b/src/libcpp/itermesh.hpp index 0c08cc4..aaac0dc 100644 --- a/src/libcpp/itermesh.hpp +++ b/src/libcpp/itermesh.hpp @@ -1,32 +1,32 @@ -/* +/* ------------------------------------------------------------ - * methods for iterative mesh optimisation in R^d. + * methods for iterative mesh optimisation in R^d. ------------------------------------------------------------ * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * ------------------------------------------------------------ @@ -45,7 +45,7 @@ # ifndef __ITERMESH__ # define __ITERMESH__ - + # include "containers.hpp" # include "algorithms.hpp" @@ -55,7 +55,6 @@ # include "meshfunc.hpp" # include "meshtype.hpp" -# include "iter_mesh/iter_params.hpp" # include "iter_mesh/iter_timers.hpp" # include "iter_mesh/iter_mesh_euclidean_2.hpp" diff --git a/src/libcpp/libbasic.hpp b/src/libcpp/libbasic.hpp index fb48cd9..84769ef 100644 --- a/src/libcpp/libbasic.hpp +++ b/src/libcpp/libbasic.hpp @@ -1,180 +1,179 @@ - -/* ------------------------------------------------------------- - * basic types, macros, compiler-settings, etc... ------------------------------------------------------------- - * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) - * - * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The - * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be - * used at your own risk. - * ------------------------------------------------------------- - * - * Last updated: 20 February, 2019 - * - * Copyright 2013-2019 - * Darren Engwirda - * de2363@columbia.edu - * https://github.com/dengwirda/ - * ------------------------------------------------------------- - */ - -# pragma once - -# ifndef __LIBBASIC__ -# define __LIBBASIC__ - -# include -# include - -/* ------------------------------------------------------------- - * push compiler settings ------------------------------------------------------------- - */ - -# if defined(_MSC_VER) -# pragma warning(disable:4127) // constant conditionals -# pragma warning(disable:4503) // decorated name length -# pragma warning(disable:4458) // shadowing - -# elif defined(__LLVM__) - -# elif defined(__GNUC__) - -# endif - -/* ------------------------------------------------------------- - * global data type alias ------------------------------------------------------------- - */ - - typedef void void_type ; - typedef bool bool_type ; - typedef char char_type ; - -/* ------------------------------------------------------------- - * breakpoint-able assert! ------------------------------------------------------------- - */ - -# ifdef NDEBUG -# define __assert(__expr) ((void) 0) -# else - std::size_t volatile __assert_holder; - inline void __assert_breakp( - ) - /*------------------------------ put breakpoint here! */ - { __assert_holder = +0; - } - -# include - -# define __assert(__expr) \ - do { \ - if(!(__expr)) \ - { \ - /*------------------------------ stop for breakpoint! */ \ - __assert_breakp (); \ - assert((__expr)); \ - } \ - } while ( false ) ; -# endif - -/* ------------------------------------------------------------- - * function call decorator ------------------------------------------------------------- - */ - -# define __inline_call inline -# define __normal_call -# define __static_call static -# define __friend_call friend -# define __nocast_call explicit - -/* ------------------------------------------------------------- - * copy // move forwarding ------------------------------------------------------------- - */ - -# define __copy(T, x) std::forward(x) -# define __move(T, x) std::forward(x) - -/* ------------------------------------------------------------- - * unused parameter macros ------------------------------------------------------------- - */ - -# define __unreferenced(x) ((void) x) - -/* ------------------------------------------------------------- - * no--alias pointer types ------------------------------------------------------------- - */ - -# define __const_ptr(T) T const *__restrict -# define __write_ptr(T) T *__restrict - -# define __const_ref(T) T const &__restrict -# define __write_ref(T) T &__restrict - -/* ------------------------------------------------------------- - * integer "flip" routines ------------------------------------------------------------- - */ - -# define __isflip(__i) ( (__i) < 0) - -# define __doflip(__i) (-(__i) - 2) - -# define __unflip(__i) (((__i) < 0) \ - ? __doflip(__i) : (__i) ) - -/* ------------------------------------------------------------- - * integer "flip" routines ------------------------------------------------------------- - */ - -# define __setbit(x,b) ((x)|= (1ULL<<(b))) - -# define __popbit(x,b) ((x)&= ~(1ULL<<(b))) - -# define __flpbit(x,b) ((x)^= (1ULL<<(b))) - -# define __chkbit(x,b) (!!((x)&(1ULL<<(b))) ) - - -# endif //__LIBBASIC__ - - - + +/* +------------------------------------------------------------ + * basic types, macros, compiler-settings, etc... +------------------------------------------------------------ + * + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) + * + * Disclaimer: Neither I nor: Columbia University, The + * Massachusetts Institute of Technology, The + * University of Sydney, nor The National Aeronautics + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be + * used at your own risk. + * +------------------------------------------------------------ + * + * Last updated: 20 February, 2019 + * + * Copyright 2013-2019 + * Darren Engwirda + * de2363@columbia.edu + * https://github.com/dengwirda/ + * +------------------------------------------------------------ + */ + +# pragma once + +# ifndef __LIBBASIC__ +# define __LIBBASIC__ + +# include +# include + +/* +------------------------------------------------------------ + * push compiler settings +------------------------------------------------------------ + */ + +# if defined(_MSC_VER) +# pragma warning(disable:4127) // constant conditionals +# pragma warning(disable:4503) // decorated name length + +# elif defined(__LLVM__) + +# elif defined(__GNUC__) + +# endif + +/* +------------------------------------------------------------ + * global data type alias +------------------------------------------------------------ + */ + + typedef void void_type ; + typedef bool bool_type ; + typedef char char_type ; + +/* +------------------------------------------------------------ + * breakpoint-able assert! +------------------------------------------------------------ + */ + +# ifdef NDEBUG +# define __assert(__expr) ((void) 0) +# else + std::size_t volatile __assert_holder; + inline void __assert_breakp( + ) + /*------------------------------ put breakpoint here! */ + { __assert_holder = +0; + } + +# include + +# define __assert(__expr) \ + do { \ + if(!(__expr)) \ + { \ + /*------------------------------ stop for breakpoint! */ \ + __assert_breakp (); \ + assert((__expr)); \ + } \ + } while ( false ) ; +# endif + +/* +------------------------------------------------------------ + * function call decorator +------------------------------------------------------------ + */ + +# define __inline_call inline +# define __normal_call +# define __static_call static +# define __friend_call friend +# define __nocast_call explicit + +/* +------------------------------------------------------------ + * copy // move forwarding +------------------------------------------------------------ + */ + +# define __copy(T, x) std::forward(x) +# define __move(T, x) std::forward(x) + +/* +------------------------------------------------------------ + * unused parameter macros +------------------------------------------------------------ + */ + +# define __unreferenced(x) ((void) x) + +/* +------------------------------------------------------------ + * no--alias pointer types +------------------------------------------------------------ + */ + +# define __const_ptr(T) T const *__restrict +# define __write_ptr(T) T *__restrict + +# define __const_ref(T) T const &__restrict +# define __write_ref(T) T &__restrict + +/* +------------------------------------------------------------ + * integer "flip" routines +------------------------------------------------------------ + */ + +# define __isflip(__i) ( (__i) < 0) + +# define __doflip(__i) (-(__i) - 2) + +# define __unflip(__i) (((__i) < 0) \ + ? __doflip(__i) : (__i) ) + +/* +------------------------------------------------------------ + * integer "flip" routines +------------------------------------------------------------ + */ + +# define __setbit(x,b) ((x)|= (1ULL<<(b))) + +# define __popbit(x,b) ((x)&= ~(1ULL<<(b))) + +# define __flpbit(x,b) ((x)^= (1ULL<<(b))) + +# define __chkbit(x,b) (!!((x)&(1ULL<<(b))) ) + + +# endif //__LIBBASIC__ + + + diff --git a/src/libcpp/libparse.hpp b/src/libcpp/libparse.hpp index eca2251..0d5a1ba 100644 --- a/src/libcpp/libparse.hpp +++ b/src/libcpp/libparse.hpp @@ -4,29 +4,29 @@ * LIBPARSE: utilities for string/file parsing. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- @@ -51,16 +51,16 @@ * TRIM: trim leading and trailing "whitespace". -------------------------------------------------------- */ - + __static_call __inline_call std::string trim ( std::string const&_line ) { - typename std::string::size_type _pos1 = + typename std::string::size_type _pos1 = _line.find_first_not_of(" \n\r\t") ; - - typename std::string::size_type _pos2 = + + typename std::string::size_type _pos2 = _line. find_last_not_of(" \n\r\t") ; if (_pos1 != std::string::npos && @@ -83,21 +83,21 @@ __static_call __inline_call std::string centred ( - std::size_t _wide, - const std::string& _ssrc) + std::size_t _wide, + const std::string& _ssrc) { std::size_t _slen = _ssrc.length() ; - if (_wide < _slen) - { - return _ssrc; + if (_wide < _slen) + { + return _ssrc; } - + std::size_t _diff = _wide - _slen ; std::size_t _pad1 = _diff / +2 ; std::size_t _pad2 = _diff - _pad1 ; - return std::string(_pad1, ' ') - + _ssrc + return std::string(_pad1, ' ') + + _ssrc + std::string(_pad2, ' ') ; } @@ -106,7 +106,7 @@ * FIND-TOKS: push delimited string onto tokens. -------------------------------------------------------- */ - + __normal_call bool_type test_char ( char _char, std::string const& _dlim @@ -133,17 +133,17 @@ ) { typename std:: - string::const_iterator + string::const_iterator _hpos = _istr.begin() , _tpos = _istr.begin() , - _tend = _istr.end () ; + _tend = _istr.end () ; for ( ; _tpos != _tend; ) { /*--------------------------- find next delimiter */ for (; _tpos != _tend; ++_tpos ) { - if (test_char(*_tpos,_dlim)) - break ; + if (test_char(*_tpos,_dlim)) + break ; } if (_tpos == _hpos) { @@ -158,7 +158,7 @@ _hpos, _tpos))) ; /*-------------------------- reached end-of-input */ if (_tpos == _tend) break ; - } + } _hpos = _tpos + 1; _tpos = _tpos + 1; } @@ -169,7 +169,7 @@ * FILE-PART: split a file name into path-name-fext. -------------------------------------------------------- */ - + __normal_call void_type file_part ( std::string const& _fsrc, std::string & _path, @@ -177,10 +177,10 @@ std::string & _fext ) { - typename std::string::size_type + typename std::string::size_type _spos = _fsrc.find_last_of("\\/"); - - typename std::string::size_type + + typename std::string::size_type _dpos = _fsrc.find_last_of("." ); typename std::string::const_iterator @@ -219,9 +219,9 @@ _name = std::string(_pos2, _pos3); _fext = std::string(_pos4, _pos5); } - - + + # endif//__LIBPARSE__ - - + + diff --git a/src/libcpp/mathutil.hpp b/src/libcpp/mathutil.hpp new file mode 100644 index 0000000..80fc8f9 --- /dev/null +++ b/src/libcpp/mathutil.hpp @@ -0,0 +1,263 @@ + + /* + -------------------------------------------------------- + * MATH-UTIL: general-purpose math utilities. + -------------------------------------------------------- + * + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) + * + * Disclaimer: Neither I nor: Columbia University, The + * Massachusetts Institute of Technology, The + * University of Sydney, nor The National Aeronautics + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be + * used at your own risk. + * + -------------------------------------------------------- + * + * Last updated: 01 July, 2019 + * + * Copyright 2013-2019 + * Darren Engwirda + * de2363@columbia.edu + * https://github.com/dengwirda/ + * + -------------------------------------------------------- + */ + +# pragma once + +# ifndef __MATH_UTIL__ +# define __MATH_UTIL__ + + namespace math + { + + /* + -------------------------------------------------------- + * calc. polynomial roots. + -------------------------------------------------------- + */ + + template < + typename real_type + > + __normal_call bool_type polyroots ( + real_type _aa, // aa*xx^2+bb*xx+cc=0 + real_type _bb, + real_type _cc, + __write_ptr (real_type) _xx + ) + { + real_type _rt = + std::numeric_limits + ::epsilon() ; + + bool_type _real = false ; + + real_type _sq = _bb * _bb - + (real_type)+4. * _aa * _cc ; + + if (_sq >= (real_type)+0.) // real roots + { + _sq = std::sqrt(_sq) ; + + _xx[0] = (-_bb + _sq) ; + _xx[1] = (-_bb - _sq) ; + + real_type _xm = std::max ( + std::abs(_xx[0]), + std::abs(_xx[1])) ; + + if (std::abs(_aa) > + std::abs(_xm) * _rt) + { + _real = true ; + + _aa *=(real_type)+2. ; + + _xx[0] /= _aa ; + _xx[1] /= _aa ; + } + else + if (std::abs(_bb) > + std::abs(_cc) * _rt) + { + _real = true ; + + _xx[0] = -_cc / _bb ; + _xx[1] = -_cc / _bb ; + } + } + + return _real ; + } + + /* + -------------------------------------------------------- + * small matrix utilities. + -------------------------------------------------------- + */ + +# define __ij(__ir , __ic , __nr) \ + ((__ir)+(__ic)*(__nr)) + + template < + typename real_type, + typename size_type + > + __inline_call real_type det_2x2 ( + size_type _la, + __const_ptr (real_type) _aa + ) + { return + _aa[__ij(0,0,_la)] * + _aa[__ij(1,1,_la)] - + _aa[__ij(0,1,_la)] * + _aa[__ij(1,0,_la)] ; + } + + template < + typename real_type, + typename size_type + > + __inline_call real_type det_3x3 ( + size_type _la, + __const_ptr (real_type) _aa + ) + { return + _aa[__ij(0,0,_la)] * ( + _aa[__ij(1,1,_la)] * + _aa[__ij(2,2,_la)] - + _aa[__ij(1,2,_la)] * + _aa[__ij(2,1,_la)] ) - + + _aa[__ij(0,1,_la)] * ( + _aa[__ij(1,0,_la)] * + _aa[__ij(2,2,_la)] - + _aa[__ij(1,2,_la)] * + _aa[__ij(2,0,_la)] ) + + + _aa[__ij(0,2,_la)] * ( + _aa[__ij(1,0,_la)] * + _aa[__ij(2,1,_la)] - + _aa[__ij(1,1,_la)] * + _aa[__ij(2,0,_la)] ) ; + } + + template < + typename real_type, + typename size_type + > + __inline_call void_type inv_2x2 ( + size_type _la, + __const_ptr (real_type) _aa, + size_type _lx, + __write_ptr (real_type) _xx, + real_type &_da + ) + { + _da = det_2x2(_la, _aa) ; + + _xx[__ij(0,0,_lx)] = + _aa[__ij(1,1,_la)] ; + _xx[__ij(1,1,_lx)] = + _aa[__ij(0,0,_la)] ; + _xx[__ij(0,1,_lx)] = + -_aa[__ij(0,1,_la)] ; + _xx[__ij(1,0,_lx)] = + -_aa[__ij(1,0,_la)] ; + } + + template < + typename real_type, + typename size_type + > + __inline_call void_type inv_3x3 ( + size_type _la, + __const_ptr (real_type) _aa, + size_type _lx, + __write_ptr (real_type) _xx, + real_type &_da + ) + { + _da = det_3x3(_la, _aa) ; + + _xx[__ij(0,0,_lx)] = + _aa[__ij(2,2,_la)] * + _aa[__ij(1,1,_la)] - + _aa[__ij(2,1,_la)] * + _aa[__ij(1,2,_la)] ; + + _xx[__ij(0,1,_lx)] = + _aa[__ij(2,1,_la)] * + _aa[__ij(0,2,_la)] - + _aa[__ij(2,2,_la)] * + _aa[__ij(0,1,_la)] ; + + _xx[__ij(0,2,_lx)] = + _aa[__ij(1,2,_la)] * + _aa[__ij(0,1,_la)] - + _aa[__ij(1,1,_la)] * + _aa[__ij(0,2,_la)] ; + + _xx[__ij(1,0,_lx)] = + _aa[__ij(2,0,_la)] * + _aa[__ij(1,2,_la)] - + _aa[__ij(2,2,_la)] * + _aa[__ij(1,0,_la)] ; + + _xx[__ij(1,1,_lx)] = + _aa[__ij(2,2,_la)] * + _aa[__ij(0,0,_la)] - + _aa[__ij(2,0,_la)] * + _aa[__ij(0,2,_la)] ; + + _xx[__ij(1,2,_lx)] = + _aa[__ij(1,0,_la)] * + _aa[__ij(0,2,_la)] - + _aa[__ij(1,2,_la)] * + _aa[__ij(0,0,_la)] ; + + _xx[__ij(2,0,_lx)] = + _aa[__ij(2,1,_la)] * + _aa[__ij(1,0,_la)] - + _aa[__ij(2,0,_la)] * + _aa[__ij(1,1,_la)] ; + + _xx[__ij(2,1,_lx)] = + _aa[__ij(2,0,_la)] * + _aa[__ij(0,1,_la)] - + _aa[__ij(2,1,_la)] * + _aa[__ij(0,0,_la)] ; + + _xx[__ij(2,2,_lx)] = + _aa[__ij(1,1,_la)] * + _aa[__ij(0,0,_la)] - + _aa[__ij(1,0,_la)] * + _aa[__ij(0,1,_la)] ; + } + + + } + +# endif//__MATH_UTIL__ + + + diff --git a/src/libcpp/mesh_func/hfun_base_k.hpp b/src/libcpp/mesh_func/hfun_base_k.hpp index fb6517f..4dcc894 100644 --- a/src/libcpp/mesh_func/hfun_base_k.hpp +++ b/src/libcpp/mesh_func/hfun_base_k.hpp @@ -1,46 +1,46 @@ /* -------------------------------------------------------- - * HFUN-BASE-K: base class for H(x) functions. + * HFUN-BASE-K: base class for H(x) functions. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 03 September, 2017 + * Last updated: 30 June, 2019 * - * Copyright 2013-2017 + * Copyright 2013-2019 * Darren Engwirda * de2363@columbia.edu * https://github.com/dengwirda/ * -------------------------------------------------------- */ - + # pragma once # ifndef __HFUN_BASE_K__ @@ -50,49 +50,52 @@ template < typename I , - typename R + typename R > class hfun_base_kd { public : - + /*-------------------- base class for size-fun in R^k */ - + typedef R real_type ; typedef I iptr_type ; - + typedef iptr_type hint_type ; - + __static_call __inline_call hint_type null_hint ( ) { return ( (hint_type) -1 ); } - + public : /*-------------------- forward dec.'s for sub-classes */ - + __normal_call void_type init ( ) {} - + + __normal_call void_type clip ( + ) {} + __normal_call void_type eval ( - real_type *_ppos , - hint_type &_hint + real_type/*_ppos*/ , + hint_type/*_hint*/ ) {} - + __inline_call real_type eval ( real_type *_ppos , hint_type&&_hint = null_hint () ) { return eval(_ppos, _hint); } - + } ; - - + + } - + # endif //__HFUN_BASE_K__ diff --git a/src/libcpp/mesh_func/hfun_clip_k.hpp b/src/libcpp/mesh_func/hfun_clip_k.hpp new file mode 100644 index 0000000..fc2edb5 --- /dev/null +++ b/src/libcpp/mesh_func/hfun_clip_k.hpp @@ -0,0 +1,702 @@ + + /* + -------------------------------------------------------- + * HFUN-CLIP-kD: kernels for eikonal solvers. + -------------------------------------------------------- + * + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) + * + * Disclaimer: Neither I nor: Columbia University, The + * Massachusetts Institute of Technology, The + * University of Sydney, nor The National Aeronautics + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be + * used at your own risk. + * + -------------------------------------------------------- + * + * Last updated: 01 July, 2019 + * + * Copyright 2013-2019 + * Darren Engwirda + * darren.engwirda@columbia.edu + * https://github.com/dengwirda + * + -------------------------------------------------------- + */ + +# pragma once + +# ifndef __HFUN_CLIP_K__ +# define __HFUN_CLIP_K__ + + namespace mesh { + + template < + typename real_type + > + __normal_call bool_type EIKONAL_edge_2d ( + __const_ptr (real_type) _p1 , + real_type _h1 , + real_type _g1 , + __const_ptr (real_type) _p2 , + real_type& _h2 , + real_type _g2 + ) + { + real_type _gg = + (_g1 + _g2) / (real_type)2. ; + + /*---------------------- form "limited" extrap. to P2 */ + real_type _hn = _h1 + _gg * + std::sqrt( + geometry::lensqr_2d(_p1, _p2) ) ; + + if (_hn < _h2) + { + _h2 = _hn; return true ; + } + else/*no clip*/return false ; + } + + template < + typename real_type + > + __normal_call bool_type EIKONAL_edge_3d ( + __const_ptr (real_type) _p1 , + real_type _h1 , + real_type _g1 , + __const_ptr (real_type) _p2 , + real_type& _h2 , + real_type _g2 + ) + { + real_type _gg = + (_g1 + _g2) / (real_type)2. ; + + /*---------------------- form "limited" extrap. to P2 */ + real_type _hn = _h1 + _gg * + std::sqrt( + geometry::lensqr_3d(_p1, _p2) ) ; + + if (_hn < _h2) + { + _h2 = _hn; return true ; + } + else/*no clip*/return false ; + } + + template < + typename real_type + > + __normal_call bool_type EIKONAL_tria_2d ( + __const_ptr (real_type) _p1 , + real_type _h1 , + real_type _g1 , + __const_ptr (real_type) _p2 , + real_type _h2 , + real_type _g2 , + __const_ptr (real_type) _p3 , + real_type& _h3 , + real_type _g3 + ) + { + real_type _gg = + (_g1+_g2+_g3)/(real_type)3. ; + + /*---------------------- form "limited" extrap. to P3 */ + real_type _d1[2]; + real_type _d3[2]; + geometry:: + vector_2d (_p1, _p2, _d1) ; + geometry:: + vector_2d (_p3, _p1, _d3) ; + + real_type _dh =_h2- _h1; + + real_type _aa = + geometry:: dot_2d(_d1, _d3) ; + real_type _bb = + geometry::lensqr_2d(_d1) ; + real_type _cc = + geometry::lensqr_2d(_d3) ; + + real_type _rr = + std::pow(_dh/_gg, +2); + real_type _at = + _bb * _bb - _rr * _bb; + real_type _bt = + +2. * _aa * (_bb-_rr); + real_type _ct = + _aa * _aa - _rr * _cc; + + real_type _hn = + std::numeric_limits + ::infinity() ; + + real_type _tt[2] ; + if (!math:: + polyroots(_at, _bt, _ct, _tt) ) + { + /*-------------------------- test flow along boundary */ + return EIKONAL_edge_2d ( + _p1, _h1, _gg, + _p3, _h3, _gg) + + | EIKONAL_edge_2d ( + _p2, _h2, _gg, + _p3, _h3, _gg) ; + } + else + { + /*-------------------------- test flow about interior */ + _tt[0] = std::min( + (real_type)+1.,_tt[0]) ; + _tt[0] = std::max( + (real_type)+0.,_tt[0]) ; + + _tt[1] = std::min( + (real_type)+1.,_tt[1]) ; + _tt[1] = std::max( + (real_type)+0.,_tt[1]) ; + + real_type _vp[2] = { + _d3[0] + _tt[0] * _d1[0], + _d3[1] + _tt[0] * _d1[1], + } ; + real_type _vm[2] = { + _d3[0] + _tt[1] * _d1[0], + _d3[1] + _tt[1] * _d1[1], + } ; + + real_type _lp = std::sqrt( + geometry::lensqr_2d(_vp)) ; + + real_type _hp = + _h1 + _tt[0]*_dh + _gg*_lp ; + + real_type _lm = std::sqrt( + geometry::lensqr_2d(_vm)) ; + + real_type _hm = + _h1 + _tt[1]*_dh + _gg*_lm ; + + _hn = std::min(_hp, _hm) ; + + if (_hn < _h3) + { + _h3 = _hn; return true ; + } + else/*no clip*/return false ; + + } + } + + template < + typename real_type + > + __normal_call bool_type EIKONAL_tria_3d ( + __const_ptr (real_type) _p1 , + real_type _h1 , + real_type _g1 , + __const_ptr (real_type) _p2 , + real_type _h2 , + real_type _g2 , + __const_ptr (real_type) _p3 , + real_type& _h3 , + real_type _g3 + ) + { + real_type _gg = + (_g1+_g2+_g3)/(real_type)3. ; + + /*---------------------- form "limited" extrap. to P3 */ + real_type _d1[3]; + real_type _d3[3]; + geometry:: + vector_3d (_p1, _p2, _d1) ; + geometry:: + vector_3d (_p3, _p1, _d3) ; + + real_type _dh =_h2- _h1; + + real_type _aa = + geometry:: dot_3d(_d1, _d3) ; + real_type _bb = + geometry::lensqr_3d(_d1) ; + real_type _cc = + geometry::lensqr_3d(_d3) ; + + real_type _rr = + std::pow(_dh/_gg, +2); + real_type _at = + _bb * _bb - _rr * _bb; + real_type _bt = + +2. * _aa * (_bb-_rr); + real_type _ct = + _aa * _aa - _rr * _cc; + + real_type _hn = + std::numeric_limits + ::infinity() ; + + real_type _tt[2] ; + if (!math:: + polyroots(_at, _bt, _ct, _tt) ) + { + /*-------------------------- test flow along boundary */ + return EIKONAL_edge_3d ( + _p1, _h1, _gg, + _p3, _h3, _gg) + + | EIKONAL_edge_3d ( + _p2, _h2, _gg, + _p3, _h3, _gg) ; + } + else + { + /*-------------------------- test flow about interior */ + _tt[0] = std::min( + (real_type)+1.,_tt[0]) ; + _tt[0] = std::max( + (real_type)+0.,_tt[0]) ; + + _tt[1] = std::min( + (real_type)+1.,_tt[1]) ; + _tt[1] = std::max( + (real_type)+0.,_tt[1]) ; + + real_type _vp[3] = { + _d3[0] + _tt[0] * _d1[0], + _d3[1] + _tt[0] * _d1[1], + _d3[2] + _tt[0] * _d1[2], + } ; + real_type _vm[3] = { + _d3[0] + _tt[1] * _d1[0], + _d3[1] + _tt[1] * _d1[1], + _d3[2] + _tt[1] * _d1[2], + } ; + + real_type _lp = std::sqrt( + geometry::lensqr_3d(_vp)) ; + + real_type _hp = + _h1 + _tt[0]*_dh + _gg*_lp ; + + real_type _lm = std::sqrt( + geometry::lensqr_3d(_vm)) ; + + real_type _hm = + _h1 + _tt[1]*_dh + _gg*_lm ; + + _hn = std::min(_hp, _hm) ; + + if (_hn < _h3) + { + _h3 = _hn; return true ; + } + else/*no clip*/return false ; + + } + } + + template < + typename real_type + > + __normal_call bool_type eikonal_edge_2d ( + __const_ptr (real_type) _p1 , + __const_ptr (real_type) _p2 , + real_type& _h1 , + real_type& _h2 , + real_type _g1 , + real_type _g2 + ) + { + /*---------------------- limit h-values within EDGE-2 */ + bool_type _clip = false ; + + real_type _h0 = std::min(_h1,_h2) ; + + if (_h2 > _h0) + /*--------------------------------- 1st node ordering */ + if (EIKONAL_edge_2d ( + _p1, _h1, _g1 , + _p2, _h2, _g2 ) ) + _clip = true ; + + if (_h1 > _h0) + /*--------------------------------- 2nd node ordering */ + if (EIKONAL_edge_2d ( + _p2, _h2, _g2 , + _p1, _h1, _g1 ) ) + _clip = true ; + + return ( _clip ) ; + } + + template < + typename real_type + > + __normal_call bool_type eikonal_edge_3d ( + __const_ptr (real_type) _p1 , + __const_ptr (real_type) _p2 , + real_type& _h1 , + real_type& _h2 , + real_type _g1 , + real_type _g2 + ) + { + /*---------------------- limit h-values within EDGE-2 */ + bool_type _clip = false ; + + real_type _h0 = std::min(_h1,_h2) ; + + if (_h2 > _h0) + /*--------------------------------- 1st node ordering */ + if (EIKONAL_edge_3d ( + _p1, _h1, _g1 , + _p2, _h2, _g2 ) ) + _clip = true ; + + if (_h1 > _h0) + /*--------------------------------- 2nd node ordering */ + if (EIKONAL_edge_3d ( + _p2, _h2, _g2 , + _p1, _h1, _g1 ) ) + _clip = true ; + + return ( _clip ) ; + } + + template < + typename real_type + > + __normal_call bool_type eikonal_tria_2d ( + __const_ptr (real_type) _p1 , + __const_ptr (real_type) _p2 , + __const_ptr (real_type) _p3 , + real_type& _h1 , + real_type& _h2 , + real_type& _h3 , + real_type _g1 , + real_type _g2 , + real_type _g3 + ) + { + /*---------------------- limit h-values within TRIA-3 */ + bool_type _clip = false ; + + real_type _h0 = + std::min( _h3, std::min(_h1,_h2)) ; + + if (_h3 > _h0) + /*--------------------------------- 1st node ordering */ + if (EIKONAL_tria_2d ( + _p1, _h1, _g1 , + _p2, _h2, _g2 , + _p3, _h3, _g3 ) ) + _clip = true ; + + if (_h1 > _h0) + /*--------------------------------- 2nd node ordering */ + if (EIKONAL_tria_2d ( + _p2, _h2, _g2 , + _p3, _h3, _g3 , + _p1, _h1, _g1 ) ) + _clip = true ; + + if (_h2 > _h0) + /*--------------------------------- 3rd node ordering */ + if (EIKONAL_tria_2d ( + _p3, _h3, _g3 , + _p1, _h1, _g1 , + _p2, _h2, _g2 ) ) + _clip = true ; + + return ( _clip ) ; + } + + template < + typename real_type + > + __normal_call bool_type eikonal_tria_3d ( + __const_ptr (real_type) _p1 , + __const_ptr (real_type) _p2 , + __const_ptr (real_type) _p3 , + real_type& _h1 , + real_type& _h2 , + real_type& _h3 , + real_type _g1 , + real_type _g2 , + real_type _g3 + ) + { + /*---------------------- limit h-values within TRIA-3 */ + bool_type _clip = false ; + + real_type _h0 = + std::min( _h3, std::min(_h1,_h2)) ; + + if (_h3 > _h0) + /*--------------------------------- 1st node ordering */ + if (EIKONAL_tria_3d ( + _p1, _h1, _g1 , + _p2, _h2, _g2 , + _p3, _h3, _g3 ) ) + _clip = true ; + + if (_h1 > _h0) + /*--------------------------------- 2nd node ordering */ + if (EIKONAL_tria_3d ( + _p2, _h2, _g2 , + _p3, _h3, _g3 , + _p1, _h1, _g1 ) ) + _clip = true ; + + if (_h2 > _h0) + /*--------------------------------- 3rd node ordering */ + if (EIKONAL_tria_3d ( + _p3, _h3, _g3 , + _p1, _h1, _g1 , + _p2, _h2, _g2 ) ) + _clip = true ; + + return ( _clip ) ; + } + + template < + typename real_type + > + __normal_call bool_type eikonal_quad_2d ( + __const_ptr (real_type) _p1 , + __const_ptr (real_type) _p2 , + __const_ptr (real_type) _p3 , + __const_ptr (real_type) _p4 , + real_type& _h1 , + real_type& _h2 , + real_type& _h3 , + real_type& _h4 , + real_type _g1 , + real_type _g2 , + real_type _g3 , + real_type _g4 + ) + { + /*---------------------- limit h-values within QUAD-4 */ + bool_type _clip = false ; + bool_type _okay = false ; + + real_type _a1 = + geometry::tria_area_2d(_p1, _p2, _p3) ; + real_type _a2 = + geometry::tria_area_2d(_p1, _p3, _p4) ; + + if (_a1*_a2 > (real_type)+0.) + { + _okay = true ; + /*--------------------------------- 1st tria ordering */ + if (eikonal_tria_2d ( + _p1, _p2, _p3 , + _h1, _h2, _h3 , + _g1, _g2, _g3 ) ) + _clip = true ; + + if (eikonal_tria_2d ( + _p1, _p3, _p4 , + _h1, _h3, _h4 , + _g1, _g3, _g4 ) ) + _clip = true ; + } + + real_type _a3 = + geometry::tria_area_2d(_p1, _p2, _p4) ; + real_type _a4 = + geometry::tria_area_2d(_p2, _p3, _p4) ; + + if (_a3*_a4 > (real_type)+0.) + { + _okay = true ; + /*--------------------------------- 2nd tria ordering */ + if (eikonal_tria_2d ( + _p1, _p2, _p4 , + _h1, _h2, _h4 , + _g1, _g2, _g4 ) ) + _clip = true ; + + if (eikonal_tria_2d ( + _p2, _p3, _p4 , + _h2, _h3, _h4 , + _g2, _g3, _g4 ) ) + _clip = true ; + } + + if (!_okay) + { + /*--------------------------------- a degenerate quad */ + if (EIKONAL_edge_2d ( + _p1, _h1, _g1 , + _p2, _h2, _g2 ) ) + _clip = true ; + + if (EIKONAL_edge_2d ( + _p2, _h2, _g2 , + _p3, _h3, _g3 ) ) + _clip = true ; + + if (EIKONAL_edge_2d ( + _p3, _h3, _g3 , + _p4, _h4, _g4 ) ) + _clip = true ; + + if (EIKONAL_edge_2d ( + _p4, _h4, _g4 , + _p1, _h1, _g1 ) ) + _clip = true ; + } + + return ( _clip ) ; + } + + template < + typename real_type + > + __normal_call bool_type eikonal_quad_3d ( + __const_ptr (real_type) _p1 , + __const_ptr (real_type) _p2 , + __const_ptr (real_type) _p3 , + __const_ptr (real_type) _p4 , + real_type& _h1 , + real_type& _h2 , + real_type& _h3 , + real_type& _h4 , + real_type _g1 , + real_type _g2 , + real_type _g3 , + real_type _g4 + ) + { + /*---------------------- limit h-values within QUAD-4 */ + bool_type _clip = false ; + bool_type _okay = false ; + + real_type _n1[3]; + geometry::tria_norm_3d(_p1, _p2, _p3, + _n1) ; + real_type _n2[3]; + geometry::tria_norm_3d(_p1, _p3, _p4, + _n2) ; + + if (geometry::dot_3d( + _n1, _n2) > (real_type)+0.) + { + _okay = true ; + /*--------------------------------- 1st tria ordering */ + if (eikonal_tria_3d ( + _p1, _p2, _p3 , + _h1, _h2, _h3 , + _g1, _g2, _g3 ) ) + _clip = true ; + + if (eikonal_tria_3d ( + _p1, _p3, _p4 , + _h1, _h3, _h4 , + _g1, _g3, _g4 ) ) + _clip = true ; + } + + real_type _n3[3]; + geometry::tria_norm_3d(_p1, _p2, _p4, + _n3) ; + real_type _n4[3]; + geometry::tria_norm_3d(_p2, _p3, _p4, + _n4) ; + + if (geometry::dot_3d( + _n3, _n4) > (real_type)+0.) + { + _okay = true ; + /*--------------------------------- 2nd tria ordering */ + if (eikonal_tria_3d ( + _p1, _p2, _p4 , + _h1, _h2, _h4 , + _g1, _g2, _g4 ) ) + _clip = true ; + + if (eikonal_tria_3d ( + _p2, _p3, _p4 , + _h2, _h3, _h4 , + _g2, _g3, _g4 ) ) + _clip = true ; + } + + if (!_okay) + { + /*--------------------------------- a degenerate quad */ + if (EIKONAL_edge_3d ( + _p1, _h1, _g1 , + _p2, _h2, _g2 ) ) + _clip = true ; + + if (EIKONAL_edge_3d ( + _p2, _h2, _g2 , + _p3, _h3, _g3 ) ) + _clip = true ; + + if (EIKONAL_edge_3d ( + _p3, _h3, _g3 , + _p4, _h4, _g4 ) ) + _clip = true ; + + if (EIKONAL_edge_3d ( + _p4, _h4, _g4 , + _p1, _h1, _g1 ) ) + _clip = true ; + } + + return ( _clip ) ; + } + + template < + typename real_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*/ , + real_type& /*_h1*/ , + real_type& /*_h2*/ , + real_type& /*_h3*/ , + real_type& /*_h4*/ , + real_type /*_g1*/ , + real_type /*_g2*/ , + real_type /*_g3*/ , + real_type /*_g4*/ + ) + { + return false ; + } + + + } + +# endif//__HFUN_CLIP_K__ + + + diff --git a/src/libcpp/mesh_func/hfun_constant_value_k.hpp b/src/libcpp/mesh_func/hfun_constant_value_k.hpp index d2dd472..762ee55 100644 --- a/src/libcpp/mesh_func/hfun_constant_value_k.hpp +++ b/src/libcpp/mesh_func/hfun_constant_value_k.hpp @@ -4,29 +4,29 @@ * HFUN-CONSTANT-VALUE-KD: uniform H(x) in R^k. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- @@ -40,7 +40,7 @@ * -------------------------------------------------------- */ - + # pragma once # ifndef __HFUN_CONSTANT_VALUE_K__ @@ -50,50 +50,50 @@ template < typename I , - typename R + typename R > - class hfun_constant_value_kd + class hfun_constant_value_kd : public hfun_base_kd { public : - + /*--------------------------- uniform size-fun in R^k */ - + typedef R real_type ; typedef I iptr_type ; - + typedef hfun_constant_value_kd < iptr_type , real_type > hfun_type ; - + typedef typename hfun_base_kd < - iptr_type , + iptr_type , real_type >::hint_type hint_type ; - + public : - + real_type _hval ; - + public : - + /*--------------------------- simply return the value */ - + __inline_call real_type eval ( real_type *_ppos, hint_type &_hint ) - { + { __unreferenced(_ppos) ; __unreferenced(_hint) ; - + return this-> _hval ; } - + } ; - - + + } - + # endif //__HFUN_CONSTANT_VALUE_K__ diff --git a/src/libcpp/mesh_func/hfun_grid_ellipsoid_3.hpp b/src/libcpp/mesh_func/hfun_grid_ellipsoid_3.hpp index 85bd44d..047dec4 100644 --- a/src/libcpp/mesh_func/hfun_grid_ellipsoid_3.hpp +++ b/src/libcpp/mesh_func/hfun_grid_ellipsoid_3.hpp @@ -4,43 +4,43 @@ * HFUN-GRID-ELLIPSOID-3D: ellipsoidal H(x) in R^3. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 24 July, 2018 + * Last updated: 28 June, 2019 * - * Copyright 2013-2018 + * Copyright 2013-2019 * Darren Engwirda * de2363@columbia.edu * https://github.com/dengwirda/ * -------------------------------------------------------- */ - + # pragma once # ifndef __HFUN_GRID_ELLIPSOID_3__ @@ -57,121 +57,599 @@ : public hfun_base_kd { public : - + /*-------------- lat.-lon. spheroidal size-fun in R^3 */ - + typedef R real_type ; typedef I iptr_type ; typedef A allocator ; - + typedef hfun_grid_ellipsoid_3d < iptr_type , real_type > hfun_type ; - + typedef typename hfun_base_kd < - iptr_type , + iptr_type , real_type >::hint_type hint_type ; - + + typedef containers::array < + real_type , + allocator > real_list ; + public : - + /*--------------- (x/a)**2 + (y/b)**2 + (z/c)**2 = 1. */ - - real_type _radA ; - real_type _radB ; - real_type _radC ; + + real_type _radA = 1. ; + real_type _radB = 1. ; + real_type _radC = 1. ; containers::array < real_type, allocator> _xpos ; containers::array < real_type, allocator> _ypos ; - + containers::array < - real_type, allocator> _hmat ; - + real_type, allocator> _hmat ; + + containers::array < + real_type, allocator> _dhdx ; + bool_type _xvar ; bool_type _yvar ; - + + bool_type _wrap ; + public : __inline_call void_type indx_from_subs ( iptr_type _ipos, iptr_type _jpos, iptr_type&_indx - ) + ) const { - iptr_type _ynum = + /*------------ helper: convert into "un-rolled" index */ + iptr_type _ynum = (iptr_type)this->_ypos.count() ; _indx = _jpos * _ynum + _ipos ; } - + + __inline_call void_type subs_from_indx ( + iptr_type _indx, + iptr_type &_ipos, + iptr_type &_jpos + ) const + { + /*------------ helper: convert from "un-rolled" index */ + iptr_type _ynum = + (iptr_type)this->_ypos.count() ; + + _ipos = _indx % _ynum ; + _jpos =(_indx - _ipos )/_ynum ; + } + + __inline_call void_type toR3 ( + __const_ptr(real_type) _apos , + __write_ptr(real_type) _ppos + ) const + { + /*------------ helper: convert from S^2 to R^3 coord. */ + _ppos[0] = this->_radA * + std::cos( _apos[0] ) * + std::cos( _apos[1] ) ; + + _ppos[1] = this->_radB * + std::sin( _apos[0] ) * + std::cos( _apos[1] ) ; + + _ppos[2] = this->_radC * + std::sin( _apos[1] ) ; + } + + __inline_call void_type toS2 ( + __const_ptr(real_type) _ppos , + __write_ptr(real_type) _apos + ) const + { + /*------------ helper: convert from R^3 to S^2 coord. */ + real_type _xmul = + _ppos[0] * this->_radB ; + real_type _ymul = + _ppos[1] * this->_radA ; + real_type _zrat = + _ppos[2] / this->_radC ; + + _zrat = std::min(+1.,_zrat); + _zrat = std::max(-1.,_zrat); + + _apos[0]= std::atan2(_ymul, + _xmul); + _apos[1]= std::asin (_zrat); + } + /* -------------------------------------------------------- * INIT: init. size-fun. class. -------------------------------------------------------- */ - + __inline_call void_type init ( ) { - real_type static const _FTOL = + real_type static const _FTOL = std::pow(std::numeric_limits ::epsilon(), (real_type).8); - + this->_xvar = false ; this->_yvar = false ; - + this->_wrap = false ; + if (this->_xpos.empty()) return ; if (this->_ypos.empty()) return ; - + real_type _xbar, _xmin, _xmax ; - _xbar = *this->_xpos.tail() - + _xbar = *this->_xpos.tail() - *this->_xpos.head() ; - + _xbar /=(this->_xpos.count () - 1) ; - + _xmin = _xbar - _FTOL * _xbar ; _xmax = _xbar + _FTOL * _xbar ; - + real_type _ybar, _ymin, _ymax ; - _ybar = *this->_ypos.tail() - + _ybar = *this->_ypos.tail() - *this->_ypos.head() ; _ybar /=(this->_ypos.count () - 1) ; - + _ymin = _ybar - _FTOL * _ybar ; _ymax = _ybar + _FTOL * _ybar ; - - for (auto + + for (auto _iter = this->_xpos.head() ; _iter != this->_xpos.tail() ; ++_iter ) { - real_type _xdel = + real_type _xdel = *(_iter+1)-*(_iter+0) ; - - if (_xdel < _xmin || - _xdel > _xmax ) + + if (_xdel < _xmin || + _xdel > _xmax ) { _xvar = true ; break ; } } - - for (auto + + for (auto _iter = this->_ypos.head() ; _iter != this->_ypos.tail() ; ++_iter ) { - real_type _ydel = + real_type _ydel = *(_iter+1)-*(_iter+0) ; - - if (_ydel < _ymin || - _ydel > _ymax ) + + if (_ydel < _ymin || + _ydel > _ymax ) { _yvar = true ; break ; } } - + + real_type _xdel = + std::cos(*this->_xpos.tail()) - + std::cos(*this->_xpos.head()) ; + + this->_wrap = + std::abs(_xdel) < _FTOL ; + } + + /* + -------------------------------------------------------- + * CLIP-HFUN: impose |dh/dx| limits. + -------------------------------------------------------- + */ + + __normal_call void_type clip ( + ) + { + class less_than + { + /*-------------------- "LESS-THAN" operator for queue */ + public : + typename + real_list::_write_it _hptr; + + public : + __inline_call less_than ( + typename + real_list::_write_it _hsrc + ) : _hptr(_hsrc) {} + + __inline_call + bool_type operator() ( + iptr_type _ipos, + iptr_type _jpos + ) + { return *(this->_hptr+_ipos) < + *(this->_hptr+_jpos) ; + } + } ; + + typedef typename + allocator:: size_type uint_type ; + + uint_type static constexpr + _null = + std::numeric_limits::max() ; + + containers::prioritymap < + iptr_type , + less_than , + allocator > + _sort((less_than(this->_hmat.head()))); + + containers:: array < + typename + allocator:: size_type, + allocator > _keys; + + /*-------------------- init. values for periodic bc's */ + 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 ; + + if (this->_wrap) + { + iptr_type _inum = +0; + for (auto _iter = + this->_ypos.head() ; + _iter != + this->_ypos.tend() ; + ++_iter , ++_inum) + { + iptr_type _left, _pair ; + indx_from_subs( + _inum, JBEG, _left); + indx_from_subs( + _inum, JEND, _pair); + + real_type _hmin = std::min( + this->_hmat[_left], + this->_hmat[_pair]) ; + + this->_hmat[_left] = _hmin; + this->_hmat[_pair] = _hmin; + } + } + + /*-------------------- push nodes onto priority queue */ + _keys.set_count ( + _hmat.count(), + containers::tight_alloc, _null) ; + + iptr_type _inum = +0; + for (auto _iter = + this->_hmat.head() ; + _iter != + this->_hmat.tend() ; + ++_iter , ++_inum) + { + { + _keys[_inum] = + _sort.push(_inum) ; + } + } + + /*-------------------- compute h(x) via fast-marching */ + for ( ; !_sort.empty() ; ) + { + iptr_type _base ; + _sort._pop_root(_base) ; + + _keys[_base] = _null ; + + iptr_type _ipos, _jpos ; + subs_from_indx( + _base, _ipos, _jpos); + + for (auto _IPOS = _ipos - 1 ; + _IPOS < _ipos + 1 ; + ++_IPOS ) + for (auto _JPOS = _jpos - 1 ; + _JPOS < _jpos + 1 ; + ++_JPOS ) + { + if (_IPOS >= IBEG && _IPOS < IEND) + if (_JPOS >= JBEG && _JPOS < JEND) + { + /*-------------------- un-pack implicit cell indexing */ + auto _ipii = _IPOS + 0 ; + auto _ipjj = _JPOS + 0 ; + + iptr_type _inod; + indx_from_subs( + _ipii, _ipjj, _inod); + + auto _jpii = _IPOS + 1 ; + auto _jpjj = _JPOS + 0 ; + + iptr_type _jnod; + indx_from_subs( + _jpii, _jpjj, _jnod); + + auto _kpii = _IPOS + 1 ; + auto _kpjj = _JPOS + 1 ; + + iptr_type _knod; + indx_from_subs( + _kpii, _kpjj, _knod); + + auto _lpii = _IPOS + 0 ; + auto _lpjj = _JPOS + 1 ; + + iptr_type _lnod; + indx_from_subs( + _lpii, _lpjj, _lnod); + + /*-------------------- skip any cells with null nodes */ + if (_keys[_inod] == _null && + _inod != _base) continue ; + if (_keys[_jnod] == _null && + _jnod != _base) continue ; + if (_keys[_knod] == _null && + _knod != _base) continue ; + if (_keys[_lnod] == _null && + _lnod != _base) continue ; + + /*-------------------- set-up cell vertex coordinates */ + real_type _alon, _alat ; + real_type _IXYZ[3] ; + _alon = this->_xpos[_ipjj]; + _alat = this->_ypos[_ipii]; + _IXYZ[0] = this->_radA * + std::cos(_alon) * + std::cos(_alat) ; + _IXYZ[1] = this->_radB * + std::sin(_alon) * + std::cos(_alat) ; + _IXYZ[2] = this->_radC * + std::sin(_alat) ; + + real_type _JXYZ[3] ; + _alon = this->_xpos[_jpjj]; + _alat = this->_ypos[_jpii]; + _JXYZ[0] = this->_radA * + std::cos(_alon) * + std::cos(_alat) ; + _JXYZ[1] = this->_radB * + std::sin(_alon) * + std::cos(_alat) ; + _JXYZ[2] = this->_radC * + std::sin(_alat) ; + + real_type _KXYZ[3] ; + _alon = this->_xpos[_kpjj]; + _alat = this->_ypos[_kpii]; + _KXYZ[0] = this->_radA * + std::cos(_alon) * + std::cos(_alat) ; + _KXYZ[1] = this->_radB * + std::sin(_alon) * + std::cos(_alat) ; + _KXYZ[2] = this->_radC * + std::sin(_alat) ; + + real_type _LXYZ[3] ; + _alon = this->_xpos[_lpjj]; + _alat = this->_ypos[_lpii]; + _LXYZ[0] = this->_radA * + std::cos(_alon) * + std::cos(_alat) ; + _LXYZ[1] = this->_radB * + std::sin(_alon) * + std::cos(_alat) ; + _LXYZ[2] = this->_radC * + std::sin(_alat) ; + + if (this->_dhdx.count() >1) + { + /*-------------------- update adj. set, g = g(x) case */ + if (eikonal_quad_3d ( + _IXYZ , _JXYZ , + _KXYZ , _LXYZ , + this->_hmat[_inod], + this->_hmat[_jnod], + this->_hmat[_knod], + this->_hmat[_lnod], + this->_dhdx[_inod], + this->_dhdx[_jnod], + this->_dhdx[_knod], + this->_dhdx[_lnod]) ) + { + + if (_keys[_inod] != _null) + _sort.update( + _keys[_inod] , _inod) ; + + if (_keys[_jnod] != _null) + _sort.update( + _keys[_jnod] , _jnod) ; + + if (_keys[_knod] != _null) + _sort.update( + _keys[_knod] , _knod) ; + + if (_keys[_lnod] != _null) + _sort.update( + _keys[_lnod] , _lnod) ; + + if (this->_wrap) + { + /*-------------------- update adj. set, periodic bc's */ + if (_ipjj==JBEG) + { + iptr_type _pair; + indx_from_subs( + _ipii, JEND , _pair) ; + + this->_hmat [_pair] = + this->_hmat [_inod] ; + + if (_keys[_pair] != _null) + _sort.update( + _keys[_pair] , _pair) ; + } + + if (_jpjj==JEND) + { + iptr_type _pair; + indx_from_subs( + _jpii, JBEG , _pair) ; + + this->_hmat [_pair] = + this->_hmat [_jnod] ; + + if (_keys[_pair] != _null) + _sort.update( + _keys[_pair] , _pair) ; + } + + if (_kpjj==JEND) + { + iptr_type _pair; + indx_from_subs( + _kpii, JBEG , _pair) ; + + this->_hmat [_pair] = + this->_hmat [_knod] ; + + if (_keys[_pair] != _null) + _sort.update( + _keys[_pair] , _pair) ; + } + + if (_lpjj==JBEG) + { + iptr_type _pair; + indx_from_subs( + _lpii, JEND , _pair) ; + + this->_hmat [_pair] = + this->_hmat [_lnod] ; + + if (_keys[_pair] != _null) + _sort.update( + _keys[_pair] , _pair) ; + } + } + + } + } + else + if (this->_dhdx.count()==1) + { + /*-------------------- update adj. set, const. g case */ + if (eikonal_quad_3d ( + _IXYZ , _JXYZ , + _KXYZ , _LXYZ , + this->_hmat[_inod], + this->_hmat[_jnod], + this->_hmat[_knod], + this->_hmat[_lnod], + this->_dhdx[ +0 ], + this->_dhdx[ +0 ], + this->_dhdx[ +0 ], + this->_dhdx[ +0 ]) ) + { + + if (_keys[_inod] != _null) + _sort.update( + _keys[_inod] , _inod) ; + + if (_keys[_jnod] != _null) + _sort.update( + _keys[_jnod] , _jnod) ; + + if (_keys[_knod] != _null) + _sort.update( + _keys[_knod] , _knod) ; + + if (_keys[_lnod] != _null) + _sort.update( + _keys[_lnod] , _lnod) ; + + if (this->_wrap) + { + /*-------------------- update adj. set, periodic bc's */ + if (_ipjj==JBEG) + { + iptr_type _pair; + indx_from_subs( + _ipii, JEND , _pair) ; + + this->_hmat [_pair] = + this->_hmat [_inod] ; + + if (_keys[_pair] != _null) + _sort.update( + _keys[_pair] , _pair) ; + } + + if (_jpjj==JEND) + { + iptr_type _pair; + indx_from_subs( + _jpii, JBEG , _pair) ; + + this->_hmat [_pair] = + this->_hmat [_jnod] ; + + if (_keys[_pair] != _null) + _sort.update( + _keys[_pair] , _pair) ; + } + + if (_kpjj==JEND) + { + iptr_type _pair; + indx_from_subs( + _kpii, JBEG , _pair) ; + + this->_hmat [_pair] = + this->_hmat [_knod] ; + + if (_keys[_pair] != _null) + _sort.update( + _keys[_pair] , _pair) ; + } + + if (_lpjj==JBEG) + { + iptr_type _pair; + indx_from_subs( + _lpii, JEND , _pair) ; + + this->_hmat [_pair] = + this->_hmat [_lnod] ; + + if (_keys[_pair] != _null) + _sort.update( + _keys[_pair] , _pair) ; + } + } + + } + } + + } + } + } + } /* @@ -179,82 +657,97 @@ * EVAL: eval. size-fun. value. -------------------------------------------------------- */ - + __normal_call real_type eval ( real_type *_ppos , hint_type &_hint ) - { - real_type static const FT = + { + real_type static const FT = std::pow ( +std::numeric_limits ::epsilon(),(real_type)+.8); - - real_type _hval = + + real_type _hval = +std::numeric_limits ::infinity(); - + __unreferenced(_hint) ; - + if (this->_xpos.count() == +0) return _hval ; - + if (this->_ypos.count() == +0) return _hval ; - + /*---------------------------- compute xyz to lat-lon */ + real_type _apos[2] ; + if (this->_radA == +1. && + this->_radB == +1. && + this->_radC == +1.) + { + /*---------------------------- "historical" workflow! */ real_type _radius = std::sqrt ( - _ppos[0]*_ppos[0] + - _ppos[1]*_ppos[1] + - _ppos[2]*_ppos[2] ) ; - + _ppos[0]*_ppos[0] + + _ppos[1]*_ppos[1] + + _ppos[2]*_ppos[2] ) ; + if (_radius < FT) - _radius = _radius + FT; - - real_type _alat = + _radius = _radius + FT ; + + _apos[1] = std::asin (_ppos[2]/ _radius ) ; - - real_type _alon = + + _apos[0] = std::atan2(_ppos[1], _ppos[0]) ; + } + else + { + /*---------------------------- for a "full" ellipsoid */ + toS2(_ppos, _apos); + } + + real_type _alon = _apos[ 0] ; + real_type _alat = _apos[ 1] ; real_type static const PI = (real_type)std::atan(+1.0) * 4. ; - - real_type static const PI_h = - (real_type)+.5 * PI ; - real_type static const PI_1 = - (real_type)+1. * PI ; - real_type static const PI_2 = - (real_type)+2. * PI ; - + + real_type static const PI_h = + (real_type)+.5 * PI ; + real_type static const PI_1 = + (real_type)+1. * PI ; + real_type static const PI_2 = + (real_type)+2. * PI ; + if (_alon<-PI_1) _alon += PI_2 ; - if (_alon>=PI_1) _alon -= PI_2 ; - + if (_alon>=PI_1) _alon -= PI_2 ; + if (_alon < *this->_xpos.head()) _alon = *this->_xpos.head(); if (_alon > *this->_xpos.tail()) _alon = *this->_xpos.tail(); - + if (_alat<-PI_h) _alat =-PI_h ; if (_alat>=PI_h) _alat = PI_h ; - + if (_alat < *this->_ypos.head()) _alat = *this->_ypos.head(); if (_alat > *this->_ypos.tail()) _alat = *this->_ypos.tail(); - + /*---------------------------- find enclosing x-range */ iptr_type _ipos = (iptr_type) -1 ; iptr_type _jpos = (iptr_type) -1 ; - + if (this->_xvar == true) { - auto _joff = + auto _joff = algorithms::upper_bound ( - this->_xpos.head(), - this->_xpos.tend(), + this->_xpos.head(), + this->_xpos.tend(), _alon,std::less() ) ; - + _jpos = (iptr_type) ( _joff - this->_xpos.head()- 1) ; } @@ -263,23 +756,23 @@ 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) ; } - + /*---------------------------- find enclosing y-range */ if (this->_yvar == true) { - auto _ioff = + auto _ioff = algorithms::upper_bound ( - this->_ypos.head(), - this->_ypos.tend(), + this->_ypos.head(), + this->_ypos.tend(), _alat,std::less() ) ; - + _ipos = (iptr_type) ( _ioff - this->_ypos.head()- 1) ; } @@ -288,45 +781,45 @@ 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) ; } - - if (_ipos == + + if (_ipos == (iptr_type)this->_ypos.count() - 1) _ipos = _ipos - 1 ; - - if (_jpos == + + if (_jpos == (iptr_type)this->_xpos.count() - 1) _jpos = _jpos - 1 ; - + /*---------------------------- a linear interpolation */ - real_type _xp11 = + real_type _xp11 = this->_xpos[_jpos + 0] ; - real_type _xp22 = + real_type _xp22 = this->_xpos[_jpos + 1] ; - - real_type _yp11 = + + real_type _yp11 = this->_ypos[_ipos + 0] ; - real_type _yp22 = + real_type _yp22 = this->_ypos[_ipos + 1] ; real_type _xval = _alon ; real_type _yval = _alat ; - - real_type _aa22 = + + real_type _aa22 = (_yval-_yp11) * (_xval-_xp11) ; - real_type _aa21 = + real_type _aa21 = (_yval-_yp11) * (_xp22-_xval) ; - real_type _aa12 = + real_type _aa12 = (_yp22-_yval) * (_xval-_xp11) ; - real_type _aa11 = + real_type _aa11 = (_yp22-_yval) * (_xp22-_xval) ; - + iptr_type _kk11 ; indx_from_subs( _ipos + 0, _jpos + 0, _kk11) ; @@ -339,20 +832,20 @@ iptr_type _kk22 ; indx_from_subs( _ipos + 1, _jpos + 1, _kk22) ; - - real_type _hbar = + + real_type _hbar = ( _aa11*this->_hmat[_kk11] + _aa12*this->_hmat[_kk12] + _aa21*this->_hmat[_kk21] + _aa22*this->_hmat[_kk22] ) / ( _aa11+_aa12+_aa21+_aa22) ; - return ( _hbar ) ; + return ( _hbar ) ; } - + } ; - - + + } # endif //__HFUN_GRID_ELLIPSOID_3__ diff --git a/src/libcpp/mesh_func/hfun_grid_euclidean_2.hpp b/src/libcpp/mesh_func/hfun_grid_euclidean_2.hpp index 6800ee1..a1fe7d9 100644 --- a/src/libcpp/mesh_func/hfun_grid_euclidean_2.hpp +++ b/src/libcpp/mesh_func/hfun_grid_euclidean_2.hpp @@ -4,36 +4,36 @@ * HFUN-GRID-EUCLIDEAN-kD: structured H(X) in R^k. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 24 July, 2018 + * Last updated: 28 June, 2019 * - * Copyright 2013-2018 + * Copyright 2013-2019 * Darren Engwirda * de2363@columbia.edu * https://github.com/dengwirda/ @@ -53,13 +53,13 @@ typename I , typename A = allocators::basic_alloc > - class hfun_grid_euclidean_2d + class hfun_grid_euclidean_2d : public hfun_base_kd { public : - + /*---------------------- "grid"-based size-fun in R^2 */ - + typedef R real_type ; typedef I iptr_type ; typedef A allocator ; @@ -69,152 +69,404 @@ iptr_type > hfun_type ; typedef typename hfun_base_kd < - iptr_type , + iptr_type , real_type >::hint_type hint_type ; - - + + typedef containers::array < + real_type , + allocator > real_list ; + + containers::array < real_type, allocator> _xpos; containers::array < real_type, allocator> _ypos; - + containers::array < - real_type, allocator> _hmat; - + real_type, allocator> _hmat; + + containers::array < + real_type, allocator> _dhdx; + bool_type _xvar; bool_type _yvar; - + public : - + __inline_call void_type indx_from_subs ( iptr_type _ipos, iptr_type _jpos, iptr_type&_indx - ) + ) const { - iptr_type _ynum = + /*------------ helper: convert into "un-rolled" index */ + iptr_type _ynum = (iptr_type)this->_ypos.count() ; _indx = _jpos * _ynum + _ipos ; } - + + __inline_call void_type subs_from_indx ( + iptr_type _indx, + iptr_type &_ipos, + iptr_type &_jpos + ) const + { + /*------------ helper: convert from "un-rolled" index */ + iptr_type _ynum = + (iptr_type)this->_ypos.count() ; + + _ipos = _indx % _ynum ; + _jpos =(_indx - _ipos )/_ynum ; + } + + /* + -------------------------------------------------------- + * CLIP-HFUN: impose |dh/dx| limits. + -------------------------------------------------------- + */ + + __normal_call void_type clip ( + ) + { + class less_than + { + /*-------------------- "LESS-THAN" operator for queue */ + public : + typename + real_list::_write_it _hptr; + + public : + __inline_call less_than ( + typename + real_list::_write_it _hsrc + ) : _hptr(_hsrc) {} + + __inline_call + bool_type operator() ( + iptr_type _ipos, + iptr_type _jpos + ) + { return *(this->_hptr+_ipos) < + *(this->_hptr+_jpos) ; + } + } ; + + typedef typename + allocator:: size_type uint_type ; + + uint_type static constexpr + _null = + std::numeric_limits::max() ; + + containers::prioritymap < + iptr_type , + less_than , + allocator > + _sort((less_than(this->_hmat.head()))); + + containers:: array < + typename + allocator:: size_type, + allocator > _keys; + + /*-------------------- push nodes onto priority queue */ + _keys.set_count ( + _hmat.count(), + containers::tight_alloc, _null) ; + + iptr_type _inum = +0; + for (auto _iter = + this->_hmat.head() ; + _iter != + this->_hmat.tend() ; + ++_iter , ++_inum) + { + { + _keys[_inum] = + _sort.push(_inum) ; + } + } + + /*-------------------- compute h(x) via fast-marching */ + 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 ; + + for ( ; !_sort.empty() ; ) + { + iptr_type _base ; + _sort._pop_root(_base) ; + + _keys[_base] = _null ; + + iptr_type _ipos, _jpos ; + subs_from_indx( + _base, _ipos, _jpos); + + for (auto _IPOS = _ipos - 1 ; + _IPOS < _ipos + 1 ; + ++_IPOS ) + for (auto _JPOS = _jpos - 1 ; + _JPOS < _jpos + 1 ; + ++_JPOS ) + { + if (_IPOS >= IBEG && _IPOS < IEND) + if (_JPOS >= JBEG && _JPOS < JEND) + { + /*-------------------- un-pack implicit cell indexing */ + auto _ipii = _IPOS + 0 ; + auto _ipjj = _JPOS + 0 ; + + iptr_type _inod; + indx_from_subs( + _ipii, _ipjj, _inod); + + auto _jpii = _IPOS + 1 ; + auto _jpjj = _JPOS + 0 ; + + iptr_type _jnod; + indx_from_subs( + _jpii, _jpjj, _jnod); + + auto _kpii = _IPOS + 1 ; + auto _kpjj = _JPOS + 1 ; + + iptr_type _knod; + indx_from_subs( + _kpii, _kpjj, _knod); + + auto _lpii = _IPOS + 0 ; + auto _lpjj = _JPOS + 1 ; + + iptr_type _lnod; + indx_from_subs( + _lpii, _lpjj, _lnod); + + /*-------------------- skip any cells with null nodes */ + if (_keys[_inod] == _null && + _inod != _base) continue ; + if (_keys[_jnod] == _null && + _jnod != _base) continue ; + if (_keys[_knod] == _null && + _knod != _base) continue ; + if (_keys[_lnod] == _null && + _lnod != _base) continue ; + + /*-------------------- set-up cell vertex coordinates */ + real_type _IXYZ[2]; + _IXYZ[0] = this->_xpos[_ipjj]; + _IXYZ[1] = this->_ypos[_ipii]; + + real_type _JXYZ[2]; + _JXYZ[0] = this->_xpos[_jpjj]; + _JXYZ[1] = this->_ypos[_jpii]; + + real_type _KXYZ[2]; + _KXYZ[0] = this->_xpos[_kpjj]; + _KXYZ[1] = this->_ypos[_kpii]; + + real_type _LXYZ[2]; + _LXYZ[0] = this->_xpos[_lpjj]; + _LXYZ[1] = this->_ypos[_lpii]; + + if (this->_dhdx.count() >1) + { + /*-------------------- update adj. set, g = g(x) case */ + if (eikonal_quad_2d ( + _IXYZ , _JXYZ , + _KXYZ , _LXYZ , + this->_hmat[_inod], + this->_hmat[_jnod], + this->_hmat[_knod], + this->_hmat[_lnod], + this->_dhdx[_inod], + this->_dhdx[_jnod], + this->_dhdx[_knod], + this->_dhdx[_lnod]) ) + { + + if (_keys[_inod] != _null) + _sort.update( + _keys[_inod] , _inod) ; + + if (_keys[_jnod] != _null) + _sort.update( + _keys[_jnod] , _jnod) ; + + if (_keys[_knod] != _null) + _sort.update( + _keys[_knod] , _knod) ; + + if (_keys[_lnod] != _null) + _sort.update( + _keys[_lnod] , _lnod) ; + + } + } + else + if (this->_dhdx.count()==1) + { + /*-------------------- update adj. set, const. g case */ + if (eikonal_quad_2d ( + _IXYZ , _JXYZ , + _KXYZ , _LXYZ , + this->_hmat[_inod], + this->_hmat[_jnod], + this->_hmat[_knod], + this->_hmat[_lnod], + this->_dhdx[ +0 ], + this->_dhdx[ +0 ], + this->_dhdx[ +0 ], + this->_dhdx[ +0 ]) ) + { + + if (_keys[_inod] != _null) + _sort.update( + _keys[_inod] , _inod) ; + + if (_keys[_jnod] != _null) + _sort.update( + _keys[_jnod] , _jnod) ; + + if (_keys[_knod] != _null) + _sort.update( + _keys[_knod] , _knod) ; + + if (_keys[_lnod] != _null) + _sort.update( + _keys[_lnod] , _lnod) ; + + } + } + + } + } + } + + } + /* -------------------------------------------------------- * INIT: init. size-fun. class. -------------------------------------------------------- */ - + __inline_call void_type init ( ) { - real_type static const _FTOL = + real_type static const _FTOL = std::pow(std::numeric_limits ::epsilon(), (real_type).8); - + this->_xvar = false ; this->_yvar = false ; - + if (this->_xpos.empty()) return ; if (this->_ypos.empty()) return ; - + real_type _xbar, _xmin, _xmax ; - _xbar = *this->_xpos.tail() - + _xbar = *this->_xpos.tail() - *this->_xpos.head() ; - + _xbar /=(this->_xpos.count () - 1) ; - + _xmin = _xbar - _FTOL * _xbar ; _xmax = _xbar + _FTOL * _xbar ; - + real_type _ybar, _ymin, _ymax ; - _ybar = *this->_ypos.tail() - + _ybar = *this->_ypos.tail() - *this->_ypos.head() ; _ybar /=(this->_ypos.count () - 1) ; - + _ymin = _ybar - _FTOL * _ybar ; _ymax = _ybar + _FTOL * _ybar ; - - for (auto + + for (auto _iter = this->_xpos.head() ; _iter != this->_xpos.tail() ; ++_iter ) { - real_type _xdel = + real_type _xdel = *(_iter+1)-*(_iter+0) ; - - if (_xdel < _xmin || - _xdel > _xmax ) + + if (_xdel < _xmin || + _xdel > _xmax ) { _xvar = true ; break ; } } - - for (auto + + for (auto _iter = this->_ypos.head() ; _iter != this->_ypos.tail() ; ++_iter ) { - real_type _ydel = + real_type _ydel = *(_iter+1)-*(_iter+0) ; - - if (_ydel < _ymin || - _ydel > _ymax ) + + if (_ydel < _ymin || + _ydel > _ymax ) { _yvar = true ; break ; } } - + } - + /* -------------------------------------------------------- * EVAL: eval. size-fun. value. -------------------------------------------------------- */ - + __inline_call real_type eval ( real_type *_ppos, hint_type &_hint ) { - real_type _hval = + real_type _hOUT = +std::numeric_limits::infinity(); - + __unreferenced (_hint) ; - + if (this->_xpos.count() == +0) - return _hval ; - - real_type _xpos = _ppos[0] ; - - if (_xpos < *this->_xpos.head() ) - _xpos = *this->_xpos.head() ; - if (_xpos > *this->_xpos.tail() ) - _xpos = *this->_xpos.tail() ; - + return _hOUT ; + + real_type _XPOS = _ppos[0] ; + + if (_XPOS < *this->_xpos.head() ) + _XPOS = *this->_xpos.head() ; + if (_XPOS > *this->_xpos.tail() ) + _XPOS = *this->_xpos.tail() ; + if (this->_ypos.count() == +0) - return _hval ; - - real_type _ypos = _ppos[1] ; - - if (_ypos < *this->_ypos.head() ) - _ypos = *this->_ypos.head() ; - if (_ypos > *this->_ypos.tail() ) - _ypos = *this->_ypos.tail() ; - + return _hOUT ; + + real_type _YPOS = _ppos[1] ; + + if (_YPOS < *this->_ypos.head() ) + _YPOS = *this->_ypos.head() ; + if (_YPOS > *this->_ypos.tail() ) + _YPOS = *this->_ypos.tail() ; + /*---------------------------- find enclosing x-range */ iptr_type _ipos = (iptr_type)-1 ; iptr_type _jpos = (iptr_type)-1 ; - + if (this->_xvar == true) { - auto _joff = + auto _joff = algorithms::upper_bound ( - this->_xpos.head(), - this->_xpos.tend(), - _xpos,std::less()); - + this->_xpos.head(), + this->_xpos.tend(), + _XPOS,std::less()); + _jpos = (iptr_type) ( _joff-this->_xpos.head() - 1); } @@ -223,23 +475,23 @@ real_type _xmin, _xmax, _xdel; _xmin = *this->_xpos.head(); _xmax = *this->_xpos.tail(); - + _xdel = (_xmax - _xmin) / (this->_xpos.count() - 1); - + _jpos = (iptr_type) - ( (_xpos - _xmin) / _xdel ); + ( (_XPOS - _xmin) / _xdel ); } - + /*---------------------------- find enclosing y-range */ if (this->_yvar == true) { - auto _ioff = + auto _ioff = algorithms::upper_bound ( - this->_ypos.head(), - this->_ypos.tend(), - _ypos,std::less()); - + this->_ypos.head(), + this->_ypos.tend(), + _YPOS,std::less()); + _ipos = (iptr_type) ( _ioff-this->_ypos.head() - 1); } @@ -248,42 +500,42 @@ real_type _ymin, _ymax, _ydel; _ymin = *this->_ypos.head(); _ymax = *this->_ypos.tail(); - + _ydel = (_ymax - _ymin) / (this->_ypos.count() - 1); - + _ipos = (iptr_type) - ( (_ypos - _ymin) / _ydel ); + ( (_YPOS - _ymin) / _ydel ); } - - if (_ipos == + + if (_ipos == (iptr_type)this->_ypos.count() - 1) _ipos = _ipos - 1 ; - - if (_jpos == + + if (_jpos == (iptr_type)this->_xpos.count() - 1) _jpos = _jpos - 1 ; - + /*---------------------------- a linear interpolation */ - real_type _xx11 = + real_type _xx11 = this->_xpos[_jpos + 0] ; - real_type _xx22 = + real_type _xx22 = this->_xpos[_jpos + 1] ; - - real_type _yy11 = + + real_type _yy11 = this->_ypos[_ipos + 0] ; - real_type _yy22 = + real_type _yy22 = this->_ypos[_ipos + 1] ; - real_type _aa22 = - (_ypos-_yy11) * (_xpos-_xx11) ; - real_type _aa21 = - (_ypos-_yy11) * (_xx22-_xpos) ; - real_type _aa12 = - (_yy22-_ypos) * (_xpos-_xx11) ; - real_type _aa11 = - (_yy22-_ypos) * (_xx22-_xpos) ; - + real_type _aa22 = + (_YPOS-_yy11) * (_XPOS-_xx11) ; + real_type _aa21 = + (_YPOS-_yy11) * (_xx22-_XPOS) ; + real_type _aa12 = + (_yy22-_YPOS) * (_XPOS-_xx11) ; + real_type _aa11 = + (_yy22-_YPOS) * (_xx22-_XPOS) ; + iptr_type _kk11, _kk12 , _kk21, _kk22 ; indx_from_subs( @@ -294,22 +546,22 @@ _ipos + 1, _jpos + 0, _kk21) ; indx_from_subs( _ipos + 1, _jpos + 1, _kk22) ; - - real_type _hbar = + + real_type _hBAR = ( _aa11*this->_hmat[_kk11] + _aa12*this->_hmat[_kk12] + _aa21*this->_hmat[_kk21] + _aa22*this->_hmat[_kk22] ) / ( _aa11+_aa12+_aa21+_aa22) ; - return ( _hbar ) ; + return ( _hBAR ) ; } - + } ; - - + + } - + # endif //__HFUN_GRID_EUCLIDEAN_2__ diff --git a/src/libcpp/mesh_func/hfun_grid_euclidean_3.hpp b/src/libcpp/mesh_func/hfun_grid_euclidean_3.hpp index 3c12ccd..3d1a2ba 100644 --- a/src/libcpp/mesh_func/hfun_grid_euclidean_3.hpp +++ b/src/libcpp/mesh_func/hfun_grid_euclidean_3.hpp @@ -4,36 +4,36 @@ * HFUN-GRID-EUCLIDEAN-kD: structured H(X) in R^k. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 24 July, 2018 + * Last updated: 28 June, 2019 * - * Copyright 2013-2018 + * Copyright 2013-2019 * Darren Engwirda * de2363@columbia.edu * https://github.com/dengwirda/ @@ -53,13 +53,13 @@ typename I , typename A = allocators::basic_alloc > - class hfun_grid_euclidean_3d + class hfun_grid_euclidean_3d : public hfun_base_kd { public : - + /*---------------------- "grid"-based size-fun in R^3 */ - + typedef R real_type ; typedef I iptr_type ; typedef A allocator ; @@ -69,26 +69,29 @@ iptr_type > hfun_type ; typedef typename hfun_base_kd < - iptr_type , + iptr_type , real_type >::hint_type hint_type ; - - + + containers::array < real_type, allocator> _xpos; containers::array < real_type, allocator> _ypos; containers::array < real_type, allocator> _zpos; - + containers::array < - real_type, allocator> _hmat; - + real_type, allocator> _hmat; + + containers::array < + real_type, allocator> _dhdx; + bool_type _xvar; bool_type _yvar; - bool_type _zvar; - + bool_type _zvar; + public : - + __inline_call void_type indx_from_subs ( iptr_type _ipos, iptr_type _jpos, @@ -96,170 +99,171 @@ iptr_type&_indx ) { - iptr_type _ynum = + /*------------ helper: convert into "un-rolled" index */ + iptr_type _ynum = (iptr_type)this->_ypos.count() ; - - iptr_type _xnum = + + iptr_type _xnum = (iptr_type)this->_xpos.count() ; _indx = _kpos * _xnum * _ynum + _jpos * _ynum + _ipos ; } - + /* -------------------------------------------------------- * INIT: init. size-fun. class. -------------------------------------------------------- */ - + __inline_call void_type init ( ) { - real_type static const _FTOL = + real_type static const _FTOL = std::pow(std::numeric_limits ::epsilon(), (real_type).8); - + this->_xvar = false ; this->_yvar = false ; this->_zvar = false ; - + if (this->_xpos.empty()) return ; if (this->_ypos.empty()) return ; if (this->_zpos.empty()) return ; - + real_type _xbar, _xmin, _xmax ; - _xbar = *this->_xpos.tail() - + _xbar = *this->_xpos.tail() - *this->_xpos.head() ; - + _xbar /=(this->_xpos.count () - 1) ; - + _xmin = _xbar - _FTOL * _xbar ; _xmax = _xbar + _FTOL * _xbar ; - + real_type _ybar, _ymin, _ymax ; - _ybar = *this->_ypos.tail() - + _ybar = *this->_ypos.tail() - *this->_ypos.head() ; _ybar /=(this->_ypos.count () - 1) ; - + _ymin = _ybar - _FTOL * _ybar ; _ymax = _ybar + _FTOL * _ybar ; - + real_type _zbar, _zmin, _zmax ; - _zbar = *this->_zpos.tail() - + _zbar = *this->_zpos.tail() - *this->_zpos.head() ; _zbar /=(this->_zpos.count () - 1) ; - + _zmin = _zbar - _FTOL * _zbar ; _zmax = _zbar + _FTOL * _zbar ; - - for (auto + + for (auto _iter = this->_xpos.head() ; _iter != this->_xpos.tail() ; ++_iter ) { - real_type _xdel = + real_type _xdel = *(_iter+1)-*(_iter+0) ; - - if (_xdel < _xmin || - _xdel > _xmax ) + + if (_xdel < _xmin || + _xdel > _xmax ) { _xvar = true ; break ; } } - - for (auto + + for (auto _iter = this->_ypos.head() ; _iter != this->_ypos.tail() ; ++_iter ) { - real_type _ydel = + real_type _ydel = *(_iter+1)-*(_iter+0) ; - - if (_ydel < _ymin || - _ydel > _ymax ) + + if (_ydel < _ymin || + _ydel > _ymax ) { _yvar = true ; break ; } } - - for (auto + + for (auto _iter = this->_zpos.head() ; _iter != this->_zpos.tail() ; ++_iter ) { - real_type _zdel = + real_type _zdel = *(_iter+1)-*(_iter+0) ; - - if (_zdel < _zmin || - _zdel > _zmax ) + + if (_zdel < _zmin || + _zdel > _zmax ) { _zvar = true ; break ; } - } - + } + } - + /* -------------------------------------------------------- * EVAL: eval. size-fun. value. -------------------------------------------------------- */ - + __inline_call real_type eval ( real_type *_ppos, hint_type &_hint ) { - real_type _hval = + real_type _hOUT = +std::numeric_limits::infinity(); - + __unreferenced (_hint) ; - + if (this->_xpos.count() == +0) - return _hval ; - - real_type _xpos = _ppos[0] ; - - if (_xpos < *this->_xpos.head() ) - _xpos = *this->_xpos.head() ; - if (_xpos > *this->_xpos.tail() ) - _xpos = *this->_xpos.tail() ; - + return _hOUT ; + + real_type _XPOS = _ppos[0] ; + + if (_XPOS < *this->_xpos.head() ) + _XPOS = *this->_xpos.head() ; + if (_XPOS > *this->_xpos.tail() ) + _XPOS = *this->_xpos.tail() ; + if (this->_ypos.count() == +0) - return _hval ; - - real_type _ypos = _ppos[1] ; - - if (_ypos < *this->_ypos.head() ) - _ypos = *this->_ypos.head() ; - if (_ypos > *this->_ypos.tail() ) - _ypos = *this->_ypos.tail() ; - + return _hOUT ; + + real_type _YPOS = _ppos[1] ; + + if (_YPOS < *this->_ypos.head() ) + _YPOS = *this->_ypos.head() ; + if (_YPOS > *this->_ypos.tail() ) + _YPOS = *this->_ypos.tail() ; + if (this->_zpos.count() == +0) - return _hval ; - - real_type _zpos = _ppos[2] ; - - if (_zpos < *this->_zpos.head() ) - _zpos = *this->_zpos.head() ; - if (_zpos > *this->_zpos.tail() ) - _zpos = *this->_zpos.tail() ; - + return _hOUT ; + + real_type _ZPOS = _ppos[2] ; + + if (_ZPOS < *this->_zpos.head() ) + _ZPOS = *this->_zpos.head() ; + if (_ZPOS > *this->_zpos.tail() ) + _ZPOS = *this->_zpos.tail() ; + /*---------------------------- find enclosing x-range */ iptr_type _ipos = (iptr_type)-1 ; iptr_type _jpos = (iptr_type)-1 ; iptr_type _kpos = (iptr_type)-1 ; - + if (this->_xvar == true) { - auto _joff = + auto _joff = algorithms::upper_bound ( - this->_xpos.head(), - this->_xpos.tend(), - _xpos,std::less()); - + this->_xpos.head(), + this->_xpos.tend(), + _XPOS,std::less()); + _jpos = (iptr_type) ( _joff-this->_xpos.head() - 1); } @@ -268,23 +272,23 @@ real_type _xmin, _xmax, _xdel; _xmin = *this->_xpos.head(); _xmax = *this->_xpos.tail(); - + _xdel = (_xmax - _xmin) / (this->_xpos.count() - 1); - + _jpos = (iptr_type) - ( (_xpos - _xmin) / _xdel ); + ( (_XPOS - _xmin) / _xdel ); } - + /*---------------------------- find enclosing y-range */ if (this->_yvar == true) { - auto _ioff = + auto _ioff = algorithms::upper_bound ( - this->_ypos.head(), - this->_ypos.tend(), - _ypos,std::less()); - + this->_ypos.head(), + this->_ypos.tend(), + _YPOS,std::less()); + _ipos = (iptr_type) ( _ioff-this->_ypos.head() - 1); } @@ -293,23 +297,23 @@ real_type _ymin, _ymax, _ydel; _ymin = *this->_ypos.head(); _ymax = *this->_ypos.tail(); - + _ydel = (_ymax - _ymin) / (this->_ypos.count() - 1); - + _ipos = (iptr_type) - ( (_ypos - _ymin) / _ydel ); + ( (_YPOS - _ymin) / _ydel ); } - + /*---------------------------- find enclosing z-range */ if (this->_zvar == true ) { - auto _koff = + auto _koff = algorithms::upper_bound ( - this->_zpos.head(), - this->_zpos.tend(), - _zpos,std::less()); - + this->_zpos.head(), + this->_zpos.tend(), + _ZPOS,std::less()); + _kpos = (iptr_type) ( _koff-this->_zpos.head() - 1); } @@ -318,80 +322,82 @@ real_type _zmin, _zmax, _zdel; _zmin = *this->_zpos.head(); _zmax = *this->_zpos.tail(); - + _zdel = (_zmax - _zmin) / (this->_zpos.count() - 1); - + _kpos = (iptr_type) - ( (_zpos - _zmin) / _zdel ); + ( (_ZPOS - _zmin) / _zdel ); } - - if (_ipos == + + if (_ipos == (iptr_type)this->_ypos.count() - 1) _ipos = _ipos - 1 ; - - if (_jpos == + + if (_jpos == (iptr_type)this->_xpos.count() - 1) _jpos = _jpos - 1 ; - - if (_kpos == + + if (_kpos == (iptr_type)this->_zpos.count() - 1) _kpos = _kpos - 1 ; - + /*---------------------------- a linear interpolation */ - real_type _xx11 = + real_type _xx11 = this->_xpos[_jpos + 0] ; - real_type _xx22 = + real_type _xx22 = this->_xpos[_jpos + 1] ; - - real_type _yy11 = + + real_type _yy11 = this->_ypos[_ipos + 0] ; - real_type _yy22 = + real_type _yy22 = this->_ypos[_ipos + 1] ; - - real_type _zz11 = + + real_type _zz11 = this->_zpos[_kpos + 0] ; - real_type _zz22 = + real_type _zz22 = this->_zpos[_kpos + 1] ; - real_type _v222 =(_zpos-_zz11) * - (_ypos-_yy11)*(_xpos-_xx11) ; - real_type _v221 =(_zz22-_zpos) * - (_ypos-_yy11)*(_xpos-_xx11) ; - real_type _v212 =(_zpos-_zz11) * - (_ypos-_yy11)*(_xx22-_xpos) ; - real_type _v122 =(_zpos-_zz11) * - (_yy22-_ypos)*(_xpos-_xx11) ; - real_type _v211 =(_zz22-_zpos) * - (_ypos-_yy11)*(_xx22-_xpos) ; - real_type _v121 =(_zz22-_zpos) * - (_yy22-_ypos)*(_xpos-_xpos) ; - real_type _v112 =(_zpos-_zz11) * - (_yy22-_ypos)*(_xx22-_xpos) ; - real_type _v111 =(_zz22-_zpos) * - (_yy22-_ypos)*(_xx22-_xpos) ; - - iptr_type _k111, _k112, _k121, - _k211, _k122, _k212, + real_type _v222 =(_ZPOS-_zz11) * + (_YPOS-_yy11)*(_XPOS-_xx11) ; + real_type _v212 =(_ZPOS-_zz11) * + (_YPOS-_yy11)*(_xx22-_XPOS) ; + real_type _v122 =(_ZPOS-_zz11) * + (_yy22-_YPOS)*(_XPOS-_xx11) ; + real_type _v112 =(_ZPOS-_zz11) * + (_yy22-_YPOS)*(_xx22-_XPOS) ; + + real_type _v221 =(_zz22-_ZPOS) * + (_YPOS-_yy11)*(_XPOS-_xx11) ; + real_type _v211 =(_zz22-_ZPOS) * + (_YPOS-_yy11)*(_xx22-_XPOS) ; + real_type _v121 =(_zz22-_ZPOS) * + (_yy22-_YPOS)*(_XPOS-_xx11) ; + real_type _v111 =(_zz22-_ZPOS) * + (_yy22-_YPOS)*(_xx22-_XPOS) ; + + iptr_type _k111, _k112, _k121, + _k211, _k122, _k212, _k221, _k222 ; indx_from_subs( _ipos+0, _jpos+0, _kpos+0, _k111); indx_from_subs( - _ipos+0, _jpos+0, _kpos+1, _k112); + _ipos+1, _jpos+0, _kpos+0, _k211); indx_from_subs( _ipos+0, _jpos+1, _kpos+0, _k121); indx_from_subs( - _ipos+1, _jpos+0, _kpos+0, _k211); + _ipos+1, _jpos+1, _kpos+0, _k221); + indx_from_subs( - _ipos+0, _jpos+1, _kpos+1, _k122); + _ipos+0, _jpos+0, _kpos+1, _k112); indx_from_subs( _ipos+1, _jpos+0, _kpos+1, _k212); indx_from_subs( - _ipos+1, _jpos+1, _kpos+0, _k221); + _ipos+0, _jpos+1, _kpos+1, _k122); indx_from_subs( _ipos+1, _jpos+1, _kpos+1, _k222); - real_type _hbar = + real_type _hBAR = ( _v111*this->_hmat[_k111] + _v112*this->_hmat[_k112] + _v121*this->_hmat[_k121] @@ -403,15 +409,15 @@ / ( _v111+_v112+_v121+_v211+ _v122+_v212+_v221+_v222) ; - return ( _hbar ) ; - } - - + return ( _hBAR ) ; + } + + } ; - - + + } - + # endif //__HFUN_GRID_EUCLIDEAN_3__ diff --git a/src/libcpp/mesh_func/hfun_mesh_ellipsoid_3.hpp b/src/libcpp/mesh_func/hfun_mesh_ellipsoid_3.hpp index 94e2370..496b73c 100644 --- a/src/libcpp/mesh_func/hfun_mesh_ellipsoid_3.hpp +++ b/src/libcpp/mesh_func/hfun_mesh_ellipsoid_3.hpp @@ -4,34 +4,34 @@ * HFUN-MESH-ELLIPSOID-3D: ellipsoidal H(x) in R^3. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 30 April, 2019 + * Last updated: 12 August, 2019 * * Copyright 2013-2019 * Darren Engwirda @@ -54,12 +54,12 @@ typename A = allocators::basic_alloc > class hfun_mesh_ellipsoid_3d - : public hfun_base_kd + : public hfun_base_kd { public : - + /*------------------------- euclidean size-fun in R^2 */ - + typedef R real_type ; typedef I iptr_type ; typedef A allocator ; @@ -69,33 +69,20 @@ iptr_type > hfun_type ; typedef typename hfun_base_kd < - iptr_type , + iptr_type , real_type >::hint_type hint_type ; - - class node_type: public tria_complex_node_3 - { - /*------------------------------------ loc. node type */ - public : - real_type _hval ; - - public : - /*------------------------------------ "write" access */ - __inline_call real_type& hval ( - ) - { return this->_hval ; - } - /*------------------------------------ "const" access */ - __inline_call real_type const& hval ( - ) const - { return this->_hval ; - } - - } ; - - typedef tria_complex_edge_2 edge_type ; - typedef tria_complex_tria_3 tri3_type ; - + typedef containers::array < + real_type , + allocator > real_list ; + + + typedef mesh_complex_node_3 + node_type ; + + typedef mesh_complex_edge_2 edge_type ; + typedef mesh_complex_tria_3 tri3_type ; + typedef mesh::tria_complex_2< node_type, edge_type, @@ -106,44 +93,89 @@ tree_node ; typedef geom_tree::aabb_item_rect_k < - real_type, + float, iptr_type, + 3 > tree_item ; - + typedef geom_tree::aabb_tree< tree_item, + 3 , tree_node, - allocator > tree_type ; - + allocator > tree_type ; + typedef geom_tree::aabb_pred_node_3 < - real_type, + float, iptr_type > tree_pred ; - - public : - + + public : + /*--------------- (x/a)**2 + (y/b)**2 + (z/c)**2 = 1. */ - - real_type _radA ; - real_type _radB ; - real_type _radC ; + + real_type _radA = 1. ; + real_type _radB = 1. ; + real_type _radC = 1. ; containers:: fixed_array _bmin ; containers:: fixed_array _bmax ; - + mesh_type _mesh ; tree_type _tree ; + containers::array< + real_type, allocator > _hval ; + + containers::array< + real_type, allocator > _dhdx ; + public : + __inline_call void_type toR3 ( + __const_ptr(real_type) _apos , + __write_ptr(real_type) _ppos + ) const + { + /*------------ helper: convert from S^2 to R^3 coord. */ + _ppos[0] = this->_radA * + std::cos( _apos[0] ) * + std::cos( _apos[1] ) ; + + _ppos[1] = this->_radB * + std::sin( _apos[0] ) * + std::cos( _apos[1] ) ; + + _ppos[2] = this->_radC * + std::sin( _apos[1] ) ; + } + + __inline_call void_type toS2 ( + __const_ptr(real_type) _ppos , + __write_ptr(real_type) _apos + ) const + { + /*------------ helper: convert from R^3 to S^2 coord. */ + real_type _xmul = + _ppos[0] * this->_radB ; + real_type _ymul = + _ppos[1] * this->_radA ; + real_type _zrat = + _ppos[2] / this->_radC ; + + _zrat = std::min(+1.,_zrat); + _zrat = std::max(-1.,_zrat); + + _apos[0]= std::atan2(_ymul, + _xmul); + _apos[1]= std::asin (_zrat); + } + /* -------------------------------------------------------- * INIT-HFUN: make tree - check signs. -------------------------------------------------------- - */ - + */ + __normal_call void_type init ( ) { @@ -151,28 +183,28 @@ { /*-------------------- TRUE if tree should index tria */ public : - __inline_call + __inline_call bool_type operator () ( tri3_type const& _tdat ) const { return _tdat.mark() >= 0 ; } } ; - + /*----------------------------- init. aabb at -+ inf. */ for(auto _idim = 3; _idim-- != 0 ; ) { - this->_bmin[_idim] = + this->_bmin[_idim] = +std::numeric_limits< real_type>::infinity() ; - - this->_bmax[_idim] = + + this->_bmax[_idim] = -std::numeric_limits< real_type>::infinity() ; } - + /*----------------------------- convert to R^3 coord. */ - for (auto _iter = + for (auto _iter = this->_mesh._set1.head() ; _iter != this->_mesh._set1.tend() ; @@ -180,26 +212,22 @@ { if (_iter->mark() >= +0) { - real_type _alon, _alat ; - _alon = _iter->pval(0) ; - _alat = _iter->pval(1) ; - - _iter->pval(0) = - this-> _radA* - std::cos(_alon) * - std::cos(_alat) ; - _iter->pval(1) = - this-> _radB* - std::sin(_alon) * - std::cos(_alat) ; - _iter->pval(2) = - this-> _radC* - std::sin(_alat) ; + real_type _apos[2]; + real_type _ppos[3]; + + _apos[0] = _iter->pval(0); + _apos[1] = _iter->pval(1); + + toR3(_apos, _ppos); + + _iter->pval(0) = _ppos[0]; + _iter->pval(1) = _ppos[1]; + _iter->pval(2) = _ppos[2]; } } /*----------------------------- calc. aabb for inputs */ - for (auto _iter = + for (auto _iter = this->_mesh._set1.head() ; _iter != this->_mesh._set1.tend() ; @@ -208,72 +236,248 @@ if (_iter->mark() >= +0) { this->_bmin[0] = std::min ( - this->_bmin[0] , + this->_bmin[0] , _iter->pval(0) ) ; this->_bmin[1] = std::min ( - this->_bmin[1] , + this->_bmin[1] , _iter->pval(1) ) ; this->_bmin[2] = std::min ( - this->_bmin[2] , + this->_bmin[2] , _iter->pval(2) ) ; - + this->_bmax[0] = std::max ( - this->_bmax[0] , + this->_bmax[0] , _iter->pval(0) ) ; this->_bmax[1] = std::max ( - this->_bmax[1] , + this->_bmax[1] , _iter->pval(1) ) ; this->_bmax[2] = std::max ( - this->_bmax[2] , + this->_bmax[2] , _iter->pval(2) ) ; } } - - real_type static const _RTOL = + + float static const _RTOL = std::pow ( - std::numeric_limits - ::epsilon(),(real_type).8) ; - + std::numeric_limits + ::epsilon(), (float) +0.9) ; + iptr_type static - constexpr _NBOX=(iptr_type)+4 ; - - real_type _BTOL[3] ; - _BTOL[0] = this->_bmax [ 0 ] - - this->_bmin [ 0 ] ; - _BTOL[1] = this->_bmax [ 1 ] - - this->_bmin [ 1 ] ; - _BTOL[2] = this->_bmax [ 2 ] - - this->_bmin [ 2 ] ; - - _BTOL[0]*=_RTOL ; - _BTOL[1]*=_RTOL ; - _BTOL[2]*=_RTOL ; + constexpr _NBOX=(iptr_type)+8 ; + + float _BTOL[3] ; + _BTOL[0] = + (float) ( this->_bmax[ 0] - + this->_bmin[ 0] ) + * _RTOL ; + _BTOL[1] = + (float) ( this->_bmax[ 1] - + this->_bmin[ 1] ) + * _RTOL ; + _BTOL[2] = + (float) ( this->_bmax[ 2] - + this->_bmin[ 2] ) + * _RTOL ; /*-------------------- make aabb-tree and init. bbox. */ - aabb_mesh( this->_mesh._set1 , - this->_mesh._set3 , + aabb_mesh( this->_mesh._set1 , + this->_mesh._set3 , this->_tree,_BTOL , _NBOX , tria_pred()) ; } - + + /* + -------------------------------------------------------- + * CLIP-HFUN: impose |dh/dx| limits. + -------------------------------------------------------- + */ + + __normal_call void_type clip ( + ) + { + class less_than + { + /*-------------------- "LESS-THAN" operator for queue */ + public : + typename + real_list::_write_it _hptr; + + public : + __inline_call less_than ( + typename + real_list::_write_it _hsrc + ) : _hptr(_hsrc) {} + + __inline_call + bool_type operator() ( + iptr_type _ipos, + iptr_type _jpos + ) + { return *(this->_hptr+_ipos) < + *(this->_hptr+_jpos) ; + } + } ; + + typedef typename + allocator:: size_type uint_type ; + + uint_type static constexpr + _null = + std::numeric_limits::max() ; + + containers::prioritymap < + iptr_type , + less_than , + allocator > + _sort((less_than(this->_hval.head()))); + + containers:: array < + typename + allocator:: size_type, + allocator > _keys; + + containers:: array < + iptr_type , + allocator > _tset; + + /*-------------------- push nodes onto priority queue */ + _keys.set_count ( + _mesh._set1.count(), + containers::tight_alloc, _null) ; + + iptr_type _inum = +0; + for (auto _iter = + this->_mesh._set1.head() ; + _iter != + this->_mesh._set1.tend() ; + ++_iter , ++_inum) + { + if (_iter->mark() >= +0 ) + { + _keys[_inum] = + _sort.push(_inum) ; + } + } + + /*-------------------- compute h(x) via fast-marching */ + for ( ; !_sort.empty() ; ) + { + iptr_type _base ; + _sort._pop_root(_base) ; + + _keys[_base] = _null ; + + _tset.set_count( +0) ; + this-> + _mesh.node_tri3(_base, _tset); + + for (auto _next = _tset.head(); + _next != _tset.tend(); + ++_next ) + { + auto _inod = this-> + _mesh._set3[*_next].node(0); + auto _jnod = this-> + _mesh._set3[*_next].node(1); + auto _knod = this-> + _mesh._set3[*_next].node(2); + + /*-------------------- skip any cells with null nodes */ + if (_keys[_inod] == _null && + _inod != _base) continue ; + if (_keys[_jnod] == _null && + _jnod != _base) continue ; + if (_keys[_knod] == _null && + _knod != _base) continue ; + + if (this->_dhdx.count() >1) + { + /*-------------------- update adj. set, g = g(x) case */ + if (eikonal_tria_3d ( + &this-> + _mesh._set1[ _inod].pval(0), + &this-> + _mesh._set1[ _jnod].pval(0), + &this-> + _mesh._set1[ _knod].pval(0), + this->_hval[_inod], + this->_hval[_jnod], + this->_hval[_knod], + this->_dhdx[_inod], + this->_dhdx[_jnod], + this->_dhdx[_knod]) ) + { + + if (_keys[_inod] != _null) + _sort.update( + _keys[_inod] , _inod) ; + + if (_keys[_jnod] != _null) + _sort.update( + _keys[_jnod] , _jnod) ; + + if (_keys[_knod] != _null) + _sort.update( + _keys[_knod] , _knod) ; + + } + } + else + if (this->_dhdx.count()==1) + { + /*-------------------- update adj. set, const. g case */ + if (eikonal_tria_3d ( + &this-> + _mesh._set1[ _inod].pval(0), + &this-> + _mesh._set1[ _jnod].pval(0), + &this-> + _mesh._set1[ _knod].pval(0), + this->_hval[_inod], + this->_hval[_jnod], + this->_hval[_knod], + this->_dhdx[ +0 ], + this->_dhdx[ +0 ], + this->_dhdx[ +0 ]) ) + { + + if (_keys[_inod] != _null) + _sort.update( + _keys[_inod] , _inod) ; + + if (_keys[_jnod] != _null) + _sort.update( + _keys[_jnod] , _jnod) ; + + if (_keys[_knod] != _null) + _sort.update( + _keys[_knod] , _knod) ; + + } + } + } + } + + } + /* -------------------------------------------------------- * FIND-TRIA: scan for nearest tria. -------------------------------------------------------- - */ - + */ + class find_tria { public : real_type *_ppos ; - + mesh_type *_mesh ; - + bool_type _find ; iptr_type _tpos ; - + public : - + /*------------------------ make a tree-tria predicate */ __inline_call find_tria ( real_type*_psrc = nullptr , @@ -284,37 +488,36 @@ _tpos( -1) {} /*------------------------ call pred. on tree matches */ - __inline_call + __inline_call void_type operator () ( - typename + typename tree_type::item_data *_iptr ) { if (this->_find) return ; - - for ( ; _iptr != nullptr; + + for ( ; _iptr != nullptr; _iptr = _iptr->_next) { real_type _qtmp[+3]; - iptr_type _tpos = + iptr_type _TPOS = _iptr->_data.ipos() ; - + if (near_pred ( _ppos , - _qtmp ,*_mesh , - _tpos ) ) + _qtmp ,*_mesh , + _TPOS ) ) { /*------------------------ is fully inside: finished! */ this->_find = true ; - this->_tpos = _tpos ; - - break ; + this->_tpos = _TPOS ; + break ; } } } - + } ; - + class near_tria { public : @@ -322,14 +525,14 @@ real_type *_qpos ; real_type _dsqr ; - + mesh_type *_mesh ; - + bool_type _find ; iptr_type _tpos ; - + public : - + /*------------------------ make a tree-tria predicate */ __inline_call near_tria ( real_type*_psrc = nullptr , @@ -344,65 +547,69 @@ _tpos( -1) {} /*------------------------ call pred. on tree matches */ - __inline_call - real_type operator () ( - typename + __inline_call float operator () ( + typename tree_type::item_data *_iptr ) { if (this->_find) return +0. ; - - for ( ; _iptr != nullptr; + + for ( ; _iptr != nullptr; _iptr = _iptr->_next) { real_type _qtmp[+3]; - iptr_type _tpos = + iptr_type _TPOS = _iptr->_data.ipos() ; - + if (near_pred ( _ppos , - _qtmp ,*_mesh , - _tpos ) ) + _qtmp ,*_mesh , + _TPOS ) ) { - /*------------------------ is fully inside: finished! */ - this->_dsqr = - (real_type) +0. ; + /*------------------------ projected match: keep best */ + real_type _dtmp = + geometry::lensqr_3d(_ppos, _qtmp); - this->_find = true ; - this->_tpos = _tpos ; - - break ; + if (_dtmp<_dsqr ) // n.b. proj. on tria + { + _qpos[0] = _qtmp[0] ; + _qpos[1] = _qtmp[1] ; + _qpos[2] = _qtmp[2] ; + + this->_dsqr = _dtmp ; + this->_tpos = _TPOS ; + } } else { /*------------------------ projected match: keep best */ - real_type _dtmp = + real_type _dtmp = geometry::lensqr_3d(_ppos, _qtmp); - if (_dtmp<_dsqr ) + if (_dtmp<_dsqr ) // n.b. proj. to rest { _qpos[0] = _qtmp[0] ; _qpos[1] = _qtmp[1] ; _qpos[2] = _qtmp[2] ; this->_dsqr = _dtmp ; - this->_tpos = _tpos ; + this->_tpos = _TPOS ; } } } - return ( this->_dsqr ) ; + return (float) this->_dsqr ; } - + } ; - + /* -------------------------------------------------------- * NEAR-PRED: TRUE if PPOS is in TPOS. -------------------------------------------------------- */ - + __static_call __normal_call bool_type near_pred ( real_type*_ppos , @@ -412,7 +619,7 @@ ) { geometry::hits_type _hits ; - if (geometry::proj_tria_3d(_ppos, + if (geometry::proj_tria_3d(_ppos, &_mesh._set1[ _mesh._set3[ _tpos].node(0)].pval(0) , @@ -430,52 +637,57 @@ else { return ( false ) ; - } + } } - + /* -------------------------------------------------------- * HINT: check for valid index. -------------------------------------------------------- */ - + __inline_call bool_type hint_okay ( hint_type _hint ) - { + { /*------------------------ test whether hint is valid */ return _hint >= (iptr_type)0 - && _hint < (iptr_type) + && _hint < (iptr_type) this->_mesh._set3.count() && this->_mesh. _set3 [_hint].mark() >= 0 ; } - + /* -------------------------------------------------------- * EVAL: eval. size-fun. value. -------------------------------------------------------- */ - + __normal_call real_type eval ( real_type *_ppos , hint_type &_hint ) /*------------------------ find tria + linear interp. */ { - real_type _QPOS[ 3] ; - _QPOS[0] = _ppos[0] ; - _QPOS[1] = _ppos[1] ; - _QPOS[2] = _ppos[2] ; + real_type _QPOS[3] = { + (real_type) _ppos[0] , + (real_type) _ppos[1] , + (real_type) _ppos[2] } ; + + float _PPOS[3] = { + (float) _ppos[0] , + (float) _ppos[1] , + (float) _ppos[2] } ; - real_type _hval = + real_type _hOUT = +std::numeric_limits::infinity() ; - + if (hint_okay(_hint)) { /*------------------------ test whether hint is valid */ - if(!near_pred( _ppos, - _QPOS, _mesh, + if(!near_pred( _ppos, + _QPOS, _mesh, _hint) ) { _hint = this->null_hint(); @@ -492,13 +704,13 @@ /*------------------------ outside: find nearest tria */ near_tria _func (_ppos, _QPOS,&_mesh) ; - + this-> - _tree.near(_ppos, _func) ; - + _tree.near(_PPOS, _func) ; + _hint = _func._tpos ; } - + if (_hint != this->null_hint()) { /*------------------------ linear interp. within tria */ @@ -517,8 +729,8 @@ _set3[_hint].node(_fnod[1]); _fnod[2] = this->_mesh. _set3[_hint].node(_fnod[2]); - - real_type _tvol = + + real_type _tvol = geometry::tria_area_3d ( &this->_mesh. _set1[_fnod[0]].pval(0) , @@ -526,21 +738,21 @@ _set1[_fnod[1]].pval(0) , _QPOS) ; - _hsum += _tvol * this-> - _mesh._set1[_fnod[2]].hval() ; - + _hsum += _tvol * + this->_hval[_fnod[2]] ; + _vsum += _tvol ; } - _hval = _hsum / _vsum ; + _hOUT = _hsum / _vsum ; } /*------------------------- size-fun interp. to ppos. */ - return _hval ; + return _hOUT ; } - + } ; @@ -548,5 +760,5 @@ # endif //__HFUN_MESH_ELLIPSOID_3__ - - + + diff --git a/src/libcpp/mesh_func/hfun_mesh_euclidean_2.hpp b/src/libcpp/mesh_func/hfun_mesh_euclidean_2.hpp index c3fc696..e10f6a1 100644 --- a/src/libcpp/mesh_func/hfun_mesh_euclidean_2.hpp +++ b/src/libcpp/mesh_func/hfun_mesh_euclidean_2.hpp @@ -4,34 +4,34 @@ * HFUN-MESH-EUCLIDEAN-kD: unstructured H(X) in R^k. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 30 April, 2019 + * Last updated: 12 August, 2019 * * Copyright 2013-2019 * Darren Engwirda @@ -54,12 +54,12 @@ typename A = allocators::basic_alloc > class hfun_mesh_euclidean_2d - : public hfun_base_kd + : public hfun_base_kd { public : - + /*------------------------- euclidean size-fun in R^2 */ - + typedef R real_type ; typedef I iptr_type ; typedef A allocator ; @@ -69,75 +69,68 @@ iptr_type > hfun_type ; typedef typename hfun_base_kd < - iptr_type , + iptr_type , real_type >::hint_type hint_type ; - - class node_type: public tria_complex_node_2 - { - /*------------------------------------ loc. node type */ - public : - real_type _hval ; - - public : - /*------------------------------------ "write" access */ - __inline_call real_type& hval ( - ) - { return this->_hval ; - } - /*------------------------------------ "const" access */ - __inline_call real_type const& hval ( - ) const - { return this->_hval ; - } - - } ; - - typedef tria_complex_edge_2 edge_type ; - typedef tria_complex_tria_3 tri3_type ; - + typedef containers::array < + real_type , + allocator > real_list ; + + + typedef mesh_complex_node_2 + node_type ; + + typedef mesh_complex_edge_2 edge_type ; + typedef mesh_complex_tria_3 tri3_type ; + typedef mesh::tria_complex_2< - node_type, - edge_type, - tri3_type, - allocator > mesh_type ; + node_type, + edge_type, + tri3_type, + allocator > mesh_type ; typedef geom_tree::aabb_node_base_k tree_node ; typedef geom_tree::aabb_item_rect_k < - real_type, - iptr_type, - + 2 > tree_item ; - + float, + iptr_type, + + 2 > tree_item ; + typedef geom_tree::aabb_tree< - tree_item, - + 2 , - tree_node, - allocator > tree_type ; - + tree_item, + + 2 , + tree_node, + allocator > tree_type ; + typedef geom_tree::aabb_pred_node_2 < - real_type, - iptr_type > tree_pred ; - - public : - + float, + iptr_type > tree_pred ; + + public : + containers:: fixed_array _bmin ; containers:: fixed_array _bmax ; - + mesh_type _mesh ; tree_type _tree ; - + + containers::array< + real_type, allocator > _hval ; + + containers::array< + real_type, allocator > _dhdx ; + public : /* -------------------------------------------------------- - * INIT-HFUN: make tree - check signs. + * INIT-HFUN: make aabb-tree for search. -------------------------------------------------------- - */ - + */ + __normal_call void_type init ( ) { @@ -145,28 +138,28 @@ { /*-------------------- TRUE if tree should index tria */ public : - __inline_call + __inline_call bool_type operator () ( tri3_type const& _tdat ) const { return _tdat.mark() >= 0 ; } } ; - + /*----------------------------- init. aabb at -+ inf. */ for(auto _idim = 2; _idim-- != 0 ; ) { - this->_bmin[_idim] = + this->_bmin[_idim] = +std::numeric_limits< real_type>::infinity() ; - - this->_bmax[_idim] = + + this->_bmax[_idim] = -std::numeric_limits< real_type>::infinity() ; } - + /*----------------------------- calc. aabb for inputs */ - for (auto _iter = + for (auto _iter = this->_mesh._set1.head() ; _iter != this->_mesh._set1.tend() ; @@ -175,63 +168,238 @@ if (_iter->mark() >= +0) { this->_bmin[0] = std::min ( - this->_bmin[0] , + this->_bmin[0] , _iter->pval(0) ) ; this->_bmin[1] = std::min ( - this->_bmin[1] , + this->_bmin[1] , _iter->pval(1) ) ; - + this->_bmax[0] = std::max ( - this->_bmax[0] , + this->_bmax[0] , _iter->pval(0) ) ; this->_bmax[1] = std::max ( - this->_bmax[1] , + this->_bmax[1] , _iter->pval(1) ) ; } } - - real_type static const _RTOL = + + float static const _RTOL = std::pow ( - std::numeric_limits - ::epsilon(),(real_type).8) ; - + std::numeric_limits + ::epsilon(), (float) +0.9) ; + iptr_type static constexpr _NBOX=(iptr_type)+4 ; - real_type _BTOL[2] ; - _BTOL[0] = this->_bmax [ 0 ] - - this->_bmin [ 0 ] ; - _BTOL[1] = this->_bmax [ 1 ] - - this->_bmin [ 1 ] ; - - _BTOL[0]*=_RTOL ; - _BTOL[1]*=_RTOL ; + float _BTOL[2] ; + _BTOL[0] = + (float) ( this->_bmax[ 0] - + this->_bmin[ 0] ) + * _RTOL ; + _BTOL[1] = + (float) ( this->_bmax[ 1] - + this->_bmin[ 1] ) + * _RTOL ; /*-------------------- make aabb-tree and init. bbox. */ - aabb_mesh( this->_mesh._set1 , - this->_mesh._set3 , + aabb_mesh( this->_mesh._set1 , + this->_mesh._set3 , this->_tree,_BTOL , _NBOX , tria_pred()) ; } - + + /* + -------------------------------------------------------- + * CLIP-HFUN: impose |dh/dx| limits. + -------------------------------------------------------- + */ + + __normal_call void_type clip ( + ) + { + class less_than + { + /*-------------------- "LESS-THAN" operator for queue */ + public : + typename + real_list::_write_it _hptr; + + public : + __inline_call less_than ( + typename + real_list::_write_it _hsrc + ) : _hptr(_hsrc) {} + + __inline_call + bool_type operator() ( + iptr_type _ipos, + iptr_type _jpos + ) + { return *(this->_hptr+_ipos) < + *(this->_hptr+_jpos) ; + } + } ; + + typedef typename + allocator:: size_type uint_type ; + + uint_type static constexpr + _null = + std::numeric_limits::max() ; + + containers::prioritymap < + iptr_type , + less_than , + allocator > + _sort((less_than(this->_hval.head()))); + + containers:: array < + typename + allocator:: size_type, + allocator > _keys; + + containers:: array < + iptr_type , + allocator > _tset; + + /*-------------------- push nodes onto priority queue */ + _keys.set_count ( + _mesh._set1.count(), + containers::tight_alloc, _null) ; + + iptr_type _inum = +0; + for (auto _iter = + this->_mesh._set1.head() ; + _iter != + this->_mesh._set1.tend() ; + ++_iter , ++_inum) + { + if (_iter->mark() >= +0 ) + { + _keys[_inum] = + _sort.push(_inum) ; + } + } + + /*-------------------- compute h(x) via fast-marching */ + for ( ; !_sort.empty() ; ) + { + iptr_type _base ; + _sort._pop_root(_base) ; + + _keys[_base] = _null ; + + _tset.set_count( +0) ; + this-> + _mesh.node_tri3(_base, _tset); + + for (auto _next = _tset.head(); + _next != _tset.tend(); + ++_next ) + { + auto _inod = this-> + _mesh._set3[*_next].node(0); + auto _jnod = this-> + _mesh._set3[*_next].node(1); + auto _knod = this-> + _mesh._set3[*_next].node(2); + + /*-------------------- skip any cells with null nodes */ + if (_keys[_inod] == _null && + _inod != _base) continue ; + if (_keys[_jnod] == _null && + _jnod != _base) continue ; + if (_keys[_knod] == _null && + _knod != _base) continue ; + + if (this->_dhdx.count() >1) + { + /*-------------------- update adj. set, g = g(x) case */ + if (eikonal_tria_2d ( + &this-> + _mesh._set1[ _inod].pval(0), + &this-> + _mesh._set1[ _jnod].pval(0), + &this-> + _mesh._set1[ _knod].pval(0), + this->_hval[_inod], + this->_hval[_jnod], + this->_hval[_knod], + this->_dhdx[_inod], + this->_dhdx[_jnod], + this->_dhdx[_knod]) ) + { + + if (_keys[_inod] != _null) + _sort.update( + _keys[_inod] , _inod) ; + + if (_keys[_jnod] != _null) + _sort.update( + _keys[_jnod] , _jnod) ; + + if (_keys[_knod] != _null) + _sort.update( + _keys[_knod] , _knod) ; + + } + } + else + if (this->_dhdx.count()==1) + { + /*-------------------- update adj. set, const. g case */ + if (eikonal_tria_2d ( + &this-> + _mesh._set1[ _inod].pval(0), + &this-> + _mesh._set1[ _jnod].pval(0), + &this-> + _mesh._set1[ _knod].pval(0), + this->_hval[_inod], + this->_hval[_jnod], + this->_hval[_knod], + this->_dhdx[ +0 ], + this->_dhdx[ +0 ], + this->_dhdx[ +0 ]) ) + { + + if (_keys[_inod] != _null) + _sort.update( + _keys[_inod] , _inod) ; + + if (_keys[_jnod] != _null) + _sort.update( + _keys[_jnod] , _jnod) ; + + if (_keys[_knod] != _null) + _sort.update( + _keys[_knod] , _knod) ; + + } + } + } + } + + } + /* -------------------------------------------------------- * FIND-TRIA: scan for nearest tria. -------------------------------------------------------- - */ - + */ + class find_tria { public : real_type *_ppos ; - + mesh_type *_mesh ; - + bool_type _find ; iptr_type _tpos ; - + public : - + /*------------------------ make a tree-tria predicate */ __inline_call find_tria ( real_type*_psrc = nullptr , @@ -242,37 +410,36 @@ _tpos( -1) {} /*------------------------ call pred. on tree matches */ - __inline_call + __inline_call void_type operator () ( - typename + typename tree_type::item_data *_iptr ) { if (this->_find) return ; - - for ( ; _iptr != nullptr; + + for ( ; _iptr != nullptr; _iptr = _iptr->_next) { real_type _qtmp[+2]; - iptr_type _tpos = + iptr_type _TPOS = _iptr->_data.ipos() ; - + if (near_pred ( _ppos , - _qtmp ,*_mesh , - _tpos ) ) + _qtmp ,*_mesh , + _TPOS ) ) { /*------------------------ is fully inside: finished! */ this->_find = true ; - this->_tpos = _tpos ; - - break ; + this->_tpos = _TPOS ; + break ; } } } - + } ; - + class near_tria { public : @@ -280,14 +447,14 @@ real_type *_qpos ; real_type _dsqr ; - + mesh_type *_mesh ; - + bool_type _find ; iptr_type _tpos ; - + public : - + /*------------------------ make a tree-tria predicate */ __inline_call near_tria ( real_type*_psrc = nullptr , @@ -302,39 +469,41 @@ _tpos( -1) {} /*------------------------ call pred. on tree matches */ - __inline_call - real_type operator () ( - typename + __inline_call float operator () ( + typename tree_type::item_data *_iptr ) { if (this->_find) return +0. ; - - for ( ; _iptr != nullptr; + + for ( ; _iptr != nullptr; _iptr = _iptr->_next) { real_type _qtmp[+2]; - iptr_type _tpos = + iptr_type _TPOS = _iptr->_data.ipos() ; - + if (near_pred ( _ppos , - _qtmp ,*_mesh , - _tpos ) ) + _qtmp ,*_mesh , + _TPOS ) ) { /*------------------------ is fully inside: finished! */ - this->_dsqr = + _qpos[0] = _qtmp[0] ; + _qpos[1] = _qtmp[1] ; + + this->_dsqr = (real_type) +0. ; this->_find = true ; - this->_tpos = _tpos ; - + this->_tpos = _TPOS ; + break ; } else { /*------------------------ projected match: keep best */ - real_type _dtmp = + real_type _dtmp = geometry::lensqr_2d(_ppos, _qtmp); if (_dtmp<_dsqr ) @@ -343,23 +512,23 @@ _qpos[1] = _qtmp[1] ; this->_dsqr = _dtmp ; - this->_tpos = _tpos ; + this->_tpos = _TPOS ; } } } - return ( this->_dsqr ) ; + return (float) this->_dsqr ; } - + } ; - + /* -------------------------------------------------------- * NEAR-PRED: TRUE if PPOS is in TPOS. -------------------------------------------------------- */ - + __static_call __normal_call bool_type near_pred ( real_type*_ppos , @@ -369,7 +538,7 @@ ) { geometry::hits_type _hits ; - if (geometry::proj_tria_2d(_ppos, + if (geometry::proj_tria_2d(_ppos, &_mesh._set1[ _mesh._set3[ _tpos].node(0)].pval(0) , @@ -387,51 +556,55 @@ else { return ( false ) ; - } + } } - + /* -------------------------------------------------------- * HINT: check for valid index. -------------------------------------------------------- */ - + __inline_call bool_type hint_okay ( hint_type _hint ) - { + { /*------------------------ test whether hint is valid */ return _hint >= (iptr_type)0 - && _hint < (iptr_type) + && _hint < (iptr_type) this->_mesh._set3.count() && this->_mesh. _set3 [_hint].mark() >= 0 ; } - + /* -------------------------------------------------------- * EVAL: eval. size-fun. value. -------------------------------------------------------- */ - + __normal_call real_type eval ( real_type *_ppos , hint_type &_hint ) /*------------------------ find tria + linear interp. */ { - real_type _QPOS[ 2] ; - _QPOS[0] = _ppos[0] ; - _QPOS[1] = _ppos[1] ; + real_type _QPOS[2] = { + (real_type) _ppos[0] , + (real_type) _ppos[1] } ; - real_type _hval = + float _PPOS[2] = { + (float) _ppos[0] , + (float) _ppos[1] } ; + + real_type _hOUT = +std::numeric_limits::infinity() ; - + if (hint_okay(_hint)) { /*------------------------ test whether hint is valid */ - if(!near_pred( _ppos, - _QPOS, _mesh, + if(!near_pred( _ppos, + _QPOS, _mesh, _hint) ) { _hint = this->null_hint(); @@ -446,15 +619,15 @@ if (_hint == this->null_hint()) { /*------------------------ scan to find bounding tria */ - tree_pred _pred (_ppos) ; + tree_pred _pred (_PPOS) ; find_tria _func (_ppos, &_mesh) ; - + this-> _tree.find(_pred, _func) ; - - _hint = _func._find ? - _func._tpos : + + _hint = _func._find ? + _func._tpos : hfun_type::null_hint () ; } @@ -463,13 +636,13 @@ /*------------------------ outside: find nearest tria */ near_tria _func (_ppos, _QPOS,&_mesh) ; - + this-> - _tree.near(_ppos, _func) ; - + _tree.near(_PPOS, _func) ; + _hint = _func._tpos ; } - + if (_hint != this->null_hint()) { /*------------------------ linear interp. within tria */ @@ -488,8 +661,8 @@ _set3[_hint].node(_fnod[1]); _fnod[2] = this->_mesh. _set3[_hint].node(_fnod[2]); - - real_type _tvol = + + real_type _tvol = geometry::tria_area_2d ( &this->_mesh. _set1[_fnod[0]].pval(0) , @@ -497,21 +670,21 @@ _set1[_fnod[1]].pval(0) , _QPOS) ; - _hsum += _tvol * this-> - _mesh._set1[_fnod[2]].hval() ; - + _hsum += _tvol * + this->_hval[_fnod[2]] ; + _vsum += _tvol ; } - _hval = _hsum / _vsum ; + _hOUT = _hsum / _vsum ; } /*------------------------- size-fun interp. to ppos. */ - return _hval ; + return _hOUT ; } - + } ; @@ -519,5 +692,5 @@ # endif //__HFUN_MESH_EUCLIDEAN_2__ - - + + diff --git a/src/libcpp/mesh_func/hfun_mesh_euclidean_3.hpp b/src/libcpp/mesh_func/hfun_mesh_euclidean_3.hpp index 047694d..eeee023 100644 --- a/src/libcpp/mesh_func/hfun_mesh_euclidean_3.hpp +++ b/src/libcpp/mesh_func/hfun_mesh_euclidean_3.hpp @@ -4,34 +4,34 @@ * HFUN-MESH-EUCLIDEAN-kD: unstructured H(X) in R^k. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAengIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 30 April, 2019 + * Last updated: 12 August, 2019 * * Copyright 2013-2019 * Darren Engwirda @@ -53,92 +53,86 @@ typename I , typename A = allocators::basic_alloc > - class hfun_mesh_euclidean_3d - : public hfun_base_kd + class hfun_mesh_euclidean_3d + : public hfun_base_kd { public : - + /*------------------------- euclidean size-fun in R^3 */ - + typedef R real_type ; typedef I iptr_type ; typedef A allocator ; - - typedef typename - allocator::size_type uint_type ; typedef hfun_mesh_euclidean_3d < real_type , iptr_type > hfun_type ; typedef typename hfun_base_kd < - iptr_type , + iptr_type , real_type >::hint_type hint_type ; - class node_type: public tria_complex_node_3 - { - /*------------------------------------ loc. node type */ - public : - real_type _hval ; - - public : - /*------------------------------------ "write" access */ - __inline_call real_type& hval ( - ) - { return this->_hval ; - } - /*------------------------------------ "const" access */ - __inline_call real_type const& hval ( - ) const - { return this->_hval ; - } - - } ; - - typedef tria_complex_edge_2 edge_type ; - typedef tria_complex_tria_3 tri3_type ; - typedef tria_complex_tria_4 tri4_type ; - + typedef containers::array < + real_type , + allocator > real_list ; + + + typedef mesh_complex_node_3 + node_type ; + + typedef mesh_complex_edge_2 edge_type ; + typedef mesh_complex_tria_3 tri3_type ; + typedef mesh_complex_tria_4 tri4_type ; + typedef mesh::tria_complex_3< - node_type, - edge_type, - tri3_type, - tri4_type, - allocator > mesh_type ; + node_type, + edge_type, + tri3_type, + tri4_type, + allocator > mesh_type ; typedef geom_tree::aabb_node_base_k tree_node ; typedef geom_tree::aabb_item_rect_k < - real_type, - iptr_type, - + 3 > tree_item ; - + float, + iptr_type, + + 3 > tree_item ; + typedef geom_tree::aabb_tree< - tree_item, - + 3 , - tree_node, - allocator > tree_type ; - - public : - + tree_item, + + 3 , + tree_node, + allocator > tree_type ; + + typedef geom_tree::aabb_pred_node_3 < + float, + iptr_type > tree_pred ; + + public : + containers:: fixed_array _bmin ; containers:: fixed_array _bmax ; - - mesh_type _mesh ; + mesh_type _mesh ; tree_type _tree ; - + + containers::array< + real_type, allocator > _hval ; + + containers::array< + real_type, allocator > _dhdx ; + public : /* -------------------------------------------------------- * INIT-HFUN: make tree - check signs. -------------------------------------------------------- - */ - + */ + __normal_call void_type init ( ) { @@ -146,28 +140,28 @@ { /*-------------------- TRUE if tree should index tria */ public : - __inline_call + __inline_call bool_type operator () ( tri4_type const& _tdat ) const { return _tdat.mark() >= 0 ; } } ; - + /*----------------------------- init. aabb at -+ inf. */ for(auto _idim = 3; _idim-- != 0 ; ) { - this->_bmin[_idim] = + this->_bmin[_idim] = +std::numeric_limits< real_type>::infinity() ; - - this->_bmax[_idim] = + + this->_bmax[_idim] = -std::numeric_limits< real_type>::infinity() ; } - + /*----------------------------- calc. aabb for inputs */ - for (auto _iter = + for (auto _iter = this->_mesh._set1.head() ; _iter != this->_mesh._set1.tend() ; @@ -176,60 +170,308 @@ if (_iter->mark() >= +0) { this->_bmin[0] = std::min ( - this->_bmin[0] , + this->_bmin[0] , _iter->pval(0) ) ; this->_bmin[1] = std::min ( - this->_bmin[1] , + this->_bmin[1] , _iter->pval(1) ) ; this->_bmin[2] = std::min ( - this->_bmin[2] , + this->_bmin[2] , _iter->pval(2) ) ; - + this->_bmax[0] = std::max ( - this->_bmax[0] , + this->_bmax[0] , _iter->pval(0) ) ; this->_bmax[1] = std::max ( - this->_bmax[1] , + this->_bmax[1] , _iter->pval(1) ) ; this->_bmax[2] = std::max ( - this->_bmax[2] , + this->_bmax[2] , _iter->pval(2) ) ; } } - - real_type static const _RTOL = + + float static const _RTOL = std::pow ( - std::numeric_limits - ::epsilon(),(real_type).8) ; - + std::numeric_limits + ::epsilon(), (float) +0.9) ; + iptr_type static constexpr _NBOX=(iptr_type)+8 ; - real_type _BTOL[3] ; - _BTOL[0] = this->_bmax [ 0 ] - - this->_bmin [ 0 ] ; - _BTOL[1] = this->_bmax [ 1 ] - - this->_bmin [ 1 ] ; - _BTOL[2] = this->_bmax [ 2 ] - - this->_bmin [ 2 ] ; - - _BTOL[0]*=_RTOL ; - _BTOL[1]*=_RTOL ; - _BTOL[2]*=_RTOL ; + float _BTOL[3] ; + _BTOL[0] = + (float) ( this->_bmax[ 0] - + this->_bmin[ 0] ) + * _RTOL ; + _BTOL[1] = + (float) ( this->_bmax[ 1] - + this->_bmin[ 1] ) + * _RTOL ; + _BTOL[2] = + (float) ( this->_bmax[ 2] - + this->_bmin[ 2] ) + * _RTOL ; /*-------------------- make aabb-tree and init. bbox. */ - aabb_mesh( this->_mesh._set1 , - this->_mesh._set4 , + aabb_mesh( this->_mesh._set1 , + this->_mesh._set4 , this->_tree,_BTOL , _NBOX , tria_pred()) ; } - + + /* + -------------------------------------------------------- + * CLIP-HFUN: impose |dh/dx| limits. + -------------------------------------------------------- + */ + + __normal_call void_type clip ( + ) + { + class less_than + { + /*-------------------- "LESS-THAN" operator for queue */ + public : + typename + real_list::_write_it _hptr; + + public : + __inline_call less_than ( + typename + real_list::_write_it _hsrc + ) : _hptr(_hsrc) {} + + __inline_call + bool_type operator() ( + iptr_type _ipos, + iptr_type _jpos + ) + { return *(this->_hptr+_ipos) < + *(this->_hptr+_jpos) ; + } + } ; + + typedef typename + allocator:: size_type uint_type ; + + uint_type static constexpr + _null = + std::numeric_limits::max() ; + + containers::prioritymap < + iptr_type , + less_than , + allocator > + _sort((less_than(this->_hval.head()))); + + containers:: array < + typename + allocator:: size_type, + allocator > _keys; + + containers:: array < + iptr_type , + allocator > _tset; + + /*-------------------- push nodes onto priority queue */ + _keys.set_count ( + _mesh._set1.count(), + containers::tight_alloc, _null) ; + + iptr_type _inum = +0; + for (auto _iter = + this->_mesh._set1.head() ; + _iter != + this->_mesh._set1.tend() ; + ++_iter , ++_inum) + { + if (_iter->mark() >= +0 ) + { + _keys[_inum] = + _sort.push(_inum) ; + } + } + + /*-------------------- compute h(x) via fast-marching */ + for ( ; !_sort.empty() ; ) + { + iptr_type _base ; + _sort._pop_root(_base) ; + + _keys[_base] = _null ; + + _tset.set_count( +0) ; + this-> + _mesh.node_tri4(_base, _tset); + + for (auto _next = _tset.head(); + _next != _tset.tend(); + ++_next ) + { + auto _inod = this-> + _mesh._set4[*_next].node(0); + auto _jnod = this-> + _mesh._set4[*_next].node(1); + auto _knod = this-> + _mesh._set4[*_next].node(2); + auto _lnod = this-> + _mesh._set4[*_next].node(3); + + /*-------------------- skip any cells with null nodes */ + if (_keys[_inod] == _null && + _inod != _base) continue ; + if (_keys[_jnod] == _null && + _jnod != _base) continue ; + if (_keys[_knod] == _null && + _knod != _base) continue ; + if (_keys[_lnod] == _null && + _lnod != _base) continue ; + + if (this->_dhdx.count() >1) + { + /*-------------------- update adj. set, g = g(x) case */ + if (eikonal_tria_3d ( + &this-> + _mesh._set1[ _inod].pval(0), + &this-> + _mesh._set1[ _jnod].pval(0), + &this-> + _mesh._set1[ _knod].pval(0), + &this-> + _mesh._set1[ _lnod].pval(0), + this->_hval[_inod], + this->_hval[_jnod], + this->_hval[_knod], + this->_hval[_lnod], + this->_dhdx[_inod], + this->_dhdx[_jnod], + this->_dhdx[_knod], + this->_dhdx[_lnod]) ) + { + + if (_keys[_inod] != _null) + _sort.update( + _keys[_inod] , _inod) ; + + if (_keys[_jnod] != _null) + _sort.update( + _keys[_jnod] , _jnod) ; + + if (_keys[_knod] != _null) + _sort.update( + _keys[_knod] , _knod) ; + + if (_keys[_lnod] != _null) + _sort.update( + _keys[_lnod] , _lnod) ; + + } + } + else + if (this->_dhdx.count()==1) + { + /*-------------------- update adj. set, const. g case */ + if (eikonal_tria_3d ( + &this-> + _mesh._set1[ _inod].pval(0), + &this-> + _mesh._set1[ _jnod].pval(0), + &this-> + _mesh._set1[ _knod].pval(0), + &this-> + _mesh._set1[ _lnod].pval(0), + this->_hval[_inod], + this->_hval[_jnod], + this->_hval[_knod], + this->_hval[_lnod], + this->_dhdx[ +0 ], + this->_dhdx[ +0 ], + this->_dhdx[ +0 ], + this->_dhdx[ +0 ]) ) + { + + if (_keys[_inod] != _null) + _sort.update( + _keys[_inod] , _inod) ; + + if (_keys[_jnod] != _null) + _sort.update( + _keys[_jnod] , _jnod) ; + + if (_keys[_knod] != _null) + _sort.update( + _keys[_knod] , _knod) ; + + if (_keys[_lnod] != _null) + _sort.update( + _keys[_lnod] , _lnod) ; + + } + } + } + } + + } + /* -------------------------------------------------------- - * NEAR-TRIA: scan for nearest tria. + * FIND-TRIA: scan for nearest tria. -------------------------------------------------------- - */ - + */ + + class find_tria + { + public : + real_type *_ppos ; + + mesh_type *_mesh ; + + bool_type _find ; + iptr_type _tpos ; + + public : + + /*------------------------ make a tree-tria predicate */ + __inline_call find_tria ( + real_type*_psrc = nullptr , + mesh_type*_msrc = nullptr + ) : _ppos(_psrc) , + _mesh(_msrc) , + _find(false) , + _tpos( -1) {} + + /*------------------------ call pred. on tree matches */ + __inline_call + void_type operator () ( + typename + tree_type::item_data *_iptr + ) + { + if (this->_find) return ; + + for ( ; _iptr != nullptr; + _iptr = _iptr->_next) + { + real_type _qtmp[+3]; + iptr_type _TPOS = + _iptr->_data.ipos() ; + + if (near_pred ( _ppos , + _qtmp ,*_mesh , + _TPOS ) ) + { + /*------------------------ is fully inside: finished! */ + this->_find = true ; + this->_tpos = _TPOS ; + + break ; + } + } + } + + } ; + class near_tria { public : @@ -237,14 +479,14 @@ real_type *_qpos ; real_type _dsqr ; - + mesh_type *_mesh ; - + bool_type _find ; iptr_type _tpos ; - + public : - + /*------------------------ make a tree-tria predicate */ __inline_call near_tria ( real_type*_psrc = nullptr , @@ -259,39 +501,42 @@ _tpos( -1) {} /*------------------------ call pred. on tree matches */ - __inline_call - real_type operator () ( - typename + __inline_call float operator () ( + typename tree_type::item_data *_iptr ) { if (this->_find) return +0. ; - - for ( ; _iptr != nullptr; + + for ( ; _iptr != nullptr; _iptr = _iptr->_next) { real_type _qtmp[+3]; - iptr_type _tpos = + iptr_type _TPOS = _iptr->_data.ipos() ; - + if (near_pred ( _ppos , - _qtmp ,*_mesh , - _tpos ) ) + _qtmp ,*_mesh , + _TPOS ) ) { /*------------------------ is fully inside: finished! */ - this->_dsqr = + _qpos[0] = _qtmp[0] ; + _qpos[1] = _qtmp[1] ; + _qpos[2] = _qtmp[2] ; + + this->_dsqr = (real_type) +0. ; this->_find = true ; - this->_tpos = _tpos ; - + this->_tpos = _TPOS ; + break ; } else { /*------------------------ projected match: keep best */ - real_type _dtmp = + real_type _dtmp = geometry::lensqr_3d(_ppos, _qtmp); if (_dtmp<_dsqr ) @@ -301,23 +546,23 @@ _qpos[2] = _qtmp[2] ; this->_dsqr = _dtmp ; - this->_tpos = _tpos ; + this->_tpos = _TPOS ; } } } - return ( this->_dsqr ) ; + return (float) this->_dsqr ; } - + } ; - + /* -------------------------------------------------------- * NEAR-PRED: TRUE if PPOS is in TPOS. -------------------------------------------------------- */ - + __static_call __normal_call bool_type near_pred ( real_type*_ppos , @@ -327,7 +572,7 @@ ) { geometry::hits_type _hits ; - if (geometry::proj_tria_3d(_ppos, + if (geometry::proj_tria_3d(_ppos, &_mesh._set1[ _mesh._set4[ _tpos].node(0)].pval(0) , @@ -348,48 +593,57 @@ else { return ( false ) ; - } + } } - + /* -------------------------------------------------------- * HINT: check for valid index. -------------------------------------------------------- */ - + __inline_call bool_type hint_okay ( hint_type _hint ) - { + { /*------------------------- test whether hint is valid */ return _hint >= (iptr_type)0 - && _hint < (iptr_type) + && _hint < (iptr_type) this->_mesh._set4.count() && this->_mesh. _set4 [_hint].mark() >= 0 ; } - + /* -------------------------------------------------------- * EVAL: eval. size-fun. value. -------------------------------------------------------- */ - + __normal_call real_type eval ( real_type *_ppos , hint_type &_hint ) /*------------------------ find tria + linear interp. */ { - real_type _QPOS[ 3] ; - real_type _hval = + real_type _QPOS[3] = { + (real_type) _ppos[0] , + (real_type) _ppos[1] , + (real_type) _ppos[2] } ; + + float _PPOS[3] = { + (float) _ppos[0] , + (float) _ppos[1] , + (float) _ppos[2] } ; + + real_type _hOUT = +std::numeric_limits::infinity() ; - + if (hint_okay(_hint)) { /*------------------------ test whether hint is valid */ - if(!near_pred( _ppos, - _QPOS, _mesh, + if(!near_pred( _ppos, + _QPOS, _mesh, _hint) ) { _hint = this->null_hint(); @@ -404,21 +658,30 @@ if (_hint == this->null_hint()) { /*------------------------ scan to find bounding tria */ - near_tria _proj (_ppos, - _QPOS,&_mesh) ; - - this->_tree.near(_ppos, - _proj) ; - - _hint = _proj._tpos ; + tree_pred _pred (_PPOS) ; + find_tria _func (_ppos, + &_mesh) ; + + this-> + _tree.find(_pred, _func) ; + + _hint = _func._find ? + _func._tpos : + hfun_type::null_hint () ; } - else + + if (_hint == this->null_hint()) { - _QPOS[0] = _ppos[0] ; - _QPOS[1] = _ppos[1] ; - _QPOS[2] = _ppos[2] ; + /*------------------------ outside: find nearest tria */ + near_tria _func (_ppos, + _QPOS,&_mesh) ; + + this-> + _tree.near(_PPOS, _func) ; + + _hint = _func._tpos ; } - + if (_hint != this->null_hint()) { /*------------------------ linear interp. within tria */ @@ -439,8 +702,8 @@ _set4[_hint].node(_fnod[2]); _fnod[3] = this->_mesh. _set4[_hint].node(_fnod[3]); - - real_type _tvol = + + real_type _tvol = geometry::tetra_vol_3d ( &this->_mesh. _set1[_fnod[0]].pval(0) , @@ -450,21 +713,21 @@ _set1[_fnod[2]].pval(0) , _QPOS) ; - _hsum += _tvol * this-> - _mesh._set1[_fnod[3]].hval() ; - + _hsum += _tvol * + this->_hval[_fnod[3]] ; + _vsum += _tvol ; } - _hval = _hsum / _vsum ; + _hOUT = _hsum / _vsum ; } /*------------------------- size-fun interp. to ppos. */ - return _hval ; + return _hOUT ; } - + } ; @@ -472,5 +735,5 @@ # endif //__HFUN_MESH_EUCLIDEAN_3__ - - + + diff --git a/src/libcpp/mesh_type/mesh_alchemy_1.hpp b/src/libcpp/mesh_type/mesh_alchemy_1.hpp deleted file mode 100644 index a60ea7c..0000000 --- a/src/libcpp/mesh_type/mesh_alchemy_1.hpp +++ /dev/null @@ -1,45 +0,0 @@ - - /* - -------------------------------------------------------- - * MESH-ALCHEMY-1: transform 1-dim. mesh cell types. - -------------------------------------------------------- - * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) - * - * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The - * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be - * used at your own risk. - * - -------------------------------------------------------- - * - * Last updated: 20 August, 2018 - * - * Copyright 2013-2018 - * Darren Engwirda - * de2363@columbia.edu - * https://github.com/dengwirda/ - * - -------------------------------------------------------- - */ - - - diff --git a/src/libcpp/mesh_type/mesh_alchemy_2.hpp b/src/libcpp/mesh_type/mesh_alchemy_2.hpp deleted file mode 100644 index de7c654..0000000 --- a/src/libcpp/mesh_type/mesh_alchemy_2.hpp +++ /dev/null @@ -1,95 +0,0 @@ - - /* - -------------------------------------------------------- - * MESH-ALCHEMY-2: transform 2-dim. mesh cell types. - -------------------------------------------------------- - * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) - * - * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The - * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be - * used at your own risk. - * - -------------------------------------------------------- - * - * Last updated: 20 August, 2018 - * - * Copyright 2013-2018 - * Darren Engwirda - * de2363@columbia.edu - * https://github.com/dengwirda/ - * - -------------------------------------------------------- - */ - - - template < - typename T - > - class pair_mesh_2 - { - public : - typedef T tria_type ; - - typedef typename - tria_type::real_type real_type ; - typedef typename - tria_type::iptr_type iptr_type ; - - - __static_call - __normal_call void_type pair_mesh ( - tria_type &_tria - ) - { - - // match_graph<> - - for (auto _epos = _tria._set2.head() ; - _epos != _tria._set2.tend() ; - ++_epos ) - { - if (_epos->mark() >= +0) - { - _tset.set_count(0); - _mesh.edge_tri3( - &_epos->node(0), _tset) ; - - if (_tset.count() == +2) - { - - //form_quad - - } - } - } - - - // match graph - - - } - - } ; - - - diff --git a/src/libcpp/mesh_type/mesh_alchemy_3.hpp b/src/libcpp/mesh_type/mesh_alchemy_3.hpp deleted file mode 100644 index d65d944..0000000 --- a/src/libcpp/mesh_type/mesh_alchemy_3.hpp +++ /dev/null @@ -1,45 +0,0 @@ - - /* - -------------------------------------------------------- - * MESH-ALCHEMY-3: transform 3-dim. mesh cell types. - -------------------------------------------------------- - * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) - * - * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The - * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be - * used at your own risk. - * - -------------------------------------------------------- - * - * Last updated: 20 August, 2018 - * - * Copyright 2013-2018 - * Darren Engwirda - * de2363@columbia.edu - * https://github.com/dengwirda/ - * - -------------------------------------------------------- - */ - - - diff --git a/src/libcpp/mesh_type/mesh_complex_3.hpp b/src/libcpp/mesh_type/mesh_complex_3.hpp new file mode 100644 index 0000000..d08871e --- /dev/null +++ b/src/libcpp/mesh_type/mesh_complex_3.hpp @@ -0,0 +1,2356 @@ + + /* + -------------------------------------------------------- + * MESH-COMPLEX-3: piecewise mixed complex in R^3. + -------------------------------------------------------- + * + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) + * + * Disclaimer: Neither I nor: Columbia University, The + * Massachusetts Institute of Technology, The + * University of Sydney, nor The National Aeronautics + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be + * used at your own risk. + * + -------------------------------------------------------- + * + * Last updated: 09 November, 2019 + * + * Copyright 2013-2019 + * Darren Engwirda + * de2363@columbia.edu + * https://github.com/dengwirda/ + * + -------------------------------------------------------- + */ + +# pragma once + +# ifndef __MESH_COMPLEX_3__ +# define __MESH_COMPLEX_3__ + + namespace mesh { + + /* + -------------------------------------------------------- + * MESH-COMPLEX-3 generic mixed-cell 3-complex. + -------------------------------------------------------- + * NODE-TYPE - 0-face type + coord.'s + * EDGE-TYPE - 1-face type + * TRI3-TYPE - 2-face type + * QUAD-TYPE - 2-face type + * TRI4-TYPE - 3-face type + * HEXA-TYPE - 3-face type + * PYRA-TYPE - 3-face type + * WEDG-TYPE - 3-face type + * ALLOCATOR - memory allocator + -------------------------------------------------------- + */ + + template < + typename NN , + typename E2 , + typename T3 , + typename Q4 , + typename T4 , + typename H8 , + typename P5 , + typename W6 , + typename AA = allocators::basic_alloc + > + class mesh_complex_3 + { +/*----------------------------------- mesh-complex in R^3 */ + public : + typedef NN node_type ; + typedef E2 edge_type ; + typedef T3 tri3_type ; + typedef Q4 quad_type ; + typedef T4 tri4_type ; + typedef H8 hexa_type ; + typedef P5 pyra_type ; + typedef W6 wedg_type ; + typedef AA allocator ; + + typedef typename + node_type::real_type real_type ; + typedef typename + edge_type::iptr_type iptr_type ; + typedef typename + allocator::size_type size_type ; + + iptr_type static constexpr _dims = +3 ; + + typedef containers::block_array < + node_type, + allocator > node_list ; + + typedef containers::block_array < + edge_type, + allocator > edge_list ; + + typedef containers::block_array < + tri3_type, + allocator > tri3_list ; + + typedef containers::block_array < + quad_type, + allocator > quad_list ; + + typedef containers::block_array < + tri4_type, + allocator > tri4_list ; + + typedef containers::block_array < + hexa_type, + allocator > hexa_list ; + + typedef containers::block_array < + pyra_type, + allocator > pyra_list ; + + typedef containers::block_array < + wedg_type, + allocator > wedg_list ; + + typedef containers::array < + iptr_type, + allocator > iptr_list ; + + #define __hashscal sizeof(iptr_type)/sizeof(uint32_t) + + class node_hash + { + public : + __const_ptr(node_list) _nset ; + public : + /*----------------------- build hash _obj. from _src. */ + __inline_call node_hash ( + node_list *_nsrc + ) : _nset( _nsrc) {} + /*----------------------- hash node indexing for node */ + __inline_call + uint32_t operator() ( + iptr_type _npos + ) const + { + return this->_nset-> + operator[](_npos).node( 0) ; + } + } ; + + class edge_hash + { + public : + __const_ptr(edge_list) _eset ; + public : + /*----------------------- build hash _obj. from _src. */ + __inline_call edge_hash ( + edge_list *_esrc + ) : _eset( _esrc) {} + /*----------------------- hash node indexing for edge */ + __inline_call + uint32_t operator() ( + iptr_type _epos + ) const + { + iptr_type _enod[2]; + _enod[0] = this->_eset-> + operator[](_epos).node( 0) ; + _enod[1] = this->_eset-> + operator[](_epos).node( 1) ; + + algorithms::isort ( + &_enod[0], &_enod[2] , + std::less()); + + return hash::hashword ( + (uint32_t*)&_enod[0] , + +2 * __hashscal, +137) ; + } + } ; + + class tri3_hash + { + public : + __const_ptr(tri3_list) _tset ; + public : + /*----------------------- build hash _obj. from _src. */ + __inline_call tri3_hash ( + tri3_list *_tsrc + ) : _tset( _tsrc) {} + /*----------------------- hash node indexing for face */ + __inline_call + uint32_t operator() ( + iptr_type _tpos + ) const + { + iptr_type _tnod[3]; + _tnod[0] = this->_tset-> + operator[](_tpos).node( 0) ; + _tnod[1] = this->_tset-> + operator[](_tpos).node( 1) ; + _tnod[2] = this->_tset-> + operator[](_tpos).node( 2) ; + + algorithms::isort ( + &_tnod[0], &_tnod[3] , + std::less()); + + return hash::hashword ( + (uint32_t*)&_tnod[0] , + +3 * __hashscal, +137) ; + } + } ; + + class tri4_hash + { + public : + __const_ptr(tri4_list) _tset ; + public : + /*----------------------- build hash _obj. from _src. */ + __inline_call tri4_hash ( + tri4_list *_tsrc + ) : _tset( _tsrc) {} + /*----------------------- hash node indexing for face */ + __inline_call + uint32_t operator() ( + iptr_type _tpos + ) const + { + iptr_type _tnod[4]; + _tnod[0] = this->_tset-> + operator[](_tpos).node( 0) ; + _tnod[1] = this->_tset-> + operator[](_tpos).node( 1) ; + _tnod[2] = this->_tset-> + operator[](_tpos).node( 2) ; + _tnod[3] = this->_tset-> + operator[](_tpos).node( 3) ; + + algorithms::isort ( + &_tnod[0], &_tnod[4] , + std::less()); + + return hash::hashword ( + (uint32_t*)&_tnod[0] , + +4 * __hashscal, +137) ; + } + } ; + + + class node_pred + { + public : + __const_ptr(node_list) _nset ; + public : + /*----------------------- build hash _obj. from _src. */ + __inline_call node_pred ( + node_list *_nsrc + ) : _nset( _nsrc) {} + /*----------------------- compute "equal-to" for node */ + __inline_call + bool_type operator() ( + iptr_type _ipos, + iptr_type _jpos + ) const + { + iptr_type _inod[1]; + _inod[0] = this->_nset-> + operator[](_ipos).node( 0) ; + + iptr_type _jnod[1]; + _jnod[0] = this->_nset-> + operator[](_jpos).node( 0) ; + + return _inod[0] == _jnod[0] ; + } + } ; + + class edge_pred + { + public : + __const_ptr(edge_list) _eset ; + public : + /*----------------------- build hash _obj. from _src. */ + __inline_call edge_pred ( + edge_list *_esrc + ) : _eset( _esrc) {} + /*----------------------- compute "equal-to" for edge */ + __inline_call + bool_type operator() ( + iptr_type _ipos, + iptr_type _jpos + ) const + { + iptr_type _inod[2]; + _inod[0] = this->_eset-> + operator[](_ipos).node( 0) ; + _inod[1] = this->_eset-> + operator[](_ipos).node( 1) ; + + iptr_type _jnod[2]; + _jnod[0] = this->_eset-> + operator[](_jpos).node( 0) ; + _jnod[1] = this->_eset-> + operator[](_jpos).node( 1) ; + + algorithms::isort ( + &_inod[0], &_inod[2], + std::less()); + + algorithms::isort ( + &_jnod[0], &_jnod[2], + std::less()); + + return _inod[0] == _jnod[0] && + _inod[1] == _jnod[1] ; + } + } ; + + class tri3_pred + { + public : + __const_ptr(tri3_list) _tset ; + public : + /*----------------------- build hash _obj. from _src. */ + __inline_call tri3_pred ( + tri3_list *_tsrc + ) : _tset( _tsrc) {} + /*----------------------- compute "equal-to" for face */ + __inline_call + bool_type operator() ( + iptr_type _ipos, + iptr_type _jpos + ) const + { + iptr_type _inod[3]; + _inod[0] = this->_tset-> + operator[](_ipos).node( 0) ; + _inod[1] = this->_tset-> + operator[](_ipos).node( 1) ; + _inod[2] = this->_tset-> + operator[](_ipos).node( 2) ; + + iptr_type _jnod[3]; + _jnod[0] = this->_tset-> + operator[](_jpos).node( 0) ; + _jnod[1] = this->_tset-> + operator[](_jpos).node( 1) ; + _jnod[2] = this->_tset-> + operator[](_jpos).node( 2) ; + + algorithms::isort ( + &_inod[0], &_inod[3], + std::less()); + + algorithms::isort ( + &_jnod[0], &_jnod[3], + std::less()); + + return _inod[0] == _jnod[0] && + _inod[1] == _jnod[1] && + _inod[2] == _jnod[2] ; + } + } ; + + class tri4_pred + { + public : + __const_ptr(tri4_list) _tset ; + public : + /*----------------------- build hash _obj. from _src. */ + __inline_call tri4_pred ( + tri4_list *_tsrc + ) : _tset( _tsrc) {} + /*----------------------- compute "equal-to" for face */ + __inline_call + bool_type operator() ( + iptr_type _ipos, + iptr_type _jpos + ) const + { + iptr_type _inod[4]; + _inod[0] = this->_tset-> + operator[](_ipos).node( 0) ; + _inod[1] = this->_tset-> + operator[](_ipos).node( 1) ; + _inod[2] = this->_tset-> + operator[](_ipos).node( 2) ; + _inod[3] = this->_tset-> + operator[](_ipos).node( 3) ; + + iptr_type _jnod[4]; + _jnod[0] = this->_tset-> + operator[](_jpos).node( 0) ; + _jnod[1] = this->_tset-> + operator[](_jpos).node( 1) ; + _jnod[2] = this->_tset-> + operator[](_jpos).node( 2) ; + _jnod[3] = this->_tset-> + operator[](_jpos).node( 3) ; + + algorithms::isort ( + &_inod[0], &_inod[4], + std::less()); + + algorithms::isort ( + &_jnod[0], &_jnod[4], + std::less()); + + return _inod[0] == _jnod[0] && + _inod[1] == _jnod[1] && + _inod[2] == _jnod[2] && + _inod[3] == _jnod[3] ; + } + } ; + + #undef __hashscal + + iptr_type static const pool_byte_size=96*1024 ; + + typedef allocators::_pool_alloc < + allocators::basic_alloc , + pool_byte_size > pool_base ; + + typedef allocators::_wrap_alloc < + pool_base > pool_wrap ; + + //typedef containers::hash_table < + // iptr_type, + // node_hash, + // node_pred, + // pool_wrap> node_maps ; + + typedef containers::hash_table < + iptr_type, + edge_hash, + edge_pred, + pool_wrap> edge_maps ; + + typedef containers::hash_table < + iptr_type, + tri3_hash, + tri3_pred, + pool_wrap> tri3_maps ; + + typedef containers::hash_table < + iptr_type, + tri4_hash, + tri4_pred, + pool_wrap> tri4_maps ; + + typedef containers::array_list < + iptr_type, + pool_wrap > conn_list ; + + public : + + pool_base _hsrc ; + pool_base _csrc ; + + conn_list _N1E2 ; + conn_list _E2T3 ; + conn_list _E2Q4 ; + conn_list _T3T4 ; + conn_list _T3P5 ; + conn_list _T3W6 ; + conn_list _adj4 ; + + //node_maps _mmN1 ; + edge_maps _mmE2 ; + tri3_maps _mmT3 ; + quad_maps _mmQ4 ; + tri4_maps _mmT4 ; + hexa_maps _mmH8 ; + pyra_maps _mmP5 ; + wedg_maps _mmW6 ; + + node_list _llN1 ; + edge_list _llE2 ; + tri3_list _llT3 ; + quad_list _llQ4 ; + tri4_list _llT4 ; + hexa_list _llH8 ; + pyra_list _llP5 ; + wedg_list _llW6 ; + + iptr_list _del1 ; + iptr_list _del2 ; + iptr_list _del3 ; + iptr_list _del4 ; + + iptr_list _tmp1 ; + iptr_list _tmp2 ; + iptr_list _tmp3 ; + iptr_list _tmp4 ; + + public : + + /* + -------------------------------------------------------- + * GET-NODE: "create" new node, push onto active set. + -------------------------------------------------------- + */ + + __inline_call iptr_type _get_node ( + ) + { + iptr_type _ipos = -1; + if (this->_del1.count() != +0 ) + { + /*---------------------------- recycle from free list */ + this->_del1._pop_tail(_ipos) ; + } + else + { + /*---------------------------- alloc. from underlying */ + _ipos = (iptr_type) + this->_set1.count() ; + this->_set1.push_tail() ; + } + + this->_set1[_ipos].mark() = +0 ; + this->_set1[_ipos].self() = +0 ; + + return ( _ipos ) ; + } + + /* + -------------------------------------------------------- + * GET-EDGE: "create" new edge, push onto active set. + -------------------------------------------------------- + */ + + __inline_call iptr_type _get_edge ( + ) + { + iptr_type _ipos = -1; + if (this->_del2.count() != +0 ) + { + /*---------------------------- recycle from free list */ + this->_del2._pop_tail(_ipos) ; + } + else + { + /*---------------------------- alloc. from underlying */ + _ipos = (iptr_type) + this->_set2.count() ; + this->_set2.push_tail() ; + } + + this->_set2[_ipos].mark() = +0 ; + this->_set2[_ipos].self() = +0 ; + + return ( _ipos ) ; + } + + /* + -------------------------------------------------------- + * GET-TRIA: "create" new tria, push onto active set. + -------------------------------------------------------- + */ + + __inline_call iptr_type _get_tri3 ( + ) + { + iptr_type _ipos = -1; + if (this->_del3.count() != +0 ) + { + /*---------------------------- recycle from free list */ + this->_del3._pop_tail(_ipos) ; + } + else + { + /*---------------------------- alloc. from underlying */ + _ipos = (iptr_type) + this->_set3.count() ; + this->_set3.push_tail() ; + } + + this->_set3[_ipos].mark() = +0 ; + this->_set3[_ipos].self() = +0 ; + + return ( _ipos ) ; + } + + /* + -------------------------------------------------------- + * GET-TRIA: "create" new tria, push onto active set. + -------------------------------------------------------- + */ + + __inline_call iptr_type _get_tri4 ( + ) + { + iptr_type _ipos = -1; + if (this->_del4.count() != +0 ) + { + /*---------------------------- recycle from free list */ + this->_del4._pop_tail(_ipos) ; + } + else + { + /*---------------------------- alloc. from underlying */ + _ipos = (iptr_type) + this->_set4.count() ; + this->_set4.push_tail() ; + } + + this->_set4[_ipos].mark() = +0 ; + this->_set4[_ipos].self() = +0 ; + + return ( _ipos ) ; + } + + /* + -------------------------------------------------------- + * PUT-ITEM: "delete" old item, _pop from active set. + -------------------------------------------------------- + */ + + __inline_call void_type _put_node ( + iptr_type _ipos + ) + { + this->_del1.push_tail (_ipos); + this->_set1[_ipos].mark() = -1 ; + this->_set1[_ipos].self() = -1 ; + } + + __inline_call void_type _put_edge ( + iptr_type _ipos + ) + { + this->_del2.push_tail (_ipos); + this->_set2[_ipos].mark() = -1 ; + this->_set2[_ipos].self() = -1 ; + } + + __inline_call void_type _put_tri3 ( + iptr_type _ipos + ) + { + this->_del3.push_tail (_ipos); + this->_set3[_ipos].mark() = -1 ; + this->_set3[_ipos].self() = -1 ; + } + + __inline_call void_type _put_tri4 ( + iptr_type _ipos + ) + { + this->_del4.push_tail (_ipos); + this->_set4[_ipos].mark() = -1 ; + this->_set4[_ipos].self() = -1 ; + } + + public : + + /* + -------------------------------------------------------- + * construct tria_complex from alloc. etc... + -------------------------------------------------------- + */ + + __normal_call tria_complex_3 ( + allocator const& _asrc = allocator() + ) : _hsrc(sizeof ( + typename tri4_maps::item_type)), + _csrc(sizeof ( + typename conn_list::item_type)), + /*------------------------------ init. adj. lists */ + _adj1(pool_wrap(&_csrc)), + _adj2(pool_wrap(&_csrc)), + _adj3(pool_wrap(&_csrc)), + _adj4(pool_wrap(&_csrc)), + /*------------------------------ init. hash lists */ + //_map1( + // node_hash(& this->_set1) , + // node_pred(& this->_set1) , + //+.8, (pool_wrap(&_hsrc))) , + _map2( + edge_hash(& this->_set2) , + edge_pred(& this->_set2) , + +.8, (pool_wrap(&_hsrc))) , + _map3( + tri3_hash(& this->_set3) , + tri3_pred(& this->_set3) , + +.8, (pool_wrap(&_hsrc))) , + _map4( + tri4_hash(& this->_set4) , + tri4_pred(& this->_set4) , + +.8, (pool_wrap(&_hsrc))) , + /*------------------------------ init. face lists */ + _set1(_asrc),_set2(_asrc) , + _set3(_asrc),_set4(_asrc) , + /*------------------------------ init. free lists */ + _del1(_asrc),_del2(_asrc) , + _del3(_asrc),_del4(_asrc) , + /*------------------------------ init. work lists */ + _tmp1(_asrc),_tmp2(_asrc) , + _tmp3(_asrc),_tmp4(_asrc) + { + } + + /* + -------------------------------------------------------- + * 'clear' a tria-complex + -------------------------------------------------------- + */ + + __normal_call void_type clear ( + containers::alloc_types _kind = + containers::loose_alloc + ) + { + this->_adj1.clear (_kind) ; + this->_adj2.clear (_kind) ; + this->_adj3.clear (_kind) ; + this->_adj4.clear (_kind) ; + + //this->_map1.clear (_kind) ; + this->_map2.clear (_kind) ; + this->_map3.clear (_kind) ; + this->_map4.clear (_kind) ; + + this->_set1.clear (_kind) ; + this->_set2.clear (_kind) ; + this->_set3.clear (_kind) ; + this->_set4.clear (_kind) ; + + this->_del1.clear (_kind) ; + this->_del2.clear (_kind) ; + this->_del3.clear (_kind) ; + this->_del4.clear (_kind) ; + + this->_tmp1.clear (_kind) ; + this->_tmp2.clear (_kind) ; + this->_tmp3.clear (_kind) ; + this->_tmp4.clear (_kind) ; + + this->_hsrc.clear (); + this->_csrc.clear (); + } + + /* + -------------------------------------------------------- + * INIT-LIST: re-size adj. lists on demand. + -------------------------------------------------------- + */ + + __inline_call void_type init_list ( + conn_list&_list, + size_type _lpos + ) + { + if (_lpos >= _list._lptr.count()) + _list._lptr.set_count ( + _lpos + 1, + containers::loose_alloc, nullptr) ; + } + + /* + -------------------------------------------------------- + * PUSH-NODE: append new 0-node to complex. + -------------------------------------------------------- + */ + + __normal_call iptr_type push_node ( + node_type const& _ndat, + bool_type _link = true, + iptr_type _itop = -1 + ) + { + iptr_type _ipos = -1 ; + + if (!_link) + { + + __assert( _itop == -1 && + "tria-complex: non-top node!" ) ; + + /*------------------------ init. external d-face data */ + _ipos = _get_node(); + + this->_set1[_ipos] = _ndat ; + this->_set1[_ipos].mark() = 0 ; + + this->_set1[_ipos].self() = 1 ; + this-> + _set1 [_ipos].node(0) =_ipos ; + + /*------------------------ init. local adj. index set */ + init_list(this->_adj1, _ipos) ; + + } + else + { + + if (_itop == -1) + { + /*------------------------ init. external d-face data */ + _ipos = _get_node(); + + this->_set1[_ipos] = _ndat ; + this->_set1[_ipos].mark() = 0 ; + this->_set1[_ipos].self() = 1 ; + + this-> + _set1 [_ipos].node(0) = _ipos; + + /*------------------------ init. local adj. index set */ + init_list(this->_adj1, _ipos) ; + + } + else + { + /*------------------------ init. internal d-face data */ + __assert(find_node( + &_ndat.node(0), _ipos) && + "tria-complex: node not here" ); + + /*------------------------ append index to adj. lists */ + this->_adj1.push( + _itop, _ndat.node(0)) ; + + } + + } + + return _ipos ; + } + + /* + -------------------------------------------------------- + * PUSH-EDGE: append new 1-edge to complex. + -------------------------------------------------------- + */ + + __normal_call iptr_type push_edge ( + edge_type const& _edat, + bool_type _link = true, + iptr_type _itop = -1 + ) + { + iptr_type _ipos = _get_edge() ; + iptr_type _npos ; + + if (!_link) + { + + __assert( _itop == -1 && + "tria-complex: non-top cell!" ) ; + + /*------------------------ init. external d-face data */ + this->_set2[_ipos] = _edat ; + this->_set2[_ipos].mark() = 0 ; + this->_set2[_ipos].self() = 1 ; + + /*------------------------ init. local adj. index set */ + init_list(this->_adj2, _ipos) ; + + } + else + { + + /*------------------------ init. external d-face data */ + this->_set2[_ipos] = _edat ; + this->_set2[_ipos].mark() = 0 ; + + if (_itop == -1) + this->_set2[_ipos].self() = 1 ; + else + this->_set2[_ipos].self() = 0 ; + + typename + edge_maps::_write_it _same ; + if (this-> + _map2.find(_ipos , _same)) + { + /*---- existing d-face found: append to existing data */ + if (_itop == -1) + { + /*----- if it's a "top"-level face, copy data */ + this->_set2[*_same] = + this->_set2[ _ipos] ; + } + else + { + /*----- otherwise, append index to adj. lists */ + this-> + _adj2.push(_itop,*_same) ; + } + + _put_edge(_ipos) ; + } + else + { + /*---- d-face is new: push and descend to (d-1)-faces */ + if (_itop == -1) + { + /*----- if it's a "top"-level face, keep data */ + init_list( + this->_adj2, _ipos) ; + } + else + { + /*----- otherwise, append index to adj. lists */ + this-> + _adj2.push(_itop, _ipos) ; + } + + /*-------------- descend into (d-1)-face data */ + for (_npos = 2; _npos-- != 0; ) + { + node_type _ndat; + _ndat.node(0) = + _edat.node(_npos) ; + + push_node( + _ndat, _link, _ipos) ; + } + + /*-------------- push new face data onto hash */ + this->_map2.push(_ipos) ; + } + + } + + return _ipos ; + } + + /* + -------------------------------------------------------- + * PUSH-TRIA: append new 2-tria to complex. + -------------------------------------------------------- + */ + + __normal_call iptr_type push_tri3 ( + tri3_type const& _tdat, + bool_type _link = true, + iptr_type _itop = -1 + ) + { + iptr_type _ipos = _get_tri3() ; + iptr_type _epos ; + + if (!_link) + { + + __assert( _itop == -1 && + "tria-complex: non-top cell!" ) ; + + /*-------------------- init. external d-face data */ + this->_set3[_ipos] = _tdat ; + this->_set3[_ipos].mark() = 0 ; + this->_set3[_ipos].self() = 1 ; + + /*-------------------- init. local adj. index set */ + init_list(this->_adj3, _ipos) ; + + } + else + { + + /*------------------------ init. external d-face data */ + this->_set3[_ipos] = _tdat ; + this->_set3[_ipos].mark() = 0 ; + + if (_itop == -1) + this->_set3[_ipos].self() = 1 ; + else + this->_set3[_ipos].self() = 0 ; + + typename + tri3_maps::_write_it _same ; + if (this-> + _map3.find(_ipos , _same)) + { + /*---- existing d-face found: append to existing data */ + if (_itop == -1) + { + /*----- if it's a "top"-level face, copy data */ + this->_set3[*_same] = + this->_set3[ _ipos] ; + } + else + { + /*----- otherwise, append index to adj. lists */ + this-> + _adj3.push(_itop,*_same) ; + } + + _put_tri3(_ipos) ; + } + else + { + /*---- d-face is new: push and descend to (d-1)-faces */ + if (_itop == -1) + { + /*----- if it's a "top"-level face, keep data */ + init_list( + this->_adj3, _ipos) ; + } + else + { + /*----- otherwise, append index to adj. lists */ + this-> + _adj3.push(_itop, _ipos) ; + } + + /*-------------- descend into (d-1)-face data */ + for (_epos = +3; _epos-- != 0 ; ) + { + iptr_type _enod [3]; + tri3_type::face_node( + _enod, _epos, 2, 1) ; + + edge_type _edat ; + _edat.node(0) = + _tdat.node(_enod[0]) ; + _edat.node(1) = + _tdat.node(_enod[1]) ; + + push_edge( + _edat, _link, _ipos) ; + } + + /*-------------- push new face data onto hash */ + this->_map3.push(_ipos) ; + } + + } + + return _ipos ; + } + + /* + -------------------------------------------------------- + * PUSH-TRIA: append new 3-tria to complex. + -------------------------------------------------------- + */ + + __normal_call iptr_type push_tri4 ( + tri4_type const& _tdat, + bool_type _link = true, + iptr_type _itop = -1 + ) + { + iptr_type _ipos = _get_tri4() ; + iptr_type _fpos ; + + if (!_link) + { + + __assert( _itop == -1 && + "tria-complex: non-top cell!" ) ; + + /*------------------------ init. external d-face data */ + this->_set4[_ipos] = _tdat ; + this->_set4[_ipos].mark() = 0 ; + this->_set4[_ipos].self() = 1 ; + + /*------------------------ init. local adj. index set */ + init_list(this->_adj4, _ipos) ; + + } + else + { + + /*------------------------ init. external d-face data */ + this->_set4[_ipos] = _tdat ; + this->_set4[_ipos].mark() = 0 ; + + if (_itop == -1) + this->_set4[_ipos].self() = 1 ; + else + this->_set4[_ipos].self() = 0 ; + + typename + tri4_maps::_write_it _same ; + if (this-> + _map4.find(_ipos , _same)) + { + /*---- existing d-face found: append to existing data */ + if (_itop == -1) + { + /*----- if it's a "top"-level face, copy data */ + this->_set4[*_same] = + this->_set4[ _ipos] ; + } + else + { + /*----- otherwise, append index to adj. lists */ + this-> + _adj4.push(_itop,*_same) ; + } + + _put_tri4(_ipos) ; + } + else + { + /*---- d-face is new: push and descend to (d-1)-faces */ + if (_itop == -1) + { + /*----- if it's a "top"-level face, keep data */ + init_list( + this->_adj4, _ipos) ; + } + else + { + /*----- otherwise, append index to adj. lists */ + this-> + _adj4.push(_itop, _ipos) ; + } + + /*-------------- descend into (d-1)-face data */ + for (_fpos = +4; _fpos-- != 0 ; ) + { + iptr_type _fnod [4]; + tri4_type::face_node( + _fnod, _fpos, 3, 2) ; + + tri3_type _fdat ; + _fdat.node(0) = + _tdat.node(_fnod[0]) ; + _fdat.node(1) = + _tdat.node(_fnod[1]) ; + _fdat.node(2) = + _tdat.node(_fnod[2]) ; + + push_tri3( + _fdat, _link, _ipos) ; + } + + /*-------------- push new face data onto hash */ + this->_map4.push(_ipos) ; + } + + } + + return _ipos ; + } + + /* + -------------------------------------------------------- + * MAKE-LINK: build item-to-item adj. + -------------------------------------------------------- + */ + + __normal_call void_type make_link ( + ) + { + this->_map2.set_slots( + (this->_set2.count()*5)/4 + 1 + + (this->_set3.count()*5)/2 + 1 + + (this->_set4.count()*3)/2 + 1 + ) ; + + this->_map3.set_slots( + (this->_set3.count()*5)/4 + 1 + + (this->_set4.count()*5)/2 + 1 + ) ; + + this->_map4.set_slots( + (this->_set4.count()*5)/4 + 1 + ) ; + + this->_adj1.empty () ; + this->_adj2.empty () ; + this->_adj3.empty () ; + this->_adj4.empty () ; + + iptr_type _epos = +0 ; + for (auto _iter = this->_set2.head(); + _iter != this->_set2.tend(); + ++_iter, ++_epos ) + { + /*-------------- push face data onto hash set */ + this->_map2.push(_epos) ; + + /*-------------- descend into (d-1)-face data */ + iptr_type _ipos; + for (_ipos = +2; _ipos-- != 0; ) + { + node_type _ndat; + _ndat.node(0) = + _iter->node( _ipos) ; + + push_node( + _ndat, true, _epos) ; + } + } + + iptr_type _fpos = +0 ; + for (auto _iter = this->_set3.head(); + _iter != this->_set3.tend(); + ++_iter, ++_fpos ) + { + /*-------------- push face data onto hash set */ + this->_map3.push(_fpos) ; + + /*-------------- descend into (d-1)-face data */ + iptr_type _ipos; + for (_ipos = +3; _ipos-- != 0; ) + { + iptr_type _enod [3]; + tri3_type::face_node( + _enod, _ipos, 2, 1 ) ; + + edge_type _edat ; + _edat.node(0) = + _iter->node(_enod[0]) ; + _edat.node(1) = + _iter->node(_enod[1]) ; + + push_edge( + _edat, true , _fpos) ; + } + } + + iptr_type _tpos = +0 ; + for (auto _iter = this->_set4.head(); + _iter != this->_set4.tend(); + ++_iter, ++_tpos ) + { + /*-------------- push face data onto hash set */ + this->_map4.push(_tpos) ; + + /*-------------- descend into (d-1)-face data */ + iptr_type _ipos; + for (_ipos = +4; _ipos-- != 0; ) + { + iptr_type _fnod [4]; + tri4_type::face_node( + _fnod, _ipos, 3, 2 ) ; + + tri3_type _fdat ; + _fdat.node(0) = + _iter->node(_fnod[0]) ; + _fdat.node(1) = + _iter->node(_fnod[1]) ; + _fdat.node(2) = + _iter->node(_fnod[2]) ; + + push_tri3( + _fdat, true , _tpos) ; + } + } + } + + /* + -------------------------------------------------------- + * NULL-ITEM: TRUE if item is delete-able. + -------------------------------------------------------- + */ + + __inline_call bool_type null_node ( + iptr_type _npos + ) const + { + return this->_set1[_npos].self()==0 + && this->_adj1.empty(_npos); + } + + __inline_call bool_type null_edge ( + iptr_type _epos + ) const + { + return this->_set2[_epos].self()==0 + && this->_adj2.empty(_epos); + } + + __inline_call bool_type null_tri3 ( + iptr_type _tpos + ) const + { + return this->_set3[_tpos].self()==0 + && this->_adj3.empty(_tpos); + } + + __inline_call bool_type null_tri4 ( + iptr_type _tpos + ) const + { + return this->_set4[_tpos].self()==0 + && this->_adj4.empty(_tpos); + } + + /* + -------------------------------------------------------- + * _POP-LIST: delete item from adj. list. + -------------------------------------------------------- + */ + + __normal_call void_type _pop_list ( + conn_list &_list, + iptr_type _lpos, + iptr_type _itop + ) + { + /*--------------------------- scan list and pop match */ + typename conn_list::_write_it + _prev = _list.hend(_lpos), + _iter = _list.head(_lpos), + _tend = _list.tend(_lpos); + + for ( ; _iter != _tend; + _prev = _iter, ++_iter) + { + if(*_iter == _itop) + { + _list._pop ( + _prev, _iter, _lpos) ; + + break ; + } + } + } + + /* + -------------------------------------------------------- + * _POP-NODE: delete 0-node from complex. + -------------------------------------------------------- + */ + + __normal_call void_type _pop_node ( + iptr_type const*_nptr, + iptr_type _itop = -1 + ) + { + iptr_type _npos = -1 ; + + iptr_type _node[1]; + _node[0] = _nptr[0]; + + /*-------------------------- find current 0-node pos. */ + if ( !find_node (_node, _npos)) + { + return ; + } + + /*-------------------------- _pop current 0-node data */ + _pop_node(_npos, _itop) ; + } + + __normal_call void_type _pop_node ( + iptr_type _npos , + iptr_type _itop + ) + { + if (_itop != -1) + { + /*---- deleteing (d+k)-face: scan adj. and _pop _itop */ + _pop_list( + this->_adj1, _npos, _itop); + } + else + { + /*---- deleting (d+0)-face: set "self" marker to null */ + this-> + _set1[_npos].self() = 0 ; + } + + if (null_node (_npos)) + { + /*---- ref. count: delete (d+0), (d-1)-faces if empty */ + _put_node (_npos); + } + } + + /* + -------------------------------------------------------- + * _POP-EDGE: delete 1-edge from complex. + -------------------------------------------------------- + */ + + __normal_call void_type _pop_edge ( + iptr_type const*_nptr, + iptr_type _itop = -1 + ) + { + iptr_type _epos = -1 ; + + iptr_type _node[2]; + _node[0] = _nptr[0]; + _node[1] = _nptr[1]; + + /*-------------------------- find current 1-edge pos. */ + if ( !find_edge (_node, _epos)) + { + return ; + } + + /*-------------------------- _pop current 1-edge data */ + _pop_edge(_epos, _itop) ; + } + + __normal_call void_type _pop_edge ( + iptr_type _epos , + iptr_type _itop = -1 + ) + { + iptr_type _npos = -1 ; + + if (_itop != -1) + { + /*---- deleteing (d+k)-face: scan adj. and _pop _itop */ + _pop_list( + this->_adj2, _epos, _itop); + } + else + { + /*---- deleting (d+0)-face: set "self" marker to null */ + this-> + _set2[_epos].self() = 0 ; + } + + if (null_edge (_epos)) + { + /*---- ref. count: delete (d+0), (d-1)-faces if empty */ + iptr_type _same ; + this->_map2._pop(_epos, _same); + + iptr_type _node [ 2] ; + _node[0] = this-> + _set2[_epos].node(0) ; + _node[1] = this-> + _set2[_epos].node(1) ; + + _put_edge(_epos); + + for (_npos = 2; _npos-- != 0; ) + { + _pop_node( + &_node[_npos], _epos); + } + } + } + + /* + -------------------------------------------------------- + * _POP-TRIA: delete 2-tria from complex. + -------------------------------------------------------- + */ + + __normal_call void_type _pop_tri3 ( + iptr_type const*_nptr, + iptr_type _itop = -1 + ) + { + iptr_type _tpos = -1 ; + + iptr_type _node[3]; + _node[0] = _nptr[0]; + _node[1] = _nptr[1]; + _node[2] = _nptr[2]; + + /*-------------------------- find current 2-tria pos. */ + if ( !find_tri3 (_node, _tpos)) + { + return ; + } + + /*-------------------------- _pop current 2-tria data */ + _pop_tri3(_tpos, _itop) ; + } + + __normal_call void_type _pop_tri3 ( + iptr_type _tpos , + iptr_type _itop = -1 + ) + { + iptr_type _epos = -1 ; + + if (_itop != -1) + { + /*---- deleteing (d+k)-face: scan adj. and _pop _itop */ + _pop_list( + this->_adj3, _tpos, _itop); + } + else + { + /*---- deleting (d+0)-face: set "self" marker to null */ + this-> + _set3[_tpos].self() = 0 ; + } + + if (null_tri3 (_tpos)) + { + /*---- ref. count: delete (d+0), (d-1)-faces if empty */ + + iptr_type _same ; + this->_map3._pop(_tpos, _same); + + iptr_type _node [ 3] ; + _node[0] = this-> + _set3[_tpos].node(0) ; + _node[1] = this-> + _set3[_tpos].node(1) ; + _node[2] = this-> + _set3[_tpos].node(2) ; + + _put_tri3(_tpos); + + for (_epos = 3; _epos-- != 0; ) + { + iptr_type _enod [3] ; + tri3_type::face_node ( + _enod, _epos, 2, 1) ; + + _enod[0] = + _node[_enod [0]]; + _enod[1] = + _node[_enod [1]]; + + _pop_edge(_enod, _tpos) ; + } + } + } + + /* + -------------------------------------------------------- + * _POP-TRIA: delete 3-tria from complex. + -------------------------------------------------------- + */ + + __normal_call void_type _pop_tri4 ( + iptr_type const*_nptr, + iptr_type _itop = -1 + ) + { + iptr_type _tpos = -1 ; + + iptr_type _node[4]; + _node[0] = _nptr[0]; + _node[1] = _nptr[1]; + _node[2] = _nptr[2]; + _node[3] = _nptr[3]; + + /*-------------------------- find current 3-tria pos. */ + if ( !find_tri4 (_node, _tpos)) + { + return ; + } + + /*-------------------------- _pop current 3-tria data */ + _pop_tri4(_tpos, _itop) ; + } + + __normal_call void_type _pop_tri4 ( + iptr_type _tpos , + iptr_type _itop = -1 + ) + { + iptr_type _fpos = -1 ; + + if (_itop != -1) + { + /*---- deleteing (d+k)-face: scan adj. and _pop _itop */ + _pop_list( + this->_adj4, _tpos, _itop); + } + else + { + /*---- deleting (d+0)-face: set "self" marker to null */ + this-> + _set4[_tpos].self() = 0 ; + } + + if (null_tri4 (_tpos)) + { + /*---- ref. count: delete (d+0), (d-1)-faces if empty */ + + iptr_type _same ; + this->_map4._pop(_tpos, _same); + + iptr_type _node [ 4] ; + _node[0] = this-> + _set4[_tpos].node(0) ; + _node[1] = this-> + _set4[_tpos].node(1) ; + _node[2] = this-> + _set4[_tpos].node(2) ; + _node[3] = this-> + _set4[_tpos].node(3) ; + + _put_tri4(_tpos); + + for (_fpos = 4; _fpos-- != 0; ) + { + iptr_type _fnod [4] ; + tri4_type::face_node ( + _fnod, _fpos, 3, 2) ; + + _fnod[0] = + _node[_fnod [0]]; + _fnod[1] = + _node[_fnod [1]]; + _fnod[2] = + _node[_fnod [2]]; + + _pop_tri3(_fnod, _tpos) ; + } + } + } + + /* + -------------------------------------------------------- + * FIND-NODE: return index of assoc. 0-node. + -------------------------------------------------------- + */ + + __normal_call bool_type find_node ( + iptr_type const*_nptr , + iptr_type&_npos + ) const + { + /*-------------------------- find current 0-node pos. */ + iptr_type _node = *_nptr ; + + if (_node >= +0 && _node < + (iptr_type)this->_set1.count() && + _set1 [_node].mark() >= +0) + { + /*------------------------------- found matching node */ + _npos =_node ; + + return true ; + } + else + { + /*------------------------------- couldn't find match */ + return false ; + } + } + + /* + -------------------------------------------------------- + * FIND-EDGE: return index of assoc. 1-edge. + -------------------------------------------------------- + */ + + __normal_call bool_type find_edge ( + iptr_type const*_node , + iptr_type&_epos + ) + { + /*-------------------------- find current 1-edge pos. */ + iptr_type _ipos = _get_edge() ; + + this-> + _set2[_ipos].node(0)=_node[0]; + this-> + _set2[_ipos].node(1)=_node[1]; + + typename edge_maps::_write_it + _same ; + if (this-> + _map2.find(_ipos, _same)) + { + /*------------------------------- found matching face */ + _put_edge(_ipos) ; + + _epos=*_same ; + + return true ; + } + else + { + /*------------------------------- couldn't find match */ + _put_edge(_ipos) ; + + return false ; + } + } + + /* + -------------------------------------------------------- + * FIND-TRIA: return index of assoc. 2-tria. + -------------------------------------------------------- + */ + + __normal_call bool_type find_tri3 ( + iptr_type const*_node , + iptr_type&_tpos + ) + { + /*-------------------------- find current 2-tria pos. */ + iptr_type _ipos = _get_tri3() ; + + this-> + _set3[_ipos].node(0)=_node[0]; + this-> + _set3[_ipos].node(1)=_node[1]; + this-> + _set3[_ipos].node(2)=_node[2]; + + typename tri3_maps::_write_it + _same ; + if (this-> + _map3.find(_ipos, _same)) + { + /*------------------------------- found matching face */ + _put_tri3(_ipos) ; + + _tpos=*_same ; + + return true ; + } + else + { + /*------------------------------- couldn't find match */ + _put_tri3(_ipos) ; + + return false ; + } + } + + /* + -------------------------------------------------------- + * FIND-TRIA: return index of assoc. 3-tria. + -------------------------------------------------------- + */ + + __normal_call bool_type find_tri4 ( + iptr_type const*_node , + iptr_type&_tpos + ) + { + /*-------------------------- find current 2-tria pos. */ + iptr_type _ipos = _get_tri4() ; + + this-> + _set4[_ipos].node(0)=_node[0]; + this-> + _set4[_ipos].node(1)=_node[1]; + this-> + _set4[_ipos].node(2)=_node[2]; + this-> + _set4[_ipos].node(3)=_node[3]; + + typename tri4_maps::_write_it + _same ; + if (this-> + _map4.find(_ipos, _same)) + { + /*------------------------------- found matching face */ + _put_tri4(_ipos) ; + + _tpos=*_same ; + + return true ; + } + else + { + /*------------------------------- couldn't find match */ + _put_tri4(_ipos) ; + + return false ; + } + } + + + /* + -------------------------------------------------------- + * NODE-EDGE: form node-to-edge adj. list. + -------------------------------------------------------- + */ + + template < + typename list_type + > + __inline_call void_type node_edge ( + iptr_type const*_node , + list_type&_conn + ) + { + node_edge(_node [ 0], _conn) ; + } + + template < + typename list_type + > + __normal_call void_type node_edge ( + iptr_type _npos, + list_type&_conn + ) + { + this->_tmp1.set_count( +0 ) ; + this->_tmp2.set_count( +0 ) ; + this->_tmp3.set_count( +0 ) ; + this->_tmp4.set_count( +0 ) ; + + this->_tmp1.push_tail(_npos) ; + + /*-------------------------- find set of adj. 1-edges */ + for (auto _iter = this->_tmp1.head(); + _iter != this->_tmp1.tend(); + ++_iter ) + { + for (auto _iadj = + this->_adj1.head(*_iter) ; + _iadj != + this->_adj1.tend(*_iter) ; + ++_iadj ) + { + if (this-> + _set2[*_iadj].mark() == 0) + { + _conn.push_tail (*_iadj); + this-> + _set2[*_iadj].mark() += 1; + } + } + } + + /*-------------------------- flip d-face marker lists */ + for (auto _iter = _conn.head() ; + _iter != _conn.tend() ; + ++_iter ) + { + this->_set2 [*_iter].mark() = +0; + } + } + + /* + -------------------------------------------------------- + * NODE-TRI3: form node-to-tria adj. list. + -------------------------------------------------------- + */ + + template < + typename list_type + > + __inline_call void_type node_tri3 ( + iptr_type const*_node , + list_type&_conn + ) + { + node_tri3(_node [ 0], _conn) ; + } + + template < + typename list_type + > + __normal_call void_type node_tri3 ( + iptr_type _npos, + list_type&_conn + ) + { + this->_tmp1.set_count( +0 ) ; + this->_tmp2.set_count( +0 ) ; + this->_tmp3.set_count( +0 ) ; + this->_tmp4.set_count( +0 ) ; + + this->_tmp1.push_tail(_npos) ; + + /*-------------------------- find set of adj. 1-edges */ + for (auto _iter = this->_tmp1.head(); + _iter != this->_tmp1.tend(); + ++_iter ) + { + for (auto _iadj = + this->_adj1.head(*_iter) ; + _iadj != + this->_adj1.tend(*_iter) ; + ++_iadj ) + { + if (this-> + _set2[*_iadj].mark() == 0) + { + this-> + _tmp2.push_tail (*_iadj); + this-> + _set2[*_iadj].mark() += 1; + } + } + } + /*-------------------------- find set of adj. 2-trias */ + for (auto _iter = this->_tmp2.head(); + _iter != this->_tmp2.tend(); + ++_iter ) + { + for (auto _iadj = + this->_adj2.head(*_iter) ; + _iadj != + this->_adj2.tend(*_iter) ; + ++_iadj ) + { + if (this-> + _set3[*_iadj].mark() == 0) + { + _conn.push_tail (*_iadj); + this-> + _set3[*_iadj].mark() += 1; + } + } + } + + /*-------------------------- flip d-face marker lists */ + for (auto _iter = _conn.head() ; + _iter != _conn.tend() ; + ++_iter ) + { + this->_set3 [*_iter].mark() = 0 ; + } + for (auto _iter = this-> + _tmp2.head() ; + _iter != this-> + _tmp2.tend() ; + ++_iter ) + { + this->_set2 [*_iter].mark() = 0 ; + } + } + + /* + -------------------------------------------------------- + * NODE-TRI4: form node-to-tria adj. list. + -------------------------------------------------------- + */ + + template < + typename list_type + > + __inline_call void_type node_tri4 ( + iptr_type const*_node , + list_type&_conn + ) + { + node_tri4(_node [ 0], _conn) ; + } + + template < + typename list_type + > + __normal_call void_type node_tri4 ( + iptr_type _npos, + list_type&_conn + ) + { + this->_tmp1.set_count( +0 ) ; + this->_tmp2.set_count( +0 ) ; + this->_tmp3.set_count( +0 ) ; + this->_tmp4.set_count( +0 ) ; + + this->_tmp1.push_tail(_npos) ; + + /*-------------------------- find set of adj. 1-edges */ + for (auto _iter = this->_tmp1.head(); + _iter != this->_tmp1.tend(); + ++_iter ) + { + for (auto _iadj = + this->_adj1.head(*_iter) ; + _iadj != + this->_adj1.tend(*_iter) ; + ++_iadj ) + { + if (this-> + _set2[*_iadj].mark() == 0) + { + this-> + _tmp2.push_tail (*_iadj); + this-> + _set2[*_iadj].mark() += 1; + } + } + } + /*-------------------------- find set of adj. 2-trias */ + for (auto _iter = this->_tmp2.head(); + _iter != this->_tmp2.tend(); + ++_iter ) + { + for (auto _iadj = + this->_adj2.head(*_iter) ; + _iadj != + this->_adj2.tend(*_iter) ; + ++_iadj ) + { + if (this-> + _set3[*_iadj].mark() == 0) + { + this-> + _tmp3.push_tail (*_iadj); + this-> + _set3[*_iadj].mark() += 1; + } + } + } + /*-------------------------- find set of adj. 3-trias */ + for (auto _iter = this->_tmp3.head(); + _iter != this->_tmp3.tend(); + ++_iter ) + { + for (auto _iadj = + this->_adj3.head(*_iter) ; + _iadj != + this->_adj3.tend(*_iter) ; + ++_iadj ) + { + if (this-> + _set4[*_iadj].mark() == 0) + { + _conn.push_tail (*_iadj); + this-> + _set4[*_iadj].mark() += 1; + } + } + } + + /*-------------------------- flip d-face marker lists */ + for (auto _iter = _conn.head() ; + _iter != _conn.tend() ; + ++_iter ) + { + this->_set4 [*_iter].mark() = 0 ; + } + for (auto _iter = this-> + _tmp3.head() ; + _iter != this-> + _tmp3.tend() ; + ++_iter ) + { + this->_set3 [*_iter].mark() = 0 ; + } + for (auto _iter = this-> + _tmp2.head() ; + _iter != this-> + _tmp2.tend() ; + ++_iter ) + { + this->_set2 [*_iter].mark() = 0 ; + } + } + + /* + -------------------------------------------------------- + * EDGE-TRI3: form edge-to-tria adj. list. + -------------------------------------------------------- + */ + + template < + typename list_type + > + __inline_call void_type edge_tri3 ( + iptr_type const*_node , + list_type&_conn + ) + { + /*-------------------------- find current 1-edge pos. */ + iptr_type _epos = -1; + if (!find_edge(_node, _epos)) + { + return ; + } + + /*-------------------------- get adj. for 1-edge pos. */ + edge_tri3(_epos, _conn) ; + } + + template < + typename list_type + > + __normal_call void_type edge_tri3 ( + iptr_type _epos, + list_type&_conn + ) + { + this->_tmp1.set_count( +0 ) ; + this->_tmp2.set_count( +0 ) ; + this->_tmp3.set_count( +0 ) ; + this->_tmp4.set_count( +0 ) ; + + this->_tmp2.push_tail(_epos) ; + + /*-------------------------- find set of adj. 2-faces */ + for (auto _iter = this->_tmp2.head(); + _iter != this->_tmp2.tend(); + ++_iter ) + { + for (auto _iadj = + this->_adj2.head(*_iter) ; + _iadj != + this->_adj2.tend(*_iter) ; + ++_iadj ) + { + if (this-> + _set3[*_iadj].mark() == 0) + { + _conn.push_tail (*_iadj); + this-> + _set3[*_iadj].mark() += 1; + } + } + } + + /*-------------------------- flip d-face marker lists */ + for (auto _iter = _conn.head() ; + _iter != _conn.tend() ; + ++_iter ) + { + this->_set3 [*_iter].mark() = 0 ; + } + } + + /* + -------------------------------------------------------- + * EDGE-3CEL: form edge-to-cell adj. list. + -------------------------------------------------------- + */ + + __inline_call void_type edge_cell ( + iptr_type const*_node , + char_type _kind , + connector&_conn + ) + { + /*-------------------------- find current 1-edge pos. */ + iptr_type _epos = -1; + if (!find_edge(_node, _epos)) + { + return ; + } + + /*-------------------------- get adj. for 1-edge pos. */ + edge_cell(_epos, _kind, _conn) ; + } + + __normal_call void_type edge_cell ( + iptr_type _epos, + char_type _kind, + connector&_conn + ) + { + this->_ttN1.set_count( +0 ) ; + this->_ttE2.set_count( +0 ) ; + this->_ttT3.set_count( +0 ) ; + this->_ttQ4.set_count( +0 ) ; + this->_ttT4.set_count( +0 ) ; + this->_ttH8.set_count( +0 ) ; + this->_ttP5.set_count( +0 ) ; + this->_ttW6.set_count( +0 ) ; + + this->_ttE2.push_tail(_epos) ; + + /*-------------------------- find set of adj. 2-faces */ + for (auto _iter = this->_ttE2.head(); + _iter != this->_ttE2.tend(); + ++_iter ) + { + for (auto _iadj = // tria-3 + this->_E2T3.head(*_iter) ; + _iadj != + this->_E2T3.tend(*_iter) ; + ++_iadj ) + { + if (this-> + _llT3[*_iadj].mark() == 0) + { + this-> + _ttT3.push_tail (*_iadj); + this-> + _llT3[*_iadj].mark() += 1; + } + } + for (auto _iadj = // quad-4 + this->_E2Q4.head(*_iter) ; + _iadj != + this->_E2Q4.tend(*_iter) ; + ++_iadj ) + { + if (this-> + _llQ4[*_iadj].mark() == 0) + { + this-> + _ttQ4.push_tail (*_iadj); + this-> + _llQ4[*_iadj].mark() += 1; + } + } + } + /*-------------------------- find set of adj. 3-faces */ + for (auto _iter = this->_ttT3.head(); + _iter != this->_ttT3.tend(); + ++_iter ) + { + for (auto _iadj = // tria-4 + this->_T3T4.head(*_iter) ; + _iadj != + this->_T3T4.tend(*_iter) ; + ++_iadj ) + { + if (this-> + _llT4[*_iadj].mark() == 0) + { + _conn.push_tail(conn_data( + *_iadj, tri4_flag)); + this-> + _llT4[*_iadj].mark() += 1; + } + } + for (auto _iadj = // pyra-5 + this->_T3P5.head(*_iter) ; + _iadj != + this->_T3P5.tend(*_iter) ; + ++_iadj ) + { + if (this-> + _llP5[*_iadj].mark() == 0) + { + _conn.push_tail(conn_data( + *_iadj, pyra_flag)); + this-> + _llP5[*_iadj].mark() += 1; + } + } + for (auto _iadj = // wedg-6 + this->_T3W6.head(*_iter) ; + _iadj != + this->_T3W6.tend(*_iter) ; + ++_iadj ) + { + if (this-> + _llW6[*_iadj].mark() == 0) + { + _conn.push_tail(conn_data( + *_iadj, wedg_flag)); + this-> + _llW6[*_iadj].mark() += 1; + } + } + } + + /*-------------------------- flip d-face marker lists */ + for (auto _iter = _conn.head() ; + _iter != _conn.tend() ; + ++_iter ) + { + if (_iter->_flag == tri4_flag) + _llT4[_iter->_ipos].mark() = 0 ; + else + if (_iter->_flag == hexa_flag) + _llH8[_iter->_ipos].mark() = 0 ; + else + if (_iter->_flag == pyra_flag) + _llP5[_iter->_ipos].mark() = 0 ; + else + if (_iter->_flag == wedg_flag) + _llW6[_iter->_ipos].mark() = 0 ; + } + for (auto _iter = this-> + _ttT3.head() ; + _iter != this-> + _ttT3.tend() ; + ++_iter ) + { + this->_llT3 [*_iter].mark() = 0 ; + } + for (auto _iter = this-> + _ttQ4.head() ; + _iter != this-> + _ttQ4.tend() ; + ++_iter ) + { + this->_llQ4 [*_iter].mark() = 0 ; + } + } + + /* + -------------------------------------------------------- + * TRI3-TRI4: form tria-to-tria adj. list. + -------------------------------------------------------- + */ + + template < + typename list_type + > + __inline_call void_type tri3_tri4 ( + iptr_type const*_node , + list_type&_conn + ) + { + /*-------------------------- find current 1-edge pos. */ + iptr_type _tpos = -1; + if (!find_tri3(_node, _tpos)) + { + return ; + } + + /*-------------------------- get adj. for 1-edge pos. */ + tri3_tri4(_tpos, _conn) ; + } + + template < + typename list_type + > + __normal_call void_type tri3_tri4 ( + iptr_type _epos, + list_type&_conn + ) + { + this->_tmp1.set_count( +0 ) ; + this->_tmp2.set_count( +0 ) ; + this->_tmp3.set_count( +0 ) ; + this->_tmp4.set_count( +0 ) ; + + this->_tmp3.push_tail(_epos) ; + + /*-------------------------- find set of adj. 2-faces */ + for (auto _iter = this->_tmp3.head(); + _iter != this->_tmp3.tend(); + ++_iter ) + { + for (auto _iadj = + this->_adj3.head(*_iter) ; + _iadj != + this->_adj3.tend(*_iter) ; + ++_iadj ) + { + if (this-> + _set4[*_iadj].mark() == 0) + { + _conn.push_tail (*_iadj); + this-> + _set4[*_iadj].mark() += 1; + } + } + } + + /*-------------------------- flip d-face marker lists */ + for (auto _iter = _conn.head() ; + _iter != _conn.tend() ; + ++_iter ) + { + this->_set4 [*_iter].mark() = 0 ; + } + } + + } ; + + + } + +# endif // __MESH_COMPLEX_3__ + + + diff --git a/src/libcpp/mesh_type/tria_complex_type_k.hpp b/src/libcpp/mesh_type/mesh_complex_type_k.hpp similarity index 56% rename from src/libcpp/mesh_type/tria_complex_type_k.hpp rename to src/libcpp/mesh_type/mesh_complex_type_k.hpp index 9d4603f..f76548b 100644 --- a/src/libcpp/mesh_type/tria_complex_type_k.hpp +++ b/src/libcpp/mesh_type/mesh_complex_type_k.hpp @@ -1,71 +1,71 @@ -/* ------------------------------------------------------------- - * TRIA-COMPLEX-TYPE-K: types for simplical complexes. ------------------------------------------------------------- - * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) - * - * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The - * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be - * used at your own risk. - * ------------------------------------------------------------- - * - * Last updated: 01 November, 2017 - * - * Copyright 2013-2017 - * Darren Engwirda - * de2363@columbia.edu - * https://github.com/dengwirda/ - * ------------------------------------------------------------- - */ - + /* + -------------------------------------------------------- + * MESH-COMPLEX-TYPE-K: types for mesh complexes. + -------------------------------------------------------- + * + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) + * + * Disclaimer: Neither I nor: Columbia University, The + * Massachusetts Institute of Technology, The + * University of Sydney, nor The National Aeronautics + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be + * used at your own risk. + * + -------------------------------------------------------- + * + * Last updated: 08 December, 2019 + * + * Copyright 2013-2019 + * Darren Engwirda + * de2363@columbia.edu + * https://github.com/dengwirda/ + * + -------------------------------------------------------- + */ + # pragma once -# ifndef __TRIA_COMPLEX_TYPE_K__ -# define __TRIA_COMPLEX_TYPE_K__ +# ifndef __MESH_COMPLEX_TYPE_K__ +# define __MESH_COMPLEX_TYPE_K__ namespace mesh { -/* ------------------------------------------------------------- - * BASE-NODE-2: node-type for tria. complexes in R^2. ------------------------------------------------------------- - * IPTR-TYPE - signed-integer typedef. - * REAL-TYPE - floating-point typedef. ------------------------------------------------------------- - */ - + /* + -------------------------------------------------------- + * BASE-NODE-2: node-type for mesh complexes in R^2. + -------------------------------------------------------- + * IPTR-TYPE - signed-integer typedef. + * REAL-TYPE - floating-point typedef. + -------------------------------------------------------- + */ + template < typename I, typename R > - class tria_complex_node_2 + class mesh_complex_node_2 { /*---------------------------------------- basic-node R^2 */ public : - + typedef R real_type ; typedef I iptr_type ; @@ -73,13 +73,13 @@ containers:: fixed_array _pval ; // node coord.'s - + containers:: fixed_array _ndat ; // node indexing - + char _mark ; char _self ; - + public : /*---------------------------------------- "write" access */ __inline_call real_type & pval ( @@ -94,11 +94,11 @@ } __inline_call char & mark ( - ) + ) { return this->_mark ; } __inline_call char & self ( - ) + ) { return this->_self ; } @@ -125,24 +125,24 @@ } ; -/* ------------------------------------------------------------- - * BASE-NODE-3: node-type for simplicial complexes in R^3. ------------------------------------------------------------- - * IPTR-TYPE - signed-integer typedef. - * REAL-TYPE - floating-point typedef. ------------------------------------------------------------- - */ - + /* + -------------------------------------------------------- + * BASE-NODE-3: node-type for mesh complexes in R^3. + -------------------------------------------------------- + * IPTR-TYPE - signed-integer typedef. + * REAL-TYPE - floating-point typedef. + -------------------------------------------------------- + */ + template < typename I, typename R > - class tria_complex_node_3 + class mesh_complex_node_3 { /*---------------------------------------- basic-node R^3 */ public : - + typedef R real_type ; typedef I iptr_type ; @@ -150,13 +150,13 @@ containers:: fixed_array _pval ; // node coord.'s - + containers:: fixed_array _ndat ; // node indexing - + char _mark ; char _self ; - + public : /*---------------------------------------- "write" access */ __inline_call real_type & pval ( @@ -171,14 +171,14 @@ } __inline_call char & mark ( - ) + ) { return this->_mark ; } __inline_call char & self ( - ) + ) { return this->_self ; } - + /*---------------------------------------- "const" access */ __inline_call real_type const& pval ( iptr_type _ipos @@ -202,24 +202,24 @@ } ; -/* ------------------------------------------------------------- - * BASE-NODE-4: node-type for simplicial complexes in R^4. ------------------------------------------------------------- - * IPTR-TYPE - signed-integer typedef. - * REAL-TYPE - floating-point typedef. ------------------------------------------------------------- - */ - + /* + -------------------------------------------------------- + * BASE-NODE-4: node-type for mesh complexes in R^4. + -------------------------------------------------------- + * IPTR-TYPE - signed-integer typedef. + * REAL-TYPE - floating-point typedef. + -------------------------------------------------------- + */ + template < typename I, typename R > - class tria_complex_node_4 + class mesh_complex_node_4 { /*---------------------------------------- basic-node R^4 */ public : - + typedef R real_type ; typedef I iptr_type ; @@ -227,13 +227,13 @@ containers:: fixed_array _pval ; // node coord.'s - + containers:: fixed_array _ndat ; // node indexing - + char _mark ; char _self ; - + public : /*---------------------------------------- "write" access */ __inline_call real_type & pval ( @@ -248,14 +248,14 @@ } __inline_call char & mark ( - ) + ) { return this->_mark ; } __inline_call char & self ( - ) + ) { return this->_self ; } - + /*---------------------------------------- "const" access */ __inline_call real_type const& pval ( iptr_type _ipos @@ -279,32 +279,32 @@ } ; -/* ------------------------------------------------------------- - * BASE-EDGE-2: 1-simplex type for TRIA-COMPLEX-K. ------------------------------------------------------------- - * IPTR-TYPE - signed-integer typedef. ------------------------------------------------------------- - */ - + /* + -------------------------------------------------------- + * BASE-EDGE-2: 1-simplex type for MESH-COMPLEX-K. + -------------------------------------------------------- + * IPTR-TYPE - signed-integer typedef. + -------------------------------------------------------- + */ + template < typename I > - class tria_complex_edge_2 + class mesh_complex_edge_2 { /*---------------------------------------- base 1-simplex */ public : - + typedef I iptr_type ; - + iptr_type static constexpr _dims = +1 ; containers:: fixed_array _ndat ; // node indexing - + char _mark ; char _self ; - + public : /*---------------------------------------- "write" access */ __inline_call iptr_type & node ( @@ -314,11 +314,11 @@ } __inline_call char & mark ( - ) + ) { return this->_mark ; } __inline_call char & self ( - ) + ) { return this->_self ; } @@ -348,7 +348,7 @@ _fnod[0] = 0 ; _fnod[1] = 1 ; } - + __static_call __inline_call void_type face_node ( iptr_type *_fnod, @@ -363,8 +363,17 @@ /* index INTO 1-dim faces */ if (_into == +1) { - faceind11(_fnod, _fpos); + faceind11(_fnod, _fpos); return ; } + else + { + _fnod[0] = -1; + _fnod[1] = -1; // suppress compiler warnings + } + } + else + { + _fnod[0] = -1; // suppress compiler warnings } } @@ -390,32 +399,32 @@ } ; -/* ------------------------------------------------------------- - * BASE-TRIA-3: 2-simplex type for TRIA-COMPLEX-K. ------------------------------------------------------------- - * IPTR-TYPE - signed-integer typedef. ------------------------------------------------------------- - */ - + /* + -------------------------------------------------------- + * BASE-TRIA-3: 2-simplex type for MESH-COMPLEX-K. + -------------------------------------------------------- + * IPTR-TYPE - signed-integer typedef. + -------------------------------------------------------- + */ + template < typename I > - class tria_complex_tria_3 + class mesh_complex_tria_3 { /*---------------------------------------- base 2-simplex */ public : - + typedef I iptr_type ; - + iptr_type static constexpr _dims = +2 ; containers:: fixed_array _ndat ; // node indexing - + char _mark ; char _self ; - + public : /*---------------------------------------- "write" access */ __inline_call iptr_type & node ( @@ -423,13 +432,13 @@ ) { return this->_ndat [_ipos]; } - + __inline_call char & mark ( - ) + ) { return this->_mark ; } __inline_call char & self ( - ) + ) { return this->_self ; } @@ -439,7 +448,7 @@ ) const { return this->_ndat[_ipos]; } - + __inline_call char const& mark ( ) const { return this->_mark ; @@ -480,21 +489,27 @@ case 0 : { _fnod[0] = 0 ; - _fnod[1] = 1 ; + _fnod[1] = 1 ; _fnod[2] = 2 ; break ; } case 1 : { _fnod[0] = 1 ; - _fnod[1] = 2 ; + _fnod[1] = 2 ; _fnod[2] = 0 ; break ; } case 2 : { _fnod[0] = 2 ; - _fnod[1] = 0 ; + _fnod[1] = 0 ; _fnod[2] = 1 ; break ; } + default: + { // suppress compiler warnings + _fnod[0] =-1 ; + _fnod[1] =-1 ; + _fnod[2] =-1 ; break ; + } } } __static_call @@ -511,13 +526,19 @@ /* index INTO 2-dim faces */ if (_into == +2) { - faceind22(_fnod, _fpos); + faceind22(_fnod, _fpos); return ; } /* index INTO 1-dim faces */ else if (_into == +1) { - faceind21(_fnod, _fpos); + faceind21(_fnod, _fpos); return ; + } + else + { + _fnod[0] = -1; // suppress compiler warnings + _fnod[1] = -1; + _fnod[2] = -1; return ; } } /* index FROM 1-dim faces */ @@ -527,9 +548,18 @@ /* index INTO 1-dim faces */ if (_into == +1) { - faceind11(_fnod, _fpos); + faceind11(_fnod, _fpos); return ; + } + else + { + _fnod[0] = -1; // suppress compiler warnings + _fnod[1] = -1; return ; } } + else + { + _fnod[0] = -1; // suppress compiler warnings + } } __static_call @@ -559,32 +589,235 @@ } ; -/* ------------------------------------------------------------- - * BASE-TRIA-4: 3-simplex type for TRIA-COMPLEX-K. ------------------------------------------------------------- - * IPTR-TYPE - signed-integer typedef. ------------------------------------------------------------- - */ - + /* + -------------------------------------------------------- + * BASE-QUAD-4: quad-4 cell type for MESH-COMPLEX-K. + -------------------------------------------------------- + * IPTR-TYPE - signed-integer typedef. + -------------------------------------------------------- + */ + + template < + typename I + > + class mesh_complex_quad_4 + { +/*-------------------------------------- base quad-4 cell */ + public : + + typedef I iptr_type ; + + iptr_type static constexpr _dims = +2 ; + + containers:: + fixed_array _ndat ; // node indexing + + char _mark ; + char _self ; + + public : +/*---------------------------------------- "write" access */ + __inline_call iptr_type & node ( + iptr_type _ipos + ) + { return this->_ndat [_ipos]; + } + + __inline_call char & mark ( + ) + { return this->_mark ; + } + __inline_call char & self ( + ) + { return this->_self ; + } + +/*---------------------------------------- "const" access */ + __inline_call iptr_type const& node ( + iptr_type _ipos + ) const + { return this->_ndat[_ipos]; + } + + __inline_call char const& mark ( + ) const + { return this->_mark ; + } + __inline_call char const& self ( + ) const + { return this->_self ; + } + +/*---------------------------------------- local indexing */ + __static_call + __inline_call void_type faceind22 ( + iptr_type *_fnod, + iptr_type//_fpos + ) + { + _fnod[0] = 0 ; + _fnod[1] = 1 ; + _fnod[2] = 2 ; + _fnod[3] = 3 ; + } + __static_call + __inline_call void_type faceind11 ( + iptr_type *_fnod, + iptr_type//_fpos + ) + { + _fnod[0] = 0 ; + _fnod[1] = 1 ; + } + __static_call + __inline_call void_type faceind21 ( + iptr_type *_fnod, + iptr_type _fpos + ) + { + switch (_fpos) + { + case 0 : + { + _fnod[0] = 0 ; + _fnod[1] = 1 ; + _fnod[2] = 2 ; + _fnod[3] = 3 ; break ; + } + case 1 : + { + _fnod[0] = 1 ; + _fnod[1] = 2 ; + _fnod[2] = 3 ; + _fnod[3] = 0 ; break ; + } + case 2 : + { + _fnod[0] = 2 ; + _fnod[1] = 3 ; + _fnod[2] = 0 ; + _fnod[3] = 1 ; break ; + } + case 3 : + { + _fnod[0] = 3 ; + _fnod[1] = 0 ; + _fnod[2] = 1 ; + _fnod[3] = 2 ; break ; + } + default: + { // suppress compiler warnings + _fnod[0] =-1 ; + _fnod[1] =-1 ; + _fnod[2] =-1 ; + _fnod[3] =-1 ; break ; + } + } + } + __static_call + __inline_call void_type face_node ( + iptr_type *_fnod, + iptr_type _fpos, + iptr_type _from, + iptr_type _into + ) + { + /* index FROM 2-dim faces */ + if (_from == +2) + { + /* index INTO 2-dim faces */ + if (_into == +2) + { + faceind22(_fnod, _fpos); return ; + } + /* index INTO 1-dim faces */ + else + if (_into == +1) + { + faceind21(_fnod, _fpos); return ; + } + else + { + _fnod[0] = -1; // suppress compiler warnings + _fnod[1] = -1; + _fnod[2] = -1; + _fnod[3] = -1; return ; + } + } + /* index FROM 1-dim faces */ + else + if (_from == +1) + { + /* index INTO 1-dim faces */ + if (_into == +1) + { + faceind11(_fnod, _fpos); return ; + } + else + { + _fnod[0] = -1; // suppress compiler warnings + _fnod[1] = -1; return ; + } + } + else + { + _fnod[0] = -1; // suppress compiler warnings + } + } + + __static_call + __inline_call iptr_type face_size ( + iptr_type _fdim + ) + { + if (_fdim == +0) + { + return +4; + } + else + if (_fdim == +1) + { + return +4; + } + else + if (_fdim == +2) + { + return +1; + } + else + { + return +0; + } + } + + } ; + + /* + -------------------------------------------------------- + * BASE-TRIA-4: 3-simplex type for MESH-COMPLEX-K. + -------------------------------------------------------- + * IPTR-TYPE - signed-integer typedef. + -------------------------------------------------------- + */ + template < - typename I + typename I > - class tria_complex_tria_4 - { + class mesh_complex_tria_4 + { /*---------------------------------------- base 3-simplex */ public : - + typedef I iptr_type ; iptr_type static constexpr _dims = +3 ; containers:: fixed_array _ndat ; // node indexing - + char _mark ; char _self ; - + public : /*---------------------------------------- "write" access */ __inline_call iptr_type & node ( @@ -594,11 +827,11 @@ } __inline_call char & mark ( - ) + ) { return this->_mark ; } __inline_call char & self ( - ) + ) { return this->_self ; } @@ -658,33 +891,40 @@ switch (_fpos) { case 0 : - { + { _fnod[0] = 0 ; _fnod[1] = 1 ; - _fnod[2] = 2 ; + _fnod[2] = 2 ; _fnod[3] = 3 ; break ; } case 1 : { _fnod[0] = 0 ; _fnod[1] = 3 ; - _fnod[2] = 1 ; + _fnod[2] = 1 ; _fnod[3] = 2 ; break ; } case 2 : { _fnod[0] = 1 ; _fnod[1] = 3 ; - _fnod[2] = 2 ; + _fnod[2] = 2 ; _fnod[3] = 0 ; break ; } case 3 : { _fnod[0] = 2 ; _fnod[1] = 3 ; - _fnod[2] = 0 ; + _fnod[2] = 0 ; _fnod[3] = 1 ; break ; } + default: + { // suppress compiler warnings + _fnod[0] =-1 ; + _fnod[1] =-1 ; + _fnod[2] =-1 ; + _fnod[3] =-1 ; break ; + } } } __static_call @@ -725,6 +965,11 @@ _fnod[0] = 2 ; _fnod[1] = 3 ; break ; } + default: + { // suppress compiler warnings + _fnod[0] =-1 ; + _fnod[1] =-1 ; break ; + } } } __static_call @@ -738,21 +983,27 @@ case 0 : { _fnod[0] = 0 ; - _fnod[1] = 1 ; + _fnod[1] = 1 ; _fnod[2] = 2 ; break ; } case 1 : { _fnod[0] = 1 ; - _fnod[1] = 2 ; + _fnod[1] = 2 ; _fnod[2] = 0 ; break ; } case 2 : { _fnod[0] = 2 ; - _fnod[1] = 0 ; + _fnod[1] = 0 ; _fnod[2] = 1 ; break ; } + default: + { // suppress compiler warnings + _fnod[0] =-1 ; + _fnod[1] =-1 ; + _fnod[2] =-1 ; break ; + } } } @@ -766,23 +1017,30 @@ { /* index FROM 3-dim faces */ if (_from == +3) - { + { /* index INTO 3-dim faces */ if (_into == +3) { - faceind33(_fnod, _fpos); + faceind33(_fnod, _fpos); return ; } /* index INTO 2-dim faces */ else if (_into == +2) { - faceind32(_fnod, _fpos); + faceind32(_fnod, _fpos); return ; } /* index INTO 1-dim faces */ else if (_into == +1) { - faceind31(_fnod, _fpos); + faceind31(_fnod, _fpos); return ; + } + else + { + _fnod[0] = -1; // suppress compiler warnings + _fnod[1] = -1; + _fnod[2] = -1; + _fnod[3] = -1; return ; } } /* index FROM 2-dim faces */ @@ -792,13 +1050,19 @@ /* index INTO 2-dim faces */ if (_into == +2) { - faceind22(_fnod, _fpos); + faceind22(_fnod, _fpos); return ; } /* index INTO 1-dim faces */ else if (_into == +1) { - faceind21(_fnod, _fpos); + faceind21(_fnod, _fpos); return ; + } + else + { + _fnod[0] = -1; // suppress compiler warnings + _fnod[1] = -1; + _fnod[2] = -1; return ; } } /* index FROM 1-dim faces */ @@ -808,8 +1072,17 @@ /* index INTO 1-dim faces */ if (_into == +1) { - faceind11(_fnod, _fpos); + faceind11(_fnod, _fpos); return ; } + else + { + _fnod[0] = -1; // suppress compiler warnings + _fnod[1] = -1; return ; + } + } + else + { + _fnod[0] = -1; // suppress compiler warnings } } @@ -844,11 +1117,11 @@ } } ; - - + + } -# endif //__TRIA_COMPLEX_TYPE_K__ +# endif //__MESH_COMPLEX_TYPE_K__ diff --git a/src/libcpp/mesh_type/tria_complex_1.hpp b/src/libcpp/mesh_type/tria_complex_1.hpp index 6dff238..98842a0 100644 --- a/src/libcpp/mesh_type/tria_complex_1.hpp +++ b/src/libcpp/mesh_type/tria_complex_1.hpp @@ -1,39 +1,39 @@ /* -------------------------------------------------------- - * TRIA-COMPLEX-1: piecewise tria. complex in R^1. + * TRIA-COMPLEX-1: piecewise tria. complex in R^1. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 11 April, 2018 + * Last updated: 30 June, 2019 * - * Copyright 2013-2018 + * Copyright 2013-2019 * Darren Engwirda * de2363@columbia.edu * https://github.com/dengwirda/ @@ -57,11 +57,11 @@ * ALLOCATOR - memory allocator -------------------------------------------------------- */ - + template < typename NN , typename E2 , - typename AA = allocators::basic_alloc + typename AA = allocators::basic_alloc > class tria_complex_1 { @@ -71,41 +71,41 @@ typedef E2 edge_type ; typedef AA allocator ; - typedef typename + typedef typename node_type::real_type real_type ; - typedef typename - edge_type::iptr_type iptr_type ; + typedef typename + edge_type::iptr_type iptr_type ; typedef typename allocator::size_type size_type ; iptr_type static constexpr _dims = +1 ; typedef containers::block_array < - node_type, + node_type, allocator > node_list ; typedef containers::block_array < - edge_type, + edge_type, allocator > edge_list ; typedef containers::array < - iptr_type, + iptr_type, allocator > iptr_list ; - + #define __hashscal sizeof(iptr_type)/sizeof(uint32_t) class node_hash { public : - __const_ptr(node_list) _nset ; + __const_ptr(node_list) _nset ; public : /*----------------------- build hash _obj. from _src. */ __inline_call node_hash ( node_list *_nsrc ) : _nset( _nsrc) {} /*----------------------- hash node indexing for node */ - __inline_call - iptr_type operator() ( + __inline_call + uint32_t operator() ( iptr_type _npos ) const { @@ -117,15 +117,15 @@ class edge_hash { public : - __const_ptr(edge_list) _eset ; + __const_ptr(edge_list) _eset ; public : /*----------------------- build hash _obj. from _src. */ __inline_call edge_hash ( edge_list *_esrc ) : _eset( _esrc) {} /*----------------------- hash node indexing for edge */ - __inline_call - iptr_type operator() ( + __inline_call + uint32_t operator() ( iptr_type _epos ) const { @@ -136,28 +136,28 @@ operator[](_epos).node( 1) ; algorithms::isort ( - &_enod[0], &_enod[2] , + &_enod[0], &_enod[2] , std::less()); - + return hash::hashword ( (uint32_t*)&_enod[0] , +2 * __hashscal, +137) ; } } ; - - + + class node_pred { public : - __const_ptr(node_list) _nset ; + __const_ptr(node_list) _nset ; public : /*----------------------- build hash _obj. from _src. */ __inline_call node_pred ( node_list *_nsrc ) : _nset( _nsrc) {} /*----------------------- compute "equal-to" for node */ - __inline_call - iptr_type operator() ( + __inline_call + bool_type operator() ( iptr_type _ipos, iptr_type _jpos ) const @@ -165,28 +165,27 @@ iptr_type _inod[1]; _inod[0] = this->_nset-> operator[](_ipos).node( 0) ; - + iptr_type _jnod[1]; _jnod[0] = this->_nset-> operator[](_jpos).node( 0) ; - - return ( _inod[0] == - _jnod[0] ); + + return _inod[0] == _jnod[0] ; } } ; - + class edge_pred { public : - __const_ptr(edge_list) _eset ; + __const_ptr(edge_list) _eset ; public : /*----------------------- build hash _obj. from _src. */ __inline_call edge_pred ( edge_list *_esrc ) : _eset( _esrc) {} /*----------------------- compute "equal-to" for edge */ - __inline_call - iptr_type operator() ( + __inline_call + bool_type operator() ( iptr_type _ipos, iptr_type _jpos ) const @@ -196,7 +195,7 @@ operator[](_ipos).node( 0) ; _inod[1] = this->_eset-> operator[](_ipos).node( 1) ; - + iptr_type _jnod[2]; _jnod[0] = this->_eset-> operator[](_jpos).node( 0) ; @@ -204,20 +203,18 @@ operator[](_jpos).node( 1) ; algorithms::isort ( - &_inod[0], &_inod[2], + &_inod[0], &_inod[2], std::less()); algorithms::isort ( - &_jnod[0], &_jnod[2], + &_jnod[0], &_jnod[2], std::less()); - - return ( _inod[0] == - _jnod[0] && - _inod[1] == - _jnod[1] ); + + return _inod[0] == _jnod[0] && + _inod[1] == _jnod[1] ; } } ; - + #undef __hashscal iptr_type static const pool_byte_size=96*1024 ; @@ -229,18 +226,18 @@ typedef allocators::_wrap_alloc < pool_base > pool_wrap ; - typedef containers::hash_table < - iptr_type, - node_hash, - node_pred, - pool_wrap> node_maps ; + //typedef containers::hash_table < + // iptr_type, + // node_hash, + // node_pred, + // pool_wrap> node_maps ; typedef containers::hash_table < - iptr_type, - edge_hash, + iptr_type, + edge_hash, edge_pred, pool_wrap> edge_maps ; - + typedef containers::array_list < iptr_type, pool_wrap > conn_list ; @@ -253,15 +250,15 @@ conn_list _adj1 ; conn_list _adj2 ; - node_maps _map1 ; + //node_maps _map1 ; edge_maps _map2 ; - + node_list _set1 ; edge_list _set2 ; - + iptr_list _del1 ; iptr_list _del2 ; - + iptr_list _tmp1 ; iptr_list _tmp2 ; @@ -273,7 +270,7 @@ * GET-NODE: "create" new node, push onto active set. -------------------------------------------------------- */ - + __inline_call iptr_type _get_node ( ) { @@ -293,16 +290,16 @@ this->_set1[_ipos].mark() = +0 ; this->_set1[_ipos].self() = +0 ; - + return ( _ipos ) ; } - + /* -------------------------------------------------------- * GET-EDGE: "create" new edge, push onto active set. -------------------------------------------------------- */ - + __inline_call iptr_type _get_edge ( ) { @@ -325,13 +322,13 @@ return ( _ipos ) ; } - + /* -------------------------------------------------------- * PUT-ITEM: "delete" old item, _pop from active set. -------------------------------------------------------- */ - + __inline_call void_type _put_node ( iptr_type _ipos ) @@ -340,7 +337,7 @@ this->_set1[_ipos].mark() = -1 ; this->_set1[_ipos].self() = -1 ; } - + __inline_call void_type _put_edge ( iptr_type _ipos ) @@ -349,15 +346,15 @@ this->_set2[_ipos].mark() = -1 ; this->_set2[_ipos].self() = -1 ; } - + public : - + /* -------------------------------------------------------- * construct tria_complex from alloc. etc... -------------------------------------------------------- */ - + __normal_call tria_complex_1 ( allocator const& _asrc = allocator() ) : _hsrc(sizeof ( @@ -368,13 +365,13 @@ _adj1(pool_wrap(&_csrc)), _adj2(pool_wrap(&_csrc)), /*------------------------------ init. hash lists */ - _map1( - node_hash(& this->_set1) , - node_pred(& this->_set1) , - +.8, (pool_wrap(&_hsrc))) , + //_map1( + // node_hash(& this->_set1) , + // node_pred(& this->_set1) , + //+.8, (pool_wrap(&_hsrc))) , _map2( - edge_hash(& this->_set2) , - edge_pred(& this->_set2) , + edge_hash(& this->_set2) , + edge_pred(& this->_set2) , +.8, (pool_wrap(&_hsrc))) , /*------------------------------ init. face lists */ _set1(_asrc),_set2(_asrc) , @@ -384,42 +381,43 @@ _tmp1(_asrc),_tmp2(_asrc) { } - + /* -------------------------------------------------------- * 'clear' a tria-complex -------------------------------------------------------- */ - + __normal_call void_type clear ( - containers::alloc_types _kind = + containers::alloc_types _kind = containers::loose_alloc ) { this->_adj1.clear (_kind) ; this->_adj2.clear (_kind) ; - - this->_map1.clear (_kind) ; + + //this->_map1.clear (_kind) ; this->_map2.clear (_kind) ; this->_set1.clear (_kind) ; this->_set2.clear (_kind) ; - + this->_del1.clear (_kind) ; this->_del2.clear (_kind) ; - + this->_tmp1.clear (_kind) ; this->_tmp2.clear (_kind) ; - - //!!do something with pool'd-alloc? + + this->_hsrc.clear (); + this->_csrc.clear (); } - + /* -------------------------------------------------------- * INIT-LIST: re-size adj. lists on demand. -------------------------------------------------------- */ - + __inline_call void_type init_list ( conn_list&_list, size_type _lpos @@ -427,146 +425,123 @@ { if (_lpos >= _list._lptr.count()) _list._lptr.set_count ( - _lpos + 1, + _lpos + 1, containers::loose_alloc, nullptr) ; } - + /* -------------------------------------------------------- * PUSH-NODE: append new 0-node to complex. -------------------------------------------------------- */ - + __normal_call iptr_type push_node ( - node_type const&_ndat, + node_type const& _ndat, bool_type _link = true, iptr_type _itop = -1 ) { - iptr_type _ipos = _get_node() ; - + iptr_type _ipos = -1 ; + if (!_link) { - + + __assert( _itop == -1 && + "tria-complex: non-top node!" ) ; + /*------------------------ init. external d-face data */ + _ipos = _get_node(); + this->_set1[_ipos] = _ndat ; this->_set1[_ipos].mark() = 0 ; - + this->_set1[_ipos].self() = 1 ; this-> _set1 [_ipos].node(0) =_ipos ; - - /*------------------------ push face data to hash set */ - this->_map1.push(_ipos) ; - + /*------------------------ init. local adj. index set */ init_list(this->_adj1, _ipos) ; - + } else { - + + if (_itop == -1) + { /*------------------------ init. external d-face data */ + _ipos = _get_node(); + this->_set1[_ipos] = _ndat ; this->_set1[_ipos].mark() = 0 ; - - if (_itop == -1) - { this->_set1[_ipos].self() = 1 ; + this-> - _set1 [_ipos].node(0) =_ipos ; - } - else - this->_set1[_ipos].self() = 0 ; - - typename - node_maps::_write_it _same ; - if (this-> - _map1.find(_ipos , _same)) - { - /*---- existing d-face found: append to existing data */ - if (_itop == -1) - { - /*----- if it's a "top"-level face, copy data */ - this->_set1[*_same] = - this->_set1[ _ipos] ; - } - else - { - /*----- otherwise, append index to adj. lists */ - this-> - _adj1.push(_itop,*_same) ; - } - - _put_node(_ipos) ; + _set1 [_ipos].node(0) = _ipos; + + /*------------------------ init. local adj. index set */ + init_list(this->_adj1, _ipos) ; + } else { - /*---- d-face is new: push and descend to (d-1)-faces */ - if (_itop == -1) - { - /*----- if it's a "top"-level face, keep data */ - init_list( - this->_adj1, _ipos) ; - } - else - { - /*----- otherwise, append index to adj. lists */ - this-> - _adj1.push(_itop, _ipos) ; - } - - /*-------------- push new face data onto hash */ - this->_map1.push(_ipos) ; + /*------------------------ init. internal d-face data */ + __assert(find_node( + &_ndat.node(0), _ipos) && + "tria-complex: node not here" ); + + /*------------------------ append index to adj. lists */ + this->_adj1.push( + _itop, _ndat.node(0)) ; + } - + } - + return _ipos ; } - + /* -------------------------------------------------------- * PUSH-EDGE: append new 1-edge to complex. -------------------------------------------------------- */ - + __normal_call iptr_type push_edge ( - edge_type const&_edat, + edge_type const& _edat, bool_type _link = true, - iptr_type _itop = -1 + iptr_type _itop = -1 ) { iptr_type _ipos = _get_edge() ; iptr_type _npos ; - + if (!_link) { - + + __assert( _itop == -1 && + "tria-complex: non-top cell!" ) ; + /*------------------------ init. external d-face data */ this->_set2[_ipos] = _edat ; this->_set2[_ipos].mark() = 0 ; this->_set2[_ipos].self() = 1 ; - - /*------------------------ push face data to hash set */ - this->_map2.push(_ipos) ; - + /*------------------------ init. local adj. index set */ init_list(this->_adj2, _ipos) ; - + } else { - + /*------------------------ init. external d-face data */ this->_set2[_ipos] = _edat ; this->_set2[_ipos].mark() = 0 ; - + if (_itop == -1) this->_set2[_ipos].self() = 1 ; else this->_set2[_ipos].self() = 0 ; - + typename edge_maps::_write_it _same ; if (this-> @@ -584,13 +559,13 @@ /*----- otherwise, append index to adj. lists */ this-> _adj2.push(_itop,*_same) ; - } - - _put_edge(_ipos) ; + } + + _put_edge(_ipos) ; } else { - /*---- d-face is new: push and descend to (d-1)-faces */ + /*---- d-face is new: push and descend to (d-1)-faces */ if (_itop == -1) { /*----- if it's a "top"-level face, keep data */ @@ -603,86 +578,93 @@ this-> _adj2.push(_itop, _ipos) ; } - + /*-------------- descend into (d-1)-face data */ for (_npos = 2; _npos-- != 0; ) { - node_type _ndat; - _ndat.node(0) = + node_type _ndat; + _ndat.node(0) = _edat.node(_npos) ; - - push_node( + + push_node( _ndat, _link, _ipos) ; } - + /*-------------- push new face data onto hash */ this->_map2.push(_ipos) ; } - + } - + return _ipos ; } - + /* -------------------------------------------------------- - * MAKE-PTRS: build item-to-item adj. + * MAKE-LINK: build item-to-item adj. -------------------------------------------------------- */ - - __normal_call void_type make_ptrs ( + + __normal_call void_type make_link ( ) { + this->_map2.set_slots( + (this->_set2.count()*5)/4 + 1 + ) ; + this->_adj1.empty () ; this->_adj2.empty () ; - + iptr_type _epos = +0 ; for (auto _iter = this->_set2.head(); _iter != this->_set2.tend(); ++_iter, ++_epos ) { + /*-------------- push face data onto hash set */ + this->_map2.push(_epos) ; + /*-------------- descend into (d-1)-face data */ iptr_type _ipos; for (_ipos = +2; _ipos-- != 0; ) { - node_type _ndat; - _ndat.node(0) = + node_type _ndat; + _ndat.node(0) = _iter->node( _ipos) ; - + push_node( _ndat, true, _epos) ; } } } - + /* -------------------------------------------------------- * NULL-ITEM: TRUE if item is delete-able. -------------------------------------------------------- */ - + __inline_call bool_type null_node ( iptr_type _npos - ) + ) const { return this->_set1[_npos].self()==0 && this->_adj1.empty(_npos); } - + __inline_call bool_type null_edge ( iptr_type _epos - ) + ) const { return this->_set2[_epos].self()==0 && this->_adj2.empty(_epos); } - + /* -------------------------------------------------------- * _POP-LIST: delete item from adj. list. -------------------------------------------------------- */ - + __normal_call void_type _pop_list ( conn_list &_list, iptr_type _lpos, @@ -694,46 +676,46 @@ _prev = _list.hend(_lpos), _iter = _list.head(_lpos), _tend = _list.tend(_lpos); - - for ( ; _iter != _tend; + + for ( ; _iter != _tend; _prev = _iter, ++_iter) { if(*_iter == _itop) { _list._pop ( - _prev, _iter, _lpos) ; - + _prev, _iter, _lpos) ; + break ; } } } - + /* -------------------------------------------------------- * _POP-NODE: delete 0-node from complex. -------------------------------------------------------- */ - - __normal_call void_type _pop_node ( - iptr_type*_nptr , + + __inline_call void_type _pop_node ( + iptr_type const*_nptr, iptr_type _itop = -1 ) { iptr_type _npos = -1 ; - + iptr_type _node[1]; _node[0] = _nptr[0]; - + /*-------------------------- find current 0-node pos. */ - if ((_npos = _node[0]) < +0) + if ( !find_node (_node, _npos)) { return ; } - - /*-------------------------- _pop current 0-node data */ + + /*-------------------------- _pop current 0-node data */ _pop_node(_npos, _itop) ; } - + __normal_call void_type _pop_node ( iptr_type _npos , iptr_type _itop @@ -751,52 +733,48 @@ this-> _set1[_npos].self() = 0 ; } - + if (null_node (_npos)) { /*---- ref. count: delete (d+0), (d-1)-faces if empty */ - - iptr_type _same ; - this->_map1._pop(_npos, _same); - - _put_node(_npos); + _put_node (_npos); } } - + /* -------------------------------------------------------- * _POP-EDGE: delete 1-edge from complex. -------------------------------------------------------- */ - + __normal_call void_type _pop_edge ( - iptr_type*_nptr , + iptr_type const*_nptr, iptr_type _itop = -1 ) { iptr_type _epos = -1 ; - + iptr_type _node[2]; _node[0] = _nptr[0]; _node[1] = _nptr[1]; - + /*-------------------------- find current 1-edge pos. */ if ( !find_edge (_node, _epos)) { return ; } - - /*-------------------------- _pop current 1-edge data */ + + /*-------------------------- _pop current 1-edge data */ _pop_edge(_epos, _itop) ; } - + __normal_call void_type _pop_edge ( iptr_type _epos , iptr_type _itop = -1 ) - { + { iptr_type _npos = -1 ; - + if (_itop != -1) { /*---- deleteing (d+k)-face: scan adj. and _pop _itop */ @@ -809,21 +787,21 @@ this-> _set2[_epos].self() = 0 ; } - + if (null_edge (_epos)) { /*---- ref. count: delete (d+0), (d-1)-faces if empty */ iptr_type _same ; this->_map2._pop(_epos, _same); - + iptr_type _node [ 2] ; _node[0] = this-> _set2[_epos].node(0) ; _node[1] = this-> _set2[_epos].node(1) ; - + _put_edge(_epos); - + for (_npos = 2; _npos-- != 0; ) { _pop_node( @@ -831,27 +809,57 @@ } } } - + + /* + -------------------------------------------------------- + * FIND-NODE: return index of assoc. 0-node. + -------------------------------------------------------- + */ + + __normal_call bool_type find_node ( + iptr_type const*_nptr , + iptr_type&_npos + ) const + { + /*-------------------------- find current 0-node pos. */ + iptr_type _node = *_nptr ; + + if (_node >= +0 && _node < + (iptr_type)this->_set1.count() && + _set1 [_node].mark() >= +0) + { + /*------------------------------- found matching node */ + _npos =_node ; + + return true ; + } + else + { + /*------------------------------- couldn't find match */ + return false ; + } + } + /* -------------------------------------------------------- * FIND-EDGE: return index of assoc. 1-edge. -------------------------------------------------------- */ - + __normal_call bool_type find_edge ( - iptr_type*_node, + iptr_type const*_node , iptr_type&_epos ) { - /*-------------------------- find current 1-edge pos. */ + /*-------------------------- find current 1-edge pos. */ iptr_type _ipos = _get_edge() ; - + this-> _set2[_ipos].node(0)=_node[0]; this-> - _set2[_ipos].node(1)=_node[1]; - - typename edge_maps::_write_it + _set2[_ipos].node(1)=_node[1]; + + typename edge_maps::_write_it _same ; if (this-> _map2.find(_ipos, _same)) @@ -860,7 +868,7 @@ _put_edge(_ipos) ; _epos=*_same ; - + return true ; } else @@ -871,24 +879,24 @@ return false ; } } - + /* -------------------------------------------------------- * NODE-EDGE: form node-to-edge adj. list. -------------------------------------------------------- */ - + template < typename list_type > - __normal_call void_type node_edge ( - iptr_type*_node, + __inline_call void_type node_edge ( + iptr_type const*_node , list_type&_conn ) { node_edge(_node [ 0], _conn) ; - } - + } + template < typename list_type > @@ -896,20 +904,20 @@ iptr_type _npos, list_type&_conn ) - { + { this->_tmp1.set_count( +0 ) ; this->_tmp2.set_count( +0 ) ; - + this->_tmp1.push_tail(_npos) ; - + /*-------------------------- find set of adj. 1-edges */ - for (auto _iter = this->_tmp1.head(); + for (auto _iter = this->_tmp1.head(); _iter != this->_tmp1.tend(); ++_iter ) { - for (auto _iadj = + for (auto _iadj = this->_adj1.head(*_iter) ; - _iadj != + _iadj != this->_adj1.tend(*_iter) ; ++_iadj ) { @@ -922,16 +930,16 @@ } } } - + /*-------------------------- flip d-face marker lists */ - for (auto _iter = _conn.head() ; + for (auto _iter = _conn.head() ; _iter != _conn.tend() ; ++_iter ) { this->_set2 [*_iter].mark() = +0; } } - + } ; diff --git a/src/libcpp/mesh_type/tria_complex_2.hpp b/src/libcpp/mesh_type/tria_complex_2.hpp index f1a597d..048f44e 100644 --- a/src/libcpp/mesh_type/tria_complex_2.hpp +++ b/src/libcpp/mesh_type/tria_complex_2.hpp @@ -1,39 +1,39 @@ /* -------------------------------------------------------- - * TRIA-COMPLEX-2: piecewise tria. complex in R^2. + * TRIA-COMPLEX-2: piecewise tria. complex in R^2. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 11 April, 2018 + * Last updated: 30 June, 2019 * - * Copyright 2013-2018 + * Copyright 2013-2019 * Darren Engwirda * de2363@columbia.edu * https://github.com/dengwirda/ @@ -58,12 +58,12 @@ * ALLOCATOR - memory allocator -------------------------------------------------------- */ - + template < typename NN , typename E2 , typename T3 , - typename AA = allocators::basic_alloc + typename AA = allocators::basic_alloc > class tria_complex_2 { @@ -74,49 +74,49 @@ typedef T3 tri3_type ; typedef AA allocator ; - typedef typename + typedef typename node_type::real_type real_type ; - typedef typename - tri3_type::iptr_type iptr_type ; + typedef typename + tri3_type::iptr_type iptr_type ; typedef typename allocator::size_type size_type ; iptr_type static constexpr _dims = +2 ; typedef containers::block_array < - node_type, + node_type, allocator > node_list ; typedef containers::block_array < - edge_type, + edge_type, allocator > edge_list ; typedef containers::block_array < - tri3_type, + tri3_type, allocator > tri3_list ; typedef containers::array < - iptr_type, + iptr_type, allocator > iptr_list ; - + #define __hashscal sizeof(iptr_type)/sizeof(uint32_t) class node_hash { public : - __const_ptr(node_list) _nset ; + __const_ptr(node_list) _nset ; public : /*----------------------- build hash _obj. from _src. */ __inline_call node_hash ( node_list *_nsrc ) : _nset( _nsrc) {} /*----------------------- hash node indexing for node */ - __inline_call - iptr_type operator() ( + __inline_call + uint32_t operator() ( iptr_type _npos ) const { - return this->_nset-> + return (uint32_t)this->_nset-> operator[](_npos).node( 0) ; } } ; @@ -124,15 +124,15 @@ class edge_hash { public : - __const_ptr(edge_list) _eset ; + __const_ptr(edge_list) _eset ; public : /*----------------------- build hash _obj. from _src. */ __inline_call edge_hash ( edge_list *_esrc ) : _eset( _esrc) {} /*----------------------- hash node indexing for edge */ - __inline_call - iptr_type operator() ( + __inline_call + uint32_t operator() ( iptr_type _epos ) const { @@ -143,27 +143,27 @@ operator[](_epos).node( 1) ; algorithms::isort ( - &_enod[0], &_enod[2] , + &_enod[0], &_enod[2] , std::less()); - + return hash::hashword ( (uint32_t*)&_enod[0] , +2 * __hashscal, +137) ; } } ; - + class tri3_hash { public : - __const_ptr(tri3_list) _tset ; + __const_ptr(tri3_list) _tset ; public : /*----------------------- build hash _obj. from _src. */ __inline_call tri3_hash ( tri3_list *_tsrc ) : _tset( _tsrc) {} /*----------------------- hash node indexing for face */ - __inline_call - iptr_type operator() ( + __inline_call + uint32_t operator() ( iptr_type _tpos ) const { @@ -176,28 +176,28 @@ operator[](_tpos).node( 2) ; algorithms::isort ( - &_tnod[0], &_tnod[3] , + &_tnod[0], &_tnod[3] , std::less()); - + return hash::hashword ( (uint32_t*)&_tnod[0] , +3 * __hashscal, +137) ; } } ; - - + + class node_pred { public : - __const_ptr(node_list) _nset ; + __const_ptr(node_list) _nset ; public : /*----------------------- build hash _obj. from _src. */ __inline_call node_pred ( node_list *_nsrc ) : _nset( _nsrc) {} /*----------------------- compute "equal-to" for node */ - __inline_call - iptr_type operator() ( + __inline_call + bool_type operator() ( iptr_type _ipos, iptr_type _jpos ) const @@ -205,28 +205,27 @@ iptr_type _inod[1]; _inod[0] = this->_nset-> operator[](_ipos).node( 0) ; - + iptr_type _jnod[1]; _jnod[0] = this->_nset-> operator[](_jpos).node( 0) ; - - return ( _inod[0] == - _jnod[0] ); + + return _inod[0] == _jnod[0] ; } } ; - + class edge_pred { public : - __const_ptr(edge_list) _eset ; + __const_ptr(edge_list) _eset ; public : /*----------------------- build hash _obj. from _src. */ __inline_call edge_pred ( edge_list *_esrc ) : _eset( _esrc) {} /*----------------------- compute "equal-to" for edge */ - __inline_call - iptr_type operator() ( + __inline_call + bool_type operator() ( iptr_type _ipos, iptr_type _jpos ) const @@ -236,7 +235,7 @@ operator[](_ipos).node( 0) ; _inod[1] = this->_eset-> operator[](_ipos).node( 1) ; - + iptr_type _jnod[2]; _jnod[0] = this->_eset-> operator[](_jpos).node( 0) ; @@ -244,32 +243,30 @@ operator[](_jpos).node( 1) ; algorithms::isort ( - &_inod[0], &_inod[2], + &_inod[0], &_inod[2], std::less()); algorithms::isort ( - &_jnod[0], &_jnod[2], + &_jnod[0], &_jnod[2], std::less()); - - return ( _inod[0] == - _jnod[0] && - _inod[1] == - _jnod[1] ); + + return _inod[0] == _jnod[0] && + _inod[1] == _jnod[1] ; } } ; - + class tri3_pred { public : - __const_ptr(tri3_list) _tset ; + __const_ptr(tri3_list) _tset ; public : /*----------------------- build hash _obj. from _src. */ __inline_call tri3_pred ( tri3_list *_tsrc ) : _tset( _tsrc) {} /*----------------------- compute "equal-to" for face */ - __inline_call - iptr_type operator() ( + __inline_call + bool_type operator() ( iptr_type _ipos, iptr_type _jpos ) const @@ -281,7 +278,7 @@ operator[](_ipos).node( 1) ; _inod[2] = this->_tset-> operator[](_ipos).node( 2) ; - + iptr_type _jnod[3]; _jnod[0] = this->_tset-> operator[](_jpos).node( 0) ; @@ -291,22 +288,19 @@ operator[](_jpos).node( 2) ; algorithms::isort ( - &_inod[0], &_inod[3], + &_inod[0], &_inod[3], std::less()); algorithms::isort ( - &_jnod[0], &_jnod[3], + &_jnod[0], &_jnod[3], std::less()); - - return ( _inod[0] == - _jnod[0] && - _inod[1] == - _jnod[1] && - _inod[2] == - _jnod[2] ); + + return _inod[0] == _jnod[0] && + _inod[1] == _jnod[1] && + _inod[2] == _jnod[2] ; } } ; - + #undef __hashscal iptr_type static const pool_byte_size=96*1024 ; @@ -318,24 +312,24 @@ typedef allocators::_wrap_alloc < pool_base > pool_wrap ; - typedef containers::hash_table < - iptr_type, - node_hash, - node_pred, - pool_wrap> node_maps ; + //typedef containers::hash_table < + // iptr_type, + // node_hash, + // node_pred, + // pool_wrap> node_maps ; typedef containers::hash_table < - iptr_type, - edge_hash, + iptr_type, + edge_hash, edge_pred, pool_wrap> edge_maps ; - + typedef containers::hash_table < - iptr_type, - tri3_hash, + iptr_type, + tri3_hash, tri3_pred, pool_wrap> tri3_maps ; - + typedef containers::array_list < iptr_type, pool_wrap > conn_list ; @@ -349,18 +343,18 @@ conn_list _adj2 ; conn_list _adj3 ; - node_maps _map1 ; + //node_maps _map1 ; edge_maps _map2 ; tri3_maps _map3 ; - + node_list _set1 ; edge_list _set2 ; tri3_list _set3 ; - + iptr_list _del1 ; iptr_list _del2 ; iptr_list _del3 ; - + iptr_list _tmp1 ; iptr_list _tmp2 ; iptr_list _tmp3 ; @@ -373,7 +367,7 @@ * GET-NODE: "create" new node, push onto active set. -------------------------------------------------------- */ - + __inline_call iptr_type _get_node ( ) { @@ -393,16 +387,16 @@ this->_set1[_ipos].mark() = +0 ; this->_set1[_ipos].self() = +0 ; - + return ( _ipos ) ; } - + /* -------------------------------------------------------- * GET-EDGE: "create" new edge, push onto active set. -------------------------------------------------------- */ - + __inline_call iptr_type _get_edge ( ) { @@ -431,7 +425,7 @@ * GET-TRIA: "create" new tria, push onto active set. -------------------------------------------------------- */ - + __inline_call iptr_type _get_tri3 ( ) { @@ -454,13 +448,13 @@ return ( _ipos ) ; } - + /* -------------------------------------------------------- * PUT-ITEM: "delete" old item, _pop from active set. -------------------------------------------------------- */ - + __inline_call void_type _put_node ( iptr_type _ipos ) @@ -469,7 +463,7 @@ this->_set1[_ipos].mark() = -1 ; this->_set1[_ipos].self() = -1 ; } - + __inline_call void_type _put_edge ( iptr_type _ipos ) @@ -478,7 +472,7 @@ this->_set2[_ipos].mark() = -1 ; this->_set2[_ipos].self() = -1 ; } - + __inline_call void_type _put_tri3 ( iptr_type _ipos ) @@ -487,15 +481,15 @@ this->_set3[_ipos].mark() = -1 ; this->_set3[_ipos].self() = -1 ; } - + public : - + /* -------------------------------------------------------- * construct tria_complex from alloc. etc... -------------------------------------------------------- */ - + __normal_call tria_complex_2 ( allocator const& _asrc = allocator() ) : _hsrc(sizeof ( @@ -507,17 +501,17 @@ _adj2(pool_wrap(&_csrc)), _adj3(pool_wrap(&_csrc)), /*------------------------------ init. hash lists */ - _map1( - node_hash(& this->_set1) , - node_pred(& this->_set1) , - +.8, (pool_wrap(&_hsrc))) , + //_map1( + // node_hash(& this->_set1) , + // node_pred(& this->_set1) , + //+.8, (pool_wrap(&_hsrc))) , _map2( - edge_hash(& this->_set2) , - edge_pred(& this->_set2) , + edge_hash(& this->_set2) , + edge_pred(& this->_set2) , +.8, (pool_wrap(&_hsrc))) , _map3( - tri3_hash(& this->_set3) , - tri3_pred(& this->_set3) , + tri3_hash(& this->_set3) , + tri3_pred(& this->_set3) , +.8, (pool_wrap(&_hsrc))) , /*------------------------------ init. face lists */ _set1(_asrc),_set2(_asrc) , @@ -530,47 +524,48 @@ _tmp3(_asrc) { } - + /* -------------------------------------------------------- * 'clear' a tria-complex -------------------------------------------------------- */ - + __normal_call void_type clear ( - containers::alloc_types _kind = + containers::alloc_types _kind = containers::loose_alloc ) { this->_adj1.clear (_kind) ; this->_adj2.clear (_kind) ; this->_adj3.clear (_kind) ; - - this->_map1.clear (_kind) ; + + //this->_map1.clear (_kind) ; this->_map2.clear (_kind) ; this->_map3.clear (_kind) ; this->_set1.clear (_kind) ; this->_set2.clear (_kind) ; this->_set3.clear (_kind) ; - + this->_del1.clear (_kind) ; this->_del2.clear (_kind) ; this->_del3.clear (_kind) ; - + this->_tmp1.clear (_kind) ; this->_tmp2.clear (_kind) ; this->_tmp3.clear (_kind) ; - - //!!do something with pool'd-alloc? + + this->_hsrc.clear (); + this->_csrc.clear (); } - + /* -------------------------------------------------------- * INIT-LIST: re-size adj. lists on demand. -------------------------------------------------------- */ - + __inline_call void_type init_list ( conn_list&_list, size_type _lpos @@ -578,146 +573,123 @@ { if (_lpos >= _list._lptr.count()) _list._lptr.set_count ( - _lpos + 1, + _lpos + 1, containers::loose_alloc, nullptr) ; } - + /* -------------------------------------------------------- * PUSH-NODE: append new 0-node to complex. -------------------------------------------------------- */ - + __normal_call iptr_type push_node ( - node_type const&_ndat, + node_type const& _ndat, bool_type _link = true, iptr_type _itop = -1 ) { - iptr_type _ipos = _get_node() ; - + iptr_type _ipos = -1 ; + if (!_link) { - + + __assert( _itop == -1 && + "tria-complex: non-top node!" ) ; + /*------------------------ init. external d-face data */ + _ipos = _get_node(); + this->_set1[_ipos] = _ndat ; this->_set1[_ipos].mark() = 0 ; - + this->_set1[_ipos].self() = 1 ; this-> _set1 [_ipos].node(0) =_ipos ; - - /*------------------------ push face data to hash set */ - this->_map1.push(_ipos) ; - + /*------------------------ init. local adj. index set */ init_list(this->_adj1, _ipos) ; - + } else { - + + if (_itop == -1) + { /*------------------------ init. external d-face data */ + _ipos = _get_node(); + this->_set1[_ipos] = _ndat ; this->_set1[_ipos].mark() = 0 ; - - if (_itop == -1) - { this->_set1[_ipos].self() = 1 ; + this-> - _set1 [_ipos].node(0) =_ipos ; - } - else - this->_set1[_ipos].self() = 0 ; - - typename - node_maps::_write_it _same ; - if (this-> - _map1.find(_ipos , _same)) - { - /*---- existing d-face found: append to existing data */ - if (_itop == -1) - { - /*----- if it's a "top"-level face, copy data */ - this->_set1[*_same] = - this->_set1[ _ipos] ; - } - else - { - /*----- otherwise, append index to adj. lists */ - this-> - _adj1.push(_itop,*_same) ; - } - - _put_node(_ipos) ; + _set1 [_ipos].node(0) = _ipos; + + /*------------------------ init. local adj. index set */ + init_list(this->_adj1, _ipos) ; + } else { - /*---- d-face is new: push and descend to (d-1)-faces */ - if (_itop == -1) - { - /*----- if it's a "top"-level face, keep data */ - init_list( - this->_adj1, _ipos) ; - } - else - { - /*----- otherwise, append index to adj. lists */ - this-> - _adj1.push(_itop, _ipos) ; - } - - /*-------------- push new face data onto hash */ - this->_map1.push(_ipos) ; + /*------------------------ init. internal d-face data */ + __assert(find_node( + &_ndat.node(0), _ipos) && + "tria-complex: node not here" ); + + /*------------------------ append index to adj. lists */ + this->_adj1.push( + _itop, _ndat.node(0)) ; + } - + } - + return _ipos ; } - + /* -------------------------------------------------------- * PUSH-EDGE: append new 1-edge to complex. -------------------------------------------------------- */ - + __normal_call iptr_type push_edge ( - edge_type const&_edat, + edge_type const& _edat, bool_type _link = true, - iptr_type _itop = -1 + iptr_type _itop = -1 ) { iptr_type _ipos = _get_edge() ; iptr_type _npos ; - + if (!_link) { - - /*-------------------- init. external d-face data */ + + __assert( _itop == -1 && + "tria-complex: non-top cell!" ) ; + + /*------------------------ init. external d-face data */ this->_set2[_ipos] = _edat ; this->_set2[_ipos].mark() = 0 ; this->_set2[_ipos].self() = 1 ; - - /*-------------------- push face data to hash set */ - this->_map2.push(_ipos) ; - - /*-------------------- init. local adj. index set */ + + /*------------------------ init. local adj. index set */ init_list(this->_adj2, _ipos) ; - + } else { - + /*------------------------ init. external d-face data */ this->_set2[_ipos] = _edat ; this->_set2[_ipos].mark() = 0 ; - + if (_itop == -1) this->_set2[_ipos].self() = 1 ; else this->_set2[_ipos].self() = 0 ; - + typename edge_maps::_write_it _same ; if (this-> @@ -735,13 +707,13 @@ /*----- otherwise, append index to adj. lists */ this-> _adj2.push(_itop,*_same) ; - } - - _put_edge(_ipos) ; + } + + _put_edge(_ipos) ; } else { - /*---- d-face is new: push and descend to (d-1)-faces */ + /*---- d-face is new: push and descend to (d-1)-faces */ if (_itop == -1) { /*----- if it's a "top"-level face, keep data */ @@ -754,69 +726,69 @@ this-> _adj2.push(_itop, _ipos) ; } - + /*-------------- descend into (d-1)-face data */ for (_npos = 2; _npos-- != 0; ) { - node_type _ndat; - _ndat.node(0) = + node_type _ndat; + _ndat.node(0) = _edat.node(_npos) ; - + push_node( _ndat, _link, _ipos) ; } - + /*-------------- push new face data onto hash */ this->_map2.push(_ipos) ; } - + } - + return _ipos ; } - + /* -------------------------------------------------------- * PUSH-TRIA: append new 2-tria to complex. -------------------------------------------------------- */ - + __normal_call iptr_type push_tri3 ( - tri3_type const&_tdat, + tri3_type const& _tdat, bool_type _link = true, - iptr_type _itop = -1 + iptr_type _itop = -1 ) { iptr_type _ipos = _get_tri3() ; iptr_type _epos ; - + if (!_link) { - + + __assert( _itop == -1 && + "tria-complex: non-top cell!" ) ; + /*-------------------- init. external d-face data */ this->_set3[_ipos] = _tdat ; this->_set3[_ipos].mark() = 0 ; this->_set3[_ipos].self() = 1 ; - - /*-------------------- push face data to hash set */ - this->_map3.push(_ipos) ; - + /*-------------------- init. local adj. index set */ init_list(this->_adj3, _ipos) ; - + } else { - + /*------------------------ init. external d-face data */ this->_set3[_ipos] = _tdat ; this->_set3[_ipos].mark() = 0 ; - + if (_itop == -1) this->_set3[_ipos].self() = 1 ; else this->_set3[_ipos].self() = 0 ; - + typename tri3_maps::_write_it _same ; if (this-> @@ -834,13 +806,13 @@ /*----- otherwise, append index to adj. lists */ this-> _adj3.push(_itop,*_same) ; - } - - _put_tri3(_ipos) ; + } + + _put_tri3(_ipos) ; } else { - /*---- d-face is new: push and descend to (d-1)-faces */ + /*---- d-face is new: push and descend to (d-1)-faces */ if (_itop == -1) { /*----- if it's a "top"-level face, keep data */ @@ -853,69 +825,84 @@ this-> _adj3.push(_itop, _ipos) ; } - + /*-------------- descend into (d-1)-face data */ for (_epos = +3; _epos-- != 0 ; ) { iptr_type _enod [3]; tri3_type::face_node( - _enod, _epos, 2, 1 ) ; - + _enod, _epos, 2, 1) ; + edge_type _edat ; - _edat.node(0) = + _edat.node(0) = _tdat.node(_enod[0]) ; - _edat.node(1) = + _edat.node(1) = _tdat.node(_enod[1]) ; - + push_edge( _edat, _link, _ipos) ; } - + /*-------------- push new face data onto hash */ this->_map3.push(_ipos) ; } - + } - + return _ipos ; } - + /* -------------------------------------------------------- - * MAKE-PTRS: build item-to-item adj. + * MAKE-LINK: build item-to-item adj. -------------------------------------------------------- */ - - __normal_call void_type make_ptrs ( + + __normal_call void_type make_link ( ) { + this->_map2.set_slots( + (this->_set2.count()*5)/4 + 1 + + (this->_set3.count()*5)/2 + 1 + ) ; + + this->_map3.set_slots( + (this->_set3.count()*5)/4 + 1 + ) ; + this->_adj1.empty () ; this->_adj2.empty () ; this->_adj3.empty () ; - + iptr_type _epos = +0 ; for (auto _iter = this->_set2.head(); _iter != this->_set2.tend(); ++_iter, ++_epos ) { + /*-------------- push face data onto hash set */ + this->_map2.push(_epos) ; + /*-------------- descend into (d-1)-face data */ iptr_type _ipos; for (_ipos = +2; _ipos-- != 0; ) { - node_type _ndat; - _ndat.node(0) = + node_type _ndat; + _ndat.node(0) = _iter->node( _ipos) ; - + push_node( _ndat, true, _epos) ; } } - + iptr_type _tpos = +0 ; for (auto _iter = this->_set3.head(); _iter != this->_set3.tend(); ++_iter, ++_tpos ) { + /*-------------- push face data onto hash set */ + this->_map3.push(_tpos) ; + /*-------------- descend into (d-1)-face data */ iptr_type _ipos; for (_ipos = +3; _ipos-- != 0; ) @@ -923,55 +910,55 @@ iptr_type _enod [3]; tri3_type::face_node( _enod, _ipos, 2, 1 ) ; - + edge_type _edat ; - _edat.node(0) = + _edat.node(0) = _iter->node(_enod[0]) ; - _edat.node(1) = + _edat.node(1) = _iter->node(_enod[1]) ; - + push_edge( _edat, true , _tpos) ; } } } - + /* -------------------------------------------------------- * NULL-ITEM: TRUE if item is delete-able. -------------------------------------------------------- */ - + __inline_call bool_type null_node ( iptr_type _npos - ) + ) const { return this->_set1[_npos].self()==0 && this->_adj1.empty(_npos); } - + __inline_call bool_type null_edge ( iptr_type _epos - ) + ) const { return this->_set2[_epos].self()==0 && this->_adj2.empty(_epos); } - + __inline_call bool_type null_tri3 ( iptr_type _tpos - ) + ) const { return this->_set3[_tpos].self()==0 && this->_adj3.empty(_tpos); } - + /* -------------------------------------------------------- * _POP-LIST: delete item from adj. list. -------------------------------------------------------- */ - + __normal_call void_type _pop_list ( conn_list &_list, iptr_type _lpos, @@ -983,46 +970,46 @@ _prev = _list.hend(_lpos), _iter = _list.head(_lpos), _tend = _list.tend(_lpos); - - for ( ; _iter != _tend; + + for ( ; _iter != _tend; _prev = _iter, ++_iter) { if(*_iter == _itop) { _list._pop ( - _prev, _iter, _lpos) ; - + _prev, _iter, _lpos) ; + break ; } } } - + /* -------------------------------------------------------- * _POP-NODE: delete 0-node from complex. -------------------------------------------------------- */ - + __normal_call void_type _pop_node ( - iptr_type*_nptr , + iptr_type const*_nptr, iptr_type _itop = -1 ) { iptr_type _npos = -1 ; - + iptr_type _node[1]; _node[0] = _nptr[0]; - + /*-------------------------- find current 0-node pos. */ - if ((_npos = _node[0]) < +0) + if ( !find_node (_node, _npos)) { return ; } - - /*-------------------------- _pop current 0-node data */ + + /*-------------------------- _pop current 0-node data */ _pop_node(_npos, _itop) ; } - + __normal_call void_type _pop_node ( iptr_type _npos , iptr_type _itop @@ -1040,52 +1027,48 @@ this-> _set1[_npos].self() = 0 ; } - + if (null_node (_npos)) { /*---- ref. count: delete (d+0), (d-1)-faces if empty */ - - iptr_type _same ; - this->_map1._pop(_npos, _same); - - _put_node(_npos); + _put_node (_npos); } } - + /* -------------------------------------------------------- * _POP-EDGE: delete 1-edge from complex. -------------------------------------------------------- */ - + __normal_call void_type _pop_edge ( - iptr_type*_nptr , + iptr_type const*_nptr, iptr_type _itop = -1 ) { iptr_type _epos = -1 ; - + iptr_type _node[2]; _node[0] = _nptr[0]; _node[1] = _nptr[1]; - + /*-------------------------- find current 1-edge pos. */ if ( !find_edge (_node, _epos)) { return ; } - - /*-------------------------- _pop current 1-edge data */ + + /*-------------------------- _pop current 1-edge data */ _pop_edge(_epos, _itop) ; } - + __normal_call void_type _pop_edge ( iptr_type _epos , iptr_type _itop = -1 ) - { + { iptr_type _npos = -1 ; - + if (_itop != -1) { /*---- deleteing (d+k)-face: scan adj. and _pop _itop */ @@ -1098,21 +1081,21 @@ this-> _set2[_epos].self() = 0 ; } - + if (null_edge (_epos)) { /*---- ref. count: delete (d+0), (d-1)-faces if empty */ iptr_type _same ; this->_map2._pop(_epos, _same); - + iptr_type _node [ 2] ; _node[0] = this-> _set2[_epos].node(0) ; _node[1] = this-> _set2[_epos].node(1) ; - + _put_edge(_epos); - + for (_npos = 2; _npos-- != 0; ) { _pop_node( @@ -1120,42 +1103,42 @@ } } } - + /* -------------------------------------------------------- * _POP-TRIA: delete 2-tria from complex. -------------------------------------------------------- */ - + __normal_call void_type _pop_tri3 ( - iptr_type*_nptr , + iptr_type const*_nptr, iptr_type _itop = -1 ) { iptr_type _tpos = -1 ; - + iptr_type _node[3]; _node[0] = _nptr[0]; _node[1] = _nptr[1]; _node[2] = _nptr[2]; - + /*-------------------------- find current 2-tria pos. */ if ( !find_tri3 (_node, _tpos)) { return ; } - - /*-------------------------- _pop current 2-tria data */ + + /*-------------------------- _pop current 2-tria data */ _pop_tri3(_tpos, _itop) ; } - + __normal_call void_type _pop_tri3 ( iptr_type _tpos , iptr_type _itop = -1 ) - { + { iptr_type _epos = -1 ; - + if (_itop != -1) { /*---- deleteing (d+k)-face: scan adj. and _pop _itop */ @@ -1168,14 +1151,14 @@ this-> _set3[_tpos].self() = 0 ; } - + if (null_tri3 (_tpos)) { /*---- ref. count: delete (d+0), (d-1)-faces if empty */ - + iptr_type _same ; this->_map3._pop(_tpos, _same); - + iptr_type _node [ 3] ; _node[0] = this-> _set3[_tpos].node(0) ; @@ -1183,45 +1166,75 @@ _set3[_tpos].node(1) ; _node[2] = this-> _set3[_tpos].node(2) ; - + _put_tri3(_tpos); - + for (_epos = 3; _epos-- != 0; ) { iptr_type _enod [3] ; tri3_type::face_node ( _enod, _epos, 2, 1) ; - - _enod[0] = + + _enod[0] = _node[_enod [0]]; - _enod[1] = + _enod[1] = _node[_enod [1]]; - + _pop_edge(_enod, _tpos) ; } } } - + + /* + -------------------------------------------------------- + * FIND-NODE: return index of assoc. 0-node. + -------------------------------------------------------- + */ + + __normal_call bool_type find_node ( + iptr_type const*_nptr , + iptr_type&_npos + ) const + { + /*-------------------------- find current 0-node pos. */ + iptr_type _node = *_nptr ; + + if (_node >= +0 && _node < + (iptr_type)this->_set1.count() && + _set1 [_node].mark() >= +0) + { + /*------------------------------- found matching node */ + _npos =_node ; + + return true ; + } + else + { + /*------------------------------- couldn't find match */ + return false ; + } + } + /* -------------------------------------------------------- * FIND-EDGE: return index of assoc. 1-edge. -------------------------------------------------------- */ - + __normal_call bool_type find_edge ( - iptr_type*_node, + iptr_type const*_node , iptr_type&_epos ) { - /*-------------------------- find current 1-edge pos. */ + /*-------------------------- find current 1-edge pos. */ iptr_type _ipos = _get_edge() ; - + this-> _set2[_ipos].node(0)=_node[0]; this-> - _set2[_ipos].node(1)=_node[1]; - - typename edge_maps::_write_it + _set2[_ipos].node(1)=_node[1]; + + typename edge_maps::_write_it _same ; if (this-> _map2.find(_ipos, _same)) @@ -1230,7 +1243,7 @@ _put_edge(_ipos) ; _epos=*_same ; - + return true ; } else @@ -1241,29 +1254,29 @@ return false ; } } - + /* -------------------------------------------------------- * FIND-TRIA: return index of assoc. 2-tria. -------------------------------------------------------- */ - + __normal_call bool_type find_tri3 ( - iptr_type*_node, + iptr_type const*_node , iptr_type&_tpos ) { - /*-------------------------- find current 2-tria pos. */ + /*-------------------------- find current 2-tria pos. */ iptr_type _ipos = _get_tri3() ; - + this-> _set3[_ipos].node(0)=_node[0]; this-> _set3[_ipos].node(1)=_node[1]; this-> - _set3[_ipos].node(2)=_node[2]; - - typename tri3_maps::_write_it + _set3[_ipos].node(2)=_node[2]; + + typename tri3_maps::_write_it _same ; if (this-> _map3.find(_ipos, _same)) @@ -1272,7 +1285,7 @@ _put_tri3(_ipos) ; _tpos=*_same ; - + return true ; } else @@ -1283,25 +1296,25 @@ return false ; } } - - + + /* -------------------------------------------------------- * NODE-EDGE: form node-to-edge adj. list. -------------------------------------------------------- */ - + template < typename list_type > - __normal_call void_type node_edge ( - iptr_type*_node, + __inline_call void_type node_edge ( + iptr_type const*_node , list_type&_conn ) { node_edge(_node [ 0], _conn) ; - } - + } + template < typename list_type > @@ -1309,21 +1322,21 @@ iptr_type _npos, list_type&_conn ) - { + { this->_tmp1.set_count( +0 ) ; this->_tmp2.set_count( +0 ) ; this->_tmp3.set_count( +0 ) ; - + this->_tmp1.push_tail(_npos) ; - + /*-------------------------- find set of adj. 1-edges */ - for (auto _iter = this->_tmp1.head(); + for (auto _iter = this->_tmp1.head(); _iter != this->_tmp1.tend(); ++_iter ) { - for (auto _iadj = + for (auto _iadj = this->_adj1.head(*_iter) ; - _iadj != + _iadj != this->_adj1.tend(*_iter) ; ++_iadj ) { @@ -1336,33 +1349,33 @@ } } } - + /*-------------------------- flip d-face marker lists */ - for (auto _iter = _conn.head() ; + for (auto _iter = _conn.head() ; _iter != _conn.tend() ; ++_iter ) { this->_set2 [*_iter].mark() = +0; } } - + /* -------------------------------------------------------- * NODE-TRIA: form node-to-tria adj. list. -------------------------------------------------------- */ - + template < typename list_type > - __normal_call void_type node_tri3 ( - iptr_type*_node, + __inline_call void_type node_tri3 ( + iptr_type const*_node , list_type&_conn ) { node_tri3(_node [ 0], _conn) ; } - + template < typename list_type > @@ -1370,21 +1383,21 @@ iptr_type _npos, list_type&_conn ) - { + { this->_tmp1.set_count( +0 ) ; this->_tmp2.set_count( +0 ) ; this->_tmp3.set_count( +0 ) ; - + this->_tmp1.push_tail(_npos) ; - + /*-------------------------- find set of adj. 1-edges */ - for (auto _iter = this->_tmp1.head(); + for (auto _iter = this->_tmp1.head(); _iter != this->_tmp1.tend(); ++_iter ) { - for (auto _iadj = + for (auto _iadj = this->_adj1.head(*_iter) ; - _iadj != + _iadj != this->_adj1.tend(*_iter) ; ++_iadj ) { @@ -1399,13 +1412,13 @@ } } /*-------------------------- find set of adj. 2-trias */ - for (auto _iter = this->_tmp2.head(); + for (auto _iter = this->_tmp2.head(); _iter != this->_tmp2.tend(); ++_iter ) { - for (auto _iadj = + for (auto _iadj = this->_adj2.head(*_iter) ; - _iadj != + _iadj != this->_adj2.tend(*_iter) ; ++_iadj ) { @@ -1418,16 +1431,16 @@ } } } - + /*-------------------------- flip d-face marker lists */ - for (auto _iter = _conn.head() ; + for (auto _iter = _conn.head() ; _iter != _conn.tend() ; ++_iter ) { this->_set3 [*_iter].mark() = 0 ; } for (auto _iter = this-> - _tmp2.head() ; + _tmp2.head() ; _iter != this-> _tmp2.tend() ; ++_iter ) @@ -1435,32 +1448,32 @@ this->_set2 [*_iter].mark() = 0 ; } } - + /* -------------------------------------------------------- * EDGE-TRIA: form edge-to-tria adj. list. -------------------------------------------------------- */ - + template < typename list_type > - __normal_call void_type edge_tri3 ( - iptr_type*_node, + __inline_call void_type edge_tri3 ( + iptr_type const*_node , list_type&_conn ) { - /*-------------------------- find current 1-edge pos. */ + /*-------------------------- find current 1-edge pos. */ iptr_type _epos = -1; if (!find_edge(_node, _epos)) { return ; } - + /*-------------------------- get adj. for 1-edge pos. */ edge_tri3(_epos, _conn) ; } - + template < typename list_type > @@ -1472,17 +1485,17 @@ this->_tmp1.set_count( +0 ) ; this->_tmp2.set_count( +0 ) ; this->_tmp3.set_count( +0 ) ; - + this->_tmp2.push_tail(_epos) ; - + /*-------------------------- find set of adj. 2-faces */ - for (auto _iter = this->_tmp2.head(); + for (auto _iter = this->_tmp2.head(); _iter != this->_tmp2.tend(); ++_iter ) { - for (auto _iadj = + for (auto _iadj = this->_adj2.head(*_iter) ; - _iadj != + _iadj != this->_adj2.tend(*_iter) ; ++_iadj ) { @@ -1495,16 +1508,16 @@ } } } - + /*-------------------------- flip d-face marker lists */ - for (auto _iter = _conn.head() ; + for (auto _iter = _conn.head() ; _iter != _conn.tend() ; ++_iter ) { this->_set3 [*_iter].mark() = 0 ; } } - + } ; diff --git a/src/libcpp/mesh_type/tria_complex_3.hpp b/src/libcpp/mesh_type/tria_complex_3.hpp index 921cced..76b5504 100644 --- a/src/libcpp/mesh_type/tria_complex_3.hpp +++ b/src/libcpp/mesh_type/tria_complex_3.hpp @@ -1,39 +1,39 @@ /* -------------------------------------------------------- - * TRIA-COMPLEX-3: piecewise tria. complex in R^3. + * TRIA-COMPLEX-3: piecewise tria. complex in R^3. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 11 April, 2018 + * Last updated: 30 June, 2019 * - * Copyright 2013-2018 + * Copyright 2013-2019 * Darren Engwirda * de2363@columbia.edu * https://github.com/dengwirda/ @@ -59,13 +59,13 @@ * ALLOCATOR - memory allocator -------------------------------------------------------- */ - + template < typename NN , typename E2 , typename T3 , typename T4 , - typename AA = allocators::basic_alloc + typename AA = allocators::basic_alloc > class tria_complex_3 { @@ -77,9 +77,9 @@ typedef T4 tri4_type ; typedef AA allocator ; - typedef typename + typedef typename node_type::real_type real_type ; - typedef typename + typedef typename tri3_type::iptr_type iptr_type ; typedef typename allocator::size_type size_type ; @@ -87,39 +87,39 @@ iptr_type static constexpr _dims = +3 ; typedef containers::block_array < - node_type, + node_type, allocator > node_list ; typedef containers::block_array < - edge_type, + edge_type, allocator > edge_list ; typedef containers::block_array < - tri3_type, + tri3_type, allocator > tri3_list ; - + typedef containers::block_array < - tri4_type, + tri4_type, allocator > tri4_list ; typedef containers::array < - iptr_type, + iptr_type, allocator > iptr_list ; - + #define __hashscal sizeof(iptr_type)/sizeof(uint32_t) class node_hash { public : - __const_ptr(node_list) _nset ; + __const_ptr(node_list) _nset ; public : /*----------------------- build hash _obj. from _src. */ __inline_call node_hash ( node_list *_nsrc ) : _nset( _nsrc) {} /*----------------------- hash node indexing for node */ - __inline_call - iptr_type operator() ( + __inline_call + uint32_t operator() ( iptr_type _npos ) const { @@ -131,15 +131,15 @@ class edge_hash { public : - __const_ptr(edge_list) _eset ; + __const_ptr(edge_list) _eset ; public : /*----------------------- build hash _obj. from _src. */ __inline_call edge_hash ( edge_list *_esrc ) : _eset( _esrc) {} /*----------------------- hash node indexing for edge */ - __inline_call - iptr_type operator() ( + __inline_call + uint32_t operator() ( iptr_type _epos ) const { @@ -150,27 +150,27 @@ operator[](_epos).node( 1) ; algorithms::isort ( - &_enod[0], &_enod[2] , + &_enod[0], &_enod[2] , std::less()); - + return hash::hashword ( (uint32_t*)&_enod[0] , +2 * __hashscal, +137) ; } } ; - + class tri3_hash { public : - __const_ptr(tri3_list) _tset ; + __const_ptr(tri3_list) _tset ; public : /*----------------------- build hash _obj. from _src. */ __inline_call tri3_hash ( tri3_list *_tsrc ) : _tset( _tsrc) {} /*----------------------- hash node indexing for face */ - __inline_call - iptr_type operator() ( + __inline_call + uint32_t operator() ( iptr_type _tpos ) const { @@ -183,27 +183,27 @@ operator[](_tpos).node( 2) ; algorithms::isort ( - &_tnod[0], &_tnod[3] , + &_tnod[0], &_tnod[3] , std::less()); - + return hash::hashword ( (uint32_t*)&_tnod[0] , +3 * __hashscal, +137) ; } } ; - + class tri4_hash { public : - __const_ptr(tri4_list) _tset ; + __const_ptr(tri4_list) _tset ; public : /*----------------------- build hash _obj. from _src. */ __inline_call tri4_hash ( tri4_list *_tsrc ) : _tset( _tsrc) {} /*----------------------- hash node indexing for face */ - __inline_call - iptr_type operator() ( + __inline_call + uint32_t operator() ( iptr_type _tpos ) const { @@ -218,28 +218,28 @@ operator[](_tpos).node( 3) ; algorithms::isort ( - &_tnod[0], &_tnod[4] , + &_tnod[0], &_tnod[4] , std::less()); - + return hash::hashword ( (uint32_t*)&_tnod[0] , +4 * __hashscal, +137) ; } } ; - - + + class node_pred { public : - __const_ptr(node_list) _nset ; + __const_ptr(node_list) _nset ; public : /*----------------------- build hash _obj. from _src. */ __inline_call node_pred ( node_list *_nsrc ) : _nset( _nsrc) {} /*----------------------- compute "equal-to" for node */ - __inline_call - iptr_type operator() ( + __inline_call + bool_type operator() ( iptr_type _ipos, iptr_type _jpos ) const @@ -247,28 +247,27 @@ iptr_type _inod[1]; _inod[0] = this->_nset-> operator[](_ipos).node( 0) ; - + iptr_type _jnod[1]; _jnod[0] = this->_nset-> operator[](_jpos).node( 0) ; - - return ( _inod[0] == - _jnod[0] ); + + return _inod[0] == _jnod[0] ; } } ; - + class edge_pred { public : - __const_ptr(edge_list) _eset ; + __const_ptr(edge_list) _eset ; public : /*----------------------- build hash _obj. from _src. */ __inline_call edge_pred ( edge_list *_esrc ) : _eset( _esrc) {} /*----------------------- compute "equal-to" for edge */ - __inline_call - iptr_type operator() ( + __inline_call + bool_type operator() ( iptr_type _ipos, iptr_type _jpos ) const @@ -278,7 +277,7 @@ operator[](_ipos).node( 0) ; _inod[1] = this->_eset-> operator[](_ipos).node( 1) ; - + iptr_type _jnod[2]; _jnod[0] = this->_eset-> operator[](_jpos).node( 0) ; @@ -286,32 +285,30 @@ operator[](_jpos).node( 1) ; algorithms::isort ( - &_inod[0], &_inod[2], + &_inod[0], &_inod[2], std::less()); algorithms::isort ( - &_jnod[0], &_jnod[2], + &_jnod[0], &_jnod[2], std::less()); - - return ( _inod[0] == - _jnod[0] && - _inod[1] == - _jnod[1] ); + + return _inod[0] == _jnod[0] && + _inod[1] == _jnod[1] ; } } ; - + class tri3_pred { public : - __const_ptr(tri3_list) _tset ; + __const_ptr(tri3_list) _tset ; public : /*----------------------- build hash _obj. from _src. */ __inline_call tri3_pred ( tri3_list *_tsrc ) : _tset( _tsrc) {} /*----------------------- compute "equal-to" for face */ - __inline_call - iptr_type operator() ( + __inline_call + bool_type operator() ( iptr_type _ipos, iptr_type _jpos ) const @@ -323,7 +320,7 @@ operator[](_ipos).node( 1) ; _inod[2] = this->_tset-> operator[](_ipos).node( 2) ; - + iptr_type _jnod[3]; _jnod[0] = this->_tset-> operator[](_jpos).node( 0) ; @@ -333,34 +330,31 @@ operator[](_jpos).node( 2) ; algorithms::isort ( - &_inod[0], &_inod[3], + &_inod[0], &_inod[3], std::less()); algorithms::isort ( - &_jnod[0], &_jnod[3], + &_jnod[0], &_jnod[3], std::less()); - - return ( _inod[0] == - _jnod[0] && - _inod[1] == - _jnod[1] && - _inod[2] == - _jnod[2] ); + + return _inod[0] == _jnod[0] && + _inod[1] == _jnod[1] && + _inod[2] == _jnod[2] ; } } ; - + class tri4_pred { public : - __const_ptr(tri4_list) _tset ; + __const_ptr(tri4_list) _tset ; public : /*----------------------- build hash _obj. from _src. */ __inline_call tri4_pred ( tri4_list *_tsrc ) : _tset( _tsrc) {} /*----------------------- compute "equal-to" for face */ - __inline_call - iptr_type operator() ( + __inline_call + bool_type operator() ( iptr_type _ipos, iptr_type _jpos ) const @@ -374,7 +368,7 @@ operator[](_ipos).node( 2) ; _inod[3] = this->_tset-> operator[](_ipos).node( 3) ; - + iptr_type _jnod[4]; _jnod[0] = this->_tset-> operator[](_jpos).node( 0) ; @@ -386,24 +380,20 @@ operator[](_jpos).node( 3) ; algorithms::isort ( - &_inod[0], &_inod[4], + &_inod[0], &_inod[4], std::less()); algorithms::isort ( - &_jnod[0], &_jnod[4], + &_jnod[0], &_jnod[4], std::less()); - - return ( _inod[0] == - _jnod[0] && - _inod[1] == - _jnod[1] && - _inod[2] == - _jnod[2] && - _inod[3] == - _jnod[3] ); + + return _inod[0] == _jnod[0] && + _inod[1] == _jnod[1] && + _inod[2] == _jnod[2] && + _inod[3] == _jnod[3] ; } } ; - + #undef __hashscal iptr_type static const pool_byte_size=96*1024 ; @@ -415,30 +405,30 @@ typedef allocators::_wrap_alloc < pool_base > pool_wrap ; - typedef containers::hash_table < - iptr_type, - node_hash, - node_pred, - pool_wrap> node_maps ; + //typedef containers::hash_table < + // iptr_type, + // node_hash, + // node_pred, + // pool_wrap> node_maps ; typedef containers::hash_table < - iptr_type, - edge_hash, + iptr_type, + edge_hash, edge_pred, pool_wrap> edge_maps ; - + typedef containers::hash_table < - iptr_type, - tri3_hash, + iptr_type, + tri3_hash, tri3_pred, pool_wrap> tri3_maps ; - + typedef containers::hash_table < - iptr_type, - tri4_hash, + iptr_type, + tri4_hash, tri4_pred, pool_wrap> tri4_maps ; - + typedef containers::array_list < iptr_type, pool_wrap > conn_list ; @@ -447,27 +437,27 @@ pool_base _hsrc ; pool_base _csrc ; - + conn_list _adj1 ; conn_list _adj2 ; conn_list _adj3 ; conn_list _adj4 ; - node_maps _map1 ; + //node_maps _map1 ; edge_maps _map2 ; tri3_maps _map3 ; tri4_maps _map4 ; - + node_list _set1 ; edge_list _set2 ; tri3_list _set3 ; tri4_list _set4 ; - + iptr_list _del1 ; iptr_list _del2 ; iptr_list _del3 ; iptr_list _del4 ; - + iptr_list _tmp1 ; iptr_list _tmp2 ; iptr_list _tmp3 ; @@ -480,7 +470,7 @@ * GET-NODE: "create" new node, push onto active set. -------------------------------------------------------- */ - + __inline_call iptr_type _get_node ( ) { @@ -500,16 +490,16 @@ this->_set1[_ipos].mark() = +0 ; this->_set1[_ipos].self() = +0 ; - + return ( _ipos ) ; } - + /* -------------------------------------------------------- * GET-EDGE: "create" new edge, push onto active set. -------------------------------------------------------- */ - + __inline_call iptr_type _get_edge ( ) { @@ -538,7 +528,7 @@ * GET-TRIA: "create" new tria, push onto active set. -------------------------------------------------------- */ - + __inline_call iptr_type _get_tri3 ( ) { @@ -561,13 +551,13 @@ return ( _ipos ) ; } - + /* -------------------------------------------------------- * GET-TRIA: "create" new tria, push onto active set. -------------------------------------------------------- */ - + __inline_call iptr_type _get_tri4 ( ) { @@ -590,13 +580,13 @@ return ( _ipos ) ; } - + /* -------------------------------------------------------- * PUT-ITEM: "delete" old item, _pop from active set. -------------------------------------------------------- */ - + __inline_call void_type _put_node ( iptr_type _ipos ) @@ -605,7 +595,7 @@ this->_set1[_ipos].mark() = -1 ; this->_set1[_ipos].self() = -1 ; } - + __inline_call void_type _put_edge ( iptr_type _ipos ) @@ -614,7 +604,7 @@ this->_set2[_ipos].mark() = -1 ; this->_set2[_ipos].self() = -1 ; } - + __inline_call void_type _put_tri3 ( iptr_type _ipos ) @@ -623,7 +613,7 @@ this->_set3[_ipos].mark() = -1 ; this->_set3[_ipos].self() = -1 ; } - + __inline_call void_type _put_tri4 ( iptr_type _ipos ) @@ -632,15 +622,15 @@ this->_set4[_ipos].mark() = -1 ; this->_set4[_ipos].self() = -1 ; } - + public : - + /* -------------------------------------------------------- * construct tria_complex from alloc. etc... -------------------------------------------------------- */ - + __normal_call tria_complex_3 ( allocator const& _asrc = allocator() ) : _hsrc(sizeof ( @@ -653,21 +643,21 @@ _adj3(pool_wrap(&_csrc)), _adj4(pool_wrap(&_csrc)), /*------------------------------ init. hash lists */ - _map1( - node_hash(& this->_set1) , - node_pred(& this->_set1) , - +.8, (pool_wrap(&_hsrc))) , + //_map1( + // node_hash(& this->_set1) , + // node_pred(& this->_set1) , + //+.8, (pool_wrap(&_hsrc))) , _map2( - edge_hash(& this->_set2) , - edge_pred(& this->_set2) , + edge_hash(& this->_set2) , + edge_pred(& this->_set2) , +.8, (pool_wrap(&_hsrc))) , _map3( - tri3_hash(& this->_set3) , - tri3_pred(& this->_set3) , + tri3_hash(& this->_set3) , + tri3_pred(& this->_set3) , +.8, (pool_wrap(&_hsrc))) , _map4( - tri4_hash(& this->_set4) , - tri4_pred(& this->_set4) , + tri4_hash(& this->_set4) , + tri4_pred(& this->_set4) , +.8, (pool_wrap(&_hsrc))) , /*------------------------------ init. face lists */ _set1(_asrc),_set2(_asrc) , @@ -680,15 +670,15 @@ _tmp3(_asrc),_tmp4(_asrc) { } - + /* -------------------------------------------------------- * 'clear' a tria-complex -------------------------------------------------------- */ - + __normal_call void_type clear ( - containers::alloc_types _kind = + containers::alloc_types _kind = containers::loose_alloc ) { @@ -696,8 +686,8 @@ this->_adj2.clear (_kind) ; this->_adj3.clear (_kind) ; this->_adj4.clear (_kind) ; - - this->_map1.clear (_kind) ; + + //this->_map1.clear (_kind) ; this->_map2.clear (_kind) ; this->_map3.clear (_kind) ; this->_map4.clear (_kind) ; @@ -706,26 +696,27 @@ this->_set2.clear (_kind) ; this->_set3.clear (_kind) ; this->_set4.clear (_kind) ; - + this->_del1.clear (_kind) ; this->_del2.clear (_kind) ; this->_del3.clear (_kind) ; this->_del4.clear (_kind) ; - + this->_tmp1.clear (_kind) ; this->_tmp2.clear (_kind) ; this->_tmp3.clear (_kind) ; this->_tmp4.clear (_kind) ; - - //!!do something with pool'd-alloc? + + this->_hsrc.clear (); + this->_csrc.clear (); } - + /* -------------------------------------------------------- * INIT-LIST: re-size adj. lists on demand. -------------------------------------------------------- */ - + __inline_call void_type init_list ( conn_list&_list, size_type _lpos @@ -733,146 +724,123 @@ { if (_lpos >= _list._lptr.count()) _list._lptr.set_count ( - _lpos + 1, + _lpos + 1, containers::loose_alloc, nullptr) ; } - + /* -------------------------------------------------------- * PUSH-NODE: append new 0-node to complex. -------------------------------------------------------- */ - + __normal_call iptr_type push_node ( - node_type const&_ndat, + node_type const& _ndat, bool_type _link = true, iptr_type _itop = -1 ) { - iptr_type _ipos = _get_node() ; - + iptr_type _ipos = -1 ; + if (!_link) { - + + __assert( _itop == -1 && + "tria-complex: non-top node!" ) ; + /*------------------------ init. external d-face data */ + _ipos = _get_node(); + this->_set1[_ipos] = _ndat ; this->_set1[_ipos].mark() = 0 ; - + this->_set1[_ipos].self() = 1 ; this-> _set1 [_ipos].node(0) =_ipos ; - - /*------------------------ push face data to hash set */ - this->_map1.push(_ipos) ; - + /*------------------------ init. local adj. index set */ init_list(this->_adj1, _ipos) ; - + } else { - + + if (_itop == -1) + { /*------------------------ init. external d-face data */ + _ipos = _get_node(); + this->_set1[_ipos] = _ndat ; this->_set1[_ipos].mark() = 0 ; - - if (_itop == -1) - { this->_set1[_ipos].self() = 1 ; + this-> - _set1 [_ipos].node(0) =_ipos ; - } - else - this->_set1[_ipos].self() = 0 ; - - typename - node_maps::_write_it _same ; - if (this-> - _map1.find(_ipos , _same)) - { - /*---- existing d-face found: append to existing data */ - if (_itop == -1) - { - /*----- if it's a "top"-level face, copy data */ - this->_set1[*_same] = - this->_set1[ _ipos] ; - } - else - { - /*----- otherwise, append index to adj. lists */ - this-> - _adj1.push(_itop,*_same) ; - } - - _put_node(_ipos) ; + _set1 [_ipos].node(0) = _ipos; + + /*------------------------ init. local adj. index set */ + init_list(this->_adj1, _ipos) ; + } else { - /*---- d-face is new: push and descend to (d-1)-faces */ - if (_itop == -1) - { - /*----- if it's a "top"-level face, keep data */ - init_list( - this->_adj1, _ipos) ; - } - else - { - /*----- otherwise, append index to adj. lists */ - this-> - _adj1.push(_itop, _ipos) ; - } - - /*-------------- push new face data onto hash */ - this->_map1.push(_ipos) ; + /*------------------------ init. internal d-face data */ + __assert(find_node( + &_ndat.node(0), _ipos) && + "tria-complex: node not here" ); + + /*------------------------ append index to adj. lists */ + this->_adj1.push( + _itop, _ndat.node(0)) ; + } - + } - + return _ipos ; } - + /* -------------------------------------------------------- * PUSH-EDGE: append new 1-edge to complex. -------------------------------------------------------- */ - + __normal_call iptr_type push_edge ( - edge_type const&_edat, + edge_type const& _edat, bool_type _link = true, - iptr_type _itop = -1 + iptr_type _itop = -1 ) { iptr_type _ipos = _get_edge() ; iptr_type _npos ; - + if (!_link) { - + + __assert( _itop == -1 && + "tria-complex: non-top cell!" ) ; + /*------------------------ init. external d-face data */ this->_set2[_ipos] = _edat ; this->_set2[_ipos].mark() = 0 ; this->_set2[_ipos].self() = 1 ; - - /*------------------------ push face data to hash set */ - this->_map2.push(_ipos) ; - + /*------------------------ init. local adj. index set */ init_list(this->_adj2, _ipos) ; - + } else { - + /*------------------------ init. external d-face data */ this->_set2[_ipos] = _edat ; this->_set2[_ipos].mark() = 0 ; - + if (_itop == -1) this->_set2[_ipos].self() = 1 ; else this->_set2[_ipos].self() = 0 ; - + typename edge_maps::_write_it _same ; if (this-> @@ -890,13 +858,13 @@ /*----- otherwise, append index to adj. lists */ this-> _adj2.push(_itop,*_same) ; - } - - _put_edge(_ipos) ; + } + + _put_edge(_ipos) ; } else { - /*---- d-face is new: push and descend to (d-1)-faces */ + /*---- d-face is new: push and descend to (d-1)-faces */ if (_itop == -1) { /*----- if it's a "top"-level face, keep data */ @@ -909,69 +877,69 @@ this-> _adj2.push(_itop, _ipos) ; } - + /*-------------- descend into (d-1)-face data */ for (_npos = 2; _npos-- != 0; ) { - node_type _ndat; - _ndat.node(0) = + node_type _ndat; + _ndat.node(0) = _edat.node(_npos) ; - + push_node( _ndat, _link, _ipos) ; } - + /*-------------- push new face data onto hash */ this->_map2.push(_ipos) ; } - + } - + return _ipos ; } - + /* -------------------------------------------------------- * PUSH-TRIA: append new 2-tria to complex. -------------------------------------------------------- */ - + __normal_call iptr_type push_tri3 ( - tri3_type const&_tdat, + tri3_type const& _tdat, bool_type _link = true, - iptr_type _itop = -1 + iptr_type _itop = -1 ) { iptr_type _ipos = _get_tri3() ; iptr_type _epos ; - + if (!_link) { - + + __assert( _itop == -1 && + "tria-complex: non-top cell!" ) ; + /*-------------------- init. external d-face data */ this->_set3[_ipos] = _tdat ; this->_set3[_ipos].mark() = 0 ; this->_set3[_ipos].self() = 1 ; - - /*-------------------- push face data to hash set */ - this->_map3.push(_ipos) ; - + /*-------------------- init. local adj. index set */ init_list(this->_adj3, _ipos) ; - + } else { - + /*------------------------ init. external d-face data */ this->_set3[_ipos] = _tdat ; this->_set3[_ipos].mark() = 0 ; - + if (_itop == -1) this->_set3[_ipos].self() = 1 ; else this->_set3[_ipos].self() = 0 ; - + typename tri3_maps::_write_it _same ; if (this-> @@ -989,13 +957,13 @@ /*----- otherwise, append index to adj. lists */ this-> _adj3.push(_itop,*_same) ; - } - - _put_tri3(_ipos) ; + } + + _put_tri3(_ipos) ; } else { - /*---- d-face is new: push and descend to (d-1)-faces */ + /*---- d-face is new: push and descend to (d-1)-faces */ if (_itop == -1) { /*----- if it's a "top"-level face, keep data */ @@ -1008,75 +976,75 @@ this-> _adj3.push(_itop, _ipos) ; } - + /*-------------- descend into (d-1)-face data */ for (_epos = +3; _epos-- != 0 ; ) { iptr_type _enod [3]; tri3_type::face_node( _enod, _epos, 2, 1) ; - + edge_type _edat ; - _edat.node(0) = + _edat.node(0) = _tdat.node(_enod[0]) ; - _edat.node(1) = + _edat.node(1) = _tdat.node(_enod[1]) ; - + push_edge( _edat, _link, _ipos) ; } - + /*-------------- push new face data onto hash */ this->_map3.push(_ipos) ; } - + } - + return _ipos ; } - + /* -------------------------------------------------------- * PUSH-TRIA: append new 3-tria to complex. -------------------------------------------------------- */ - + __normal_call iptr_type push_tri4 ( - tri4_type const&_tdat, + tri4_type const& _tdat, bool_type _link = true, - iptr_type _itop = -1 + iptr_type _itop = -1 ) { iptr_type _ipos = _get_tri4() ; iptr_type _fpos ; - + if (!_link) { - + + __assert( _itop == -1 && + "tria-complex: non-top cell!" ) ; + /*------------------------ init. external d-face data */ this->_set4[_ipos] = _tdat ; this->_set4[_ipos].mark() = 0 ; this->_set4[_ipos].self() = 1 ; - - /*------------------------ push face data to hash set */ - this->_map4.push(_ipos) ; - + /*------------------------ init. local adj. index set */ init_list(this->_adj4, _ipos) ; - + } else { - + /*------------------------ init. external d-face data */ this->_set4[_ipos] = _tdat ; this->_set4[_ipos].mark() = 0 ; - + if (_itop == -1) this->_set4[_ipos].self() = 1 ; else this->_set4[_ipos].self() = 0 ; - + typename tri4_maps::_write_it _same ; if (this-> @@ -1094,13 +1062,13 @@ /*----- otherwise, append index to adj. lists */ this-> _adj4.push(_itop,*_same) ; - } - - _put_tri4(_ipos) ; + } + + _put_tri4(_ipos) ; } else { - /*---- d-face is new: push and descend to (d-1)-faces */ + /*---- d-face is new: push and descend to (d-1)-faces */ if (_itop == -1) { /*----- if it's a "top"-level face, keep data */ @@ -1113,72 +1081,93 @@ this-> _adj4.push(_itop, _ipos) ; } - + /*-------------- descend into (d-1)-face data */ for (_fpos = +4; _fpos-- != 0 ; ) { iptr_type _fnod [4]; tri4_type::face_node( _fnod, _fpos, 3, 2) ; - + tri3_type _fdat ; - _fdat.node(0) = + _fdat.node(0) = _tdat.node(_fnod[0]) ; - _fdat.node(1) = + _fdat.node(1) = _tdat.node(_fnod[1]) ; - _fdat.node(2) = + _fdat.node(2) = _tdat.node(_fnod[2]) ; - + push_tri3( _fdat, _link, _ipos) ; } - + /*-------------- push new face data onto hash */ this->_map4.push(_ipos) ; } - + } - + return _ipos ; } - + /* -------------------------------------------------------- - * MAKE-PTRS: build item-to-item adj. + * MAKE-LINK: build item-to-item adj. -------------------------------------------------------- */ - - __normal_call void_type make_ptrs ( + + __normal_call void_type make_link ( ) { + this->_map2.set_slots( + (this->_set2.count()*5)/4 + 1 + + (this->_set3.count()*5)/2 + 1 + + (this->_set4.count()*3)/2 + 1 + ) ; + + this->_map3.set_slots( + (this->_set3.count()*5)/4 + 1 + + (this->_set4.count()*5)/2 + 1 + ) ; + + this->_map4.set_slots( + (this->_set4.count()*5)/4 + 1 + ) ; + this->_adj1.empty () ; this->_adj2.empty () ; this->_adj3.empty () ; this->_adj4.empty () ; - + iptr_type _epos = +0 ; for (auto _iter = this->_set2.head(); _iter != this->_set2.tend(); ++_iter, ++_epos ) { + /*-------------- push face data onto hash set */ + this->_map2.push(_epos) ; + /*-------------- descend into (d-1)-face data */ iptr_type _ipos; for (_ipos = +2; _ipos-- != 0; ) { - node_type _ndat; - _ndat.node(0) = + node_type _ndat; + _ndat.node(0) = _iter->node( _ipos) ; - + push_node( _ndat, true, _epos) ; } } - + iptr_type _fpos = +0 ; for (auto _iter = this->_set3.head(); _iter != this->_set3.tend(); ++_iter, ++_fpos ) { + /*-------------- push face data onto hash set */ + this->_map3.push(_fpos) ; + /*-------------- descend into (d-1)-face data */ iptr_type _ipos; for (_ipos = +3; _ipos-- != 0; ) @@ -1186,23 +1175,26 @@ iptr_type _enod [3]; tri3_type::face_node( _enod, _ipos, 2, 1 ) ; - + edge_type _edat ; - _edat.node(0) = + _edat.node(0) = _iter->node(_enod[0]) ; - _edat.node(1) = + _edat.node(1) = _iter->node(_enod[1]) ; - + push_edge( _edat, true , _fpos) ; } } - + iptr_type _tpos = +0 ; for (auto _iter = this->_set4.head(); _iter != this->_set4.tend(); ++_iter, ++_tpos ) { + /*-------------- push face data onto hash set */ + this->_map4.push(_tpos) ; + /*-------------- descend into (d-1)-face data */ iptr_type _ipos; for (_ipos = +4; _ipos-- != 0; ) @@ -1210,65 +1202,65 @@ iptr_type _fnod [4]; tri4_type::face_node( _fnod, _ipos, 3, 2 ) ; - + tri3_type _fdat ; - _fdat.node(0) = + _fdat.node(0) = _iter->node(_fnod[0]) ; - _fdat.node(1) = + _fdat.node(1) = _iter->node(_fnod[1]) ; - _fdat.node(2) = + _fdat.node(2) = _iter->node(_fnod[2]) ; - + push_tri3( _fdat, true , _tpos) ; } } } - + /* -------------------------------------------------------- * NULL-ITEM: TRUE if item is delete-able. -------------------------------------------------------- */ - + __inline_call bool_type null_node ( iptr_type _npos - ) + ) const { return this->_set1[_npos].self()==0 && this->_adj1.empty(_npos); } - + __inline_call bool_type null_edge ( iptr_type _epos - ) + ) const { return this->_set2[_epos].self()==0 && this->_adj2.empty(_epos); } - + __inline_call bool_type null_tri3 ( iptr_type _tpos - ) + ) const { return this->_set3[_tpos].self()==0 && this->_adj3.empty(_tpos); } - + __inline_call bool_type null_tri4 ( iptr_type _tpos - ) + ) const { return this->_set4[_tpos].self()==0 && this->_adj4.empty(_tpos); } - + /* -------------------------------------------------------- * _POP-LIST: delete item from adj. list. -------------------------------------------------------- */ - + __normal_call void_type _pop_list ( conn_list &_list, iptr_type _lpos, @@ -1280,46 +1272,46 @@ _prev = _list.hend(_lpos), _iter = _list.head(_lpos), _tend = _list.tend(_lpos); - - for ( ; _iter != _tend; + + for ( ; _iter != _tend; _prev = _iter, ++_iter) { if(*_iter == _itop) { _list._pop ( - _prev, _iter, _lpos) ; - + _prev, _iter, _lpos) ; + break ; } } } - + /* -------------------------------------------------------- * _POP-NODE: delete 0-node from complex. -------------------------------------------------------- */ - + __normal_call void_type _pop_node ( - iptr_type*_nptr , + iptr_type const*_nptr, iptr_type _itop = -1 ) { iptr_type _npos = -1 ; - + iptr_type _node[1]; _node[0] = _nptr[0]; - + /*-------------------------- find current 0-node pos. */ - if ((_npos = _node[0]) < +0) + if ( !find_node (_node, _npos)) { return ; } - - /*-------------------------- _pop current 0-node data */ + + /*-------------------------- _pop current 0-node data */ _pop_node(_npos, _itop) ; } - + __normal_call void_type _pop_node ( iptr_type _npos , iptr_type _itop @@ -1337,52 +1329,48 @@ this-> _set1[_npos].self() = 0 ; } - + if (null_node (_npos)) { /*---- ref. count: delete (d+0), (d-1)-faces if empty */ - - iptr_type _same ; - this->_map1._pop(_npos, _same); - - _put_node(_npos); + _put_node (_npos); } } - + /* -------------------------------------------------------- * _POP-EDGE: delete 1-edge from complex. -------------------------------------------------------- */ - + __normal_call void_type _pop_edge ( - iptr_type*_nptr , + iptr_type const*_nptr, iptr_type _itop = -1 ) { iptr_type _epos = -1 ; - + iptr_type _node[2]; _node[0] = _nptr[0]; _node[1] = _nptr[1]; - + /*-------------------------- find current 1-edge pos. */ if ( !find_edge (_node, _epos)) { return ; } - - /*-------------------------- _pop current 1-edge data */ + + /*-------------------------- _pop current 1-edge data */ _pop_edge(_epos, _itop) ; } - + __normal_call void_type _pop_edge ( iptr_type _epos , iptr_type _itop = -1 ) - { + { iptr_type _npos = -1 ; - + if (_itop != -1) { /*---- deleteing (d+k)-face: scan adj. and _pop _itop */ @@ -1395,21 +1383,21 @@ this-> _set2[_epos].self() = 0 ; } - + if (null_edge (_epos)) { /*---- ref. count: delete (d+0), (d-1)-faces if empty */ iptr_type _same ; this->_map2._pop(_epos, _same); - + iptr_type _node [ 2] ; _node[0] = this-> _set2[_epos].node(0) ; _node[1] = this-> _set2[_epos].node(1) ; - + _put_edge(_epos); - + for (_npos = 2; _npos-- != 0; ) { _pop_node( @@ -1417,42 +1405,42 @@ } } } - + /* -------------------------------------------------------- * _POP-TRIA: delete 2-tria from complex. -------------------------------------------------------- */ - + __normal_call void_type _pop_tri3 ( - iptr_type*_nptr , + iptr_type const*_nptr, iptr_type _itop = -1 ) { iptr_type _tpos = -1 ; - + iptr_type _node[3]; _node[0] = _nptr[0]; _node[1] = _nptr[1]; _node[2] = _nptr[2]; - + /*-------------------------- find current 2-tria pos. */ if ( !find_tri3 (_node, _tpos)) { return ; } - - /*-------------------------- _pop current 2-tria data */ + + /*-------------------------- _pop current 2-tria data */ _pop_tri3(_tpos, _itop) ; } - + __normal_call void_type _pop_tri3 ( iptr_type _tpos , iptr_type _itop = -1 ) - { + { iptr_type _epos = -1 ; - + if (_itop != -1) { /*---- deleteing (d+k)-face: scan adj. and _pop _itop */ @@ -1465,14 +1453,14 @@ this-> _set3[_tpos].self() = 0 ; } - + if (null_tri3 (_tpos)) { /*---- ref. count: delete (d+0), (d-1)-faces if empty */ - + iptr_type _same ; this->_map3._pop(_tpos, _same); - + iptr_type _node [ 3] ; _node[0] = this-> _set3[_tpos].node(0) ; @@ -1480,61 +1468,61 @@ _set3[_tpos].node(1) ; _node[2] = this-> _set3[_tpos].node(2) ; - + _put_tri3(_tpos); - + for (_epos = 3; _epos-- != 0; ) { iptr_type _enod [3] ; tri3_type::face_node ( _enod, _epos, 2, 1) ; - - _enod[0] = + + _enod[0] = _node[_enod [0]]; - _enod[1] = + _enod[1] = _node[_enod [1]]; - + _pop_edge(_enod, _tpos) ; } } } - + /* -------------------------------------------------------- * _POP-TRIA: delete 3-tria from complex. -------------------------------------------------------- */ - + __normal_call void_type _pop_tri4 ( - iptr_type*_nptr , + iptr_type const*_nptr, iptr_type _itop = -1 ) { iptr_type _tpos = -1 ; - + iptr_type _node[4]; _node[0] = _nptr[0]; _node[1] = _nptr[1]; _node[2] = _nptr[2]; _node[3] = _nptr[3]; - + /*-------------------------- find current 3-tria pos. */ if ( !find_tri4 (_node, _tpos)) { return ; } - - /*-------------------------- _pop current 3-tria data */ + + /*-------------------------- _pop current 3-tria data */ _pop_tri4(_tpos, _itop) ; } - + __normal_call void_type _pop_tri4 ( iptr_type _tpos , iptr_type _itop = -1 ) - { + { iptr_type _fpos = -1 ; - + if (_itop != -1) { /*---- deleteing (d+k)-face: scan adj. and _pop _itop */ @@ -1547,14 +1535,14 @@ this-> _set4[_tpos].self() = 0 ; } - + if (null_tri4 (_tpos)) { /*---- ref. count: delete (d+0), (d-1)-faces if empty */ - + iptr_type _same ; this->_map4._pop(_tpos, _same); - + iptr_type _node [ 4] ; _node[0] = this-> _set4[_tpos].node(0) ; @@ -1564,48 +1552,77 @@ _set4[_tpos].node(2) ; _node[3] = this-> _set4[_tpos].node(3) ; - + _put_tri4(_tpos); - + for (_fpos = 4; _fpos-- != 0; ) { iptr_type _fnod [4] ; tri4_type::face_node ( _fnod, _fpos, 3, 2) ; - - _fnod[0] = + + _fnod[0] = _node[_fnod [0]]; - _fnod[1] = + _fnod[1] = _node[_fnod [1]]; - _fnod[2] = + _fnod[2] = _node[_fnod [2]]; - + _pop_tri3(_fnod, _tpos) ; } } } - - + + /* + -------------------------------------------------------- + * FIND-NODE: return index of assoc. 0-node. + -------------------------------------------------------- + */ + + __normal_call bool_type find_node ( + iptr_type const*_nptr , + iptr_type&_npos + ) const + { + /*-------------------------- find current 0-node pos. */ + iptr_type _node = *_nptr ; + + if (_node >= +0 && _node < + (iptr_type)this->_set1.count() && + _set1 [_node].mark() >= +0) + { + /*------------------------------- found matching node */ + _npos =_node ; + + return true ; + } + else + { + /*------------------------------- couldn't find match */ + return false ; + } + } + /* -------------------------------------------------------- * FIND-EDGE: return index of assoc. 1-edge. -------------------------------------------------------- */ - + __normal_call bool_type find_edge ( - iptr_type*_node, + iptr_type const*_node , iptr_type&_epos ) { - /*-------------------------- find current 1-edge pos. */ + /*-------------------------- find current 1-edge pos. */ iptr_type _ipos = _get_edge() ; - + this-> _set2[_ipos].node(0)=_node[0]; this-> - _set2[_ipos].node(1)=_node[1]; - - typename edge_maps::_write_it + _set2[_ipos].node(1)=_node[1]; + + typename edge_maps::_write_it _same ; if (this-> _map2.find(_ipos, _same)) @@ -1614,7 +1631,7 @@ _put_edge(_ipos) ; _epos=*_same ; - + return true ; } else @@ -1625,29 +1642,29 @@ return false ; } } - + /* -------------------------------------------------------- * FIND-TRIA: return index of assoc. 2-tria. -------------------------------------------------------- */ - + __normal_call bool_type find_tri3 ( - iptr_type*_node, + iptr_type const*_node , iptr_type&_tpos ) { - /*-------------------------- find current 2-tria pos. */ + /*-------------------------- find current 2-tria pos. */ iptr_type _ipos = _get_tri3() ; - + this-> _set3[_ipos].node(0)=_node[0]; this-> _set3[_ipos].node(1)=_node[1]; this-> - _set3[_ipos].node(2)=_node[2]; - - typename tri3_maps::_write_it + _set3[_ipos].node(2)=_node[2]; + + typename tri3_maps::_write_it _same ; if (this-> _map3.find(_ipos, _same)) @@ -1656,7 +1673,7 @@ _put_tri3(_ipos) ; _tpos=*_same ; - + return true ; } else @@ -1667,21 +1684,21 @@ return false ; } } - + /* -------------------------------------------------------- * FIND-TRIA: return index of assoc. 3-tria. -------------------------------------------------------- */ - + __normal_call bool_type find_tri4 ( - iptr_type*_node, + iptr_type const*_node , iptr_type&_tpos ) { - /*-------------------------- find current 2-tria pos. */ + /*-------------------------- find current 2-tria pos. */ iptr_type _ipos = _get_tri4() ; - + this-> _set4[_ipos].node(0)=_node[0]; this-> @@ -1689,9 +1706,9 @@ this-> _set4[_ipos].node(2)=_node[2]; this-> - _set4[_ipos].node(3)=_node[3]; - - typename tri4_maps::_write_it + _set4[_ipos].node(3)=_node[3]; + + typename tri4_maps::_write_it _same ; if (this-> _map4.find(_ipos, _same)) @@ -1700,7 +1717,7 @@ _put_tri4(_ipos) ; _tpos=*_same ; - + return true ; } else @@ -1711,25 +1728,25 @@ return false ; } } - - + + /* -------------------------------------------------------- * NODE-EDGE: form node-to-edge adj. list. -------------------------------------------------------- */ - + template < typename list_type > - __normal_call void_type node_edge ( - iptr_type*_node, + __inline_call void_type node_edge ( + iptr_type const*_node , list_type&_conn ) { node_edge(_node [ 0], _conn) ; - } - + } + template < typename list_type > @@ -1737,22 +1754,22 @@ iptr_type _npos, list_type&_conn ) - { + { this->_tmp1.set_count( +0 ) ; this->_tmp2.set_count( +0 ) ; this->_tmp3.set_count( +0 ) ; this->_tmp4.set_count( +0 ) ; - + this->_tmp1.push_tail(_npos) ; - + /*-------------------------- find set of adj. 1-edges */ - for (auto _iter = this->_tmp1.head(); + for (auto _iter = this->_tmp1.head(); _iter != this->_tmp1.tend(); ++_iter ) { - for (auto _iadj = + for (auto _iadj = this->_adj1.head(*_iter) ; - _iadj != + _iadj != this->_adj1.tend(*_iter) ; ++_iadj ) { @@ -1765,33 +1782,33 @@ } } } - + /*-------------------------- flip d-face marker lists */ - for (auto _iter = _conn.head() ; + for (auto _iter = _conn.head() ; _iter != _conn.tend() ; ++_iter ) { this->_set2 [*_iter].mark() = +0; } } - + /* -------------------------------------------------------- * NODE-TRI3: form node-to-tria adj. list. -------------------------------------------------------- */ - + template < typename list_type > - __normal_call void_type node_tri3 ( - iptr_type*_node, + __inline_call void_type node_tri3 ( + iptr_type const*_node , list_type&_conn ) { node_tri3(_node [ 0], _conn) ; } - + template < typename list_type > @@ -1799,22 +1816,22 @@ iptr_type _npos, list_type&_conn ) - { + { this->_tmp1.set_count( +0 ) ; this->_tmp2.set_count( +0 ) ; this->_tmp3.set_count( +0 ) ; this->_tmp4.set_count( +0 ) ; - + this->_tmp1.push_tail(_npos) ; - + /*-------------------------- find set of adj. 1-edges */ - for (auto _iter = this->_tmp1.head(); + for (auto _iter = this->_tmp1.head(); _iter != this->_tmp1.tend(); ++_iter ) { - for (auto _iadj = + for (auto _iadj = this->_adj1.head(*_iter) ; - _iadj != + _iadj != this->_adj1.tend(*_iter) ; ++_iadj ) { @@ -1829,13 +1846,13 @@ } } /*-------------------------- find set of adj. 2-trias */ - for (auto _iter = this->_tmp2.head(); + for (auto _iter = this->_tmp2.head(); _iter != this->_tmp2.tend(); ++_iter ) { - for (auto _iadj = + for (auto _iadj = this->_adj2.head(*_iter) ; - _iadj != + _iadj != this->_adj2.tend(*_iter) ; ++_iadj ) { @@ -1848,16 +1865,16 @@ } } } - + /*-------------------------- flip d-face marker lists */ - for (auto _iter = _conn.head() ; + for (auto _iter = _conn.head() ; _iter != _conn.tend() ; ++_iter ) { this->_set3 [*_iter].mark() = 0 ; } for (auto _iter = this-> - _tmp2.head() ; + _tmp2.head() ; _iter != this-> _tmp2.tend() ; ++_iter ) @@ -1865,24 +1882,24 @@ this->_set2 [*_iter].mark() = 0 ; } } - + /* -------------------------------------------------------- * NODE-TRI4: form node-to-tria adj. list. -------------------------------------------------------- */ - + template < typename list_type > - __normal_call void_type node_tri4 ( - iptr_type*_node, + __inline_call void_type node_tri4 ( + iptr_type const*_node , list_type&_conn ) { node_tri4(_node [ 0], _conn) ; } - + template < typename list_type > @@ -1890,22 +1907,22 @@ iptr_type _npos, list_type&_conn ) - { + { this->_tmp1.set_count( +0 ) ; this->_tmp2.set_count( +0 ) ; this->_tmp3.set_count( +0 ) ; this->_tmp4.set_count( +0 ) ; - + this->_tmp1.push_tail(_npos) ; - + /*-------------------------- find set of adj. 1-edges */ - for (auto _iter = this->_tmp1.head(); + for (auto _iter = this->_tmp1.head(); _iter != this->_tmp1.tend(); ++_iter ) { - for (auto _iadj = + for (auto _iadj = this->_adj1.head(*_iter) ; - _iadj != + _iadj != this->_adj1.tend(*_iter) ; ++_iadj ) { @@ -1920,13 +1937,13 @@ } } /*-------------------------- find set of adj. 2-trias */ - for (auto _iter = this->_tmp2.head(); + for (auto _iter = this->_tmp2.head(); _iter != this->_tmp2.tend(); ++_iter ) { - for (auto _iadj = + for (auto _iadj = this->_adj2.head(*_iter) ; - _iadj != + _iadj != this->_adj2.tend(*_iter) ; ++_iadj ) { @@ -1941,13 +1958,13 @@ } } /*-------------------------- find set of adj. 3-trias */ - for (auto _iter = this->_tmp3.head(); + for (auto _iter = this->_tmp3.head(); _iter != this->_tmp3.tend(); ++_iter ) { - for (auto _iadj = + for (auto _iadj = this->_adj3.head(*_iter) ; - _iadj != + _iadj != this->_adj3.tend(*_iter) ; ++_iadj ) { @@ -1960,16 +1977,16 @@ } } } - + /*-------------------------- flip d-face marker lists */ - for (auto _iter = _conn.head() ; + for (auto _iter = _conn.head() ; _iter != _conn.tend() ; ++_iter ) { this->_set4 [*_iter].mark() = 0 ; } for (auto _iter = this-> - _tmp3.head() ; + _tmp3.head() ; _iter != this-> _tmp3.tend() ; ++_iter ) @@ -1977,7 +1994,7 @@ this->_set3 [*_iter].mark() = 0 ; } for (auto _iter = this-> - _tmp2.head() ; + _tmp2.head() ; _iter != this-> _tmp2.tend() ; ++_iter ) @@ -1985,32 +2002,32 @@ this->_set2 [*_iter].mark() = 0 ; } } - + /* -------------------------------------------------------- * EDGE-TRI3: form edge-to-tria adj. list. -------------------------------------------------------- */ - + template < typename list_type > - __normal_call void_type edge_tri3 ( - iptr_type*_node, + __inline_call void_type edge_tri3 ( + iptr_type const*_node , list_type&_conn ) { - /*-------------------------- find current 1-edge pos. */ + /*-------------------------- find current 1-edge pos. */ iptr_type _epos = -1; if (!find_edge(_node, _epos)) { return ; } - + /*-------------------------- get adj. for 1-edge pos. */ edge_tri3(_epos, _conn) ; } - + template < typename list_type > @@ -2023,17 +2040,17 @@ this->_tmp2.set_count( +0 ) ; this->_tmp3.set_count( +0 ) ; this->_tmp4.set_count( +0 ) ; - + this->_tmp2.push_tail(_epos) ; - + /*-------------------------- find set of adj. 2-faces */ - for (auto _iter = this->_tmp2.head(); + for (auto _iter = this->_tmp2.head(); _iter != this->_tmp2.tend(); ++_iter ) { - for (auto _iadj = + for (auto _iadj = this->_adj2.head(*_iter) ; - _iadj != + _iadj != this->_adj2.tend(*_iter) ; ++_iadj ) { @@ -2046,41 +2063,41 @@ } } } - + /*-------------------------- flip d-face marker lists */ - for (auto _iter = _conn.head() ; + for (auto _iter = _conn.head() ; _iter != _conn.tend() ; ++_iter ) { this->_set3 [*_iter].mark() = 0 ; } } - + /* -------------------------------------------------------- * EDGE-TRI4: form edge-to-tria adj. list. -------------------------------------------------------- */ - + template < typename list_type > - __normal_call void_type edge_tri4 ( - iptr_type*_node, + __inline_call void_type edge_tri4 ( + iptr_type const*_node , list_type&_conn ) { - /*-------------------------- find current 1-edge pos. */ + /*-------------------------- find current 1-edge pos. */ iptr_type _epos = -1; if (!find_edge(_node, _epos)) { return ; } - + /*-------------------------- get adj. for 1-edge pos. */ edge_tri4(_epos, _conn) ; } - + template < typename list_type > @@ -2093,17 +2110,17 @@ this->_tmp2.set_count( +0 ) ; this->_tmp3.set_count( +0 ) ; this->_tmp4.set_count( +0 ) ; - + this->_tmp2.push_tail(_epos) ; - + /*-------------------------- find set of adj. 2-faces */ - for (auto _iter = this->_tmp2.head(); + for (auto _iter = this->_tmp2.head(); _iter != this->_tmp2.tend(); ++_iter ) { - for (auto _iadj = + for (auto _iadj = this->_adj2.head(*_iter) ; - _iadj != + _iadj != this->_adj2.tend(*_iter) ; ++_iadj ) { @@ -2118,13 +2135,13 @@ } } /*-------------------------- find set of adj. 3-faces */ - for (auto _iter = this->_tmp3.head(); + for (auto _iter = this->_tmp3.head(); _iter != this->_tmp3.tend(); ++_iter ) { - for (auto _iadj = + for (auto _iadj = this->_adj3.head(*_iter) ; - _iadj != + _iadj != this->_adj3.tend(*_iter) ; ++_iadj ) { @@ -2137,16 +2154,16 @@ } } } - + /*-------------------------- flip d-face marker lists */ - for (auto _iter = _conn.head() ; + for (auto _iter = _conn.head() ; _iter != _conn.tend() ; ++_iter ) { this->_set4 [*_iter].mark() = 0 ; } for (auto _iter = this-> - _tmp3.head() ; + _tmp3.head() ; _iter != this-> _tmp3.tend() ; ++_iter ) @@ -2154,32 +2171,32 @@ this->_set3 [*_iter].mark() = 0 ; } } - + /* -------------------------------------------------------- * TRI3-TRI4: form tria-to-tria adj. list. -------------------------------------------------------- */ - + template < typename list_type > - __normal_call void_type tri3_tri4 ( - iptr_type*_node, + __inline_call void_type tri3_tri4 ( + iptr_type const*_node , list_type&_conn ) { - /*-------------------------- find current 1-edge pos. */ + /*-------------------------- find current 1-edge pos. */ iptr_type _tpos = -1; if (!find_tri3(_node, _tpos)) { return ; } - + /*-------------------------- get adj. for 1-edge pos. */ tri3_tri4(_tpos, _conn) ; } - + template < typename list_type > @@ -2192,17 +2209,17 @@ this->_tmp2.set_count( +0 ) ; this->_tmp3.set_count( +0 ) ; this->_tmp4.set_count( +0 ) ; - + this->_tmp3.push_tail(_epos) ; - + /*-------------------------- find set of adj. 2-faces */ - for (auto _iter = this->_tmp3.head(); + for (auto _iter = this->_tmp3.head(); _iter != this->_tmp3.tend(); ++_iter ) { - for (auto _iadj = + for (auto _iadj = this->_adj3.head(*_iter) ; - _iadj != + _iadj != this->_adj3.tend(*_iter) ; ++_iadj ) { @@ -2215,9 +2232,9 @@ } } } - + /*-------------------------- flip d-face marker lists */ - for (auto _iter = _conn.head() ; + for (auto _iter = _conn.head() ; _iter != _conn.tend() ; ++_iter ) { diff --git a/src/libcpp/meshfunc.hpp b/src/libcpp/meshfunc.hpp index dcf1245..dbe1078 100644 --- a/src/libcpp/meshfunc.hpp +++ b/src/libcpp/meshfunc.hpp @@ -1,37 +1,37 @@ -/* +/* ------------------------------------------------------------ - * data-structures for discrete function rep. in R^d. + * data-structures for discrete function rep. in R^d. ------------------------------------------------------------ * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * ------------------------------------------------------------ * - * Last updated: 18 April, 2019 + * Last updated: 30 June, 2019 * * Copyright 2013-2019 * Darren Engwirda @@ -45,16 +45,18 @@ # ifndef __MESHFUNC__ # define __MESHFUNC__ - + # include "containers.hpp" # include "algorithms.hpp" +# include "mathutil.hpp" # include "geometry.hpp" # include "aabbtree.hpp" # include "meshtype.hpp" # include "mesh_func/hfun_base_k.hpp" +# include "mesh_func/hfun_clip_k.hpp" # include "mesh_func/hfun_constant_value_k.hpp" @@ -68,6 +70,7 @@ # include "mesh_func/hfun_grid_ellipsoid_3.hpp" + # endif//__MESHFUNC__ diff --git a/src/libcpp/meshtype.hpp b/src/libcpp/meshtype.hpp index 32e9391..a06cc68 100644 --- a/src/libcpp/meshtype.hpp +++ b/src/libcpp/meshtype.hpp @@ -1,37 +1,37 @@ -/* +/* ------------------------------------------------------------ - * data-structures for discrete complexes in R^d. + * data-structures for discrete complexes in R^d. ------------------------------------------------------------ * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * ------------------------------------------------------------ * - * Last updated: 19 January, 2019 + * Last updated: 08 December, 2019 * * Copyright 2013-2019 * Darren Engwirda @@ -45,8 +45,8 @@ # ifndef __MESHTYPE__ # define __MESHTYPE__ - - namespace mesh + + namespace mesh { /*-------------------------- classification of mesh cells */ char_type EMPTY_tag = +0 ; @@ -59,12 +59,12 @@ char_type WEDG6_tag = 70 ; char_type PYRA5_tag = 80 ; } - + # include "containers.hpp" # include "hashfunc.hpp" -# include "mesh_type/tria_complex_type_k.hpp" +# include "mesh_type/mesh_complex_type_k.hpp" # include "mesh_type/tria_complex_1.hpp" # include "mesh_type/tria_complex_2.hpp" diff --git a/src/libcpp/mp_floats/dd_flt.hpp b/src/libcpp/mp_floats/dd_flt.hpp index 895f1bc..0d21bf1 100644 --- a/src/libcpp/mp_floats/dd_flt.hpp +++ b/src/libcpp/mp_floats/dd_flt.hpp @@ -15,50 +15,50 @@ class dd_flt ; __inline_call dd_flt operator + ( - dd_flt const&, + dd_flt const&, double ) ; __inline_call dd_flt operator + ( double , dd_flt const&) ; __inline_call dd_flt operator + ( - dd_flt const&, + dd_flt const&, dd_flt const&) ; - + __inline_call dd_flt operator - ( - dd_flt const&, + dd_flt const&, double ) ; __inline_call dd_flt operator - ( double , dd_flt const&) ; __inline_call dd_flt operator - ( - dd_flt const&, + dd_flt const&, dd_flt const&) ; - + __inline_call dd_flt operator * ( - dd_flt const&, + dd_flt const&, double ) ; __inline_call dd_flt operator * ( double , dd_flt const&) ; __inline_call dd_flt operator * ( - dd_flt const&, + dd_flt const&, dd_flt const&) ; - + __inline_call dd_flt operator / ( - dd_flt const&, + dd_flt const&, double ) ; __inline_call dd_flt operator / ( double , dd_flt const&) ; __inline_call dd_flt operator / ( - dd_flt const&, + dd_flt const&, dd_flt const&) ; class dd_flt { private : double _xx[2] ; - + public : __inline_call double& hi ( ) @@ -67,7 +67,7 @@ class dd_flt __inline_call double& lo ( ) { return this->_xx[1] ; - } + } __inline_call double const& hi ( ) const { return this->_xx[0] ; @@ -75,8 +75,8 @@ class dd_flt __inline_call double const& lo ( ) const { return this->_xx[1] ; - } - + } + public : __inline_call dd_flt ( double _hi = double(+0.0) , @@ -85,22 +85,22 @@ class dd_flt { this->_xx[0] = _hi ; this->_xx[1] = _lo ; } - + __inline_call dd_flt ( double const* _dx ) { this->_xx[0] = _dx[0] ; this->_xx[1] = _dx[1] ; } - + __inline_call dd_flt ( int _ii ) { this->_xx[0] =(double)_ii ; this->_xx[1] = +0. ; } - - + + __inline_call dd_flt ( dd_flt const& _aa ) @@ -108,15 +108,15 @@ class dd_flt this->_xx[0] = _aa.hi(); this->_xx[1] = _aa.lo(); } - - + + __inline_call dd_flt& operator = ( double _aa ) - { + { this->_xx[0] = _aa ; this->_xx[1] = +0. ; - + return ( *this ) ; } __inline_call dd_flt& operator = ( @@ -125,21 +125,21 @@ class dd_flt { this->_xx[0] = _aa.hi(); this->_xx[1] = _aa.lo(); - + return ( *this ) ; - } - - + } + + __inline_call operator double ( - ) + ) const { return ( (double)(hi()+lo()) ) ; } __inline_call operator int ( - ) + ) const { return ( (int )(hi()+lo()) ) ; } - - + + __inline_call dd_flt operator + ( ) const { return dd_flt(+hi(), +lo()) ; @@ -148,131 +148,131 @@ class dd_flt ) const { return dd_flt(-hi(), -lo()) ; } - - + + __inline_call dd_flt& operator += ( double _aa ) - { + { dd_flt _tt = *this + _aa ; hi() = _tt.hi(); lo() = _tt.lo(); - + return ( *this ) ; } - + __inline_call dd_flt& operator -= ( double _aa ) - { + { dd_flt _tt = *this - _aa ; hi() = _tt.hi(); lo() = _tt.lo(); - + return ( *this ) ; } - + __inline_call dd_flt& operator *= ( double _aa ) - { + { dd_flt _tt = *this * _aa ; hi() = _tt.hi(); lo() = _tt.lo(); - + return ( *this ) ; } - + __inline_call dd_flt& operator /= ( double _aa ) - { + { dd_flt _tt = *this / _aa ; hi() = _tt.hi(); lo() = _tt.lo(); - + return ( *this ) ; } - - + + __inline_call dd_flt& operator += ( dd_flt const& _aa ) - { + { dd_flt _tt = *this + _aa ; hi() = _tt.hi(); lo() = _tt.lo(); - + return ( *this ) ; } - + __inline_call dd_flt& operator -= ( dd_flt const& _aa ) - { + { dd_flt _tt = *this - _aa ; hi() = _tt.hi(); lo() = _tt.lo(); - + return ( *this ) ; } - + __inline_call dd_flt& operator *= ( dd_flt const& _aa ) - { + { dd_flt _tt = *this * _aa ; hi() = _tt.hi(); lo() = _tt.lo(); - + return ( *this ) ; } - + __inline_call dd_flt& operator /= ( dd_flt const& _aa ) - { + { dd_flt _tt = *this / _aa ; hi() = _tt.hi(); lo() = _tt.lo(); - + return ( *this ) ; - } - + } + } ; - + // a+b __inline_call dd_flt operator + ( - dd_flt const& _aa, + dd_flt const& _aa, double _bb ) { double _y0, _y1; dd_imp::two_one_add ( - _aa.hi(), + _aa.hi(), _aa.lo(), _bb, _y1, _y0 ) ; - + return dd_flt(_y1, _y0) ; } - + __inline_call dd_flt operator + ( double _aa, dd_flt const& _bb ) { return ( _bb + _aa ) ; } - + __inline_call dd_flt operator + ( - dd_flt const& _aa, + dd_flt const& _aa, dd_flt const& _bb ) { @@ -281,25 +281,25 @@ class dd_flt _aa.hi(), _aa.lo(), _bb.hi(), _bb.lo(), _y1, _y0) ; - + return dd_flt(_y1, _y0) ; } - + // a-b __inline_call dd_flt operator - ( - dd_flt const& _aa, + dd_flt const& _aa, double _bb ) { double _y0, _y1; dd_imp::two_one_sub ( - _aa.hi(), + _aa.hi(), _aa.lo(), _bb, _y1, _y0 ) ; - + return dd_flt(_y1, _y0) ; } - + __inline_call dd_flt operator - ( double _aa, dd_flt const& _bb @@ -307,15 +307,15 @@ class dd_flt { double _y0, _y1; dd_imp::one_two_sub (_aa, - _bb.hi(), + _bb.hi(), _bb.lo(), _y1, _y0 ) ; - + return dd_flt(_y1, _y0) ; } - + __inline_call dd_flt operator - ( - dd_flt const& _aa, + dd_flt const& _aa, dd_flt const& _bb ) { @@ -324,34 +324,34 @@ class dd_flt _aa.hi(), _aa.lo(), _bb.hi(), _bb.lo(), _y1, _y0) ; - + return dd_flt(_y1, _y0) ; } - + // a * b __inline_call dd_flt operator * ( - dd_flt const& _aa, + dd_flt const& _aa, double _bb ) { double _y0, _y1; dd_imp::two_one_mul ( - _aa.hi(), + _aa.hi(), _aa.lo(), _bb, _y1, _y0 ) ; - + return dd_flt(_y1, _y0) ; } - + __inline_call dd_flt operator * ( double _aa, dd_flt const& _bb ) { return ( _bb * _aa ) ; } - + __inline_call dd_flt operator * ( - dd_flt const& _aa, + dd_flt const& _aa, dd_flt const& _bb ) { @@ -360,10 +360,10 @@ class dd_flt _aa.hi(), _aa.lo(), _bb.hi(), _bb.lo(), _y1, _y0) ; - + return dd_flt(_y1, _y0) ; } - + // a / b __inline_call dd_flt operator / ( dd_flt const& _aa, @@ -371,7 +371,7 @@ class dd_flt ) { return ( _aa / dd_flt(_bb) ) ; } - + __inline_call dd_flt operator / ( double _aa, dd_flt const& _bb @@ -380,7 +380,7 @@ class dd_flt } __inline_call dd_flt operator / ( - dd_flt const& _aa, + dd_flt const& _aa, dd_flt const& _bb ) { @@ -389,63 +389,63 @@ class dd_flt _aa.hi(), _aa.lo(), _bb.hi(), _bb.lo(), _y1, _y0) ; - + return dd_flt(_y1, _y0) ; } - + __inline_call bool operator == ( - dd_flt const& _aa, + dd_flt const& _aa, dd_flt const& _bb ) { return _aa.hi() == _bb.hi() && _aa.lo() == _bb.lo() ; } - + __inline_call bool operator != ( - dd_flt const& _aa, + dd_flt const& _aa, dd_flt const& _bb ) { return _aa.hi() != _bb.hi() || _aa.lo() != _bb.lo() ; } - + __inline_call bool operator < ( - dd_flt const& _aa, + dd_flt const& _aa, dd_flt const& _bb ) { return _aa.hi() != _bb.hi() ? _aa.hi() < _bb.hi() : _aa.lo() < _bb.lo() ; } - + __inline_call bool operator > ( - dd_flt const& _aa, + dd_flt const& _aa, dd_flt const& _bb ) { return _aa.hi() != _bb.hi() ? _aa.hi() > _bb.hi() : _aa.lo() > _bb.lo() ; } - + __inline_call bool operator <= ( - dd_flt const& _aa, + dd_flt const& _aa, dd_flt const& _bb ) { return _aa.hi() == _bb.hi() ? _aa.lo() <= _bb.lo() : _aa.hi() <= _bb.hi() ; } - + __inline_call bool operator >= ( - dd_flt const& _aa, + dd_flt const& _aa, dd_flt const& _bb ) { return _aa.hi() == _bb.hi() ? _aa.lo() >= _bb.lo() : _aa.hi() >= _bb.hi() ; } - + #endif//__DD_FLT__ diff --git a/src/libcpp/mp_floats/dd_imp.hpp b/src/libcpp/mp_floats/dd_imp.hpp index 08f2af6..f135e9b 100644 --- a/src/libcpp/mp_floats/dd_imp.hpp +++ b/src/libcpp/mp_floats/dd_imp.hpp @@ -10,9 +10,9 @@ class dd_imp { public : typedef double word ; - - public : - __static_call + + public : + __static_call __inline_call void_type one_one_add_fast ( word _aa , word _bb , @@ -24,8 +24,8 @@ class dd_imp _er = _yy - _aa ; _er = _bb - _er ; } - - __static_call + + __static_call __inline_call void_type one_one_sub_fast ( word _aa , word _bb , @@ -38,7 +38,7 @@ class dd_imp _er = _er - _bb ; } - __static_call + __static_call __inline_call void_type one_one_add_full ( word _aa , word _bb , @@ -47,19 +47,19 @@ class dd_imp ) { _yy = _aa + _bb ; - + word _t0 , _t1 ; _t0 = _yy - _aa ; _t1 = _yy - _t0 ; - + word _t2 , _t3 ; _t2 = _aa - _t1 ; _t3 = _bb - _t0 ; - + _er = _t2 + _t3 ; } - - __static_call + + __static_call __inline_call void_type one_one_sub_full ( word _aa , word _bb , @@ -68,26 +68,26 @@ class dd_imp ) { _yy = _aa - _bb ; - + word _t0 , _t1 ; - _t0 = _yy - _aa ; + _t0 = _yy - _aa ; _t1 = _yy - _t0 ; - + word _t2 , _t3 ; _t2 = _aa - _t1 ; _t3 = _bb + _t0 ; - + _er = _t2 - _t3 ; } - + __static_call __inline_call void_type one_split ( word _aa , word& _a1 , word& _a0 ) - { - if (_aa > +6.69692879491417E+299 || + { + if (_aa > +6.69692879491417E+299 || _aa < -6.69692879491417E+299 ) { word _tt , _ss ; @@ -108,7 +108,7 @@ class dd_imp _a0 = _aa - _a1 ; } } - + __static_call __inline_call void_type one_one_mul_full ( word _aa , @@ -116,22 +116,22 @@ class dd_imp word& _y1 , word& _y0 ) - { + { word _a1, _a0, _b1, _b0 ; one_split(_aa, _a1, _a0); one_split(_bb, _b1, _b0); - + _y1 = _aa * _bb ; - + word _e1, _e2, _e3 ; _e1 = _y1 - (_a1 * _b1) ; _e2 = _e1 - (_a0 * _b1) ; _e3 = _e2 - (_a1 * _b0) ; - + _y0 = (_a0 * _b0) - _e3 ; - + } - + __static_call __inline_call void_type two_one_add ( word _a1 , @@ -143,15 +143,15 @@ class dd_imp { word _t0, _t1 ; one_one_add_full ( - _a1, _bb, + _a1, _bb, _t1, _t0) ; - + _t0 += _a0 ; one_one_add_fast ( - _t1, _t0, + _t1, _t0, _y1, _y0) ; } - + __static_call __inline_call void_type two_one_sub ( word _a1 , @@ -163,15 +163,15 @@ class dd_imp { word _t0, _t1 ; one_one_sub_full ( - _a1, _bb, + _a1, _bb, _t1, _t0) ; - + _t0 += _a0 ; one_one_add_fast ( - _t1, _t0, + _t1, _t0, _y1, _y0) ; } - + __static_call __inline_call void_type one_two_sub ( word _aa , @@ -183,15 +183,15 @@ class dd_imp { word _t0, _t1 ; one_one_sub_full ( - _aa, _b1, + _aa, _b1, _t1, _t0) ; - + _t0 -= _b0 ; one_one_add_fast ( _t1, _t0, _y1, _y0) ; } - + __static_call __inline_call void_type two_two_add ( word _a1 , @@ -206,23 +206,23 @@ class dd_imp word _t0, _t1 ; word _w0, _w1 ; one_one_add_full ( - _a1, _b1, + _a1, _b1, _s1, _s0) ; one_one_add_full ( - _a0, _b0, + _a0, _b0, _t1, _t0) ; - + _s0 += _t1; one_one_add_fast ( - _s1, _s0, + _s1, _s0, _w1, _w0) ; - + _w0 += _t0; one_one_add_fast ( - _w1, _w0, + _w1, _w0, _y1, _y0) ; } - + __static_call __inline_call void_type two_two_sub ( word _a1 , @@ -237,23 +237,23 @@ class dd_imp word _t0, _t1 ; word _w0, _w1 ; one_one_sub_full ( - _a1, _b1, + _a1, _b1, _s1, _s0) ; one_one_sub_full ( - _a0, _b0, + _a0, _b0, _t1, _t0) ; - + _s0 += _t1; one_one_add_fast ( - _s1, _s0, + _s1, _s0, _w1, _w0) ; - + _w0 += _t0; one_one_add_fast ( - _w1, _w0, + _w1, _w0, _y1, _y0) ; } - + __static_call __inline_call void_type two_one_mul ( word _a1 , @@ -265,17 +265,17 @@ class dd_imp { word _t0, _t1, _ss ; one_one_mul_full ( - _a1, _bb, + _a1, _bb, _t1, _t0) ; - + _ss = _a0 * _bb ; _t0 = _t0 + _ss ; - + one_one_add_fast ( - _t1, _t0, + _t1, _t0, _y1, _y0) ; } - + __static_call __inline_call void_type two_two_mul ( word _a1 , @@ -285,21 +285,21 @@ class dd_imp word& _y1 , word& _y0 ) - { + { word _t0, _t1, _ss ; one_one_mul_full ( - _a1, _b1, + _a1, _b1, _t1, _t0) ; - + _ss = _a1 * _b0 + _a0 * _b1 ; _t0 = _t0 + _ss ; - + one_one_add_fast ( - _t1, _t0, + _t1, _t0, _y1, _y0) ; } - + __static_call __inline_call void_type two_two_div ( word _a1 , @@ -315,36 +315,36 @@ class dd_imp word _r0 , _r1 ; word _w0 , _w1 ; - two_one_mul(_b1, _b0, // rr = bb * t1 - _t1, + two_one_mul(_b1, _b0, // rr = bb * t1 + _t1, _r1, _r0) ; - - two_two_sub(_a1, _a0, // ww = aa - rr + + two_two_sub(_a1, _a0, // ww = aa - rr _r1, _r0, _w1, _w0) ; - + _t0 = _w1 / _b1 ; - + word _u0 , _u1 ; two_one_mul(_b1, _b0, // rr = bb * t0 - _t0, + _t0, _r1, _r0) ; - two_two_sub(_w1, _w0, // uu = ww - rr + two_two_sub(_w1, _w0, // uu = ww - rr _r1, _r0, _u1, _u0) ; - + _ee = _u1 / _b1 ; - + word _q0 , _q1 ; one_one_add_fast(_t1, _t0, _q1, _q0); - - two_one_add(_q1, _q0, - _ee, + + two_one_add(_q1, _q0, + _ee, _t1, _t0) ; - - _y1 = _t1; _y0 = _t0; + + _y1 = _t1; _y0 = _t0; } - + } ; - - + + diff --git a/src/libcpp/mp_floats/mp_imp.hpp b/src/libcpp/mp_floats/mp_imp.hpp index 156a9b4..868e5f7 100644 --- a/src/libcpp/mp_floats/mp_imp.hpp +++ b/src/libcpp/mp_floats/mp_imp.hpp @@ -9,10 +9,10 @@ class mp_imp { public : typedef double word ; - + public : - __static_call + __static_call __inline_call void_type one_one_add_full ( word _aa , word _bb , @@ -21,19 +21,19 @@ class mp_imp ) { _y0 = _aa + _bb ; - + word _t0 , _t1 ; _t0 = _y0 - _aa ; _t1 = _y0 - _t0 ; - + word _t2 , _t3 ; _t2 = _aa - _t1 ; _t3 = _bb - _t0 ; - + _y1 = _t2 + _t3 ; } - __static_call + __static_call __inline_call void_type one_one_sub_full ( word _aa , word _bb , @@ -42,15 +42,15 @@ class mp_imp ) { _y0 = _aa - _bb ; - + word _t0 , _t1 ; - _t0 = _y0 - _aa ; + _t0 = _y0 - _aa ; _t1 = _y0 - _t0 ; - + word _t2 , _t3 ; _t2 = _aa - _t1 ; _t3 = _bb + _t0 ; - + _y1 = _t2 - _t3 ; } @@ -60,12 +60,12 @@ class mp_imp word& _a0 , word& _a1 ) - { - if (_aa > +6.69692879491417E+299 || + { + if (_aa > +6.69692879491417E+299 || _aa < -6.69692879491417E+299 ) { word _tt , _ss ; - _aa*= + _aa*= + 3.7252902984619140625E-09 ; _tt = _aa * 134217729.0 ; _ss = _tt - _aa ; @@ -83,7 +83,7 @@ class mp_imp _a1 = _aa - _a0 ; } } - + __static_call __inline_call void_type one_one_mul_full ( word _aa , @@ -91,18 +91,18 @@ class mp_imp word& _y1 , word& _y0 ) - { + { word _a1, _a0, _b1, _b0 ; one_split(_aa, _a0, _a1); one_split(_bb, _b0, _b1); - + _y0 = _aa * _bb ; - + word _e1, _e2, _e3 ; _e1 = _y0 - (_a0 * _b0) ; _e2 = _e1 - (_a1 * _b0) ; _e3 = _e2 - (_a0 * _b1) ; - + _y1 = (_a1 * _b1) - _e3 ; } @@ -165,24 +165,24 @@ class mp_imp { size_t _nn = +2 ; _nn = std::min (_nn, X) ; - + double _tt ; - __assert( _nn <= X && + __assert( _nn <= X && "MP-FLT: N out of range" ) ; _xx._dn = _nn ; if (_nn == 2) mp_imp::one_one_add_full ( - _aa, _bb, - _xx._dx [ 0], + _aa, _bb, + _xx._dx [ 0], _xx._dx [ 1]) ; else if (_nn == 1) mp_imp::one_one_add_full ( - _aa, _bb, - _xx._dx [ 0], + _aa, _bb, + _xx._dx [ 0], _tt ) ; } @@ -191,7 +191,7 @@ class mp_imp size_t X > __inline_call void_type mp_add ( - mp_flt const& _aa, + mp_flt const& _aa, double _bb, mp_flt & _xx ) @@ -204,7 +204,7 @@ class mp_imp size_t X > __inline_call void_type mp_add ( - mp_flt const& _aa, + mp_flt const& _aa, double _bb, size_t _ib, mp_flt & _xx @@ -213,7 +213,7 @@ class mp_imp size_t _nn = _aa._dn+1 ; _nn = std::min(_nn, X) ; - __assert( _nn <= X && + __assert( _nn <= X && "MP-FLT: N out of range" ) ; _xx._dn = _nn ; @@ -224,7 +224,7 @@ class mp_imp for (_ii = _ib; _ii < _xx._dn-1; ++_ii) { mp_imp::one_one_add_full ( - _aa._dx[_ii], _bb, + _aa._dx[_ii], _bb, _xx._dx[_ii], _tt) ; _bb = _tt ; @@ -238,13 +238,13 @@ class mp_imp size_t X > __inline_call void_type mp_add ( - mp_flt const& _aa, + mp_flt const& _aa, mp_flt const& _bb, mp_flt & _xx ) { mp_add(_aa, _bb._dx[ +0], +0, _xx) ; - + size_t _ii; for (_ii = 1; _ii < _bb._dn; ++_ii) @@ -264,24 +264,24 @@ class mp_imp { size_t _nn = +2 ; _nn = std::min (_nn, X) ; - + double _tt ; - __assert( _nn <= X && + __assert( _nn <= X && "MP-FLT: N out of range" ) ; _xx._dn = _nn ; if (_nn == 2) mp_imp::one_one_sub_full ( - _aa, _bb, - _xx._dx [ 0], + _aa, _bb, + _xx._dx [ 0], _xx._dx [ 1]) ; else if (_nn == 1) mp_imp::one_one_sub_full ( - _aa, _bb, - _xx._dx [ 0], + _aa, _bb, + _xx._dx [ 0], _tt ) ; } @@ -290,7 +290,7 @@ class mp_imp size_t X > __inline_call void_type mp_sub ( - mp_flt const& _aa, + mp_flt const& _aa, double _bb, mp_flt & _xx ) @@ -303,7 +303,7 @@ class mp_imp size_t X > __inline_call void_type mp_sub ( - mp_flt const& _aa, + mp_flt const& _aa, double _bb, size_t _ib, mp_flt & _xx @@ -312,7 +312,7 @@ class mp_imp size_t _nn = _aa._dn+1 ; _nn = std::min(_nn, X) ; - __assert( _nn <= X && + __assert( _nn <= X && "MP-FLT: N out of range" ) ; _xx._dn = _nn ; @@ -323,7 +323,7 @@ class mp_imp for (_ii = _ib; _ii < _xx._dn-1; ++_ii) { mp_imp::one_one_sub_full ( - _aa._dx[_ii], _bb, + _aa._dx[_ii], _bb, _xx._dx[_ii], _tt) ; _bb = _tt ; @@ -337,13 +337,13 @@ class mp_imp size_t X > __inline_call void_type mp_sub ( - mp_flt const& _aa, + mp_flt const& _aa, mp_flt const& _bb, mp_flt & _xx ) { mp_sub(_aa, _bb._dx[ +0], +0, _xx) ; - + size_t _ii; for (_ii = 1; _ii < _bb._dn; ++_ii) diff --git a/src/libcpp/mpfloats.hpp b/src/libcpp/mpfloats.hpp index a5fe989..03f2aa1 100644 --- a/src/libcpp/mpfloats.hpp +++ b/src/libcpp/mpfloats.hpp @@ -1,32 +1,32 @@ -/* +/* ------------------------------------------------------------ * multi-precision floating-point data-types... ------------------------------------------------------------ * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * ------------------------------------------------------------ @@ -56,7 +56,7 @@ # include "mp_floats/qd_flt.hpp" # include "mp_floats/ap_flt.hpp" - + */ # endif//__MP_FLOATS__ diff --git a/src/libcpp/iter_mesh/iter_params.hpp b/src/libcpp/parameters/iter_params.hpp similarity index 72% rename from src/libcpp/iter_mesh/iter_params.hpp rename to src/libcpp/parameters/iter_params.hpp index 6212e13..b41da9c 100644 --- a/src/libcpp/iter_mesh/iter_params.hpp +++ b/src/libcpp/parameters/iter_params.hpp @@ -4,29 +4,29 @@ * ITER-PARAMS: parameters for ITER-MESH-K. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- @@ -53,62 +53,62 @@ * ITER-PARAMS: user-param's for ITER-MESH-K -------------------------------------------------------- */ - + template < - typename R , + typename R , typename I > class iter_params { public : - + typedef R real_type ; typedef I iptr_type ; - + typedef iter_params self_type ; - + iptr_type _verb ; - + iptr_type _iter ; - + real_type _qtol ; real_type _qlim ; - + bool_type _zip_ ; bool_type _div_ ; bool_type _tria ; bool_type _dual ; - - public : - + + public : + /*-------------------------- construct default param. */ __inline_call iter_params ( - ) : + ) : _verb ((iptr_type) + 0 ) , - + _iter ((iptr_type) + 16 ) , - + _qtol ((real_type) +1.E-04) , - _qlim ((real_type) +0.9375) , - + _qlim ((real_type) +0.9375) , + _zip_ ((bool_type) true ) , _div_ ((bool_type) true ) , _tria ((bool_type) true ) , _dual ((bool_type) false ) { // load default values } - + /*------------------------------------ "write" access */ __inline_call iptr_type & verb ( ) { return this->_verb ; } - + __inline_call iptr_type & iter ( ) { return this->_iter ; } - + __inline_call real_type & qtol ( ) { return this->_qtol ; @@ -117,7 +117,7 @@ ) { return this->_qlim ; } - + __inline_call bool_type & zip_ ( ) { return this->_zip_ ; @@ -134,18 +134,18 @@ ) { return this->_dual ; } - + /*------------------------------------ "const" access */ __inline_call iptr_type const& verb ( ) const { return this->_verb ; } - + __inline_call iptr_type const& iter ( ) const { return this->_iter ; } - + __inline_call real_type const& qtol ( ) const { return this->_qtol ; @@ -154,7 +154,7 @@ ) const { return this->_qlim ; } - + __inline_call bool_type const& zip_ ( ) const { return this->_zip_ ; @@ -171,9 +171,9 @@ ) const { return this->_dual ; } - + } ; - + } diff --git a/src/libcpp/rdel_mesh/rdel_params.hpp b/src/libcpp/parameters/mesh_params.hpp similarity index 81% rename from src/libcpp/rdel_mesh/rdel_params.hpp rename to src/libcpp/parameters/mesh_params.hpp index 1818450..91b6a16 100644 --- a/src/libcpp/rdel_mesh/rdel_params.hpp +++ b/src/libcpp/parameters/mesh_params.hpp @@ -1,37 +1,37 @@ /* -------------------------------------------------------- - * RDEL-PARAMS: parameters for RDEL-MESH-K. + * MESH-PARAMS: parameters for meshing kernels. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 10 April, 2019 + * Last updated: 27 November, 2019 * * Copyright 2013-2019 * Darren Engwirda @@ -43,36 +43,36 @@ # pragma once -# ifndef __RDEL_PARAMS__ -# define __RDEL_PARAMS__ +# ifndef __MESH_PARAMS__ +# define __MESH_PARAMS__ namespace mesh { /* -------------------------------------------------------- - * RDEL-PARAMS: user-param's for RDEL-MESH-K + * MESH-PARAMS: user-param's for meshing kernels -------------------------------------------------------- */ - + template < - typename R , + typename R , typename I > - class rdel_params + class mesh_params { public : - + typedef R real_type ; typedef I iptr_type ; - - typedef mesh::rdel_params self_type ; - - enum node_kind { - null_kind = +0 , + + typedef mesh::mesh_params self_type ; + + enum node_kind { // "off-centre" descriptors + null_kind = +0 , fail_kind , circ_kind , // "circ"-type refinement sink_kind , // "sink"-type off-centre - offH_kind , // "size"-type off-centre + offH_kind , // "size"-type off-centre offC_kind , // "circ"-type off-centre offE_kind , // "err."-type off-centre offT_kind , // "topo"-type off-centre @@ -81,10 +81,10 @@ iptr_type _verb ; // logfile output verbosity iptr_type _seed ; // no. init. "seed" nodes - + real_type _phi1 ; // 1-"hard" angle tolerance real_type _phi2 ; // 2-"hard" angle tolerance - + real_type _eta1 ; // 1-"soft" angle tolerance real_type _eta2 ; // 2-"soft" angle tolerance @@ -93,24 +93,24 @@ real_type _near ; // "zip" tolerance for IC's iptr_type _dims ; // topo. dimensions to mesh - + iptr_type _iter ; // max. num. refine iter. - + iptr_type _rule ; // rule for cell refinement - + real_type _siz1 ; // 1-dim. element size mul. real_type _siz2 ; // 2-dim. element size mul. real_type _siz3 ; // 3-dim. element size mul. - + real_type _eps1 ; // 1-dim. 1-hausdorff error real_type _eps2 ; // 2-dim. 2-hausdorff error - + real_type _rad2 ; // 2-dim. radius-edge ratio real_type _rad3 ; // 3-dim. radius-edge ratio - + real_type _off2 ; // 2-off. radius-edge ratio real_type _off3 ; // 3-off. radius-edge ratio - + real_type _snk2 ; // 2-dim. sink "safe" ratio real_type _snk3 ; // 3-dim. sink "safe" ratio @@ -120,7 +120,7 @@ bool_type _top2 ; // impose 2-"manifold-ness" public : - + __static_call __inline_call real_type init_siz1 ( ) @@ -129,16 +129,16 @@ __static_call __inline_call real_type init_siz2 ( ) - { return .5 *(4./3. + + { return .5 *(4./3. + 2. / (1.+std::sqrt(1./3.))) ; } __static_call __inline_call real_type init_siz3 ( ) - { return .5 *(4./3. + + { return .5 *(4./3. + 2. / (1.+std::sqrt(3./8.))) ; } - + __static_call __inline_call iptr_type init_rule ( ) @@ -148,10 +148,10 @@ __setbit( _rule, offC_kind) ; //__setbit( _rule, offT_kind) ; __setbit( _rule, sink_kind) ; - + return _rule ; } - + __static_call __inline_call iptr_type init_iter ( ) @@ -159,85 +159,85 @@ std::numeric_limits ::max()) ; } - - public : - + + public : + /*-------------------------- construct default param. */ - __inline_call rdel_params ( - ) : + __inline_call mesh_params ( + ) : _verb(iptr_type(+ 0)) , - + _seed(iptr_type(+ 8)) , - + _phi1(real_type(+ 60.)) , _phi2(real_type(+ 60.)) , - + _eta1(real_type(+ 45.)) , _eta2(real_type(+ 45.)) , - + _feat(bool_type(false)) , _near(real_type(1.E-8)) , - + _dims(iptr_type(+ 3)) , - + _iter(init_iter()) , - + _rule(init_rule()) , - + _siz1(init_siz1()) , _siz2(init_siz2()) , _siz3(init_siz3()) , - + _eps1(real_type(+.333)) , _eps2(real_type(+.333)) , - + _rad2(real_type(+1.05)) , _rad3(real_type(+2.05)) , - + _off2(real_type(+0.90)) , _off3(real_type(+1.10)) , - + _snk2(real_type(+.200)) , _snk3(real_type(+.333)) , - + _vol3(real_type(+.000)) , - + _top1(bool_type(false)) , _top2(bool_type(false)) { // load default values } - + /*------------------------------------ "write" access */ __inline_call iptr_type & verb ( ) { return this->_verb ; } - + __inline_call iptr_type & rule ( ) { return this->_rule ; } - + __inline_call iptr_type & iter ( ) { return this->_iter ; } - + __inline_call iptr_type & seed ( ) { return this->_seed ; } - + __inline_call real_type & phi1 ( ) { return this->_phi1 ; - } + } __inline_call real_type & phi2 ( ) { return this->_phi2 ; } - + __inline_call real_type & eta1 ( ) { return this->_eta1 ; @@ -246,12 +246,12 @@ ) { return this->_eta2 ; } - + __inline_call bool_type & feat ( ) { return this->_feat ; } - + __inline_call real_type & near ( ) { return this->_near ; @@ -274,7 +274,7 @@ ) { return this->_siz3 ; } - + __inline_call real_type & eps1 ( ) { return this->_eps1 ; @@ -283,7 +283,7 @@ ) { return this->_eps2 ; } - + __inline_call real_type & rad2 ( ) { return this->_rad2 ; @@ -292,7 +292,7 @@ ) { return this->_rad3 ; } - + __inline_call real_type & off2 ( ) { return this->_off2 ; @@ -301,7 +301,7 @@ ) { return this->_off3 ; } - + __inline_call real_type & snk2 ( ) { return this->_snk2 ; @@ -310,7 +310,7 @@ ) { return this->_snk3 ; } - + __inline_call real_type & vol3 ( ) { return this->_vol3 ; @@ -324,37 +324,37 @@ ) { return this->_top2 ; } - + /*------------------------------------ "const" access */ __inline_call iptr_type const& verb ( ) const { return this->_verb ; } - + __inline_call iptr_type const& rule ( ) const { return this->_rule ; } - + __inline_call iptr_type const& iter ( ) const { return this->_iter ; } - + __inline_call iptr_type const& seed ( ) const { return this->_seed ; } - + __inline_call real_type const& phi1 ( ) const { return this->_phi1 ; - } + } __inline_call real_type const& phi2 ( ) const { return this->_phi2 ; } - + __inline_call real_type const& eta1 ( ) const { return this->_eta1 ; @@ -363,7 +363,7 @@ ) const { return this->_eta2 ; } - + __inline_call bool_type const& feat ( ) const { return this->_feat ; @@ -373,7 +373,7 @@ ) const { return this->_near ; } - + __inline_call iptr_type const& dims ( ) const { return this->_dims ; @@ -391,7 +391,7 @@ ) const { return this->_siz3 ; } - + __inline_call real_type const& eps1 ( ) const { return this->_eps1 ; @@ -400,7 +400,7 @@ ) const { return this->_eps2 ; } - + __inline_call real_type const& rad2 ( ) const { return this->_rad2 ; @@ -409,7 +409,7 @@ ) const { return this->_rad3 ; } - + __inline_call real_type const& off2 ( ) const { return this->_off2 ; @@ -418,7 +418,7 @@ ) const { return this->_off3 ; } - + __inline_call real_type const& snk2 ( ) const { return this->_snk2 ; @@ -427,7 +427,7 @@ ) const { return this->_snk3 ; } - + __inline_call real_type const& vol3 ( ) const { return this->_vol3 ; @@ -441,12 +441,12 @@ ) const { return this->_top2 ; } - + } ; } -# endif // __RDEL_PARAMS__ +# endif // __MESH_PARAMS__ diff --git a/src/libcpp/rdel_mesh/rdel_base_2.hpp b/src/libcpp/rdel_mesh/rdel_base_2.hpp index d2ac909..9fbdccc 100644 --- a/src/libcpp/rdel_mesh/rdel_base_2.hpp +++ b/src/libcpp/rdel_mesh/rdel_base_2.hpp @@ -1,37 +1,37 @@ /* -------------------------------------------------------- - * RDEL-PRED-BASE-2: base-class for refinement in R^2. + * RDEL-PRED-BASE-2: base-class for refinement in R^2. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 24 January, 2019 + * Last updated: 10 July, 2019 * * Copyright 2013-2019 * Darren Engwirda @@ -40,55 +40,55 @@ * -------------------------------------------------------- * - * This class defines the basic "restricted" delaunay + * This class defines the basic "restricted" delaunay * predicates for meshing in R^2, as described in: * - * D. Engwirda and D. Ivers, (2016): Off-centre Steiner - * points for Delaunay-refinement on curved surfaces, - * Computer-Aided Design, 72, pp. 157-171, + * D. Engwirda and D. Ivers, (2016): Off-centre Steiner + * points for Delaunay-refinement on curved surfaces, + * Computer-Aided Design, 72, pp. 157-171, * http://dx.doi.org/10.1016/j.cad.2015.10.007 * - * D. Engwirda, (2016): "Conforming restricted Delaunay - * mesh generation for piecewise smooth complexes", - * Procedia Engineering, 163, pp. 84-96, + * D. Engwirda, (2016): "Conforming restricted Delaunay + * mesh generation for piecewise smooth complexes", + * Procedia Engineering, 163, pp. 84-96, * http://dx.doi.org/10.1016/j.proeng.2016.11.024 * * D. Engwirda, (2014): "Locally-optimal Delaunay- - * refinement and optimisation-based mesh generation", - * Ph.D. Thesis, School of Mathematics and Statistics, - * Univ. of Sydney. + * refinement and optimisation-based mesh generation", + * Ph.D. Thesis, School of Mathematics and Statistics, + * Univ. of Sydney. * http://hdl.handle.net/2123/13148 * - * building on various previous works on rDT methods, + * building on various previous works on rDT methods, * including (primarily): * - * J.D. Boissonnat, S. Oudot, (2005): "Provably Good - * Sampling and Meshing of Surfaces", Graphical Models, + * J.D. Boissonnat, S. Oudot, (2005): "Provably Good + * Sampling and Meshing of Surfaces", Graphical Models, * 67, pp. 405-451, * https://doi.org/10.1016/j.gmod.2005.01.004 * - * C. Jamin, P. Alliez, M. Yvinec, and J.D. Boissonnat, - * (2015): "CGALmesh: a generic framework for Delaunay - * mesh generation", ACM Transactions on Mathematical + * C. Jamin, P. Alliez, M. Yvinec, and J.D. Boissonnat, + * (2015): "CGALmesh: a generic framework for Delaunay + * mesh generation", ACM Transactions on Mathematical * Software (TOMS), 41, pp. 23 * https://doi.org/10.1145/2699463 * - * S.W. Cheng, T.K. Dey, E.A. Ramos, (2010): "Delaunay - * Refinement for Piecewise Smooth Complexes", + * S.W. Cheng, T.K. Dey, E.A. Ramos, (2010): "Delaunay + * Refinement for Piecewise Smooth Complexes", * Discrete & Computational Geometry, 43, pp. 121-166, * https://doi.org/10.1007/s00454-008-9109-3 * - * Testing "restricted-ness" by incrementally clipping + * Testing "restricted-ness" by incrementally clipping * against dual half-planes is an elaboration on ideas * introduced in: * - * B. Levy, (2016): "Robustness and efficiency of - * geometric programs: The Predicate Construction Kit + * B. Levy, (2016): "Robustness and efficiency of + * geometric programs: The Predicate Construction Kit * (PCK)", 72, pp. 3-12, * https://doi.org/10.1016/j.cad.2015.10.004 * - * though I make use of an "epsilon"-based strategy - * designed to support geometry predicates that return + * though I make use of an "epsilon"-based strategy + * designed to support geometry predicates that return * intersections that may be "imprecise". * -------------------------------------------------------- @@ -100,7 +100,7 @@ # define __RDEL_PRED_BASE_2__ namespace mesh { - + template < typename G , typename M @@ -108,25 +108,25 @@ class rdel_pred_base_2 { public : - + /*------------ base-class for refinement kern. in R^2 */ - + typedef G geom_type ; typedef M mesh_type ; - typedef typename + typedef typename mesh_type::real_type real_type ; - typedef typename + typedef typename mesh_type::iptr_type iptr_type ; - + typedef containers:: fixed_array half_type ; - typedef typename + typedef typename geom_type::line_type line_type ; - typedef typename + typedef typename geom_type::ball_type ball_type ; - + /* -------------------------------------------------------- * CLIP-DUAL: test pt. wrt dual halfplanes. @@ -146,26 +146,26 @@ _pm[1] = _pa[1] * 0.5 ; _pm[0]+= _pb[0] * 0.5 ; _pm[1]+= _pb[1] * 0.5 ; - + double _ab[2]; _ab[0] = _pb[0] ; _ab[1] = _pb[1] ; _ab[0]-= _pa[0] ; _ab[1]-= _pa[1] ; - + double _mp[2]; _mp[0] = _pp[0] ; _mp[1] = _pp[1] ; _mp[0]-= _pm[0] ; _mp[1]-= _pm[1] ; - - double _dp = - _ab[0] * _mp[0] + + + double _dp = + _ab[0] * _mp[0] + _ab[1] * _mp[1] ; - + return ((double) _dp ); } - + template < typename half_list > @@ -196,13 +196,13 @@ _tria.node(_anod)->pval(0) ; _APOS[1] = _mesh. _tria.node(_anod)->pval(1) ; - + double _BPOS[2] ; _BPOS[0] = _mesh. _tria.node(_bnod)->pval(0) ; _BPOS[1] = _mesh. _tria.node(_bnod)->pval(1) ; - + double _sign = +0.0 ; if (_bnod > _anod) _sign = + half_sign ( @@ -214,7 +214,7 @@ (double*) _PPOS, (double*) _BPOS, (double*) _APOS) ; - + /*-------- "fatten" dual cavity to filter imprecision */ if (_sign >= -_rtol && _sign <= +_rtol) @@ -231,8 +231,8 @@ * EDGE-BALL: calc. edge-based circumballs. -------------------------------------------------------- */ - - __static_call + + __static_call __normal_call bool_type edge_ball ( geom_type &_geom, mesh_type &_mesh, @@ -245,19 +245,24 @@ iptr_type &_part ) { - real_type static const _rEPS = + real_type static const _rEPS = std::pow(std::numeric_limits ::epsilon(),+.67); + real_type _blen = + _geom._bmax[0]-_geom._bmin[0] + + _geom._bmax[1]-_geom._bmin[1] ; + _blen /= (real_type) +2. ; + /*--------------------------- init. output balls = 0. */ _ebal[0] = (real_type) +0. ; _ebal[1] = (real_type) +0. ; _ebal[2] = (real_type) +0. ; - + _sbal[0] = (real_type) +0. ; _sbal[1] = (real_type) +0. ; _sbal[2] = (real_type) +0. ; - + /*--------------------------- get local neighbourhood */ iptr_type _topp = +0 ; iptr_type _eopp = +0 ; @@ -265,12 +270,18 @@ _mesh. _tria.find_pair ( _tadj, _topp, _eadj, _eopp, _tmrk) ; - + /*--------------------------- skip faces adj. to hull */ if (_topp == _mesh._tria.null_flag()) return ( false ) ; - + /*--------------------------- assemble local indexing */ + if (_topp < _tadj) + { + std::swap(_tadj, _topp) ; + std::swap(_eadj, _eopp) ; + } + iptr_type _enod[ +3] ; mesh_type::tria_type::tria_type:: face_node(_enod, _eadj, 2, 1); @@ -280,7 +291,7 @@ tria(_tadj)->node(_enod[ 1]); _enod[2] =_mesh._tria. tria(_tadj)->node(_enod[ 2]); - + iptr_type _onod[ +3] ; mesh_type::tria_type::tria_type:: face_node(_onod, _eopp, 2, 1); @@ -290,172 +301,229 @@ tria(_topp)->node(_onod[ 1]); _onod[2] =_mesh._tria. tria(_topp)->node(_onod[ 2]); - - /*------------------------------ bipolar voronoi edge */ - if (_topp < _tadj) - std::swap(_tadj, _topp); - - real_type _ibal[ 2] = { - _mesh. - _tria.tria(_tadj)->circ( 0), - _mesh. - _tria.tria(_tadj)->circ( 1) - } ; - - real_type _jbal[ 2] = { - _mesh. - _tria.tria(_topp)->circ( 0), - _mesh. - _tria.tria(_topp)->circ( 1) - } ; - - /*--------------------------- calc. intersection halo */ - geometry::circ_ball_2d(_ebal , + + /*--------------------------- calc. faceted face-ball */ + iptr_type _ENOD[ 2] ; + _ENOD[0] = _enod[ 0] ; + _ENOD[1] = _enod[ 1] ; + + algorithms::isort( + &_ENOD[0], &_ENOD[2] , + std::less()) ; + + geometry:: + circ_ball_2d( _ebal, &_mesh._tria. - node(_enod[0])->pval(0), + node(_ENOD[0])->pval(0), &_mesh._tria. - node(_enod[1])->pval(0)) ; - - real_type _nvec[2]; - geometry::line_norm_2d ( + node(_ENOD[1])->pval(0)) ; + + /*--------------------------- est. dual voronoi patch */ + line_type _line; + _line._ipos[0] = + _mesh._tria. + tria(_tadj )->circ(0) ; + _line._ipos[1] = + _mesh._tria. + tria(_tadj )->circ(1) ; + + _line._jpos[0] = + _mesh._tria. + tria(_topp )->circ(0) ; + _line._jpos[1] = + _mesh._tria. + tria(_topp )->circ(1) ; + + real_type _nvec[3]; + geometry::line_norm_2d( &_mesh._tria. - node(_enod[0])->pval(0), + node(_enod[0])->pval(0) , &_mesh._tria. - node(_enod[1])->pval(0), - _nvec) ; + node(_enod[1])->pval(0) , + _nvec) ; + + _nvec[2] = + geometry::length_2d(_nvec) ; + _nvec[0]/= _nvec[2] ; + _nvec[1]/= _nvec[2] ; real_type _ival, _jval; - geometry::proj_line_2d(_ibal , + geometry::proj_line_2d( + _line. _ipos, _ebal, _nvec, _ival) ; - - geometry::proj_line_2d(_jbal , + + geometry::proj_line_2d( + _line. _jpos, _ebal, _nvec, _jval) ; real_type _diff ; _diff = _jval - _ival; - _ival-= _rEPS * _diff; - - _ibal[0] = + + if (_diff > (real_type)0.) + { + _diff = + std::max( _diff, +_blen) ; + } + else + { + _diff = + std::min( _diff, -_blen) ; + } + + _ival -= _rEPS * _diff; + + _line._ipos[0] = _ebal[0] + _ival*_nvec [0] ; - _ibal[1] = + _line._ipos[1] = _ebal[1] + _ival*_nvec [1] ; - - _jval+= _rEPS * _diff; - - _jbal[0] = + + _jval += _rEPS * _diff; + + _line._jpos[0] = _ebal[0] + _jval*_nvec [0] ; - _jbal[1] = + _line._jpos[1] = _ebal[1] + _jval*_nvec [1] ; - + /*--------------------------- find loc. intersections */ - line_type _line ; - _line._ipos[0] = _ibal [0] ; - _line._ipos[1] = _ibal [1] ; - _line._jpos[0] = _jbal [0] ; - _line._jpos[1] = _jbal [1] ; - mesh::keep_all_2d < real_type , - iptr_type > _pred ; + iptr_type > _pred ; if(!_geom.intersect ( _line, _pred) ) /*--------------------------- face cant be restricted */ - return false ; + return false ; /*--------------------------- form list of halfplanes */ containers:: fixed_array _hset ; - + _hset[0][0] = _enod[2] ; _hset[0][1] = _enod[0] ; _hset[1][0] = _enod[2] ; _hset[1][1] = _enod[1] ; - + _hset[2][0] = _onod[2] ; _hset[2][1] = _enod[0] ; _hset[3][0] = _onod[2] ; _hset[3][1] = _enod[1] ; - + /*--------------------------- test loc. intersections */ - auto _imin = _pred._list.tend() ; + auto _iful = _pred._list.tend() ; auto _imax = _pred._list.tend() ; - real_type _RTOL = _rEPS*_ebal[2] ; + real_type _RTOL = _rEPS*_ebal[2]; real_type _dmax = -std::numeric_limits ::infinity() ; - real_type _dmin = - +std::numeric_limits + real_type _dful = + -std::numeric_limits ::infinity() ; - - bool_type _safe, _have = false ; - for (auto _iter = + + bool_type _safe ; + for (auto _iter = _pred._list.head() ; - _iter != + _iter != _pred._list.tend() ; ++_iter ) { - if (clip_dual( _mesh, _hset , - &_iter->pval( 0), + if (clip_dual( _mesh, _hset , + &_iter->pval( 0), _safe, _RTOL) ) { - /*--------------------------- dist to face circumball */ - real_type _dsqr = - geometry::lensqr_2d( - _ebal , - &_iter->pval( 0)) ; + /*--------------------------- prune near-degeneracies */ + if (!_safe) + { + typename mesh_type:: + tria_type:: + tria_pred:: + template circ_pred< + typename mesh_type::tria_type> + _isDT (&_iter-> pval( 0)); - real_type _dtol = - (real_type) 1./3. * _ebal[2] ; + bool_type _okay = + _isDT(_mesh._tria, _tadj, 0)|| + _isDT(_mesh._tria, _topp, 0) ; - if(!_safe && _dsqr > _dtol) - /*--------------------------- prune near-degeneracies */ - continue ; + if (!_okay) continue ; + } + + /*--------------------------- dist to face circumball */ + real_type _dsqr = + geometry::lensqr_2d( + _ebal, + &_iter->pval( 0)) ; /*--------------------------- keep furthest from ball */ if (_dsqr > _dmax ) { - _have = true ; _dmax = _dsqr ; _imax = _iter ; } - if (_dsqr < _dmin ) + if (_dsqr > _dful && + _safe ) { - _have = true ; - _dmin = _dsqr ; - _imin = _iter ; + _dful = _dsqr ; + _iful = _iter ; } } } - if ( _have ) + if (_iful != + _pred._list.tend() ) + { + /*--------------------------- keep best intersections */ + _sbal[ 0] = _iful->pval(0); + _sbal[ 1] = _iful->pval(1); + + _part = _iful->itag (); + _feat = _iful->feat (); + _topo = _iful->topo (); + + /*--------------------------- eval. surf. ball radius */ + _sbal[ 2]+= + geometry::lensqr_2d(_sbal , + &_mesh._tria. + node(_enod[0])->pval(0)) ; + _sbal[ 2]+= + geometry::lensqr_2d(_sbal , + &_mesh._tria. + node(_enod[1])->pval(0)) ; + + _sbal[ 2]/= (real_type) +2.; + + /*--------------------------- return restricted state */ + return ( true ) ; + } + else + if (_imax != + _pred._list.tend() ) { /*--------------------------- keep best intersections */ _sbal[ 0] = _imax->pval(0); _sbal[ 1] = _imax->pval(1); - + _part = _imax->itag (); _feat = _imax->feat (); _topo = _imax->topo (); - + /*--------------------------- eval. surf. ball radius */ - _sbal[ 2]+= - geometry::lensqr_2d(_sbal , + _sbal[ 2]+= + geometry::lensqr_2d(_sbal , &_mesh._tria. node(_enod[0])->pval(0)) ; - _sbal[ 2]+= - geometry::lensqr_2d(_sbal , + _sbal[ 2]+= + geometry::lensqr_2d(_sbal , &_mesh._tria. node(_enod[1])->pval(0)) ; - - _sbal[ 2]/= (real_type) +2.; - + + _sbal[ 2]/= (real_type) +2.; + /*--------------------------- return restricted state */ return ( true ) ; } - + return ( false ) ; } @@ -464,8 +532,8 @@ * TRIA-BALL: calc. tria-based circumballs. -------------------------------------------------------- */ - - __static_call + + __static_call __inline_call bool_type tria_ball ( geom_type &_geom, mesh_type &_mesh, @@ -489,26 +557,26 @@ _tria.tria(_tpos)->circ(+0) ; _tbal[1] = _mesh. _tria.tria(_tpos)->circ(+1) ; - - _tbal[2] = (real_type)+.0 ; - _tbal[2]+= - geometry::lensqr_2d (_tbal, + + _tbal[2] = (real_type)+.0 ; + _tbal[2]+= + geometry::lensqr_2d (_tbal, &_mesh._tria.node( _tnod[0])->pval(0)) ; - _tbal[2]+= - geometry::lensqr_2d (_tbal, + _tbal[2]+= + geometry::lensqr_2d (_tbal, &_mesh._tria.node( _tnod[1])->pval(0)) ; - _tbal[2]+= - geometry::lensqr_2d (_tbal, + _tbal[2]+= + geometry::lensqr_2d (_tbal, &_mesh._tria.node( _tnod[2])->pval(0)) ; - + _tbal[2]/= (real_type)+3. ; - + /*------------------------- evaluate "in--out" status */ - if (_part <= -1 && (_part = - _geom.is_inside(_tbal)) < +0) + if (_part <= -1 && (_part = + _geom.is_inside(_tbal)) < +0) { /*------------------------- is not a restricted facet */ return false ; @@ -516,14 +584,14 @@ else { return true ; - } + } } } ; - + } - + # endif //__RDEL_PRED_BASE_2__ diff --git a/src/libcpp/rdel_mesh/rdel_base_3.hpp b/src/libcpp/rdel_mesh/rdel_base_3.hpp index f552b88..dffe78f 100644 --- a/src/libcpp/rdel_mesh/rdel_base_3.hpp +++ b/src/libcpp/rdel_mesh/rdel_base_3.hpp @@ -1,37 +1,37 @@ /* -------------------------------------------------------- - * RDEL-PRED-BASE-3: base-class for refinement in R^3. + * RDEL-PRED-BASE-3: base-class for refinement in R^3. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 24 January, 2019 + * Last updated: 10 July, 2019 * * Copyright 2013-2019 * Darren Engwirda @@ -40,63 +40,63 @@ * -------------------------------------------------------- * - * This class defines the basic "restricted" delaunay + * This class defines the basic "restricted" delaunay * predicates for meshing in R^3, as described in: * - * D. Engwirda and D. Ivers, (2016): Off-centre Steiner - * points for Delaunay-refinement on curved surfaces, - * Computer-Aided Design, 72, pp. 157-171, + * D. Engwirda and D. Ivers, (2016): Off-centre Steiner + * points for Delaunay-refinement on curved surfaces, + * Computer-Aided Design, 72, pp. 157-171, * http://dx.doi.org/10.1016/j.cad.2015.10.007 * - * D. Engwirda, (2016): "Conforming restricted Delaunay - * mesh generation for piecewise smooth complexes", - * Procedia Engineering, 163, pp. 84-96, + * D. Engwirda, (2016): "Conforming restricted Delaunay + * mesh generation for piecewise smooth complexes", + * Procedia Engineering, 163, pp. 84-96, * http://dx.doi.org/10.1016/j.proeng.2016.11.024 * * D. Engwirda, (2014): "Locally-optimal Delaunay- - * refinement and optimisation-based mesh generation", - * Ph.D. Thesis, School of Mathematics and Statistics, - * Univ. of Sydney. + * refinement and optimisation-based mesh generation", + * Ph.D. Thesis, School of Mathematics and Statistics, + * Univ. of Sydney. * http://hdl.handle.net/2123/13148 * - * building on various previous works on rDT methods, + * building on various previous works on rDT methods, * including (primarily): * - * J.D. Boissonnat, S. Oudot, (2005): "Provably Good - * Sampling and Meshing of Surfaces", Graphical Models, + * J.D. Boissonnat, S. Oudot, (2005): "Provably Good + * Sampling and Meshing of Surfaces", Graphical Models, * 67, pp. 405-451, * https://doi.org/10.1016/j.gmod.2005.01.004 * - * C. Jamin, P. Alliez, M. Yvinec, and J.D. Boissonnat, - * (2015): "CGALmesh: a generic framework for Delaunay - * mesh generation", ACM Transactions on Mathematical + * C. Jamin, P. Alliez, M. Yvinec, and J.D. Boissonnat, + * (2015): "CGALmesh: a generic framework for Delaunay + * mesh generation", ACM Transactions on Mathematical * Software (TOMS), 41, pp. 23 * https://doi.org/10.1145/2699463 * - * S.W. Cheng, T.K. Dey, E.A. Ramos, (2010): "Delaunay - * Refinement for Piecewise Smooth Complexes", + * S.W. Cheng, T.K. Dey, E.A. Ramos, (2010): "Delaunay + * Refinement for Piecewise Smooth Complexes", * Discrete & Computational Geometry, 43, pp. 121-166, * https://doi.org/10.1007/s00454-008-9109-3 * - * The use of dual "faces" to identify "restricted" + * The use of dual "faces" to identify "restricted" * edges is an extension of the methods introduced in: * - * L. Rineau, M. Yvinec, (2008): "Meshing 3D Domains - * Bounded by Piecewise Smooth Surfaces", Proc. of the + * L. Rineau, M. Yvinec, (2008): "Meshing 3D Domains + * Bounded by Piecewise Smooth Surfaces", Proc. of the * 16th International Meshing Roundtable, pp. 443-460, * https://doi.org/10.1007/978-3-540-75103-8_25 * - * Testing "restricted-ness" by incrementally clipping + * Testing "restricted-ness" by incrementally clipping * against dual half-planes is an elaboration on ideas * introduced in: * - * B. Levy, (2016): "Robustness and efficiency of - * geometric programs: The Predicate Construction Kit + * B. Levy, (2016): "Robustness and efficiency of + * geometric programs: The Predicate Construction Kit * (PCK)", 72, pp. 3-12, * https://doi.org/10.1016/j.cad.2015.10.004 * - * though I make use of an "epsilon"-based strategy - * designed to support geometry predicates that return + * though I make use of an "epsilon"-based strategy + * designed to support geometry predicates that return * intersections that may be "imprecise". * -------------------------------------------------------- @@ -108,7 +108,7 @@ # define __RDEL_PRED_BASE_3__ namespace mesh { - + template < typename G , typename M @@ -116,29 +116,29 @@ class rdel_pred_base_3 { public : - + /*------------ base-class for refinement kern. in R^3 */ - + typedef G geom_type ; typedef M mesh_type ; - typedef typename + typedef typename mesh_type::real_type real_type ; - typedef typename + typedef typename mesh_type::iptr_type iptr_type ; typedef containers:: fixed_array half_type ; - typedef typename + typedef typename geom_type::line_type line_type ; - typedef typename + typedef typename geom_type::flat_type flat_type ; - typedef typename + typedef typename geom_type::disc_type disc_type ; - typedef typename + typedef typename geom_type::ball_type ball_type ; - + /* -------------------------------------------------------- * CLIP-DUAL: test pt. wrt dual halfplanes. @@ -160,7 +160,7 @@ _pm[0]+= _pb[0] * 0.5 ; _pm[1]+= _pb[1] * 0.5 ; _pm[2]+= _pb[2] * 0.5 ; - + double _ab[3]; _ab[0] = _pb[0] ; _ab[1] = _pb[1] ; @@ -168,7 +168,7 @@ _ab[0]-= _pa[0] ; _ab[1]-= _pa[1] ; _ab[2]-= _pa[2] ; - + double _mp[3]; _mp[0] = _pp[0] ; _mp[1] = _pp[1] ; @@ -177,12 +177,12 @@ _mp[1]-= _pm[1] ; _mp[2]-= _pm[2] ; - double _dp = - _ab[0] * _mp[0] + - _ab[1] * _mp[1] + + double _dp = + _ab[0] * _mp[0] + + _ab[1] * _mp[1] + _ab[2] * _mp[2] ; - - return ((double) _dp ); + + return ((double) _dp) ; } template < @@ -218,7 +218,7 @@ _tria.node(_anod)->pval(1) ; _APOS[2] = _mesh. _tria.node(_anod)->pval(2) ; - + double _BPOS[3] ; _BPOS[0] = _mesh. _tria.node(_bnod)->pval(0) ; @@ -238,7 +238,7 @@ (double*) _PPOS, (double*) _BPOS, (double*) _APOS) ; - + /*-------- "fatten" dual cavity to filter imprecision */ if (_sign >= -_rtol && _sign <= +_rtol) @@ -255,7 +255,7 @@ * EDGE-LOOP: assemble tria.'s adj. to edge. -------------------------------------------------------- */ - + template < typename list_type > @@ -272,11 +272,11 @@ iptr_type _tcur = _tadj ; iptr_type _fcur = _fadj ; - iptr_type _null = + iptr_type _null = _mesh._tria.null_flag (); while (true) - { + { _loop.push_tail ( _tcur); iptr_type _tpos = _tcur ; @@ -312,7 +312,7 @@ } _mesh._tria.find_pair( - _tpos, _tcur, + _tpos, _tcur, _fpos, _fcur, _tmrk) ; if (_tcur == _tadj) { break ; } @@ -340,10 +340,16 @@ iptr_type &_part ) { - real_type static const _rEPS = + real_type static const _rEPS = std::pow(std::numeric_limits ::epsilon(),+.67); + real_type _blen = + _geom._bmax[0]-_geom._bmin[0] + + _geom._bmax[1]-_geom._bmin[1] + + _geom._bmax[2]-_geom._bmin[2] ; + _blen /= (real_type) +3. ; + /*--------------------------- assemble local indexing */ iptr_type _enod[ +4] ; mesh_type::tria_type::tria_type:: @@ -352,22 +358,22 @@ tria(_tadj)->node(_enod[ 0]); _enod[1] =_mesh._tria. tria(_tadj)->node(_enod[ 1]); - + if (_enod[1] < _enod[0]) std::swap( _enod[0],_enod[1]); - + /*--------------------------- init. output balls = 0. */ _ebal[0] = (real_type) +0. ; _ebal[1] = (real_type) +0. ; _ebal[2] = (real_type) +0. ; _ebal[3] = (real_type) +0. ; - + _sbal[0] = (real_type) +0. ; _sbal[1] = (real_type) +0. ; _sbal[2] = (real_type) +0. ; _sbal[3] = (real_type) +0. ; - - /*--------------------------- get local neighbourhood */ + + /*--------------------------- get local neighbourhood */ iptr_type _fadj; for (_fadj = +4; _fadj-- != +0; ) { @@ -400,19 +406,19 @@ containers::array _hset ; _tset. set_alloc(+32); _hset. set_alloc(+32); - edge_loop( _mesh, _enod, + edge_loop( _mesh, _enod, _tadj, _fadj, _tset) ; - + if (_tset.count()<+3) return false ; /*--------------------------- get the face circumball */ geometry:: - circ_ball_3d( _ebal , + circ_ball_3d( _ebal , &_mesh._tria. node(_enod[0])->pval(0) , &_mesh._tria. node(_enod[1])->pval(0) ) ; - + real_type _evec[ 3] = { _mesh._tria. node(_enod[1])->pval(0) - @@ -426,7 +432,7 @@ node(_enod[1])->pval(2) - _mesh._tria. node(_enod[0])->pval(2) } ; - + /*--------------------------- calc. intersection halo */ real_type _RMIN[3] ; _RMIN[0] = +std:: @@ -435,7 +441,7 @@ numeric_limits::infinity(); _RMIN[2] = +std:: numeric_limits::infinity(); - + real_type _RMAX[3] ; _RMAX[0] = -std:: numeric_limits::infinity(); @@ -443,7 +449,7 @@ numeric_limits::infinity(); _RMAX[2] = -std:: numeric_limits::infinity(); - + for (auto _tpos = _tset.head() ; _tpos != _tset.tend() ; ++_tpos ) @@ -477,22 +483,19 @@ _flat._nvec[0] = _evec [0] ; _flat._nvec[1] = _evec [1] ; _flat._nvec[2] = _evec [2] ; - - real_type _btol = - _rEPS* std::sqrt(_ebal [3]); - - _flat._rmin[0] = _RMIN [0] - - _btol ; - _flat._rmin[1] = _RMIN [1] - - _btol ; - _flat._rmin[2] = _RMIN [2] - - _btol ; - _flat._rmax[0] = _RMAX [0] - + _btol ; - _flat._rmax[1] = _RMAX [1] - + _btol ; - _flat._rmax[2] = _RMAX [2] - + _btol ; + + _flat._rmin[0] = _RMIN [0] + - _rEPS * _blen ; + _flat._rmin[1] = _RMIN [1] + - _rEPS * _blen ; + _flat._rmin[2] = _RMIN [2] + - _rEPS * _blen ; + _flat._rmax[0] = _RMAX [0] + + _rEPS * _blen ; + _flat._rmax[1] = _RMAX [1] + + _rEPS * _blen ; + _flat._rmax[2] = _RMAX [2] + + _rEPS * _blen ; mesh::keep_all_3d < real_type , @@ -549,7 +552,7 @@ /*--------------------------- test loc. intersections */ auto _iful = _pred._list.tend() ; auto _imax = _pred._list.tend() ; - + real_type _RTOL = _rEPS*_ebal[3]; real_type _dmax = @@ -558,30 +561,45 @@ real_type _dful = -std::numeric_limits ::infinity() ; - + bool_type _safe ; - for (auto _iter = + for (auto _iter = _pred._list.head() ; - _iter != + _iter != _pred._list.tend() ; ++_iter ) { - if (clip_dual( _mesh, _hset , - &_iter->pval( 0), + if (clip_dual( _mesh, _hset , + &_iter->pval( 0), _safe, _RTOL) ) { - /*--------------------------- dist to face circumball */ - real_type _dsqr = - geometry::lensqr_3d( - _ebal , - &_iter->pval( 0)) ; + /*--------------------------- prune near-degeneracies */ + if(!_safe) + { + typename mesh_type:: + tria_type:: + tria_pred:: + template circ_pred< + typename mesh_type::tria_type> + _isDT (&_iter-> pval( 0)); + + bool_type _okay = false ; + for (auto _tpos =_tset.head(); + !_okay && _tpos!=_tset.tend(); + ++_tpos ) + { + _okay = _okay || + _isDT(_mesh._tria, *_tpos, 0); + } - real_type _dtol = - (real_type) 1./3. * _ebal[3] ; + if(!_okay) continue ; + } - if(!_safe && _dsqr > _dtol) - /*--------------------------- prune near-degeneracies */ - continue; + /*--------------------------- dist to face circumball */ + real_type _dsqr = + geometry::lensqr_3d( + _ebal, + &_iter->pval( 0)) ; /*--------------------------- keep furthest from ball */ if (_dsqr > _dmax ) @@ -598,66 +616,66 @@ } } - if (_iful != + if (_iful != _pred._list.tend() ) { /*--------------------------- keep best intersections */ _sbal[ 0] = _iful->pval(0); _sbal[ 1] = _iful->pval(1); _sbal[ 2] = _iful->pval(2); - + _part = _iful->itag (); - + _hits = _iful->hits (); _feat = _iful->feat (); _topo = _iful->topo (); - + /*--------------------------- eval. surf. ball radius */ - _sbal[ 3]+= - geometry::lensqr_3d(_sbal , + _sbal[ 3]+= + geometry::lensqr_3d(_sbal , &_mesh._tria. node(_enod[0])->pval(0)) ; - _sbal[ 3]+= - geometry::lensqr_3d(_sbal , + _sbal[ 3]+= + geometry::lensqr_3d(_sbal , &_mesh._tria. node(_enod[1])->pval(0)) ; - - _sbal[ 3]/= (real_type) +2.; - + + _sbal[ 3]/= (real_type) +2.; + /*--------------------------- return restricted state */ return ( true ) ; } else - if (_imax != + if (_imax != _pred._list.tend() ) { /*--------------------------- keep best intersections */ _sbal[ 0] = _imax->pval(0); _sbal[ 1] = _imax->pval(1); _sbal[ 2] = _imax->pval(2); - + _part = _imax->itag (); - + _hits = _imax->hits (); _feat = _imax->feat (); _topo = _imax->topo (); - + /*--------------------------- eval. surf. ball radius */ - _sbal[ 3]+= - geometry::lensqr_3d(_sbal , + _sbal[ 3]+= + geometry::lensqr_3d(_sbal , &_mesh._tria. node(_enod[0])->pval(0)) ; - _sbal[ 3]+= - geometry::lensqr_3d(_sbal , + _sbal[ 3]+= + geometry::lensqr_3d(_sbal , &_mesh._tria. node(_enod[1])->pval(0)) ; - - _sbal[ 3]/= (real_type) +2.; - + + _sbal[ 3]/= (real_type) +2.; + /*--------------------------- return restricted state */ return ( true ) ; } - + return ( false ) ; } @@ -667,7 +685,7 @@ -------------------------------------------------------- */ - __static_call + __static_call __normal_call bool_type face_ball ( geom_type &_geom, mesh_type &_mesh, @@ -680,16 +698,22 @@ iptr_type &_part ) { - real_type static const _rEPS = + real_type static const _rEPS = std::pow(std::numeric_limits ::epsilon(),+.67); + real_type _blen = + _geom._bmax[0]-_geom._bmin[0] + + _geom._bmax[1]-_geom._bmin[1] + + _geom._bmax[2]-_geom._bmin[2] ; + _blen /= (real_type) +3. ; + /*--------------------------- init. output balls = 0. */ _fbal[0] = (real_type) +0. ; _fbal[1] = (real_type) +0. ; _fbal[2] = (real_type) +0. ; _fbal[3] = (real_type) +0. ; - + _sbal[0] = (real_type) +0. ; _sbal[1] = (real_type) +0. ; _sbal[2] = (real_type) +0. ; @@ -708,6 +732,12 @@ return ( false ) ; /*--------------------------- assemble local indexing */ + if (_topp < _tadj) + { + std::swap(_tadj, _topp) ; + std::swap(_fadj, _fopp) ; + } + iptr_type _fnod[ +4] ; mesh_type::tria_type::tria_type:: face_node(_fnod, _fadj, 3, 2); @@ -732,96 +762,118 @@ _onod[3] =_mesh._tria. tria(_topp)->node(_onod[ 3]); - /*------------------------------ bipolar voronoi edge */ - if (_topp < _tadj) - std::swap(_tadj, _topp); - - real_type _ibal[ 3] = { - _mesh. - _tria.tria(_tadj)->circ( 0), - _mesh. - _tria.tria(_tadj)->circ( 1), - _mesh. - _tria.tria(_tadj)->circ( 2) - } ; - - real_type _jbal[ 3] = { - _mesh. - _tria.tria(_topp)->circ( 0), - _mesh. - _tria.tria(_topp)->circ( 1), - _mesh. - _tria.tria(_topp)->circ( 2) - } ; - - /*--------------------------- calc. intersection halo */ - geometry::circ_ball_3d(_fbal , + /*--------------------------- calc. faceted face-ball */ + iptr_type _FNOD[ 3] ; + _FNOD[0] = _fnod[ 0] ; + _FNOD[1] = _fnod[ 1] ; + _FNOD[2] = _fnod[ 2] ; + + algorithms::isort( + &_FNOD[0], &_FNOD[3] , + std::less()) ; + + geometry:: + circ_ball_3d( _fbal, &_mesh._tria. - node(_fnod[0])->pval(0), + node(_FNOD[0])->pval(0), &_mesh._tria. - node(_fnod[1])->pval(0), + node(_FNOD[1])->pval(0), &_mesh._tria. - node(_fnod[2])->pval(0)) ; - - real_type _nvec[3]; - geometry::tria_norm_3d ( + node(_FNOD[2])->pval(0)) ; + + /*--------------------------- est. dual voronoi patch */ + line_type _line; + _line._ipos[0] = + _mesh._tria. + tria(_tadj )->circ(0) ; + _line._ipos[1] = + _mesh._tria. + tria(_tadj )->circ(1) ; + _line._ipos[2] = + _mesh._tria. + tria(_tadj )->circ(2) ; + + _line._jpos[0] = + _mesh._tria. + tria(_topp )->circ(0) ; + _line._jpos[1] = + _mesh._tria. + tria(_topp )->circ(1) ; + _line._jpos[2] = + _mesh._tria. + tria(_topp )->circ(2) ; + + real_type _nvec[4]; + geometry::tria_norm_3d( &_mesh._tria. - node(_fnod[0])->pval(0), + node(_fnod[0])->pval(0) , &_mesh._tria. - node(_fnod[1])->pval(0), + node(_fnod[1])->pval(0) , &_mesh._tria. - node(_fnod[2])->pval(0), - _nvec) ; + node(_fnod[2])->pval(0) , + _nvec) ; + + _nvec[3] = + geometry::length_3d(_nvec) ; + _nvec[0]/= _nvec[3] ; + _nvec[1]/= _nvec[3] ; + _nvec[2]/= _nvec[3] ; real_type _ival, _jval; - geometry::proj_line_3d(_ibal , + geometry::proj_line_3d( + _line. _ipos, _fbal, _nvec, _ival) ; - - geometry::proj_line_3d(_jbal , + + geometry::proj_line_3d( + _line. _jpos, _fbal, _nvec, _jval) ; real_type _diff ; _diff = _jval - _ival; - _ival-= _rEPS * _diff; - - _ibal[0] = + + if (_diff > (real_type)0.) + { + _diff = + std::max( _diff, +_blen) ; + } + else + { + _diff = + std::min( _diff, -_blen) ; + } + + _ival -= _rEPS * _diff; + + _line._ipos[0] = _fbal[0] + _ival*_nvec [0] ; - _ibal[1] = + _line._ipos[1] = _fbal[1] + _ival*_nvec [1] ; - _ibal[2] = + _line._ipos[2] = _fbal[2] + _ival*_nvec [2] ; - - _jval+= _rEPS * _diff; - - _jbal[0] = + + _jval += _rEPS * _diff; + + _line._jpos[0] = _fbal[0] + _jval*_nvec [0] ; - _jbal[1] = + _line._jpos[1] = _fbal[1] + _jval*_nvec [1] ; - _jbal[2] = + _line._jpos[2] = _fbal[2] + _jval*_nvec [2] ; - - /*--------------------------- find loc. intersections */ - line_type _line ; - _line._ipos[0] = _ibal [0] ; - _line._ipos[1] = _ibal [1] ; - _line._ipos[2] = _ibal [2] ; - _line._jpos[0] = _jbal [0] ; - _line._jpos[1] = _jbal [1] ; - _line._jpos[2] = _jbal [2] ; + /*--------------------------- calc. intersection halo */ mesh::keep_all_3d < real_type , - iptr_type > _pred ; + iptr_type > _pred ; if(!_geom.intersect ( _line, _pred) ) /*--------------------------- face cant be restricted */ - return false ; + return false ; /*--------------------------- form list of halfplanes */ containers:: fixed_array _hset ; - + _hset[0][0] = _fnod[3] ; _hset[0][1] = _fnod[0] ; _hset[1][0] = _fnod[3] ; @@ -835,11 +887,11 @@ _hset[4][1] = _fnod[1] ; _hset[5][0] = _onod[3] ; _hset[5][1] = _fnod[2] ; - + /*--------------------------- test loc. intersections */ auto _iful = _pred._list.tend() ; auto _imax = _pred._list.tend() ; - + real_type _RTOL = _rEPS*_fbal[3]; real_type _dmax = @@ -848,30 +900,40 @@ real_type _dful = -std::numeric_limits ::infinity() ; - + bool_type _safe ; - for (auto _iter = + for (auto _iter = _pred._list.head() ; - _iter != + _iter != _pred._list.tend() ; ++_iter ) { - if (clip_dual( _mesh, _hset , - &_iter->pval( 0), + if (clip_dual( _mesh, _hset , + &_iter->pval( 0), _safe, _RTOL) ) { + /*--------------------------- prune near-degeneracies */ + if (!_safe) + { + typename mesh_type:: + tria_type:: + tria_pred:: + template circ_pred< + typename mesh_type::tria_type> + _isDT (&_iter-> pval( 0)); + + bool_type _okay = + _isDT(_mesh._tria, _tadj, 0)|| + _isDT(_mesh._tria, _topp, 0) ; + + if (!_okay) continue ; + } + /*--------------------------- dist to face circumball */ - real_type _dsqr = + real_type _dsqr = geometry::lensqr_3d( - _fbal , - &_iter->pval( 0)) ; - - real_type _dtol = - (real_type) 1./3. * _fbal[3] ; - - if(!_safe && _dsqr > _dtol) - /*--------------------------- prune near-degeneracies */ - continue ; + _fbal, + &_iter->pval( 0)) ; /*--------------------------- keep furthest from ball */ if (_dsqr > _dmax ) @@ -879,7 +941,7 @@ _dmax = _dsqr ; _imax = _iter ; } - if (_dsqr < _dful && + if (_dsqr > _dful && _safe ) { _dful = _dsqr ; @@ -895,27 +957,27 @@ _sbal[ 0] = _iful->pval(0); _sbal[ 1] = _iful->pval(1); _sbal[ 2] = _iful->pval(2); - + _part = _iful->itag (); _feat = _iful->feat (); _topo = _iful->topo (); - + /*--------------------------- eval. surf. ball radius */ - _sbal[ 3]+= - geometry::lensqr_3d(_sbal , + _sbal[ 3]+= + geometry::lensqr_3d(_sbal , &_mesh._tria. node(_fnod[0])->pval(0)) ; - _sbal[ 3]+= - geometry::lensqr_3d(_sbal , + _sbal[ 3]+= + geometry::lensqr_3d(_sbal , &_mesh._tria. node(_fnod[1])->pval(0)) ; - _sbal[ 3]+= - geometry::lensqr_3d(_sbal , + _sbal[ 3]+= + geometry::lensqr_3d(_sbal , &_mesh._tria. node(_fnod[2])->pval(0)) ; - - _sbal[ 3]/= (real_type) +3.; - + + _sbal[ 3]/= (real_type) +3.; + /*--------------------------- return restricted state */ return ( true ) ; } @@ -927,41 +989,41 @@ _sbal[ 0] = _imax->pval(0); _sbal[ 1] = _imax->pval(1); _sbal[ 2] = _imax->pval(2); - + _part = _imax->itag (); _feat = _imax->feat (); _topo = _imax->topo (); - + /*--------------------------- eval. surf. ball radius */ - _sbal[ 3]+= - geometry::lensqr_3d(_sbal , + _sbal[ 3]+= + geometry::lensqr_3d(_sbal , &_mesh._tria. node(_fnod[0])->pval(0)) ; - _sbal[ 3]+= - geometry::lensqr_3d(_sbal , + _sbal[ 3]+= + geometry::lensqr_3d(_sbal , &_mesh._tria. node(_fnod[1])->pval(0)) ; - _sbal[ 3]+= - geometry::lensqr_3d(_sbal , + _sbal[ 3]+= + geometry::lensqr_3d(_sbal , &_mesh._tria. node(_fnod[2])->pval(0)) ; - - _sbal[ 3]/= (real_type) +3.; - + + _sbal[ 3]/= (real_type) +3.; + /*--------------------------- return restricted state */ return ( true ) ; } - + return ( false ) ; } - + /* -------------------------------------------------------- * TRIA-BALL: calc. tria-based circumballs. -------------------------------------------------------- */ - - __static_call + + __static_call __inline_call bool_type tria_ball ( geom_type &_geom, mesh_type &_mesh, @@ -989,30 +1051,30 @@ _tria.tria(_tpos)->circ(+1) ; _tbal[2] = _mesh. _tria.tria(_tpos)->circ(+2) ; - - _tbal[3] = (real_type)+.0 ; - _tbal[3]+= - geometry::lensqr_3d (_tbal, + + _tbal[3] = (real_type)+.0 ; + _tbal[3]+= + geometry::lensqr_3d (_tbal, &_mesh._tria.node( _tnod[0])->pval(0)) ; - _tbal[3]+= - geometry::lensqr_3d (_tbal, + _tbal[3]+= + geometry::lensqr_3d (_tbal, &_mesh._tria.node( _tnod[1])->pval(0)) ; - _tbal[3]+= - geometry::lensqr_3d (_tbal, + _tbal[3]+= + geometry::lensqr_3d (_tbal, &_mesh._tria.node( _tnod[2])->pval(0)) ; - _tbal[3]+= - geometry::lensqr_3d (_tbal, + _tbal[3]+= + geometry::lensqr_3d (_tbal, &_mesh._tria.node( _tnod[3])->pval(0)) ; - + _tbal[3]/= (real_type)+4. ; - + /*------------------------- evaluate "in--out" status */ - if (_part <= -1 && (_part = - _geom.is_inside(_tbal)) < +0) + if (_part <= -1 && (_part = + _geom.is_inside(_tbal)) < +0) { /*------------------------- is not a restricted facet */ return false ; @@ -1022,13 +1084,13 @@ return true ; } } - + } ; - - + + } - + # endif //__RDEL_PRED_BASE_3__ - - - + + + diff --git a/src/libcpp/rdel_mesh/rdel_complex_2.hpp b/src/libcpp/rdel_mesh/rdel_complex_2.hpp index 28802f2..a20700c 100644 --- a/src/libcpp/rdel_mesh/rdel_complex_2.hpp +++ b/src/libcpp/rdel_mesh/rdel_complex_2.hpp @@ -4,36 +4,36 @@ * RDEL-COMPLEX-2: restricted delaunay obj. in R^2. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 08 April, 2018 + * Last updated: 03 July, 2019 * - * Copyright 2013-2018 + * Copyright 2013-2019 * Darren Engwirda * de2363@columbia.edu * https://github.com/dengwirda/ @@ -47,7 +47,7 @@ # define __RDEL_COMPLEX_2__ namespace mesh { - + template < typename R, typename I @@ -55,34 +55,34 @@ class rdel_complex_2d { public : - + /*--------------- restricted delauany-tri obj. in R^2 */ - + typedef R real_type; typedef I iptr_type; - + typedef mesh::delaunay_tri_node_2 < - iptr_type , + iptr_type , real_type > dtri_node_base ; - + typedef mesh::delaunay_tri_tria_2 < - iptr_type , + iptr_type , real_type > dtri_tria_base ; - + class dtri_node : public dtri_node_base { public : - /*---------------------------- delaunay-tri node type */ + /*---------------------------- delaunay-tri node type */ iptr_type _idxh ; iptr_type _part ; - + char_type _fdim ; - + char_type _feat ; char_type _topo ; - + public : - + __inline_call iptr_type & idxh ( ) { @@ -134,15 +134,15 @@ return this->_topo ; } } ; - + class dtri_tria : public dtri_tria_base { public : /*---------------------------- delaunay-tri tria type */ real_type _circ[ +2] ; - + public : - + __inline_call real_type & circ ( iptr_type _ipos ) @@ -156,17 +156,17 @@ return this->_circ[ _ipos] ; } } ; - + typedef mesh::delaunay_tri_euclidean_2 < iptr_type , real_type > dtri_pred ; - + typedef mesh::delaunay_tri_k < dtri_node , dtri_tria , dtri_pred > tria_type ; - - + + #define __hashscal sizeof(iptr_type)/sizeof(uint32_t) class node_data @@ -180,22 +180,22 @@ iptr_type _tadj; } ; - + class ball_data { public : /*---------------------------------------- ball radii */ containers:: fixed_array _ball; - + containers:: fixed_array _node; - + iptr_type _pass; - + char_type _kind; } ; - + class edge_data { public : @@ -213,7 +213,7 @@ char_type _eadj; iptr_type _tadj; } ; - + class tria_data { public : @@ -231,13 +231,13 @@ class node_hash { public : - __inline_call iptr_type operator() ( - node_data const&_node + __inline_call uint32_t operator() ( + node_data const&_ndat ) const { /*----------------------- hash node indexing for node */ return hash::hashword ( - (uint32_t*)&_node._node[0], + (uint32_t*)&_ndat._node[0], +1 * __hashscal, +137); } } ; @@ -245,38 +245,38 @@ { /*----------------------- hash node indexing for ball */ public : - __inline_call iptr_type operator() ( - ball_data const&_ball + __inline_call uint32_t operator() ( + ball_data const&_bdat ) const { return hash::hashword ( - (uint32_t*)&_ball._node[0], + (uint32_t*)&_bdat._node[0], +1 * __hashscal, +137); } } ; class edge_hash { public : - __inline_call iptr_type operator() ( - edge_data const&_edge + __inline_call uint32_t operator() ( + edge_data const&_edat ) const { /*----------------------- hash node indexing for edge */ return hash::hashword ( - (uint32_t*)&_edge._node[0], + (uint32_t*)&_edat._node[0], +2 * __hashscal, +137); } } ; class tria_hash { public : - __inline_call iptr_type operator() ( - tria_data const&_tria + __inline_call uint32_t operator() ( + tria_data const&_tdat ) const { - /*----------------------- hash node indexing for tria */ + /*----------------------- hash node indexing for tria */ return hash::hashword ( - (uint32_t*)&_tria._node[0], + (uint32_t*)&_tdat._node[0], +3 * __hashscal, +137); } } ; @@ -344,7 +344,7 @@ #undef __hashscal - iptr_type static + iptr_type static constexpr pool_byte_size = 96 * 1024 ; typedef allocators::_pool_alloc < @@ -354,33 +354,33 @@ pool_base> pool_wrap ; typedef containers::hash_table < - node_data, - node_hash, + node_data, + node_hash, node_pred, pool_wrap> node_list ; typedef containers::hash_table < - ball_data, - ball_hash, + ball_data, + ball_hash, ball_pred, pool_wrap> ball_list ; typedef containers::hash_table < - edge_data, - edge_hash, + edge_data, + edge_hash, edge_pred, pool_wrap> edge_list ; typedef containers::hash_table < - tria_data, - tria_hash, + tria_data, + tria_hash, tria_pred, pool_wrap> tria_list ; - typedef typename + typedef typename node_list::item_type node_item ; - typedef typename + typedef typename ball_list::item_type ball_item ; - typedef typename + typedef typename edge_list::item_type edge_item ; - typedef typename + typedef typename tria_list::item_type tria_item ; public : @@ -398,7 +398,7 @@ tria_list _tset ; public : - + __inline_call rdel_complex_2d ( //tria_type const& _tsrc = tria_type() ) : _npol( @@ -409,35 +409,55 @@ sizeof(typename edge_list::item_type)) , _tpol( sizeof(typename tria_list::item_type)) , - - _nset(node_hash(), - node_pred(), - +.8, (pool_wrap(&_npol))) , - _bset(ball_hash(), - ball_pred(), - +.8, (pool_wrap(&_bpol))) , - _eset(edge_hash(), - edge_pred(), - +.8, (pool_wrap(&_epol))) , - _tset(tria_hash(), - tria_pred(), - +.8, (pool_wrap(&_tpol))) + + _nset(node_hash(), + node_pred(), + +.8, (pool_wrap(&_npol))) , + _bset(ball_hash(), + ball_pred(), + +.8, (pool_wrap(&_bpol))) , + _eset(edge_hash(), + edge_pred(), + +.8, (pool_wrap(&_epol))) , + _tset(tria_hash(), + tria_pred(), + +.8, (pool_wrap(&_tpol))) { } - __inline_call + __normal_call void_type clear ( + containers::alloc_types _alloc = + containers::loose_alloc + ) + { + this->_tria.clear(_alloc) ; + + this->_nset.clear(_alloc) ; + this->_npol.clear() ; + + this->_bset.clear(_alloc) ; + this->_bpol.clear() ; + + this->_eset.clear(_alloc) ; + this->_epol.clear() ; + + this->_tset.clear(_alloc) ; + this->_tpol.clear() ; + } + + __inline_call typename ball_list::_write_it push_ball ( ball_data const&_bdat ) { return this->_bset.push(_bdat); } - __inline_call + __inline_call typename edge_list::_write_it push_edge ( edge_data const&_edat ) { return this->_eset.push(_edat); } - __inline_call + __inline_call typename tria_list::_write_it push_tria ( tria_data const&_tdat ) @@ -448,19 +468,35 @@ ball_data const&_bdat, ball_data &_same ) - { return this->_bset._pop(_bdat, _same); + { return this->_bset._pop(_bdat, _same); } __inline_call bool_type _pop_edge ( edge_data const&_edat, edge_data &_same ) - { return this->_eset._pop(_edat, _same); + { return this->_eset._pop(_edat, _same); } __inline_call bool_type _pop_tria ( tria_data const&_tdat, tria_data &_same ) - { return this->_tset._pop(_tdat, _same); + { return this->_tset._pop(_tdat, _same); + } + + __inline_call bool_type _pop_ball ( + ball_data const&_bdat + ) + { return this->_bset._pop(_bdat); + } + __inline_call bool_type _pop_edge ( + edge_data const&_edat + ) + { return this->_eset._pop(_edat); + } + __inline_call bool_type _pop_tria ( + tria_data const&_tdat + ) + { return this->_tset._pop(_tdat); } __inline_call bool_type find_ball ( @@ -481,13 +517,13 @@ ) { return this->_tset.find(_tdat, _same); } - + } ; - - + + } - + # endif //__RDEL_COMPLEX_2__ - - - + + + diff --git a/src/libcpp/rdel_mesh/rdel_complex_3.hpp b/src/libcpp/rdel_mesh/rdel_complex_3.hpp index 083e55b..4b55848 100644 --- a/src/libcpp/rdel_mesh/rdel_complex_3.hpp +++ b/src/libcpp/rdel_mesh/rdel_complex_3.hpp @@ -4,36 +4,36 @@ * RDEL-COMPLEX-3: restricted delaunay obj. in R^3. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 12 April, 2018 + * Last updated: 03 July, 2019 * - * Copyright 2013-2018 + * Copyright 2013-2019 * Darren Engwirda * de2363@columbia.edu * https://github.com/dengwirda/ @@ -55,34 +55,34 @@ class rdel_complex_3d { public : - + /*--------------- restricted delauany-tri obj. in R^3 */ - + typedef R real_type; typedef I iptr_type; - + typedef mesh::delaunay_tri_node_3 < - iptr_type , + iptr_type , real_type > dtri_node_base ; - + typedef mesh::delaunay_tri_tria_3 < - iptr_type , + iptr_type , real_type > dtri_tria_base ; - + class dtri_node : public dtri_node_base { public : - /*---------------------------- delaunay-tri node type */ + /*---------------------------- delaunay-tri node type */ iptr_type _idxh ; iptr_type _part ; - + char_type _fdim ; - + char_type _feat ; char_type _topo ; - + public : - + __inline_call iptr_type & idxh ( ) { @@ -112,7 +112,7 @@ ) const { return this->_fdim ; - } + } __inline_call char_type & feat ( ) { @@ -133,16 +133,16 @@ { return this->_topo ; } - } ; - + } ; + class dtri_tria : public dtri_tria_base { public : /*---------------------------- delaunay-tri tria type */ real_type _circ[ +3] ; - + public : - + __inline_call real_type & circ ( iptr_type _ipos ) @@ -155,17 +155,17 @@ { return this->_circ[ _ipos] ; } - } ; - + } ; + typedef mesh::delaunay_tri_euclidean_3 < iptr_type , real_type > dtri_pred ; - + typedef mesh::delaunay_tri_k < dtri_node , dtri_tria , - dtri_pred > tria_type ; - + dtri_pred > tria_type ; + #define __hashscal sizeof(iptr_type)/sizeof(uint32_t) class node_data @@ -179,22 +179,22 @@ iptr_type _tadj; } ; - + class ball_data { public : /*---------------------------------------- ball radii */ containers:: fixed_array _ball; - + containers:: fixed_array _node; - + iptr_type _pass; - + char_type _kind; } ; - + class edge_data { public : @@ -212,7 +212,7 @@ char_type _eadj; iptr_type _tadj; } ; - + class face_data { public : @@ -230,14 +230,14 @@ char_type _fadj; iptr_type _tadj; } ; - + class tria_data { public : /*---------------------------------------- tria nodes */ containers:: fixed_array _node; - + iptr_type _pass; iptr_type _part; char_type _kind; @@ -248,13 +248,13 @@ class node_hash { public : - __inline_call iptr_type operator() ( - node_data const&_node + __inline_call uint32_t operator() ( + node_data const&_ndat ) const { /*----------------------- hash node indexing for node */ return hash::hashword ( - (uint32_t*)&_node._node[0], + (uint32_t*)&_ndat._node[0], +1 * __hashscal, +137); } } ; @@ -262,51 +262,51 @@ { /*----------------------- hash node indexing for ball */ public : - __inline_call iptr_type operator() ( - ball_data const&_ball + __inline_call uint32_t operator() ( + ball_data const&_bdat ) const { return hash::hashword ( - (uint32_t*)&_ball._node[0], + (uint32_t*)&_bdat._node[0], +1 * __hashscal, +137); } } ; class edge_hash { public : - __inline_call iptr_type operator() ( - edge_data const&_edge + __inline_call uint32_t operator() ( + edge_data const&_edat ) const { /*----------------------- hash node indexing for edge */ return hash::hashword ( - (uint32_t*)&_edge._node[0], + (uint32_t*)&_edat._node[0], +2 * __hashscal, +137); } } ; class face_hash { public : - __inline_call iptr_type operator() ( - face_data const&_face + __inline_call uint32_t operator() ( + face_data const&_fdat ) const - { - /*----------------------- hash node indexing for face */ + { + /*----------------------- hash node indexing for face */ return hash::hashword ( - (uint32_t*)&_face._node[0], + (uint32_t*)&_fdat._node[0], +3 * __hashscal, +137); } } ; class tria_hash { public : - __inline_call iptr_type operator() ( - tria_data const&_tria + __inline_call uint32_t operator() ( + tria_data const&_tdat ) const { - /*----------------------- hash node indexing for tria */ + /*----------------------- hash node indexing for tria */ return hash::hashword ( - (uint32_t*)&_tria._node[0], + (uint32_t*)&_tdat._node[0], +4 * __hashscal, +137); } } ; @@ -393,7 +393,7 @@ #undef __hashscal - iptr_type static + iptr_type static constexpr pool_byte_size = 96 * 1024 ; typedef allocators::_pool_alloc < @@ -403,40 +403,40 @@ pool_base> pool_wrap ; typedef containers::hash_table < - node_data, - node_hash, + node_data, + node_hash, node_pred, pool_wrap> node_list ; typedef containers::hash_table < - ball_data, - ball_hash, + ball_data, + ball_hash, ball_pred, pool_wrap> ball_list ; typedef containers::hash_table < - edge_data, - edge_hash, + edge_data, + edge_hash, edge_pred, pool_wrap> edge_list ; typedef containers::hash_table < - face_data, - face_hash, + face_data, + face_hash, face_pred, pool_wrap> face_list ; typedef containers::hash_table < - tria_data, - tria_hash, + tria_data, + tria_hash, tria_pred, pool_wrap> tria_list ; - typedef typename + typedef typename node_list::item_type node_item ; - typedef typename + typedef typename ball_list::item_type ball_item ; - typedef typename + typedef typename edge_list::item_type edge_item ; - typedef typename + typedef typename face_list::item_type face_item ; - typedef typename + typedef typename tria_list::item_type tria_item ; public : @@ -469,43 +469,66 @@ _tpol( sizeof(typename tria_list::item_type)) , - _nset(node_hash(), - node_pred(), - +.8, (pool_wrap(&_npol))) , - _bset(ball_hash(), - ball_pred(), - +.8, (pool_wrap(&_bpol))) , - _eset(edge_hash(), - edge_pred(), - +.8, (pool_wrap(&_epol))) , - _fset(face_hash(), - face_pred(), - +.8, (pool_wrap(&_fpol))) , - _tset(tria_hash(), - tria_pred(), - +.8, (pool_wrap(&_tpol))) + _nset(node_hash(), + node_pred(), + +.8, (pool_wrap(&_npol))) , + _bset(ball_hash(), + ball_pred(), + +.8, (pool_wrap(&_bpol))) , + _eset(edge_hash(), + edge_pred(), + +.8, (pool_wrap(&_epol))) , + _fset(face_hash(), + face_pred(), + +.8, (pool_wrap(&_fpol))) , + _tset(tria_hash(), + tria_pred(), + +.8, (pool_wrap(&_tpol))) { } - __inline_call + __normal_call void_type clear ( + containers::alloc_types _alloc = + containers::loose_alloc + ) + { + this->_tria.clear(_alloc) ; + + this->_nset.clear(_alloc) ; + this->_npol.clear() ; + + this->_bset.clear(_alloc) ; + this->_bpol.clear() ; + + this->_eset.clear(_alloc) ; + this->_epol.clear() ; + + this->_fset.clear(_alloc) ; + this->_fpol.clear() ; + + this->_tset.clear(_alloc) ; + this->_tpol.clear() ; + } + + __inline_call typename ball_list::_write_it push_ball ( ball_data const&_bdat ) { return this->_bset.push(_bdat); } - __inline_call + __inline_call typename edge_list::_write_it push_edge ( edge_data const&_edat ) { return this->_eset.push(_edat); } - __inline_call + __inline_call typename face_list::_write_it push_face ( face_data const&_fdat ) { return this->_fset.push(_fdat); } - __inline_call + __inline_call typename tria_list::_write_it push_tria ( tria_data const&_tdat ) @@ -516,25 +539,46 @@ ball_data const&_bdat, ball_data &_same ) - { return this->_bset._pop(_bdat, _same); + { return this->_bset._pop(_bdat, _same); } __inline_call bool_type _pop_edge ( edge_data const&_edat, edge_data &_same ) - { return this->_eset._pop(_edat, _same); + { return this->_eset._pop(_edat, _same); } __inline_call bool_type _pop_face ( face_data const&_fdat, face_data &_same ) - { return this->_fset._pop(_fdat, _same); + { return this->_fset._pop(_fdat, _same); } __inline_call bool_type _pop_tria ( tria_data const&_tdat, tria_data &_same ) - { return this->_tset._pop(_tdat, _same); + { return this->_tset._pop(_tdat, _same); + } + + __inline_call bool_type _pop_ball ( + ball_data const&_bdat + ) + { return this->_bset._pop(_bdat); + } + __inline_call bool_type _pop_edge ( + edge_data const&_edat + ) + { return this->_eset._pop(_edat); + } + __inline_call bool_type _pop_face ( + face_data const&_fdat + ) + { return this->_fset._pop(_fdat); + } + __inline_call bool_type _pop_tria ( + tria_data const&_tdat + ) + { return this->_tset._pop(_tdat); } __inline_call bool_type find_ball ( @@ -561,13 +605,13 @@ ) { return this->_tset.find(_tdat, _same); } - + } ; - - + + } - + # endif //__RDEL_COMPLEX_3__ - - + + diff --git a/src/libcpp/rdel_mesh/rdel_cost_delaunay_2.inc b/src/libcpp/rdel_mesh/rdel_cost_delaunay_2.inc index cb955d9..4aef371 100644 --- a/src/libcpp/rdel_mesh/rdel_cost_delaunay_2.inc +++ b/src/libcpp/rdel_mesh/rdel_cost_delaunay_2.inc @@ -1,37 +1,37 @@ /* -------------------------------------------------------- - * RDEL-PRED-DELAUNAY-2: "classical" kernel in R^2. + * RDEL-PRED-DELAUNAY-2: "classical" kernel in R^2. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 29 December, 2018 + * Last updated: 30 August, 2019 * * Copyright 2013-2018 * Darren Engwirda @@ -40,16 +40,16 @@ * -------------------------------------------------------- */ - + // from rdel_pred_delaunay_2.hpp - - + + /* -------------------------------------------------------- * EDGE-COST: calc. edge refinement "cost". -------------------------------------------------------- */ - + __static_call __normal_call void_type edge_cost ( geom_type &_geom, @@ -79,44 +79,50 @@ tria(_tadj)->node(_enod[ 0]); _enod[1] =_mesh._tria. tria(_tadj)->node(_enod[ 1]); - + /*--------------------------------- calc. circumballs */ - if (!base_type::edge_ball ( - _geom, _mesh, _tadj, - _eadj, _ebal, _pmax, + if (!base_type::edge_ball ( + _geom, _mesh, _tadj, + _eadj, _ebal, _pmax, _feat, _topo, _part) ) /*--------------------------------- is not restricted */ return ; - + /*------------------------- calc. refinement priority */ - _edat._cost = _pmax[ +2] ; + _edat._cost = (float) _pmax[2] ; /*------------------------- eval. size func. at _tbal */ - real_type _esiz = (real_type)0.; - _esiz += _hfun.eval( + real_type _esiz = (real_type)+0.; + _esiz += (real_type)+1.*_hfun.eval( &_mesh._tria. - node(_enod[0])->pval(0) , + node(_enod[0])->pval(0) , _mesh._tria. node(_enod[0])->idxh()) ; - _esiz += _hfun.eval( + _esiz += (real_type)+1.*_hfun.eval( &_mesh._tria. - node(_enod[1])->pval(0) , + node(_enod[1])->pval(0) , _mesh._tria. node(_enod[1])->idxh()) ; - - _esiz /= (real_type)+2.0 ; + + auto _hint = + _mesh._tria.node(_enod[ 1])->idxh() ; + + _esiz += (real_type)+1.0 * + _hfun.eval( _pmax, _hint) ; + + _esiz /= (real_type)+3.0 ; real_type _eave =_pmax [ +2] ; _eave /= _esiz * _esiz ; _eave *= (real_type)+4.0 ; /*------------------------- eval. surface-disc.-error */ - real_type _srat = + real_type _srat = geometry::lensqr_2d( _ebal, _pmax)/(_esiz * _esiz) ; /*------------------------- refinement classification */ - if (_eave >= _args.siz1() * + if (_eave >= _args.siz1() * _args.siz1() || _srat >= _args.eps1() * _args.eps1() ) @@ -134,7 +140,7 @@ * TRIA-COST: calc. tria refinement "cost". -------------------------------------------------------- */ - + __static_call __normal_call void_type tria_cost ( geom_type &_geom, @@ -163,12 +169,12 @@ /*--------------------------------- calc. circumballs */ real_type _tbal[3] ; - if (!base_type::tria_ball ( - _geom, _mesh, + if (!base_type::tria_ball ( + _geom, _mesh, _tpos, _tbal, _part) ) /*--------------------------------- is not restricted */ return ; - + /*--------------------------------- find edge lengths */ real_type _llen[3] ; iptr_type _enum ; @@ -183,31 +189,31 @@ _enod[1] = _mesh._tria. tria(_tpos)->node(_enod[ 1]); - _llen[_enum] = + _llen[_enum] = geometry::lensqr_2d ( &_mesh._tria. node(_enod[0])->pval(0), &_mesh._tria. node(_enod[1])->pval(0)) ; } - + /*--------------------------------- find min/max edge */ iptr_type _emin = (iptr_type)+0; iptr_type _emax = (iptr_type)+0; for(_enum = +3; _enum-- != +1; ) { - if (_llen[_emax] < _llen[_enum]) + if (_llen[_emax] < _llen[_enum]) _emax = _enum ; - if (_llen[_emin] > _llen[_enum]) + if (_llen[_emin] > _llen[_enum]) _emin = _enum ; } /*------------------------- eval. radius--edge ratios */ - real_type _erat = _tbal[ 2] / + real_type _erat = _tbal[ 2] / _llen[_emin] ; - + /*------------------------- calc. refinement priority */ - _tdat._cost = _erat ; + _tdat._cost = (float) _erat; /*------------------------- refinement classification */ if (_erat >= _args.rad2() * @@ -217,24 +223,30 @@ } /*------------------------- eval. size func. at _tbal */ - real_type _tsiz = (real_type)0.; - _tsiz += _hfun.eval ( + real_type _tsiz = (real_type)+0.; + _tsiz += (real_type)+1.*_hfun.eval( &_mesh._tria. - node(_tnod[0])->pval(0) , + node(_tnod[0])->pval(0) , _mesh._tria. node(_tnod[0])->idxh()) ; - _tsiz += _hfun.eval ( + _tsiz += (real_type)+1.*_hfun.eval( &_mesh._tria. - node(_tnod[1])->pval(0) , + node(_tnod[1])->pval(0) , _mesh._tria. node(_tnod[1])->idxh()) ; - _tsiz += _hfun.eval ( + _tsiz += (real_type)+1.*_hfun.eval( &_mesh._tria. - node(_tnod[2])->pval(0) , + node(_tnod[2])->pval(0) , _mesh._tria. node(_tnod[2])->idxh()) ; - _tsiz /= (real_type)+3.0 ; + auto _hint = + _mesh._tria.node(_tnod[ 2])->idxh() ; + + _tsiz += (real_type)+1.0 * + _hfun.eval( _tbal, _hint) ; + + _tsiz /= (real_type)+4.0 ; real_type _eave = _tbal[ +2] ; _eave /= _tsiz * _tsiz; @@ -251,6 +263,6 @@ _kind = mesh::good_item; return ; } } - - - + + + diff --git a/src/libcpp/rdel_mesh/rdel_cost_delaunay_3.inc b/src/libcpp/rdel_mesh/rdel_cost_delaunay_3.inc index 9187b03..5c04bef 100644 --- a/src/libcpp/rdel_mesh/rdel_cost_delaunay_3.inc +++ b/src/libcpp/rdel_mesh/rdel_cost_delaunay_3.inc @@ -1,37 +1,37 @@ /* -------------------------------------------------------- - * RDEL-PRED-DELAUNAY-3: "classical" kernel in R^3. + * RDEL-PRED-DELAUNAY-3: "classical" kernel in R^3. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 29 December, 2018 + * Last updated: 30 August, 2019 * * Copyright 2013-2018 * Darren Engwirda @@ -41,15 +41,15 @@ -------------------------------------------------------- */ - // from rdel_pred_delaunay_3.hpp - + // from rdel_pred_delaunay_3.hpp + /* -------------------------------------------------------- * EDGE-COST: calc. edge refinement "cost". -------------------------------------------------------- */ - + __static_call __normal_call void_type edge_cost ( geom_type &_geom, @@ -80,45 +80,51 @@ tria(_tadj)->node(_enod[ 0]); _enod[1] =_mesh._tria. tria(_tadj)->node(_enod[ 1]); - + /*--------------------------------- calc. circumballs */ - if (!base_type::edge_ball ( - _geom, _mesh, _tadj, - _eadj, _ebal, _pmax, - _hits, + if (!base_type::edge_ball ( + _geom, _mesh, _tadj, + _eadj, _ebal, _pmax, + _hits, _feat, _topo, _part) ) /*--------------------------------- is not restricted */ return ; - + /*------------------------- calc. refinement priority */ - _edat._cost = _pmax[ +3] ; + _edat._cost = (float) _pmax[3] ; /*------------------------- eval. size func. at _tbal */ - real_type _esiz = (real_type)+0.; - _esiz += _hfun.eval( + real_type _esiz = (real_type)+0.; + _esiz += (real_type)+1.*_hfun.eval( &_mesh._tria. - node(_enod[0])->pval(0) , + node(_enod[0])->pval(0) , _mesh._tria. - node(_enod[0])->idxh()) ; - _esiz += _hfun.eval( + node(_enod[0])->idxh()) ; + _esiz += (real_type)+1.*_hfun.eval( &_mesh._tria. - node(_enod[1])->pval(0) , + node(_enod[1])->pval(0) , _mesh._tria. node(_enod[1])->idxh()) ; - - _esiz /= (real_type)+2.0 ; + + auto _hint = + _mesh._tria.node(_enod[ 1])->idxh() ; + + _esiz += (real_type)+1.0 * + _hfun.eval( _pmax, _hint) ; + + _esiz /= (real_type)+3.0 ; real_type _eave =_pmax [ +3] ; _eave /= _esiz * _esiz ; _eave *= (real_type)+4.0 ; /*------------------------- eval. surface-disc.-error */ - real_type _srat = + real_type _srat = geometry::lensqr_3d( _ebal, _pmax)/(_esiz * _esiz) ; /*------------------------- refinement classification */ - if (_eave >= _args.siz1() * + if (_eave >= _args.siz1() * _args.siz1() || _srat >= _args.eps1() * _args.eps1() ) @@ -130,13 +136,13 @@ _kind = mesh::good_item; return ; } } - + /* -------------------------------------------------------- * FACE-COST: calc. face refinement "cost". -------------------------------------------------------- */ - + __static_call __normal_call void_type face_cost ( geom_type &_geom, @@ -170,13 +176,13 @@ tria(_tadj)->node(_fnod [ 2]) ; /*--------------------------------- calc. circumballs */ - if (!base_type::face_ball ( - _geom, _mesh, _tadj, - _fadj, _tbal, _pmax, + if (!base_type::face_ball ( + _geom, _mesh, _tadj, + _fadj, _tbal, _pmax, _feat, _topo, _part) ) /*--------------------------------- is not restricted */ return ; - + /*--------------------------------- find edge lengths */ real_type _llen[ +3] ; _llen[0] = geometry::lensqr_3d ( @@ -201,24 +207,24 @@ iptr_type _emax = (iptr_type)+0; for(_enum = +3; _enum-- != +1; ) { - if (_llen[_emax] < _llen[_enum]) + if (_llen[_emax] < _llen[_enum]) _emax = _enum ; - if (_llen[_emin] > _llen[_enum]) + if (_llen[_emin] > _llen[_enum]) _emin = _enum ; } /*------------------------- eval. radius--edge ratios */ - real_type _prat = _pmax[ 3] / + real_type _prat = _pmax[ 3] / _llen[_emin] ; - - real_type _erat = _tbal[ 3] / + + real_type _erat = _tbal[ 3] / _llen[_emin] ; __unreferenced(_prat); __unreferenced(_erat); /*------------------------- calc. refinement priority */ - _fdat._cost = _prat ; + _fdat._cost = (float) _prat; /*------------------------- refinement classification */ if (_prat >= _args.rad2() * @@ -226,38 +232,44 @@ { _kind = mesh::ring_item; return ; } - + /*------------------------- eval. size func. at _tbal */ - real_type _tsiz = (real_type)+0. ; - _tsiz += _hfun.eval( + real_type _tsiz = (real_type)+0.; + _tsiz += (real_type)+1.*_hfun.eval( &_mesh._tria. - node(_fnod[0])->pval(0) , + node(_fnod[0])->pval(0) , _mesh._tria. node(_fnod[0])->idxh()) ; - _tsiz += _hfun.eval( + _tsiz += (real_type)+1.*_hfun.eval( &_mesh._tria. - node(_fnod[1])->pval(0) , + node(_fnod[1])->pval(0) , _mesh._tria. node(_fnod[1])->idxh()) ; - _tsiz += _hfun.eval( + _tsiz += (real_type)+1.*_hfun.eval( &_mesh._tria. - node(_fnod[2])->pval(0) , + node(_fnod[2])->pval(0) , _mesh._tria. node(_fnod[2])->idxh()) ; - - _tsiz /= (real_type)+3.0 ; + + auto _hint = + _mesh._tria.node(_fnod[ 2])->idxh() ; + + _tsiz += (real_type)+1.0 * + _hfun.eval( _pmax, _hint) ; + + _tsiz /= (real_type)+4.0 ; real_type _eave =_pmax [ +3] ; _eave /= _tsiz * _tsiz; _eave *= (real_type)+3.0 ; /*------------------------- eval. surface-disc/-error */ - real_type _srat = + real_type _srat = geometry::lensqr_3d( _tbal, _pmax)/(_tsiz * _tsiz) ; /*------------------------- refinement classification */ - if (_eave >= _args.siz2() * + if (_eave >= _args.siz2() * _args.siz2() || _srat >= _args.eps2() * _args.eps2() ) @@ -306,8 +318,8 @@ /*--------------------------------- calc. circumballs */ real_type _tbal[4] ; - if (!base_type::tria_ball ( - _geom, _mesh, + if (!base_type::tria_ball ( + _geom, _mesh, _tpos, _tbal, _part) ) /*--------------------------------- is not restricted */ return ; @@ -326,31 +338,31 @@ _enod[1] = _mesh._tria. tria(_tpos)->node(_enod[ 1]); - _llen[_enum] = + _llen[_enum] = geometry::lensqr_3d ( &_mesh._tria. node(_enod[0])->pval(0), &_mesh._tria. node(_enod[1])->pval(0)) ; } - + /*--------------------------------- find min/max edge */ iptr_type _emin = (iptr_type)+0; iptr_type _emax = (iptr_type)+0; for(_enum = +6; _enum-- != +1; ) { - if (_llen[_emax] < _llen[_enum]) + if (_llen[_emax] < _llen[_enum]) _emax = _enum ; - if (_llen[_emin] > _llen[_enum]) + if (_llen[_emin] > _llen[_enum]) _emin = _enum ; } /*------------------------- eval. radius--edge ratios */ - real_type _erat = _tbal[ 3] / + real_type _erat = _tbal[ 3] / _llen[_emin] ; - + /*------------------------- calc. refinement priority */ - _tdat._cost = _erat; + _tdat._cost = (float) _erat; /*------------------------- refinement classification */ if (_erat >= _args.rad3() * @@ -361,28 +373,34 @@ /*------------------------- eval. size func. at _tbal */ real_type _tsiz = (real_type)+0.; - _tsiz += _hfun.eval( + _tsiz += (real_type)+1.*_hfun.eval( &_mesh._tria. - node(_tnod[0])->pval(0) , + node(_tnod[0])->pval(0) , _mesh._tria. node(_tnod[0])->idxh()) ; - _tsiz += _hfun.eval( + _tsiz += (real_type)+1.*_hfun.eval( &_mesh._tria. - node(_tnod[1])->pval(0) , + node(_tnod[1])->pval(0) , _mesh._tria. node(_tnod[1])->idxh()) ; - _tsiz += _hfun.eval( + _tsiz += (real_type)+1.*_hfun.eval( &_mesh._tria. - node(_tnod[2])->pval(0) , + node(_tnod[2])->pval(0) , _mesh._tria. node(_tnod[2])->idxh()) ; - _tsiz += _hfun.eval( + _tsiz += (real_type)+1.*_hfun.eval( &_mesh._tria. - node(_tnod[3])->pval(0) , + node(_tnod[3])->pval(0) , _mesh._tria. node(_tnod[3])->idxh()) ; - - _tsiz /= (real_type)+4.0 ; + + auto _hint = + _mesh._tria.node(_tnod[ 3])->idxh() ; + + _tsiz += (real_type)+1.0 * + _hfun.eval( _tbal, _hint) ; + + _tsiz /= (real_type)+5.0 ; real_type _eave = _tbal[ +3] ; _eave /= (_tsiz*_tsiz) ; @@ -397,7 +415,7 @@ } /*------------------------- eval. vol.--length metric */ - real_type _vlen = + real_type _vlen = geometry::tria_quality_3d ( &_mesh._tria. node(_tnod[0])->pval(0) , @@ -418,6 +436,6 @@ _kind = mesh::good_item; return ; } } - - - + + + diff --git a/src/libcpp/rdel_mesh/rdel_cost_delfront_2.inc b/src/libcpp/rdel_mesh/rdel_cost_delfront_2.inc index 01d34a1..5da5d63 100644 --- a/src/libcpp/rdel_mesh/rdel_cost_delfront_2.inc +++ b/src/libcpp/rdel_mesh/rdel_cost_delfront_2.inc @@ -1,55 +1,55 @@ /* -------------------------------------------------------- - * RDEL-PRED-DELFRONT-2: "frontal-DEL" kernel in R^2. + * RDEL-PRED-DELFRONT-2: "frontal-DEL" kernel in R^2. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 29 December, 2018 + * Last updated: 30 August, 2019 * - * Copyright 2013-2018 + * Copyright 2013-2019 * Darren Engwirda * de2363@columbia.edu * https://github.com/dengwirda/ * -------------------------------------------------------- */ - + // from rdel_pred_delfront_2.hpp - - + + /* -------------------------------------------------------- * EDGE-COST: calc. edge refinement "cost". -------------------------------------------------------- */ - + __static_call __normal_call void_type edge_cost ( geom_type &_geom, @@ -79,52 +79,64 @@ tria(_tadj)->node(_enod[ 0]); _enod[1] =_mesh._tria. tria(_tadj)->node(_enod[ 1]); - + /*--------------------------------- calc. circumballs */ - if (!base_type::edge_ball ( - _geom, _mesh, _tadj, - _eadj, _ebal, _pmax, + if (!base_type::edge_ball ( + _geom, _mesh, _tadj, + _eadj, _ebal, _pmax, _feat, _topo, _part) ) /*--------------------------------- is not restricted */ return ; - + /*------------------------- calc. refinement priority */ _edat._mark = _mesh._tria.node(_enod[0])->fdim() + _mesh._tria.node(_enod[1])->fdim() ; - _edat._cost = _pmax[2] ; + _edat._cost = + (float) _pmax[2] ; + + // scaling via node numbering seems to make slightly + // better (more topologically regular) meshes + // this implicitly boosts the refinement priority of + // "old" cells, which typically produces meshes with + // fewer "seams"... - _edat._imax = _enod[0] ; - _edat._imax = std::max( - _edat._imax, _enod[1]); + _edat._cost/= _enod[0]+1 ; + _edat._cost/= _enod[1]+1 ; /*------------------------- eval. size func. at _tbal */ real_type _esiz = (real_type)+0.; - _esiz += _hfun.eval( + _esiz += (real_type)+1.*_hfun.eval( &_mesh._tria. - node(_enod[0])->pval(0) , + node(_enod[0])->pval(0) , _mesh._tria. node(_enod[0])->idxh()) ; - _esiz += _hfun.eval( + _esiz += (real_type)+1.*_hfun.eval( &_mesh._tria. - node(_enod[1])->pval(0) , + node(_enod[1])->pval(0) , _mesh._tria. node(_enod[1])->idxh()) ; - - _esiz /= (real_type)+2.0 ; + + auto _hint = + _mesh._tria.node(_enod[ 1])->idxh() ; + + _esiz += (real_type)+1.0 * + _hfun.eval( _pmax, _hint) ; + + _esiz /= (real_type)+3.0 ; real_type _eave =_pmax [ +2] ; _eave /= _esiz * _esiz ; _eave *= (real_type)+4.0 ; /*------------------------- eval. surface-disc.-error */ - real_type _srat = + real_type _srat = geometry::lensqr_2d( _ebal, _pmax)/(_esiz * _esiz) ; /*------------------------- refinement classification */ - if (_eave >= _args.siz1() * + if (_eave >= _args.siz1() * _args.siz1() || _srat >= _args.eps1() * _args.eps1() ) @@ -136,13 +148,13 @@ _kind = mesh::good_item; return ; } } - + /* -------------------------------------------------------- * TRIA-COST: calc. tria refinement "cost". -------------------------------------------------------- */ - + __static_call __normal_call void_type tria_cost ( geom_type &_geom, @@ -171,12 +183,12 @@ /*--------------------------------- calc. circumballs */ real_type _tbal[3] ; - if (!base_type::tria_ball ( - _geom, _mesh, + if (!base_type::tria_ball ( + _geom, _mesh, _tpos, _tbal, _part) ) /*--------------------------------- is not restricted */ return ; - + /*--------------------------------- find edge lengths */ real_type _llen[ +3]; _llen[0] = geometry::lensqr_2d ( @@ -201,16 +213,21 @@ iptr_type _emax = (iptr_type)+0; for(_enum = +3; _enum-- != +1; ) { - if (_llen[_emax] < _llen[_enum]) + if (_llen[_emax] < _llen[_enum]) _emax = _enum ; - if (_llen[_emin] > _llen[_enum]) + if (_llen[_emin] > _llen[_enum]) _emin = _enum ; } - + /*------------------------- calc. refinement priority */ - _tdat._mark = +0 ; + iptr_type _ebnd=_emin ; + real_type _best; + _best = _llen[_emax]; + _best += (real_type)1.; - # ifdef __bias_BNDS + _tdat._mark = +0 ; + + # ifdef __bias_BNDS for(_enum = +3; _enum-- != +0; ) { iptr_type _enod[ +3]; @@ -223,34 +240,50 @@ algorithms::isort( &_enod[0] , &_enod[2] , std::less()) ; - + typename mesh_type:: edge_data _edat; _edat._node[0] = _enod[0] ; _edat._node[1] = _enod[1] ; - + typename mesh_type:: edge_list:: item_type *_eptr = nullptr ; if (_mesh.find_edge(_edat,_eptr)) { + if (_best > _llen[_enum]) + { + _ebnd = _enum ; + _best = _llen[_enum]; + } + _tdat._mark -= +1 ; - } + } } # endif /*------------------------- eval. radius--edge ratios */ - real_type _erat = _tbal[ 2] / + real_type _erat = _tbal[ 2] / _llen[_emin] ; - + /*------------------------- calc. refinement priority */ - _tdat._cost = _erat * _tbal[2] ; + _tdat._cost = + (float) (_erat * _tbal[2]) ; + + // scaling via node numbering seems to make slightly + // better (more topologically regular) meshes + // this implicitly boosts the refinement priority of + // "old" cells, which typically produces meshes with + // fewer "seams"... - _tdat._imax = _tnod[0] ; - _tdat._imax = std::max( - _tdat._imax, _tnod[1]); - _tdat._imax = std::max( - _tdat._imax, _tnod[2]); + iptr_type _enod[ +3]; + mesh_type::tria_type::tria_type:: + face_node(_enod, _ebnd, 2, 1); + _enod[ +0] = _tnod[_enod[+0]]; + _enod[ +1] = _tnod[_enod[+1]]; + + _tdat._cost/= _enod[0] + 1 ; + _tdat._cost/= _enod[1] + 1 ; /*------------------------- refinement classification */ if (_erat >= _args.rad2() * @@ -261,23 +294,29 @@ /*------------------------- eval. size func. at _tbal */ real_type _tsiz = (real_type)+0.; - _tsiz += _hfun.eval( + _tsiz += (real_type)+1.*_hfun.eval( &_mesh._tria. - node(_tnod[0])->pval(0) , + node(_tnod[0])->pval(0) , _mesh._tria. node(_tnod[0])->idxh()) ; - _tsiz += _hfun.eval( + _tsiz += (real_type)+1.*_hfun.eval( &_mesh._tria. - node(_tnod[1])->pval(0) , + node(_tnod[1])->pval(0) , _mesh._tria. node(_tnod[1])->idxh()) ; - _tsiz += _hfun.eval( + _tsiz += (real_type)+1.*_hfun.eval( &_mesh._tria. - node(_tnod[2])->pval(0) , + node(_tnod[2])->pval(0) , _mesh._tria. node(_tnod[2])->idxh()) ; - _tsiz /= (real_type)+3.0 ; + auto _hint = + _mesh._tria.node(_tnod[ 2])->idxh() ; + + _tsiz += (real_type)+1.0 * + _hfun.eval( _tbal, _hint) ; + + _tsiz /= (real_type)+4.0 ; real_type _eave = _tbal[ +2] ; _eave /= _tsiz * _tsiz; @@ -294,6 +333,6 @@ _kind = mesh::good_item; return ; } } - - - + + + diff --git a/src/libcpp/rdel_mesh/rdel_cost_delfront_3.inc b/src/libcpp/rdel_mesh/rdel_cost_delfront_3.inc index 24f1b9f..94cc35c 100644 --- a/src/libcpp/rdel_mesh/rdel_cost_delfront_3.inc +++ b/src/libcpp/rdel_mesh/rdel_cost_delfront_3.inc @@ -1,55 +1,55 @@ /* -------------------------------------------------------- - * RDEL-PRED-DELFRONT-3: "frontal-DEL" kernel in R^3. + * RDEL-PRED-DELFRONT-3: "frontal-DEL" kernel in R^3. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 29 December, 2018 + * Last updated: 30 August, 2019 * - * Copyright 2013-2018 + * Copyright 2013-2019 * Darren Engwirda * de2363@columbia.edu * https://github.com/dengwirda/ * -------------------------------------------------------- */ - + // from rdel_pred_delfront_3.hpp - - + + /* -------------------------------------------------------- * EDGE-COST: calc. edge refinement "cost". -------------------------------------------------------- - */ - + */ + __static_call __normal_call void_type edge_cost ( geom_type &_geom, @@ -69,7 +69,7 @@ ) { _kind = mesh::null_item ; - + if (_args.dims() < +1) return; /*--------------------------- assemble local indexing */ @@ -80,53 +80,65 @@ tria(_tadj)->node(_enod[ 0]); _enod[1] =_mesh._tria. tria(_tadj)->node(_enod[ 1]); - + /*--------------------------------- calc. circumballs */ - if (!base_type::edge_ball ( - _geom, _mesh, _tadj, - _eadj, _ebal, - _pmax, _hits, + if (!base_type::edge_ball ( + _geom, _mesh, _tadj, + _eadj, _ebal, + _pmax, _hits, _feat, _topo, _part) ) /*--------------------------------- is not restricted */ return ; - + /*------------------------- calc. refinement priority */ _edat._mark = _mesh._tria.node(_enod[0])->fdim() + _mesh._tria.node(_enod[1])->fdim() ; - - _edat._cost = _pmax[3] ; - - _edat._imax = _enod[0] ; - _edat._imax = std::max( - _edat._imax, _enod[1]); + + _edat._cost = + (float) _pmax[3] ; + + // scaling via node numbering seems to make slightly + // better (more topologically regular) meshes + // this implicitly boosts the refinement priority of + // "old" cells, which typically produces meshes with + // fewer "seams"... + + _edat._cost/= _enod[0]+1 ; + _edat._cost/= _enod[1]+1 ; /*------------------------- eval. size func. at _tbal */ real_type _esiz = (real_type)+0.; - _esiz += _hfun.eval( + _esiz += (real_type)+1.*_hfun.eval( &_mesh._tria. - node(_enod[0])->pval(0) , + node(_enod[0])->pval(0) , _mesh._tria. node(_enod[0])->idxh()) ; - _esiz += _hfun.eval( + _esiz += (real_type)+1.*_hfun.eval( &_mesh._tria. - node(_enod[1])->pval(0) , + node(_enod[1])->pval(0) , _mesh._tria. node(_enod[1])->idxh()) ; - - _esiz /= (real_type)+2.0 ; + + auto _hint = + _mesh._tria.node(_enod[ 1])->idxh() ; + + _esiz += (real_type)+1.0 * + _hfun.eval( _pmax, _hint) ; + + _esiz /= (real_type)+3.0 ; real_type _eave =_pmax [ +3] ; _eave /= _esiz * _esiz ; _eave *= (real_type)+4.0 ; /*------------------------- eval. surface-disc.-error */ - real_type _srat = + real_type _srat = geometry::lensqr_3d ( _ebal, _pmax)/(_esiz * _esiz) ; /*------------------------- refinement classification */ - if (_eave >= _args.siz1() * + if (_eave >= _args.siz1() * _args.siz1() || _srat >= _args.eps1() * _args.eps1() ) @@ -138,13 +150,13 @@ _kind = mesh::good_item; return ; } } - + /* -------------------------------------------------------- * FACE-COST: calc. face refinement "cost". -------------------------------------------------------- */ - + __static_call __normal_call void_type face_cost ( geom_type &_geom, @@ -178,13 +190,13 @@ tria(_tadj)->node(_fnod[ 2]); /*--------------------------------- calc. circumballs */ - if (!base_type::face_ball ( - _geom, _mesh, _tadj, - _fadj, _tbal, _pmax, + if (!base_type::face_ball ( + _geom, _mesh, _tadj, + _fadj, _tbal, _pmax, _feat, _topo, _part) ) /*--------------------------------- is not restricted */ return ; - + /*--------------------------------- find edge lengths */ real_type _llen[ +3]; _llen[0] = geometry::lensqr_3d ( @@ -209,16 +221,21 @@ iptr_type _emax = (iptr_type)+0; for(_enum = +3; _enum-- != +1; ) { - if (_llen[_emax] < _llen[_enum]) + if (_llen[_emax] < _llen[_enum]) _emax = _enum ; - if (_llen[_emin] > _llen[_enum]) + if (_llen[_emin] > _llen[_enum]) _emin = _enum ; } - + /*------------------------- calc. refinement priority */ + iptr_type _ebnd=_emin ; + real_type _best; + _best = _llen[_emax]; + _best += (real_type)1.; + _fdat._mark = +0 ; - - # ifdef __bias_BNDS + + # ifdef __bias_BNDS for(_enum = +3; _enum-- != +0; ) { iptr_type _enod[ +3]; @@ -231,78 +248,100 @@ algorithms::isort( &_enod[0] , &_enod[2] , std::less()) ; - + typename mesh_type:: edge_data _edat; _edat._node[0] = _enod[0] ; _edat._node[1] = _enod[1] ; - + typename mesh_type:: edge_list:: item_type *_eptr = nullptr ; if (_mesh.find_edge(_edat,_eptr)) { + if (_best > _llen[_enum]) + { + _ebnd = _enum ; + _best = _llen[_enum]; + } + _fdat._mark -= +1 ; - } + } } # endif /*------------------------- eval. radius--edge ratios */ - real_type _prat = _pmax[ 3] / + real_type _prat = _pmax[ 3] / _llen[_emin] ; - real_type _erat = _tbal[ 3] / + real_type _erat = _tbal[ 3] / _llen[_emin] ; __unreferenced(_prat) ; __unreferenced(_erat) ; /*------------------------- calc. refinement priority */ - _fdat._cost = _prat * _pmax[3] ; - - _fdat._imax = _fnod[0] ; - _fdat._imax = std::max( - _fdat._imax, _fnod[1]); - _fdat._imax = std::max( - _fdat._imax, _fnod[2]); - + _fdat._cost = + (float) (_prat * _pmax[3]) ; + + // scaling via node numbering seems to make slightly + // better (more topologically regular) meshes + // this implicitly boosts the refinement priority of + // "old" cells, which typically produces meshes with + // fewer "seams"... + + iptr_type _enod[ +3]; + mesh_type::tria_type::tria_type:: + face_node(_enod, _ebnd, 2, 1); + _enod[ +0] = _fnod[_enod[+0]]; + _enod[ +1] = _fnod[_enod[+1]]; + + _fdat._cost/= _enod[0] + 1 ; + _fdat._cost/= _enod[1] + 1 ; + /*------------------------- refinement classification */ if (_prat >= _args.rad2() * _args.rad2() ) { _kind = mesh::ring_item; return ; } - + /*------------------------- eval. size func. at _fbal */ real_type _tsiz = (real_type)+0.; - _tsiz += _hfun.eval( + _tsiz += (real_type)+1.*_hfun.eval( &_mesh._tria. - node(_fnod[0])->pval(0) , + node(_fnod[0])->pval(0) , _mesh._tria. node(_fnod[0])->idxh()) ; - _tsiz += _hfun.eval( + _tsiz += (real_type)+1.*_hfun.eval( &_mesh._tria. - node(_fnod[1])->pval(0) , + node(_fnod[1])->pval(0) , _mesh._tria. node(_fnod[1])->idxh()) ; - _tsiz += _hfun.eval( + _tsiz += (real_type)+1.*_hfun.eval( &_mesh._tria. - node(_fnod[2])->pval(0) , + node(_fnod[2])->pval(0) , _mesh._tria. node(_fnod[2])->idxh()) ; - _tsiz /= (real_type)+3.0 ; + auto _hint = + _mesh._tria.node(_fnod[ 2])->idxh() ; + + _tsiz += (real_type)+1.0 * + _hfun.eval( _pmax, _hint) ; + + _tsiz /= (real_type)+4.0 ; real_type _eave =_pmax [ +3] ; _eave /= _tsiz * _tsiz; _eave *= (real_type)+3.0 ; /*------------------------- eval. surface-disc.-error */ - real_type _srat = + real_type _srat = geometry::lensqr_3d( _tbal, _pmax)/(_tsiz * _tsiz) ; /*------------------------- refinement classification */ - if (_eave >= _args.siz2() * + if (_eave >= _args.siz2() * _args.siz2() || _srat >= _args.eps2() * _args.eps2() ) @@ -314,13 +353,13 @@ _kind = mesh::good_item; return ; } } - + /* -------------------------------------------------------- * TRIA-COST: calc. tria refinement "cost". -------------------------------------------------------- */ - + __static_call __normal_call void_type tria_cost ( geom_type &_geom, @@ -354,12 +393,12 @@ /*--------------------------------- calc. circumballs */ real_type _tbal[4] ; - if (!base_type::tria_ball ( - _geom, _mesh, + if (!base_type::tria_ball ( + _geom, _mesh, _tpos, _tbal, _part) ) /*--------------------------------- is not restricted */ return ; - + /*--------------------------------- find edge lengths */ real_type _llen[6] ; iptr_type _enum ; @@ -374,17 +413,16 @@ _enod[1] = _mesh._tria. tria(_tpos)->node(_enod[ 1]); - _llen[_enum] = + _llen[_enum] = geometry::lensqr_3d ( &_mesh._tria. node(_enod[0])->pval(0), &_mesh._tria. node(_enod[1])->pval(0)) ; } - + /*--------------------------------- find 2-face radii */ real_type _frad[4] ; - real_type _frat[4] ; iptr_type _fnum ; for(_fnum = +4; _fnum-- != +0; ) { @@ -408,42 +446,17 @@ &_mesh._tria. node(_fnod[2])->pval(0)) ; - real_type _ll12 = - geometry::lensqr_3d ( - &_mesh._tria. - node(_fnod[0])->pval(0), - &_mesh._tria. - node(_fnod[1])->pval(0)) ; - - real_type _ll23 = - geometry::lensqr_3d ( - &_mesh._tria. - node(_fnod[1])->pval(0), - &_mesh._tria. - node(_fnod[2])->pval(0)) ; - - real_type _ll31 = - geometry::lensqr_3d ( - &_mesh._tria. - node(_fnod[2])->pval(0), - &_mesh._tria. - node(_fnod[0])->pval(0)) ; - - _frad[_fnum] = _fbal[ 3] ; - - _frat[_fnum] = _fbal[ 3] / - std::min(_ll12, - std::min(_ll23, _ll31)); + _frad[_fnum] = _fbal[3]; } - + /*--------------------------------- find min/max edge */ iptr_type _emin = (iptr_type)+0; iptr_type _emax = (iptr_type)+0; for(_enum = +6; _enum-- != +1; ) { - if (_llen[_emax] < _llen[_enum]) + if (_llen[_emax] < _llen[_enum]) _emax = _enum ; - if (_llen[_emin] > _llen[_enum]) + if (_llen[_emin] > _llen[_enum]) _emin = _enum ; } @@ -452,15 +465,20 @@ iptr_type _fmax = (iptr_type)+0; for(_fnum = +4; _fnum-- != +1; ) { - if (_frad[_fmax] < _frad[_fnum]) + if (_frad[_fmax] < _frad[_fnum]) _fmax = _fnum ; - if (_frad[_fmin] > _frad[_fnum]) + if (_frad[_fmin] > _frad[_fnum]) _fmin = _fnum ; } /*------------------------- calc. refinement priority */ + iptr_type _fbnd=_fmin ; + real_type _best; + _best = _frad[_fmax]; + _best += (real_type)1.; + _tdat._mark = +0 ; - + # ifdef __bias_BNDS for(_fnum = +4; _fnum-- != +0; ) { @@ -478,40 +496,58 @@ algorithms::isort( &_fnod[0] , &_fnod[3] , std::less()) ; - + typename mesh_type:: face_data _fdat; _fdat._node[0] = _fnod[0] ; _fdat._node[1] = _fnod[1] ; _fdat._node[2] = _fnod[2] ; - + typename mesh_type:: face_list:: item_type *_fptr = nullptr ; if (_mesh.find_face(_fdat,_fptr)) { + if (_best > _frad[_fnum]) + { + _fbnd = _fnum ; + _best = _frad[_fnum]; + } + _tdat._mark -= +1 ; - } + } } # endif /*------------------------- eval. radius--edge ratios */ - real_type _erat = _tbal[ +3] / + real_type _erat = _tbal[ +3] / _llen[_emin] ; - - __unreferenced( _erat) ; - - /*------------------------- calc. refinement priority */ - _tdat._cost = - _erat / _frat[_fmin] * _tbal[3] ; - - _tdat._imax = _tnod[0] ; - _tdat._imax = std::max( - _tdat._imax, _tnod[1]); - _tdat._imax = std::max( - _tdat._imax, _tnod[2]); - _tdat._imax = std::max( - _tdat._imax, _tnod[3]); + + real_type _frat = _tbal[ +3] / + _frad[_fmin] ; + + real_type _trat = _erat*_frat; + + /*------------------------- calc. refinement priority */ + _tdat._cost = + (float) (_trat * _tbal[3]) ; + + // scaling via node numbering seems to make slightly + // better (more topologically regular) meshes + // this implicitly boosts the refinement priority of + // "old" cells, which typically produces meshes with + // fewer "seams"... + + iptr_type _fnod[ +4]; + mesh_type::tria_type::tria_type:: + face_node(_fnod, _fbnd, 3, 2); + _fnod[ +0] = _tnod[_fnod[+0]]; + _fnod[ +1] = _tnod[_fnod[+1]]; + _fnod[ +2] = _tnod[_fnod[+2]]; + + _tdat._cost/= _fnod[0] + 1 ; + _tdat._cost/= _fnod[1] + 1 ; + _tdat._cost/= _fnod[2] + 1 ; /*------------------------- refinement classification */ if (_erat >= _args.rad3() * @@ -522,34 +558,40 @@ /*------------------------- eval. size func. at _tbal */ real_type _tsiz = (real_type)+0.; - _tsiz += _hfun.eval( + _tsiz += (real_type)+1.*_hfun.eval( &_mesh._tria. - node(_tnod[0])->pval(0) , + node(_tnod[0])->pval(0) , _mesh._tria. node(_tnod[0])->idxh()) ; - _tsiz += _hfun.eval( + _tsiz += (real_type)+1.*_hfun.eval( &_mesh._tria. - node(_tnod[1])->pval(0) , + node(_tnod[1])->pval(0) , _mesh._tria. node(_tnod[1])->idxh()) ; - _tsiz += _hfun.eval( + _tsiz += (real_type)+1.*_hfun.eval( &_mesh._tria. - node(_tnod[2])->pval(0) , + node(_tnod[2])->pval(0) , _mesh._tria. node(_tnod[2])->idxh()) ; - _tsiz += _hfun.eval( + _tsiz += (real_type)+1.*_hfun.eval( &_mesh._tria. - node(_tnod[3])->pval(0) , + node(_tnod[3])->pval(0) , _mesh._tria. node(_tnod[3])->idxh()) ; - - _tsiz /= (real_type)+4.0 ; + + auto _hint = + _mesh._tria.node(_tnod[ 3])->idxh() ; + + _tsiz += (real_type)+1.0 * + _hfun.eval( _tbal, _hint) ; + + _tsiz /= (real_type)+5.0 ; real_type _eave = _tbal [+3] ; _eave /= (_tsiz*_tsiz) ; _eave *= (real_type)+8.0 / (real_type)+3.0 ; - + /*------------------------- refinement classification */ if (_eave >= _args.siz3() * _args.siz3() ) @@ -557,8 +599,10 @@ _kind = mesh::ring_item; return ; } + _tdat._mark += +4 ; + /*------------------------- eval. vol.--length metric */ - real_type _vlen = + real_type _vlen = geometry::tria_quality_3d ( &_mesh._tria. node(_tnod[0])->pval(0), @@ -578,6 +622,6 @@ _kind = mesh::good_item; return ; } } - - - + + + diff --git a/src/libcpp/rdel_mesh/rdel_create_init_2.inc b/src/libcpp/rdel_mesh/rdel_create_init_2.inc index 395c4b3..16d7eb8 100644 --- a/src/libcpp/rdel_mesh/rdel_create_init_2.inc +++ b/src/libcpp/rdel_mesh/rdel_create_init_2.inc @@ -4,34 +4,34 @@ * RDEL-INITIAL-MESH-2: set initial conditions in R^2. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 21 June, 2019 + * Last updated: 09 August, 2019 * * Copyright 2013-2019 * Darren Engwirda @@ -50,61 +50,58 @@ -------------------------------------------------------- */ - template < - typename init_type - > __static_call __normal_call void_type init_sort ( init_type &_init, iptr_list &_iset ) { - typedef geom_tree::aabb_node_base_k + typedef geom_tree::aabb_node_base_k tree_node ; typedef geom_tree:: aabb_item_node_k < real_type, iptr_type, 2> tree_item ; - + typedef geom_tree::aabb_tree < tree_item, 2, tree_node, allocator > tree_type ; - + containers::array _bbox; - - /*------------------------------ initialise aabb-tree */ + + /*------------------------------ initialise aabb-tree */ iptr_type _npos = 0 ; tree_type _tree ; - for (auto _node = - _init._mesh._set1.head() ; - _node != + for (auto _node = + _init._mesh._set1.head() ; + _node != _init._mesh._set1.tend() ; ++_node, ++_npos) { if (_node->mark() >= +0) { - + _bbox.push_tail() ; _bbox.tail()-> pval(0) = _node->pval(0) ; _bbox.tail()-> pval(1) = _node->pval(1) ; - + _bbox.tail()-> ipos () = _npos ; - + } } - - iptr_type _NBOX = + + iptr_type _NBOX = (iptr_type) std::pow (8, 2) ; // 8^ndim - + _tree.load(_bbox.head(), _bbox.tend(), _NBOX) ; - - /*------------------------------ randomised tree sort */ + + /*------------------------------ randomised tree sort */ _tree.brio(_iset) ; } @@ -120,18 +117,18 @@ iptr_list &_imap, char_type &_eadj, iptr_type &_tadj, - iptr_type *_enod + iptr_type *_enod ) { class node_pred { /*--------------------- find adj. set of tria-to-node */ public : - + typedef typename mesh_type::tria_type tria_type ; - public : + public : iptr_type _npos; public : @@ -142,9 +139,9 @@ __inline_call bool_type operator() ( tria_type&_tria, iptr_type _tpos, - iptr_type _fpos - ) - { + iptr_type _fpos + ) + { iptr_type _tnod[3] = { _tria.tria(_tpos)->node(0) , _tria.tria(_tpos)->node(1) , @@ -159,7 +156,7 @@ return true ; if (_tnod[2] == this->_npos) return true ; - + return false ; } } ; @@ -168,17 +165,17 @@ _imap[_enod[1]] != -1 ) { /*--------------------- TRUE if we find edge in DTRI. */ - iptr_type _emap[2]; + iptr_type _emap[2]; _emap[0] = _imap[_enod[ 0]] ; _emap[1] = _imap[_enod[ 1]] ; - + /*--------------------- find all tria's about ENOD[0] */ iptr_list _tset; char_type _epos; _tset.set_alloc( +32) ; _mesh._tria.walk_node ( - _emap[0], + _emap[0], node_pred(_emap[0]), _tset); /*--------------------- can find exact match to edge? */ @@ -192,28 +189,28 @@ mesh_type::tria_type:: tria_type::face_node( _ENOD, _epos, +2, +1 ); - + _ENOD[0] = _mesh. _tria .tria( *_tpos)->node(_ENOD[0]); _ENOD[1] = _mesh. _tria .tria( *_tpos)->node(_ENOD[1]); - - iptr_type _same = +0 ; + + iptr_type _same = +0 ; if (_emap[0] == _ENOD[0] || _emap[0] == _ENOD[1] ) _same += +1 ; if (_emap[1] == _ENOD[0] || _emap[1] == _ENOD[1] ) _same += +1 ; - + if (_same == +2 ) { /*--------------------- return TRUE for edge in DTRI. */ - _eadj = _epos ; - - _tadj =*_tpos ; + _eadj = _epos ; + + _tadj =*_tpos ; return true ; } @@ -231,16 +228,14 @@ -------------------------------------------------------- */ - template < - typename init_type - > __static_call __normal_call void_type init_init ( - init_type &_init, - mesh_type &_mesh, - typename + init_type &_init , + geom_type &_geom , + mesh_type &_mesh , + typename mesh_type::edge_list & _epro, - typename + typename mesh_type::edge_list & _ebad, real_type _NEAR ) @@ -250,48 +245,48 @@ iptr_type _null = -1 ; iptr_list _iset, _imap ; init_sort(_init, _iset) ; - + /*------------------------------ find "central" point */ iptr_type _imid = -1 ; - real_type _dmin = + real_type _dmin = std::numeric_limits ::infinity(); - + _imap.set_count ( - _iset.count(), + _iset.count(), containers::tight_alloc, _null); - + real_type _pmid[2] ; _pmid[0] = (real_type) +0. ; _pmid[1] = (real_type) +0. ; - + for (auto _iter = _iset.head(); _iter != _iset.tend(); ++_iter ) { - auto _node = + auto _node = &_init._mesh._set1 [*_iter] ; - _pmid[0] += + _pmid[0] += _node->pval(0); - _pmid[1] += + _pmid[1] += _node->pval(1); } - + _pmid[0] /= _iset.count () ; _pmid[1] /= _iset.count () ; - + for (auto _iter = _iset.head(); _iter != _iset.tend(); ++_iter ) { - auto _node = + auto _node = &_init._mesh._set1 [*_iter] ; - - real_type _dsqr = + + real_type _dsqr = geometry::lensqr_2d( &_node->pval(0), _pmid) ; - + if (_dsqr < _dmin) { _dmin = _dsqr ; @@ -303,24 +298,30 @@ /*------------------------------ seed node from init. */ if (_imid > -1) { - auto _node = + auto _node = &_init._mesh._set1 [ _imid] ; - + iptr_type _npos = -1 ; iptr_type _near = -1 ; - + + if (_node->itag () >= +0 ) + _geom.projector( + &_node->pval(0) , + _node->itag () , + &_node->pval(0) ) ; + if (_mesh._tria.find_node( &_node->pval(0) , _near, _hint ) ) { /*------------------------------ find len. to nearest */ - auto _nptr = + auto _nptr = _mesh._tria. node ( _near) ; _hint = _mesh._tria. node(_near)->next() ; - real_type _dsqr = + real_type _dsqr = geometry::lensqr_2d ( &_node->pval(0) , &_nptr->pval(0) ) ; @@ -328,23 +329,23 @@ if (_dsqr >= _NEAR ) { if (_mesh._tria.push_node( - &_node->pval(0) , + &_node->pval(0) , _npos, _hint ) ) { /*------------------------------ is "new" if distinct */ _imap[_imid] = _npos ; _mesh._tria.node - (_npos)->fdim() + (_npos)->fdim() = _node->fdim() ; - + _mesh._tria.node - (_npos)->feat() + (_npos)->feat() = _node->feat() ; - + _mesh._tria.node - (_npos)->topo() = 2 ; - + (_npos)->topo() = 2 ; + _hint = _npos ; } @@ -366,52 +367,58 @@ _iter != _iset.tend(); ++_iter ) { - if (*_iter == _imid) + if (*_iter == _imid) continue ; - + auto _inum =*_iter; - auto _node = + auto _node = &_init._mesh ._set1[*_iter] ; iptr_type _near = -1 ; iptr_type _npos = -1 ; - + + if (_node->itag () >= +0 ) + _geom.projector( + &_node->pval(0) , + _node->itag () , + &_node->pval(0) ) ; + if (_mesh._tria.find_node( &_node->pval(0) , _near, _hint ) ) { /*------------------------------ find len. to nearest */ - auto _nptr = + auto _nptr = _mesh._tria. node ( _near) ; _hint = _mesh._tria. node(_near)->next() ; - real_type _dsqr = + real_type _dsqr = geometry::lensqr_2d ( &_node->pval(0) , &_nptr->pval(0) ) ; if (_dsqr >= _NEAR ) - { + { if (_mesh._tria.push_node( - &_node->pval(0) , + &_node->pval(0) , _npos, _hint ) ) { /*------------------------------ is "new" if distinct */ _imap[_inum] = _npos ; - + _mesh._tria.node - (_npos)->fdim() + (_npos)->fdim() = _node->fdim() ; - + _mesh._tria.node - (_npos)->feat() + (_npos)->feat() = _node->feat() ; - + _mesh._tria.node - (_npos)->topo() = 2 ; - + (_npos)->topo() = 2 ; + _hint = _npos ; } @@ -429,9 +436,9 @@ } /*------------------------------ seed edge from init. */ - for (auto _iter = + for (auto _iter = _init._mesh._set2.head(); - _iter != + _iter != _init._mesh._set2.tend(); ++_iter ) { @@ -439,28 +446,28 @@ if (_iter->itag() <= -1) { /*------------------------------ find edge "in" DTRI. */ - char_type _eadj ; + char_type _eadj ; iptr_type _tadj ; - if (have_edge( _mesh, + if (have_edge( _mesh, _imap,_eadj,_tadj, &_iter->node( +0 )) ) { /*------------------------------ mark as un-refinable */ edge_data _edat; - _edat._node[0] = + _edat._node[0] = _imap[_iter->node( 0 )] ; - _edat._node[1] = + _edat._node[1] = _imap[_iter->node( 1 )] ; - _edat._part = + _edat._part = _iter->itag() ; - + _edat._eadj = _eadj ; _edat._tadj = _tadj ; algorithms::isort ( - _edat._node.head(), - _edat._node.tend(), + _edat._node.head(), + _edat._node.tend(), std::less()) ; _epro.push(_edat) ; @@ -470,12 +477,12 @@ { /*------------------------------ edge is non-Delaunay */ edge_data _edat; - _edat._node[0] = + _edat._node[0] = _iter->node( 0) ; - _edat._node[1] = + _edat._node[1] = _iter->node( 1) ; - - _edat._part = + + _edat._part = _iter->itag() ; _ebad.push(_edat) ; diff --git a/src/libcpp/rdel_mesh/rdel_create_init_3.inc b/src/libcpp/rdel_mesh/rdel_create_init_3.inc index fae17a4..2d92145 100644 --- a/src/libcpp/rdel_mesh/rdel_create_init_3.inc +++ b/src/libcpp/rdel_mesh/rdel_create_init_3.inc @@ -4,34 +4,34 @@ * RDEL-INITIAL-MESH-3: set initial conditions in R^3. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 21 June, 2019 + * Last updated: 09 August, 2019 * * Copyright 2013-2019 * Darren Engwirda @@ -50,42 +50,39 @@ -------------------------------------------------------- */ - template < - typename init_type - > __static_call __normal_call void_type init_sort ( init_type &_init, iptr_list &_iset ) { - typedef geom_tree::aabb_node_base_k + typedef geom_tree::aabb_node_base_k tree_node ; typedef geom_tree:: aabb_item_node_k < real_type, iptr_type, 3> tree_item ; - + typedef geom_tree::aabb_tree < tree_item, 3, tree_node, allocator > tree_type ; - + containers::array _bbox; - - /*------------------------------ initialise aabb-tree */ + + /*------------------------------ initialise aabb-tree */ iptr_type _npos = 0 ; tree_type _tree ; - for (auto _node = - _init._mesh._set1.head() ; - _node != + for (auto _node = + _init._mesh._set1.head() ; + _node != _init._mesh._set1.tend() ; ++_node, ++_npos) { if (_node->mark() >= +0) { - + _bbox.push_tail() ; _bbox.tail()-> pval(0) = _node->pval(0) ; @@ -93,20 +90,20 @@ pval(1) = _node->pval(1) ; _bbox.tail()-> pval(2) = _node->pval(2) ; - + _bbox.tail()-> ipos () = _npos ; - + } } - - iptr_type _NBOX = + + iptr_type _NBOX = (iptr_type) std::pow (8, 3) ; // 8^ndim - + _tree.load(_bbox.head(), _bbox.tend(), _NBOX) ; - - /*------------------------------ randomised tree sort */ + + /*------------------------------ randomised tree sort */ _tree.brio(_iset) ; } @@ -122,18 +119,18 @@ iptr_list &_imap, char_type &_eadj, iptr_type &_tadj, - iptr_type *_enod + iptr_type *_enod ) { class node_pred { /*--------------------- find adj. set of tria-to-node */ public : - + typedef typename mesh_type::tria_type tria_type ; - public : + public : iptr_type _npos; public : @@ -144,9 +141,9 @@ __inline_call bool_type operator() ( tria_type&_tria, iptr_type _tpos, - iptr_type _fpos - ) - { + iptr_type _fpos + ) + { iptr_type _tnod[4] = { _tria.tria(_tpos)->node(0) , _tria.tria(_tpos)->node(1) , @@ -164,7 +161,7 @@ return true ; if (_tnod[3] == this->_npos) return true ; - + return false ; } } ; @@ -173,17 +170,17 @@ _imap[_enod[1]] != -1 ) { /*--------------------- TRUE if we find edge in DTRI. */ - iptr_type _emap[2]; + iptr_type _emap[2]; _emap[0] = _imap[_enod[ 0]] ; _emap[1] = _imap[_enod[ 1]] ; - + /*--------------------- find all tria's about ENOD[0] */ iptr_list _tset; char_type _epos; _tset.set_alloc( +32) ; _mesh._tria.walk_node ( - _emap[0], + _emap[0], node_pred(_emap[0]), _tset); /*--------------------- can find exact match to edge? */ @@ -197,27 +194,27 @@ mesh_type::tria_type:: tria_type::face_node( _ENOD, _epos, +3, +1 ); - + _ENOD[0] = _mesh. _tria .tria( *_tpos)->node(_ENOD[0]); _ENOD[1] = _mesh. _tria .tria( *_tpos)->node(_ENOD[1]); - - iptr_type _same = +0 ; + + iptr_type _same = +0 ; if (_emap[0] == _ENOD[0] || _emap[0] == _ENOD[1] ) _same += +1 ; if (_emap[1] == _ENOD[0] || _emap[1] == _ENOD[1] ) _same += +1 ; - + if (_same == +2 ) { /*--------------------- return TRUE for edge in DTRI. */ - _eadj = _epos ; - _tadj =*_tpos ; + _eadj = _epos ; + _tadj =*_tpos ; return true ; } @@ -241,18 +238,18 @@ iptr_list &_imap, char_type &_fadj, iptr_type &_tadj, - iptr_type *_fnod + iptr_type *_fnod ) { class node_pred { /*--------------------- find adj. set of tria-to-node */ public : - + typedef typename mesh_type::tria_type tria_type ; - public : + public : iptr_type _npos; public : @@ -263,9 +260,9 @@ __inline_call bool_type operator() ( tria_type&_tria, iptr_type _tpos, - iptr_type _fpos - ) - { + iptr_type _fpos + ) + { iptr_type _tnod[4] = { _tria.tria(_tpos)->node(0) , _tria.tria(_tpos)->node(1) , @@ -283,7 +280,7 @@ return true ; if (_tnod[3] == this->_npos) return true ; - + return false ; } } ; @@ -293,10 +290,10 @@ _imap[_fnod[2]] != -1 ) { /*--------------------- TRUE if we find edge in DTRI. */ - iptr_type _fmap[3]; + iptr_type _fmap[3]; _fmap[0] = _imap[_fnod[ 0]] ; _fmap[1] = _imap[_fnod[ 1]] ; - _fmap[2] = _imap[_fnod[ 2]] ; + _fmap[2] = _imap[_fnod[ 2]] ; /*--------------------- find all tria's about ENOD[0] */ iptr_list _tset; @@ -304,7 +301,7 @@ _tset.set_alloc( +32) ; _mesh._tria.walk_node ( - _fmap[0], + _fmap[0], node_pred(_fmap[0]), _tset); /*--------------------- can find exact match to edge? */ @@ -318,7 +315,7 @@ mesh_type::tria_type:: tria_type::face_node( _FNOD, _fpos, +3, +2 ); - + _FNOD[0] = _mesh. _tria .tria( *_tpos)->node(_FNOD[0]); @@ -328,8 +325,8 @@ _FNOD[2] = _mesh. _tria .tria( *_tpos)->node(_FNOD[2]); - - iptr_type _same = +0 ; + + iptr_type _same = +0 ; if (_fmap[0] == _FNOD[0] || _fmap[0] == _FNOD[1] || _fmap[0] == _FNOD[2] ) @@ -342,12 +339,12 @@ _fmap[2] == _FNOD[1] || _fmap[2] == _FNOD[2] ) _same += +1 ; - + if (_same == +3 ) { /*--------------------- return TRUE for edge in DTRI. */ - _fadj = _fpos ; - _tadj =*_tpos ; + _fadj = _fpos ; + _tadj =*_tpos ; return true ; } @@ -365,20 +362,18 @@ -------------------------------------------------------- */ - template < - typename init_type - > __static_call __normal_call void_type init_init ( - init_type &_init, - mesh_type &_mesh, - typename + init_type &_init , + geom_type &_geom , + mesh_type &_mesh , + typename mesh_type::edge_list & _epro, - typename + typename mesh_type::edge_list & _ebad, - typename + typename mesh_type::face_list & _fpro, - typename + typename mesh_type::face_list & _fbad, real_type _NEAR ) @@ -388,52 +383,52 @@ iptr_type _null = -1 ; iptr_list _iset, _imap ; init_sort(_init, _iset) ; - + /*------------------------------ find "central" point */ iptr_type _imid = -1 ; - real_type _dmin = + real_type _dmin = std::numeric_limits ::infinity(); - + _imap.set_count ( - _iset.count(), + _iset.count(), containers::tight_alloc, _null); - + real_type _pmid[3] ; _pmid[0] = (real_type) +0. ; _pmid[1] = (real_type) +0. ; _pmid[2] = (real_type) +0. ; - + for (auto _iter = _iset.head(); _iter != _iset.tend(); ++_iter ) { - auto _node = + auto _node = &_init._mesh._set1 [*_iter] ; - _pmid[0] += + _pmid[0] += _node->pval(0); - _pmid[1] += + _pmid[1] += _node->pval(1); - _pmid[2] += + _pmid[2] += _node->pval(2); } - + _pmid[0] /= _iset.count () ; _pmid[1] /= _iset.count () ; _pmid[2] /= _iset.count () ; - + for (auto _iter = _iset.head(); _iter != _iset.tend(); ++_iter ) { - auto _node = + auto _node = &_init._mesh._set1 [*_iter] ; - - real_type _dsqr = + + real_type _dsqr = geometry::lensqr_3d( &_node->pval(0), _pmid) ; - + if (_dsqr < _dmin) { _dmin = _dsqr ; @@ -441,28 +436,34 @@ _imid =*_iter ; } } - + /*------------------------------ seed node from init. */ if (_imid > -1) { - auto _node = + auto _node = &_init._mesh._set1 [ _imid] ; - + iptr_type _npos = -1 ; iptr_type _near = -1 ; - + + if (_node->itag () >= +0 ) + _geom.projector( + &_node->pval(0) , + _node->itag () , + &_node->pval(0) ) ; + if (_mesh._tria.find_node( &_node->pval(0) , _near, _hint ) ) { /*------------------------------ find len. to nearest */ - auto _nptr = + auto _nptr = _mesh._tria. node ( _near) ; _hint = _mesh._tria. node(_near)->next() ; - real_type _dsqr = + real_type _dsqr = geometry::lensqr_3d ( &_node->pval(0) , &_nptr->pval(0) ) ; @@ -470,23 +471,23 @@ if (_dsqr >= _NEAR ) { if (_mesh._tria.push_node( - &_node->pval(0) , + &_node->pval(0) , _npos, _hint ) ) { /*------------------------------ is "new" if distinct */ _imap[_imid] = _npos ; _mesh._tria.node - (_npos)->fdim() + (_npos)->fdim() = _node->fdim() ; - + _mesh._tria.node - (_npos)->feat() + (_npos)->feat() = _node->feat() ; - + _mesh._tria.node - (_npos)->topo() = 2 ; - + (_npos)->topo() = 2 ; + _hint = _npos ; } @@ -502,58 +503,64 @@ } } - + /*------------------------------ seed node from init. */ for (auto _iter = _iset.head(); _iter != _iset.tend(); ++_iter ) { - if (*_iter == _imid) + if (*_iter == _imid) continue ; - + auto _inum =*_iter; - auto _node = + auto _node = &_init._mesh ._set1[*_iter] ; iptr_type _near = -1 ; iptr_type _npos = -1 ; - + + if (_node->itag () >= +0 ) + _geom.projector( + &_node->pval(0) , + _node->itag () , + &_node->pval(0) ) ; + if (_mesh._tria.find_node( &_node->pval(0) , _near, _hint ) ) { /*------------------------------ find len. to nearest */ - auto _nptr = + auto _nptr = _mesh._tria. node ( _near) ; _hint = _mesh._tria. node(_near)->next() ; - real_type _dsqr = + real_type _dsqr = geometry::lensqr_3d ( &_node->pval(0) , &_nptr->pval(0) ) ; if (_dsqr >= _NEAR ) - { + { if (_mesh._tria.push_node( - &_node->pval(0) , + &_node->pval(0) , _npos, _hint ) ) { /*------------------------------ is "new" if distinct */ _imap[_inum] = _npos ; - + _mesh._tria.node - (_npos)->fdim() + (_npos)->fdim() = _node->fdim() ; - + _mesh._tria.node - (_npos)->feat() + (_npos)->feat() = _node->feat() ; - + _mesh._tria.node - (_npos)->topo() = 2 ; - + (_npos)->topo() = 2 ; + _hint = _npos ; } @@ -571,9 +578,9 @@ } /*------------------------------ seed edge from init. */ - for (auto _iter = + for (auto _iter = _init._mesh._set2.head(); - _iter != + _iter != _init._mesh._set2.tend(); ++_iter ) { @@ -581,28 +588,28 @@ if (_iter->itag() <= -1) { /*------------------------------ find edge "in" DTRI. */ - char_type _eadj ; + char_type _eadj ; iptr_type _tadj ; - if (have_edge( _mesh, + if (have_edge( _mesh, _imap,_eadj,_tadj, &_iter->node( +0 )) ) { /*------------------------------ mark as un-refinable */ edge_data _edat; - _edat._node[0] = + _edat._node[0] = _imap[_iter->node( 0 )] ; - _edat._node[1] = + _edat._node[1] = _imap[_iter->node( 1 )] ; - _edat._part = + _edat._part = _iter->itag() ; - + _edat._eadj = _eadj ; _edat._tadj = _tadj ; algorithms::isort ( - &_edat._node[0], - &_edat._node[2], + &_edat._node[0], + &_edat._node[2], std::less()) ; _epro.push(_edat) ; @@ -612,12 +619,12 @@ { /*------------------------------ edge is non-Delaunay */ edge_data _edat; - _edat._node[0] = + _edat._node[0] = _iter->node( 0) ; - _edat._node[1] = + _edat._node[1] = _iter->node( 1) ; - - _edat._part = + + _edat._part = _iter->itag() ; _ebad.push(_edat) ; @@ -628,9 +635,9 @@ } /*------------------------------ seed face from init. */ - for (auto _iter = + for (auto _iter = _init._mesh._set3.head(); - _iter != + _iter != _init._mesh._set3.tend(); ++_iter ) { @@ -638,30 +645,30 @@ if (_iter->itag() <= -1) { /*------------------------------ find face "in" DTRI. */ - char_type _fadj ; + char_type _fadj ; iptr_type _tadj ; - if (have_face( _mesh, + if (have_face( _mesh, _imap,_fadj,_tadj, &_iter->node( +0 )) ) { /*------------------------------ mark as un-refinable */ face_data _fdat; - _fdat._node[0] = + _fdat._node[0] = _imap[_iter->node( 0 )] ; - _fdat._node[1] = + _fdat._node[1] = _imap[_iter->node( 1 )] ; - _fdat._node[2] = + _fdat._node[2] = _imap[_iter->node( 2 )] ; - _fdat._part = + _fdat._part = _iter->itag() ; - + _fdat._fadj = _fadj ; _fdat._tadj = _tadj ; algorithms::isort ( - _fdat._node.head(), - _fdat._node.tend(), + _fdat._node.head(), + _fdat._node.tend(), std::less()) ; _fpro.push(_fdat) ; @@ -671,14 +678,14 @@ { /*------------------------------ face is non-Delaunay */ face_data _fdat; - _fdat._node[0] = + _fdat._node[0] = _iter->node( 0) ; - _fdat._node[1] = + _fdat._node[1] = _iter->node( 1) ; - _fdat._node[2] = + _fdat._node[2] = _iter->node( 2) ; - _fdat._part = + _fdat._part = _iter->itag() ; _fbad.push(_fdat) ; diff --git a/src/libcpp/rdel_mesh/rdel_filt_k.hpp b/src/libcpp/rdel_mesh/rdel_filt_k.hpp index d60237a..075b6bc 100644 --- a/src/libcpp/rdel_mesh/rdel_filt_k.hpp +++ b/src/libcpp/rdel_mesh/rdel_filt_k.hpp @@ -4,29 +4,29 @@ * RDEL-FILT-K: proximity filters for RDEL-MESH-K. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- @@ -55,22 +55,22 @@ class keep_base_2d { /*--------------------- "base" intersection predicate */ - public : + public : typedef R real_type ; typedef I iptr_type ; - + class node_data { /*----------------------- internal "co-ord." type */ public : real_type _ppos[2]={(real_type)0.} ; - + char_type _hits ; - + char_type _feat ; char_type _topo ; - - iptr_type _itag ; + + iptr_type _itag ; public : __inline_call real_type & pval ( iptr_type _ipos @@ -114,7 +114,7 @@ ) const { return this-> _itag ; } - } ; + } ; } ; template < @@ -124,22 +124,22 @@ class keep_base_3d { /*-------------------------- intersection "base" type */ - public : + public : typedef R real_type ; - typedef I iptr_type ; - + typedef I iptr_type ; + class node_data { /*----------------------- internal "co-ord." type */ public : real_type _ppos[3]={(real_type)0.} ; - + char_type _hits ; - + char_type _feat ; char_type _topo ; - - iptr_type _itag ; + + iptr_type _itag ; public : __inline_call real_type & pval ( iptr_type _ipos @@ -183,7 +183,7 @@ ) const { return this-> _itag ; } - } ; + } ; } ; template < @@ -193,25 +193,25 @@ class keep_all_2d : public keep_base_2d { /*----------------- "keep-all" intersection predicate */ - public : + public : typedef R real_type ; typedef I iptr_type ; - + typedef keep_base_2d < - real_type , + real_type , iptr_type > pred_base ; public : containers::array < typename pred_base::node_data> _list ; - + iptr_type _inum ; bool_type _find ; - + public : /*------------------------------ construct from _src. */ __inline_call keep_all_2d ( - ) + ) { this->_find = false; this->_inum = +0 ; @@ -221,12 +221,12 @@ ) { this->_list.clear(); - + this->_find = false; this->_inum = +0 ; } /*------------------------------ process intersection */ - __inline_call + __inline_call void_type operator() ( __const_ptr ( real_type) _xpos, char_type _hits, @@ -236,7 +236,7 @@ ) { this->_inum += +1 ; - + this->_list.push_tail() ; this->_list.tail() ->hits () = _hits ; @@ -246,16 +246,16 @@ ->topo () = _topo ; this->_list.tail() ->itag () = _itag ; - + this->_list.tail() ->pval(0) = _xpos[0]; this->_list.tail() ->pval(1) = _xpos[1]; - + this->_find = true ; - } + } } ; - + template < typename R, typename I @@ -263,25 +263,25 @@ class keep_all_3d : public keep_base_3d { /*----------------- "keep-all" intersection predicate */ - public : + public : typedef R real_type ; typedef I iptr_type ; typedef keep_base_3d < - real_type , + real_type , iptr_type > pred_base ; public : containers::array < typename pred_base::node_data> _list ; - + iptr_type _inum ; bool_type _find ; - + public : /*------------------------------ construct from _src. */ __inline_call keep_all_3d ( - ) + ) { this->_find = false; this->_inum = +0 ; @@ -291,12 +291,12 @@ ) { this->_list.clear(); - + this->_find = false; this->_inum = +0 ; } /*------------------------------ process intersection */ - __inline_call + __inline_call void_type operator() ( __const_ptr ( real_type) _xpos, char_type _hits, @@ -306,7 +306,7 @@ ) { this->_inum += +1 ; - + this->_list.push_tail() ; this->_list.tail() ->hits () = _hits ; @@ -316,66 +316,66 @@ ->topo () = _topo ; this->_list.tail() ->itag () = _itag ; - + this->_list.tail() ->pval(0) = _xpos[0]; this->_list.tail() ->pval(1) = _xpos[1]; this->_list.tail() ->pval(2) = _xpos[2]; - + this->_find = true ; - } + } } ; template < typename R, typename I > - class keep_minmax_length_2d + class keep_minmax_length_2d : public keep_base_2d { /*--------- "min/max-distance" intersection predicate */ - public : + public : typedef R real_type ; typedef I iptr_type ; typedef keep_base_3d < - real_type , + real_type , iptr_type > pred_base ; public : containers:: fixed_array _ppos ; - - typename + + typename pred_base::node_data _pmin ; - typename + typename pred_base::node_data _pmax ; real_type _dmin ; real_type _dmax ; iptr_type _inum ; - + bool_type _find ; public : /*------------------------------ construct from _src. */ __inline_call keep_minmax_length_2d ( __const_ptr ( real_type) _psrc - ) + ) { this->_ppos[ 0] = _psrc[ 0] ; this->_ppos[ 1] = _psrc[ 1] ; this->_inum = +0 ; - this->_dmin = + this->_dmin = +std::numeric_limits::infinity(); - this->_dmax = + this->_dmax = -std::numeric_limits::infinity(); - + this->_find = false ; } @@ -390,7 +390,7 @@ { this->_inum += +1 ; /*-------------------------------- calc. distance */ - real_type _dist = + real_type _dist = geometry::lensqr_2d ( _xpos, &this->_ppos[0]); /*------------------------------------- keep min. */ @@ -400,23 +400,23 @@ _pmin.pval(0) = _xpos[0]; this-> _pmin.pval(1) = _xpos[1]; - + this-> _pmin.hits () = _hits; this-> _pmin.feat () = _feat; this-> - _pmin.topo () = _topo; + _pmin.topo () = _topo; this-> _pmin.itag () = _itag; - + this->_dmin = _dist; - + this->_find = true; } /*------------------------------------- keep max. */ if (this->_dmax < _dist || - (this->_dmax == _dist && + (this->_dmax == _dist && this-> _pmax.hits() < _hits) ) { @@ -424,18 +424,18 @@ _pmax.pval(0) = _xpos[0]; this-> _pmax.pval(1) = _xpos[1]; - + this-> _pmax.hits () = _hits; this-> _pmax.feat () = _feat; this-> - _pmax.topo () = _topo; + _pmax.topo () = _topo; this-> _pmax.itag () = _itag; - + this->_dmax = _dist; - + this->_find = true; } } @@ -449,35 +449,35 @@ : public keep_base_3d { /*--------- "min/max-distance" intersection predicate */ - public : + public : typedef R real_type ; typedef I iptr_type ; typedef keep_base_3d < - real_type , + real_type , iptr_type > pred_base ; public : containers:: fixed_array _ppos ; - - typename + + typename pred_base::node_data _pmin ; - typename + typename pred_base::node_data _pmax ; real_type _dmin ; real_type _dmax ; iptr_type _inum ; - + bool_type _find ; public : /*------------------------------ construct from _src. */ __inline_call keep_minmax_length_3d ( __const_ptr ( real_type) _psrc - ) + ) { this->_ppos[ 0] = _psrc[ 0] ; this->_ppos[ 1] = _psrc[ 1] ; @@ -485,16 +485,16 @@ this->_inum = +0 ; - this->_dmin = + this->_dmin = +std::numeric_limits::infinity(); - this->_dmax = + this->_dmax = -std::numeric_limits::infinity(); - - this->_pmin.hits() = + + this->_pmin.hits() = geometry::null_hits; - this->_pmax.hits() = + this->_pmax.hits() = geometry::null_hits; - + this->_find = false ; } @@ -509,7 +509,7 @@ { this->_inum += +1 ; /*-------------------------------- calc. distance */ - real_type _dist = + real_type _dist = geometry::lensqr_3d ( _xpos, &this->_ppos[0]); /*------------------------------------- keep min. */ @@ -521,18 +521,18 @@ _pmin.pval(1) = _xpos[1]; this-> _pmin.pval(2) = _xpos[2]; - + this-> _pmin.hits () = _hits; this-> _pmin.feat () = _feat; this-> - _pmin.topo () = _topo; + _pmin.topo () = _topo; this-> _pmin.itag () = _itag; - + this->_dmin = _dist; - + this->_find = true; } /*------------------------------------- keep max. */ @@ -544,18 +544,18 @@ _pmax.pval(1) = _xpos[1]; this-> _pmax.pval(2) = _xpos[2]; - + this-> _pmax.hits () = _hits; this-> _pmax.feat () = _feat; this-> - _pmax.topo () = _topo; + _pmax.topo () = _topo; this-> _pmax.itag () = _itag; - + this->_dmax = _dist; - + this->_find = true; } } @@ -569,18 +569,18 @@ : public keep_base_2d { /*--------------- "max-cosine" intersection predicate */ - public : + public : typedef R real_type ; typedef I iptr_type ; typedef keep_base_3d < - real_type , + real_type , iptr_type > pred_base ; public : containers:: fixed_array _ppos ; - + containers:: fixed_array _dvec ; @@ -591,7 +591,7 @@ real_type _best ; iptr_type _inum ; - + bool_type _find ; public : @@ -599,20 +599,20 @@ __inline_call keep_minmax_cosine_2d ( __const_ptr ( real_type) _psrc, __const_ptr ( real_type) _vsrc, - real_type const&_cmin = real_type(+.50) - ) + real_type const&_csrc = real_type(+.50) + ) { this->_find = false; this->_inum = +0 ; - + this->_ppos[ 0] = _psrc[ 0]; this->_ppos[ 1] = _psrc[ 1]; - + this->_dvec[ 0] = _vsrc[ 0]; this->_dvec[ 1] = _vsrc[ 1]; - - this->_cmin = _cmin; - this->_best = _cmin; + + this->_cmin = _csrc; + this->_best = _csrc; } /*------------------------------ process intersection */ @@ -631,7 +631,7 @@ _xvec[ 1] = _xpos[ 1] - this->_ppos[ 1]; - real_type _vcos = + real_type _vcos = geometry::cosine_2d ( &this->_dvec[0], _xvec) ; @@ -646,18 +646,18 @@ _proj.pval(0) = _xpos[0]; this-> _proj.pval(1) = _xpos[1]; - + this-> _proj.hits () = _hits; this-> _proj.feat () = _feat; this-> - _proj.topo () = _topo; + _proj.topo () = _topo; this-> _proj.itag () = _itag; - + this->_best = _vcos; - + this->_find = true; } } @@ -671,18 +671,18 @@ : public keep_base_3d { /*--------------- "max-cosine" intersection predicate */ - public : + public : typedef R real_type ; typedef I iptr_type ; typedef keep_base_3d < - real_type , + real_type , iptr_type > pred_base ; public : containers:: fixed_array _ppos ; - + containers:: fixed_array _dvec ; @@ -693,7 +693,7 @@ real_type _best ; iptr_type _inum ; - + bool_type _find ; public : @@ -701,12 +701,12 @@ __inline_call keep_minmax_cosine_3d ( __const_ptr ( real_type) _psrc, __const_ptr ( real_type) _vsrc, - real_type const&_cmin = real_type(+.50) - ) + real_type const&_csrc = real_type(+.50) + ) { this->_find = false; this->_inum = +0 ; - + this->_ppos[ 0] = _psrc[ 0]; this->_ppos[ 1] = _psrc[ 1]; this->_ppos[ 2] = _psrc[ 2]; @@ -714,9 +714,9 @@ this->_dvec[ 0] = _vsrc[ 0]; this->_dvec[ 1] = _vsrc[ 1]; this->_dvec[ 2] = _vsrc[ 2]; - - this->_cmin = _cmin; - this->_best = _cmin; + + this->_cmin = _csrc; + this->_best = _csrc; } /*------------------------------ process intersection */ @@ -737,7 +737,7 @@ _xvec[ 2] = _xpos[ 2] - this->_ppos[ 2]; - real_type _vcos = + real_type _vcos = geometry::cosine_3d ( &this->_dvec[0], _xvec) ; @@ -754,27 +754,27 @@ _proj.pval(1) = _xpos[1]; this-> _proj.pval(2) = _xpos[2]; - + this-> - _proj.hits () = _hits; + _proj.hits () = _hits; this-> _proj.feat () = _feat; this-> - _proj.topo () = _topo; + _proj.topo () = _topo; this-> _proj.itag () = _itag; - + this->_best = _vcos; - + this->_find = true; } } } ; - - + + } # endif //__RDEL_FILT_K__ - - - + + + diff --git a/src/libcpp/rdel_mesh/rdel_make_2.hpp b/src/libcpp/rdel_mesh/rdel_make_2.hpp index 339a25f..5beb08c 100644 --- a/src/libcpp/rdel_mesh/rdel_make_2.hpp +++ b/src/libcpp/rdel_mesh/rdel_make_2.hpp @@ -1,37 +1,37 @@ /* -------------------------------------------------------- - * RDEL-MAKE-2: restricted delaunay tria. in R^2. + * RDEL-MAKE-2: restricted delaunay tria. in R^2. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 24 January, 2019 + * Last updated: 09 August, 2019 * * Copyright 2013-2019 * Darren Engwirda @@ -40,7 +40,7 @@ * -------------------------------------------------------- * - * This class defines the "restricted" delaunay + * This class defines the "restricted" delaunay * tessellation algorithm for domains in R^2. A * bounding DT is built for the points, and the rDT * constructed by evaluating the dual predicate for @@ -49,27 +49,27 @@ * My implementation is described here: * * D. Engwirda, (2014): "Locally-optimal Delaunay- - * refinement and optimisation-based mesh generation", - * Ph.D. Thesis, School of Mathematics and Statistics, - * Univ. of Sydney. + * refinement and optimisation-based mesh generation", + * Ph.D. Thesis, School of Mathematics and Statistics, + * Univ. of Sydney. * http://hdl.handle.net/2123/13148 * - * building on various previous works on rDT methods, + * building on various previous works on rDT methods, * including (primarily): * - * J.D. Boissonnat, S. Oudot, (2005): "Provably Good - * Sampling and Meshing of Surfaces", Graphical Models, + * J.D. Boissonnat, S. Oudot, (2005): "Provably Good + * Sampling and Meshing of Surfaces", Graphical Models, * 67, pp. 405-451, * https://doi.org/10.1016/j.gmod.2005.01.004 * - * C. Jamin, P. Alliez, M. Yvinec, and J.D. Boissonnat, - * (2015): "CGALmesh: a generic framework for Delaunay - * mesh generation", ACM Transactions on Mathematical + * C. Jamin, P. Alliez, M. Yvinec, and J.D. Boissonnat, + * (2015): "CGALmesh: a generic framework for Delaunay + * mesh generation", ACM Transactions on Mathematical * Software (TOMS), 41, pp. 23 * https://doi.org/10.1145/2699463 * - * L. Rineau, M. Yvinec, (2008): "Meshing 3D Domains - * Bounded by Piecewise Smooth Surfaces", Proc. of the + * L. Rineau, M. Yvinec, (2008): "Meshing 3D Domains + * Bounded by Piecewise Smooth Surfaces", Proc. of the * 16th International Meshing Roundtable, pp. 443-460, * https://doi.org/10.1007/978-3-540-75103-8_25 * @@ -82,70 +82,72 @@ # define __RDEL_MAKE_2__ namespace mesh { - + template < typename M , typename G , + typename I , typename A = allocators::basic_alloc > class rdel_make_2d - { - public : - - /*----------- restricted delaunay tessellation in R^2 */ - + { + public : + + /*----------- restricted delaunay tessellation in R^2 */ + typedef M mesh_type ; typedef G geom_type ; + typedef I init_type ; typedef A allocator ; - typedef typename + typedef typename mesh_type::real_type real_type ; - typedef typename + typedef typename mesh_type::iptr_type iptr_type ; - - typedef typename + + typedef typename allocator::size_type uint_type ; - typedef typename + typedef typename mesh_type::node_data node_data ; - typedef typename + typedef typename mesh_type::edge_data edge_data ; - typedef typename + typedef typename mesh_type::tria_data tria_data ; typedef containers::array < iptr_type > iptr_list ; - + typedef mesh::rdel_pred_base_2 < geom_type, mesh_type > rdel_pred ; - typedef mesh::rdel_params < - real_type, + typedef mesh::mesh_params < + real_type, iptr_type > rdel_opts ; typedef mesh::rdel_timers < real_type , iptr_type > rdel_stat ; - + /* -------------------------------------------------------- * PUSH-EDGE: add new edge to restricted-tria. -------------------------------------------------------- */ - + __static_call __normal_call void_type test_edge ( mesh_type &_mesh , geom_type &_geom , iptr_type _tpos , - typename + typename mesh_type::edge_list & _edge_test , iptr_type &_nedg , iptr_type &_ndup , rdel_opts &_opts ) - { + { /*-------------------------------- check "restricted" */ for (auto _fpos =+3; _fpos-- != +0; ) { @@ -154,12 +156,12 @@ 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 || @@ -168,7 +170,7 @@ continue ; algorithms::isort ( - &_tnod[0], &_tnod[2], + &_tnod[0], &_tnod[2], std::less()) ; edge_data _fdat; @@ -179,39 +181,39 @@ edge_list:: item_type *_mptr = nullptr ; if(_edge_test. - find( _fdat, _mptr) ) + find( _fdat, _mptr) ) { /*--------------------------- count bnd. repeats! */ - _ndup += + _ndup += _mptr->_data._dups; - + /*--------------------------- don't test repeats! */ continue ; } _fdat._tadj = _tpos; - _fdat._eadj = + _fdat._eadj = (char_type) _fpos; _fdat._pass = 0 ; _fdat._dups = 0 ; // count num. dup's // only in hash-set - + /*--------------------------- call face predicate */ char_type _feat, _topo; real_type _fbal[ 3]; real_type _sbal[ 3]; - + __unreferenced(_opts); - + bool_type _rBND = rdel_pred::edge_ball ( - _geom,_mesh, + _geom,_mesh, _fdat._tadj, _fdat._eadj, _fbal,_sbal, _feat,_topo, _fdat._part) ; - + /*--------------------------- push edge onto mesh */ if (_rBND) _nedg += +1 ; @@ -226,21 +228,21 @@ } // for (auto _fpos = +3; _fpos-- != +0; ) } - + /* -------------------------------------------------------- * PUSH-TRIA: add new tria to restricted-tria. -------------------------------------------------------- */ - + __static_call __normal_call void_type test_tria ( mesh_type &_mesh , geom_type &_geom , iptr_type _tpos , iptr_type &_sign , - typename - mesh_type::tria_list & _tria_test , + /* typename + mesh_type::tria_list & _tria_test , */ iptr_type &_ntri , rdel_opts &_opts ) @@ -271,15 +273,7 @@ _tdat._tadj = _tpos; - typename mesh_type:: - tria_list:: - item_type *_mptr = nullptr; - if(_tria_test. - find( _tdat, _mptr) ) - { - /*--------------------------- don't test repeats! */ - return ; - } + //!!_tria_test.push (_tdat) ; won't have repeats! /*--------------------------- call tria predicate */ _tdat._part = _sign ; @@ -289,13 +283,13 @@ __unreferenced(_opts); - bool_type _rBND = + bool_type _rBND = rdel_pred::tria_ball ( _geom,_mesh, _tdat._tadj, _tbal, _tdat._part) ; - + _sign = _tdat. _part ; /*--------------------------- push tria onto mesh */ @@ -303,13 +297,10 @@ if (_rBND) _mesh.push_tria(_tdat) ; - - - //!!_tria_test.push(_tdat) ; won't have repeats! - + } } - + /* -------------------------------------------------------- * TRIA-CIRC: calc. circumball for tria. @@ -332,97 +323,92 @@ } ; algorithms::isort( - &_tnod[0], &_tnod[3], + &_tnod[0], &_tnod[3], std::less()) ; - + /*---------------------- calc. ball in floating-point */ real_type _tbal[3] ; geometry::circ_ball_2d ( - _tbal , + _tbal , &_mesh._tria. - node(_tnod[0])->pval(0) , + node(_tnod[0])->pval(0) , &_mesh._tria. node(_tnod[1])->pval(0) , &_mesh._tria. node(_tnod[2])->pval(0) ) ; - + _mesh._tria.tria( _tpos)->circ(0) = _tbal[0] ; _mesh._tria.tria( _tpos)->circ(1) = _tbal[1] ; - } - + } + /* -------------------------------------------------------- - * INIT-MESH: init. the bounding DT. + * INIT-MESH: init. the bounding DT. -------------------------------------------------------- */ - template < - typename init_type - > __static_call __normal_call void_type init_sort ( init_type &_init, iptr_list &_iset ) { - typedef geom_tree::aabb_node_base_k + typedef geom_tree::aabb_node_base_k tree_node ; typedef geom_tree:: aabb_item_node_k < real_type, iptr_type, 2> tree_item ; - + typedef geom_tree::aabb_tree < tree_item, 2, tree_node, allocator > tree_type ; - + containers::array _bbox; - - /*------------------------------ initialise aabb-tree */ + + /*------------------------------ initialise aabb-tree */ iptr_type _npos = 0 ; tree_type _tree ; - for (auto _node = - _init._mesh._set1.head() ; - _node != + for (auto _node = + _init._mesh._set1.head() ; + _node != _init._mesh._set1.tend() ; ++_node, ++_npos) { if (_node->mark() >= +0) { - + _bbox.push_tail() ; _bbox.tail()-> pval(0) = _node->pval(0) ; _bbox.tail()-> pval(1) = _node->pval(1) ; - + _bbox.tail()-> ipos () = _npos ; - + } } - - iptr_type _NBOX = + + iptr_type _NBOX = (iptr_type) std::pow (8, 2) ; // 8^ndim - + _tree.load(_bbox.head(), _bbox.tend(), _NBOX) ; - - /*------------------------------ randomised tree sort */ + + /*------------------------------ randomised tree sort */ _tree.brio(_iset) ; } - template < - typename init_type - > __static_call __normal_call void_type init_init ( init_type &_init, + geom_type &_geom, mesh_type &_mesh ) { @@ -430,115 +416,125 @@ iptr_type _hint = -1 ; iptr_list _iset ; init_sort(_init, _iset) ; - + /*------------------------------ find "central" point */ iptr_type _imid = -1 ; - real_type _dmin = + real_type _dmin = std::numeric_limits ::infinity(); - + real_type _pmid[2] ; _pmid[0] = (real_type) +0. ; _pmid[1] = (real_type) +0. ; - + for (auto _iter = _iset.head(); _iter != _iset.tend(); ++_iter ) { - auto _node = + auto _node = &_init._mesh._set1 [*_iter] ; - - _pmid[0] += + + _pmid[0] += _node->pval(0); - _pmid[1] += + _pmid[1] += _node->pval(1); } - + _pmid[0] /= _iset.count () ; _pmid[1] /= _iset.count () ; - + for (auto _iter = _iset.head(); _iter != _iset.tend(); ++_iter ) { - auto _node = + auto _node = &_init._mesh._set1 [*_iter] ; - - real_type _dsqr = + + real_type _dsqr = geometry::lensqr_2d( &_node->pval(0), _pmid) ; - + if (_dsqr < _dmin) { _dmin = _dsqr ; + _imid =*_iter ; } } - + /*------------------------------ seed mesh from init. */ if (_imid > -1) { - auto _node = + auto _node = &_init._mesh._set1 [ _imid] ; - + + if (_node->itag () >= +0 ) + _geom.projector( + &_node->pval(0) , + _node->itag () , + &_node->pval(0) ) ; + iptr_type _npos = -1 ; if (_mesh._tria.push_node( - &_node->pval(0) , + &_node->pval(0) , _npos, _hint ) ) { - + _mesh._tria.node (_npos)->fdim() = 0 ; - + _mesh._tria.node - (_npos)->feat() + (_npos)->feat() = _node->feat() ; - + _mesh._tria.node - (_npos)->topo() = 2 ; - + (_npos)->topo() = 2 ; + _hint = _mesh._tria. node(_npos)->next() ; - + } } - + /*------------------------------ seed mesh from init. */ for (auto _iter = _iset.head(); _iter != _iset.tend(); ++_iter ) { if (*_iter == _imid) continue; - - auto _node = + + auto _node = &_init._mesh._set1 [*_iter] ; - + + if (_node->itag () >= +0 ) + _geom.projector( + &_node->pval(0) , + _node->itag () , + &_node->pval(0) ) ; + iptr_type _npos = -1 ; if (_mesh._tria.push_node( - &_node->pval(0) , + &_node->pval(0) , _npos, _hint ) ) { - + _mesh._tria.node (_npos)->fdim() = 0 ; - + _mesh._tria.node - (_npos)->feat() + (_npos)->feat() = _node->feat() ; - + _mesh._tria.node - (_npos)->topo() = 2 ; - + (_npos)->topo() = 2 ; + _hint = _mesh._tria. node(_npos)->next() ; - + } } } - template < - typename init_type - > __static_call __normal_call void_type init_mesh ( geom_type &_geom, @@ -556,10 +552,10 @@ _pmin[ 1] = _geom._bmin[ 1] ; _pmax[ 0] = _geom._bmax[ 0] ; _pmax[ 1] = _geom._bmax[ 1] ; - - for (auto _node = - _init._mesh._set1.head(); - _node != + + for (auto _node = + _init._mesh._set1.head(); + _node != _init._mesh._set1.tend(); ++_node ) { @@ -569,26 +565,26 @@ _pmin[ 0], _node->pval(0)) ; _pmax[ 0] = std::max( _pmax[ 0], _node->pval(0)) ; - + _pmin[ 1] = std::min( _pmin[ 1], _node->pval(1)) ; _pmax[ 1] = std::max( - _pmax[ 1], _node->pval(1)) ; + _pmax[ 1], _node->pval(1)) ; } } - + real_type _plen[ 2] = { _pmax[ 0] - _pmin[ 0] , _pmax[ 1] - _pmin[ 1] , - } ; + } ; _plen[ 0]*= (real_type)+2.0 ; _plen[ 1]*= (real_type)+2.0 ; - + _pmin[ 0]-= _plen[ 0] ; _pmin[ 1]-= _plen[ 1] ; _pmax[ 0]+= _plen[ 0] ; _pmax[ 1]+= _plen[ 1] ; - + _mesh. _tria.push_root(_pmin, _pmax) ; @@ -599,14 +595,14 @@ _tria.node(+1)->fdim() = +3 ; _mesh. _tria.node(+2)->fdim() = +3 ; - + _mesh. _tria.node(+0)->feat() = +0 ; _mesh. _tria.node(+1)->feat() = +0 ; _mesh. _tria.node(+2)->feat() = +0 ; - + _mesh. _tria.node(+0)->topo() = +0 ; _mesh. @@ -615,17 +611,16 @@ _tria.node(+2)->topo() = +0 ; /*------------------------------ seed mesh from init. */ - init_init(_init, _mesh); + init_init(_init, _geom, _mesh); } - + /* -------------------------------------------------------- - * RDEL-MAKE: build an rDT in R^2 . + * RDEL-MAKE: build an rDT in R^2 . -------------------------------------------------------- */ template < - typename init_type , typename jlog_file > __static_call @@ -636,8 +631,8 @@ rdel_opts &_args , jlog_file &_dump ) - { - /*------------------------------ ensure deterministic */ + { + /*------------------------------ ensure deterministic */ std::srand( +1 ) ; rdel_stat _tcpu ; @@ -664,40 +659,27 @@ _geom , _init, _mesh, _args) ; # ifdef __use_timers - _ttoc = _time.now() ; - _tcpu._mesh_seed += + _ttoc = _time.now() ; + _tcpu._mesh_seed += _tcpu.time_span(_ttic,_ttoc) ; # endif//__use_timers - + iptr_type _nedg = +0 ; iptr_type _ntri = +0 ; - + iptr_type _ndup = +0 ; - - /*------------------------- init. for local hash obj. */ - typename - mesh_type::edge_list _eset ( - typename mesh_type::edge_hash(), - typename mesh_type::edge_pred(), - +.8, _mesh._eset.get_alloc()) ; - - typename - mesh_type::tria_list _tset ( - typename mesh_type::tria_hash(), - typename mesh_type::tria_pred(), - +.8, _mesh._tset.get_alloc()) ; /*------------------------- DT cells to check for rDT */ iptr_list _tnew ; _tnew.set_alloc ( _mesh._tria._tset.count()) ; - + iptr_type _tpos = +0 ; - - for (auto _iter = - _mesh._tria._tset.head() ; - _iter != - _mesh._tria._tset.tend() ; + + for (auto _iter = + _mesh._tria._tset.head() ; + _iter != + _mesh._tria._tset.tend() ; ++_iter, ++_tpos) { if (_iter->mark() >= +0) @@ -705,141 +687,205 @@ _tnew. push_tail( _tpos) ; } } - + /*------------------------- calc. voronoi-dual points */ - for( auto _iter = _tnew.head(); - _iter != _tnew.tend(); + for( auto _iter = _tnew.head(); + _iter != _tnew.tend(); ++_iter ) { tria_circ(_mesh,*_iter) ; } - + /*------------------------- test for restricted edges */ if (_args.dims() >= 1 && _geom.have_feat(1) ) - { + { - _eset._lptr.set_count ( - _tnew.count()*3 , - containers::loose_alloc,nullptr) ; + 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(); + for( auto _iter = _tnew.head(); + _iter != _tnew.tend(); ++_iter ) - { + { test_edge(_mesh, _geom, - *_iter, - _eset, - _nedg, _ndup, + *_iter, + _eset, + _nedg, _ndup, _args) ; } # ifdef __use_timers - _ttoc = _time.now() ; - _tcpu._edge_init += + _ttoc = _time.now() ; + _tcpu._edge_init += _tcpu.time_span(_ttic,_ttoc) ; # endif//__use_timers } - - /*------------------------- test for restricted tria. */ + + /*------------------------- test for restricted tria. */ 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 ; - - _tset._lptr.set_count ( - _tnew.count()*1 , - containers::loose_alloc,nullptr) ; - + + //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(); + for( auto _iter = _tnew.head(); + _iter != _tnew.tend(); ++_iter ) { _sign = _safe ? _sign : -1 ; test_tria(_mesh, _geom, - *_iter, - _sign, - _tset, _ntri, + *_iter, + _sign, _ntri, _args) ; } # ifdef __use_timers - _ttoc = _time.now() ; - _tcpu._tria_init += + _ttoc = _time.now() ; + _tcpu._tria_init += _tcpu.time_span(_ttic,_ttoc) ; # endif//__use_timers } - - /* - if (_args.verb() >= +2 ) - { - //------------------------- push rDEL memory metrics * - - _dump.push("\n") ; - _dump.push(" rDT statistics... \n") ; - _dump.push("\n") ; - - } - */ - + if (_args.verb() >= +2 ) { /*------------------------- push rDEL scheme metrics */ - + _dump.push("\n") ; - _dump.push(" rDT statistics... \n") ; + _dump.push("**DELTRI statistics... \n") ; + _dump.push("\n") ; + + _dump.push("**FUNCTION timing: ") ; _dump.push("\n") ; _dump.push(" MESH-SEED = ") ; _dump.push( - std::to_string (_tcpu._mesh_seed)) ; + std::to_string (_tcpu._mesh_seed)); _dump.push("\n") ; _dump.push(" EDGE-INIT = ") ; _dump.push( - std::to_string (_tcpu._edge_init)) ; + std::to_string (_tcpu._edge_init)); _dump.push("\n") ; _dump.push(" TRIA-INIT = ") ; _dump.push( - std::to_string (_tcpu._tria_init)) ; + std::to_string (_tcpu._tria_init)); _dump.push("\n") ; _dump.push("\n") ; - - _dump.push(" |rDEL-1| (edge) = ") ; - _dump.push(std::to_string (_nedg)) ; + + _dump.push("**RESTRICTED-TRIA: ") ; _dump.push("\n") ; - - _dump.push(" |rDEL-2| (tria) = ") ; - _dump.push(std::to_string (_ntri)) ; + + _dump.push(" rDEL-EDGE = "); + _dump.push(std::to_string (_nedg)); _dump.push("\n") ; + + _dump.push(" rDEL-TRIA = "); + _dump.push(std::to_string (_ntri)); _dump.push("\n") ; - + _dump.push("\n") ; + } - + + if (_args.verb() >= +3 ) + { + /*------------------------- push rDEL memory metrics */ + + _dump.push("\n") ; + _dump.push("**MEMORY statistics... \n") ; + _dump.push("\n") ; + + _dump.push("**DELAUNAY-OBJECT: ") ; + _dump.push("\n") ; + + _dump.push(" NODE-BYTE = ") ; + _dump.push(std::to_string( + sizeof(typename mesh_type:: + tria_type:: node_type)) ) ; + _dump.push("\n") ; + _dump.push(" NODE-LIST = ") ; + _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("\n") ; + _dump.push(" TRIA-LIST = ") ; + _dump.push(std::to_string( + _mesh._tria._tset.alloc())) ; + _dump.push("\n") ; + _dump.push("\n") ; + + _dump.push("**RESTRICTED-TRIA: ") ; + _dump.push("\n") ; + + _dump.push(" EDGE-BYTE = ") ; + _dump.push(std::to_string( + sizeof( + typename mesh_type::edge_item)) ) ; + _dump.push("\n") ; + _dump.push(" EDGE-HASH = ") ; + _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("\n") ; + + _dump.push(" TRIA-BYTE = ") ; + _dump.push(std::to_string( + sizeof( + typename mesh_type::tria_item)) ) ; _dump.push("\n") ; + _dump.push(" TRIA-HASH = ") ; + _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("\n") ; + _dump.push("\n") ; + + } + } - + } ; - - + + } - -# endif //__RDEL_MAKE_2__ - - - + +# endif //__RDEL_MAKE_2__ + + + diff --git a/src/libcpp/rdel_mesh/rdel_make_3.hpp b/src/libcpp/rdel_mesh/rdel_make_3.hpp index 174ef3f..28cff4c 100644 --- a/src/libcpp/rdel_mesh/rdel_make_3.hpp +++ b/src/libcpp/rdel_mesh/rdel_make_3.hpp @@ -1,37 +1,37 @@ - + /* -------------------------------------------------------- - * RDEL-MAKE-3: restricted delaunay tria. in R^3. + * RDEL-MAKE-3: restricted delaunay tria. in R^3. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 24 January, 2019 + * Last updated: 06 July, 2019 * * Copyright 2013-2019 * Darren Engwirda @@ -40,7 +40,7 @@ * -------------------------------------------------------- * - * This class defines the "restricted" delaunay + * This class defines the "restricted" delaunay * tessellation algorithm for domains in R^3. A * bounding DT is built for the points, and the rDT * constructed by evaluating the dual predicate for @@ -49,27 +49,27 @@ * My implementation is described here: * * D. Engwirda, (2014): "Locally-optimal Delaunay- - * refinement and optimisation-based mesh generation", - * Ph.D. Thesis, School of Mathematics and Statistics, - * Univ. of Sydney. + * refinement and optimisation-based mesh generation", + * Ph.D. Thesis, School of Mathematics and Statistics, + * Univ. of Sydney. * http://hdl.handle.net/2123/13148 * - * building on various previous works on rDT methods, + * building on various previous works on rDT methods, * including (primarily): * - * J.D. Boissonnat, S. Oudot, (2005): "Provably Good - * Sampling and Meshing of Surfaces", Graphical Models, + * J.D. Boissonnat, S. Oudot, (2005): "Provably Good + * Sampling and Meshing of Surfaces", Graphical Models, * 67, pp. 405-451, * https://doi.org/10.1016/j.gmod.2005.01.004 * - * C. Jamin, P. Alliez, M. Yvinec, and J.D. Boissonnat, - * (2015): "CGALmesh: a generic framework for Delaunay - * mesh generation", ACM Transactions on Mathematical + * C. Jamin, P. Alliez, M. Yvinec, and J.D. Boissonnat, + * (2015): "CGALmesh: a generic framework for Delaunay + * mesh generation", ACM Transactions on Mathematical * Software (TOMS), 41, pp. 23 * https://doi.org/10.1145/2699463 * - * L. Rineau, M. Yvinec, (2008): "Meshing 3D Domains - * Bounded by Piecewise Smooth Surfaces", Proc. of the + * L. Rineau, M. Yvinec, (2008): "Meshing 3D Domains + * Bounded by Piecewise Smooth Surfaces", Proc. of the * 16th International Meshing Roundtable, pp. 443-460, * https://doi.org/10.1007/978-3-540-75103-8_25 * @@ -82,66 +82,68 @@ # define __RDEL_MAKE_3__ namespace mesh { - + template < typename M , typename G , + typename I , typename A = allocators::basic_alloc > class rdel_make_3d - { - public : - - /*----------- restricted delaunay tessellation in R^3 */ - + { + public : + + /*----------- restricted delaunay tessellation in R^3 */ + typedef M mesh_type ; typedef G geom_type ; + typedef I init_type ; typedef A allocator ; - typedef typename + typedef typename mesh_type::real_type real_type ; - typedef typename + typedef typename mesh_type::iptr_type iptr_type ; - - typedef typename + + typedef typename allocator::size_type uint_type ; - typedef typename + typedef typename mesh_type::node_data node_data ; - typedef typename + typedef typename mesh_type::edge_data edge_data ; - typedef typename + typedef typename mesh_type::face_data face_data ; - typedef typename + typedef typename mesh_type::tria_data tria_data ; typedef containers::array < iptr_type > iptr_list ; - + typedef mesh::rdel_pred_base_3 < geom_type, mesh_type > rdel_pred ; - typedef mesh::rdel_params < - real_type, + typedef mesh::mesh_params < + real_type, iptr_type > rdel_opts ; typedef mesh::rdel_timers < real_type , iptr_type > rdel_stat ; - + /* -------------------------------------------------------- * PUSH-EDGE: add new edge to restricted-tria. -------------------------------------------------------- */ - + __static_call __normal_call void_type test_edge ( mesh_type &_mesh , geom_type &_geom , iptr_type _tpos , - typename + typename mesh_type::edge_list & _edge_test , iptr_type &_nedg , rdel_opts &_opts @@ -154,7 +156,7 @@ iptr_type _tnod[ +4] ; mesh_type::tria_type:: tria_type:: - face_node(_tnod, _fpos, +3, +1) ; + face_node(_tnod, _fpos, +3, +1) ; _tnod[0] = _mesh._tria. tria(_tpos)->node(_tnod[0]); _tnod[1] = _mesh._tria. @@ -166,9 +168,9 @@ _mesh._tria.node( _tnod[1])->fdim() > 1 ) continue ; - + algorithms::isort ( - &_tnod[0], &_tnod[2], + &_tnod[0], &_tnod[2], std::less()) ; edge_data _edat; @@ -179,27 +181,27 @@ edge_list:: item_type *_mptr = nullptr ; if(_edge_test. - find( _edat, _mptr) ) + find( _edat, _mptr) ) { /*--------------------------- don't test repeats! */ continue ; } _edat._tadj = _tpos; - _edat._eadj = + _edat._eadj = (char_type) _fpos; _edat._pass = +0 ; - + /*--------------------------- call edge predicate */ char_type _hits; real_type _fbal[ 4]; real_type _sbal[ 4]; - + __unreferenced(_opts); - + bool_type _rBND = rdel_pred::edge_ball ( - _geom,_mesh, + _geom,_mesh, _edat._tadj, _edat._eadj, _fbal,_sbal, @@ -207,31 +209,31 @@ _edat._feat, _edat._topo, _edat._part) ; - + /*--------------------------- push edge onto mesh */ if (_rBND) _nedg += +1 ; if (_rBND) _mesh.push_edge(_edat) ; - - + + _edge_test.push(_edat) ; - } // for (auto _fpos = +6; _fpos-- != +0; ) + } // for (auto _fpos = +6; _fpos-- != +0; ) } - + /* -------------------------------------------------------- * PUSH-FACE: add new face to restricted-tria. -------------------------------------------------------- */ - + __static_call __normal_call void_type test_face ( mesh_type &_mesh , geom_type &_geom , iptr_type _tpos , - typename + typename mesh_type::face_list & _face_test , iptr_type &_nfac , iptr_type &_ndup , @@ -263,7 +265,7 @@ continue ; algorithms::isort ( - &_tnod[0], &_tnod[3], + &_tnod[0], &_tnod[3], std::less()) ; face_data _fdat; @@ -275,39 +277,39 @@ face_list:: item_type *_mptr = nullptr ; if(_face_test. - find( _fdat, _mptr) ) + find( _fdat, _mptr) ) { /*--------------------------- count bnd. repeats! */ - _ndup += + _ndup += _mptr->_data._dups; - + /*--------------------------- don't test repeats! */ continue ; } _fdat._tadj = _tpos; - _fdat._fadj = + _fdat._fadj = (char_type) _fpos; _fdat._pass = 0 ; _fdat._dups = 0 ; // count num. dup's // only in hash-set - + /*--------------------------- call face predicate */ char_type _feat, _topo; real_type _fbal[ 4]; real_type _sbal[ 4]; - + __unreferenced(_opts); - + bool_type _rBND = rdel_pred::face_ball ( - _geom,_mesh, + _geom,_mesh, _fdat._tadj, _fdat._fadj, _fbal,_sbal, _feat,_topo, _fdat._part) ; - + /*--------------------------- push face onto mesh */ if (_rBND) _nfac += +1 ; @@ -322,21 +324,21 @@ } // for (auto _fpos = +4; _fpos-- != +0; ) } - + /* -------------------------------------------------------- * PUSH-TRIA: add new tria to restricted-tria. -------------------------------------------------------- */ - + __static_call __normal_call void_type test_tria ( mesh_type &_mesh , geom_type &_geom , iptr_type _tpos , iptr_type &_sign , - typename - mesh_type::tria_list & _tria_test , + /* typename + mesh_type::tria_list & _tria_test , */ iptr_type &_ntri , rdel_opts &_opts ) @@ -372,15 +374,8 @@ _tdat._tadj = _tpos; - typename mesh_type:: - tria_list:: - item_type *_mptr = nullptr; - if(_tria_test. - find( _tdat, _mptr) ) - { - /*--------------------------- don't test repeats! */ - return ; - } + + //!!_tria_test.push (_tdat) ; won't have repeats! /*--------------------------- call tria predicate */ _tdat._part = _sign ; @@ -390,7 +385,7 @@ __unreferenced(_opts); - bool_type _rBND = + bool_type _rBND = rdel_pred::tria_ball ( _geom,_mesh, _tdat._tadj, @@ -404,13 +399,10 @@ if (_rBND) _mesh.push_tria(_tdat) ; - - - //!!_tria_test.push(_tdat) ; won't have repeats! - + } } - + /* -------------------------------------------------------- * TRIA-CIRC: calc. circumball for tria. @@ -435,15 +427,15 @@ } ; algorithms::isort( - &_tnod[0], &_tnod[4], + &_tnod[0], &_tnod[4], std::less()) ; - + /*---------------------- calc. ball in floating-point */ real_type _tbal[4] ; geometry::circ_ball_3d ( - _tbal , + _tbal , &_mesh._tria. - node(_tnod[0])->pval(0) , + node(_tnod[0])->pval(0) , &_mesh._tria. node(_tnod[1])->pval(0) , &_mesh._tria. @@ -451,7 +443,7 @@ &_mesh._tria. node(_tnod[3])->pval(0) ) ; - + _mesh._tria.tria( _tpos)->circ(0) = _tbal[0] ; _mesh._tria.tria( @@ -459,49 +451,46 @@ _mesh._tria.tria( _tpos)->circ(2) = _tbal[2] ; } - + /* -------------------------------------------------------- - * INIT-MESH: init. the bounding DT. + * INIT-MESH: init. the bounding DT. -------------------------------------------------------- */ - template < - typename init_type - > __static_call __normal_call void_type init_sort ( init_type &_init, iptr_list &_iset ) { - typedef geom_tree::aabb_node_base_k + typedef geom_tree::aabb_node_base_k tree_node ; typedef geom_tree:: aabb_item_node_k < real_type, iptr_type, 3> tree_item ; - + typedef geom_tree::aabb_tree < tree_item, 3, tree_node, allocator > tree_type ; - + containers::array _bbox; - - /*------------------------------ initialise aabb-tree */ + + /*------------------------------ initialise aabb-tree */ iptr_type _npos = 0 ; tree_type _tree ; - for (auto _node = - _init._mesh._set1.head() ; - _node != + for (auto _node = + _init._mesh._set1.head() ; + _node != _init._mesh._set1.tend() ; ++_node, ++_npos) { if (_node->mark() >= +0) { - + _bbox.push_tail() ; _bbox.tail()-> pval(0) = _node->pval(0) ; @@ -509,29 +498,27 @@ pval(1) = _node->pval(1) ; _bbox.tail()-> pval(2) = _node->pval(2) ; - + _bbox.tail()-> ipos () = _npos ; - + } } - - iptr_type _NBOX = + + iptr_type _NBOX = (iptr_type) std::pow (8, 3) ; // 8^ndim - + _tree.load(_bbox.head(), _bbox.tend(), _NBOX) ; - - /*------------------------------ randomised tree sort */ + + /*------------------------------ randomised tree sort */ _tree.brio(_iset) ; } - template < - typename init_type - > __static_call __normal_call void_type init_init ( init_type &_init, + geom_type &_geom, mesh_type &_mesh ) { @@ -539,119 +526,129 @@ iptr_type _hint = -1 ; iptr_list _iset ; init_sort(_init, _iset) ; - + /*------------------------------ find "central" point */ iptr_type _imid = -1 ; - real_type _dmin = + real_type _dmin = std::numeric_limits ::infinity(); - + real_type _pmid[3] ; _pmid[0] = (real_type) +0. ; _pmid[1] = (real_type) +0. ; _pmid[2] = (real_type) +0. ; - + for (auto _iter = _iset.head(); _iter != _iset.tend(); ++_iter ) { - auto _node = + auto _node = &_init._mesh._set1 [*_iter] ; - - _pmid[0] += + + _pmid[0] += _node->pval(0); - _pmid[1] += + _pmid[1] += _node->pval(1); - _pmid[2] += + _pmid[2] += _node->pval(2); } - + _pmid[0] /= _iset.count () ; _pmid[1] /= _iset.count () ; _pmid[2] /= _iset.count () ; - + for (auto _iter = _iset.head(); _iter != _iset.tend(); ++_iter ) { - auto _node = + auto _node = &_init._mesh._set1 [*_iter] ; - - real_type _dsqr = + + real_type _dsqr = geometry::lensqr_3d( &_node->pval(0), _pmid) ; - + if (_dsqr < _dmin) { _dmin = _dsqr ; + _imid =*_iter ; } } - + /*------------------------------ seed mesh from init. */ if (_imid > -1) { - auto _node = + auto _node = &_init._mesh._set1 [ _imid] ; - + + if (_node->itag () >= +0 ) + _geom.projector( + &_node->pval(0) , + _node->itag () , + &_node->pval(0) ) ; + iptr_type _npos = -1 ; if (_mesh._tria.push_node( - &_node->pval(0) , + &_node->pval(0) , _npos, _hint ) ) { - + _mesh._tria.node (_npos)->fdim() = 0 ; - + _mesh._tria.node - (_npos)->feat() + (_npos)->feat() = _node->feat() ; - + _mesh._tria.node - (_npos)->topo() = 2 ; - + (_npos)->topo() = 2 ; + _hint = _mesh._tria. node(_npos)->next() ; - + } } - + /*------------------------------ seed mesh from init. */ for (auto _iter = _iset.head(); _iter != _iset.tend(); ++_iter ) { - if (*_iter == _imid) continue; - - auto _node = + if (*_iter == _imid) continue ; + + auto _node = &_init._mesh._set1 [*_iter] ; - + + if (_node->itag () >= +0 ) + _geom.projector( + &_node->pval(0) , + _node->itag () , + &_node->pval(0) ) ; + iptr_type _npos = -1 ; if (_mesh._tria.push_node( - &_node->pval(0) , + &_node->pval(0) , _npos, _hint ) ) { - + _mesh._tria.node (_npos)->fdim() = 0 ; - + _mesh._tria.node - (_npos)->feat() + (_npos)->feat() = _node->feat() ; - + _mesh._tria.node - (_npos)->topo() = 2 ; - + (_npos)->topo() = 2 ; + _hint = _mesh._tria. node(_npos)->next() ; - + } } } - template < - typename init_type - > __static_call __normal_call void_type init_mesh ( geom_type &_geom, @@ -671,10 +668,10 @@ _pmax[ 0] = _geom._bmax[ 0] ; _pmax[ 1] = _geom._bmax[ 1] ; _pmax[ 2] = _geom._bmax[ 2] ; - - for (auto _node = - _init._mesh._set1.head(); - _node != + + for (auto _node = + _init._mesh._set1.head(); + _node != _init._mesh._set1.tend(); ++_node ) { @@ -684,28 +681,28 @@ _pmin[ 0], _node->pval(0)) ; _pmax[ 0] = std::max( _pmax[ 0], _node->pval(0)) ; - + _pmin[ 1] = std::min( _pmin[ 1], _node->pval(1)) ; _pmax[ 1] = std::max( _pmax[ 1], _node->pval(1)) ; - + _pmin[ 2] = std::min( _pmin[ 2], _node->pval(2)) ; _pmax[ 2] = std::max( - _pmax[ 2], _node->pval(2)) ; + _pmax[ 2], _node->pval(2)) ; } } - + real_type _plen[ 3] = { _pmax[ 0] - _pmin[ 0] , _pmax[ 1] - _pmin[ 1] , _pmax[ 2] - _pmin[ 2] , - } ; + } ; _plen[ 0]*= (real_type)+2.0 ; _plen[ 1]*= (real_type)+2.0 ; _plen[ 2]*= (real_type)+2.0 ; - + _pmin[ 0]-= _plen[ 0] ; _pmin[ 1]-= _plen[ 1] ; _pmin[ 2]-= _plen[ 2] ; @@ -725,7 +722,7 @@ _tria.node(+2)->fdim() = +4 ; _mesh. _tria.node(+3)->fdim() = +4 ; - + _mesh. _tria.node(+0)->feat() = +0 ; _mesh. @@ -734,7 +731,7 @@ _tria.node(+2)->feat() = +0 ; _mesh. _tria.node(+3)->feat() = +0 ; - + _mesh. _tria.node(+0)->topo() = +0 ; _mesh. @@ -743,19 +740,18 @@ _tria.node(+2)->topo() = +0 ; _mesh. _tria.node(+3)->topo() = +0 ; - + /*------------------------------ seed mesh from init. */ - init_init(_init, _mesh); + init_init(_init, _geom, _mesh); } - + /* -------------------------------------------------------- - * RDEL-MAKE: build an rDT in R^3 . + * RDEL-MAKE: build an rDT in R^3 . -------------------------------------------------------- */ template < - typename init_type , typename jlog_file > __static_call @@ -766,8 +762,8 @@ rdel_opts &_args , jlog_file &_dump ) - { - /*------------------------------ ensure deterministic */ + { + /*------------------------------ ensure deterministic */ std::srand( +1 ) ; rdel_stat _tcpu ; @@ -794,47 +790,28 @@ _geom , _init, _mesh, _args) ; # ifdef __use_timers - _ttoc = _time.now() ; - _tcpu._mesh_seed += + _ttoc = _time.now() ; + _tcpu._mesh_seed += _tcpu.time_span(_ttic,_ttoc) ; # endif//__use_timers - + iptr_type _nedg = +0 ; iptr_type _nfac = +0 ; iptr_type _ntri = +0 ; - + iptr_type _ndup = +0 ; - - /*------------------------- init. for local hash obj. */ - typename - mesh_type::edge_list _eset ( - typename mesh_type::edge_hash(), - typename mesh_type::edge_pred(), - +.8, _mesh._eset.get_alloc()) ; - - typename - mesh_type::face_list _fset ( - typename mesh_type::face_hash(), - typename mesh_type::face_pred(), - +.8, _mesh._fset.get_alloc()) ; - - typename - mesh_type::tria_list _tset ( - typename mesh_type::tria_hash(), - typename mesh_type::tria_pred(), - +.8, _mesh._tset.get_alloc()) ; /*------------------------- DT cells to check for rDT */ iptr_list _tnew ; _tnew.set_alloc ( _mesh._tria._tset.count()) ; - + iptr_type _tpos = +0 ; - - for (auto _iter = - _mesh._tria._tset.head() ; - _iter != - _mesh._tria._tset.tend() ; + + for (auto _iter = + _mesh._tria._tset.head() ; + _iter != + _mesh._tria._tset.tend() ; ++_iter, ++_tpos) { if (_iter->mark() >= +0) @@ -842,184 +819,265 @@ _tnew. push_tail( _tpos) ; } } - + if (_geom.have_feat(1) || _geom.have_feat(2) ) - { + { /*------------------------- calc. voronoi-dual points */ - for( auto _iter = _tnew.head(); - _iter != _tnew.tend(); + for( auto _iter = _tnew.head(); + _iter != _tnew.tend(); ++_iter ) { tria_circ(_mesh,*_iter) ; } } - + /*------------------------- test for restricted edges */ if (_args.dims() >= 1 && _geom.have_feat(1) ) { - _eset._lptr.set_count ( - _tnew.count()*6 , - containers::loose_alloc,nullptr) ; + 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(); + + for( auto _iter = _tnew.head(); + _iter != _tnew.tend(); ++_iter ) - { + { test_edge(_mesh, _geom, - *_iter, - _eset, _nedg, + *_iter, + _eset, _nedg, _args) ; } # ifdef __use_timers - _ttoc = _time.now() ; - _tcpu._edge_init += + _ttoc = _time.now() ; + _tcpu._edge_init += _tcpu.time_span(_ttic,_ttoc) ; # endif//__use_timers } - + /*------------------------- test for restricted edges */ if (_args.dims() >= 2 && _geom.have_feat(2) ) - { + { - _fset._lptr.set_count ( - _tnew.count()*4 , - containers::loose_alloc,nullptr) ; + 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(); + for( auto _iter = _tnew.head(); + _iter != _tnew.tend(); ++_iter ) - { + { test_face(_mesh, _geom, - *_iter, - _fset, - _nfac, _ndup, + *_iter, + _fset, + _nfac, _ndup, _args) ; } # ifdef __use_timers - _ttoc = _time.now() ; - _tcpu._face_init += + _ttoc = _time.now() ; + _tcpu._face_init += _tcpu.time_span(_ttic,_ttoc) ; # endif//__use_timers } - - /*------------------------- test for restricted tria. */ + + /*------------------------- test for restricted tria. */ if (_args.dims() >= 3 && _geom.have_feat(2) ) - { + { bool_type _safe = true ; iptr_type _sign = -1 ; - - //if (_nedg >= +1) _safe = false ; + + //if (_nfac >= +1) _safe = false ; if (_ndup >= +1) _safe = false ; - - _tset._lptr.set_count ( - _tnew.count()*1 , - containers::loose_alloc,nullptr) ; - + + //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(); + for( auto _iter = _tnew.head(); + _iter != _tnew.tend(); ++_iter ) { _sign = _safe ? _sign : -1 ; test_tria(_mesh, _geom, - *_iter, - _sign, - _tset, _ntri, + *_iter, + _sign, _ntri, _args) ; } # ifdef __use_timers - _ttoc = _time.now() ; - _tcpu._tria_init += + _ttoc = _time.now() ; + _tcpu._tria_init += _tcpu.time_span(_ttic,_ttoc) ; # endif//__use_timers } - - /* - if (_args.verb() >= +2 ) - { - //------------------------- push rDEL memory metrics * - - _dump.push("\n") ; - _dump.push(" rDT statistics... \n") ; - _dump.push("\n") ; - - } - */ - + if (_args.verb() >= +2 ) { /*------------------------- push rDEL scheme metrics */ - + _dump.push("\n") ; - _dump.push(" rDT statistics... \n") ; + _dump.push("**DELTRI statistics... \n") ; + _dump.push("\n") ; + + _dump.push("**FUNCTION timing: ") ; _dump.push("\n") ; _dump.push(" MESH-SEED = ") ; _dump.push( - std::to_string (_tcpu._mesh_seed)) ; + std::to_string (_tcpu._mesh_seed)); _dump.push("\n") ; _dump.push(" EDGE-INIT = ") ; _dump.push( - std::to_string (_tcpu._edge_init)) ; + std::to_string (_tcpu._edge_init)); _dump.push("\n") ; _dump.push(" FACE-INIT = ") ; _dump.push( - std::to_string (_tcpu._face_init)) ; + std::to_string (_tcpu._face_init)); _dump.push("\n") ; _dump.push(" TRIA-INIT = ") ; _dump.push( - std::to_string (_tcpu._tria_init)) ; + std::to_string (_tcpu._tria_init)); _dump.push("\n") ; _dump.push("\n") ; - _dump.push(" |rDEL-1| (edge) = ") ; - _dump.push(std::to_string (_nedg)) ; + _dump.push("**RESTRICTED-TRIA: ") ; _dump.push("\n") ; - - _dump.push(" |rDEL-2| (face) = ") ; - _dump.push(std::to_string (_nfac)) ; + + _dump.push(" rDEL-EDGE = "); + _dump.push(std::to_string (_nedg)); _dump.push("\n") ; - - _dump.push(" |rDEL-3| (tria) = ") ; - _dump.push(std::to_string (_ntri)) ; + + _dump.push(" rDEL-FACE = "); + _dump.push(std::to_string (_nfac)); _dump.push("\n") ; + + _dump.push(" rDEL-TRIA = "); + _dump.push(std::to_string (_ntri)); _dump.push("\n") ; - + _dump.push("\n") ; + } - + + if (_args.verb() >= +3 ) + { + /*------------------------- push rDEL memory metrics */ + + _dump.push("\n") ; + _dump.push("**MEMORY statistics... \n") ; + _dump.push("\n") ; + + _dump.push("**DELAUNAY-OBJECT: ") ; + _dump.push("\n") ; + + _dump.push(" NODE-BYTE = ") ; + _dump.push(std::to_string( + sizeof(typename mesh_type:: + tria_type:: node_type)) ) ; + _dump.push("\n") ; + _dump.push(" NODE-LIST = ") ; + _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("\n") ; + _dump.push(" TRIA-LIST = ") ; + _dump.push(std::to_string( + _mesh._tria._tset.alloc())) ; + _dump.push("\n") ; + _dump.push("\n") ; + + _dump.push("**RESTRICTED-TRIA: ") ; _dump.push("\n") ; + + _dump.push(" EDGE-BYTE = ") ; + _dump.push(std::to_string( + sizeof( + typename mesh_type::edge_item)) ) ; + _dump.push("\n") ; + _dump.push(" EDGE-HASH = ") ; + _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("\n") ; + + _dump.push(" FACE-BYTE = ") ; + _dump.push(std::to_string( + sizeof( + typename mesh_type::face_item)) ) ; + _dump.push("\n") ; + _dump.push(" FACE-HASH = ") ; + _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("\n") ; + + _dump.push(" TRIA-BYTE = ") ; + _dump.push(std::to_string( + sizeof( + typename mesh_type::tria_item)) ) ; + _dump.push("\n") ; + _dump.push(" TRIA-HASH = ") ; + _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("\n") ; + _dump.push("\n") ; + + } + } - + } ; - - + + } - -# endif //__RDEL_MAKE_3__ + +# endif //__RDEL_MAKE_3__ diff --git a/src/libcpp/rdel_mesh/rdel_mesh_2.hpp b/src/libcpp/rdel_mesh/rdel_mesh_2.hpp index 53ad07d..52d59a3 100644 --- a/src/libcpp/rdel_mesh/rdel_mesh_2.hpp +++ b/src/libcpp/rdel_mesh/rdel_mesh_2.hpp @@ -1,37 +1,37 @@ /* -------------------------------------------------------- - * RDEL-MESH-2: restricted delaunay mesh-gen. in R^2. + * RDEL-MESH-2: restricted delaunay mesh-gen. in R^2. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 08 April, 2019 + * Last updated: 09 August, 2019 * * Copyright 2013-2019 * Darren Engwirda @@ -41,9 +41,9 @@ -------------------------------------------------------- * * This class defines the "restricted" delaunay mesh - * generation scheme for domains in R^2. This is the + * generation scheme for domains in R^2. This is the * top-level class, implementing the main method loops: - * "sampling" the geometry and incrementally refining + * "sampling" the geometry and incrementally refining * to convergence. In brief: a set of priority queues * are maintained for the nodes, edges, faces and cells * in the rDT, with new refinement points inserted to @@ -51,7 +51,7 @@ * * The algorithm is parameterised by various templated * types: MESH-TYPE which holds the rDT, MESH-PRED that - * defines the refinement strategy, GEOM-TYPE which + * defines the refinement strategy, GEOM-TYPE which * represents the domain geometry, and HFUN-TYPE which * represents the "mesh-spacing" function h(x). These * predicates derive from base classes defining common @@ -59,43 +59,43 @@ * * My implementation is described in: * - * D. Engwirda and D. Ivers, (2016): Off-centre Steiner - * points for Delaunay-refinement on curved surfaces, - * Computer-Aided Design, 72, pp. 157-171, + * D. Engwirda and D. Ivers, (2016): Off-centre Steiner + * points for Delaunay-refinement on curved surfaces, + * Computer-Aided Design, 72, pp. 157-171, * http://dx.doi.org/10.1016/j.cad.2015.10.007 * - * D. Engwirda, (2016): "Conforming restricted Delaunay - * mesh generation for piecewise smooth complexes", - * Procedia Engineering, 163, pp. 84-96, + * D. Engwirda, (2016): "Conforming restricted Delaunay + * mesh generation for piecewise smooth complexes", + * Procedia Engineering, 163, pp. 84-96, * http://dx.doi.org/10.1016/j.proeng.2016.11.024 * * D. Engwirda, (2014): "Locally-optimal Delaunay- - * refinement and optimisation-based mesh generation", - * Ph.D. Thesis, School of Mathematics and Statistics, - * Univ. of Sydney. + * refinement and optimisation-based mesh generation", + * Ph.D. Thesis, School of Mathematics and Statistics, + * Univ. of Sydney. * http://hdl.handle.net/2123/13148 * - * building on various previous works on rDT methods, + * building on various previous works on rDT methods, * including (primarily): * - * J.D. Boissonnat, S. Oudot, (2005): "Provably Good - * Sampling and Meshing of Surfaces", Graphical Models, + * J.D. Boissonnat, S. Oudot, (2005): "Provably Good + * Sampling and Meshing of Surfaces", Graphical Models, * 67, pp. 405-451, * https://doi.org/10.1016/j.gmod.2005.01.004 * - * C. Jamin, P. Alliez, M. Yvinec, and J.D. Boissonnat, - * (2015): "CGALmesh: a generic framework for Delaunay - * mesh generation", ACM Transactions on Mathematical + * C. Jamin, P. Alliez, M. Yvinec, and J.D. Boissonnat, + * (2015): "CGALmesh: a generic framework for Delaunay + * mesh generation", ACM Transactions on Mathematical * Software (TOMS), 41, pp. 23 * https://doi.org/10.1145/2699463 * - * L. Rineau, M. Yvinec, (2008): "Meshing 3D Domains - * Bounded by Piecewise Smooth Surfaces", Proc. of the + * L. Rineau, M. Yvinec, (2008): "Meshing 3D Domains + * Bounded by Piecewise Smooth Surfaces", Proc. of the * 16th International Meshing Roundtable, pp. 443-460, * https://doi.org/10.1007/978-3-540-75103-8_25 * - * S.W. Cheng, T.K. Dey, E.A. Ramos, (2010): "Delaunay - * Refinement for Piecewise Smooth Complexes", + * S.W. Cheng, T.K. Dey, E.A. Ramos, (2010): "Delaunay + * Refinement for Piecewise Smooth Complexes", * Discrete & Computational Geometry, 43, pp. 121-166, * https://doi.org/10.1007/s00454-008-9109-3 * @@ -108,45 +108,47 @@ # define __RDEL_MESH_2__ namespace mesh { - + template < typename M , typename P , typename G , typename H , + typename I , typename A = allocators::basic_alloc > class rdel_mesh_2d - { - public : - - /*-------- restricted delaunay mesh-generation in R^2 */ - + { + public : + + /*-------- restricted delaunay mesh-generation in R^2 */ + typedef M mesh_type ; typedef P mesh_pred ; typedef G geom_type ; typedef H hfun_type ; + typedef I init_type ; typedef A allocator ; - typedef typename + typedef typename mesh_type::real_type real_type ; - typedef typename + typedef typename mesh_type::iptr_type iptr_type ; - - typedef typename + + typedef typename allocator::size_type uint_type ; typedef char_type mode_type ; - + char_type static constexpr null_mode = +0 ; char_type static constexpr node_mode = +1 ; char_type static constexpr edge_mode = +2 ; char_type static constexpr etop_mode = +3 ; char_type static constexpr tria_mode = +4 ; - class node_pred ; class ball_pred ; + class node_pred ; class ball_pred ; class edge_pred ; class tria_pred ; - + class edge_cost : public mesh_pred::edge_data { public : @@ -159,23 +161,23 @@ iptr_type _node[ 3] ; iptr_type _pass; } ; - - typedef typename + + typedef typename mesh_type::node_data node_data ; - typedef typename + typedef typename mesh_type::ball_data ball_data ; - typedef typename + typedef typename mesh_type::edge_data edge_data ; - typedef typename + typedef typename mesh_type::tria_data tria_data ; - typedef typename + typedef typename mesh_type::edge_list edge_hash ; - typedef typename + typedef typename mesh_type::tria_list tria_hash ; - typedef mesh::rdel_params < - real_type, + typedef mesh::mesh_params < + real_type, iptr_type > rdel_opts ; typedef mesh::rdel_timers < @@ -188,37 +190,37 @@ /*------------------------------------------ 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 ; /*------------------------------------------ refine lists */ typedef containers::priorityset < - node_data, + node_data, node_pred > node_heap ; typedef containers::priorityset < - edge_cost, + edge_cost, edge_pred > edge_heap ; typedef containers::priorityset < - tria_cost, + tria_cost, tria_pred > tria_heap ; - + /*------------------------------------------ collar lists */ typedef containers::array < ball_data > ball_list ; - + typedef containers::priorityset < - ball_data, + ball_data, ball_pred > ball_heap ; - + class node_pred { /*---------------------- "less-than" for node objects */ @@ -227,8 +229,8 @@ node_data const& _idat, node_data const& _jdat ) const - { return _idat._node[0] < - _jdat._node[0] ; + { return _idat._node[0] < + _jdat._node[0] ; } } ; class ball_pred @@ -239,8 +241,8 @@ ball_data const& _idat, ball_data const& _jdat ) const - { return _idat._ball[2] > - _jdat._ball[2] ; + { return _idat._ball[2] > + _jdat._ball[2] ; } } ; class edge_pred @@ -271,50 +273,50 @@ /* -------------------------------------------------------- - * RDEL-CREATE: set-up initial nodes/faces. + * RDEL-CREATE: set-up initial nodes/faces. -------------------------------------------------------- */ - #include "rdel_create_init_2.inc" + #include "rdel_create_init_2.inc" /* -------------------------------------------------------- - * RDEL-UPDATE: update the restricted-tria. + * RDEL-UPDATE: update the restricted-tria. -------------------------------------------------------- */ - + #include "rdel_update_face_2.inc" #include "rdel_update_topo_2.inc" - - + + /* -------------------------------------------------------- - * RDEL-BOUNDS: test restricted boundaries. + * RDEL-BOUNDS: test restricted boundaries. -------------------------------------------------------- */ - + #include "rdel_test_bounds_2.inc" - - + + /* -------------------------------------------------------- - * RDEL-REFINE: refine restricted subfaces. + * RDEL-REFINE: refine restricted subfaces. -------------------------------------------------------- */ - + #include "rdel_refine_base_2.inc" #include "rdel_refine_ball_2.inc" #include "rdel_refine_face_2.inc" #include "rdel_refine_topo_2.inc" - - + + /* -------------------------------------------------------- - * TRIM-LIST: prune null faces from queues. + * TRIM-LIST: prune null faces from queues. -------------------------------------------------------- */ - + template < typename list_type > @@ -323,10 +325,10 @@ list_type &_list ) { - typedef typename + typedef typename list_type:: size_type size_type; - + size_type _amin = +512; size_type _alim = +256; size_type _amax = @@ -334,7 +336,7 @@ size_type _anew = (size_type)+2 * _list.count() ; - _anew = + _anew = std::max(_alim, _anew) ; if (_list.alloc() > _amin) @@ -344,7 +346,7 @@ /* -------------------------------------------------------- - * TRIM-EEPQ: prune null edges from queues. + * TRIM-EEPQ: prune null edges from queues. -------------------------------------------------------- */ @@ -360,21 +362,21 @@ iptr_type _dead = +0 ; iptr_type _okay = +0 ; - for (auto _hpos = _eepq.count() - 1 ; - _hpos > +0 ; + for (auto _hpos = _eepq.count() - 1 ; + _hpos > +0 ; --_hpos ) { - if (_okay > +1024 && + if (_okay > +1024 && _dead < _okay / 4) break; iptr_type _pass; edge_data _edat; - _edat._node[0] = + _edat._node[0] = _eepq. peek(_hpos)._node[0]; - _edat._node[1] = + _edat._node[1] = _eepq. peek(_hpos)._node[1]; - _pass = + _pass = _eepq. peek(_hpos)._pass ; typename mesh_type:: @@ -399,13 +401,13 @@ } } } - + trim_list ( _eepq ) ; } /* -------------------------------------------------------- - * TRIM-TTPQ: prune null tria. from queues. + * TRIM-TTPQ: prune null tria. from queues. -------------------------------------------------------- */ @@ -421,23 +423,23 @@ iptr_type _dead = +0 ; iptr_type _okay = +0 ; - for (auto _hpos = _ttpq.count() - 1 ; - _hpos > +0 ; + for (auto _hpos = _ttpq.count() - 1 ; + _hpos > +0 ; --_hpos ) { - if (_okay > +1024 && + if (_okay > +1024 && _dead < _okay / 4) break; iptr_type _pass; tria_data _tdat; - _tdat._node[0] = + _tdat._node[0] = _ttpq. peek(_hpos)._node[0]; - _tdat._node[1] = + _tdat._node[1] = _ttpq. peek(_hpos)._node[1]; - _tdat._node[2] = + _tdat._node[2] = _ttpq. peek(_hpos)._node[2]; - _pass = + _pass = _ttpq. peek(_hpos)._pass ; typename mesh_type:: @@ -462,17 +464,17 @@ } } } - + trim_list ( _ttpq ) ; } /* -------------------------------------------------------- - * INIT-RDEL: init. face-set in rDT. + * INIT-RDEL: init. face-set in rDT. -------------------------------------------------------- */ - __static_call + __static_call __normal_call void_type init_rdel ( geom_type &_geom , hfun_type &_hfun , @@ -493,10 +495,10 @@ { /*-------------------- mark all existing elem. as new */ iptr_type _npos = 0, _tpos = 0 ; - for (auto _iter = - _mesh._tria._nset.head() ; - _iter != - _mesh._tria._nset.tend() ; + for (auto _iter = + _mesh._tria._nset.head() ; + _iter != + _mesh._tria._nset.tend() ; ++_iter , ++_npos) { if (_iter->mark() >= +0) @@ -504,10 +506,10 @@ _nnew. push_tail( _npos) ; } } - for (auto _iter = - _mesh._tria._tset.head() ; - _iter != - _mesh._tria._tset.tend() ; + for (auto _iter = + _mesh._tria._tset.head() ; + _iter != + _mesh._tria._tset.tend() ; ++_iter , ++_tpos) { if (_iter->mark() >= +0) @@ -516,34 +518,31 @@ } } /*-------------------- init. restricted triangulation */ - push_rdel( _geom, _hfun, - _mesh, _init, - _nnew, _tnew, - _escr, _ecav, + push_rdel( _geom, _hfun, + _mesh, _init, + _nnew, _tnew, + _escr, _ecav, _tscr, _tcav, - _bscr, _bcav, + _bscr, _bcav, -1, _pass, _fdim, _fdim, _args) ; } /* -------------------------------------------------------- - * INIT-MESH: init. the bounding DT. + * INIT-MESH: init. the bounding DT. -------------------------------------------------------- */ - template < - typename init_type - > __static_call __normal_call void_type init_mesh ( geom_type &_geom, init_type &_init, hfun_type &_hfun, mesh_type &_mesh, - typename + typename mesh_type::edge_list & _epro, - typename + typename mesh_type::edge_list & _ebad, rdel_opts &_opts ) @@ -557,10 +556,10 @@ _pmin[ 1] = _geom._bmin[ 1] ; _pmax[ 0] = _geom._bmax[ 0] ; _pmax[ 1] = _geom._bmax[ 1] ; - - for (auto _node = - _init._mesh._set1.head(); - _node != + + for (auto _node = + _init._mesh._set1.head(); + _node != _init._mesh._set1.tend(); ++_node ) { @@ -570,19 +569,19 @@ _pmin[ 0], _node->pval(0)) ; _pmax[ 0] = std::max( _pmax[ 0], _node->pval(0)) ; - + _pmin[ 1] = std::min( _pmin[ 1], _node->pval(1)) ; _pmax[ 1] = std::max( - _pmax[ 1], _node->pval(1)) ; + _pmax[ 1], _node->pval(1)) ; } } - + real_type _plen[ 2] = { _pmax[ 0] - _pmin[ 0] , - _pmax[ 1] - _pmin[ 1] } ; + _pmax[ 1] - _pmin[ 1] } ; - real_type _scal = + real_type _scal = (real_type)+0.0 ; _scal = std::max( _scal , _plen[ 0]); @@ -591,12 +590,12 @@ _plen[ 0]*= (real_type)+2.0 ; _plen[ 1]*= (real_type)+2.0 ; - + _pmin[ 0]-= _plen[ 0] ; _pmin[ 1]-= _plen[ 1] ; _pmax[ 0]+= _plen[ 0] ; _pmax[ 1]+= _plen[ 1] ; - + _mesh. _tria.push_root(_pmin, _pmax) ; @@ -607,47 +606,47 @@ _tria.node(+1)->fdim() = +3 ; _mesh. _tria.node(+2)->fdim() = +3 ; - + _mesh. _tria.node(+0)->feat() = +0 ; _mesh. _tria.node(+1)->feat() = +0 ; _mesh. _tria.node(+2)->feat() = +0 ; - + _mesh. _tria.node(+0)->topo() = +0 ; _mesh. _tria.node(+1)->topo() = +0 ; _mesh. _tria.node(+2)->topo() = +0 ; - + /*------------------------------ seed feat from geom. */ _geom. seed_feat(_mesh, _opts) ; - + /*------------------------------ seed mesh from init. */ real_type _NEAR = - _scal *_opts.near() * - _scal *_opts.near() ; + _scal *_opts.near() * + _scal *_opts.near() ; - init_init(_init, _mesh , + init_init(_init, _geom , + _mesh, _epro, _ebad , _NEAR) ; - + /*------------------------------ seed mesh from geom. */ _geom. - seed_mesh(_mesh, _opts) ; + seed_mesh(_mesh, _opts) ; } /* -------------------------------------------------------- - * RDEL-MESH: build an rDT mesh in R^2. + * RDEL-MESH: build an rDT mesh in R^2. -------------------------------------------------------- */ template < - typename init_type , typename jlog_file > __static_call @@ -659,15 +658,18 @@ rdel_opts &_args , jlog_file &_dump ) - { + { mode_type _mode = null_mode ; - + /*------------------------------ push log-file header */ - _dump.push ( + if (_args.verb() >= 0 ) + { + _dump.push( "#------------------------------------------------------------\n" "# |ITER.| |DEL-1| |DEL-2| \n" "#------------------------------------------------------------\n" - ) ; + ) ; + } # ifdef __use_timers typename std ::chrono:: @@ -682,7 +684,7 @@ __unreferenced(_time) ; // why does MSVC need this?? # endif//__use_timers - /*------------------------------ ensure deterministic */ + /*------------------------------ ensure deterministic */ std::srand( +1 ) ; rdel_stat _tcpu ; @@ -690,13 +692,13 @@ /*------------------------------ init. list workspace */ iptr_list _nnew, _nold ; iptr_list _tnew, _told ; - + iptr_list _emrk ; - + escr_list _escr ; tscr_list _tscr ; ball_list _bscr ; - + edat_list _edat, _eprv ; tdat_list _tdat ; ball_list _bdat ; @@ -706,37 +708,37 @@ tria_heap _ttpq ; node_heap _etpq ; ball_heap _nbpq ; - + /*------------------------------ alloc. for hash obj. */ - _mesh._eset._lptr. set_count ( - _mesh._tria._tset.count()*+3 , - containers::loose_alloc, nullptr); - - _mesh._tset._lptr. set_count ( - _mesh._tria._tset.count()*+1 , - containers::loose_alloc, nullptr); + _mesh._eset.set_slots ( + _mesh._tria._tset.count()*+3 , + containers::tight_alloc) ; + + _mesh._tset.set_slots ( + _mesh._tria._tset.count()*+1 , + containers::tight_alloc) ; /*------------------------------ init. topo hash obj. */ - typename + typename mesh_type::edge_list _epro ( typename mesh_type::edge_hash(), - typename mesh_type::edge_pred(), + typename mesh_type::edge_pred(), +.8,_mesh._eset.get_alloc()) ; - typename + typename mesh_type::edge_list _ebad ( typename mesh_type::edge_hash(), - typename mesh_type::edge_pred(), + typename mesh_type::edge_pred(), +.8,_mesh._eset.get_alloc()) ; - + /*------------------------------ init. point counters */ containers:: fixed_array< iptr_type , rdel_opts::last_kind> _enod; _enod.fill( +0 ) ; - + containers:: fixed_array< - iptr_type , + iptr_type , rdel_opts::last_kind> _tnod; _tnod.fill( +0 ) ; @@ -745,8 +747,8 @@ _ttic = _time.now() ; # endif//__use_timers - init_mesh( _geom , _init, _hfun, - _mesh, _epro , + init_mesh( _geom , _init, _hfun, + _mesh, _epro , _ebad, _args ) ; if (_ebad.count() > +0) @@ -758,28 +760,31 @@ } # ifdef __use_timers - _ttoc = _time.now() ; - _tcpu._mesh_seed += + _ttoc = _time.now() ; + _tcpu._mesh_seed += _tcpu.time_span(_ttic,_ttoc) ; # endif//__use_timers - + /*------------------------------ calc. hfun. at seeds */ - for (auto _node = - _mesh._tria._nset.head() ; - _node != + for (auto _node = + _mesh._tria._nset.head() ; + _node != _mesh._tria._nset.tend() ; ++_node ) { if (_node->mark() >= +0) { - _node->idxh() = + _node->idxh() = hfun_type::null_hint () ; } } /*-------------------- main: refine edges/faces/trias */ - iptr_type _pass = +0 ; - + iptr_type _pass = +0 ; + uint_type _Nbpq = +0 ; + uint_type _Nepq = +0 ; + uint_type _Ntpq = +0 ; + for(bool_type _done=false; !_done ; ) { iptr_type _trim_freq = +10000 ; @@ -790,23 +795,30 @@ # endif if(++_pass>_args.iter()) break; - + /*------------------------- init. array workspace */ - + + _Nbpq = std::max( + _Nbpq, _nbpq.alloc()) ; + _Nepq = std::max( + _Nepq, _eepq.alloc()) ; + _Ntpq = std::max( + _Ntpq, _ttpq.alloc()) ; + _nnew.set_count( +0 ) ; // del-tri idx lists _nold.set_count( +0 ) ; _tnew.set_count( +0 ) ; _told.set_count( +0 ) ; - + _escr.set_count( +0 ) ; // face "cost" lists _tscr.set_count( +0 ) ; _bscr.set_count( +0 ) ; - + _eprv.set_count( +0 ) ; // "old" edge in cav _edat.set_count( +0 ) ; // "new" edge in cav _tdat.set_count( +0 ) ; // "new" cell in cav _bdat.set_count( +0 ) ; // "new" ball in cav - + /*--------- calc. "restricted-ness" incrementally */ bool_type _irDT = false ; @@ -817,26 +829,26 @@ # ifdef __use_timers _ttic = _time.now() ; # endif//__use_timers - + _mode = node_mode; - + _irDT = true; // init. new face in rDT - - init_rdel( _geom, _hfun, - _mesh, false, - _nnew, _tnew, - _edat, _escr, + + init_rdel( _geom, _hfun, + _mesh, false, + _nnew, _tnew, + _edat, _escr, _tdat, _tscr, - _bdat, _bscr, _pass, + _bdat, _bscr, _pass, _mode, _args) ; # ifdef __use_timers - _ttoc = _time.now() ; - _tcpu._node_init += + _ttoc = _time.now() ; + _tcpu._node_init += _tcpu.time_span(_ttic,_ttoc) ; # endif//__use_timers } - + if (_mode == node_mode && _nbpq. empty() && _bscr. empty() && @@ -848,38 +860,41 @@ # endif//__use_timers _mode = edge_mode; - + _irDT = true; // init. new face in rDT - + + if(_geom.have_feat(+1)) + { init_ball( _geom, _hfun, - _mesh, _epro, _pass, - _mode, _args) ; - - init_rdel( _geom, _hfun, + _mesh, _epro, _pass, + _mode, _args) ; + + init_rdel( _geom, _hfun, _mesh, true,// init. circum. for rDT - _nnew, _tnew, - _edat, _escr, + _nnew, _tnew, + _edat, _escr, _tdat, _tscr, - _bdat, _bscr, _pass, + _bdat, _bscr, _pass, _mode, _args) ; + } # ifdef __use_timers - _ttoc = _time.now() ; - _tcpu._edge_init += + _ttoc = _time.now() ; + _tcpu._edge_init += _tcpu.time_span(_ttic,_ttoc) ; # endif//__use_timers - } - if (_mode == edge_mode && + } + if (_mode == edge_mode && _eepq. empty() && _escr. empty() && _edat. empty() ) { /*------------------------- init. restricted topo */ - + _mode = etop_mode ; } - - if (_mode == etop_mode && + + if (_mode == etop_mode && _etpq. empty() && _escr. empty() && _edat. empty() ) @@ -888,22 +903,25 @@ # ifdef __use_timers _ttic = _time.now() ; # endif//__use_timers - + _mode = tria_mode; - + + if(_geom.have_feat(+1)) + { _irDT = true; // init. new face in rDT - - init_rdel( _geom, _hfun, - _mesh, false, - _nnew, _tnew, - _edat, _escr, + + init_rdel( _geom, _hfun, + _mesh, false, + _nnew, _tnew, + _edat, _escr, _tdat, _tscr, - _bdat, _bscr, _pass, + _bdat, _bscr, _pass, _mode, _args) ; - + } + # ifdef __use_timers - _ttoc = _time.now() ; - _tcpu._tria_init += + _ttoc = _time.now() ; + _tcpu._tria_init += _tcpu.time_span(_ttic,_ttoc) ; # endif//__use_timers } @@ -914,9 +932,9 @@ { char_type _tdim = -1; - typename rdel_opts::node_kind + typename rdel_opts::node_kind _kind = rdel_opts::null_kind ; - + if (!_nbpq.empty() ) { /*----------------------------- refine "bad" ball */ @@ -929,13 +947,13 @@ _nnew, _nold, _tnew, _told, _nbpq, _eprv, _edat, _escr, - _tdat, _tscr, - _bdat, _bscr, _tdim, + _tdat, _tscr, + _bdat, _bscr, _tdim, _pass, _args) ; # ifdef __use_timers - _ttoc = _time.now() ; - _tcpu._node_rule += + _ttoc = _time.now() ; + _tcpu._node_rule += _tcpu.time_span(_ttic,_ttoc) ; # endif//__use_timers } @@ -947,18 +965,18 @@ _ttic = _time.now() ; # endif//__use_timers - _kind =_bad_edge( _geom, + _kind =_bad_edge( _geom, _hfun, _mesh, _mode, - _epro, _nnew, _nold, + _epro, _nnew, _nold, _tnew, _told, _eepq, - _eprv, _edat, _escr, - _tdat, _tscr, - _bdat, _bscr, _tdim, + _eprv, _edat, _escr, + _tdat, _tscr, + _bdat, _bscr, _tdim, _pass, _args) ; # ifdef __use_timers - _ttoc = _time.now() ; - _tcpu._edge_rule += + _ttoc = _time.now() ; + _tcpu._edge_rule += _tcpu.time_span(_ttic,_ttoc) ; # endif//__use_timers } @@ -970,19 +988,19 @@ _ttic = _time.now() ; # endif//__use_timers - _kind =_bad_etop( _geom, - _hfun, _mesh, _mode, - _epro, _nnew, _nold, + _kind =_bad_etop( _geom, + _hfun, _mesh, _mode, + _epro, _nnew, _nold, _tnew, _told, - _etpq, _emrk, - _eprv, _edat, _escr, - _tdat, _tscr, - _bdat, _bscr, _tdim, + _etpq, _emrk, + _eprv, _edat, _escr, + _tdat, _tscr, + _bdat, _bscr, _tdim, _pass, _args) ; # ifdef __use_timers - _ttoc = _time.now() ; - _tcpu._edge_rule += + _ttoc = _time.now() ; + _tcpu._edge_rule += _tcpu.time_span(_ttic,_ttoc) ; # endif//__use_timers } @@ -994,35 +1012,38 @@ _ttic = _time.now() ; # endif//__use_timers - _kind =_bad_tria( _geom, - _hfun, _mesh, _mode, + _kind =_bad_tria( _geom, + _hfun, _mesh, _mode, _epro, _nnew, _nold, - _tnew, _told, _ttpq, + _tnew, _told, _ttpq, _eprv, _edat, _escr, - _tdat, _tscr, - _bdat, _bscr, _tdim, + _tdat, _tscr, + _bdat, _bscr, _tdim, _pass, _args) ; # ifdef __use_timers - _ttoc = _time.now() ; - _tcpu._tria_rule += + _ttoc = _time.now() ; + _tcpu._tria_rule += _tcpu.time_span(_ttic,_ttoc) ; # endif//__use_timers } /*----------------------------- meshing converged */ else { _done = true ; } - + if (_pass%_jlog_freq==+0 || _done) { /*----------------------------- output to logfile */ + if (_args.verb() >= +0) + { std::stringstream _sstr; _sstr << std::setw(+11) << - _pass << std::setw(+13) << + _pass << std::setw(+13) << _mesh._eset.count () - << std::setw(+13) << + << std::setw(+13) << _mesh._tset.count () << "\n" ; _dump.push(_sstr.str()); + } } if (_kind != rdel_opts::null_kind) @@ -1040,24 +1061,22 @@ } } - + if (_pass%_trim_freq == +0 ) { /*--------------- trim null PQ items "on-the-fly" */ - //trim_nbpq( _mesh , - // _nbpq ) ; - trim_eepq( _mesh , + trim_list( _nbpq ) ; + trim_eepq( _mesh , _eepq ) ; - trim_ttpq( _mesh , + trim_ttpq( _mesh , _ttpq ) ; - //trim_etpq( _mesh , - // _etpq ) ; - + trim_list( _etpq ) ; + trim_list( _nnew ) ; trim_list( _nold ) ; trim_list( _tnew ) ; trim_list( _told ) ; - + trim_list( _eprv ) ; trim_list( _edat ) ; trim_list( _escr ) ; @@ -1066,132 +1085,126 @@ trim_list( _bscr ) ; trim_list( _bdat ) ; } - - /*--------------- enqueue nodes for topol. checks */ - - fill_topo( _mesh, _pass, - _etpq, _emrk, + + /*--------------- enqueue nodes for topol. checks */ + + fill_topo( _mesh, _pass, + _etpq, _emrk, _edat, _eprv, _args) ; - + /*--------------- update restricted triangulation */ - + for (auto _npos = _nold.head() ; - _npos != _nold.tend() ; + _npos != _nold.tend() ; ++_npos ) { ball_data _ball, _same; _ball._node[0] = *_npos; - _ball._kind = feat_ball; + _ball._kind = feat_ball; _mesh. _pop_ball( _ball, _same) ; } - + for (auto _tpos = _told.head() ; - _tpos != _told.tend() ; + _tpos != _told.tend() ; ++_tpos ) { _pop_edge(_mesh, *_tpos) ; _pop_tria(_mesh, *_tpos) ; } for (auto _tpos = _told.head() ; - _tpos != _told.tend() ; + _tpos != _told.tend() ; ++_tpos ) { _mesh. _tria._put_tria( *_tpos) ; } - + for (auto _iter = _bscr.head() ; - _iter != _bscr.tend() ; + _iter != _bscr.tend() ; ++_iter ) { _nbpq .push( *_iter ) ; } for (auto _iter = _escr.head() ; - _iter != _escr.tend() ; + _iter != _escr.tend() ; ++_iter ) { _eepq .push( *_iter ) ; } for (auto _iter = _tscr.head() ; - _iter != _tscr.tend() ; + _iter != _tscr.tend() ; ++_iter ) { _ttpq .push( *_iter ) ; } - + for (auto _iter = _bdat.head() ; - _iter != _bdat.tend() ; + _iter != _bdat.tend() ; ++_iter ) { _mesh.push_ball( *_iter) ; } for (auto _iter = _edat.head() ; - _iter != _edat.tend() ; + _iter != _edat.tend() ; ++_iter ) { _mesh.push_edge( *_iter) ; - } + } for (auto _iter = _tdat.head() ; - _iter != _tdat.tend() ; + _iter != _tdat.tend() ; ++_iter ) { _mesh.push_tria( *_iter) ; } - - } - /* - if (_args.verb() >= +2 ) - { - //-------------------- push refinement memory metrics * - - _dump.push("\n") ; - _dump.push(" MEMORY statistics... \n") ; - _dump.push("\n") ; - } - */ - + if (_args.verb() >= +2 ) { /*-------------------- push refinement scheme metrics */ - + + _dump.push("\n") ; + _dump.push("**REFINE statistics... \n") ; _dump.push("\n") ; - _dump.push(" REFINE statistics... \n") ; + + _dump.push("**FUNCTION timing: ") ; _dump.push("\n") ; _dump.push(" MESH-SEED = ") ; _dump.push( - std::to_string (_tcpu._mesh_seed)) ; + std::to_string (_tcpu._mesh_seed)); _dump.push("\n") ; _dump.push(" NODE-INIT = ") ; _dump.push( - std::to_string (_tcpu._node_init)) ; + std::to_string (_tcpu._node_init)); _dump.push("\n") ; _dump.push(" NODE-RULE = ") ; _dump.push( - std::to_string (_tcpu._node_rule)) ; + std::to_string (_tcpu._node_rule)); _dump.push("\n") ; - + _dump.push(" EDGE-INIT = ") ; _dump.push( - std::to_string (_tcpu._edge_init)) ; + std::to_string (_tcpu._edge_init)); _dump.push("\n") ; _dump.push(" EDGE-RULE = ") ; _dump.push( - std::to_string (_tcpu._edge_rule)) ; + std::to_string (_tcpu._edge_rule)); _dump.push("\n") ; _dump.push(" TRIA-INIT = ") ; _dump.push( - std::to_string (_tcpu._tria_init)) ; + std::to_string (_tcpu._tria_init)); _dump.push("\n") ; _dump.push(" TRIA-RULE = ") ; _dump.push( - std::to_string (_tcpu._tria_rule)) ; + std::to_string (_tcpu._tria_rule)); + _dump.push("\n") ; _dump.push("\n") ; + + _dump.push("**INSERTION rules: ") ; _dump.push("\n") ; _dump.push(" EDGE-CIRC = ") ; @@ -1224,18 +1237,141 @@ _dump.push(std::to_string( _tnod[rdel_opts::offC_kind])); _dump.push("\n") ; - + _dump.push("\n") ; + + } + + if (_args.verb() >= +3 ) + { + /*-------------------- push refinement memory metrics */ + + _dump.push("\n") ; + _dump.push("**MEMORY statistics... \n") ; + _dump.push("\n") ; + + _dump.push("**DELAUNAY-OBJECT: ") ; + _dump.push("\n") ; + + _dump.push(" NODE-BYTE = ") ; + _dump.push(std::to_string( + sizeof(typename mesh_type:: + tria_type:: node_type)) ) ; + _dump.push("\n") ; + _dump.push(" NODE-LIST = ") ; + _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("\n") ; + _dump.push(" TRIA-LIST = ") ; + _dump.push(std::to_string( + _mesh._tria._tset.alloc())) ; + _dump.push("\n") ; + _dump.push("\n") ; + + _dump.push("**RESTRICTED-TRIA: ") ; + _dump.push("\n") ; + + _dump.push(" BALL-BYTE = ") ; + _dump.push(std::to_string( + sizeof( + typename mesh_type::ball_item)) ) ; + _dump.push("\n") ; + _dump.push(" BALL-HASH = ") ; + _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("\n") ; + + _dump.push(" NODE-BYTE = ") ; + _dump.push(std::to_string( + sizeof( + typename mesh_type::node_item)) ) ; + _dump.push("\n") ; + _dump.push(" NODE-HASH = ") ; + _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("\n") ; + + _dump.push(" EDGE-BYTE = ") ; + _dump.push(std::to_string( + sizeof( + typename mesh_type::edge_item)) ) ; + _dump.push("\n") ; + _dump.push(" EDGE-HASH = ") ; + _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("\n") ; + + _dump.push(" TRIA-BYTE = ") ; + _dump.push(std::to_string( + sizeof( + typename mesh_type::tria_item)) ) ; + _dump.push("\n") ; + _dump.push(" TRIA-HASH = ") ; + _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("\n") ; + _dump.push("\n") ; + + _dump.push("**PRIORITY-QUEUES: ") ; + _dump.push("\n") ; + + _dump.push(" BSCR-BYTE = ") ; + _dump.push( + std::to_string(sizeof(ball_data))); + _dump.push("\n") ; + _dump.push(" BBPQ-ITEM = ") ; + _dump.push(std::to_string(_Nbpq)) ; + _dump.push("\n") ; + + _dump.push(" ESCR-BYTE = ") ; + _dump.push( + std::to_string(sizeof(edge_cost))); + _dump.push("\n") ; + _dump.push(" EEPQ-ITEM = ") ; + _dump.push(std::to_string(_Nepq)) ; + _dump.push("\n") ; + + _dump.push(" TSCR-BYTE = ") ; + _dump.push( + std::to_string(sizeof(tria_cost))); + _dump.push("\n") ; + _dump.push(" TTPQ-ITEM = ") ; + _dump.push(std::to_string(_Ntpq)) ; + _dump.push("\n") ; + _dump.push("\n") ; + } - + _dump.push("\n") ; } - + } ; - + } - + # endif //__RDEL_MESH_2__ - - - + + + diff --git a/src/libcpp/rdel_mesh/rdel_mesh_3.hpp b/src/libcpp/rdel_mesh/rdel_mesh_3.hpp index c422786..6b06fb6 100644 --- a/src/libcpp/rdel_mesh/rdel_mesh_3.hpp +++ b/src/libcpp/rdel_mesh/rdel_mesh_3.hpp @@ -1,37 +1,37 @@ /* -------------------------------------------------------- - * RDEL-MESH-3: restricted delaunay mesh-gen. in R^3. + * RDEL-MESH-3: restricted delaunay mesh-gen. in R^3. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 08 April, 2019 + * Last updated: 30 June, 2019 * * Copyright 2013-2019 * Darren Engwirda @@ -41,9 +41,9 @@ -------------------------------------------------------- * * This class defines the "restricted" delaunay mesh - * generation scheme for domains in R^3. This is the + * generation scheme for domains in R^3. This is the * top-level class, implementing the main method loops: - * "sampling" the geometry and incrementally refining + * "sampling" the geometry and incrementally refining * to convergence. In brief: a set of priority queues * are maintained for the nodes, edges, faces and cells * in the rDT, with new refinement points inserted to @@ -51,7 +51,7 @@ * * The algorithm is parameterised by various templated * types: MESH-TYPE which holds the rDT, MESH-PRED that - * defines the refinement strategy, GEOM-TYPE which + * defines the refinement strategy, GEOM-TYPE which * represents the domain geometry, and HFUN-TYPE which * represents the "mesh-spacing" function h(x). These * predicates derive from base classes defining common @@ -59,43 +59,43 @@ * * My implementation is described in: * - * D. Engwirda and D. Ivers, (2016): Off-centre Steiner - * points for Delaunay-refinement on curved surfaces, - * Computer-Aided Design, 72, pp. 157-171, + * D. Engwirda and D. Ivers, (2016): Off-centre Steiner + * points for Delaunay-refinement on curved surfaces, + * Computer-Aided Design, 72, pp. 157-171, * http://dx.doi.org/10.1016/j.cad.2015.10.007 * - * D. Engwirda, (2016): "Conforming restricted Delaunay - * mesh generation for piecewise smooth complexes", - * Procedia Engineering, 163, pp. 84-96, + * D. Engwirda, (2016): "Conforming restricted Delaunay + * mesh generation for piecewise smooth complexes", + * Procedia Engineering, 163, pp. 84-96, * http://dx.doi.org/10.1016/j.proeng.2016.11.024 * * D. Engwirda, (2014): "Locally-optimal Delaunay- - * refinement and optimisation-based mesh generation", - * Ph.D. Thesis, School of Mathematics and Statistics, - * Univ. of Sydney. + * refinement and optimisation-based mesh generation", + * Ph.D. Thesis, School of Mathematics and Statistics, + * Univ. of Sydney. * http://hdl.handle.net/2123/13148 * - * building on various previous works on rDT methods, + * building on various previous works on rDT methods, * including (primarily): * - * J.D. Boissonnat, S. Oudot, (2005): "Provably Good - * Sampling and Meshing of Surfaces", Graphical Models, + * J.D. Boissonnat, S. Oudot, (2005): "Provably Good + * Sampling and Meshing of Surfaces", Graphical Models, * 67, pp. 405-451, * https://doi.org/10.1016/j.gmod.2005.01.004 * - * C. Jamin, P. Alliez, M. Yvinec, and J.D. Boissonnat, - * (2015): "CGALmesh: a generic framework for Delaunay - * mesh generation", ACM Transactions on Mathematical + * C. Jamin, P. Alliez, M. Yvinec, and J.D. Boissonnat, + * (2015): "CGALmesh: a generic framework for Delaunay + * mesh generation", ACM Transactions on Mathematical * Software (TOMS), 41, pp. 23 * https://doi.org/10.1145/2699463 * - * L. Rineau, M. Yvinec, (2008): "Meshing 3D Domains - * Bounded by Piecewise Smooth Surfaces", Proc. of the + * L. Rineau, M. Yvinec, (2008): "Meshing 3D Domains + * Bounded by Piecewise Smooth Surfaces", Proc. of the * 16th International Meshing Roundtable, pp. 443-460, * https://doi.org/10.1007/978-3-540-75103-8_25 * - * S.W. Cheng, T.K. Dey, E.A. Ramos, (2010): "Delaunay - * Refinement for Piecewise Smooth Complexes", + * S.W. Cheng, T.K. Dey, E.A. Ramos, (2010): "Delaunay + * Refinement for Piecewise Smooth Complexes", * Discrete & Computational Geometry, 43, pp. 121-166, * https://doi.org/10.1007/s00454-008-9109-3 * @@ -108,36 +108,38 @@ # define __RDEL_MESH_3__ namespace mesh { - + template < typename M , typename P , typename G , typename H , + typename I , typename A = allocators::basic_alloc > class rdel_mesh_3d - { - public : - - /*-------- restricted delaunay mesh-generation in R^3 */ - + { + public : + + /*-------- restricted delaunay mesh-generation in R^3 */ + typedef M mesh_type ; typedef P mesh_pred ; typedef G geom_type ; typedef H hfun_type ; + typedef I init_type ; typedef A allocator ; - typedef typename + typedef typename mesh_type::real_type real_type ; - typedef typename + typedef typename mesh_type::iptr_type iptr_type ; - - typedef typename + + typedef typename allocator::size_type uint_type ; typedef char_type mode_type ; - + char_type static constexpr null_mode = +0 ; char_type static constexpr node_mode = +1 ; char_type static constexpr edge_mode = +2 ; @@ -146,8 +148,8 @@ char_type static constexpr ftop_mode = +5 ; char_type static constexpr tria_mode = +6 ; - class node_pred ; class ball_pred ; - class edge_pred ; class face_pred ; + class node_pred ; class ball_pred ; + class edge_pred ; class face_pred ; class tria_pred ; class edge_cost : public mesh_pred::edge_data @@ -168,20 +170,20 @@ iptr_type _node[ +4] ; iptr_type _pass; } ; - - typedef typename + + typedef typename mesh_type::node_data node_data ; - typedef typename + typedef typename mesh_type::ball_data ball_data ; - typedef typename + typedef typename mesh_type::edge_data edge_data ; - typedef typename + typedef typename mesh_type::face_data face_data ; - typedef typename + typedef typename mesh_type::tria_data tria_data ; - typedef mesh::rdel_params < - real_type, + typedef mesh::mesh_params < + real_type, iptr_type > rdel_opts ; typedef mesh::rdel_timers < @@ -194,47 +196,47 @@ /*------------------------------------------ cavity lists */ typedef containers::array < edge_data > edat_list ; - + typedef containers::array < edge_cost > escr_list ; - + typedef containers::array < face_data > fdat_list ; - + typedef containers::array < face_cost > fscr_list ; - + typedef containers::array < tria_data > tdat_list ; - + typedef containers::array < tria_cost > tscr_list ; /*------------------------------------------ refine lists */ typedef containers::priorityset < - node_data, + node_data, node_pred > node_heap ; typedef containers::priorityset < - edge_cost, + edge_cost, edge_pred > edge_heap ; typedef containers::priorityset < - face_cost, + face_cost, face_pred > face_heap ; - + typedef containers::priorityset < - tria_cost, + tria_cost, tria_pred > tria_heap ; - + /*------------------------------------------ collar lists */ typedef containers::array < ball_data > ball_list ; - + typedef containers::priorityset < - ball_data, + ball_data, ball_pred > ball_heap ; - + class node_pred { /*---------------------- "less-than" for node objects */ @@ -243,8 +245,8 @@ node_data const& _idat, node_data const& _jdat ) const - { return _idat._node[0] < - _jdat._node[0] ; + { return _idat._node[0] < + _jdat._node[0] ; } } ; class ball_pred @@ -255,8 +257,8 @@ ball_data const& _idat, ball_data const& _jdat ) const - { return _idat._ball[3] > - _jdat._ball[3] ; + { return _idat._ball[3] > + _jdat._ball[3] ; } } ; class edge_pred @@ -295,55 +297,55 @@ ::tria_pred(_idat, _jdat) ; } } ; - + /* -------------------------------------------------------- - * RDEL-CREATE: set-up initial nodes/faces. + * RDEL-CREATE: set-up initial nodes/faces. -------------------------------------------------------- */ - #include "rdel_create_init_3.inc" - - + #include "rdel_create_init_3.inc" + + /* -------------------------------------------------------- - * RDEL-UPDATE: update the restricted-tria. + * RDEL-UPDATE: update the restricted-tria. -------------------------------------------------------- */ - + #include "rdel_update_face_3.inc" #include "rdel_update_topo_3.inc" - - + + /* -------------------------------------------------------- - * RDEL-BOUNDS: test restricted boundaries. + * RDEL-BOUNDS: test restricted boundaries. -------------------------------------------------------- */ - + #include "rdel_test_bounds_3.inc" /* -------------------------------------------------------- - * RDEL-REFINE: refine restricted subfaces. + * RDEL-REFINE: refine restricted subfaces. -------------------------------------------------------- */ - + #include "rdel_refine_base_3.inc" #include "rdel_refine_ball_3.inc" #include "rdel_refine_face_3.inc" #include "rdel_refine_topo_3.inc" - + /* -------------------------------------------------------- - * TRIM-LIST: prune null faces from queues. + * TRIM-LIST: prune null faces from queues. -------------------------------------------------------- */ - + template < typename list_type > @@ -352,10 +354,10 @@ list_type &_list ) { - typedef typename + typedef typename list_type:: size_type size_type; - + size_type _amin = +512; size_type _alim = +256; size_type _amax = @@ -363,7 +365,7 @@ size_type _anew = (size_type)+2 * _list.count() ; - _anew = + _anew = std::max(_alim, _anew) ; if (_list.alloc() > _amin) @@ -373,7 +375,7 @@ /* -------------------------------------------------------- - * TRIM-EEPQ: prune null edges from queues. + * TRIM-EEPQ: prune null edges from queues. -------------------------------------------------------- */ @@ -389,21 +391,21 @@ iptr_type _dead = +0 ; iptr_type _okay = +0 ; - for (auto _hpos = _eepq.count() - 1 ; - _hpos > +0 ; + for (auto _hpos = _eepq.count() - 1 ; + _hpos > +0 ; --_hpos ) { - if (_okay > +1024 && + if (_okay > +1024 && _dead < _okay / 4) break; iptr_type _pass; edge_data _edat; - _edat._node[0] = + _edat._node[0] = _eepq. peek(_hpos)._node[0]; - _edat._node[1] = + _edat._node[1] = _eepq. peek(_hpos)._node[1]; - _pass = + _pass = _eepq. peek(_hpos)._pass; typename mesh_type:: @@ -428,13 +430,13 @@ } } } - + trim_list ( _eepq ) ; } /* -------------------------------------------------------- - * TRIM-FFPQ: prune null faces from queues. + * TRIM-FFPQ: prune null faces from queues. -------------------------------------------------------- */ @@ -450,23 +452,23 @@ iptr_type _dead = +0 ; iptr_type _okay = +0 ; - for (auto _hpos = _ffpq.count() - 1 ; - _hpos > +0 ; + for (auto _hpos = _ffpq.count() - 1 ; + _hpos > +0 ; --_hpos ) { - if (_okay > +1024 && + if (_okay > +1024 && _dead < _okay / 4) break; iptr_type _pass ; face_data _fdat; - _fdat._node[0] = + _fdat._node[0] = _ffpq. peek(_hpos)._node[0]; - _fdat._node[1] = + _fdat._node[1] = _ffpq. peek(_hpos)._node[1]; - _fdat._node[2] = + _fdat._node[2] = _ffpq. peek(_hpos)._node[2]; - _pass = + _pass = _ffpq. peek(_hpos)._pass; typename mesh_type:: @@ -491,13 +493,13 @@ } } } - + trim_list ( _ffpq ) ; } /* -------------------------------------------------------- - * TRIM-TTPQ: prune null tria. from queues. + * TRIM-TTPQ: prune null tria. from queues. -------------------------------------------------------- */ @@ -513,25 +515,25 @@ iptr_type _dead = +0 ; iptr_type _okay = +0 ; - for (auto _hpos = _ttpq.count() - 1 ; - _hpos > +0 ; + for (auto _hpos = _ttpq.count() - 1 ; + _hpos > +0 ; --_hpos ) { - if (_okay > +1024 && + if (_okay > +1024 && _dead < _okay / 4) break; iptr_type _pass; tria_data _tdat; - _tdat._node[0] = + _tdat._node[0] = _ttpq. peek(_hpos)._node[0]; - _tdat._node[1] = + _tdat._node[1] = _ttpq. peek(_hpos)._node[1]; - _tdat._node[2] = + _tdat._node[2] = _ttpq. peek(_hpos)._node[2]; - _tdat._node[3] = + _tdat._node[3] = _ttpq. peek(_hpos)._node[3]; - _pass = + _pass = _ttpq. peek(_hpos)._pass; typename mesh_type:: @@ -556,17 +558,17 @@ } } } - + trim_list ( _ttpq ) ; } - + /* -------------------------------------------------------- - * INIT-RDEL: init. face-set in rDT. + * INIT-RDEL: init. face-set in rDT. -------------------------------------------------------- */ - __static_call + __static_call __normal_call void_type init_rdel ( geom_type &_geom , hfun_type &_hfun , @@ -589,10 +591,10 @@ { /*-------------------- mark all existing elem. as new */ iptr_type _npos = 0, _tpos = 0 ; - for (auto _iter = - _mesh._tria._nset.head() ; - _iter != - _mesh._tria._nset.tend() ; + for (auto _iter = + _mesh._tria._nset.head() ; + _iter != + _mesh._tria._nset.tend() ; ++_iter , ++_npos) { if (_iter->mark() >= +0) @@ -600,10 +602,10 @@ _nnew. push_tail( _npos) ; } } - for (auto _iter = - _mesh._tria._tset.head() ; - _iter != - _mesh._tria._tset.tend() ; + for (auto _iter = + _mesh._tria._tset.head() ; + _iter != + _mesh._tria._tset.tend() ; ++_iter , ++_tpos) { if (_iter->mark() >= +0) @@ -612,11 +614,11 @@ } } /*-------------------- init. restricted triangulation */ - push_rdel( _geom, _hfun, + push_rdel( _geom, _hfun, _mesh, _init, - _nnew, _tnew, - _escr, _ecav, - _fscr, _fcav, + _nnew, _tnew, + _escr, _ecav, + _fscr, _fcav, _tscr, _tcav, _bscr, _bcav, -1, _pass, @@ -625,27 +627,24 @@ /* -------------------------------------------------------- - * INIT-MESH: init. the bounding DT. + * INIT-MESH: init. the bounding DT. -------------------------------------------------------- */ - template < - typename init_type - > __static_call __normal_call void_type init_mesh ( geom_type &_geom, init_type &_init, hfun_type &_hfun, mesh_type &_mesh, - typename + typename mesh_type::edge_list & _epro, - typename + typename mesh_type::edge_list & _ebad, - typename + typename mesh_type::face_list & _fpro, - typename - mesh_type::face_list & _fbad, + typename + mesh_type::face_list & _fbad, rdel_opts &_opts ) { @@ -660,10 +659,10 @@ _pmax[ 0] = _geom._bmax[ 0] ; _pmax[ 1] = _geom._bmax[ 1] ; _pmax[ 2] = _geom._bmax[ 2] ; - - for (auto _node = - _init._mesh._set1.head(); - _node != + + for (auto _node = + _init._mesh._set1.head(); + _node != _init._mesh._set1.tend(); ++_node ) { @@ -673,25 +672,25 @@ _pmin[ 0], _node->pval(0)) ; _pmax[ 0] = std::max( _pmax[ 0], _node->pval(0)) ; - + _pmin[ 1] = std::min( _pmin[ 1], _node->pval(1)) ; _pmax[ 1] = std::max( _pmax[ 1], _node->pval(1)) ; - + _pmin[ 2] = std::min( _pmin[ 2], _node->pval(2)) ; _pmax[ 2] = std::max( - _pmax[ 2], _node->pval(2)) ; + _pmax[ 2], _node->pval(2)) ; } } - + real_type _plen[ 3] = { _pmax[ 0] - _pmin[ 0] , _pmax[ 1] - _pmin[ 1] , - _pmax[ 2] - _pmin[ 2] } ; + _pmax[ 2] - _pmin[ 2] } ; - real_type _scal = + real_type _scal = (real_type)+0.0 ; _scal = std::max( _scal , _plen[ 0]); @@ -703,7 +702,7 @@ _plen[ 0]*= (real_type)+2.0 ; _plen[ 1]*= (real_type)+2.0 ; _plen[ 2]*= (real_type)+2.0 ; - + _pmin[ 0]-= _plen[ 0] ; _pmin[ 1]-= _plen[ 1] ; _pmin[ 2]-= _plen[ 2] ; @@ -723,7 +722,7 @@ _tria.node(+2)->fdim() = +4 ; _mesh. _tria.node(+3)->fdim() = +4 ; - + _mesh. _tria.node(+0)->feat() = +0 ; _mesh. @@ -732,7 +731,7 @@ _tria.node(+2)->feat() = +0 ; _mesh. _tria.node(+3)->feat() = +0 ; - + _mesh. _tria.node(+0)->topo() = +0 ; _mesh. @@ -741,34 +740,34 @@ _tria.node(+2)->topo() = +0 ; _mesh. _tria.node(+3)->topo() = +0 ; - + /*------------------------------ seed feat from geom. */ _geom. seed_feat(_mesh, _opts) ; - + /*------------------------------ seed node from init. */ real_type _NEAR = - _scal *_opts.near() * + _scal *_opts.near() * _scal *_opts.near() ; - init_init(_init, _mesh , - _epro, _ebad , + init_init(_init, _geom , + _mesh, + _epro, _ebad , _fpro, _fbad , _NEAR) ; /*------------------------------ seed mesh from geom. */ _geom. - seed_mesh(_mesh, _opts) ; + seed_mesh(_mesh, _opts) ; } - + /* -------------------------------------------------------- - * RDEL-MESH: build an rDT mesh in R^3. + * RDEL-MESH: build an rDT mesh in R^3. -------------------------------------------------------- */ - + template < - typename init_type , typename jlog_file > __static_call @@ -780,15 +779,18 @@ rdel_opts &_args , jlog_file &_dump ) - { + { mode_type _mode = null_mode ; - + /*------------------------------ push log-file header */ - _dump.push ( + if (_args.verb() >= 0 ) + { + _dump.push( "#------------------------------------------------------------\n" "# |ITER.| |DEL-1| |DEL-2| |DEL-3| \n" "#------------------------------------------------------------\n" - ) ; + ) ; + } # ifdef __use_timers typename std ::chrono:: @@ -803,7 +805,7 @@ __unreferenced(_time) ; // why does MSVC need this?? # endif//__use_timers - /*------------------------------ ensure deterministic */ + /*------------------------------ ensure deterministic */ std::srand( +1 ) ; rdel_stat _tcpu ; @@ -811,14 +813,14 @@ /*------------------------------ init. list workspace */ iptr_list _nnew, _nold ; iptr_list _tnew, _told ; - + iptr_list _emrk, _fmrk ; - + escr_list _escr ; fscr_list _fscr ; tscr_list _tscr ; ball_list _bscr ; - + edat_list _edat, _eprv ; fdat_list _fdat, _fprv ; tdat_list _tdat ; @@ -829,60 +831,60 @@ face_heap _ffpq ; tria_heap _ttpq ; ball_heap _nbpq ; - + node_heap _etpq, _ftpq ; /*------------------------------ alloc. for hash obj. */ - _mesh._eset._lptr. set_count ( - _mesh._tria._tset.count()*+6 , - containers::loose_alloc, nullptr); - - _mesh._fset._lptr. set_count ( - _mesh._tria._tset.count()*+4 , - containers::loose_alloc, nullptr); - - _mesh._tset._lptr. set_count ( - _mesh._tria._tset.count()*+1 , - containers::loose_alloc, nullptr); + _mesh._eset.set_slots ( + _mesh._tria._tset.count()*+6 , + containers::tight_alloc) ; + + _mesh._fset.set_slots ( + _mesh._tria._tset.count()*+4 , + containers::tight_alloc) ; + + _mesh._tset.set_slots ( + _mesh._tria._tset.count()*+1 , + containers::tight_alloc) ; /*------------------------------ init. topo hash obj. */ - typename + typename mesh_type::edge_list _epro ( typename mesh_type::edge_hash(), - typename mesh_type::edge_pred(), + typename mesh_type::edge_pred(), +.8,_mesh._eset.get_alloc()) ; - typename + typename mesh_type::edge_list _ebad ( typename mesh_type::edge_hash(), - typename mesh_type::edge_pred(), + typename mesh_type::edge_pred(), +.8,_mesh._eset.get_alloc()) ; - - typename + + typename mesh_type::face_list _fpro ( typename mesh_type::face_hash(), - typename mesh_type::face_pred(), + typename mesh_type::face_pred(), +.8,_mesh._fset.get_alloc()) ; - typename + typename mesh_type::face_list _fbad ( typename mesh_type::face_hash(), - typename mesh_type::face_pred(), + typename mesh_type::face_pred(), +.8,_mesh._fset.get_alloc()) ; /*------------------------------ init. point counters */ containers:: fixed_array< - iptr_type, + iptr_type, rdel_opts::last_kind> _enod; - _enod.fill( +0 ) ; + _enod.fill( +0 ) ; containers:: fixed_array< - iptr_type, + iptr_type, rdel_opts::last_kind> _fnod; _fnod.fill( +0 ) ; containers:: fixed_array< - iptr_type, + iptr_type, rdel_opts::last_kind> _tnod; _tnod.fill( +0 ) ; @@ -891,9 +893,9 @@ _ttic = _time.now() ; # endif//__use_timers - init_mesh( _geom , _init, _hfun, - _mesh, _epro , - _ebad, _fpro , + init_mesh( _geom , _init, _hfun, + _mesh, _epro , + _ebad, _fpro , _fbad, _args ) ; if (_ebad.count() > +0) @@ -912,28 +914,32 @@ } # ifdef __use_timers - _ttoc = _time.now() ; - _tcpu._mesh_seed += + _ttoc = _time.now() ; + _tcpu._mesh_seed += _tcpu.time_span(_ttic,_ttoc) ; # endif//__use_timers - + /*------------------------------ calc. hfun. at seeds */ - for (auto _node = - _mesh._tria._nset.head() ; - _node != + for (auto _node = + _mesh._tria._nset.head() ; + _node != _mesh._tria._nset.tend() ; ++_node ) { if (_node->mark() >= +0) { - _node->idxh() = + _node->idxh() = hfun_type::null_hint () ; } } /*-------------------- main: refine edges/faces/trias */ - iptr_type _pass = +0 ; - + iptr_type _pass = +0 ; + uint_type _Nbpq = +0 ; + uint_type _Nepq = +0 ; + uint_type _Nfpq = +0 ; + uint_type _Ntpq = +0 ; + for(bool_type _done=false; !_done ; ) { iptr_type _trim_freq = +10000 ; @@ -946,24 +952,33 @@ if(++_pass>_args.iter()) break; /*------------------------- init. array workspace */ - + + _Nbpq = std::max( + _Nbpq, _nbpq.alloc()) ; + _Nepq = std::max( + _Nepq, _eepq.alloc()) ; + _Nfpq = std::max( + _Nfpq, _ffpq.alloc()) ; + _Ntpq = std::max( + _Ntpq, _ttpq.alloc()) ; + _nnew.set_count( +0 ) ; // del-tri idx lists - _nold.set_count( +0 ) ; + _nold.set_count( +0 ) ; _tnew.set_count( +0 ) ; _told.set_count( +0 ) ; - + _escr.set_count( +0 ) ; // face "cost" lists _fscr.set_count( +0 ) ; _tscr.set_count( +0 ) ; _bscr.set_count( +0 ) ; - + _eprv.set_count( +0 ) ; // "old" edge in cav _edat.set_count( +0 ) ; // "new" edge in cav _fprv.set_count( +0 ) ; // "old" face in cav _fdat.set_count( +0 ) ; // "new" face in cav _tdat.set_count( +0 ) ; // "new" cell in cav _bdat.set_count( +0 ) ; // "new" ball in cav - + /*--------- calc. "restricted-ness" incrementally */ bool_type _irDT = false ; @@ -976,25 +991,25 @@ # endif//__use_timers _mode = node_mode; - + _irDT = true; // init. new face in rDT - - init_rdel( _geom, _hfun, + + init_rdel( _geom, _hfun, _mesh, false, - _nnew, _tnew, - _edat, _escr, - _fdat, _fscr, + _nnew, _tnew, + _edat, _escr, + _fdat, _fscr, _tdat, _tscr, - _bdat, _bscr, _pass, + _bdat, _bscr, _pass, _mode, _args) ; # ifdef __use_timers - _ttoc = _time.now() ; - _tcpu._node_init += + _ttoc = _time.now() ; + _tcpu._node_init += _tcpu.time_span(_ttic,_ttoc) ; # endif//__use_timers } - + if (_mode == node_mode && _nbpq. empty() && _bscr. empty() && @@ -1006,30 +1021,33 @@ # endif//__use_timers _mode = edge_mode; - + + if(_geom.have_feat(+1)) + { _irDT = true; // init. new face in rDT - + init_ball( _geom, _hfun, _mesh, - _epro, _fpro, _pass, - _mode, _args) ; - - init_rdel( _geom, _hfun, + _epro, _fpro, _pass, + _mode, _args) ; + + init_rdel( _geom, _hfun, _mesh, true,// init. circum. for rDT - _nnew, _tnew, - _edat, _escr, - _fdat, _fscr, + _nnew, _tnew, + _edat, _escr, + _fdat, _fscr, _tdat, _tscr, - _bdat, _bscr, _pass, + _bdat, _bscr, _pass, _mode, _args) ; + } # ifdef __use_timers - _ttoc = _time.now() ; - _tcpu._edge_init += + _ttoc = _time.now() ; + _tcpu._edge_init += _tcpu.time_span(_ttic,_ttoc) ; # endif//__use_timers - } - if (_mode == edge_mode && + } + if (_mode == edge_mode && _eepq. empty() && _escr. empty() && _edat. empty() ) @@ -1037,7 +1055,7 @@ /*------------------------- init. restricted topo */ _mode = etop_mode ; } - + if (_mode == etop_mode && _etpq. empty() && _escr. empty() && @@ -1049,32 +1067,35 @@ # endif//__use_timers _mode = face_mode; - + + if(_geom.have_feat(+2)) + { _irDT = true; // init. new face in rDT - + /* init_disc( _geom, _hfun, _mesh, - _epro, _fpro, _pass, - _mode, _args) ; + _epro, _fpro, _pass, + _mode, _args) ; */ - - init_rdel( _geom, _hfun, + + init_rdel( _geom, _hfun, _mesh, true, - _nnew, _tnew, - _edat, _escr, - _fdat, _fscr, + _nnew, _tnew, + _edat, _escr, + _fdat, _fscr, _tdat, _tscr, - _bdat, _bscr, _pass, + _bdat, _bscr, _pass, _mode, _args) ; + } # ifdef __use_timers - _ttoc = _time.now() ; - _tcpu._face_init += + _ttoc = _time.now() ; + _tcpu._face_init += _tcpu.time_span(_ttic,_ttoc) ; # endif//__use_timers - } - if (_mode == face_mode && + } + if (_mode == face_mode && _ffpq. empty() && _fscr. empty() && _fdat. empty() ) @@ -1083,8 +1104,8 @@ _mode = ftop_mode ; } - - if (_mode == ftop_mode && + + if (_mode == ftop_mode && _ftpq. empty() && _fscr. empty() && _fdat. empty() ) @@ -1093,23 +1114,26 @@ # ifdef __use_timers _ttic = _time.now() ; # endif//__use_timers - + _mode = tria_mode; - + + if(_geom.have_feat(+2)) + { _irDT = true; // init. new face in rDT - - init_rdel( _geom, _hfun, + + init_rdel( _geom, _hfun, _mesh, false, - _nnew, _tnew, - _edat, _escr, - _fdat, _fscr, + _nnew, _tnew, + _edat, _escr, + _fdat, _fscr, _tdat, _tscr, - _bdat, _bscr, _pass, + _bdat, _bscr, _pass, _mode, _args) ; + } # ifdef __use_timers - _ttoc = _time.now() ; - _tcpu._tria_init += + _ttoc = _time.now() ; + _tcpu._tria_init += _tcpu.time_span(_ttic,_ttoc) ; # endif//__use_timers } @@ -1120,9 +1144,9 @@ { char_type _tdim = -1; - typename rdel_opts::node_kind + typename rdel_opts::node_kind _kind = rdel_opts::null_kind ; - + if (!_nbpq.empty() ) { /*----------------------------- refine "bad" ball */ @@ -1137,12 +1161,12 @@ _eprv, _edat, _escr, _fprv, _fdat, _fscr, _tdat, _tscr, - _bdat, _bscr, + _bdat, _bscr, _tdim, _pass, _args) ; # ifdef __use_timers - _ttoc = _time.now() ; - _tcpu._node_rule += + _ttoc = _time.now() ; + _tcpu._node_rule += _tcpu.time_span(_ttic,_ttoc) ; # endif//__use_timers } @@ -1154,20 +1178,20 @@ _ttic = _time.now() ; # endif//__use_timers - _kind =_bad_edge( _geom, + _kind =_bad_edge( _geom, _hfun, _mesh, _mode, _epro, _fpro, - _nnew, _nold, + _nnew, _nold, _tnew, _told, _eepq, - _eprv, _edat, _escr, - _fprv, _fdat, _fscr, - _tdat, _tscr, + _eprv, _edat, _escr, + _fprv, _fdat, _fscr, + _tdat, _tscr, _bdat, _bscr, _tdim, _pass, _args) ; # ifdef __use_timers - _ttoc = _time.now() ; - _tcpu._edge_rule += + _ttoc = _time.now() ; + _tcpu._edge_rule += _tcpu.time_span(_ttic,_ttoc) ; # endif//__use_timers } @@ -1179,21 +1203,21 @@ _ttic = _time.now() ; # endif//__use_timers - _kind =_bad_etop( _geom, - _hfun, _mesh, _mode, - _epro, _fpro, - _nnew, _nold, + _kind =_bad_etop( _geom, + _hfun, _mesh, _mode, + _epro, _fpro, + _nnew, _nold, _tnew, _told, - _etpq, _emrk, - _eprv, _edat, _escr, - _fprv, _fdat, _fscr, + _etpq, _emrk, + _eprv, _edat, _escr, + _fprv, _fdat, _fscr, _tdat, _tscr, - _bdat, _bscr, + _bdat, _bscr, _tdim, _pass, _args) ; # ifdef __use_timers - _ttoc = _time.now() ; - _tcpu._edge_rule += + _ttoc = _time.now() ; + _tcpu._edge_rule += _tcpu.time_span(_ttic,_ttoc) ; # endif//__use_timers } @@ -1205,20 +1229,20 @@ _ttic = _time.now() ; # endif//__use_timers - _kind =_bad_face( _geom, + _kind =_bad_face( _geom, _hfun, _mesh, _mode, - _epro, _fpro, + _epro, _fpro, _nnew, _nold, - _tnew, _told, _ffpq, + _tnew, _told, _ffpq, _eprv, _edat, _escr, - _fprv, _fdat, _fscr, + _fprv, _fdat, _fscr, _tdat, _tscr, - _bdat, _bscr, + _bdat, _bscr, _tdim, _pass, _args) ; # ifdef __use_timers - _ttoc = _time.now() ; - _tcpu._face_rule += + _ttoc = _time.now() ; + _tcpu._face_rule += _tcpu.time_span(_ttic,_ttoc) ; # endif//__use_timers } @@ -1230,21 +1254,21 @@ _ttic = _time.now() ; # endif//__use_timers - _kind =_bad_ftop( _geom, - _hfun, _mesh, _mode, - _epro, _fpro, + _kind =_bad_ftop( _geom, + _hfun, _mesh, _mode, + _epro, _fpro, _nnew, _nold, - _tnew, _told, - _ftpq, _fmrk, - _eprv, _edat, _escr, - _fprv, _fdat, _fscr, + _tnew, _told, + _ftpq, _fmrk, + _eprv, _edat, _escr, + _fprv, _fdat, _fscr, _tdat, _tscr, - _bdat, _bscr, + _bdat, _bscr, _tdim, _pass, _args) ; # ifdef __use_timers - _ttoc = _time.now() ; - _tcpu._face_rule += + _ttoc = _time.now() ; + _tcpu._face_rule += _tcpu.time_span(_ttic,_ttoc) ; # endif//__use_timers } @@ -1256,39 +1280,42 @@ _ttic = _time.now() ; # endif//__use_timers - _kind =_bad_tria( _geom, - _hfun, _mesh, _mode, - _epro, _fpro, + _kind =_bad_tria( _geom, + _hfun, _mesh, _mode, + _epro, _fpro, _nnew, _nold, - _tnew, _told, _ttpq, + _tnew, _told, _ttpq, _eprv, _edat, _escr, - _fprv, _fdat, _fscr, + _fprv, _fdat, _fscr, _tdat, _tscr, - _bdat, _bscr, + _bdat, _bscr, _tdim, _pass, _args) ; # ifdef __use_timers - _ttoc = _time.now() ; - _tcpu._tria_rule += + _ttoc = _time.now() ; + _tcpu._tria_rule += _tcpu.time_span(_ttic,_ttoc) ; # endif//__use_timers } /*----------------------------- meshing converged */ else { _done = true ; } - + if (_pass%_jlog_freq==+0 || _done) { /*----------------------------- output to logfile */ + if (_args.verb() >= +0) + { std::stringstream _sstr; _sstr << std::setw(+11) << - _pass << std::setw(+13) << + _pass << std::setw(+13) << _mesh._eset.count () - << std::setw(+13) << + << std::setw(+13) << _mesh._fset.count () - << std::setw(+13) << + << std::setw(+13) << _mesh._tset.count () << "\n" ; _dump.push(_sstr.str()); + } } if (_kind != rdel_opts::null_kind) @@ -1315,24 +1342,21 @@ if (_pass%_trim_freq == +0 ) { /*--------------- trim null PQ items "on-the-fly" */ - //trim_nbpq( _mesh , - // _nbpq ) ; - trim_eepq( _mesh , + trim_list( _nbpq ) ; + trim_eepq( _mesh , _eepq ) ; - trim_ffpq( _mesh , + trim_ffpq( _mesh , _ffpq ) ; - trim_ttpq( _mesh , + trim_ttpq( _mesh , _ttpq ) ; - //trim_etpq( _mesh , - // _etpq ) ; - //trim_ftpq( _mesh , - // _ftpq ) ; - + trim_list( _etpq ) ; + trim_list( _ftpq ) ; + trim_list( _nnew ) ; trim_list( _nold ) ; trim_list( _tnew ) ; trim_list( _told ) ; - + trim_list( _eprv ) ; trim_list( _edat ) ; trim_list( _escr ) ; @@ -1341,33 +1365,33 @@ trim_list( _fscr ) ; trim_list( _tdat ) ; trim_list( _tscr ) ; - trim_list( _bdat ) ; - trim_list( _bscr ) ; + trim_list( _bdat ) ; + trim_list( _bscr ) ; } - /*--------------- enqueue nodes for topol. checks */ - - fill_topo( _mesh, _pass, + /*--------------- enqueue nodes for topol. checks */ + + fill_topo( _mesh, _pass, _etpq, _emrk, - _ftpq, _fmrk, - _edat, _eprv, + _ftpq, _fmrk, + _edat, _eprv, _fdat, _fprv, _args) ; /*--------------- update restricted triangulation */ - + for (auto _npos = _nold.head() ; - _npos != _nold.tend() ; + _npos != _nold.tend() ; ++_npos ) { ball_data _ball, _same; _ball._node[0] = *_npos; - _ball._kind = feat_ball; + _ball._kind = feat_ball; _mesh. _pop_ball( _ball, _same) ; } - + for (auto _tpos = _told.head() ; - _tpos != _told.tend() ; + _tpos != _told.tend() ; ++_tpos ) { _pop_edge(_mesh, *_tpos) ; @@ -1375,125 +1399,119 @@ _pop_tria(_mesh, *_tpos) ; } for (auto _tpos = _told.head() ; - _tpos != _told.tend() ; + _tpos != _told.tend() ; ++_tpos ) { _mesh. _tria._put_tria( *_tpos) ; } - + for (auto _iter = _bscr.head() ; - _iter != _bscr.tend() ; + _iter != _bscr.tend() ; ++_iter ) { _nbpq .push( *_iter ) ; } for (auto _iter = _escr.head() ; - _iter != _escr.tend() ; + _iter != _escr.tend() ; ++_iter ) { _eepq .push( *_iter ) ; } for (auto _iter = _fscr.head() ; - _iter != _fscr.tend() ; + _iter != _fscr.tend() ; ++_iter ) { _ffpq .push( *_iter ) ; } for (auto _iter = _tscr.head() ; - _iter != _tscr.tend() ; + _iter != _tscr.tend() ; ++_iter ) { _ttpq .push( *_iter ) ; } - + for (auto _iter = _bdat.head() ; - _iter != _bdat.tend() ; + _iter != _bdat.tend() ; ++_iter ) { _mesh.push_ball( *_iter) ; } for (auto _iter = _edat.head() ; - _iter != _edat.tend() ; + _iter != _edat.tend() ; ++_iter ) { _mesh.push_edge( *_iter) ; } for (auto _iter = _fdat.head() ; - _iter != _fdat.tend() ; + _iter != _fdat.tend() ; ++_iter ) { _mesh.push_face( *_iter) ; } for (auto _iter = _tdat.head() ; - _iter != _tdat.tend() ; + _iter != _tdat.tend() ; ++_iter ) { _mesh.push_tria( *_iter) ; } - + } - /* if (_args.verb() >= +2 ) { - //-------------------- push refinement memory metrics * - - _dump.push("\n") ; - _dump.push(" MEMORY statistics... \n") ; - _dump.push("\n") ; - - } - */ - - if (_args.verb() >= +2 ) - { /*-------------------- push refinement scheme metrics */ - + + _dump.push("\n") ; + _dump.push("**REFINE statistics... \n") ; _dump.push("\n") ; - _dump.push(" REFINE statistics... \n") ; + + _dump.push("**FUNCTION timing: ") ; _dump.push("\n") ; _dump.push(" MESH-SEED = ") ; _dump.push( - std::to_string (_tcpu._mesh_seed)) ; + std::to_string (_tcpu._mesh_seed)); _dump.push("\n") ; _dump.push(" NODE-INIT = ") ; _dump.push( - std::to_string (_tcpu._node_init)) ; + std::to_string (_tcpu._node_init)); _dump.push("\n") ; _dump.push(" NODE-RULE = ") ; _dump.push( - std::to_string (_tcpu._node_rule)) ; + std::to_string (_tcpu._node_rule)); _dump.push("\n") ; - + _dump.push(" EDGE-INIT = ") ; _dump.push( - std::to_string (_tcpu._edge_init)) ; + std::to_string (_tcpu._edge_init)); _dump.push("\n") ; _dump.push(" EDGE-RULE = ") ; _dump.push( - std::to_string (_tcpu._edge_rule)) ; + std::to_string (_tcpu._edge_rule)); _dump.push("\n") ; _dump.push(" FACE-INIT = ") ; _dump.push( - std::to_string (_tcpu._face_init)) ; + std::to_string (_tcpu._face_init)); _dump.push("\n") ; _dump.push(" FACE-RULE = ") ; _dump.push( - std::to_string (_tcpu._face_rule)) ; + std::to_string (_tcpu._face_rule)); _dump.push("\n") ; _dump.push(" TRIA-INIT = ") ; _dump.push( - std::to_string (_tcpu._tria_init)) ; + std::to_string (_tcpu._tria_init)); _dump.push("\n") ; _dump.push(" TRIA-RULE = ") ; _dump.push( - std::to_string (_tcpu._tria_rule)) ; + std::to_string (_tcpu._tria_rule)); + _dump.push("\n") ; _dump.push("\n") ; + + _dump.push("**INSERTION rules: ") ; _dump.push("\n") ; _dump.push(" EDGE-CIRC = ") ; @@ -1548,18 +1566,163 @@ _dump.push(std::to_string( _tnod[rdel_opts::offC_kind])); _dump.push("\n") ; - + _dump.push("\n") ; + } - + + if (_args.verb() >= +3 ) + { + /*-------------------- push refinement memory metrics */ + + _dump.push("\n") ; + _dump.push("**MEMORY statistics... \n") ; + _dump.push("\n") ; + + _dump.push("**DELAUNAY-OBJECT: ") ; + _dump.push("\n") ; + + _dump.push(" NODE-BYTE = ") ; + _dump.push(std::to_string( + sizeof(typename mesh_type:: + tria_type:: node_type)) ) ; + _dump.push("\n") ; + _dump.push(" NODE-LIST = ") ; + _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("\n") ; + _dump.push(" TRIA-LIST = ") ; + _dump.push(std::to_string( + _mesh._tria._tset.alloc())) ; + _dump.push("\n") ; + _dump.push("\n") ; + + _dump.push("**RESTRICTED-TRIA: ") ; + _dump.push("\n") ; + + _dump.push(" BALL-BYTE = ") ; + _dump.push(std::to_string( + sizeof( + typename mesh_type::ball_item)) ) ; + _dump.push("\n") ; + _dump.push(" BALL-HASH = ") ; + _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("\n") ; + + _dump.push(" NODE-BYTE = ") ; + _dump.push(std::to_string( + sizeof( + typename mesh_type::node_item)) ) ; + _dump.push("\n") ; + _dump.push(" NODE-HASH = ") ; + _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("\n") ; + + _dump.push(" EDGE-BYTE = ") ; + _dump.push(std::to_string( + sizeof( + typename mesh_type::edge_item)) ) ; + _dump.push("\n") ; + _dump.push(" EDGE-HASH = ") ; + _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("\n") ; + + _dump.push(" FACE-BYTE = ") ; + _dump.push(std::to_string( + sizeof( + typename mesh_type::face_item)) ) ; + _dump.push("\n") ; + _dump.push(" FACE-HASH = ") ; + _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("\n") ; + + _dump.push(" TRIA-BYTE = ") ; + _dump.push(std::to_string( + sizeof( + typename mesh_type::tria_item)) ) ; + _dump.push("\n") ; + _dump.push(" TRIA-HASH = ") ; + _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("\n") ; + _dump.push("\n") ; + + _dump.push("**PRIORITY-QUEUES: ") ; + _dump.push("\n") ; + + _dump.push(" BSCR-BYTE = ") ; + _dump.push( + std::to_string(sizeof(ball_data))); + _dump.push("\n") ; + _dump.push(" BBPQ-ITEM = ") ; + _dump.push(std::to_string(_Nbpq)) ; + _dump.push("\n") ; + + _dump.push(" ESCR-BYTE = ") ; + _dump.push( + std::to_string(sizeof(edge_cost))); + _dump.push("\n") ; + _dump.push(" EEPQ-ITEM = ") ; + _dump.push(std::to_string(_Nepq)) ; + _dump.push("\n") ; + + _dump.push(" FSCR-BYTE = ") ; + _dump.push( + std::to_string(sizeof(face_cost))); + _dump.push("\n") ; + _dump.push(" FFPQ-ITEM = ") ; + _dump.push(std::to_string(_Nfpq)) ; + _dump.push("\n") ; + + _dump.push(" TSCR-BYTE = ") ; + _dump.push( + std::to_string(sizeof(tria_cost))); + _dump.push("\n") ; + _dump.push(" TTPQ-ITEM = ") ; + _dump.push(std::to_string(_Ntpq)) ; + _dump.push("\n") ; + _dump.push("\n") ; + + } + _dump.push("\n") ; } - + } ; - - + + } - + # endif //__RDEL_MESH_3__ - - - + + + diff --git a/src/libcpp/rdel_mesh/rdel_offh_delfront_2.inc b/src/libcpp/rdel_mesh/rdel_offh_delfront_2.inc index 2842bd7..dacaac4 100644 --- a/src/libcpp/rdel_mesh/rdel_offh_delfront_2.inc +++ b/src/libcpp/rdel_mesh/rdel_offh_delfront_2.inc @@ -1,37 +1,37 @@ /* -------------------------------------------------------- - * RDEL-PRED-DELFRONT-2: "frontal-DEL" kernel in R^2. + * RDEL-PRED-DELFRONT-2: "frontal-DEL" kernel in R^2. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 19 February, 2019 + * Last updated: 30 August, 2019 * * Copyright 2013-2019 * Darren Engwirda @@ -40,7 +40,7 @@ * -------------------------------------------------------- */ - + // from rdel_pred_delfront_2.hpp @@ -49,9 +49,9 @@ * EDGE-OFFH: "size"-optimal off-centre . -------------------------------------------------------- */ - - __static_call - __normal_call + + __static_call + __normal_call typename rdel_opts::node_kind edge_offh ( geom_type &_geom, hfun_type &_hfun, @@ -62,38 +62,41 @@ rdel_opts &_args ) { - typename rdel_opts::node_kind + typename rdel_opts::node_kind _kind = rdel_opts::null_kind ; - - typename hfun_type::hint_type + + typename hfun_type::hint_type _hint =_hfun .null_hint () ; - real_type static const _rtol = + real_type static const _rtol = (real_type)+1.00E-03 ; - - real_type static const _dtol = + + real_type static const _dtol = (real_type)+8.75E-01 ; - - real_type static const _epsb = + + real_type static const _lgap = (real_type)+9.50E-01 ; + real_type static const _ugap = + (real_type)+1.05E+00 ; + __unreferenced(_args) ; if (_enod[1] < _enod[0]) std::swap(_enod[0], _enod[1]) ; - real_type _nsiz [ 3] ; + real_type _nsiz [ 4] ; _nsiz[ 0] = _hfun.eval ( &_mesh._tria. - node(_enod[0])->pval(0) , + node(_enod[0])->pval(0) , _mesh._tria. node(_enod[0])->idxh()) ; _nsiz[ 1] = _hfun.eval ( &_mesh._tria. - node(_enod[1])->pval(0) , + node(_enod[1])->pval(0) , _mesh._tria. node(_enod[1])->idxh()) ; - + real_type _dvec[3] ; real_type _ipos[2] = { _mesh._tria. @@ -101,31 +104,31 @@ _mesh._tria. node(_enod[0])->pval(1) } ; - + _hint = _mesh._tria. node (_enod[0])->idxh() ; - _dvec[ 0] = + _dvec[ 0] = _sbal[ 0] - _ipos[ 0] ; - _dvec[ 1] = + _dvec[ 1] = _sbal[ 1] - _ipos[ 1] ; - - _dvec[ 2] = + + _dvec[ 2] = geometry::length_2d(_dvec) ; _dvec[ 0]/= _dvec[ 2] ; _dvec[ 1]/= _dvec[ 2] ; _ppos[ 0] = _sbal[ 0] ; _ppos[ 1] = _sbal[ 1] ; - + typename geom_type::ball_type _ball; _ball. _pmid[ 0] = _ipos[ 0] ; _ball. _pmid[ 1] = _ipos[ 1] ; - - real_type static const _seps = + + real_type static const _seps = (real_type)std::sqrt( +std::numeric_limits::epsilon()); @@ -135,34 +138,55 @@ ((real_type)(_hash % +4096)) / +4096 ; _pert += + 1 ; _pert *= _seps ; - - for(iptr_type _iter = +0; _iter++ != +4 ; ) + + for (auto _iter = +0; _iter++ != +4 ; ) { - _nsiz[ 2] = _hfun.eval (_ppos, _hint) ; + _nsiz[2] = _hfun.eval(_ppos, _hint) ; + + real_type _PMID[2] = { + (real_type)+.5 * (_ipos[0]+_ppos[0]) , + (real_type)+.5 * (_ipos[1]+_ppos[1]) , + } ; - real_type _hval = - _nsiz[0] * (real_type)+1./2. + - _nsiz[2] * (real_type)+1./2. ; + typename hfun_type::hint_type + _HINT = _hint ; + _nsiz[3] = _hfun.eval(_PMID, _HINT) ; + + real_type _hval = + _nsiz[0] * (real_type)1./3. + + _nsiz[2] * (real_type)1./3. + + _nsiz[3] * (real_type)1./3. ; real_type _dist = _hval ; - if (_dist >= _epsb * _dvec[2]) + + if (_dist >= _dvec[2] * _lgap && + _dist < _dvec[2] * _ugap ) + { // circumball cushion + _dist += _dvec[2] ; + _dist /= (real_type)2.; + + _kind = + rdel_opts::offH_kind ; + } + else + if (_dist >= _dvec[2] * _ugap ) { // circumball limiter - _ppos[0]=_sbal[0]; - _ppos[1]=_sbal[1]; - - _kind = + _ppos[0]=_sbal[0] ; + _ppos[1]=_sbal[1] ; + + _kind = rdel_opts::circ_kind ; - + return _kind ; } else // adv.-front limiter { - _kind = + _kind = rdel_opts::offH_kind ; } - + _dist -= _pert * _dist ; - + iptr_type _dual = -1 ; cosine_intersect _pred(_ipos,_dvec); _ball._rrad = _dist ; @@ -172,7 +196,7 @@ if (!_pred. _find ) return rdel_opts::null_kind ; - real_type _move = + real_type _move = geometry::length_2d( _ppos,&_pred._proj.pval(0)); @@ -181,32 +205,32 @@ _mesh._tria.find_node ( // test voro. limiter &_ppos[0], _dual, _enod[ 0]) ; - - real_type _dlen = + + real_type _dlen = geometry::length_2d( _ppos, &_mesh._tria. node(_dual)->pval(0)) ; - + if (_dual != _enod [ +0] ) if (_dlen <= _dtol*_hval ) { return rdel_opts::null_kind ; } - + if (_move <= _rtol*_hval ) break ; } return ( _kind ) ; } - + /* -------------------------------------------------------- * TRIA-OFFH: "size"-optimal off-centre . -------------------------------------------------------- */ - - __static_call - __normal_call + + __static_call + __normal_call typename rdel_opts::node_kind tria_offh ( geom_type &_geom, hfun_type &_hfun, @@ -219,43 +243,46 @@ rdel_opts &_args ) { - typename rdel_opts::node_kind + typename rdel_opts::node_kind _kind = rdel_opts::null_kind ; - - typename hfun_type::hint_type + + typename hfun_type::hint_type _hint =_hfun .null_hint () ; - - real_type static const _rtol = + + real_type static const _rtol = (real_type)+1.00E-03 ; - - real_type static const _epsb = + + real_type static const _lgap = (real_type)+9.50E-01 ; - - real_type static const _alth = + + real_type static const _ugap = + (real_type)+1.05E+00 ; + + real_type static const _alth = (real_type)std::sqrt(3.)/2. ; __unreferenced(_geom) ; __unreferenced(_args) ; - real_type _nsiz [ 3] ; + real_type _nsiz [ 4] ; _nsiz[ 0] = _hfun.eval ( &_mesh._tria. - node(_fnod[0])->pval(0) , + node(_fnod[0])->pval(0) , _mesh._tria. node(_fnod[0])->idxh()) ; _nsiz[ 1] = _hfun.eval ( &_mesh._tria. - node(_fnod[1])->pval(0) , + node(_fnod[1])->pval(0) , _mesh._tria. node(_fnod[1])->idxh()) ; - - _hint = + + _hint = _mesh._tria.node(_fnod[0])->idxh() ; _ppos[ 0] = _tbal[ 0] ; _ppos[ 1] = _tbal[ 1] ; - - real_type static const _seps = + + real_type static const _seps = (real_type)std::sqrt( +std::numeric_limits::epsilon()); @@ -265,23 +292,33 @@ ((real_type)(_hash % +4096)) / +4096 ; _pert += + 1 ; _pert *= _seps ; - - for(iptr_type _iter = +0; _iter++ != +4 ; ) + + for (auto _iter = +0; _iter++ != +4 ; ) { _nsiz[2] = _hfun.eval(_ppos, _hint) ; - - real_type _hmid = - _nsiz[0] * (real_type)1./4. + - _nsiz[1] * (real_type)1./4. + - _nsiz[2] * (real_type)2./4. ; + + real_type _PMID[2] = { + (real_type)+.5 * (_fbal[0]+_ppos[0]) , + (real_type)+.5 * (_fbal[1]+_ppos[1]) , + } ; + + typename hfun_type::hint_type + _HINT = _hint ; + _nsiz[3] = _hfun.eval(_PMID, _HINT) ; + + real_type _hmid = + _nsiz[0] * (real_type)1./6. + + _nsiz[1] * (real_type)1./6. + + _nsiz[2] * (real_type)2./6. + + _nsiz[3] * (real_type)2./6. ; _kind = rdel_opts::offH_kind ; - + real_type _dist ; - real_type _dsqr = + real_type _dsqr = _hmid*_hmid - _fbal[ 2] ; - real_type _near = + real_type _near = _fbal[2] * (real_type)1./3. ; if (_dsqr < _near) @@ -291,42 +328,54 @@ } else { - _dist = + _dist = (real_type)std::sqrt(_dsqr) ; } - - if (_dist > _alth * _hmid) + + if (_dist > _alth * _hmid) { // adv.-front limiter - _dist = _alth * _hmid; - _kind = - rdel_opts::offH_kind; + _dist = _alth * _hmid ; + _kind = + rdel_opts::offH_kind ; } + if (_dist >= _dvec[3]) // off-centre limiter { - _dist = _dvec[3]; - _kind = - rdel_opts::offC_kind; + _dist = _dvec[3] ; + _kind = + rdel_opts::offC_kind ; } - if (_dist >= _dvec[2] * _epsb) + + if (_dist >= _dvec[2] * _lgap && + _dist < _dvec[2] * _ugap ) + { // circumball cushion + _dist += _dvec[2] ; + _dist /= (real_type)2.; + + _kind = + rdel_opts::offH_kind ; + } + else + if (_dist >= _dvec[2] * _ugap ) { // circumball limiter - _ppos[0]=_tbal[0]; - _ppos[1]=_tbal[1]; - - _kind = - rdel_opts::circ_kind; - - return _kind; + _ppos[0]=_tbal[0] ; + _ppos[1]=_tbal[1] ; + + _kind = + rdel_opts::circ_kind ; + + return _kind ; } - + _dist -= _pert * _dist ; real_type _proj[2] ; - _proj[ 0] = - _fbal[ 0] + _dist*_dvec[ 0]; - _proj[ 1] = - _fbal[ 1] + _dist*_dvec[ 1]; + _proj[ 0] = + _fbal[ 0] + _dist*_dvec[0]; + _proj[ 1] = + _fbal[ 1] + _dist*_dvec[1]; - real_type _move = + real_type _move = geometry::length_2d(_ppos, _proj); _ppos[ 0] = _proj[ 0]; @@ -337,6 +386,6 @@ return ( _kind ) ; } - - - + + + diff --git a/src/libcpp/rdel_mesh/rdel_offh_delfront_3.inc b/src/libcpp/rdel_mesh/rdel_offh_delfront_3.inc index d2aef15..81177b6 100644 --- a/src/libcpp/rdel_mesh/rdel_offh_delfront_3.inc +++ b/src/libcpp/rdel_mesh/rdel_offh_delfront_3.inc @@ -1,37 +1,37 @@ /* -------------------------------------------------------- - * RDEL-PRED-DELFRONT-3: "frontal-DEL" kernel in R^3. + * RDEL-PRED-DELFRONT-3: "frontal-DEL" kernel in R^3. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 19 February, 2019 + * Last updated: 30 August, 2019 * * Copyright 2013-2019 * Darren Engwirda @@ -40,18 +40,18 @@ * -------------------------------------------------------- */ - + // from rdel_pred_delfront_3.hpp - - + + /* -------------------------------------------------------- * EDGE-OFFH: "size"-optimal off-centre . -------------------------------------------------------- */ - - __static_call - __normal_call + + __static_call + __normal_call typename rdel_opts::node_kind edge_offh ( geom_type &_geom, hfun_type &_hfun, @@ -62,38 +62,41 @@ rdel_opts &_args ) { - typename rdel_opts::node_kind + typename rdel_opts::node_kind _kind = rdel_opts::null_kind ; - - typename hfun_type::hint_type + + typename hfun_type::hint_type _hint =_hfun .null_hint () ; - real_type static const _rtol = + real_type static const _rtol = (real_type)+1.00E-03 ; - - real_type static const _dtol = + + real_type static const _dtol = (real_type)+8.75E-01 ; - - real_type static const _epsb = + + real_type static const _lgap = (real_type)+9.50E-01 ; - + + real_type static const _ugap = + (real_type)+1.05E+00 ; + __unreferenced(_args) ; - + if (_enod[1] < _enod[0]) std::swap(_enod[0], _enod[1]) ; - real_type _nsiz [ 3] ; + real_type _nsiz [ 4] ; _nsiz[ 0] = _hfun.eval ( &_mesh._tria. - node(_enod[0])->pval(0) , + node(_enod[0])->pval(0) , _mesh._tria. node(_enod[0])->idxh()) ; _nsiz[ 1] = _hfun.eval ( &_mesh._tria. - node(_enod[1])->pval(0) , + node(_enod[1])->pval(0) , _mesh._tria. node(_enod[1])->idxh()) ; - + real_type _dvec[4] ; real_type _ipos[3] = { _mesh._tria. @@ -103,18 +106,18 @@ _mesh._tria. node(_enod[0])->pval(2) } ; - + _hint = _mesh._tria. node (_enod[0])->idxh() ; - _dvec[ 0] = + _dvec[ 0] = _sbal[ 0] - _ipos[ 0] ; - _dvec[ 1] = + _dvec[ 1] = _sbal[ 1] - _ipos[ 1] ; - _dvec[ 2] = + _dvec[ 2] = _sbal[ 2] - _ipos[ 2] ; - - _dvec[ 3] = + + _dvec[ 3] = geometry::length_3d(_dvec) ; _dvec[ 0]/= _dvec[ 3] ; _dvec[ 1]/= _dvec[ 3] ; @@ -133,7 +136,7 @@ _ball. _pmid[ 2] = _ipos[ 2] ; - real_type static const _seps = + real_type static const _seps = (real_type)std::sqrt( +std::numeric_limits::epsilon()); @@ -143,31 +146,53 @@ ((real_type)(_hash % +4096)) / +4096 ; _pert += + 1 ; _pert *= _seps ; - - for(iptr_type _iter = +0; _iter++ != +4 ; ) + + for (auto _iter = +0; _iter++ != +4 ; ) { _nsiz[2] = _hfun.eval(_ppos, _hint) ; - real_type _hval = - _nsiz[0] * (real_type)1./2.+ - _nsiz[2] * (real_type)1./2.; + real_type _PMID[3] = { + (real_type)+.5 * (_ipos[0]+_ppos[0]) , + (real_type)+.5 * (_ipos[1]+_ppos[1]) , + (real_type)+.5 * (_ipos[2]+_ppos[2]) , + } ; + + typename hfun_type::hint_type + _HINT = _hint ; + _nsiz[3] = _hfun.eval(_PMID, _HINT) ; + + real_type _hval = + _nsiz[0] * (real_type)1./3. + + _nsiz[2] * (real_type)1./3. + + _nsiz[3] * (real_type)1./3. ; real_type _dist = _hval ; - if (_dist >= _dvec[3] * _epsb) + + if (_dist >= _dvec[3] * _lgap && + _dist < _dvec[3] * _ugap ) + { // circumball cushion + _dist += _dvec[3] ; + _dist /= (real_type)2.; + + _kind = + rdel_opts::offH_kind ; + } + else + if (_dist >= _dvec[3] * _ugap ) { // circumball limiter - _ppos[0]=_sbal[0]; - _ppos[1]=_sbal[1]; - _ppos[2]=_sbal[2]; - - _kind = - rdel_opts::circ_kind ; - - return _kind; + _ppos[0]=_sbal[0] ; + _ppos[1]=_sbal[1] ; + _ppos[2]=_sbal[2] ; + + _kind = + rdel_opts::circ_kind ; + + return _kind ; } else // adv.-front limiter { - _kind = - rdel_opts::offH_kind ; + _kind = + rdel_opts::offH_kind ; } _dist -= _pert * _dist ; @@ -180,43 +205,43 @@ return rdel_opts::null_kind ; if (!_pred. _find ) return rdel_opts::null_kind ; - - real_type _move = + + real_type _move = geometry::length_3d( _ppos,&_pred._proj.pval(0)); _ppos[ 0] = _pred._proj.pval(0); _ppos[ 1] = _pred._proj.pval(1); _ppos[ 2] = _pred._proj.pval(2); - + _mesh._tria.find_node ( // test voro. limiter &_ppos[0], _dual, _enod[ 0]) ; - - real_type _dlen = + + real_type _dlen = geometry::length_3d( _ppos, &_mesh._tria. node(_dual)->pval(0)) ; - + if (_dual != _enod [ +0] ) if (_dlen <= _dtol*_hval ) { return rdel_opts::null_kind ; } - + if (_move <= _rtol*_hval ) break ; } return (_kind ) ; } - + /* -------------------------------------------------------- * FACE-OFFH: "size"-optimal off-centre . -------------------------------------------------------- */ - - __static_call - __normal_call + + __static_call + __normal_call typename rdel_opts::node_kind face_offh ( geom_type &_geom, hfun_type &_hfun, @@ -230,38 +255,41 @@ rdel_opts &_args ) { - typename rdel_opts::node_kind + typename rdel_opts::node_kind _kind = rdel_opts::null_kind ; - - typename hfun_type::hint_type + + typename hfun_type::hint_type _hint =_hfun .null_hint () ; - real_type static const _rtol = + real_type static const _rtol = (real_type)+1.00E-03 ; - - real_type static const _dtol = + + real_type static const _dtol = (real_type)+8.75E-01 ; - - real_type static const _epsb = + + real_type static const _lgap = (real_type)+9.50E-01 ; - - real_type static const _alth = + + real_type static const _ugap = + (real_type)+1.05E+00 ; + + real_type static const _alth = (real_type)std::sqrt(3.)/2. ; __unreferenced(_args) ; - real_type _nsiz [ 3] ; + real_type _nsiz [ 4] ; _nsiz[ 0] = _hfun.eval ( &_mesh._tria. - node(_enod[0])->pval(0) , + node(_enod[0])->pval(0) , _mesh._tria. node(_enod[0])->idxh()) ; _nsiz[ 1] = _hfun.eval ( &_mesh._tria. - node(_enod[1])->pval(0) , + node(_enod[1])->pval(0) , _mesh._tria. node(_enod[1])->idxh()) ; - + _hint = _mesh._tria. node (_enod[0])->idxh() ; @@ -284,10 +312,10 @@ _disc. _nvec[ 2] = _evec[ 2] ; - real_type _epsh = + real_type _epsh = +std::numeric_limits::infinity(); - - real_type static const _seps = + + real_type static const _seps = (real_type)std::sqrt( +std::numeric_limits::epsilon()); @@ -297,27 +325,38 @@ ((real_type)(_hash % +4096)) / +4096 ; _pert += + 1 ; _pert *= _seps ; - - for(iptr_type _iter = +0; _iter++ != +4 ; ) + + for (auto _iter = +0; _iter++ != +4 ; ) { _nsiz[2] = _hfun.eval(_ppos, _hint) ; - real_type _hval = - _nsiz[0] * (real_type)1./4. + - _nsiz[1] * (real_type)1./4. + - _nsiz[2] * (real_type)2./4. ; + real_type _PMID[3] = { + (real_type)+.5 * (_pmid[0]+_ppos[0]) , + (real_type)+.5 * (_pmid[1]+_ppos[1]) , + (real_type)+.5 * (_pmid[2]+_ppos[2]) , + } ; + + typename hfun_type::hint_type + _HINT = _hint ; + _nsiz[3] = _hfun.eval(_PMID, _HINT) ; + + real_type _hval = + _nsiz[0] * (real_type)1./6. + + _nsiz[1] * (real_type)1./6. + + _nsiz[2] * (real_type)2./6. + + _nsiz[3] * (real_type)2./6. ; real_type _hmin ; _hmin = std::min (_hval , _epsh); real_type _elen = _evec[ 3] ; real_type _dist ; - real_type _dsqr = _hmin * _hmin - + real_type _dsqr = _hmin * _hmin - (real_type)+.25 * _elen * _elen ; - real_type _frad = + real_type _frad = (real_type)+.25 * _elen * _elen ; - real_type _near = + real_type _near = (real_type)+.33 * _frad ; _kind = rdel_opts::offH_kind ; @@ -329,83 +368,95 @@ } else { - _dist = + _dist = (real_type)std::sqrt(_dsqr) ; } if (_dist > _alth * _hval) { // adv.-front limiter - _dist = _alth * _hval; - _kind = - rdel_opts::offH_kind; + _dist = _alth * _hval ; + _kind = + rdel_opts::offH_kind ; } - if (_dist >= _dvec[4]) // off-centre limiter + + if (_dist >= _dvec[4]) // off-centre limiter { - _dist = _dvec[4]; - _kind = - rdel_opts::offC_kind; + _dist = _dvec[4] ; + _kind = + rdel_opts::offC_kind ; + } + + if (_dist >= _dvec[3] * _lgap && + _dist < _dvec[3] * _ugap ) + { // circumball cushion + _dist += _dvec[3] ; + _dist /= (real_type)2.; + + _kind = + rdel_opts::offH_kind ; } - if (_dist >= _dvec[3] * _epsb) + else + if (_dist >= _dvec[3] * _ugap ) { // circumball limiter - _ppos[0]=_sbal[0]; - _ppos[1]=_sbal[1]; - _ppos[2]=_sbal[2]; - - _kind = - rdel_opts::circ_kind; - - return _kind; + _ppos[0]=_sbal[0] ; + _ppos[1]=_sbal[1] ; + _ppos[2]=_sbal[2] ; + + _kind = + rdel_opts::circ_kind ; + + return _kind ; } - + _dist -= _pert * _dist ; - + iptr_type _dual = -1 ; cosine_intersect _pred(_pmid,_dvec); _disc._rrad = _dist ; if (!_geom.intersect ( - _disc, + _disc, _sbal, _pred) ) return rdel_opts::null_kind ; if (!_pred. _find ) return rdel_opts::null_kind ; - - real_type _move = + + real_type _move = geometry::length_3d( _ppos,&_pred._proj.pval(0)); _ppos[ 0] = _pred._proj.pval(0); _ppos[ 1] = _pred._proj.pval(1); _ppos[ 2] = _pred._proj.pval(2); - + _mesh._tria.find_node ( // test voro. limiter &_ppos[0], _dual, _enod[ 0]) ; - - real_type _dlen = + + real_type _dlen = geometry::length_3d( _ppos, &_mesh._tria. node(_dual)->pval(0)) ; - + if (_dual != _enod [ +0] && _dual != _enod [ +1] ) if (_dlen <= _dtol*_hmin ) { return rdel_opts::null_kind ; } - + if (_move <= _rtol*_hmin ) break ; } return (_kind ) ; } - + /* -------------------------------------------------------- * TRIA-OFFH: "size"-optimal off-centre . -------------------------------------------------------- */ - - __static_call - __normal_call + + __static_call + __normal_call typename rdel_opts::node_kind tria_offh ( geom_type &_geom, hfun_type &_hfun, @@ -418,51 +469,54 @@ rdel_opts &_args ) { - typename rdel_opts::node_kind + typename rdel_opts::node_kind _kind = rdel_opts::null_kind ; - - typename hfun_type::hint_type + + typename hfun_type::hint_type _hint =_hfun .null_hint () ; - + __unreferenced(_geom) ; - real_type static const _rtol = + real_type static const _rtol = (real_type)+1.00E-03 ; - - real_type static const _epsb = + + real_type static const _lgap = (real_type)+9.50E-01 ; - - real_type static const _alth = + + real_type static const _ugap = + (real_type)+1.05E+00 ; + + real_type static const _alth = (real_type)std::sqrt(6.)/3. ; __unreferenced(_geom) ; __unreferenced(_args) ; - real_type _nsiz [ 4] ; + real_type _nsiz [ 5] ; _nsiz[ 0] = _hfun.eval ( &_mesh._tria. - node(_fnod[0])->pval(0) , + node(_fnod[0])->pval(0) , _mesh._tria. node(_fnod[0])->idxh()) ; _nsiz[ 1] = _hfun.eval ( &_mesh._tria. - node(_fnod[1])->pval(0) , + node(_fnod[1])->pval(0) , _mesh._tria. node(_fnod[1])->idxh()) ; _nsiz[ 2] = _hfun.eval ( &_mesh._tria. - node(_fnod[2])->pval(0) , + node(_fnod[2])->pval(0) , _mesh._tria. node(_fnod[2])->idxh()) ; - + _hint = _mesh._tria. node (_fnod[0])->idxh() ; _ppos[ 0] = _tbal[ 0] ; _ppos[ 1] = _tbal[ 1] ; _ppos[ 2] = _tbal[ 2] ; - - real_type static const _seps = + + real_type static const _seps = (real_type)std::sqrt( +std::numeric_limits::epsilon()); @@ -472,74 +526,95 @@ ((real_type)(_hash % +4096)) / +4096 ; _pert += + 1 ; _pert *= _seps ; - - for(iptr_type _iter = +0; _iter++ != +4 ; ) + + for (auto _iter = +0; _iter++ != +4 ; ) { _nsiz[3] = _hfun.eval(_ppos, _hint) ; - real_type _hmid = - _nsiz[0] * (real_type)1./6. + - _nsiz[1] * (real_type)1./6. + - _nsiz[2] * (real_type)1./6. + - _nsiz[3] * (real_type)3./6. ; - + real_type _PMID[3] = { + (real_type)+.5 * (_fbal[0]+_ppos[0]) , + (real_type)+.5 * (_fbal[1]+_ppos[1]) , + (real_type)+.5 * (_fbal[2]+_ppos[2]) , + } ; + + typename hfun_type::hint_type + _HINT = _hint ; + _nsiz[4] = _hfun.eval(_PMID, _HINT) ; + + real_type _hmid = + _nsiz[0] * (real_type)1./9. + + _nsiz[1] * (real_type)1./9. + + _nsiz[2] * (real_type)1./9. + + _nsiz[3] * (real_type)3./9. + + _nsiz[4] * (real_type)3./9. ; + _kind = rdel_opts::offH_kind ; - + real_type _dist ; - real_type _dsqr = + real_type _dsqr = _hmid*_hmid - _fbal[ 3] ; - real_type _near = - _fbal[3] * (real_type)1./3. ; + real_type _near = + _fbal[3] * (real_type)2./3. ; if (_dsqr < _near) - { // min.-space limiter + { // min.-space limiter _dist = std::numeric_limits ::infinity() ; } else { - _dist = + _dist = (real_type) std::sqrt(_dsqr) ; } - - if (_dist > _alth * _hmid) + + if (_dist > _alth * _hmid) { // adv.-front limiter - _dist = _alth * _hmid; - _kind = - rdel_opts::offH_kind; + _dist = _alth * _hmid ; + _kind = + rdel_opts::offH_kind ; } - - if (_dist >= _dvec[4]) // off-centre limiter + + if (_dist >= _dvec[4]) // off-centre limiter { _dist = _dvec[4]; - _kind = - rdel_opts::offC_kind; + _kind = + rdel_opts::offC_kind ; } - - if (_dist >= _dvec[3] * _epsb) + + if (_dist >= _dvec[3] * _lgap && + _dist < _dvec[3] * _ugap ) + { // circumball cushion + _dist += _dvec[3] ; + _dist /= (real_type)2.; + + _kind = + rdel_opts::offH_kind ; + } + else + if (_dist >= _dvec[3] * _ugap ) { // circumball limiter - _ppos[0]=_tbal[0]; - _ppos[1]=_tbal[1]; - _ppos[2]=_tbal[2]; - - _kind = - rdel_opts::circ_kind; - + _ppos[0]=_tbal[0] ; + _ppos[1]=_tbal[1] ; + _ppos[2]=_tbal[2] ; + + _kind = + rdel_opts::circ_kind ; + return _kind ; } - + _dist -= _pert * _dist ; - + real_type _proj[3] ; - _proj[ 0] = - _fbal[ 0] + _dist*_dvec[ 0]; - _proj[ 1] = - _fbal[ 1] + _dist*_dvec[ 1]; - _proj[ 2] = - _fbal[ 2] + _dist*_dvec[ 2]; - - real_type _move = + _proj[ 0] = + _fbal[ 0] + _dist*_dvec[0]; + _proj[ 1] = + _fbal[ 1] + _dist*_dvec[1]; + _proj[ 2] = + _fbal[ 2] + _dist*_dvec[2]; + + real_type _move = geometry::length_3d(_ppos, _proj); _ppos[ 0] = _proj[ 0]; @@ -551,6 +626,6 @@ return (_kind ) ; } - - - + + + diff --git a/src/libcpp/rdel_mesh/rdel_pred_delaunay_2.hpp b/src/libcpp/rdel_mesh/rdel_pred_delaunay_2.hpp index 71589be..b54fcd0 100644 --- a/src/libcpp/rdel_mesh/rdel_pred_delaunay_2.hpp +++ b/src/libcpp/rdel_mesh/rdel_pred_delaunay_2.hpp @@ -1,32 +1,32 @@ /* -------------------------------------------------------- - * RDEL-PRED-DELAUNAY-2: "classical" kernel in R^2. + * RDEL-PRED-DELAUNAY-2: "classical" kernel in R^2. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- @@ -42,44 +42,44 @@ * * This class defines the behaviour of the "standard" * restricted delaunay refinement scheme for meshes - * in R^2. Routines are provided to assess the - * "restricted-ness" of faces, to compute refinement + * in R^2. Routines are provided to assess the + * "restricted-ness" of faces, to compute refinement * "costs" (priorities), and to insert new vertices. * * My implementation is described in: * - * D. Engwirda and D. Ivers, (2016): Off-centre Steiner - * points for Delaunay-refinement on curved surfaces, - * Computer-Aided Design, 72, pp. 157-171, + * D. Engwirda and D. Ivers, (2016): Off-centre Steiner + * points for Delaunay-refinement on curved surfaces, + * Computer-Aided Design, 72, pp. 157-171, * http://dx.doi.org/10.1016/j.cad.2015.10.007 * - * D. Engwirda, (2016): "Conforming restricted Delaunay - * mesh generation for piecewise smooth complexes", - * Procedia Engineering, 163, pp. 84-96, + * D. Engwirda, (2016): "Conforming restricted Delaunay + * mesh generation for piecewise smooth complexes", + * Procedia Engineering, 163, pp. 84-96, * http://dx.doi.org/10.1016/j.proeng.2016.11.024 * * D. Engwirda, (2014): "Locally-optimal Delaunay- - * refinement and optimisation-based mesh generation", - * Ph.D. Thesis, School of Mathematics and Statistics, - * Univ. of Sydney. + * refinement and optimisation-based mesh generation", + * Ph.D. Thesis, School of Mathematics and Statistics, + * Univ. of Sydney. * http://hdl.handle.net/2123/13148 * * which is based on various previous works, including * (primarily): * - * J.D. Boissonnat, S. Oudot, (2005): "Provably Good - * Sampling and Meshing of Surfaces", Graphical Models, + * J.D. Boissonnat, S. Oudot, (2005): "Provably Good + * Sampling and Meshing of Surfaces", Graphical Models, * 67, pp. 405-451, * https://doi.org/10.1016/j.gmod.2005.01.004 * - * C. Jamin, P. Alliez, M. Yvinec, and J.D. Boissonnat, - * (2015): "CGALmesh: a generic framework for Delaunay - * mesh generation", ACM Transactions on Mathematical + * C. Jamin, P. Alliez, M. Yvinec, and J.D. Boissonnat, + * (2015): "CGALmesh: a generic framework for Delaunay + * mesh generation", ACM Transactions on Mathematical * Software (TOMS), 41, pp. 23 * https://doi.org/10.1145/2699463 * - * S.W. Cheng, T.K. Dey, E.A. Ramos, (2010): "Delaunay - * Refinement for Piecewise Smooth Complexes", + * S.W. Cheng, T.K. Dey, E.A. Ramos, (2010): "Delaunay + * Refinement for Piecewise Smooth Complexes", * Discrete & Computational Geometry, 43, pp. 121-166, * https://doi.org/10.1007/s00454-008-9109-3 * @@ -102,72 +102,74 @@ public rdel_pred_base_2 { public : - + /*------------ "classical" delaunay refinement in R^2 */ - + typedef G geom_type ; typedef H hfun_type ; typedef M mesh_type ; - typedef typename + typedef typename mesh_type::real_type real_type ; - typedef typename + typedef typename mesh_type::iptr_type iptr_type ; - typedef mesh::rdel_params < - real_type , + typedef mesh::mesh_params < + real_type , iptr_type > rdel_opts ; typedef mesh::rdel_pred_base_2 < - geom_type , + geom_type , mesh_type > base_type ; typedef mesh::keep_minmax_length_2d < - real_type , + real_type , iptr_type > minmax_intersect ; - + /*------------------------ refinement priority types */ class edge_data { public : - real_type _cost ; + float _cost ; } ; class tria_data { public : - real_type _cost ; + float _cost ; } ; /*------------------------ refinement priority pred. */ - + __static_call __inline_call bool_type edge_pred ( edge_data const&_idat , edge_data const&_jdat ) - { return ( _idat. _cost > - _jdat. _cost ) ; + { + return _idat._cost > + _jdat._cost ; } - + __static_call __inline_call bool_type tria_pred ( tria_data const&_idat , tria_data const&_jdat ) - { return ( _idat. _cost > - _jdat. _cost ) ; + { + return _idat._cost > + _jdat._cost ; } - + /* -------------------------------------------------------- * FACE-COST: calc. face refinement "cost". -------------------------------------------------------- */ - + #include "rdel_cost_delaunay_2.inc" - + /* -------------------------------------------------------- @@ -176,7 +178,7 @@ */ __static_call - __normal_call + __normal_call typename rdel_opts::node_kind edge_node ( geom_type &_geom, hfun_type &_size, @@ -197,15 +199,15 @@ iptr_type _part; real_type _ebal[ +3]; real_type _pmax[ +3]; - if (!base_type::edge_ball ( - _geom, _mesh, _tadj, - _eadj, _ebal, _pmax, + if (!base_type::edge_ball ( + _geom, _mesh, _tadj, + _eadj, _ebal, _pmax, _feat, _topo, _part) ) { /*--------------------------------- is not restricted */ - __assert( false && + __assert( false && "EDGE-NODE: interior facet!") ; - + return rdel_opts:: null_kind; } @@ -223,7 +225,7 @@ */ __static_call - __normal_call + __normal_call typename rdel_opts::node_kind tria_node ( geom_type &_geom, hfun_type &_size, @@ -254,10 +256,10 @@ } } ; - - + + } - + # endif //__RDEL_PRED_DELAUNAY_2__ diff --git a/src/libcpp/rdel_mesh/rdel_pred_delaunay_3.hpp b/src/libcpp/rdel_mesh/rdel_pred_delaunay_3.hpp index 3a2a915..14e4799 100644 --- a/src/libcpp/rdel_mesh/rdel_pred_delaunay_3.hpp +++ b/src/libcpp/rdel_mesh/rdel_pred_delaunay_3.hpp @@ -1,32 +1,32 @@ /* -------------------------------------------------------- - * RDEL-PRED-DELAUNAY-3: "classical" kernel in R^3. + * RDEL-PRED-DELAUNAY-3: "classical" kernel in R^3. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- @@ -42,44 +42,44 @@ * * This class defines the behaviour of the "standard" * restricted delaunay refinement scheme for meshes - * in R^3. Routines are provided to assess the - * "restricted-ness" of faces, to compute refinement + * in R^3. Routines are provided to assess the + * "restricted-ness" of faces, to compute refinement * "costs" (priorities), and to insert new vertices. * * My implementation is described in: * - * D. Engwirda and D. Ivers, (2016): Off-centre Steiner - * points for Delaunay-refinement on curved surfaces, - * Computer-Aided Design, 72, pp. 157-171, + * D. Engwirda and D. Ivers, (2016): Off-centre Steiner + * points for Delaunay-refinement on curved surfaces, + * Computer-Aided Design, 72, pp. 157-171, * http://dx.doi.org/10.1016/j.cad.2015.10.007 * - * D. Engwirda, (2016): "Conforming restricted Delaunay - * mesh generation for piecewise smooth complexes", - * Procedia Engineering, 163, pp. 84-96, + * D. Engwirda, (2016): "Conforming restricted Delaunay + * mesh generation for piecewise smooth complexes", + * Procedia Engineering, 163, pp. 84-96, * http://dx.doi.org/10.1016/j.proeng.2016.11.024 * * D. Engwirda, (2014): "Locally-optimal Delaunay- - * refinement and optimisation-based mesh generation", - * Ph.D. Thesis, School of Mathematics and Statistics, - * Univ. of Sydney. + * refinement and optimisation-based mesh generation", + * Ph.D. Thesis, School of Mathematics and Statistics, + * Univ. of Sydney. * http://hdl.handle.net/2123/13148 * * which is based on various previous works, including * (primarily): * - * J.D. Boissonnat, S. Oudot, (2005): "Provably Good - * Sampling and Meshing of Surfaces", Graphical Models, + * J.D. Boissonnat, S. Oudot, (2005): "Provably Good + * Sampling and Meshing of Surfaces", Graphical Models, * 67, pp. 405-451, * https://doi.org/10.1016/j.gmod.2005.01.004 * - * C. Jamin, P. Alliez, M. Yvinec, and J.D. Boissonnat, - * (2015): "CGALmesh: a generic framework for Delaunay - * mesh generation", ACM Transactions on Mathematical + * C. Jamin, P. Alliez, M. Yvinec, and J.D. Boissonnat, + * (2015): "CGALmesh: a generic framework for Delaunay + * mesh generation", ACM Transactions on Mathematical * Software (TOMS), 41, pp. 23 * https://doi.org/10.1145/2699463 * - * S.W. Cheng, T.K. Dey, E.A. Ramos, (2010): "Delaunay - * Refinement for Piecewise Smooth Complexes", + * S.W. Cheng, T.K. Dey, E.A. Ramos, (2010): "Delaunay + * Refinement for Piecewise Smooth Complexes", * Discrete & Computational Geometry, 43, pp. 121-166, * https://doi.org/10.1007/s00454-008-9109-3 * @@ -92,7 +92,7 @@ # define __RDEL_PRED_DELAUNAY_3__ namespace mesh { - + template < typename G , typename H , @@ -102,48 +102,48 @@ public rdel_pred_base_3 { public : - + /*------------ "classical" delaunay refinement in R^3 */ - + typedef G geom_type ; typedef H hfun_type ; typedef M mesh_type ; - typedef typename + typedef typename mesh_type::real_type real_type ; - typedef typename + typedef typename mesh_type::iptr_type iptr_type ; - typedef mesh::rdel_params < - real_type , + typedef mesh::mesh_params < + real_type , iptr_type > rdel_opts ; - + typedef mesh::rdel_pred_base_3 < - geom_type , + geom_type , mesh_type > base_type ; typedef mesh::keep_minmax_length_3d < - real_type , + real_type , iptr_type > minmax_intersect ; - + /*------------------------ refinement priority types */ - + class edge_data { public : - real_type _cost ; + float _cost ; } ; - + class face_data { public : - real_type _cost ; + float _cost ; } ; - + class tria_data { public : - real_type _cost ; + float _cost ; } ; /*------------------------ refinement priority pred. */ @@ -153,26 +153,29 @@ edge_data const&_idat , edge_data const&_jdat ) - { return ( _idat. _cost > - _jdat. _cost ) ; + { + return _idat._cost > + _jdat._cost ; } - + __static_call __inline_call bool_type face_pred ( face_data const&_idat , face_data const&_jdat ) - { return ( _idat. _cost > - _jdat. _cost ) ; + { + return _idat._cost > + _jdat._cost ; } - + __static_call __inline_call bool_type tria_pred ( tria_data const&_idat , tria_data const&_jdat ) - { return ( _idat. _cost > - _jdat. _cost ) ; + { + return _idat._cost > + _jdat._cost ; } /* @@ -180,9 +183,9 @@ * FACE-COST: calc. face refinement "cost". -------------------------------------------------------- */ - + #include "rdel_cost_delaunay_3.inc" - + /* -------------------------------------------------------- @@ -191,7 +194,7 @@ */ __static_call - __normal_call + __normal_call typename rdel_opts::node_kind edge_node ( geom_type &_geom, hfun_type &_size, @@ -213,16 +216,16 @@ iptr_type _part; real_type _ebal[ +4] ; real_type _pmax[ +4] ; - if (!base_type::edge_ball ( - _geom, _mesh, _tadj, - _eadj, _ebal, _pmax, - _hits, + if (!base_type::edge_ball ( + _geom, _mesh, _tadj, + _eadj, _ebal, _pmax, + _hits, _feat, _topo, _part) ) { /*--------------------------------- is not restricted */ - __assert( false && + __assert( false && "EDGE-NODE: interior facet!") ; - + return rdel_opts:: null_kind; } @@ -241,7 +244,7 @@ */ __static_call - __normal_call + __normal_call typename rdel_opts::node_kind face_node ( geom_type &_geom, hfun_type &_size, @@ -262,15 +265,15 @@ iptr_type _part; real_type _fbal[ +4] ; real_type _pmax[ +4] ; - if (!base_type::face_ball ( - _geom, _mesh, _tadj, - _fadj, _fbal, _pmax, + if (!base_type::face_ball ( + _geom, _mesh, _tadj, + _fadj, _fbal, _pmax, _feat, _topo, _part) ) { /*--------------------------------- is not restricted */ - __assert( false && + __assert( false && "FACE-NODE: interior facet!") ; - + return rdel_opts:: null_kind; } @@ -289,7 +292,7 @@ */ __static_call - __normal_call + __normal_call typename rdel_opts::node_kind tria_node ( geom_type &_geom, hfun_type &_size, @@ -323,10 +326,10 @@ } } ; - - + + } - + # endif //__RDEL_PRED_DELAUNAY_3__ diff --git a/src/libcpp/rdel_mesh/rdel_pred_delfront_2.hpp b/src/libcpp/rdel_mesh/rdel_pred_delfront_2.hpp index b357964..a10dae6 100644 --- a/src/libcpp/rdel_mesh/rdel_pred_delfront_2.hpp +++ b/src/libcpp/rdel_mesh/rdel_pred_delfront_2.hpp @@ -1,39 +1,39 @@ /* -------------------------------------------------------- - * RDEL-PRED-DELFRONT-2: "frontal-DEL" kernel in R^2. + * RDEL-PRED-DELFRONT-2: "frontal-DEL" kernel in R^2. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 22 August, 2018 + * Last updated: 10 July, 2019 * - * Copyright 2013-2018 + * Copyright 2013-2019 * Darren Engwirda * de2363@columbia.edu * https://github.com/dengwirda/ @@ -42,44 +42,44 @@ * * This class defines the behaviour of the "frontal" * restricted delaunay refinement scheme for meshes - * in R^2. Routines are provided to assess the - * "restricted-ness" of faces, to compute refinement + * in R^2. Routines are provided to assess the + * "restricted-ness" of faces, to compute refinement * "costs" (priorities), and to insert new vertices. * * My implementation is described in: * - * D. Engwirda and D. Ivers, (2016): Off-centre Steiner - * points for Delaunay-refinement on curved surfaces, - * Computer-Aided Design, 72, pp. 157-171, + * D. Engwirda and D. Ivers, (2016): Off-centre Steiner + * points for Delaunay-refinement on curved surfaces, + * Computer-Aided Design, 72, pp. 157-171, * http://dx.doi.org/10.1016/j.cad.2015.10.007 * - * D. Engwirda, (2016): "Conforming restricted Delaunay - * mesh generation for piecewise smooth complexes", - * Procedia Engineering, 163, pp. 84-96, + * D. Engwirda, (2016): "Conforming restricted Delaunay + * mesh generation for piecewise smooth complexes", + * Procedia Engineering, 163, pp. 84-96, * http://dx.doi.org/10.1016/j.proeng.2016.11.024 * * D. Engwirda, (2014): "Locally-optimal Delaunay- - * refinement and optimisation-based mesh generation", - * Ph.D. Thesis, School of Mathematics and Statistics, - * Univ. of Sydney. + * refinement and optimisation-based mesh generation", + * Ph.D. Thesis, School of Mathematics and Statistics, + * Univ. of Sydney. * http://hdl.handle.net/2123/13148 * * which is based on various previous works, including * (primarily): * - * J.D. Boissonnat, S. Oudot, (2005): "Provably Good - * Sampling and Meshing of Surfaces", Graphical Models, + * J.D. Boissonnat, S. Oudot, (2005): "Provably Good + * Sampling and Meshing of Surfaces", Graphical Models, * 67, pp. 405-451, * https://doi.org/10.1016/j.gmod.2005.01.004 * - * C. Jamin, P. Alliez, M. Yvinec, and J.D. Boissonnat, - * (2015): "CGALmesh: a generic framework for Delaunay - * mesh generation", ACM Transactions on Mathematical + * C. Jamin, P. Alliez, M. Yvinec, and J.D. Boissonnat, + * (2015): "CGALmesh: a generic framework for Delaunay + * mesh generation", ACM Transactions on Mathematical * Software (TOMS), 41, pp. 23 * https://doi.org/10.1145/2699463 * - * S.W. Cheng, T.K. Dey, E.A. Ramos, (2010): "Delaunay - * Refinement for Piecewise Smooth Complexes", + * S.W. Cheng, T.K. Dey, E.A. Ramos, (2010): "Delaunay + * Refinement for Piecewise Smooth Complexes", * Discrete & Computational Geometry, 43, pp. 121-166, * https://doi.org/10.1007/s00454-008-9109-3 * @@ -87,14 +87,14 @@ * of "off-centre" refinement rules - a generalisation * of ideas introduced in: * - * S. Rebay, (1993): "Efficient Unstructured Mesh - * Generation by Means of Delaunay Triangulation and - * the Bowyer-Watson Algorithm", J. Comp. Phys., 106, - * pp. 125-138 + * S. Rebay, (1993): "Efficient Unstructured Mesh + * Generation by Means of Delaunay Triangulation and + * the Bowyer-Watson Algorithm", J. Comp. Phys., 106, + * pp. 125-138 * https://doi.org/10.1006/jcph.1993.1097 * - * H. Erten, A. Üngör, (2009): "Quality Triangulations - * with Locally Optimal Steiner Points", SIAM J. Sci. + * H. Erten, A. Üngör, (2009): "Quality Triangulations + * with Locally Optimal Steiner Points", SIAM J. Sci. * Comp., 31, pp. 2103-2130, * https://doi.org/10.1137/080716748 * @@ -107,9 +107,9 @@ # define __RDEL_PRED_DELFRONT_2__ namespace mesh { - + # define __bias_BNDS // preference "bnd" faces - + template < typename G , typename H , @@ -119,50 +119,48 @@ public rdel_pred_base_2 { public : - + /*-------------- "frontal" delaunay refinement in R^2 */ - + typedef G geom_type ; typedef H hfun_type ; typedef M mesh_type ; - typedef typename + typedef typename mesh_type::real_type real_type ; - typedef typename + typedef typename mesh_type::iptr_type iptr_type ; - typedef mesh::rdel_params < - real_type , + typedef mesh::mesh_params < + real_type , iptr_type > rdel_opts ; typedef mesh::rdel_pred_base_2 < - geom_type , + geom_type , mesh_type > base_type ; typedef mesh::keep_minmax_length_2d < - real_type , + real_type , iptr_type > minmax_intersect ; - + typedef mesh::keep_minmax_cosine_2d < - real_type, + real_type, iptr_type > cosine_intersect ; - + /*------------------------ refinement priority types */ class edge_data { public : iptr_type _mark = +0; - iptr_type _imax = +0; - real_type _cost ; + float _cost ; } ; - + class tria_data { public : iptr_type _mark = +0; - iptr_type _imax = +0; - real_type _cost ; + float _cost ; } ; /*------------------------ refinement priority pred. */ @@ -172,88 +170,76 @@ edge_data const&_idat , edge_data const&_jdat ) - { + { if(_idat._mark == _jdat._mark ) - { - if(_idat._cost == _jdat._cost ) - return _idat._imax < - _jdat._imax ; - else - return _idat._cost > + return _idat._cost > _jdat._cost ; - } else - return _idat._mark < + return _idat._mark < _jdat._mark ; } - + __static_call __inline_call bool_type tria_pred ( tria_data const&_idat , tria_data const&_jdat ) - { + { if(_idat._mark == _jdat._mark ) - { - if(_idat._cost == _jdat._cost ) - return _idat._imax < - _jdat._imax ; - else - return _idat._cost > + return _idat._cost > _jdat._cost ; - } else - return _idat._mark < + return _idat._mark < _jdat._mark ; } - + /*------------------------ deterministic coord. hash */ - + __static_call __inline_call uint32_t hash_ball ( real_type*_ball ) { - uint32_t _rsiz = + uint32_t _rsiz = sizeof(real_type) * +2 ; - uint32_t _usiz = + uint32_t _usiz = sizeof(uint32_t ) * +1 ; - + uint32_t _hash ; _hash = hash::hashword ( (uint32_t*)_ball, _rsiz / _usiz, +13) ; - - return ( _hash ) ; + + return ( _hash ) ; } - + /* -------------------------------------------------------- * FACE-COST: calc. face refinement "cost". -------------------------------------------------------- - */ - + */ + #include "rdel_cost_delfront_2.inc" - - + + /* -------------------------------------------------------- * FACE-OFFH: form "size"-based off-centre. -------------------------------------------------------- - */ - + */ + #include "rdel_offh_delfront_2.inc" - - + + /* -------------------------------------------------------- * FACE-SINK: form "sink"-based off-centre. -------------------------------------------------------- - */ - + */ + #include "rdel_sink_delfront_2.inc" - - + + /* -------------------------------------------------------- * BASE-EDGE: TRUE if edge is "frontal". @@ -276,7 +262,7 @@ tria(_tpos)->node(_fnod[1]); algorithms::isort ( - &_fnod[0], &_fnod[2], + &_fnod[0], &_fnod[2], std::less()); typename mesh_type:: @@ -287,7 +273,7 @@ typename mesh_type:: edge_list:: item_type *_fptr = nullptr ; - if(_mesh.find_edge(_fdat,_fptr)) + if(_mesh.find_edge(_fdat,_fptr)) { return ( true ) ; } @@ -296,26 +282,26 @@ iptr_type _fadj = +0 ; iptr_type _tmrk = +0 ; _mesh. _tria.find_pair ( - _tpos, _tadj, + _tpos, _tadj, _fpos, _fadj, _tmrk) ; if (_tadj != _mesh._tria.null_flag()) { typename mesh_type:: tria_data _tdat ; - _tdat._node[0] = + _tdat._node[0] = _mesh._tria.tria(_tadj)->node(0); - _tdat._node[1] = + _tdat._node[1] = _mesh._tria.tria(_tadj)->node(1); - _tdat._node[2] = + _tdat._node[2] = _mesh._tria.tria(_tadj)->node(2); - + typename mesh_type:: tria_list:: item_type *_tptr = nullptr ; - if(_mesh.find_tria(_tdat,_tptr)) + if(_mesh.find_tria(_tdat,_tptr)) { - if (_tptr->_data._kind + if (_tptr->_data._kind == mesh::good_item) return ( true ) ; } @@ -327,15 +313,15 @@ return ( false ) ; } - + /* -------------------------------------------------------- * EDGE-NODE: compute edge-based steiner point. -------------------------------------------------------- */ - + __static_call - __normal_call + __normal_call typename rdel_opts::node_kind edge_node ( geom_type &_geom, hfun_type &_size, @@ -347,11 +333,11 @@ rdel_opts &_args ) { - typename rdel_opts::node_kind + typename rdel_opts::node_kind _kind = rdel_opts::null_kind ; __unreferenced(_edat); - + /*--------------------------- assemble local indexing */ iptr_type _enod[ +3] ; mesh_type::tria_type::tria_type:: @@ -367,14 +353,14 @@ real_type _ebal[ +3] ; real_type _pmax[ +3] ; if (!base_type::edge_ball ( - _geom, _mesh, _tadj, - _eadj, _ebal, _pmax, + _geom, _mesh, _tadj, + _eadj, _ebal, _pmax, _feat, _topo, _part) ) { /*--------------------------------- is not restricted */ - __assert( false && + __assert( false && "EDGE-NODE: interior facet!") ; - + return ( _kind ) ; } @@ -384,8 +370,8 @@ if(__chkbit(_args.rule(), rdel_opts ::offH_kind) ) - _kind = edge_offh( _geom, - _size, _mesh , _enod, + _kind = edge_offh( _geom, + _size, _mesh , _enod, _pmax, _ppos , _args) ; } if (_kind == rdel_opts::null_kind || @@ -394,22 +380,22 @@ /*----------------------- resort to circumball centre */ _ppos[0] = _pmax[0] ; _ppos[1] = _pmax[1] ; - + _kind = rdel_opts::circ_kind ; } /*----------------------- report point-placement kind */ return ( _kind ) ; } - + /* -------------------------------------------------------- * TRIA-NODE: compute tria-based steiner point. -------------------------------------------------------- */ - + __static_call - __normal_call + __normal_call typename rdel_opts::node_kind tria_node ( geom_type &_geom, hfun_type &_size, @@ -420,7 +406,7 @@ rdel_opts &_args ) { - typename rdel_opts::node_kind + typename rdel_opts::node_kind _kind = rdel_opts::null_kind ; __unreferenced(_geom) ; @@ -443,21 +429,21 @@ _tria.tria(_tpos)->circ(0); _tbal[1] = _mesh. _tria.tria(_tpos)->circ(1); - - _tbal[2] = (real_type)+0. ; - _tbal[2]+= - geometry::lensqr_2d (_tbal, + + _tbal[2] = (real_type)+0. ; + _tbal[2]+= + geometry::lensqr_2d (_tbal, &_mesh._tria.node( _tnod[0])->pval( 0)) ; - _tbal[2]+= - geometry::lensqr_2d (_tbal, + _tbal[2]+= + geometry::lensqr_2d (_tbal, &_mesh._tria.node( _tnod[1])->pval( 0)) ; - _tbal[2]+= - geometry::lensqr_2d (_tbal, + _tbal[2]+= + geometry::lensqr_2d (_tbal, &_mesh._tria.node( _tnod[2])->pval( 0)) ; - + _tbal[2]/= (real_type)+3. ; /*--------------------------------- find edge lengths */ @@ -474,74 +460,35 @@ _enod[1] = _mesh._tria. tria(_tpos)->node(_enod[ 1]); - _llen[_enum] = + _llen[_enum] = geometry::lensqr_2d ( &_mesh._tria. node(_enod[0])->pval(0), &_mesh._tria. node(_enod[1])->pval(0)) ; } - + /*--------------------------------- find min/max edge */ iptr_type _emin = (iptr_type)+0; iptr_type _emax = (iptr_type)+0; for(_enum = +3; _enum-- != +1; ) { - if (_llen[_emax] < _llen[_enum]) + if (_llen[_emax] < _llen[_enum]) _emax = _enum ; - if (_llen[_emin] > _llen[_enum]) + if (_llen[_emin] > _llen[_enum]) _emin = _enum ; } - - /*--------------------------------- hop to constraint */ - real_type _best = - std::numeric_limits - ::infinity () ; - - for(_enum = +3; _enum-- != +0; ) - { - iptr_type _enod[ +3]; - mesh_type::tria_type:: - tria_type:: - face_node(_enod, _enum, 2, 1); - _enod[ +0] = _mesh._tria. - tria(_tpos)->node(_enod[ 0]); - _enod[ +1] = _mesh._tria. - tria(_tpos)->node(_enod[ 1]); - - algorithms::isort( - &_enod[0] , &_enod[2] , - std::less()) ; - - typename mesh_type:: - edge_data _edat; - _edat._node[0] = _enod[0] ; - _edat._node[1] = _enod[1] ; - - typename mesh_type:: - edge_list:: - item_type *_eptr = nullptr ; - if (_mesh.find_edge(_edat,_eptr)) - { - if (_best > _llen[_enum]) - { - _emin = _enum; - - _best = _llen[_enum]; - } - } - } - - /*-------------------------- ask for "frontal" status */ + + /*-------------------------- ask for "frontal" status */ if(!base_edge(_mesh,_tpos,_emin)) { if (_tdat._mark <= +512) // finite cycles! // { /*---------------------- reject as "void" element */ - uint32_t _hash = + uint32_t _hash = hash_ball(_tbal) % +8u ; - - _tdat._mark += + + _tdat._mark += std::max(1u, _hash) ; return ( _kind ) ; @@ -551,7 +498,7 @@ /*----------------------------- just fall through */ } } - + /*--------------------------------- get face indexing */ iptr_type _enod [ +3]; mesh_type::tria_type::tria_type:: @@ -560,7 +507,7 @@ tria(_tpos)->node( _enod[0]) ; _enod[1] = _mesh._tria. tria(_tpos)->node( _enod[1]) ; - + /*----------------------------------- calc. edge-ball */ real_type _ebal [ +3]; geometry::circ_ball_2d(_ebal, @@ -577,26 +524,26 @@ _dvec[1] = _tbal[1] - _ebal[1] ; - _dvec[2] = + _dvec[2] = geometry::length_2d(_dvec) ; _dvec[0]/= _dvec[2] ; _dvec[1]/= _dvec[2] ; /*-------------------------- off-centre, a la "ungor" */ - _dvec[3] = + _dvec[3] = +std::numeric_limits ::infinity() ; - - real_type _elen = + + real_type _elen = _ebal[2] * (real_type)+4. ; - real_type _rtri = + real_type _rtri = std::sqrt(_elen) * _args.off2() ; - real_type _rfac = + real_type _rfac = std::sqrt(_elen) * (real_type)+.5 ; - + if (_rtri > _rfac ) _dvec[ 3] = _rtri + std::sqrt ( - _rtri * _rtri - + _rtri * _rtri - _rfac * _rfac ) ; if (_kind == rdel_opts::null_kind ) @@ -605,9 +552,9 @@ if(__chkbit(_args.rule(), rdel_opts ::offH_kind) ) - _kind = tria_offh( _geom, - _size , _mesh, _enod, - _ebal , _tbal, _dvec, + _kind = tria_offh( _geom, + _size , _mesh, _enod, + _ebal , _tbal, _dvec, _ppos , _args) ; } if (_kind == rdel_opts::null_kind || @@ -617,9 +564,9 @@ if(__chkbit(_args.rule(), rdel_opts ::sink_kind) ) - _kind = tria_sink( _geom, - _size , _mesh, - _tpos , _tnod, _tbal, + _kind = tria_sink( _geom, + _size , _mesh, + _tpos , _tnod, _tbal, _ppos , _args) ; } if (_kind == rdel_opts::null_kind || @@ -628,22 +575,22 @@ /*----------------------- resort to circumball centre */ _ppos[ 0] = _tbal[ 0] ; _ppos[ 1] = _tbal[ 1] ; - + _kind = rdel_opts::circ_kind ; } /*----------------------- report point-placement kind */ return ( _kind ) ; } - + } ; - + # undef __bias_BNDS - - + + } - + # endif //__RDEL_PRED_DELFRONT_2__ - - - + + + diff --git a/src/libcpp/rdel_mesh/rdel_pred_delfront_3.hpp b/src/libcpp/rdel_mesh/rdel_pred_delfront_3.hpp index 80c36c0..daa41bb 100644 --- a/src/libcpp/rdel_mesh/rdel_pred_delfront_3.hpp +++ b/src/libcpp/rdel_mesh/rdel_pred_delfront_3.hpp @@ -1,39 +1,39 @@ /* -------------------------------------------------------- - * RDEL-PRED-DELFRONT-3: "frontal-DEL" kernel in R^3. + * RDEL-PRED-DELFRONT-3: "frontal-DEL" kernel in R^3. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 22 August, 2018 + * Last updated: 10 July, 2019 * - * Copyright 2013-2018 + * Copyright 2013-2019 * Darren Engwirda * de2363@columbia.edu * https://github.com/dengwirda/ @@ -42,44 +42,44 @@ * * This class defines the behaviour of the "frontal" * restricted delaunay refinement scheme for meshes - * in R^3. Routines are provided to assess the - * "restricted-ness" of faces, to compute refinement + * in R^3. Routines are provided to assess the + * "restricted-ness" of faces, to compute refinement * "costs" (priorities), and to insert new vertices. * * My implementation is described in: * - * D. Engwirda and D. Ivers, (2016): Off-centre Steiner - * points for Delaunay-refinement on curved surfaces, - * Computer-Aided Design, 72, pp. 157-171, + * D. Engwirda and D. Ivers, (2016): Off-centre Steiner + * points for Delaunay-refinement on curved surfaces, + * Computer-Aided Design, 72, pp. 157-171, * http://dx.doi.org/10.1016/j.cad.2015.10.007 * - * D. Engwirda, (2016): "Conforming restricted Delaunay - * mesh generation for piecewise smooth complexes", - * Procedia Engineering, 163, pp. 84-96, + * D. Engwirda, (2016): "Conforming restricted Delaunay + * mesh generation for piecewise smooth complexes", + * Procedia Engineering, 163, pp. 84-96, * http://dx.doi.org/10.1016/j.proeng.2016.11.024 * * D. Engwirda, (2014): "Locally-optimal Delaunay- - * refinement and optimisation-based mesh generation", - * Ph.D. Thesis, School of Mathematics and Statistics, - * Univ. of Sydney. + * refinement and optimisation-based mesh generation", + * Ph.D. Thesis, School of Mathematics and Statistics, + * Univ. of Sydney. * http://hdl.handle.net/2123/13148 * * which is based on various previous works, including * (primarily): * - * J.D. Boissonnat, S. Oudot, (2005): "Provably Good - * Sampling and Meshing of Surfaces", Graphical Models, + * J.D. Boissonnat, S. Oudot, (2005): "Provably Good + * Sampling and Meshing of Surfaces", Graphical Models, * 67, pp. 405-451, * https://doi.org/10.1016/j.gmod.2005.01.004 * - * C. Jamin, P. Alliez, M. Yvinec, and J.D. Boissonnat, - * (2015): "CGALmesh: a generic framework for Delaunay - * mesh generation", ACM Transactions on Mathematical + * C. Jamin, P. Alliez, M. Yvinec, and J.D. Boissonnat, + * (2015): "CGALmesh: a generic framework for Delaunay + * mesh generation", ACM Transactions on Mathematical * Software (TOMS), 41, pp. 23 * https://doi.org/10.1145/2699463 * - * S.W. Cheng, T.K. Dey, E.A. Ramos, (2010): "Delaunay - * Refinement for Piecewise Smooth Complexes", + * S.W. Cheng, T.K. Dey, E.A. Ramos, (2010): "Delaunay + * Refinement for Piecewise Smooth Complexes", * Discrete & Computational Geometry, 43, pp. 121-166, * https://doi.org/10.1007/s00454-008-9109-3 * @@ -87,14 +87,14 @@ * of "off-centre" refinement rules - a generalisation * of ideas introduced in: * - * S. Rebay, (1993): "Efficient Unstructured Mesh - * Generation by Means of Delaunay Triangulation and - * the Bowyer-Watson Algorithm", J. Comp. Phys., 106, - * pp. 125-138 + * S. Rebay, (1993): "Efficient Unstructured Mesh + * Generation by Means of Delaunay Triangulation and + * the Bowyer-Watson Algorithm", J. Comp. Phys., 106, + * pp. 125-138 * https://doi.org/10.1006/jcph.1993.1097 * - * H. Erten, A. Üngör, (2009): "Quality Triangulations - * with Locally Optimal Steiner Points", SIAM J. Sci. + * H. Erten, A. Üngör, (2009): "Quality Triangulations + * with Locally Optimal Steiner Points", SIAM J. Sci. * Comp., 31, pp. 2103-2130, * https://doi.org/10.1137/080716748 * @@ -107,9 +107,9 @@ # define __RDEL_PRED_DELFRONT_3__ namespace mesh { - + # define __bias_BNDS // preference "bnd" faces - + template < typename G , typename H , @@ -119,57 +119,54 @@ public rdel_pred_base_3 { public : - + /*-------------- "frontal" delaunay refinement in R^3 */ - + typedef G geom_type ; typedef H hfun_type ; typedef M mesh_type ; - typedef typename + typedef typename mesh_type::real_type real_type ; - typedef typename + typedef typename mesh_type::iptr_type iptr_type ; - typedef mesh::rdel_params < - real_type, + typedef mesh::mesh_params < + real_type, iptr_type > rdel_opts ; - + typedef mesh::rdel_pred_base_3 < - geom_type , + geom_type , mesh_type > base_type ; typedef mesh::keep_minmax_length_3d < - real_type, + real_type, iptr_type > minmax_intersect ; typedef mesh::keep_minmax_cosine_3d < - real_type, + real_type, iptr_type > cosine_intersect ; - + /*------------------------ refinement priority types */ - + class edge_data { public : iptr_type _mark = +0; - iptr_type _imax = +0; - real_type _cost ; + float _cost ; } ; - + class face_data { public : iptr_type _mark = +0; - iptr_type _imax = +0; - real_type _cost ; + float _cost ; } ; - + class tria_data { public : iptr_type _mark = +0; - iptr_type _imax = +0; - real_type _cost ; + float _cost ; } ; /*------------------------ refinement priority pred. */ @@ -179,114 +176,96 @@ edge_data const&_idat , edge_data const&_jdat ) - { + { if(_idat._mark == _jdat._mark ) - { - if(_idat._cost == _jdat._cost ) - return _idat._imax < - _jdat._imax ; - else - return _idat._cost > + return _idat._cost > _jdat._cost ; - } else - return _idat._mark < + return _idat._mark < _jdat._mark ; } - + __static_call __inline_call bool_type face_pred ( face_data const&_idat , face_data const&_jdat ) - { + { if(_idat._mark == _jdat._mark ) - { - if(_idat._cost == _jdat._cost ) - return _idat._imax < - _jdat._imax ; - else - return _idat._cost > + return _idat._cost > _jdat._cost ; - } else - return _idat._mark < + return _idat._mark < _jdat._mark ; } - + __static_call __inline_call bool_type tria_pred ( tria_data const&_idat , tria_data const&_jdat ) - { + { if(_idat._mark == _jdat._mark ) - { - if(_idat._cost == _jdat._cost ) - return _idat._imax < - _jdat._imax ; - else - return _idat._cost > + return _idat._cost > _jdat._cost ; - } else - return _idat._mark < + return _idat._mark < _jdat._mark ; } - + /*------------------------ deterministic coord. hash */ - + __static_call __inline_call uint32_t hash_ball ( real_type*_ball ) { - uint32_t _rsiz = + uint32_t _rsiz = sizeof(real_type) * +3 ; - uint32_t _usiz = + uint32_t _usiz = sizeof(uint32_t ) * +1 ; - + uint32_t _hash ; _hash = hash::hashword ( (uint32_t*)_ball, _rsiz / _usiz, +13) ; - - return ( _hash ) ; + + return ( _hash ) ; } /* -------------------------------------------------------- * FACE-COST: calc. face refinement "cost". -------------------------------------------------------- - */ - + */ + #include "rdel_cost_delfront_3.inc" - - + + /* -------------------------------------------------------- * FACE-OFFH: form "size"-based off-centre. -------------------------------------------------------- - */ - + */ + #include "rdel_offh_delfront_3.inc" - - + + /* -------------------------------------------------------- * FACE-SINK: form "sink"-based off-centre. -------------------------------------------------------- - */ - + */ + #include "rdel_sink_delfront_3.inc" - - + + /* -------------------------------------------------------- * BASE-EDGE: TRUE if edge is "frontal". -------------------------------------------------------- */ - + template < typename list_type > @@ -303,23 +282,23 @@ _edat._node[1] = _enod[1] ; algorithms::isort ( - _edat._node.head(), - _edat._node.tend(), + _edat._node.head(), + _edat._node.tend(), std::less()) ; typename mesh_type:: edge_list:: item_type *_eptr = nullptr ; - if (_mesh.find_edge(_edat,_eptr)) + if (_mesh.find_edge(_edat,_eptr)) { - if (_eptr->_data._kind + if (_eptr->_data._kind == mesh::good_item ) return ( true ) ; } iptr_type _fpos ; - for (auto _tpos = _tset.head(); - _tpos != _tset.tend(); + for (auto _tpos = _tset.head(); + _tpos != _tset.tend(); ++_tpos ) { for (_fpos = +4 ; _fpos-- != +0; ) @@ -346,7 +325,7 @@ _fnod[2] == _enod[1] ) _same += +1; if (_same != +2) continue ; - + if (_mesh._tria. node(_fnod[0])->fdim() > +2 || _mesh._tria. @@ -357,7 +336,7 @@ if (_same != +2) continue ; algorithms::isort ( - &_fnod[0], &_fnod[3], + &_fnod[0], &_fnod[3], std::less ()); typename mesh_type:: @@ -369,9 +348,9 @@ typename mesh_type:: face_list:: item_type *_fptr = nullptr ; - if (_mesh.find_face(_fdat,_fptr)) + if (_mesh.find_face(_fdat,_fptr)) { - if (_fptr->_data._kind + if (_fptr->_data._kind == mesh::good_item ) return ( true ) ; } @@ -380,13 +359,13 @@ return ( false ) ; } - + /* -------------------------------------------------------- * BASE-FACE: TRUE if face is "frontal". -------------------------------------------------------- */ - + __static_call __normal_call bool_type base_face ( mesh_type &_mesh, @@ -405,7 +384,7 @@ tria(_tpos)->node(_fnod[2]); algorithms::isort ( - &_fnod[0], &_fnod[3], + &_fnod[0], &_fnod[3], std::less()); typename mesh_type:: @@ -417,7 +396,7 @@ typename mesh_type:: face_list:: item_type *_fptr = nullptr ; - if(_mesh.find_face(_fdat,_fptr)) + if(_mesh.find_face(_fdat,_fptr)) { return ( true ) ; } @@ -433,21 +412,21 @@ { typename mesh_type:: tria_data _tdat ; - _tdat._node[0] = + _tdat._node[0] = _mesh._tria.tria(_tadj)->node(0); - _tdat._node[1] = + _tdat._node[1] = _mesh._tria.tria(_tadj)->node(1); - _tdat._node[2] = + _tdat._node[2] = _mesh._tria.tria(_tadj)->node(2); - _tdat._node[3] = + _tdat._node[3] = _mesh._tria.tria(_tadj)->node(3); typename mesh_type:: tria_list:: item_type *_tptr = nullptr ; - if(_mesh.find_tria(_tdat,_tptr)) + if(_mesh.find_tria(_tdat,_tptr)) { - if (_tptr->_data._kind + if (_tptr->_data._kind == mesh::good_item) return ( true ) ; } @@ -459,15 +438,15 @@ return ( false ) ; } - + /* -------------------------------------------------------- * EDGE-NODE: compute edge-based steiner point. -------------------------------------------------------- */ - + __static_call - __normal_call + __normal_call typename rdel_opts::node_kind edge_node ( geom_type &_geom, hfun_type &_size, @@ -479,11 +458,11 @@ rdel_opts &_args ) { - typename rdel_opts::node_kind + typename rdel_opts::node_kind _kind = rdel_opts::null_kind ; __unreferenced(_edat); - + /*--------------------------- assemble local indexing */ iptr_type _enod[ +4] ; mesh_type::tria_type::tria_type:: @@ -498,16 +477,16 @@ iptr_type _part; real_type _ebal[ +4] ; real_type _pmax[ +4] ; - if (!base_type::edge_ball ( - _geom, _mesh, _tadj, - _eadj, _ebal, - _pmax, _hits, + if (!base_type::edge_ball ( + _geom, _mesh, _tadj, + _eadj, _ebal, + _pmax, _hits, _feat, _topo, _part) ) { /*--------------------------------- is not restricted */ - __assert( false && + __assert( false && "EDGE-NODE: interior facet!") ; - + return ( _kind ) ; } @@ -517,8 +496,8 @@ if(__chkbit(_args.rule(), rdel_opts ::offH_kind) ) - _kind = edge_offh( _geom, - _size , _mesh, _enod, + _kind = edge_offh( _geom, + _size , _mesh, _enod, _pmax , _ppos, _args) ; } if (_kind == rdel_opts::null_kind || @@ -535,15 +514,15 @@ /*----------------------- report point-placement kind */ return ( _kind ) ; } - + /* -------------------------------------------------------- * FACE-NODE: compute face-based steiner point. -------------------------------------------------------- */ - + __static_call - __normal_call + __normal_call typename rdel_opts::node_kind face_node ( geom_type &_geom, hfun_type &_size, @@ -555,7 +534,7 @@ rdel_opts &_args ) { - typename rdel_opts::node_kind + typename rdel_opts::node_kind _kind = rdel_opts::null_kind ; /*--------------------------- assemble local indexing */ @@ -574,15 +553,15 @@ iptr_type _part; real_type _fbal[ +4] ; real_type _pmax[ +4] ; - if (!base_type::face_ball ( - _geom, _mesh, _tadj, - _fadj, _fbal, _pmax, + if (!base_type::face_ball ( + _geom, _mesh, _tadj, + _fadj, _fbal, _pmax, _feat, _topo, _part) ) { /*--------------------------------- is not restricted */ - __assert( false && + __assert( false && "FACE-NODE: interior facet!") ; - + return ( _kind ) ; } @@ -598,62 +577,25 @@ _enod[ 0] = _fnod[_enod[0]] ; _enod[ 1] = _fnod[_enod[1]] ; - _llen[_enum] = + _llen[_enum] = geometry::lensqr_3d ( &_mesh._tria. node(_enod[0])->pval(0), &_mesh._tria. node(_enod[1])->pval(0)) ; } - + /*--------------------------------- find min/max edge */ iptr_type _emin = (iptr_type)+0; iptr_type _emax = (iptr_type)+0; for(_enum = +3; _enum-- != +1; ) { - if (_llen[_emax] < _llen[_enum]) + if (_llen[_emax] < _llen[_enum]) _emax = _enum ; - if (_llen[_emin] > _llen[_enum]) + if (_llen[_emin] > _llen[_enum]) _emin = _enum ; } - - /*--------------------------------- hop to constraint */ - real_type _best = - std::numeric_limits - ::infinity () ; - - for(_enum = +3; _enum-- != +0; ) - { - iptr_type _enod[ +3]; - mesh_type::tria_type:: - tria_type:: - face_node(_enod, _enum, 2, 1) ; - _enod[0] = _fnod[_enod[ 0]] ; - _enod[1] = _fnod[_enod[ 1]] ; - - algorithms::isort( - &_enod[0], &_enod[2], - std::less()) ; - - typename mesh_type:: - edge_data _edat ; - _edat._node[0] = _enod[0]; - _edat._node[1] = _enod[1]; - - typename mesh_type:: - edge_list:: - item_type *_eptr = nullptr ; - if (_mesh.find_edge(_edat,_eptr)) - { - if (_best > _llen[_enum]) - { - _emin = _enum; - - _best = _llen[_enum]; - } - } - } - + /*--------------------------------- pop edge indexing */ iptr_type _enod[ +3]; mesh_type::tria_type::tria_type:: @@ -661,24 +603,24 @@ _enod[0] = _fnod[_enod[ 0]]; _enod[1] = _fnod[_enod[ 1]]; _enod[2] = _fnod[_enod[ 2]]; - + containers ::array _tset ; _tset.set_alloc(8) ; - base_type::edge_loop ( _mesh , - _enod, _tadj , + base_type::edge_loop ( _mesh , + _enod, _tadj , _fadj, _tset ) ; - - /*-------------------------- ask for "frontal" status */ + + /*-------------------------- ask for "frontal" status */ if(!base_edge(_mesh, _enod, _tset)) { if (_fdat._mark <= +512) // finite cycles! // { /*---------------------- reject as "void" element */ - uint32_t _hash = + uint32_t _hash = hash_ball(_pmax) % +8u ; - - _fdat._mark += + + _fdat._mark += std::max(1u, _hash) ; return ( _kind ) ; @@ -692,30 +634,30 @@ /*--------------------------------- eval edge metrics */ real_type _evec[4] = { _mesh. - _tria.node(_enod[1])->pval(0) - + _tria.node(_enod[1])->pval(0) - _mesh. _tria.node(_enod[0])->pval(0) , _mesh. - _tria.node(_enod[1])->pval(1) - + _tria.node(_enod[1])->pval(1) - _mesh. _tria.node(_enod[0])->pval(1) , _mesh. - _tria.node(_enod[1])->pval(2) - + _tria.node(_enod[1])->pval(2) - _mesh. _tria.node(_enod[0])->pval(2) } ; real_type _pmid[3] = { _mesh. - _tria.node(_enod[0])->pval(0) + + _tria.node(_enod[0])->pval(0) + _mesh. _tria.node(_enod[1])->pval(0) , - _mesh. - _tria.node(_enod[0])->pval(1) + + _mesh. + _tria.node(_enod[0])->pval(1) + _mesh. _tria.node(_enod[1])->pval(1) , _mesh. - _tria.node(_enod[0])->pval(2) + + _tria.node(_enod[0])->pval(2) + _mesh. _tria.node(_enod[1])->pval(2) } ; @@ -723,40 +665,40 @@ _pmid[ 0]*= (real_type) +.5 ; _pmid[ 1]*= (real_type) +.5 ; _pmid[ 2]*= (real_type) +.5 ; - + real_type _dvec[ +5] ; _dvec[ 0] = _pmax[0] - _pmid[0] ; - _dvec[ 1] = _pmax[1] - + _dvec[ 1] = _pmax[1] - _pmid[1] ; - _dvec[ 2] = _pmax[2] - + _dvec[ 2] = _pmax[2] - _pmid[2] ; - _evec[ 3] = + _evec[ 3] = geometry::length_3d(_evec) ; _evec[ 0]/= _evec[3] ; _evec[ 1]/= _evec[3] ; _evec[ 2]/= _evec[3] ; - - _dvec[ 3] = + + _dvec[ 3] = geometry::length_3d(_dvec) ; _dvec[ 0]/= _dvec[3] ; _dvec[ 1]/= _dvec[3] ; _dvec[ 2]/= _dvec[3] ; /*-------------------------- off-centre, a la "ungor" */ - _dvec[4] = + _dvec[4] = +std::numeric_limits ::infinity() ; - - real_type _rtri = + + real_type _rtri = _evec[3] * _args.off2() ; - real_type _rfac = + real_type _rfac = _evec[3] * (real_type)+.5 ; - + if (_rtri > _rfac) _dvec[ 4] = _rtri + std::sqrt ( - _rtri * _rtri - + _rtri * _rtri - _rfac * _rfac); if (_kind == rdel_opts::null_kind ) @@ -765,10 +707,10 @@ if(__chkbit(_args.rule(), rdel_opts ::offH_kind) ) - _kind = face_offh( _geom, - _size , _mesh, _enod, - _pmid , _evec, _dvec, - _pmax , + _kind = face_offh( _geom, + _size , _mesh, _enod, + _pmid , _evec, _dvec, + _pmax , _ppos , _args) ; } if (_kind == rdel_opts::null_kind || @@ -778,18 +720,18 @@ if(__chkbit(_args.rule(), rdel_opts ::sink_kind) ) - _kind = face_sink( _geom, - _size , _mesh, _tadj, - _enod , _pmax, + _kind = face_sink( _geom, + _size , _mesh, _tadj, + _enod , _pmax, _ppos , _args) ; } if (_kind == rdel_opts::null_kind || _kind == rdel_opts::circ_kind ) { /*----------------------- resort to circumball centre */ - _ppos[0] = _pmax[0] ; - _ppos[1] = _pmax[1] ; - _ppos[2] = _pmax[2] ; + _ppos[ 0] = _pmax[ 0] ; + _ppos[ 1] = _pmax[ 1] ; + _ppos[ 2] = _pmax[ 2] ; _kind = rdel_opts::circ_kind ; } @@ -797,15 +739,15 @@ /*----------------------- report point-placement kind */ return ( _kind ) ; } - + /* -------------------------------------------------------- * TRIA-NODE: compute tria-based steiner point. -------------------------------------------------------- */ - + __static_call - __normal_call + __normal_call typename rdel_opts::node_kind tria_node ( geom_type &_geom, hfun_type &_size, @@ -816,7 +758,7 @@ rdel_opts &_args ) { - typename rdel_opts::node_kind + typename rdel_opts::node_kind _kind = rdel_opts::null_kind ; __unreferenced(_geom) ; @@ -843,25 +785,25 @@ _tria.tria(_tpos)->circ(1); _tbal[2] = _mesh. _tria.tria(_tpos)->circ(2); - - _tbal[3] = (real_type)+0. ; - _tbal[3]+= - geometry::lensqr_3d (_tbal, + + _tbal[3] = (real_type)+0. ; + _tbal[3]+= + geometry::lensqr_3d (_tbal, &_mesh._tria.node( _tnod[0])->pval( 0)) ; - _tbal[3]+= - geometry::lensqr_3d (_tbal, + _tbal[3]+= + geometry::lensqr_3d (_tbal, &_mesh._tria.node( _tnod[1])->pval( 0)) ; - _tbal[3]+= - geometry::lensqr_3d (_tbal, + _tbal[3]+= + geometry::lensqr_3d (_tbal, &_mesh._tria.node( _tnod[2])->pval( 0)) ; - _tbal[3]+= - geometry::lensqr_3d (_tbal, + _tbal[3]+= + geometry::lensqr_3d (_tbal, &_mesh._tria.node( _tnod[3])->pval( 0)) ; - + _tbal[3]/= (real_type)+4. ; /*--------------------------------- find edge lengths */ @@ -878,25 +820,25 @@ _enod[1] = _mesh._tria. tria(_tpos)->node(_enod[ 1]); - _llen[_enum] = + _llen[_enum] = geometry::lensqr_3d ( &_mesh._tria. node(_enod[0])->pval(0), &_mesh._tria. node(_enod[1])->pval(0)) ; } - + /*--------------------------------- find min/max edge */ iptr_type _emin = (iptr_type)+0; iptr_type _emax = (iptr_type)+0; for(_enum = +6; _enum-- != +1; ) { - if (_llen[_emax] < _llen[_enum]) + if (_llen[_emax] < _llen[_enum]) _emax = _enum ; - if (_llen[_emin] > _llen[_enum]) + if (_llen[_emin] > _llen[_enum]) _emin = _enum ; } - + /*--------------------------------- find 2-face radii */ real_type _frad[4] ; iptr_type _fpos ; @@ -914,83 +856,38 @@ tria(_tpos)->node(_fnod[ 2]); real_type _fbal [ +4]; - geometry::circ_ball_3d(_fbal, - &_mesh._tria. - node(_fnod[0])->pval(0), - &_mesh._tria. - node(_fnod[1])->pval(0), - &_mesh._tria. - node(_fnod[2])->pval(0)); - - real_type _blen = geometry:: - lensqr_3d(_fbal, _tbal); - - _frad[_fpos] = _fbal[3] / _blen ; + geometry::circ_ball_3d(_fbal , + &_mesh._tria. + node(_fnod[0])->pval(0), + &_mesh._tria. + node(_fnod[1])->pval(0), + &_mesh._tria. + node(_fnod[2])->pval(0)) ; + + _frad[_fpos] = _fbal[3]; } - + /*--------------------------------- find min/max face */ iptr_type _fmin = (iptr_type)+0; iptr_type _fmax = (iptr_type)+0; for(_fpos = +4; _fpos-- != +1; ) { - if (_frad[_fmax] < _frad[_fpos]) + if (_frad[_fmax] < _frad[_fpos]) _fmax = _fpos ; - if (_frad[_fmin] > _frad[_fpos]) + if (_frad[_fmin] > _frad[_fpos]) _fmin = _fpos ; } - - /*--------------------------------- hop to constraint */ - real_type _best = - std::numeric_limits - ::infinity () ; - - for(_fpos = +4; _fpos-- != +0; ) - { - iptr_type _fnod[ +4]; - mesh_type::tria_type:: - tria_type:: - face_node(_fnod, _fpos, 3, 2); - _fnod[ +0] = _mesh._tria. - tria(_tpos)->node(_fnod[ 0]); - _fnod[ +1] = _mesh._tria. - tria(_tpos)->node(_fnod[ 1]); - _fnod[ +2] = _mesh._tria. - tria(_tpos)->node(_fnod[ 2]); - - algorithms::isort( - &_fnod[0], &_fnod[3], - std::less()) ; - - typename mesh_type:: - face_data _fdat; - _fdat._node[0] = _fnod[0] ; - _fdat._node[1] = _fnod[1] ; - _fdat._node[2] = _fnod[2] ; - - typename mesh_type:: - face_list:: - item_type *_fptr = nullptr ; - if (_mesh.find_face(_fdat,_fptr)) - { - if (_best > _frad[_fpos]) - { - _fmin = _fpos ; - - _best = _frad[_fpos]; - } - } - } - - /*-------------------------- ask for "frontal" status */ + + /*-------------------------- ask for "frontal" status */ if(!base_face(_mesh,_tpos,_fmin)) { if (_tdat._mark <= +512) // finite cycles! // { /*---------------------- reject as "void" element */ - uint32_t _hash = + uint32_t _hash = hash_ball(_tbal) % +8u ; - - _tdat._mark += + + _tdat._mark += std::max(1u, _hash) ; return ( _kind ) ; @@ -1046,39 +943,39 @@ _fbal[0] ; _dvec[1] = _tbal[1] - _fbal[1] ; - _dvec[2] = _tbal[2] - + _dvec[2] = _tbal[2] - _fbal[2] ; - _dvec[3] = + _dvec[3] = geometry::length_3d (_dvec) ; _dvec[0]/= _dvec[3] ; _dvec[1]/= _dvec[3] ; _dvec[2]/= _dvec[3] ; /*------------------------- off-centre - a'la "ungor" */ - _dvec[4] = + _dvec[4] = std::numeric_limits ::infinity() ; - - real_type _rfac = + + real_type _rfac = std::sqrt(_fbal[ +3]) ; - real_type _rtri = + real_type _rtri = std::sqrt(_elen) * _args.off3() ; if (_rtri > _rfac) _dvec[4] = _rtri + std::sqrt ( - _rtri * _rtri - + _rtri * _rtri - _rfac * _rfac); - + if (_kind == rdel_opts::null_kind ) { /*----------------------- attempt offcentre placement */ if(__chkbit(_args.rule(), rdel_opts ::offH_kind) ) - _kind = tria_offh( _geom, - _size , _mesh, _fnod, - _fbal , _tbal, _dvec, + _kind = tria_offh( _geom, + _size , _mesh, _fnod, + _fbal , _tbal, _dvec, _ppos , _args) ; } if (_kind == rdel_opts::null_kind || @@ -1088,34 +985,49 @@ if(__chkbit(_args.rule(), rdel_opts ::sink_kind) ) - _kind = tria_sink( _geom, - _size , _mesh, - _tpos , _tnod, _tbal, + _kind = tria_sink( _geom, + _size , _mesh, + _tpos , _tnod, _tbal, _ppos , _args) ; } if (_kind == rdel_opts::null_kind || _kind == rdel_opts::circ_kind ) { /*----------------------- resort to circumball centre */ + if (_tdat._mark <= +8 ) + { + /*---------------------- reject as "void" element */ + uint32_t _hash = + hash_ball(_tbal) % +8u; + + _tdat._mark += + std::max(1u, _hash) ; + + _kind = rdel_opts::null_kind ; + } + else + { + /*---------------------- take circumcentre direct */ _ppos[ 0] = _tbal[ 0] ; _ppos[ 1] = _tbal[ 1] ; _ppos[ 2] = _tbal[ 2] ; - _kind = rdel_opts::circ_kind ; + _kind = rdel_opts::circ_kind ; + } } /*----------------------- report point-placement kind */ return ( _kind ) ; } - + } ; - + # undef __bias_BNDS - - + + } - + # endif //__RDEL_PRED_DELFRONT_3__ - - - + + + diff --git a/src/libcpp/rdel_mesh/rdel_refine_ball_2.inc b/src/libcpp/rdel_mesh/rdel_refine_ball_2.inc index 255e137..2698d32 100644 --- a/src/libcpp/rdel_mesh/rdel_refine_ball_2.inc +++ b/src/libcpp/rdel_mesh/rdel_refine_ball_2.inc @@ -1,32 +1,32 @@ /* -------------------------------------------------------- - * RDEL-REFINE-2: refine restricted subfaces in R^2. + * RDEL-REFINE-2: refine restricted subfaces in R^2. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- @@ -40,18 +40,18 @@ * -------------------------------------------------------- */ - + // from rdel_mesh_2.hpp - - + + /* -------------------------------------------------------- * _BAD-BALL: refine a "bad" ball. -------------------------------------------------------- */ - __static_call - __normal_call + __static_call + __normal_call typename rdel_opts::node_kind _bad_ball ( geom_type &_geom , hfun_type &_hfun , @@ -78,11 +78,11 @@ { /*--------------------- find adj. set of tria-to-node */ public : - + typedef typename mesh_type::tria_type tria_type ; - public : + public : iptr_type _npos; public : @@ -93,9 +93,9 @@ __inline_call bool_type operator() ( tria_type&_tria, iptr_type _tpos, - iptr_type _fpos - ) - { + iptr_type _fpos + ) + { iptr_type _tnod[3] = { _tria.tria(_tpos)->node(0) , _tria.tria(_tpos)->node(1) , @@ -110,16 +110,16 @@ return true ; if (_tnod[2] == this->_npos) return true ; - + return false ; } } ; - - typename rdel_opts::node_kind + + typename rdel_opts::node_kind _kind = rdel_opts::null_kind ; - + __unreferenced( _hfun) ; - __unreferenced( _mode) ; + __unreferenced( _mode) ; __unreferenced( _tdim) ; __unreferenced( _pass) ; __unreferenced( _args) ; @@ -128,22 +128,22 @@ _nold.set_count( +0 ) ; _tnew.set_count( +0 ) ; _told.set_count( +0 ) ; - + _eold.set_count( +0 ) ; _escr.set_count( +0 ) ; _ecav.set_count( +0 ) ; _tscr.set_count( +0 ) ; _tcav.set_count( +0 ) ; - + _bcav.set_count( +0 ) ; _bscr.set_count( +0 ) ; - + /*--------------------- pop() leading element from PQ */ typename mesh_type:: ball_list:: item_type*_bptr = nullptr; ball_data _ball ; - + bool_type _find = false; for ( ; !_nbpq.empty() ; ) { @@ -160,51 +160,51 @@ } } if ( !_find ) return _kind ; - - /*--------------------- check dist. to existing nodes */ - real_type static const _HTOL = + + /*--------------------- check dist. to existing nodes */ + real_type static const _HTOL = (real_type) +.333 * .333 ; - - real_type static const _STOL = + + real_type static const _STOL = (real_type) +.500 * .500 ; - + iptr_list _tset; _tset.set_alloc( +32) ; - - iptr_type _nadj = + + iptr_type _nadj = _ball._node [ 0] ; - + _mesh._tria.walk_node ( - _nadj, + _nadj, node_pred(_nadj), _tset) ; - - real_type _rmax = + + real_type _rmax = _ball._ball [ 2] ; - for (auto _tpos = _tset.head() ; + for (auto _tpos = _tset.head() ; _tpos != _tset.tend() ; ++_tpos ) { iptr_type _npos; for (_npos = +3; _npos-- != +0; ) { - iptr_type _node = + iptr_type _node = _mesh._tria. tria(*_tpos)->node(_npos) ; - + if (_node == _nadj) continue; - - iptr_type _feat = + + iptr_type _feat = _mesh. _tria.node(_node)->feat() ; - - real_type _dsqr = + + real_type _dsqr = geometry::lensqr_2d ( &_mesh._tria. node(_nadj)->pval(0) , &_mesh._tria. node(_node)->pval(0) ) ; - + if (_feat == hard_feat) { _rmax = std::min ( @@ -214,57 +214,57 @@ { _rmax = std::min ( _rmax, _STOL * _dsqr) ; - } - } + } + } } - + /*--------------------- otherwise push "collar" nodes */ _ball._ball[2] = std:: min ( _ball._ball[2],_rmax) ; _ball._ball[2] = std::sqrt ( _ball._ball [ 2]) ; - - iptr_type _ndeg = + + iptr_type _ndeg = _mesh._tria. node(_nadj)->topo() ; - - /*--------------------- find intersections with GEOM. */ + + /*--------------------- find intersections with GEOM. */ typename geom_type::ball_type _pdat, _hdat ; _pdat._pmid[0] = _ball._ball[0] ; _pdat._pmid[1] = _ball._ball[1] ; - + _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 ; - + for (auto _iter = 32; _iter-- != 0 ; ) - { - bool_type _okay = true; - + { + bool_type _okay = true; + _pred.clear() ; _halo.clear() ; - - _pdat._rrad = + + _pdat._rrad = (real_type)+1.0 * _ball._ball[2] ; - - _hdat._rrad = + + _hdat._rrad = (real_type)+1.5 * _ball._ball[2] ; - + _bptr->_data._ball[2] = // save to mesh "proper" - (real_type)+1.0 * _ball._ball[2] + (real_type)+1.0 * _ball._ball[2] * _ball._ball[2] ; - + _okay = _okay & _geom.intersect ( _pdat, _pred) ; // actual! - + if(!_okay) { _ball._ball[2] *= // reduce R for GEOM. @@ -278,10 +278,10 @@ (real_type) +.67 ; continue ; } - + _okay = _okay & _geom.intersect ( _hdat, _halo) ; // bracket - + if(!_okay) { _ball._ball[2] *= // reduce R for GEOM. @@ -296,8 +296,8 @@ continue ; } else break ; - } - + } + return ( _kind ) ; } @@ -306,13 +306,13 @@ * INIT-BALL: setup ball "collar". -------------------------------------------------------- */ - - __static_call + + __static_call __normal_call void_type init_ball ( geom_type &_geom , hfun_type &_hfun , mesh_type &_mesh , - typename + typename mesh_type::edge_list &_epro , iptr_type _mode , iptr_type _pass , @@ -324,75 +324,75 @@ __unreferenced(_mode) ; __unreferenced(_pass) ; __unreferenced(_args) ; - - for (auto _bpos = + + for (auto _bpos = _mesh._bset._lptr.head () ; - _bpos != + _bpos != _mesh._bset._lptr.tend () ; ++_bpos ) { if ( *_bpos == nullptr) continue ; - + for (auto _ball = *_bpos ; _ball != nullptr; _ball = _ball->_next ) { - + typename geom_type::ball_type _hdat ; - _hdat._pmid[0] = + _hdat._pmid[0] = _ball->_data._ball[0] ; - _hdat._pmid[1] = + _hdat._pmid[1] = _ball->_data._ball[1] ; - - _hdat._rrad = + + _hdat._rrad = std::sqrt(_ball->_data._ball[2]) ; - + iptr_type _nadj = _ball->_data._node[0] ; - + mesh::keep_all_2d < real_type , iptr_type > _halo ; - + _geom. intersect(_hdat, _halo) ; - + for (auto _iter = _halo._list.head() ; _iter != _halo._list.tend() ; ++_iter ) { - iptr_type _hint = + iptr_type _hint = _mesh._tria. - node(_nadj)->next() ; - + node(_nadj)->next() ; + iptr_type _node = -1; if (_mesh._tria.push_node( &_iter->pval(0), _node, _hint ) ) { _mesh._tria.node( - _node)->idxh() = + _node)->idxh() = hfun_type::null_hint(); - + _mesh._tria.node( _node)->fdim() = 1 ; - + _mesh._tria.node( _node)->feat() = 0 ; - + _mesh._tria.node( _node)->topo() = 2 ; - + edge_data _edat; _edat._node[0] = _nadj ; _edat._node[1] = _node ; _epro.push(_edat) ; - } + } + } + } - - } } } diff --git a/src/libcpp/rdel_mesh/rdel_refine_ball_3.inc b/src/libcpp/rdel_mesh/rdel_refine_ball_3.inc index c3e49f7..d8a9cc5 100644 --- a/src/libcpp/rdel_mesh/rdel_refine_ball_3.inc +++ b/src/libcpp/rdel_mesh/rdel_refine_ball_3.inc @@ -1,32 +1,32 @@ /* -------------------------------------------------------- - * RDEL-REFINE-3: refine restricted subfaces in R^3. + * RDEL-REFINE-3: refine restricted subfaces in R^3. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- @@ -40,18 +40,18 @@ * -------------------------------------------------------- */ - + // from rdel_mesh_3.hpp - - + + /* -------------------------------------------------------- * _BAD-BALL: refine a "bad" ball. -------------------------------------------------------- */ - - __static_call - __normal_call + + __static_call + __normal_call typename rdel_opts::node_kind _bad_ball ( geom_type &_geom , hfun_type &_hfun , @@ -81,11 +81,11 @@ { /*--------------------- find adj. set of tria-to-node */ public : - + typedef typename mesh_type::tria_type tria_type ; - public : + public : iptr_type _npos; public : @@ -96,9 +96,9 @@ __inline_call bool_type operator() ( tria_type&_tria, iptr_type _tpos, - iptr_type _fpos - ) - { + iptr_type _fpos + ) + { iptr_type _tnod[4] = { _tria.tria(_tpos)->node(0) , _tria.tria(_tpos)->node(1) , @@ -116,14 +116,14 @@ return true ; if (_tnod[3] == this->_npos) return true ; - + return false ; } } ; - - typename rdel_opts::node_kind + + typename rdel_opts::node_kind _kind = rdel_opts::null_kind ; - + __unreferenced( _hfun) ; __unreferenced( _mode) ; __unreferenced( _tdim) ; @@ -134,7 +134,7 @@ _nold.set_count( +0 ) ; _tnew.set_count( +0 ) ; _told.set_count( +0 ) ; - + _eold.set_count( +0 ) ; _escr.set_count( +0 ) ; _ecav.set_count( +0 ) ; @@ -143,7 +143,7 @@ _fcav.set_count( +0 ) ; _tscr.set_count( +0 ) ; _tcav.set_count( +0 ) ; - + _bscr.set_count( +0 ) ; _bcav.set_count( +0 ) ; @@ -152,7 +152,7 @@ ball_list:: item_type*_bptr = nullptr; ball_data _ball ; - + bool_type _find = false; for ( ; !_nbpq.empty() ; ) { @@ -169,45 +169,45 @@ } } if ( !_find ) return _kind ; - - /*--------------------- check dist. to existing nodes */ - real_type static const _HTOL = + + /*--------------------- check dist. to existing nodes */ + real_type static const _HTOL = (real_type) +.333 * .333 ; - - real_type static const _STOL = + + real_type static const _STOL = (real_type) +.500 * .500 ; - + iptr_list _tset; _tset.set_alloc( +32) ; - iptr_type _nadj = + iptr_type _nadj = _ball._node [ 0] ; _mesh._tria.walk_node ( - _nadj, + _nadj, node_pred(_nadj), _tset) ; - real_type _rmax = + real_type _rmax = _ball._ball [ 3] ; - for (auto _tpos = _tset.head() ; + for (auto _tpos = _tset.head() ; _tpos != _tset.tend() ; ++_tpos ) { iptr_type _npos; for (_npos = +3; _npos-- != +0; ) { - iptr_type _node = + iptr_type _node = _mesh._tria. tria(*_tpos)->node(_npos) ; if (_node == _nadj) continue; - iptr_type _feat = + iptr_type _feat = _mesh. _tria.node(_node)->feat() ; - real_type _dsqr = + real_type _dsqr = geometry::lensqr_3d ( &_mesh._tria. node(_nadj)->pval(0) , @@ -223,32 +223,32 @@ { _rmax = std::min ( _rmax, _STOL * _dsqr) ; - } - } + } + } } - + /*--------------------- otherwise form "collar" radii */ _ball._ball[3] = std:: min ( _ball._ball[3],_rmax) ; _ball._ball[3] = std::sqrt ( _ball._ball [ 3]) ; - - iptr_type _ndeg = + + iptr_type _ndeg = _mesh._tria. node(_nadj)->topo() ; - - /*--------------------- find intersections with geom. */ + + /*--------------------- find intersections with geom. */ typename geom_type::ball_type _pdat, _hdat ; _pdat._pmid[0] = _ball._ball[0] ; _pdat._pmid[1] = _ball._ball[1] ; _pdat._pmid[2] = _ball._ball[2] ; - + _hdat._pmid[0] = _ball._ball[0] ; _hdat._pmid[1] = _ball._ball[1] ; _hdat._pmid[2] = _ball._ball[2] ; - + mesh::keep_all_3d < real_type , iptr_type > _pred ; @@ -257,25 +257,25 @@ iptr_type > _halo ; for(auto _iter = 32; _iter-- != 0 ; ) - { + { bool_type _okay = true ; - + _pred.clear() ; _halo.clear() ; - - _pdat._rrad = + + _pdat._rrad = (real_type)+1.0 * _ball._ball[3] ; - - _hdat._rrad = + + _hdat._rrad = (real_type)+1.5 * _ball._ball[3] ; - + _bptr->_data._ball[3] = // save to mesh "proper" - (real_type)+1.0 * _ball._ball[3] + (real_type)+1.0 * _ball._ball[3] * _ball._ball[3] ; - + _okay = _okay & _geom.intersect ( _pdat, _pred) ; // actual! - + if(!_okay) { _ball._ball[3] *= // reduce rad. for geom. @@ -307,25 +307,25 @@ continue ; } else break ; - } - - return ( _kind ) ; + } + + return ( _kind ) ; } - + /* -------------------------------------------------------- * INIT-BALL: setup ball "collar". -------------------------------------------------------- */ - - __static_call + + __static_call __normal_call void_type init_ball ( geom_type &_geom , hfun_type &_hfun , mesh_type &_mesh , - typename + typename mesh_type::edge_list &_epro , - typename + typename mesh_type::face_list &_fpro , iptr_type _mode , iptr_type _pass , @@ -338,120 +338,120 @@ __unreferenced(_pass) ; __unreferenced(_args) ; __unreferenced(_fpro) ; - - for (auto _bpos = + + for (auto _bpos = _mesh._bset._lptr.head () ; - _bpos != + _bpos != _mesh._bset._lptr.tend () ; ++_bpos ) { if ( *_bpos == nullptr) continue ; - + for (auto _ball = *_bpos ; _ball != nullptr; _ball = _ball->_next ) { - + typename geom_type::ball_type _hdat ; - _hdat._pmid[0] = + _hdat._pmid[0] = _ball->_data._ball[0] ; - _hdat._pmid[1] = + _hdat._pmid[1] = _ball->_data._ball[1] ; - _hdat._pmid[2] = + _hdat._pmid[2] = _ball->_data._ball[2] ; - - _hdat._rrad = + + _hdat._rrad = std::sqrt(_ball->_data._ball[3]) ; - + iptr_type _nadj = _ball->_data._node[0] ; - + mesh::keep_all_3d < real_type , iptr_type > _halo ; - + _geom. intersect(_hdat, _halo) ; - + for (auto _iter = _halo._list.head() ; _iter != _halo._list.tend() ; ++_iter ) { - iptr_type _hint = + iptr_type _hint = _mesh._tria. - node(_nadj)->next() ; - + node(_nadj)->next() ; + iptr_type _node = -1; if (_mesh._tria.push_node( &_iter->pval(0), _node, _hint ) ) { _mesh._tria.node( - _node)->idxh() = + _node)->idxh() = hfun_type::null_hint(); - + _mesh._tria.node( _node)->fdim() = 1 ; - + _mesh._tria.node( _node)->feat() = 0 ; - + _mesh._tria.node( _node)->topo() = 2 ; - + edge_data _edat; _edat._node[0] = _nadj ; _edat._node[1] = _node ; _epro.push(_edat) ; - } + } + } + } - - } } } - + /* -------------------------------------------------------- * INIT-DISC: setup disc "collar". -------------------------------------------------------- */ - - __static_call + + __static_call __normal_call void_type init_disc ( geom_type &_geom , hfun_type &_hfun , mesh_type &_mesh , - typename + typename mesh_type::edge_list &_epro , - typename + typename mesh_type::face_list &_fpro , iptr_type _mode , iptr_type _pass , rdel_opts &_args ) { - real_type static constexpr + real_type static constexpr _DTOL = (real_type) 7./4. ; - + /*--------------------- push finalised "collar" nodes */ __unreferenced(_hfun) ; __unreferenced(_mode) ; __unreferenced(_pass) ; __unreferenced(_args) ; __unreferenced(_epro) ; - + return; - for (auto _epos = + for (auto _epos = _mesh._eset._lptr.head () ; - _epos != + _epos != _mesh._eset._lptr.tend () ; ++_epos ) { if ( *_epos == nullptr) continue ; - + for (auto _edge = *_epos ; _edge != nullptr; _edge = _edge->_next ) @@ -459,7 +459,7 @@ if (_edge->_data. _feat == hard_feat ) { - + real_type _ebal[ 4]; geometry ::circ_ball_3d (_ebal , @@ -470,7 +470,7 @@ _edge->_data. _node[1])->pval(0) ) ; - + real_type _evec[ 3]; geometry::vector_3d( &_mesh._tria.node( @@ -480,42 +480,42 @@ _edge->_data. _node[1])->pval(0), _evec ) ; - + typename geom_type::disc_type _hdat ; _hdat._pmid[0] = _ebal[0] ; _hdat._pmid[1] = _ebal[1] ; _hdat._pmid[2] = _ebal[2] ; - + _hdat._nvec[0] = _evec[0] ; _hdat._nvec[1] = _evec[1] ; _hdat._nvec[2] = _evec[2] ; - - _hdat._rrad = + + _hdat._rrad = _DTOL* std::sqrt(_ebal[3]) ; - + mesh::keep_all_3d < real_type , iptr_type > _halo ; - - - //!! + + + //!! real_type _junk[3] = {+0.} ; - + _geom. intersect(_hdat, _junk, _halo) ; - - - for (auto _iter = + + + for (auto _iter = _halo._list.head() ; - _iter != + _iter != _halo._list.tend() ; ++_iter ) { - iptr_type _hint = + iptr_type _hint = _mesh._tria.node(_edge-> - _data._node[0])->next(); - + _data._node[0])->next(); + /* iptr_type _near = -1; _mesh._tria.find_node( @@ -523,12 +523,12 @@ _edge-> _data._node[0]) ; - if (_near != + if (_near != _edge->_data._node[0] && - _near != + _near != _edge->_data._node[1] ) - continue ; - */ + continue ; + */ iptr_type _node = -1; if (_mesh._tria.push_node( @@ -536,34 +536,34 @@ _hint ) ) { _mesh._tria.node( - _node)->idxh() = + _node)->idxh() = hfun_type::null_hint(); - + _mesh._tria.node( _node)->fdim() = 2 ; - + _mesh._tria.node( _node)->feat() = 0 ; - + _mesh._tria.node( _node)->topo() = 2 ; - + face_data _fdat; - _fdat._node[0] = + _fdat._node[0] = _edge ->_data._node [0]; - _fdat._node[1] = + _fdat._node[1] = _edge ->_data._node [1]; _fdat._node[2] = _node ; _fpro.push(_fdat) ; - } + } } - - } - + + } + } - } - } - - - + } + } + + + diff --git a/src/libcpp/rdel_mesh/rdel_refine_base_2.inc b/src/libcpp/rdel_mesh/rdel_refine_base_2.inc index 4ee8218..c57d24a 100644 --- a/src/libcpp/rdel_mesh/rdel_refine_base_2.inc +++ b/src/libcpp/rdel_mesh/rdel_refine_base_2.inc @@ -1,32 +1,32 @@ /* -------------------------------------------------------- - * RDEL-REFINE-2: refine restricted subfaces in R^2. + * RDEL-REFINE-2: refine restricted subfaces in R^2. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- @@ -40,16 +40,16 @@ * -------------------------------------------------------- */ - + // from rdel_mesh_2.hpp - - + + /* -------------------------------------------------------- - * TRIA-SIGN: return sign/part assoc. with tria. + * TRIA-SIGN: return sign/part assoc. with tria. -------------------------------------------------------- */ - + __static_call __normal_call iptr_type tria_sign ( mesh_type &_mesh, @@ -65,7 +65,7 @@ _tria.tria(_tpos)->node(+1) ; _tdat._node[2] = _mesh. _tria.tria(_tpos)->node(+2) ; - + typename mesh_type:: tria_list:: item_type *_tptr = nullptr ; @@ -92,9 +92,9 @@ mode_type _mode , char_type _topo , real_type *_ppos , - typename + typename rdel_opts::node_kind _kind , - typename + typename mesh_type::edge_list &_epro , // "protected" 1-edge iptr_list &_nnew , iptr_list &_nold , @@ -113,28 +113,28 @@ rdel_opts &_args ) { - typename rdel_opts::node_kind + typename rdel_opts::node_kind _kout = _kind; - + /*---------------- try lower-dim. faces until success */ for (_tdim = _topo; _tdim > 0 ; ) { _eold.set_count( +0) ; - + iptr_type _node = -1; if(!_mesh._tria.push_node ( - _ppos, _node, + _ppos, _node, _hint, &_tnew, &_told)) { /*------------------------- bail if DT push fails */ - _kout = + _kout = rdel_opts ::null_kind; - + _nnew.set_count(+0) ; _nold.set_count(+0) ; _tnew.set_count(+0) ; _told.set_count(+0) ; - + _eold.set_count(+0) ; _escr.set_count(+0) ; _ecav.set_count(+0) ; @@ -142,13 +142,13 @@ _tcav.set_count(+0) ; _bscr.set_count(+0) ; _bcav.set_count(+0) ; - + break ; } - + /*------------------------- config. new node data */ _mesh._tria. - node(_node)->idxh() = + node(_node)->idxh() = hfun_type::null_hint() ; _mesh._tria. @@ -161,25 +161,25 @@ iptr_type _sign = -1 ; if (_told.count() > +0 ) { - _sign = + _sign = tria_sign(_mesh, _told[0]); } /*------------------------- keep "old" rDT cavity */ - find_rdel( _geom, _mesh , + find_rdel( _geom, _mesh , _told, _eold ) ; /*------------------------- form "new" rDT cavity */ - push_rdel( _geom, _hfun , - _mesh, true, - _nnew, _tnew, - _escr, _ecav, + push_rdel( _geom, _hfun , + _mesh, true, + _nnew, _tnew, + _escr, _ecav, _tscr, _tcav, - _bscr, _bcav, - _sign, _pass, - null_mode, + _bscr, _bcav, + _sign, _pass, + null_mode, _mode, _args ) ; - + _mesh._tria.node( _node)->fdim() = _tdim ; @@ -187,8 +187,8 @@ _pnow[0] = _ppos[0] ; _pnow[1] = _ppos[1] ; - if (_cav_bnds( _geom, _mesh , - _told, _epro, + if (_cav_bnds( _geom, _mesh , + _told, _epro, _ecav, _eold) ) { /*-------- new node modifies constraint sub-faces */ @@ -198,57 +198,57 @@ _tdim = +0 ; _kout = rdel_opts::null_kind ; - + _nnew.set_count(+0) ; _nold.set_count(+0) ; _tnew.set_count(+0) ; _told.set_count(+0) ; - + _eold.set_count(+0) ; _escr.set_count(+0) ; _ecav.set_count(+0) ; _tscr.set_count(+0) ; _tcav.set_count(+0) ; - + _bscr.set_count(+0) ; _bcav.set_count(+0) ; } else - if (_cav_bnds( _geom, _mesh , - _told, _ecav, _pnow , + if (_cav_bnds( _geom, _mesh , + _told, _ecav, _pnow , _ppos, _tdim) ) { /*-------- new node modifies restricted sub-faces */ _mesh. _tria.roll_back(_tnew, _told); - _cav_bnds( _geom, _mesh , - _told, _ecav, - _eold, _pnow, + _cav_bnds( _geom, _mesh , + _told, _ecav, + _eold, _pnow, _ppos, _tdim) ; _kout = rdel_opts::circ_kind ; - + _nnew.set_count(+0) ; _nold.set_count(+0) ; _tnew.set_count(+0) ; _told.set_count(+0) ; - + _eold.set_count(+0) ; _escr.set_count(+0) ; _ecav.set_count(+0) ; _tscr.set_count(+0) ; _tcav.set_count(+0) ; - + _bscr.set_count(+0) ; _bcav.set_count(+0) ; } /*------------------- new node acceptable "as-is" */ else 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 1c80ccf..ce7477f 100644 --- a/src/libcpp/rdel_mesh/rdel_refine_base_3.inc +++ b/src/libcpp/rdel_mesh/rdel_refine_base_3.inc @@ -1,32 +1,32 @@ /* -------------------------------------------------------- - * RDEL-REFINE-3: refine restricted subfaces in R^3. + * RDEL-REFINE-3: refine restricted subfaces in R^3. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- @@ -40,16 +40,16 @@ * -------------------------------------------------------- */ - + // from rdel_mesh_3.hpp - - + + /* -------------------------------------------------------- - * TRIA-SIGN: return sign/part assoc. with tria. + * TRIA-SIGN: return sign/part assoc. with tria. -------------------------------------------------------- */ - + __static_call __normal_call iptr_type tria_sign ( mesh_type &_mesh, @@ -94,11 +94,11 @@ mode_type _mode , char_type _topo , real_type *_ppos , - typename + typename rdel_opts::node_kind _kind , - typename + typename mesh_type::edge_list &_epro , - typename + typename mesh_type::face_list &_fpro , iptr_list &_nnew , iptr_list &_nold , @@ -120,18 +120,18 @@ rdel_opts &_args ) { - typename rdel_opts::node_kind + typename rdel_opts::node_kind _kout = _kind; - + /*---------------- try lower-dim. faces until success */ for (_tdim = _topo; _tdim > 0 ; ) { _eold.set_count( +0) ; _fold.set_count( +0) ; - + iptr_type _node = -1; if(!_mesh._tria.push_node ( - _ppos, _node, + _ppos, _node, _hint, &_tnew, &_told)) { /*------------------------- bail if DT push fails */ @@ -139,7 +139,7 @@ _nold.set_count(+0) ; _tnew.set_count(+0) ; _told.set_count(+0) ; - + _eold.set_count(+0) ; _escr.set_count(+0) ; _ecav.set_count(+0) ; @@ -148,19 +148,19 @@ _fcav.set_count(+0) ; _tscr.set_count(+0) ; _tcav.set_count(+0) ; - + _bscr.set_count(+0) ; _bcav.set_count(+0) ; - - _kout = + + _kout = rdel_opts ::null_kind; - + break ; } - + /*------------------------- config. new node data */ _mesh._tria. - node(_node)->idxh() = + node(_node)->idxh() = hfun_type::null_hint() ; _mesh._tria. @@ -173,26 +173,26 @@ iptr_type _sign = -1 ; if (_told.count() > +0 ) { - _sign = + _sign = tria_sign(_mesh, _told[0]); } /*------------------------- keep "old" rDT cavity */ - find_rdel( _geom, _mesh , + find_rdel( _geom, _mesh , _told, _eold, _fold ) ; /*------------------------- form "new" rDT cavity */ - push_rdel( _geom, _hfun , + push_rdel( _geom, _hfun , _mesh, true, - _nnew, _tnew, - _escr, _ecav, + _nnew, _tnew, + _escr, _ecav, _fscr, _fcav, _tscr, _tcav, - _bscr, _bcav, - _sign, _pass, - null_mode, + _bscr, _bcav, + _sign, _pass, + null_mode, _mode, _args ) ; - + _mesh._tria.node( _node)->fdim() = _tdim; @@ -201,9 +201,9 @@ _pnow[1] = _ppos[1] ; _pnow[2] = _ppos[2] ; - if (_cav_bnds( _geom, _mesh, - _told, _epro, _fpro, - _ecav, _fcav, + if (_cav_bnds( _geom, _mesh, + _told, _epro, _fpro, + _ecav, _fcav, _eold, _fold) ) { /*-------- new node modifies constraint sub-faces */ @@ -218,7 +218,7 @@ _nold.set_count(+0) ; _tnew.set_count(+0) ; _told.set_count(+0) ; - + _eold.set_count(+0) ; _escr.set_count(+0) ; _ecav.set_count(+0) ; @@ -227,33 +227,33 @@ _fcav.set_count(+0) ; _tscr.set_count(+0) ; _tcav.set_count(+0) ; - + _bscr.set_count(+0) ; _bcav.set_count(+0) ; } else - if (_cav_bnds( _geom, _mesh, - _told, - _ecav, _fcav, _pnow, + if (_cav_bnds( _geom, _mesh, + _told, + _ecav, _fcav, _pnow, _ppos, _tdim) ) { /*-------- new node modifies restricted sub-faces */ _mesh. _tria.roll_back(_tnew, _told); - _cav_bnds( _geom, _mesh, - _told, _ecav, - _fcav, _eold, - _fold, _pnow, + _cav_bnds( _geom, _mesh, + _told, _ecav, + _fcav, _eold, + _fold, _pnow, _ppos, _tdim) ; - + _kout = rdel_opts::circ_kind ; _nnew.set_count(+0) ; _nold.set_count(+0) ; _tnew.set_count(+0) ; _told.set_count(+0) ; - + _eold.set_count(+0) ; _escr.set_count(+0) ; _ecav.set_count(+0) ; @@ -262,14 +262,14 @@ _fcav.set_count(+0) ; _tscr.set_count(+0) ; _tcav.set_count(+0) ; - + _bscr.set_count(+0) ; _bcav.set_count(+0) ; } /*------------------- new node acceptable "as-is" */ else 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 60b6775..bf37895 100644 --- a/src/libcpp/rdel_mesh/rdel_refine_face_2.inc +++ b/src/libcpp/rdel_mesh/rdel_refine_face_2.inc @@ -1,32 +1,32 @@ /* -------------------------------------------------------- - * RDEL-REFINE-2: refine restricted subfaces in R^2. + * RDEL-REFINE-2: refine restricted subfaces in R^2. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- @@ -40,24 +40,24 @@ * -------------------------------------------------------- */ - + // from rdel_mesh_2.hpp - - + + /* -------------------------------------------------------- * _BAD-EDGE: refine a "bad" edge. -------------------------------------------------------- */ - __static_call - __normal_call + __static_call + __normal_call typename rdel_opts::node_kind _bad_edge ( geom_type &_geom , hfun_type &_hfun , mesh_type &_mesh , mode_type _mode , - typename + typename mesh_type::edge_list &_epro , iptr_list &_nnew , iptr_list &_nold , @@ -76,14 +76,14 @@ rdel_opts &_args ) { - typename rdel_opts::node_kind + typename rdel_opts::node_kind _kind = rdel_opts::null_kind ; _nnew.set_count( +0) ; _nold.set_count( +0) ; _tnew.set_count( +0) ; _told.set_count( +0) ; - + _eold.set_count( +0) ; _escr.set_count( +0) ; _ecav.set_count( +0) ; @@ -91,7 +91,7 @@ _tcav.set_count( +0) ; _bscr.set_count( +0) ; _bcav.set_count( +0) ; - + /*--------------------- pop() leading element from PQ */ iptr_type _hint= -1; real_type _ppos[ +3] ; @@ -104,26 +104,26 @@ _edat._node[0] = _qdat._node[0] ; _edat._node[1] = _qdat._node[1] ; - + typename mesh_type:: edge_list:: - item_type *_eptr = nullptr ; + item_type *_eptr = nullptr ; if (_mesh.find_edge(_edat,_eptr)) { if(_eptr->_data._pass == _qdat. _pass ) { /*----------------- new steiner vertex coords */ - _kind = + _kind = mesh_pred::edge_node ( - _geom, _hfun , - _mesh, _qdat , - _eptr->_data._tadj, - _eptr->_data._eadj, + _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) @@ -142,23 +142,23 @@ } } } - + if (_kind == rdel_opts::null_kind) { return _kind ; } - + /*------------------------- push node via constraints */ - _kind = push_node( _geom , - _hfun , _mesh, _mode , + _kind = push_node( _geom , + _hfun , _mesh, _mode , +1 , _ppos, _kind , _epro , _nnew, _nold , - _tnew , _told, _eold , - _ecav , _escr, + _tnew , _told, _eold , + _ecav , _escr, _tcav , _tscr, _bcav , _bscr, _hint, _tdim , _pass, _args ) ; - + if (_kind != rdel_opts::null_kind) { if (_tdim != +1) @@ -167,24 +167,24 @@ _escr.push_tail(_qdat) ; } } - + return _kind ; } - + /* -------------------------------------------------------- * _BAD-TRIA: refine a "bad" tria. -------------------------------------------------------- */ - - __static_call - __normal_call + + __static_call + __normal_call typename rdel_opts::node_kind _bad_tria ( geom_type &_geom , hfun_type &_hfun , mesh_type &_mesh , mode_type _mode , - typename + typename mesh_type::edge_list &_epro , iptr_list &_nnew , iptr_list &_nold , @@ -203,14 +203,14 @@ rdel_opts &_args ) { - typename rdel_opts::node_kind + typename rdel_opts::node_kind _kind = rdel_opts::null_kind ; _nnew.set_count( +0) ; _nold.set_count( +0) ; _tnew.set_count( +0) ; _told.set_count( +0) ; - + _eold.set_count( +0) ; _escr.set_count( +0) ; _ecav.set_count( +0) ; @@ -218,7 +218,7 @@ _tcav.set_count( +0) ; _bscr.set_count( +0) ; _bcav.set_count( +0) ; - + /*--------------------- pop() leading element from PQ */ iptr_type _hint= -1; real_type _ppos[ +3] ; @@ -242,14 +242,14 @@ _qdat. _pass ) { /*----------------- new steiner vertex coords */ - _kind = + _kind = mesh_pred::tria_node ( - _geom, _hfun , + _geom, _hfun , _mesh, _qdat , - _tptr->_data._tadj , + _tptr->_data._tadj , _ppos, _args ) ; - _hint = + _hint = _tptr->_data._tadj ; if (_kind == rdel_opts:: @@ -268,23 +268,23 @@ } } } - + if (_kind == rdel_opts::null_kind) { return _kind ; } - + /*------------------------- push node via constraints */ - _kind = push_node( _geom , - _hfun , _mesh, _mode , + _kind = push_node( _geom , + _hfun , _mesh, _mode , +2 , _ppos, _kind , _epro , _nnew, _nold , _tnew , _told, _eold , - _ecav , _escr, + _ecav , _escr, _tcav , _tscr, _bcav , _bscr, _hint , _tdim , _pass, _args ) ; - + if (_kind != rdel_opts::null_kind) { if (_tdim != +2) @@ -293,9 +293,9 @@ _tscr.push_tail(_qdat) ; } } - + return _kind ; } - + diff --git a/src/libcpp/rdel_mesh/rdel_refine_face_3.inc b/src/libcpp/rdel_mesh/rdel_refine_face_3.inc index 3afc20b..ce226c3 100644 --- a/src/libcpp/rdel_mesh/rdel_refine_face_3.inc +++ b/src/libcpp/rdel_mesh/rdel_refine_face_3.inc @@ -1,32 +1,32 @@ /* -------------------------------------------------------- - * RDEL-REFINE-3: refine restricted subfaces in R^3. + * RDEL-REFINE-3: refine restricted subfaces in R^3. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- @@ -40,26 +40,26 @@ * -------------------------------------------------------- */ - + // from rdel_mesh_3.hpp - - + + /* -------------------------------------------------------- * _BAD-EDGE: refine a "bad" edge. -------------------------------------------------------- */ - - __static_call - __normal_call + + __static_call + __normal_call typename rdel_opts::node_kind _bad_edge ( geom_type &_geom , hfun_type &_hfun , mesh_type &_mesh , mode_type _mode , - typename + typename mesh_type::edge_list &_epro , - typename + typename mesh_type::face_list &_fpro , iptr_list &_nnew , iptr_list &_nold , @@ -81,14 +81,14 @@ rdel_opts &_args ) { - typename rdel_opts::node_kind + typename rdel_opts::node_kind _kind = rdel_opts::null_kind ; _nnew.set_count( +0) ; _nold.set_count( +0) ; _tnew.set_count( +0) ; _told.set_count( +0) ; - + _eold.set_count( +0) ; _escr.set_count( +0) ; _ecav.set_count( +0) ; @@ -97,7 +97,7 @@ _fcav.set_count( +0) ; _tscr.set_count( +0) ; _tcav.set_count( +0) ; - + _bscr.set_count( +0) ; _bcav.set_count( +0) ; @@ -113,27 +113,27 @@ _edat._node[0] = _qdat._node[0] ; _edat._node[1] = _qdat._node[1] ; - + typename mesh_type:: edge_list:: - item_type *_eptr = nullptr ; + item_type *_eptr = nullptr ; if (_mesh.find_edge(_edat,_eptr)) { if(_eptr->_data._pass == _qdat. _pass ) { /*----------------- new steiner vertex coords */ - _kind = + _kind = mesh_pred::edge_node ( - _geom, _hfun , - _mesh, _qdat , - _eptr->_data._tadj , - _eptr->_data._eadj , + _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) { @@ -151,25 +151,25 @@ } } } - + if (_kind == rdel_opts::null_kind) { return _kind ; } - + /*------------------------- push node via constraints */ - _kind = push_node( _geom , - _hfun , _mesh, _mode , + _kind = push_node( _geom , + _hfun , _mesh, _mode , +1 , _ppos, _kind , _epro , _fpro, _nnew , _nold, - _tnew , _told, - _eold , _ecav, _escr , - _fold , _fcav, _fscr , + _tnew , _told, + _eold , _ecav, _escr , + _fold , _fcav, _fscr , _tcav , _tscr, _bcav , _bscr, _hint , _tdim , _pass, _args ) ; - + if (_kind != rdel_opts::null_kind) { if (_tdim != +1) @@ -178,26 +178,26 @@ _escr.push_tail(_qdat) ; } } - + return _kind ; } - + /* -------------------------------------------------------- * _BAD-FACE: refine a "bad" face. -------------------------------------------------------- */ - - __static_call - __normal_call + + __static_call + __normal_call typename rdel_opts::node_kind _bad_face ( geom_type &_geom , hfun_type &_hfun , mesh_type &_mesh , mode_type _mode , - typename + typename mesh_type::edge_list &_epro , - typename + typename mesh_type::face_list &_fpro , iptr_list &_nnew , iptr_list &_nold , @@ -218,15 +218,15 @@ iptr_type _pass , rdel_opts &_args ) - { - typename rdel_opts::node_kind + { + typename rdel_opts::node_kind _kind = rdel_opts::null_kind ; _nnew.set_count( +0) ; _nold.set_count( +0) ; _tnew.set_count( +0) ; _told.set_count( +0) ; - + _eold.set_count( +0) ; _escr.set_count( +0) ; _ecav.set_count( +0) ; @@ -235,7 +235,7 @@ _fcav.set_count( +0) ; _tscr.set_count( +0) ; _tcav.set_count( +0) ; - + _bscr.set_count( +0) ; _bcav.set_count( +0) ; @@ -252,27 +252,27 @@ _fdat._node[0] = _qdat._node[0] ; _fdat._node[1] = _qdat._node[1] ; _fdat._node[2] = _qdat._node[2] ; - + typename mesh_type:: face_list:: - item_type *_fptr = nullptr ; + item_type *_fptr = nullptr ; if (_mesh.find_face(_fdat,_fptr)) { if(_fptr->_data._pass == _qdat. _pass ) { /*----------------- new steiner vertex coords */ - _kind = + _kind = mesh_pred::face_node ( - _geom, _hfun , - _mesh, _qdat , - _fptr->_data._tadj , - _fptr->_data._fadj , + _geom, _hfun , + _mesh, _qdat , + _fptr->_data._tadj , + _fptr->_data._fadj , _ppos, _args ) ; - - _hint = + + _hint = _fptr->_data._tadj ; - + if (_kind == rdel_opts:: fail_kind) { @@ -289,25 +289,25 @@ } } } - + if (_kind == rdel_opts::null_kind) { return _kind ; } - + /*------------------------- push node via constraints */ - _kind = push_node( _geom , - _hfun , _mesh, _mode , + _kind = push_node( _geom , + _hfun , _mesh, _mode , +2 , _ppos, _kind , _epro , _fpro, _nnew , _nold, - _tnew , _told, - _eold , _ecav, _escr , - _fold , _fcav, _fscr , + _tnew , _told, + _eold , _ecav, _escr , + _fold , _fcav, _fscr , _tcav , _tscr, _bcav , _bscr, _hint , _tdim , _pass, _args ) ; - + if (_kind != rdel_opts::null_kind) { if (_tdim != +2) @@ -316,26 +316,26 @@ _fscr.push_tail(_qdat) ; } } - + return _kind ; } - + /* -------------------------------------------------------- * _BAD-TRIA: refine a "bad" tria. -------------------------------------------------------- */ - - __static_call - __normal_call + + __static_call + __normal_call typename rdel_opts::node_kind _bad_tria ( geom_type &_geom , hfun_type &_hfun , mesh_type &_mesh , mode_type _mode , - typename + typename mesh_type::edge_list &_epro , - typename + typename mesh_type::face_list &_fpro , iptr_list &_nnew , iptr_list &_nold , @@ -357,14 +357,14 @@ rdel_opts &_args ) { - typename rdel_opts::node_kind + typename rdel_opts::node_kind _kind = rdel_opts::null_kind ; _nnew.set_count( +0) ; _nold.set_count( +0) ; _tnew.set_count( +0) ; _told.set_count( +0) ; - + _eold.set_count( +0) ; _escr.set_count( +0) ; _ecav.set_count( +0) ; @@ -401,16 +401,16 @@ _qdat. _pass ) { /*----------------- new steiner vertex coords */ - _kind = + _kind = mesh_pred::tria_node ( - _geom, _hfun , + _geom, _hfun , _mesh, _qdat , - _tptr->_data._tadj , + _tptr->_data._tadj , _ppos, _args ) ; - _hint = - _tptr->_data._tadj ; - + _hint = + _tptr->_data._tadj ; + if (_kind == rdel_opts:: fail_kind) { @@ -427,36 +427,36 @@ } } } - + if (_kind == rdel_opts::null_kind) { return _kind ; } - + /*------------------------- push node via constraints */ - _kind = push_node( _geom , - _hfun , _mesh, _mode , + _kind = push_node( _geom , + _hfun , _mesh, _mode , +3 , _ppos, _kind , _epro , _fpro, _nnew , _nold, - _tnew , _told, - _eold , _ecav, _escr , - _fold , _fcav, _fscr , + _tnew , _told, + _eold , _ecav, _escr , + _fold , _fcav, _fscr , _tcav , _tscr, _bcav , _bscr, _hint , _tdim , _pass, _args ) ; - + if (_kind != rdel_opts::null_kind) { if (_tdim != +3) - { + { /*------------------------- re-queue face if un-split */ _tscr.push_tail(_qdat) ; } } - + return _kind ; } - - - + + + diff --git a/src/libcpp/rdel_mesh/rdel_refine_topo_2.inc b/src/libcpp/rdel_mesh/rdel_refine_topo_2.inc index 23e0eb8..810bd83 100644 --- a/src/libcpp/rdel_mesh/rdel_refine_topo_2.inc +++ b/src/libcpp/rdel_mesh/rdel_refine_topo_2.inc @@ -1,37 +1,37 @@ /* -------------------------------------------------------- - * RDEL-REFINE-2: refine restricted subfaces in R^2. + * RDEL-REFINE-2: refine restricted subfaces in R^2. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 18 February, 2019 + * Last updated: 03 July, 2019 * * Copyright 2013-2019 * Darren Engwirda @@ -40,10 +40,10 @@ * -------------------------------------------------------- */ - + // from rdel_mesh_2.hpp - - + + /* -------------------------------------------------------- * ETOP-DISK: return TRUE if 1-manifold disk. @@ -58,29 +58,29 @@ edat_list &_eset ) { - typename + typename mesh_type::edge_list _edup ( typename mesh_type::edge_hash(), - typename mesh_type::edge_pred(), + typename mesh_type::edge_pred(), .8, _mesh._eset.get_alloc()) ; - - _edup._lptr.set_count ( - _tset.count() * +3 , - containers::loose_alloc, nullptr); - - iptr_type _feat = + + _edup.set_slots ( + _tset.count() * +3 , + containers::tight_alloc) ; + + iptr_type _feat = _mesh._tria.node(_npos)->feat() ; - uint_type _topo = + uint_type _topo = _mesh._tria.node(_npos)->topo() ; - - _topo = + + _topo = (_feat != null_feat) ? _topo : 2 ; - - for (auto _tpos = _tset.head() ; - _tpos != _tset.tend() ; + + for (auto _tpos = _tset.head() ; + _tpos != _tset.tend() ; ++_tpos ) - { - /*--------------------- assemble 1-dim. topo disk */ + { + /*--------------------- assemble 1-dim. topo disk */ for (auto _epos = +3; _epos-- != +0; ) { iptr_type _enod [ +3]; @@ -90,22 +90,22 @@ tria(*_tpos)->node(_enod[0]); _enod[1] = _mesh._tria. tria(*_tpos)->node(_enod[1]); - + iptr_type _same = +0 ; if (_enod[0] == _npos) _same += +1; if (_enod[1] == _npos) _same += +1; if (_same != +1) continue ; - + algorithms::isort ( - &_enod[0], &_enod[2], + &_enod[0], &_enod[2], std::less()) ; - + edge_data _edat; _edat._node[0] = _enod[0] ; _edat._node[1] = _enod[1] ; - + typename mesh_type:: edge_list:: item_type*_mptr=nullptr; @@ -117,14 +117,14 @@ continue ; if( _edup.find(_edat, _eptr)) continue ; - + _edup.push (_edat ) ; - + _eset.push_tail( - _mptr->_data ) ; + _mptr->_data ) ; + } } - } - + return ( _eset.count() == _topo ) ; } @@ -135,7 +135,7 @@ */ __static_call - __normal_call + __normal_call typename rdel_opts::node_kind topo_node ( geom_type &_geom, mesh_type &_mesh, @@ -148,9 +148,9 @@ rdel_opts &_opts ) { - typename rdel_opts::node_kind + typename rdel_opts::node_kind _kind = rdel_opts::null_kind ; - + real_type _rEPS = std::pow ( std::numeric_limits ::epsilon (), +.75) ; @@ -167,7 +167,7 @@ for (auto _edge = _eset.head() ; _edge != _eset.tend() ; ++_edge ) - { + { mesh_type::tria_type:: tria_type::face_node( _enod, _edge->_eadj, 2, 1) ; @@ -183,12 +183,12 @@ real_type _fbal[ +3] ; real_type _sbal[ +3] ; if (!mesh_pred::edge_ball ( - _geom, _mesh , - _edge->_tadj , - _edge->_eadj , - _fbal, _sbal , + _geom, _mesh , + _edge->_tadj , + _edge->_eadj , + _fbal, _sbal , _feat, _topo , _part ) ) - __assert( false && + __assert( false && "TOPO-NODE: edge-ball" ) ; real_type _enrm[ +3] ; @@ -199,12 +199,12 @@ node(_enod[1])->pval(0) , _enrm) ; - _enrm[2] = + _enrm[2] = geometry::length_2d(_enrm) ; _enrm[0]/= _enrm[2] ; _enrm[1]/= _enrm[2] ; - - real_type _sign = + + real_type _sign = geometry::dot_2d(_enrm, _vnrm) ; if (_sign >= (real_type) +0. ) @@ -222,37 +222,37 @@ { _pmax[2] = _sbal[2]; - _kind = + _kind = rdel_opts::circ_kind ; _tdim = +1; - + _tadj = _edge->_tadj ; - + _pmax[0] = _sbal[0]; _pmax[1] = _sbal[1]; } } - - if(__chkbit(_opts.rule(), + + if(__chkbit(_opts.rule(), rdel_opts ::offT_kind) ) { - /*--------------------- calc. "skinny" off-centre */ - _vnrm[2] = + /*--------------------- calc. "skinny" off-centre */ + _vnrm[2] = geometry::length_2d(_vnrm) ; _vnrm[0]/= _vnrm[2] ; _vnrm[1]/= _vnrm[2] ; - real_type _rrad = + real_type _rrad = std::sqrt(_pmax[ 2]); if (_vnrm[2] >= _rEPS * _rrad) { /*--------------------- project on local "normal" */ - _vnrm[0]*= _rrad * + _vnrm[0]*= _rrad * (real_type) +2. ; - _vnrm[1]*= _rrad * + _vnrm[1]*= _rrad * (real_type) +2. ; typename @@ -261,7 +261,7 @@ - _vnrm[0]; _ldat._ipos[1] = _ppos[1] - _vnrm[1]; - + _ldat._jpos[0] = _ppos[0] + _vnrm[0]; _ldat._jpos[1] = _ppos[1] @@ -271,12 +271,12 @@ real_type , iptr_type > _halo ; - _geom.intersect( _ldat , + _geom.intersect( _ldat , _halo ) ; auto _ioff = _halo._list.tend(); - real_type _dmin = + real_type _dmin = _rEPS * std::pow(_rrad, +2); real_type static constexpr @@ -286,9 +286,9 @@ +std::numeric_limits ::infinity(); - for (auto _iter = + for (auto _iter = _halo._list.head() ; - _iter != + _iter != _halo._list.tend() ; ++_iter ) { @@ -299,38 +299,38 @@ auto _nptr = &_mesh. _tria.node(_near)->pval(0) ; - real_type _nsqr = + real_type _nsqr = geometry::lensqr_2d ( &_iter->pval(0), _nptr) ; - real_type _dsqr = + real_type _dsqr = geometry::lensqr_2d ( &_iter->pval(0), _ppos) ; - if (_nsqr > _dsqr * + if (_nsqr > _dsqr * _NEAR ) if (_dsqr < _best && _dsqr > _dmin ) { - _kind = + _kind = rdel_opts::offT_kind ; - + _best = _dsqr ; _ioff = _iter ; } } - + if (_ioff != _halo._list.tend()) { _pmax[0] = _ioff->pval (0) ; _pmax[1] = _ioff->pval (1) ; } - } + } } - return _kind ; + return _kind ; } /* @@ -339,14 +339,14 @@ -------------------------------------------------------- */ - __static_call - __normal_call + __static_call + __normal_call typename rdel_opts::node_kind _bad_etop ( geom_type &_geom , hfun_type &_hfun , mesh_type &_mesh , mode_type _mode , - typename + typename mesh_type::edge_list &_epro , iptr_list &_nnew , iptr_list &_nold , @@ -370,11 +370,11 @@ { /*--------------------- find adj. set of tria-to-node */ public : - + typedef typename mesh_type::tria_type tria_type ; - public : + public : iptr_type _npos; public : @@ -385,9 +385,9 @@ __inline_call bool_type operator() ( tria_type&_tria, iptr_type _tpos, - iptr_type _fpos - ) - { + iptr_type _fpos + ) + { iptr_type _tnod[3] = { _tria.tria(_tpos)->node(0) , _tria.tria(_tpos)->node(1) , @@ -402,12 +402,12 @@ return true ; if (_tnod[2] == this->_npos) return true ; - + return false ; } } ; - typename rdel_opts::node_kind + typename rdel_opts::node_kind _kind = rdel_opts::null_kind ; /*--------------------- pop() leading element from PQ */ @@ -429,7 +429,7 @@ array _tset ; containers:: array _eset ; - + _tset.set_alloc( +32) ; _eset.set_alloc( +32) ; @@ -440,7 +440,7 @@ { node_data _ndat; _etpq._pop_root(_ndat) ; - + _npos = _ndat._node[0] ; _emrk[_npos] = -1; @@ -448,45 +448,45 @@ _tset.set_count( +0) ; _eset.set_count( +0) ; - _mesh._tria.walk_node( - _npos , + _mesh._tria.walk_node( + _npos , node_pred(_npos),_tset) ; - if (!etop_disk(_mesh, + if (!etop_disk(_mesh, _npos, _tset, _eset) ) { _find = true; break ; } } if (!_find) return _kind ; - + /*------------------------- calc. best node in cavity */ real_type _pmax [ +3] ; char_type _tmax = -1; iptr_type _hint = -1; - - auto _ppos = + + auto _ppos = &_mesh . _tria.node (_npos)->pval(0) ; - + _kind = topo_node( _geom, - _mesh , _eset, - _npos , _ppos, _pmax, + _mesh , _eset, + _npos , _ppos, _pmax, _tmax , _hint, _args) ; - + /*------------------------- push node via constraints */ - _kind = push_node( _geom, + _kind = push_node( _geom, _hfun , _mesh, _mode, _tmax , _pmax, _kind, _epro , _nnew, _nold, - _tnew , _told, _etmp, - _ecav , _escr, + _tnew , _told, _etmp, + _ecav , _escr, _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 0458d5e..4e91fbf 100644 --- a/src/libcpp/rdel_mesh/rdel_refine_topo_3.inc +++ b/src/libcpp/rdel_mesh/rdel_refine_topo_3.inc @@ -1,37 +1,37 @@ /* -------------------------------------------------------- - * RDEL-REFINE-3: refine restricted subfaces in R^3. + * RDEL-REFINE-3: refine restricted subfaces in R^3. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 18 February, 2019 + * Last updated: 03 July, 2019 * * Copyright 2013-2019 * Darren Engwirda @@ -40,10 +40,10 @@ * -------------------------------------------------------- */ - + // from rdel_mesh_3.hpp - - + + /* -------------------------------------------------------- * FTOP-SCAN: return no. connected components. @@ -54,47 +54,47 @@ __normal_call iptr_type ftop_scan ( mesh_type &_mesh, fdat_list &_fset, - typename + typename mesh_type::edge_list &_edup ) - { + { containers::array < typename mesh_type:: edge_list::item_type*> _aset; - - iptr_list _seen, _fbfs; + + iptr_list _seen, _fbfs; _seen.set_count(_fset.count(), containers::loose_alloc, 0) ; - - iptr_type _fcon = +0 ; + + iptr_type _fcon = +0 ; iptr_type _fnum = +0 ; iptr_type _fpos ; - + for (auto _face = _fset.head() ; _face != _fset.tend() ; ++_face, ++_fnum) { if (_seen [_fnum] == +0) { - + _seen[_fnum] = +1 ; - + _fbfs.push_tail(_fnum) ; _fcon += +1 ; for ( ; !_fbfs.empty() ; ) { - + _fbfs._pop_tail(_fpos) ; - + for(auto _epos = +3; _epos-- != +0; ) { - iptr_type _tadj = + iptr_type _tadj = _fset[_fpos]._tadj ; - iptr_type _fadj = + iptr_type _fadj = _fset[_fpos]._fadj ; - + iptr_type _fnod [ +4]; mesh_type::tria_type::tria_type:: face_node(_fnod, _fadj, 3, 2); @@ -104,58 +104,58 @@ tria( _tadj)->node(_fnod[1]); _fnod[2] = _mesh._tria. tria( _tadj)->node(_fnod[2]); - + iptr_type _enod [ +3] ; mesh_type::tria_type::tria_type:: face_node(_enod, _epos, 2, 1); _enod[0] = _fnod[_enod[ 0] ] ; _enod[1] = _fnod[_enod[ 1] ] ; - + algorithms::isort ( - &_enod[0], &_enod[2], + &_enod[0], &_enod[2], std::less()) ; - + edge_data _edat; _edat._node[0] = _enod[0] ; _edat._node[1] = _enod[1] ; - + _aset.set_count(+0, containers::loose_alloc); - + if(!_edup.find(_edat, _aset)) continue ; - + for (auto _iter = _aset.head() ; _iter != _aset.tend() ; ++_iter ) { iptr_type _iadj = (*_iter)->_data._tadj; - + if (_seen[_iadj] == +0) { _seen[_iadj] = +1 ; - + _fbfs. push_tail( _iadj ); } } } - + } - + } } - + return ( _fcon ) ; } - + /* -------------------------------------------------------- * ETOP-DISK: return TRUE if 1-manifold disk. -------------------------------------------------------- */ - + __static_call __normal_call bool_type etop_disk ( mesh_type &_mesh, @@ -164,29 +164,29 @@ edat_list &_eset ) { - typename + typename mesh_type::edge_list _edup ( typename mesh_type::edge_hash(), - typename mesh_type::edge_pred(), + typename mesh_type::edge_pred(), +.8, _mesh._eset.get_alloc()) ; - - _edup._lptr.set_count ( - _tset.count() * +6 , - containers::loose_alloc, nullptr); - - iptr_type _feat = + + _edup.set_slots ( + _tset.count() * +6 , + containers::tight_alloc) ; + + iptr_type _feat = _mesh._tria.node(_npos)->feat() ; - uint_type _topo = + uint_type _topo = _mesh._tria.node(_npos)->topo() ; - - _topo = + + _topo = (_feat != null_feat) ? _topo : 2 ; - - for (auto _tpos = _tset.head() ; - _tpos != _tset.tend() ; + + for (auto _tpos = _tset.head() ; + _tpos != _tset.tend() ; ++_tpos ) - { - /*--------------------- assemble 1-dim. topo disk */ + { + /*--------------------- assemble 1-dim. topo disk */ for (auto _epos = +6; _epos-- != +0; ) { iptr_type _enod [ +4]; @@ -196,22 +196,22 @@ tria(*_tpos)->node(_enod[0]); _enod[1] = _mesh._tria. tria(*_tpos)->node(_enod[1]); - + iptr_type _same = +0 ; if (_enod[0] == _npos) _same += +1; if (_enod[1] == _npos) _same += +1; if (_same != +1) continue ; - + algorithms::isort ( - &_enod[0], &_enod[2], + &_enod[0], &_enod[2], std::less()) ; - + edge_data _edat; _edat._node[0] = _enod[0] ; _edat._node[1] = _enod[1] ; - + typename mesh_type:: edge_list:: item_type*_mptr=nullptr; @@ -226,11 +226,11 @@ else { _edup.push(_edat) ; } - - _eset.push_tail(_mptr->_data ) ; + + _eset.push_tail(_mptr->_data ) ; + } } - } - + return ( _eset.count() <= _topo ) ; //!! what about missing edges? } @@ -249,34 +249,34 @@ fdat_list &_fset ) { - typename + typename mesh_type::edge_list _edup ( typename mesh_type::edge_hash(), - typename mesh_type::edge_pred(), + typename mesh_type::edge_pred(), +.8, _mesh._eset.get_alloc()) ; - typename + typename mesh_type::face_list _fdup ( typename mesh_type::face_hash(), - typename mesh_type::face_pred(), + typename mesh_type::face_pred(), +.8, _mesh._fset.get_alloc()) ; - + containers::array < typename mesh_type:: edge_list::item_type*> _aset ; - - _edup._lptr.set_count ( - _tset.count() * +6 , - containers::loose_alloc, nullptr); - - _fdup._lptr.set_count ( - _tset.count() * +4 , - containers::loose_alloc, nullptr); - - for (auto _tpos = _tset.head() ; - _tpos != _tset.tend() ; + + _edup.set_slots ( + _tset.count() * +6 , + containers::tight_alloc) ; + + _fdup.set_slots ( + _tset.count() * +4 , + containers::tight_alloc) ; + + for (auto _tpos = _tset.head() ; + _tpos != _tset.tend() ; ++_tpos ) - { - /*--------------------- assemble 2-dim. topo disk */ + { + /*--------------------- assemble 2-dim. topo disk */ for (auto _fpos = +4; _fpos-- != +0; ) { iptr_type _fnod [ +4]; @@ -288,7 +288,7 @@ tria(*_tpos)->node(_fnod[1]); _fnod[2] = _mesh._tria. tria(*_tpos)->node(_fnod[2]); - + iptr_type _same = +0 ; if (_fnod[0] == _npos) _same += +1; @@ -297,16 +297,16 @@ if (_fnod[2] == _npos) _same += +1; if (_same != +1) continue ; - + algorithms::isort ( - &_fnod[0], &_fnod[3], + &_fnod[0], &_fnod[3], std::less()) ; - + face_data _fdat; _fdat._node[0] = _fnod[0] ; _fdat._node[1] = _fnod[1] ; _fdat._node[2] = _fnod[2] ; - + typename mesh_type:: face_list:: item_type*_mptr=nullptr; @@ -321,22 +321,22 @@ else { _fdup.push(_fdat) ; } - + _fset.push_tail(_mptr->_data ) ; } } - + iptr_type _fpos = +0; - for (auto _face = _fset.head() ; - _face != _fset.tend() ; + for (auto _face = _fset.head() ; + _face != _fset.tend() ; ++_face, ++_fpos) - { - /*--------------------- assemble 1-dim. topo disk */ + { + /*--------------------- assemble 1-dim. topo disk */ for (auto _epos = +3; _epos-- != +0; ) { iptr_type _tadj = _face->_tadj ; iptr_type _fadj = _face->_fadj ; - + iptr_type _fnod [ +4]; mesh_type::tria_type::tria_type:: face_node(_fnod, _fadj, 3, 2); @@ -346,61 +346,61 @@ tria( _tadj)->node(_fnod[1]); _fnod[2] = _mesh._tria. tria( _tadj)->node(_fnod[2]); - + iptr_type _enod [ +3] ; mesh_type::tria_type::tria_type:: face_node(_enod, _epos, 2, 1); _enod[0] = _fnod[_enod[ 0] ] ; _enod[1] = _fnod[_enod[ 1] ] ; - + iptr_type _same = +0; if (_enod[0] == _npos) _same += +1; if (_enod[1] == _npos) _same += +1; if (_same != +1) continue ; - + algorithms::isort ( - &_enod[0], &_enod[2], + &_enod[0], &_enod[2], std::less()) ; - + edge_data _edat; _edat._node[0] = _enod[0] ; _edat._node[1] = _enod[1] ; - - _edat._tadj = + + _edat._tadj = (iptr_type) _fpos ; //!! no ?? - _edat._eadj = + _edat._eadj = (char_type) _epos ; - + typename mesh_type:: edge_list:: item_type*_eptr=nullptr; if(!_edup.find(_edat, _eptr)) - { + { _edup.push(_edat) ; _eset. push_tail(_edat) ; } else - { + { _edup.push(_edat) ; } } } - - for (auto _edge = _eset.head() ; - _edge != _eset.tend() ; + + for (auto _edge = _eset.head() ; + _edge != _eset.tend() ; ++_edge ) { _aset.set_count ( +0, containers::loose_alloc); - + if(_edup.find(*_edge, _aset)) { /*------------------- "internal" topo. degree */ uint_type _topo = +2; - + typename mesh_type:: edge_list:: item_type*_eptr=nullptr; @@ -408,15 +408,15 @@ find_edge(*_edge, _eptr)) { /*------------------- "external" topo. degree */ - _topo = + _topo = _eptr->_data. _topo ; } - + if (_aset.count () != _topo ) return false ; - } + } } - + /*--------------------- count no. connected comp. */ return ftop_scan(_mesh, _fset, _edup) == 1; } @@ -428,7 +428,7 @@ */ __static_call - __normal_call + __normal_call typename rdel_opts::node_kind etop_node ( geom_type &_geom, mesh_type &_mesh, @@ -441,9 +441,9 @@ rdel_opts &_opts ) { - typename rdel_opts::node_kind + typename rdel_opts::node_kind _kind = rdel_opts::null_kind ; - + real_type _rEPS = std::pow ( std::numeric_limits ::epsilon (), +.75) ; @@ -454,14 +454,14 @@ _vdir[1] = (real_type) +0. ; _vdir[2] = (real_type) +0. ; _vdir[3] = (real_type) +0. ; - + _pmax[3] = (real_type) +0. ; - + /*--------------------- find max. SDB in edge-set */ for (auto _edge = _eset.head() ; _edge != _eset.tend() ; ++_edge ) - { + { mesh_type::tria_type:: tria_type::face_node( _enod, _edge->_eadj, 3, 1) ; @@ -471,22 +471,22 @@ _enod[1] =_mesh._tria. tria(_edge->_tadj) ->node( _enod[ 1]) ; - + char_type _hits; char_type _feat, _topo ; iptr_type _part; real_type _fbal[ +4] ; real_type _sbal[ +4] ; if (!mesh_pred::edge_ball ( - _geom, _mesh , - _edge->_tadj , - _edge->_eadj , - _fbal, _sbal , - _hits, _feat , + _geom, _mesh , + _edge->_tadj , + _edge->_eadj , + _fbal, _sbal , + _hits, _feat , _topo, _part ) ) - __assert( false && + __assert( false && "TOPO-NODE: edge-ball" ) ; - + real_type _edir[ +4] ; geometry::vector_3d ( &_mesh._tria. @@ -495,13 +495,13 @@ node(_enod[1])->pval(0) , _edir) ; - _edir[3] = + _edir[3] = geometry::length_3d(_edir) ; _edir[0]/= _edir[3] ; _edir[1]/= _edir[3] ; _edir[2]/= _edir[3] ; - - real_type _sign = + + real_type _sign = geometry::dot_3d(_edir, _vdir) ; if (_sign >= (real_type) +0. ) @@ -521,31 +521,31 @@ { _pmax[3] = _sbal[3]; - _kind = + _kind = rdel_opts::circ_kind ; _tdim = +1; - + _tadj = _edge->_tadj ; - + _pmax[0] = _sbal[0]; _pmax[1] = _sbal[1]; _pmax[2] = _sbal[2]; } } - - if(__chkbit(_opts.rule(), + + if(__chkbit(_opts.rule(), rdel_opts ::offT_kind) ) { - /*--------------------- calc. "skinny" off-centre */ - _vdir[3] = + /*--------------------- calc. "skinny" off-centre */ + _vdir[3] = geometry::length_3d(_vdir) ; _vdir[0]/= _vdir[3] ; _vdir[1]/= _vdir[3] ; _vdir[2]/= _vdir[3] ; - real_type _rrad = + real_type _rrad = std::sqrt(_pmax[ 3]); if (_vdir[3] >= _rEPS * _rrad) @@ -559,7 +559,7 @@ _fdat._nvec[0] = _vdir[0]; _fdat._nvec[1] = _vdir[1]; _fdat._nvec[2] = _vdir[2]; - + _fdat._rmin[0] = _ppos[0] - (real_type)+2.*_rrad ; _fdat._rmin[1] = _ppos[1] @@ -573,17 +573,17 @@ + (real_type)+2.*_rrad ; _fdat._rmax[2] = _ppos[2] + (real_type)+2.*_rrad ; - + mesh::keep_all_3d < real_type , iptr_type > _halo ; - _geom.intersect( _fdat , + _geom.intersect( _fdat , _halo ) ; - + auto _ioff = _halo._list.tend(); - real_type _dmin = + real_type _dmin = _rEPS * std::pow(_rrad, +2); real_type static constexpr @@ -593,9 +593,9 @@ +std::numeric_limits ::infinity(); - for (auto _iter = + for (auto _iter = _halo._list.head() ; - _iter != + _iter != _halo._list.tend() ; ++_iter ) { @@ -606,43 +606,43 @@ auto _nptr = &_mesh. _tria.node(_near)->pval(0) ; - real_type _nsqr = + real_type _nsqr = geometry::lensqr_3d ( &_iter->pval(0), _nptr) ; - real_type _dsqr = + real_type _dsqr = geometry::lensqr_3d ( &_iter->pval(0), _ppos) ; - if (_nsqr > _dsqr * + if (_nsqr > _dsqr * _NEAR ) if (_dsqr < _best && _dsqr > _dmin ) { - _kind = + _kind = rdel_opts::offT_kind ; - + _best = _dsqr ; _ioff = _iter ; } } - + if (_ioff != _halo._list.tend()) { _pmax[0] = _ioff->pval (0) ; _pmax[1] = _ioff->pval (1) ; _pmax[2] = _ioff->pval (2) ; - } - + } + } } - + return _kind ; } - + __static_call - __normal_call + __normal_call typename rdel_opts::node_kind ftop_node ( geom_type &_geom, mesh_type &_mesh, @@ -655,9 +655,9 @@ rdel_opts &_opts ) { - typename rdel_opts::node_kind + typename rdel_opts::node_kind _kind = rdel_opts::null_kind ; - + real_type _rEPS = std::pow ( std::numeric_limits ::epsilon (), +.75) ; @@ -668,9 +668,9 @@ _vnrm[1] = (real_type) +0. ; _vnrm[2] = (real_type) +0. ; _vnrm[3] = (real_type) +0. ; - + _pmax[3] = (real_type) +0. ; - + /*--------------------- find max. SDB in face-set */ for (auto _face = _fset.head() ; _face != _fset.tend() ; @@ -688,20 +688,20 @@ _fnod[2] =_mesh._tria. tria(_face->_tadj) ->node( _fnod[ 2]) ; - + char_type _feat, _topo ; iptr_type _part; real_type _fbal[ +4] ; real_type _sbal[ +4] ; if (!mesh_pred::face_ball ( - _geom, _mesh , - _face->_tadj , - _face->_fadj , - _fbal, _sbal , + _geom, _mesh , + _face->_tadj , + _face->_fadj , + _fbal, _sbal , _feat, _topo , _part) ) - __assert( false && + __assert( false && "TOPO-NODE: face-ball" ) ; - + real_type _fnrm[ +4] ; geometry::tria_norm_3d ( &_mesh._tria. @@ -712,13 +712,13 @@ node(_fnod[2])->pval(0) , _fnrm) ; - _fnrm[3] = + _fnrm[3] = geometry::length_3d(_fnrm) ; _fnrm[0]/= _fnrm[3] ; _fnrm[1]/= _fnrm[3] ; _fnrm[2]/= _fnrm[3] ; - real_type _sign = + real_type _sign = geometry::dot_3d(_fnrm, _vnrm) ; if (_sign >= (real_type) +0. ) @@ -733,57 +733,57 @@ _vnrm[1]-= _fnrm[1]; _vnrm[2]-= _fnrm[2]; } - + if (_pmax[3] < _sbal[3]) { _pmax[3] = _sbal[3]; - _kind = + _kind = rdel_opts::circ_kind ; _tdim = +2; - + _tadj = _face->_tadj ; - + _pmax[0] = _sbal[0]; _pmax[1] = _sbal[1]; _pmax[2] = _sbal[2]; } } - - if(__chkbit(_opts.rule(), + + if(__chkbit(_opts.rule(), rdel_opts ::offT_kind) ) { - /*--------------------- calc. "skinny" off-centre */ - _vnrm[3] = + /*--------------------- calc. "skinny" off-centre */ + _vnrm[3] = geometry::length_3d(_vnrm) ; _vnrm[0]/= _vnrm[3] ; _vnrm[1]/= _vnrm[3] ; _vnrm[2]/= _vnrm[3] ; - real_type _rrad = + real_type _rrad = std::sqrt(_pmax[ 3]); if (_vnrm[3] >= _rEPS * _rrad) { /*--------------------- project on local "normal" */ - _vnrm[0]*= _rrad * + _vnrm[0]*= _rrad * (real_type) +2. ; - _vnrm[1]*= _rrad * + _vnrm[1]*= _rrad * (real_type) +2. ; - _vnrm[2]*= _rrad * + _vnrm[2]*= _rrad * (real_type) +2. ; typename geom_type::line_type _ldat ; - _ldat._ipos[0] = _ppos[0] + _ldat._ipos[0] = _ppos[0] - _vnrm[0]; _ldat._ipos[1] = _ppos[1] - _vnrm[1]; _ldat._ipos[2] = _ppos[2] - _vnrm[2]; - + _ldat._jpos[0] = _ppos[0] + _vnrm[0]; _ldat._jpos[1] = _ppos[1] @@ -795,12 +795,12 @@ real_type , iptr_type > _halo ; - _geom.intersect( _ldat , + _geom.intersect( _ldat , _halo ) ; auto _ioff = _halo._list.tend(); - real_type _dmin = + real_type _dmin = _rEPS * std::pow(_rrad, +2); real_type static constexpr @@ -810,9 +810,9 @@ +std::numeric_limits ::infinity(); - for (auto _iter = + for (auto _iter = _halo._list.head() ; - _iter != + _iter != _halo._list.tend() ; ++_iter ) { @@ -823,28 +823,28 @@ auto _nptr = &_mesh. _tria.node(_near)->pval(0) ; - real_type _nsqr = + real_type _nsqr = geometry::lensqr_3d ( &_iter->pval(0), _nptr) ; - real_type _dsqr = + real_type _dsqr = geometry::lensqr_3d ( &_iter->pval(0), _ppos) ; - if (_nsqr > _dsqr * + if (_nsqr > _dsqr * _NEAR ) if (_dsqr < _best && _dsqr > _dmin ) { - _kind = + _kind = rdel_opts::offT_kind ; - + _best = _dsqr ; _ioff = _iter ; } } - + if (_ioff != _halo._list.tend()) { _pmax[0] = _ioff->pval (0) ; @@ -852,10 +852,10 @@ _pmax[2] = _ioff->pval (2) ; } - } + } } - return _kind ; + return _kind ; } /* @@ -864,16 +864,16 @@ -------------------------------------------------------- */ - __static_call - __normal_call + __static_call + __normal_call typename rdel_opts::node_kind _bad_etop ( geom_type &_geom , hfun_type &_hfun , mesh_type &_mesh , mode_type _mode , - typename + typename mesh_type::edge_list &_epro , - typename + typename mesh_type::face_list &_fpro , iptr_list &_nnew , iptr_list &_nold , @@ -900,11 +900,11 @@ { /*--------------------- find adj. set of tria-to-node */ public : - + typedef typename mesh_type::tria_type tria_type ; - public : + public : iptr_type _npos; public : @@ -915,9 +915,9 @@ __inline_call bool_type operator() ( tria_type&_tria, iptr_type _tpos, - iptr_type _fpos - ) - { + iptr_type _fpos + ) + { iptr_type _tnod[4] = { _tria.tria(_tpos)->node(0) , _tria.tria(_tpos)->node(1) , @@ -935,12 +935,12 @@ return true ; if (_tnod[3] == this->_npos) return true ; - + return false ; } } ; - typename rdel_opts::node_kind + typename rdel_opts::node_kind _kind = rdel_opts::null_kind ; /*--------------------- pop() leading element from PQ */ @@ -967,7 +967,7 @@ array _eset ; containers:: array _fset ; - + _tset.set_alloc( +32) ; _eset.set_alloc( +32) ; @@ -978,7 +978,7 @@ { node_data _ndat; _etpq._pop_root(_ndat) ; - + _npos = _ndat._node[0] ; _emrk[_npos] = -1; @@ -986,64 +986,64 @@ _tset.set_count( +0) ; _eset.set_count( +0) ; - _mesh._tria.walk_node( - _npos , + _mesh._tria.walk_node( + _npos , node_pred(_npos),_tset) ; - if (!etop_disk(_mesh, + if (!etop_disk(_mesh, _npos, _tset, _eset) ) { _find = true; break ; } } if (!_find) return _kind ; - + /*------------------------- calc. best node in cavity */ real_type _pmax [ +4] ; char_type _tmax = -1; iptr_type _hint = -1; - - auto _ppos = + + auto _ppos = &_mesh . _tria.node (_npos)->pval(0) ; - + _kind = etop_node( _geom, - _mesh , _eset, - _npos , _ppos, _pmax, + _mesh , _eset, + _npos , _ppos, _pmax, _tmax , _hint, _args) ; - + /*------------------------- push node via constraints */ - _kind = push_node( _geom, + _kind = push_node( _geom, _hfun , _mesh, _mode, _tmax , _pmax, _kind, _epro , _fpro, _nnew , _nold, - _tnew , _told, - _etmp , _ecav, _escr, - _ftmp , _fcav, _fscr, + _tnew , _told, + _etmp , _ecav, _escr, + _ftmp , _fcav, _fscr, _tcav , _tscr, _bcav , _bscr, _hint, _tdim , _pass, _args) ; - + return ( _kind ) ; } - + /* -------------------------------------------------------- * _BAD-FTOP: refine a "bad" face-disk. -------------------------------------------------------- */ - - __static_call - __normal_call + + __static_call + __normal_call typename rdel_opts::node_kind _bad_ftop ( geom_type &_geom , hfun_type &_hfun , mesh_type &_mesh , mode_type _mode , - typename + typename mesh_type::edge_list &_epro , - typename + typename mesh_type::face_list &_fpro , iptr_list &_nnew , iptr_list &_nold , @@ -1070,11 +1070,11 @@ { /*--------------------- find adj. set of tria-to-node */ public : - + typedef typename mesh_type::tria_type tria_type ; - public : + public : iptr_type _npos; public : @@ -1085,9 +1085,9 @@ __inline_call bool_type operator() ( tria_type&_tria, iptr_type _tpos, - iptr_type _fpos - ) - { + iptr_type _fpos + ) + { iptr_type _tnod[4] = { _tria.tria(_tpos)->node(0) , _tria.tria(_tpos)->node(1) , @@ -1105,12 +1105,12 @@ return true ; if (_tnod[3] == this->_npos) return true ; - + return false ; } } ; - typename rdel_opts::node_kind + typename rdel_opts::node_kind _kind = rdel_opts::null_kind ; /*--------------------- pop() leading element from PQ */ @@ -1125,7 +1125,7 @@ _fcav.set_count( + 0) ; _tscr.set_count( + 0) ; _tcav.set_count( + 0) ; - + _bscr.set_count( + 0) ; _bcav.set_count( + 0) ; @@ -1135,7 +1135,7 @@ array _eset ; containers:: array _fset ; - + _tset.set_alloc( +32) ; _eset.set_alloc( +32) ; _fset.set_alloc( +32) ; @@ -1147,7 +1147,7 @@ { node_data _ndat; _ftpq._pop_root(_ndat) ; - + _npos = _ndat._node[0] ; _fmrk[_npos] = -1; @@ -1156,48 +1156,48 @@ _eset.set_count( +0) ; _fset.set_count( +0) ; - _mesh._tria.walk_node( - _npos , + _mesh._tria.walk_node( + _npos , node_pred(_npos), _tset) ; - if (!ftop_disk(_mesh, - _npos, + if (!ftop_disk(_mesh, + _npos, _tset, _eset, _fset) ) { _find = true; break ; } } if (!_find) return _kind ; - + /*------------------------- calc. best node in cavity */ real_type _pmax [ +4] ; char_type _tmax = -1; iptr_type _hint = -1; - - auto _ppos = + + auto _ppos = &_mesh . _tria.node (_npos)->pval(0) ; - + _kind = ftop_node( _geom, - _mesh , _fset, - _npos , _ppos, _pmax, + _mesh , _fset, + _npos , _ppos, _pmax, _tmax , _hint, _args) ; - + /*------------------------- push node via constraints */ - _kind = push_node( _geom, + _kind = push_node( _geom, _hfun , _mesh, _mode, _tmax , _pmax, _kind, _epro , _fpro, _nnew , _nold, - _tnew , _told, - _etmp , _ecav, _escr, - _ftmp , _fcav, _fscr, + _tnew , _told, + _etmp , _ecav, _escr, + _ftmp , _fcav, _fscr, _tcav , _tscr, _bcav , _bscr, _hint, _tdim , _pass, _args) ; - + return ( _kind ) ; } - - + + diff --git a/src/libcpp/rdel_mesh/rdel_sink_delfront_2.inc b/src/libcpp/rdel_mesh/rdel_sink_delfront_2.inc index e7fd4ac..c014efb 100644 --- a/src/libcpp/rdel_mesh/rdel_sink_delfront_2.inc +++ b/src/libcpp/rdel_mesh/rdel_sink_delfront_2.inc @@ -1,57 +1,57 @@ /* -------------------------------------------------------- - * RDEL-PRED-DELFRONT-2: "frontal-DEL" kernel in R^2. + * RDEL-PRED-DELFRONT-2: "frontal-DEL" kernel in R^2. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 22 August, 2018 + * Last updated: 03 July, 2019 * - * Copyright 2013-2018 + * Copyright 2013-2019 * Darren Engwirda * de2363@columbia.edu * https://github.com/dengwirda/ * -------------------------------------------------------- */ - + // from rdel_pred_delfront_2.hpp - - + + /* -------------------------------------------------------- * TRIA-SINK: "sink"-based off-centre. -------------------------------------------------------- */ - __static_call - __normal_call + __static_call + __normal_call typename rdel_opts::node_kind tria_sink ( geom_type &_geom, hfun_type &_size, @@ -67,10 +67,10 @@ { /*-------------------- helper: find "sink" candidates */ public : - + typedef typename mesh_type::tria_type tria_type ; - + public : iptr_type _tnod[ 3] ; @@ -111,17 +111,17 @@ _nadj[2] == _tnod[1] || _nadj[2] == _tnod[2] ) _same += +1 ; - - return _same >= +1 ; + + return _same >= +2 ; } } ; - typename rdel_opts::node_kind + typename rdel_opts::node_kind _kind = rdel_opts::null_kind ; __unreferenced(_geom); __unreferenced(_size); - + /*-------------------------------- find list of sinks */ real_type _near = _args.snk2()* _args.snk2(); @@ -130,16 +130,16 @@ containers:: array _tset; _tset. set_alloc(+64); - _mesh._tria.walk_tria( _tpos, + _mesh._tria.walk_tria( _tpos, sink_pred(&_tnod[0]), _tset) ; - real_type static const _ftol = + real_type static const _ftol = std::pow( std::numeric_limits ::epsilon(),(real_type) +.80) ; real_type _best = _tbal[2] ; - real_type _btol = + real_type _btol = (real_type)+1. + _ftol ; _best *= _btol ; @@ -150,6 +150,18 @@ { if ( *_iter == _tpos) continue; + real_type _ball[3]; + _ball[0] = _mesh. + _tria.tria(*_iter)->circ(0); + _ball[1] = _mesh. + _tria.tria(*_iter)->circ(1); + + real_type _dsqr = geometry + ::lensqr_2d(_tbal, _ball) ; + + if (_dsqr < _near ) + { + /*-------------------------------- sink must be in DT */ iptr_type _nadj[ 3] ; _nadj[0] = _mesh. _tria.tria(*_iter)->node(0); @@ -163,13 +175,13 @@ _tdat._node[ 0] = _nadj[ 0]; _tdat._node[ 1] = _nadj[ 1]; _tdat._node[ 2] = _nadj[ 2]; - + typename mesh_type:: tria_list:: item_type *_tptr = nullptr ; - if (_mesh.find_tria(_tdat,_tptr)) + if (_mesh.find_tria(_tdat,_tptr)) { - if (_tptr->_data._kind + if (_tptr->_data._kind == mesh::good_item ) continue ;// skip good tria } @@ -177,38 +189,30 @@ { continue ;// not restricted } - real_type _ball[3]; - _ball[0] = _mesh. - _tria.tria(*_iter)->circ(0); - _ball[1] = _mesh. - _tria.tria(*_iter)->circ(1); - - _ball[2] = (real_type)+0. ; - _ball[2]+= - geometry::lensqr_2d (_ball, + /*-------------------------------- sink must inc ball */ + _ball[2] = (real_type)+0. ; + _ball[2]+= + geometry::lensqr_2d (_ball, &_mesh._tria.node( _nadj[0])->pval(0)) ; - _ball[2]+= - geometry::lensqr_2d (_ball, + _ball[2]+= + geometry::lensqr_2d (_ball, &_mesh._tria.node( _nadj[1])->pval(0)) ; - _ball[2]+= - geometry::lensqr_2d (_ball, + _ball[2]+= + geometry::lensqr_2d (_ball, &_mesh._tria.node( _nadj[2])->pval(0)) ; - - _ball[2]/= (real_type)+3. ; - real_type _dsqr = geometry - ::lensqr_2d(_tbal, _ball) ; + _ball[2]/= (real_type)+3. ; + - if (_dsqr < _near ) - { if (_best < _ball[2]) { + /*-------------------------------- retain best so far */ _best = _ball[2]; - _kind = + _kind = rdel_opts::sink_kind ; _ppos[0] = _ball[0]; @@ -219,6 +223,6 @@ return ( _kind ) ; } - - - + + + diff --git a/src/libcpp/rdel_mesh/rdel_sink_delfront_3.inc b/src/libcpp/rdel_mesh/rdel_sink_delfront_3.inc index 1eee356..da559db 100644 --- a/src/libcpp/rdel_mesh/rdel_sink_delfront_3.inc +++ b/src/libcpp/rdel_mesh/rdel_sink_delfront_3.inc @@ -1,57 +1,57 @@ /* -------------------------------------------------------- - * RDEL-PRED-DELFRONT-3: "frontal-DEL" kernel in R^3. + * RDEL-PRED-DELFRONT-3: "frontal-DEL" kernel in R^3. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 22 August, 2018 + * Last updated: 03 July, 2019 * - * Copyright 2013-2018 + * Copyright 2013-2019 * Darren Engwirda * de2363@columbia.edu * https://github.com/dengwirda/ * -------------------------------------------------------- */ - + // from rdel_pred_delfront_3.hpp - - + + /* -------------------------------------------------------- * FACE-SINK: "sink"-based off-centre. -------------------------------------------------------- */ - - __static_call - __normal_call + + __static_call + __normal_call typename rdel_opts::node_kind face_sink ( geom_type &_geom, hfun_type &_size, @@ -67,10 +67,10 @@ { /*-------------------- helper: find "sink" candidates */ public : - + typedef typename mesh_type::tria_type tria_type ; - + public : iptr_type _fnod[ 3] ; @@ -116,12 +116,12 @@ _tnod[3] == _fnod[1] || _tnod[3] == _fnod[2] ) _same += +1 ; - - return ( _same >= +1 ) ; + + return ( _same >= +2 ) ; } } ; - typename rdel_opts::node_kind + typename rdel_opts::node_kind _kind = rdel_opts::null_kind ; __unreferenced(_size); @@ -130,34 +130,27 @@ containers:: array _tset; _tset. set_alloc(+64); - _mesh._tria.walk_tria(_tadj, + _mesh._tria.walk_tria(_tadj, sink_pred(&_fnod[0]),_tset) ; - - typename - mesh_type::face_list _fset ( - typename mesh_type::face_hash(), - typename mesh_type::face_pred(), - +.8,_mesh._fset.get_alloc() - ) ; real_type _near = _args.snk2() * _args.snk2() ; _near *= _fbal[3] ; - real_type static const _ftol = + real_type static const _ftol = std::pow( std::numeric_limits ::epsilon(),(real_type) +.80) ; real_type _best = _fbal[3] ; - real_type _btol = + real_type _btol = (real_type)+1. + _ftol ; _best *= _btol ; /*-------------------------------- keep the best sink */ iptr_type _fpos ; - for (auto _tpos = _tset.head(); - _tpos != _tset.tend(); + for (auto _tpos = _tset.head(); + _tpos != _tset.tend(); ++_tpos ) { for (_fpos = +4 ; _fpos-- != +0; ) @@ -173,6 +166,7 @@ _snod[2] = _mesh._tria. tria(*_tpos)->node(_snod[2]); + /*-------------------------------- test sink topology */ if (_mesh._tria. node(_snod[0])->fdim() > +2 || _mesh._tria. @@ -181,6 +175,23 @@ node(_snod[2])->fdim() > +2 ) continue ; + iptr_type _same = +0; + if (_snod[0] == _fnod[0] || + _snod[0] == _fnod[1] || + _snod[0] == _fnod[2] ) + _same += +1 ; + if (_snod[1] == _fnod[0] || + _snod[1] == _fnod[1] || + _snod[1] == _fnod[2] ) + _same += +1 ; + if (_snod[2] == _fnod[0] || + _snod[2] == _fnod[1] || + _snod[2] == _fnod[2] ) + _same += +1 ; + if (_same == +0) continue; + if (_same == +3) continue; + + /*-------------------------------- sink must be in DT */ algorithms::isort ( &_snod[0], &_snod[3], std::less()) ; @@ -194,42 +205,37 @@ typename mesh_type:: face_list:: item_type *_fptr = nullptr ; - if (_mesh.find_face(_fdat,_fptr)) + if (_mesh.find_face(_fdat,_fptr)) { - if (_fptr->_data._kind + if (_fptr->_data._kind == mesh::good_item ) continue ;// skip good face } else { continue ;// not restricted - } - - if (_fset.find(_fdat, _fptr)) - { continue ;// only test once - } - else - { _fset.push(_fdat) ; } + /*-------------------------------- sink must inc ball */ char_type _feat, _topo; iptr_type _itag; real_type _sbal[4]; real_type _junk[4]; - base_type::face_ball(_geom , - _mesh , *_tpos , _fpos , - _junk , _sbal , _feat , + base_type::face_ball(_geom , + _mesh , *_tpos , _fpos , + _junk , _sbal , _feat , _topo , _itag ) ; - real_type _dsqr = + real_type _dsqr = geometry::lensqr_3d(_fbal,_sbal); if (_dsqr < _near ) { if (_best < _sbal[3]) { + /*-------------------------------- retain best so far */ _best = _sbal[3]; - _kind = + _kind = rdel_opts::sink_kind ; _ppos[0] = _sbal[0]; @@ -242,15 +248,15 @@ return ( _kind ) ; } - + /* -------------------------------------------------------- * TRIA-SINK: "sink"-based off-centre. -------------------------------------------------------- */ - - __static_call - __normal_call + + __static_call + __normal_call typename rdel_opts::node_kind tria_sink ( geom_type &_geom, hfun_type &_size, @@ -266,10 +272,10 @@ { /*-------------------- helper: find "sink" candidates */ public : - + typedef typename mesh_type::tria_type tria_type ; - + public : iptr_type _tnod[ 4] ; @@ -320,17 +326,17 @@ _nadj[3] == _tnod[2] || _nadj[3] == _tnod[3] ) _same += +1 ; - - return _same >= +1 ; + + return _same >= +2 ; } } ; - typename rdel_opts::node_kind + typename rdel_opts::node_kind _kind = rdel_opts::null_kind ; __unreferenced(_geom); __unreferenced(_size); - + /*-------------------------------- find list of sinks */ real_type _near = _args.snk3()* _args.snk3(); @@ -339,16 +345,16 @@ containers:: array _tset; _tset. set_alloc(+64); - _mesh._tria.walk_tria( _tpos, + _mesh._tria.walk_tria( _tpos, sink_pred(&_tnod[0]), _tset) ; - real_type static const _ftol = + real_type static const _ftol = std::pow( std::numeric_limits ::epsilon(),(real_type) +.80) ; real_type _best = _tbal[3] ; - real_type _btol = + real_type _btol = (real_type)+1. + _ftol ; _best *= _btol ; @@ -359,6 +365,20 @@ { if ( *_iter == _tpos) continue; + real_type _ball[4]; + _ball[0] = _mesh. + _tria.tria(*_iter)->circ(0); + _ball[1] = _mesh. + _tria.tria(*_iter)->circ(1); + _ball[2] = _mesh. + _tria.tria(*_iter)->circ(2); + + real_type _dsqr = geometry + ::lensqr_3d(_tbal, _ball) ; + + if (_dsqr < _near ) + { + /*-------------------------------- sink must be in DT */ iptr_type _nadj[4]; _nadj[0] = _mesh. _tria.tria(*_iter)->node(0); @@ -375,13 +395,13 @@ _tdat._node[ 1] = _nadj[ 1]; _tdat._node[ 2] = _nadj[ 2]; _tdat._node[ 3] = _nadj[ 3]; - + typename mesh_type:: tria_list:: item_type *_tptr = nullptr ; - if (_mesh.find_tria(_tdat,_tptr)) + if (_mesh.find_tria(_tdat,_tptr)) { - if (_tptr->_data._kind + if (_tptr->_data._kind == mesh::good_item ) continue ;// skip good tria } @@ -389,42 +409,32 @@ { continue ;// not restricted } - real_type _ball[4]; - _ball[0] = _mesh. - _tria.tria(*_iter)->circ(0); - _ball[1] = _mesh. - _tria.tria(*_iter)->circ(1); - _ball[2] = _mesh. - _tria.tria(*_iter)->circ(2); - - _ball[3] = (real_type)+.0 ; - _ball[3]+= - geometry::lensqr_3d (_ball, + /*-------------------------------- sink must inc ball */ + _ball[3] = (real_type)+.0 ; + _ball[3]+= + geometry::lensqr_3d (_ball, &_mesh._tria.node( _nadj[0])->pval(0)) ; - _ball[3]+= - geometry::lensqr_3d (_ball, + _ball[3]+= + geometry::lensqr_3d (_ball, &_mesh._tria.node( _nadj[1])->pval(0)) ; - _ball[3]+= - geometry::lensqr_3d (_ball, + _ball[3]+= + geometry::lensqr_3d (_ball, &_mesh._tria.node( _nadj[2])->pval(0)) ; - _ball[3]+= - geometry::lensqr_3d (_ball, + _ball[3]+= + geometry::lensqr_3d (_ball, &_mesh._tria.node( _nadj[3])->pval(0)) ; - - _ball[3]/= (real_type)+4. ; - real_type _dsqr = geometry - ::lensqr_3d(_tbal, _ball) ; + _ball[3]/= (real_type)+4. ; + - if (_dsqr < _near ) - { if (_best < _ball[3]) { - _kind = + /*-------------------------------- retain best so far */ + _kind = rdel_opts::sink_kind ; _best = _ball[3]; @@ -438,6 +448,6 @@ return ( _kind ) ; } - - - + + + diff --git a/src/libcpp/rdel_mesh/rdel_test_bounds_2.inc b/src/libcpp/rdel_mesh/rdel_test_bounds_2.inc index 7d83f48..0439050 100644 --- a/src/libcpp/rdel_mesh/rdel_test_bounds_2.inc +++ b/src/libcpp/rdel_mesh/rdel_test_bounds_2.inc @@ -1,37 +1,37 @@ /* -------------------------------------------------------- - * RDEL-BOUNDS-2: test restricted boundaries in R^2. + * RDEL-BOUNDS-2: test restricted boundaries in R^2. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 09 April, 2019 + * Last updated: 03 July, 2019 * * Copyright 2013-2019 * Darren Engwirda @@ -40,15 +40,15 @@ * -------------------------------------------------------- */ - + // from rdel_mesh_2.hpp - - + + # define __GEOMBNDS - + /* -------------------------------------------------------- - * FIND-RDEL: assemble restricted faces in cavity. + * FIND-RDEL: assemble restricted faces in cavity. -------------------------------------------------------- */ @@ -67,7 +67,7 @@ _tpos != _tset.tend(); ++_tpos ) { - /*------------------------- extract restricted 1-face */ + /*------------------------- extract restricted 1-face */ for ( auto _epos = 3; _epos-- != 0; ) { iptr_type _tnod[ +3] ; @@ -77,7 +77,7 @@ tria(*_tpos)->node(_tnod[0]) ; _tnod[1] = _mesh._tria. tria(*_tpos)->node(_tnod[1]) ; - + if (_mesh._tria. node(_tnod[0])->fdim()>1 || _mesh._tria. @@ -85,7 +85,7 @@ continue ; algorithms::isort ( - &_tnod[0], &_tnod[2], + &_tnod[0], &_tnod[2], std::less()) ; edge_data _fdat; @@ -102,7 +102,7 @@ } } } - + /* -------------------------------------------------------- * _CAV-BNDS: return TRUE if encroachment found. @@ -121,16 +121,16 @@ ) { bool_type _bnds = false; - + __unreferenced( _told ); - - real_type static const _pert = + + real_type static const _pert = std::pow( std::numeric_limits ::epsilon(),(real_type)+.8); - + _pmax[2] = (real_type) +.0 ; - + if (_mode > +1) { for ( auto _epos = _enew.head(); @@ -143,40 +143,40 @@ real_type _fbal[ +3] ; real_type _sbal[ +3] ; if (!mesh_pred::edge_ball ( - _geom, _mesh , - _epos->_tadj , - _epos->_eadj , + _geom, _mesh , + _epos->_tadj , + _epos->_eadj , _fbal, _sbal , _feat, _topo , _part ) ) - __assert( false && + __assert( false && "_NEW-BNDS: edge-ball" ) ; - - real_type _blen = + + real_type _blen = geometry::lensqr_2d(_pcur, _sbal) ; - + _blen += _pert * _blen; - + typename mesh_type:: edge_list:: item_type *_mptr=nullptr; if(!_mesh. find_edge(*_epos, _mptr)) { - /*----------------- keep worst TOPO. encroachment */ + /*----------------- keep worst TOPO. encroachment */ if (_pmax[2] < _sbal[2]) { _pmax[2] = _sbal[2]; _mode = + 1 ; - + _bnds = true ; _pmax[0] = _sbal[0]; _pmax[1] = _sbal[1]; } } - + # ifdef __GEOMBNDS if (_blen < _sbal[2]) { @@ -186,7 +186,7 @@ _pmax[2] = _sbal[2]; _mode = + 1 ; - + _bnds = true ; _pmax[0] = _sbal[0]; @@ -196,7 +196,7 @@ # endif//__GEOMBNDS } } - + return _bnds ; } @@ -218,29 +218,30 @@ char_type &_mode ) { + real_type static const _pert = + std::pow( + std::numeric_limits + ::epsilon(),(real_type)+.80) ; + bool_type _bnds = false; - + + __unreferenced( _told ); + + if (_mode > +0) + { /*------------------------- init. for local hash obj. */ - typename + typename mesh_type::edge_list _eset ( typename mesh_type::edge_hash(), - typename mesh_type::edge_pred(), + typename mesh_type::edge_pred(), +.8, _mesh._eset.get_alloc()) ; - + /*------------------------- push alloc. for hash obj. */ - _eset._lptr.set_count ( - _enew.count() * +2 , - containers::loose_alloc, nullptr); - - __unreferenced( _told ); + _eset.set_slots ( + _enew.count() * +2 , + containers::tight_alloc) ; - real_type static const _pert = - std::pow( - std::numeric_limits - ::epsilon(),(real_type)+.80) ; - - if (_mode > +0) - { + /*---------------------------------------- test edges */ for ( auto _epos = _enew.head(); _epos != _enew.tend(); ++_epos ) @@ -257,39 +258,39 @@ real_type _fbal[ +3] ; real_type _sbal[ +3] ; if (!mesh_pred::edge_ball ( - _geom, _mesh , - _epos->_tadj , - _epos->_eadj , - _fbal, _sbal , + _geom, _mesh , + _epos->_tadj , + _epos->_eadj , + _fbal, _sbal , _feat, _topo , _part ) ) - __assert( false && + __assert( false && "_OLD-BNDS: edge-ball" ) ; - - real_type _blen = + + real_type _blen = geometry::lensqr_2d(_ppos, _sbal) ; - + _blen += _pert * _blen; - + typename mesh_type:: edge_list:: item_type *_mptr=nullptr; if(!_eset.find(*_epos, _mptr)) { - /*----------------- keep worst TOPO. encroachment */ + /*----------------- keep worst TOPO. encroachment */ if (_pmax[2] < _sbal[2]) { _pmax[2] = _sbal[2]; _mode = + 1 ; - + _bnds = true ; _pmax[0] = _sbal[0]; _pmax[1] = _sbal[1]; - } } - + } + # ifdef __GEOMBNDS if (_blen < _sbal[2]) { @@ -299,7 +300,7 @@ _pmax[2] = _sbal[2]; _mode = + 1 ; - + _bnds = true ; _pmax[0] = _sbal[0]; @@ -309,7 +310,7 @@ # endif//__GEOMBNDS } } - + return _bnds ; } @@ -318,13 +319,13 @@ * _CAV-BNDS: return TRUE if encroachment found. -------------------------------------------------------- */ - + __static_call __normal_call bool_type _cav_bnds ( geom_type &_geom , mesh_type &_mesh , iptr_list &_told , - typename + typename mesh_type::edge_list &_epro , // "protected" edges edat_list &_enew , edat_list &_eold @@ -336,24 +337,24 @@ if (_epro.count() > +0) { /*------------------------- init. for local hash obj. */ - typename + typename mesh_type::edge_list _eset ( typename mesh_type::edge_hash(), - typename mesh_type::edge_pred(), + typename mesh_type::edge_pred(), +.8, _mesh._eset.get_alloc()) ; - + /*------------------------- push alloc. for hash obj. */ - _eset._lptr.set_count ( - _enew.count() * +2 , - containers::loose_alloc,nullptr) ; - + _eset.set_slots ( + _enew.count() * +2 , + containers::tight_alloc) ; + for ( auto _epos = _enew.head(); _epos != _enew.tend(); ++_epos ) { _eset.push(*_epos) ; } - + for ( auto _epos = _eold.head(); _epos != _eold.tend(); ++_epos ) @@ -377,6 +378,6 @@ #undef __GEOMBNDS - - - + + + diff --git a/src/libcpp/rdel_mesh/rdel_test_bounds_3.inc b/src/libcpp/rdel_mesh/rdel_test_bounds_3.inc index bfc779b..75a516c 100644 --- a/src/libcpp/rdel_mesh/rdel_test_bounds_3.inc +++ b/src/libcpp/rdel_mesh/rdel_test_bounds_3.inc @@ -1,37 +1,37 @@ /* -------------------------------------------------------- - * RDEL-BOUNDS-3: test restricted boundaries in R^3. + * RDEL-BOUNDS-3: test restricted boundaries in R^3. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 09 April, 2019 + * Last updated: 03 July, 2019 * * Copyright 2013-2019 * Darren Engwirda @@ -40,18 +40,18 @@ * -------------------------------------------------------- */ - + // from rdel_mesh_3.hpp - - + + # define __GEOMBNDS /* -------------------------------------------------------- - * FIND-RDEL: assemble restricted faces in cavity. + * FIND-RDEL: assemble restricted faces in cavity. -------------------------------------------------------- */ - + __static_call __normal_call void_type find_rdel ( geom_type &_geom , @@ -61,14 +61,14 @@ fdat_list &_fcav ) { - /*------------------------- extract restricted k-face */ + /*------------------------- extract restricted k-face */ __unreferenced(_geom) ; for ( auto _tpos = _tset.head(); _tpos != _tset.tend(); ++_tpos ) { - /*------------------------- extract restricted 1-face */ + /*------------------------- extract restricted 1-face */ for ( auto _epos = 6; _epos-- != 0; ) { iptr_type _tnod[ +4] ; @@ -78,7 +78,7 @@ tria(*_tpos)->node(_tnod[0]) ; _tnod[1] = _mesh._tria. tria(*_tpos)->node(_tnod[1]) ; - + if (_mesh._tria. node(_tnod[0])->fdim()>1 || _mesh._tria. @@ -86,7 +86,7 @@ continue ; algorithms::isort ( - &_tnod[0], &_tnod[2], + &_tnod[0], &_tnod[2], std::less()) ; edge_data _fdat; @@ -97,7 +97,7 @@ edge_list:: item_type *_mptr=nullptr ; if (_mesh. - find_edge(_fdat, _mptr)) + find_edge(_fdat, _mptr)) _ecav. push_tail(_mptr->_data); } @@ -113,7 +113,7 @@ tria(*_tpos)->node(_tnod[1]) ; _tnod[2] = _mesh._tria. tria(*_tpos)->node(_tnod[2]) ; - + if (_mesh._tria. node(_tnod[0])->fdim()>2 || _mesh._tria. @@ -123,7 +123,7 @@ continue ; algorithms::isort ( - &_tnod[0], &_tnod[3], + &_tnod[0], &_tnod[3], std::less()) ; face_data _fdat; @@ -135,11 +135,11 @@ face_list:: item_type *_mptr=nullptr ; if (_mesh. - find_face(_fdat, _mptr)) + find_face(_fdat, _mptr)) _fcav. push_tail(_mptr->_data); - } - } + } + } } /* @@ -161,16 +161,16 @@ ) { bool_type _bnds = false; - + __unreferenced( _told ); - - real_type static const _pert = + + real_type static const _pert = std::pow( std::numeric_limits ::epsilon(),(real_type)+.80) ; - + _pmax[ 3] = (real_type)+.00 ; - + if (_mode > +1) { /*---------------------------------------- test edges */ @@ -185,34 +185,34 @@ real_type _fbal[ +4] ; real_type _sbal[ +4] ; if (!mesh_pred::edge_ball ( - _geom, _mesh , - _epos->_tadj , - _epos->_eadj , + _geom, _mesh , + _epos->_tadj , + _epos->_eadj , _fbal, _sbal , - _hits, _feat , + _hits, _feat , _topo, _part ) ) - __assert( false && + __assert( false && "_NEW-BNDS: edge-ball" ); - - real_type _blen = + + real_type _blen = geometry::lensqr_3d(_pcur, _sbal) ; - + _blen += _pert * _blen ; - + typename mesh_type:: edge_list:: item_type *_mptr=nullptr ; if(!_mesh. find_edge(*_epos, _mptr)) - { - /*----------------- keep worst TOPO. encroachment */ + { + /*----------------- keep worst TOPO. encroachment */ if (_pmax[3] < _sbal[3]) { _pmax[3] = _sbal[3]; _mode = + 1 ; - + _bnds = true ; _pmax[0] = _sbal[0]; @@ -220,7 +220,7 @@ _pmax[2] = _sbal[2]; } } - + # ifdef __GEOMBNDS if (_blen < _sbal[3]) { @@ -230,7 +230,7 @@ _pmax[3] = _sbal[3]; _mode = + 1 ; - + _bnds = true ; _pmax[0] = _sbal[0]; @@ -241,7 +241,7 @@ # endif//__GEOMBNDS } } - + if (_mode > +2) { /*---------------------------------------- test faces */ @@ -255,20 +255,20 @@ real_type _fbal[ +4] ; real_type _sbal[ +4] ; if (!mesh_pred::face_ball ( - _geom, _mesh , - _fpos->_tadj , - _fpos->_fadj , + _geom, _mesh , + _fpos->_tadj , + _fpos->_fadj , _fbal, _sbal , _feat, _topo , _part) ) - __assert( false && + __assert( false && "_NEW-BNDS: face-ball" ); - - real_type _blen = + + real_type _blen = geometry::lensqr_3d(_pcur, _sbal) ; - + _blen += _pert * _blen ; - + typename mesh_type:: face_list:: item_type *_mptr=nullptr ; @@ -281,7 +281,7 @@ _pmax[3] = _sbal[3]; _mode = + 2 ; - + _bnds = true ; _pmax[0] = _sbal[0]; @@ -289,7 +289,7 @@ _pmax[2] = _sbal[2]; } } - + # ifdef __GEOMBNDS if (_blen < _sbal[3]) { @@ -299,7 +299,7 @@ _pmax[3] = _sbal[3]; _mode = + 2 ; - + _bnds = true ; _pmax[0] = _sbal[0]; @@ -310,7 +310,7 @@ # endif//__GEOMBNDS } } - + return _bnds ; } @@ -334,38 +334,30 @@ char_type &_mode ) { + real_type static const _pert = + std::pow( + std::numeric_limits + ::epsilon(),(real_type)+.80) ; + bool_type _bnds = false; - + + __unreferenced( _told ); + + if (_mode > +0) + { /*------------------------- init. for local hash obj. */ - typename + typename mesh_type::edge_list _eset ( typename mesh_type::edge_hash(), - typename mesh_type::edge_pred(), + typename mesh_type::edge_pred(), +.8, _mesh._eset.get_alloc()) ; - typename - mesh_type::face_list _fset ( - typename mesh_type::face_hash(), - typename mesh_type::face_pred(), - +.8, _mesh._fset.get_alloc()) ; /*------------------------- push alloc. for hash obj. */ - _eset._lptr.set_count ( - _enew.count() * +2 , - containers::loose_alloc, nullptr); - _fset._lptr.set_count ( - _fnew.count() * +2 , - containers::loose_alloc, nullptr); - - __unreferenced( _told ); + _eset.set_slots ( + _enew.count() * +2 , + containers::tight_alloc) ; - real_type static const _pert = - std::pow( - std::numeric_limits - ::epsilon(),(real_type)+.80) ; - - if (_mode > +0) - { - /*---------------------------------------- test edges */ + /*---------------------------------------- test edges */ for ( auto _epos = _enew.head(); _epos != _enew.tend(); ++_epos ) @@ -383,41 +375,41 @@ real_type _fbal[ +4] ; real_type _sbal[ +4] ; if (!mesh_pred::edge_ball ( - _geom, _mesh , - _epos->_tadj , - _epos->_eadj , - _fbal, _sbal , - _hits, _feat , + _geom, _mesh , + _epos->_tadj , + _epos->_eadj , + _fbal, _sbal , + _hits, _feat , _topo, _part ) ) - __assert( false && + __assert( false && "_old_bnds: edge-ball" ); - - real_type _blen = + + real_type _blen = geometry::lensqr_3d(_ppos, _sbal) ; - + _blen += _pert * _blen ; - + typename mesh_type:: edge_list:: item_type *_mptr=nullptr; if(!_eset.find(*_epos, _mptr)) { - /*----------------- keep worst TOPO. encroachment */ + /*----------------- keep worst TOPO. encroachment */ if (_pmax[3] < _sbal[3]) { _pmax[3] = _sbal[3]; _mode = + 1 ; - + _bnds = true ; _pmax[0] = _sbal[0]; _pmax[1] = _sbal[1]; _pmax[2] = _sbal[2]; - } } - + } + # ifdef __GEOMBNDS if (_blen < _sbal[3]) { @@ -427,7 +419,7 @@ _pmax[3] = _sbal[3]; _mode = + 1 ; - + _bnds = true ; _pmax[0] = _sbal[0]; @@ -438,9 +430,21 @@ # endif//__GEOMBNDS } } - + if (_mode > +1) { + /*------------------------- init. for local hash obj. */ + typename + mesh_type::face_list _fset ( + typename mesh_type::face_hash(), + typename mesh_type::face_pred(), + +.8, _mesh._fset.get_alloc()) ; + + /*------------------------- push alloc. for hash obj. */ + _fset.set_slots ( + _fnew.count() * +2 , + containers::tight_alloc) ; + /*---------------------------------------- test faces */ for ( auto _fpos = _fnew.head(); _fpos != _fnew.tend(); @@ -458,32 +462,32 @@ real_type _fbal[ +4] ; real_type _sbal[ +4] ; if (!mesh_pred::face_ball ( - _geom, _mesh , - _fpos->_tadj , - _fpos->_fadj , - _fbal, _sbal , + _geom, _mesh , + _fpos->_tadj , + _fpos->_fadj , + _fbal, _sbal , _feat, _topo , _part) ) - __assert( false && + __assert( false && "_OLD-BNDS: face-ball" ); - - real_type _blen = + + real_type _blen = geometry::lensqr_3d(_ppos, _sbal) ; - + _blen += _pert * _blen; - + typename mesh_type:: face_list:: item_type *_mptr=nullptr; if(!_fset.find(*_fpos, _mptr)) - { + { /*----------------- keep worst TOPO. encroachment */ if (_pmax[3] < _sbal[3]) { _pmax[3] = _sbal[3]; _mode = + 2 ; - + _bnds = true ; _pmax[0] = _sbal[0]; @@ -491,7 +495,7 @@ _pmax[2] = _sbal[2]; } } - + # ifdef __GEOMBNDS if (_blen < _sbal[3]) { @@ -501,7 +505,7 @@ _pmax[3] = _sbal[3]; _mode = + 2 ; - + _bnds = true ; _pmax[0] = _sbal[0]; @@ -512,7 +516,7 @@ # endif//__GEOMBNDS } } - + return _bnds ; } @@ -527,9 +531,9 @@ geom_type &_geom , mesh_type &_mesh , iptr_list &_told , - typename + typename mesh_type::edge_list &_epro , // "protected" edges - typename + typename mesh_type::face_list &_fpro , // "protected" faces edat_list &_enew , fdat_list &_fnew , @@ -543,24 +547,24 @@ if (_epro.count() > +0) { /*------------------------- init. for local hash obj. */ - typename + typename mesh_type::edge_list _eset ( typename mesh_type::edge_hash(), - typename mesh_type::edge_pred(), + typename mesh_type::edge_pred(), +.8, _mesh._eset.get_alloc()) ; - + /*------------------------- push alloc. for hash obj. */ - _eset._lptr.set_count ( - _enew.count() * +2 , - containers::loose_alloc,nullptr) ; - + _eset.set_slots ( + _enew.count() * +2 , + containers::tight_alloc) ; + for ( auto _epos = _enew.head(); _epos != _enew.tend(); ++_epos ) { _eset.push(*_epos) ; } - + for ( auto _epos = _eold.head(); _epos != _eold.tend(); ++_epos ) @@ -582,16 +586,16 @@ if (_fpro.count() > +0) { /*------------------------- init. for local hash obj. */ - typename + typename mesh_type::face_list _fset ( typename mesh_type::face_hash(), - typename mesh_type::face_pred(), + typename mesh_type::face_pred(), +.8, _mesh._fset.get_alloc()) ; /*------------------------- push alloc. for hash obj. */ - _fset._lptr.set_count ( - _fnew.count() * +2 , - containers::loose_alloc,nullptr) ; + _fset.set_slots ( + _fnew.count() * +2 , + containers::tight_alloc) ; for ( auto _fpos = _fnew.head(); _fpos != _fnew.tend(); @@ -599,7 +603,7 @@ { _fset.push(*_fpos) ; } - + for ( auto _fpos = _fold.head(); _fpos != _fold.tend(); ++_fpos ) diff --git a/src/libcpp/rdel_mesh/rdel_timers.hpp b/src/libcpp/rdel_mesh/rdel_timers.hpp index 1369bf8..2c5c7b1 100644 --- a/src/libcpp/rdel_mesh/rdel_timers.hpp +++ b/src/libcpp/rdel_mesh/rdel_timers.hpp @@ -4,29 +4,29 @@ * RDEL-TIMERS: CPU timers for RDEL-MESH-K. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- @@ -53,20 +53,20 @@ * RDEL-TIMERS: cpu timers for RDEL-MESH-K -------------------------------------------------------- */ - + template < - typename R , + typename R , typename I > class rdel_timers { public : - + typedef R real_type ; typedef I iptr_type ; - + typedef rdel_timers self_type ; - + real_type _mesh_seed = (real_type) +0. ; real_type _node_init = (real_type) +0. ; real_type _node_rule = (real_type) +0. ; @@ -76,13 +76,13 @@ real_type _face_rule = (real_type) +0. ; real_type _tria_init = (real_type) +0. ; real_type _tria_rule = (real_type) +0. ; - + public : - + /*-------------------------------------- elapsed time */ - + # ifdef __use_timers - + __inline_call double time_span ( typename std:: chrono::high_resolution_clock @@ -99,7 +99,7 @@ } # endif//__use_timers - + } ; } diff --git a/src/libcpp/rdel_mesh/rdel_update_face_2.inc b/src/libcpp/rdel_mesh/rdel_update_face_2.inc index 1dd48d6..4b0a9c8 100644 --- a/src/libcpp/rdel_mesh/rdel_update_face_2.inc +++ b/src/libcpp/rdel_mesh/rdel_update_face_2.inc @@ -1,37 +1,37 @@ /* -------------------------------------------------------- - * RDEL-UPDATE-2: update restricted delaunay in R^2. + * RDEL-UPDATE-2: update restricted delaunay in R^2. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 02 February, 2019 + * Last updated: 06 July, 2019 * * Copyright 2013-2019 * Darren Engwirda @@ -40,17 +40,17 @@ * -------------------------------------------------------- */ - + // from rdel_mesh_2.hpp - - + + /* -------------------------------------------------------- - * _POP-EDGE: delete edge from restricted-tria. + * _POP-EDGE: delete edge from restricted-tria. -------------------------------------------------------- */ - - __static_call + + __static_call __normal_call void_type _pop_edge ( mesh_type &_mesh , iptr_type _tpos @@ -69,24 +69,24 @@ tria(_tpos)->node(_tnod[1]); algorithms::isort ( - &_tnod[0], &_tnod[2], + &_tnod[0], &_tnod[2], std::less()); - edge_data _edat, _same ; + edge_data _edat; _edat._node[0] = _tnod[0]; _edat._node[1] = _tnod[1]; /*--------------------------------- remove if present */ - _mesh._pop_edge(_edat, _same) ; + _mesh._pop_edge(_edat); } } - + /* -------------------------------------------------------- - * _POP-TRIA: delete tria from restricted-tria. + * _POP-TRIA: delete tria from restricted-tria. -------------------------------------------------------- */ - + __static_call __normal_call void_type _pop_tria ( mesh_type &_mesh , @@ -95,25 +95,25 @@ { { /*--------------------------------- get tria indexing */ - tria_data _tdat, _same; + 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); - + /*--------------------------------- remove if present */ - _mesh._pop_tria(_tdat, _same) ; + _mesh._pop_tria(_tdat); } } - + /* -------------------------------------------------------- * INIT-BALL: add new ball to restricted-tria. -------------------------------------------------------- */ - + __static_call __normal_call void_type init_ball ( mesh_type &_mesh, @@ -129,41 +129,41 @@ { __unreferenced ( _geom ) ; __unreferenced ( _opts ) ; - + if (_mesh._tria. node(_npos)->feat()==hard_feat) { /*---------- push protecting ball for "hard" features */ ball_data _ball ; _ball._node[0] = _npos; - + _ball._pass = _pass; _ball._kind = _kind; - + _ball._ball[0] = _mesh. _tria.node(_npos)->pval(0) ; _ball._ball[1] = _mesh. _tria.node(_npos)->pval(1) ; - + real_type _rbal = _hfun.eval ( &_mesh._tria. node(_npos)->pval(0) , _mesh._tria. node(_npos)->idxh()) ; - + _ball._ball[2] = _rbal * _rbal ; - + _bset.push_tail (_ball) ; - _bscr.push_tail (_ball) ; + _bscr.push_tail (_ball) ; } } - + /* -------------------------------------------------------- * PUSH-EDGE: add new edge to restricted-tria. -------------------------------------------------------- */ - + __static_call __normal_call void_type push_edge ( mesh_type &_mesh , @@ -172,7 +172,7 @@ iptr_type _tpos , edat_list &_eset , escr_list &_escr , - typename + typename mesh_type::edge_list & _edge_test , iptr_type &_nedg , iptr_type &_ndup , @@ -181,8 +181,8 @@ ) { if(!_geom.have_feat(1))return ; - - /*-------------------------------- correct node dims? */ + + /*-------------------------------- correct node dims? */ iptr_type _fdim =+0; for (auto _node =+3; _node-- != +0; ) { @@ -206,7 +206,7 @@ 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 || @@ -215,7 +215,7 @@ continue ; algorithms::isort ( - &_tnod[0], &_tnod[2], + &_tnod[0], &_tnod[2], std::less()) ; edge_data _fdat; @@ -230,12 +230,12 @@ edge_list:: item_type *_mptr = nullptr ; if(_edge_test. - find( _fdat, _mptr) ) + find( _fdat, _mptr) ) { /*--------------------------- count bnd. repeats! */ - _ndup += + _ndup += _mptr->_data._dups; - + /*--------------------------- don't test repeats! */ continue ; } @@ -244,18 +244,18 @@ _fdat._pass = _pass; _fdat._tadj = _tpos; - _fdat._eadj = + _fdat._eadj = (char_type) _fpos; _fdat._dups = +0; // count num. dup's // only in hash-set - + /*--------------------------- call face predicate */ char_type _feat, _topo; real_type _fbal[ 3]; real_type _sbal[ 3]; mesh_pred::edge_cost ( - _geom,_hfun, - _mesh, + _geom,_hfun, + _mesh, _fdat._tadj, _fdat._eadj, _opts,_cdat, @@ -263,22 +263,22 @@ _feat,_topo, _fdat._kind, _fbal,_sbal) ; - + /*--------------------------- push edge onto mesh */ - if (_fdat._kind + if (_fdat._kind == mesh::ring_item) _escr. push_tail(_cdat) ; - if (_fdat._kind + if (_fdat._kind != mesh::null_item) _nedg += +1 ; - if (_fdat._kind + if (_fdat._kind != mesh::null_item) _fdat. _dups = +1 ; - if (_fdat._kind + if (_fdat._kind != mesh::null_item) _eset. push_tail(_fdat) ; @@ -287,13 +287,13 @@ } // for (auto _fpos = +3; _fpos-- != +0; ) } - + /* -------------------------------------------------------- * PUSH-TRIA: add new tria to restricted-tria. -------------------------------------------------------- */ - + __static_call __normal_call void_type push_tria ( mesh_type &_mesh , @@ -303,8 +303,8 @@ iptr_type &_sign , tdat_list &_tset , tscr_list &_tscr , - typename - mesh_type::tria_list & _tria_test , + /* typename + mesh_type::tria_list & _tria_test , */ iptr_type &_ntri , iptr_type _pass , rdel_opts &_opts @@ -312,8 +312,8 @@ { /*-------------------------------- check "restricted" */ { - if(!_geom.have_feat(1)) return; - + if(!_geom.have_feat(1)) return ; + iptr_type _tnod[ +3] ; _tnod[0] = _mesh. _tria.tria(_tpos)->node(0); @@ -343,15 +343,6 @@ _cdat._node[1] = _tnod[ 1] ; _cdat._node[2] = _tnod[ 2] ; - typename mesh_type:: - tria_list:: - item_type *_mptr = nullptr; - if(_tria_test. - find( _tdat, _mptr) ) - { - /*--------------------------- don't test repeats! */ - return ; - } //!!_tria_test.push( _tdat) ; won't have repeats! @@ -362,8 +353,8 @@ _tdat._pass = _pass ; mesh_pred::tria_cost ( - _geom,_hfun, - _mesh, + _geom,_hfun, + _mesh, _tdat._tadj, _opts,_cdat, _tdat._part, @@ -372,15 +363,15 @@ _sign = _tdat. _part ; /*--------------------------- push edge onto mesh */ - if (_tdat._kind + if (_tdat._kind == mesh::ring_item) _tscr. push_tail(_cdat) ; - if (_tdat._kind + if (_tdat._kind != mesh::null_item) _ntri += +1 ; - if (_tdat._kind + if (_tdat._kind != mesh::null_item) _tset. push_tail(_tdat) ; } @@ -399,30 +390,30 @@ ) { iptr_type _tnod[3] = { - _mesh. + _mesh. _tria.tria( _tpos)->node(0) , - _mesh. + _mesh. _tria.tria( _tpos)->node(1) , - _mesh. + _mesh. _tria.tria( _tpos)->node(2) } ; algorithms::isort( - &_tnod[0], &_tnod[3], + &_tnod[0], &_tnod[3], std::less()) ; - + /*---------------------- calc. ball in floating-point */ real_type _tbal[3] ; geometry::circ_ball_2d ( - _tbal , + _tbal , &_mesh._tria. - node(_tnod[0])->pval(0) , + node(_tnod[0])->pval(0) , &_mesh._tria. node(_tnod[1])->pval(0) , &_mesh._tria. node(_tnod[2])->pval(0) ) ; - + _mesh._tria.tria( _tpos)->circ(0) = _tbal[0] ; _mesh._tria.tria( @@ -451,107 +442,98 @@ ball_list &_bdat , iptr_type _sign , iptr_type _pass , - mode_type _dim0 , // lo rDT dim. to examine + mode_type _dim0 , // lo rDT dim. to examine mode_type _dim1 , // hi rDT dim. to examine rdel_opts &_opts ) { - /*------------------------- init. for local hash obj. */ - typename - mesh_type::edge_list _eset ( - typename mesh_type::edge_hash(), - typename mesh_type::edge_pred(), - +.8, _mesh._eset.get_alloc()) ; - typename - mesh_type::tria_list _tset ( - typename mesh_type::tria_hash(), - typename mesh_type::tria_pred(), - +.8, _mesh._tset.get_alloc()) ; - - /*------------------------- push alloc. for hash obj. */ - _eset._lptr.set_count ( - _tnew.count() * +3 , - containers::loose_alloc, nullptr); - _tset._lptr.set_count ( - _tnew.count() * +1 , - containers::loose_alloc, nullptr); - /*------------------------- no. "restricted" subfaces */ iptr_type _nedg = +0 ; iptr_type _ntri = +0 ; - - iptr_type _ndup = +0 ; - /*------------------------- flag if we're not testing */ - bool_type _safe ; - _safe = (_dim0>=2) ? false : true ; + iptr_type _ndup = +0 ; /*------------------------- calc. voronoi-dual points */ - for( auto _iter = _tnew.head(); - _iter != _tnew.tend(); + 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(); + for( auto _iter = _nnew.head(); + _iter != _nnew.tend(); ++_iter ) - { + { char_type _kind = feat_ball; - + init_ball(_mesh, _geom , - _hfun,*_iter , - _bdat, _bscr , + _hfun,*_iter , + _bdat, _bscr , _kind, _pass, _opts) ; - } + } } /*------------- push any new restricted edges created */ if (_dim0 <= edge_mode && _dim1 >= edge_mode ) { - for( auto _iter = _tnew.head(); - _iter != _tnew.tend(); + typename + mesh_type::edge_list _eset ( + typename mesh_type::edge_hash(), + typename mesh_type::edge_pred(), + +.8, _mesh._eset.get_alloc(), + _tnew.count() * +3) ; + + for( auto _iter = _tnew.head(); + _iter != _tnew.tend(); ++_iter ) - { + { push_edge(_mesh, _geom , - _hfun,*_iter , - _edat, _escr , - _eset, _nedg , - _ndup, + _hfun,*_iter , + _edat, _escr , + _eset, _nedg , + _ndup, _pass, _opts) ; - } + } } /*------------- push any new restricted trias created */ - if (_dim0 <= tria_mode && + if (_dim0 <= tria_mode && _dim1 >= tria_mode ) { - + //typename + // mesh_type::tria_list _tset ( + //typename mesh_type::tria_hash(), + //typename mesh_type::tria_pred(), + // +.8, _mesh._tset.get_alloc(), + // _tnew.count() * +1) ; + + bool_type _safe = true ; + + if (_dim0 > +0) _safe = false ; + //if (_nedg >= +1) _safe = false ; if (_ndup >= +1) _safe = false ; - - /*-------------------------- compute cavity tria cost */ - for( auto _iter = _tnew.head(); - _iter != _tnew.tend(); + + for( auto _iter = _tnew.head(); + _iter != _tnew.tend(); ++_iter ) { _sign = (!_safe) ? -1 : _sign ; push_tria(_mesh, _geom , - _hfun,*_iter , - _sign, _tdat , - _tscr, _tset , - _ntri, + _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 d6ac0cf..1f9dda7 100644 --- a/src/libcpp/rdel_mesh/rdel_update_face_3.inc +++ b/src/libcpp/rdel_mesh/rdel_update_face_3.inc @@ -1,37 +1,37 @@ /* -------------------------------------------------------- - * RDEL-UPDATE-3: update restricted delaunay in R^3. + * RDEL-UPDATE-3: update restricted delaunay in R^3. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 02 February, 2019 + * Last updated: 06 July, 2019 * * Copyright 2013-2019 * Darren Engwirda @@ -40,17 +40,17 @@ * -------------------------------------------------------- */ - + // from rdel_mesh_3.hpp - - + + /* -------------------------------------------------------- - * _POP-EDGE: delete edge from restricted-tria. + * _POP-EDGE: delete edge from restricted-tria. -------------------------------------------------------- */ - - __static_call + + __static_call __normal_call void_type _pop_edge ( mesh_type &_mesh , iptr_type _tpos @@ -69,24 +69,24 @@ tria(_tpos)->node(_tnod[1]); algorithms::isort ( - &_tnod[0], &_tnod[2], + &_tnod[0], &_tnod[2], std::less()); - edge_data _edat, _same ; + edge_data _edat; _edat._node[0] = _tnod[0]; _edat._node[1] = _tnod[1]; /*--------------------------------- remove if present */ - _mesh._pop_edge(_edat, _same) ; + _mesh._pop_edge(_edat); } } - + /* -------------------------------------------------------- - * _POP-FACE: delete face from restricted-tria. + * _POP-FACE: delete face from restricted-tria. -------------------------------------------------------- */ - + __static_call __normal_call void_type _pop_face ( mesh_type &_mesh , @@ -108,25 +108,25 @@ tria(_tpos)->node(_tnod[2]); algorithms::isort ( - &_tnod[0], &_tnod[3], + &_tnod[0], &_tnod[3], std::less()); - face_data _fdat, _same ; + face_data _fdat; _fdat._node[0] = _tnod[0]; _fdat._node[1] = _tnod[1]; _fdat._node[2] = _tnod[2]; /*--------------------------------- remove if present */ - _mesh._pop_face(_fdat, _same) ; + _mesh._pop_face(_fdat); } } - + /* -------------------------------------------------------- - * _POP-TRIA: delete tria from restricted-tria. + * _POP-TRIA: delete tria from restricted-tria. -------------------------------------------------------- */ - + __static_call __normal_call void_type _pop_tria ( mesh_type &_mesh , @@ -135,7 +135,7 @@ { { /*--------------------------------- get tria indexing */ - tria_data _tdat, _same; + tria_data _tdat; _tdat._node[0] = _mesh. _tria.tria(_tpos)->node(0); _tdat._node[1] = _mesh. @@ -146,16 +146,16 @@ _tria.tria(_tpos)->node(3); /*--------------------------------- remove if present */ - _mesh._pop_tria(_tdat, _same) ; + _mesh._pop_tria(_tdat); } } - + /* -------------------------------------------------------- * INIT-BALL: add new ball to restricted-tria. -------------------------------------------------------- */ - + __static_call __normal_call void_type init_ball ( mesh_type &_mesh, @@ -171,43 +171,43 @@ { __unreferenced ( _geom ) ; __unreferenced ( _opts ) ; - + if (_mesh._tria. node(_npos)->feat()==hard_feat) { /*---------- push protecting ball for "hard" features */ ball_data _ball ; _ball._node[0] = _npos; - + _ball._pass = _pass; _ball._kind = _kind; - + _ball._ball[0] = _mesh. _tria.node(_npos)->pval(0) ; _ball._ball[1] = _mesh. _tria.node(_npos)->pval(1) ; _ball._ball[2] = _mesh. _tria.node(_npos)->pval(2) ; - + real_type _rbal = _hfun.eval ( &_mesh._tria. node(_npos)->pval(0), _mesh._tria. node(_npos)->idxh()); - + _ball._ball[3] = _rbal * _rbal ; - + _bset.push_tail (_ball) ; - _bscr.push_tail (_ball) ; + _bscr.push_tail (_ball) ; } } - + /* -------------------------------------------------------- * PUSH-EDGE: add new edge to restricted-tria. -------------------------------------------------------- */ - + __static_call __normal_call void_type push_edge ( mesh_type &_mesh , @@ -216,7 +216,7 @@ iptr_type _tpos , edat_list &_eset , escr_list &_escr , - typename + typename mesh_type::edge_list & _edge_test , iptr_type &_nedg , iptr_type _pass , @@ -224,8 +224,8 @@ ) { if(!_geom.have_feat(1))return ; - - /*-------------------------------- correct node dims? */ + + /*-------------------------------- correct node dims? */ iptr_type _fdim =+0; for (auto _node =+4; _node-- != +0; ) { @@ -256,9 +256,9 @@ _mesh._tria.node( _tnod[1])->fdim() > 1 ) continue ; - + algorithms::isort ( - &_tnod[0], &_tnod[2], + &_tnod[0], &_tnod[2], std::less()) ; edge_data _edat; @@ -273,7 +273,7 @@ edge_list:: item_type *_mptr = nullptr ; if(_edge_test. - find( _edat, _mptr) ) + find( _edat, _mptr) ) { /*--------------------------- don't test repeats! */ continue ; @@ -283,16 +283,16 @@ _edat._pass = _pass; _edat._tadj = _tpos; - _edat._eadj = + _edat._eadj = (char_type) _fpos; - + /*--------------------------- call edge predicate */ char_type _hits; real_type _fbal[ 4]; real_type _sbal[ 4]; mesh_pred::edge_cost ( - _geom,_hfun, - _mesh, + _geom,_hfun, + _mesh, _edat._tadj, _edat._eadj, _opts,_cdat, @@ -302,32 +302,32 @@ _edat._topo, _edat._kind, _fbal,_sbal) ; - + /*--------------------------- push edge onto mesh */ - if (_edat._kind + if (_edat._kind == mesh::ring_item) _escr. push_tail(_cdat) ; - if (_edat._kind + if (_edat._kind != mesh::null_item) _nedg += +1 ; - if (_edat._kind + if (_edat._kind != mesh::null_item) _eset. push_tail(_edat) ; - - + + _edge_test.push( _edat) ; } // for (auto _fpos = +6; _fpos-- != +0; ) } - + /* -------------------------------------------------------- * PUSH-FACE: add new face to restricted-tria. -------------------------------------------------------- */ - + __static_call __normal_call void_type push_face ( mesh_type &_mesh , @@ -336,7 +336,7 @@ iptr_type _tpos , fdat_list &_fset , fscr_list &_fscr , - typename + typename mesh_type::face_list & _face_test , iptr_type &_nfac , iptr_type &_ndup , @@ -345,8 +345,8 @@ ) { if(!_geom.have_feat(2))return ; - - /*-------------------------------- correct node dims? */ + + /*-------------------------------- correct node dims? */ iptr_type _fdim =+0; for (auto _node =+4; _node-- != +0; ) { @@ -383,7 +383,7 @@ continue ; algorithms::isort ( - &_tnod[0], &_tnod[3], + &_tnod[0], &_tnod[3], std::less()) ; face_data _fdat; @@ -400,12 +400,12 @@ face_list:: item_type *_mptr = nullptr ; if(_face_test. - find( _fdat, _mptr) ) + find( _fdat, _mptr) ) { /*--------------------------- count bnd. repeats! */ - _ndup += + _ndup += _mptr->_data._dups; - + /*--------------------------- don't test repeats! */ continue ; } @@ -414,18 +414,18 @@ _fdat._pass = _pass; _fdat._tadj = _tpos; - _fdat._fadj = + _fdat._fadj = (char_type) _fpos; _fdat._dups = +0; // count num. dup's // only in hash-set - + /*--------------------------- call face predicate */ char_type _feat, _topo; real_type _fbal[ 4]; real_type _sbal[ 4]; mesh_pred::face_cost ( - _geom,_hfun, - _mesh, + _geom,_hfun, + _mesh, _fdat._tadj, _fdat._fadj, _opts,_cdat, @@ -435,20 +435,20 @@ _fbal,_sbal) ; /*--------------------------- push face onto mesh */ - if (_fdat._kind + if (_fdat._kind == mesh::ring_item) _fscr. push_tail(_cdat) ; - if (_fdat._kind + if (_fdat._kind != mesh::null_item) _nfac += +1 ; - - if (_fdat._kind + + if (_fdat._kind != mesh::null_item) _fdat. _dups = +1 ; - if (_fdat._kind + if (_fdat._kind != mesh::null_item) _fset. push_tail(_fdat) ; @@ -457,13 +457,13 @@ } // for (auto _fpos = +4; _fpos-- != +0; ) } - + /* -------------------------------------------------------- * PUSH-TRIA: add new tria to restricted-tria. -------------------------------------------------------- */ - + __static_call __normal_call void_type push_tria ( mesh_type &_mesh , @@ -473,16 +473,16 @@ iptr_type &_sign , tdat_list &_tset , tscr_list &_tscr , - typename - mesh_type::tria_list & _tria_test , + /* typename + mesh_type::tria_list & _tria_test , */ iptr_type &_ntri , iptr_type _pass , rdel_opts &_opts ) { { - if(!_geom.have_feat(2)) return; - + if(!_geom.have_feat(2)) return ; + /*---------------------------- check "restricted" */ iptr_type _tnod[ +4] ; _tnod[0] = _mesh. @@ -503,8 +503,8 @@ _tnod[2])->fdim() > 3 || _mesh._tria.node( _tnod[3])->fdim() > 3 ) - return ; - + return ; + tria_data _tdat; _tdat._node[0] = _tnod[ 0] ; _tdat._node[1] = _tnod[ 1] ; @@ -519,15 +519,6 @@ _cdat._node[2] = _tnod[ 2] ; _cdat._node[3] = _tnod[ 3] ; - typename mesh_type:: - tria_list:: - item_type *_mptr = nullptr; - if(_tria_test. - find(_tdat , _mptr) ) - { - /*--------------------------- don't test repeats! */ - return ; - } //!!_tria_test.push( _tdat) ; won't have repeats! @@ -538,8 +529,8 @@ _tdat._pass = _pass ; mesh_pred::tria_cost ( - _geom,_hfun, - _mesh, + _geom,_hfun, + _mesh, _tdat._tadj, _opts,_cdat, _tdat._part, @@ -548,15 +539,15 @@ _sign = _tdat. _part ; /*--------------------------- push tria onto mesh */ - if (_tdat._kind + if (_tdat._kind == mesh::ring_item) _tscr. push_tail(_cdat) ; - if (_tdat._kind + if (_tdat._kind != mesh::null_item) _ntri += +1 ; - if (_tdat._kind + if (_tdat._kind != mesh::null_item) _tset. push_tail(_tdat) ; } @@ -575,26 +566,26 @@ ) { iptr_type _tnod[4] = { - _mesh. + _mesh. _tria.tria( _tpos)->node(0) , - _mesh. + _mesh. _tria.tria( _tpos)->node(1) , - _mesh. + _mesh. _tria.tria( _tpos)->node(2) , - _mesh. + _mesh. _tria.tria( _tpos)->node(3) } ; algorithms::isort( - &_tnod[0], &_tnod[4] , + &_tnod[0], &_tnod[4] , std::less()) ; - + /*---------------------- calc. ball in floating-point */ real_type _tbal[4] ; geometry::circ_ball_3d ( - _tbal , + _tbal , &_mesh._tria. - node(_tnod[0])->pval(0) , + node(_tnod[0])->pval(0) , &_mesh._tria. node(_tnod[1])->pval(0) , &_mesh._tria. @@ -602,7 +593,7 @@ &_mesh._tria. node(_tnod[3])->pval(0) ) ; - + _mesh._tria.tria( _tpos)->circ(0) = _tbal[0] ; _mesh._tria.tria( @@ -640,126 +631,116 @@ rdel_opts &_opts ) { - /*------------------------- init. for local hash obj. */ - typename - mesh_type::edge_list _eset ( - typename mesh_type::edge_hash(), - typename mesh_type::edge_pred(), - +.8, _mesh._eset.get_alloc()) ; - typename - mesh_type::face_list _fset ( - typename mesh_type::face_hash(), - typename mesh_type::face_pred(), - +.8, _mesh._fset.get_alloc()) ; - typename - mesh_type::tria_list _tset ( - typename mesh_type::tria_hash(), - typename mesh_type::tria_pred(), - +.8, _mesh._tset.get_alloc()) ; - - /*------------------------- push alloc. for hash obj. */ - _eset._lptr.set_count ( - _tnew.count() * +6 , - containers::loose_alloc, nullptr); - _fset._lptr.set_count ( - _tnew.count() * +4 , - containers::loose_alloc, nullptr); - _tset._lptr.set_count ( - _tnew.count() * +1 , - containers::loose_alloc, nullptr); - /*------------------------- no. "restricted" subfaces */ iptr_type _nedg = +0 ; iptr_type _nfac = +0 ; iptr_type _ntri = +0 ; - - iptr_type _ndup = +0 ; - /*------------------------- flag if we're not testing */ - bool_type _safe ; - _safe = (_dim0>=3) ? false : true ; + iptr_type _ndup = +0 ; /*------------------------- calc. voronoi-dual points */ - for( auto _iter = _tnew.head(); - _iter != _tnew.tend(); + 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(); + for( auto _iter = _nnew.head(); + _iter != _nnew.tend(); ++_iter ) - { + { char_type _kind = feat_ball; - + init_ball(_mesh, _geom , - _hfun,*_iter , - _bdat, _bscr , + _hfun,*_iter , + _bdat, _bscr , _kind, _pass, _opts) ; - } + } } /*------------- push any new restricted edges created */ if (_dim0 <= edge_mode && _dim1 >= edge_mode ) { - for( auto _iter = _tnew.head(); - _iter != _tnew.tend(); + typename + mesh_type::edge_list _eset ( + typename mesh_type::edge_hash(), + typename mesh_type::edge_pred(), + +.8, _mesh._eset.get_alloc(), + _tnew.count() * +6) ; + + for( auto _iter = _tnew.head(); + _iter != _tnew.tend(); ++_iter ) - { + { push_edge(_mesh, _geom , - _hfun,*_iter , - _edat, _escr , - _eset, _nedg , + _hfun,*_iter , + _edat, _escr , + _eset, _nedg , _pass, _opts) ; - } + } } /*------------- push any new restricted faces created */ if (_dim0 <= face_mode && _dim1 >= face_mode ) { - for( auto _iter = _tnew.head(); - _iter != _tnew.tend(); + typename + mesh_type::face_list _fset ( + typename mesh_type::face_hash(), + typename mesh_type::face_pred(), + +.8, _mesh._fset.get_alloc(), + _tnew.count() * +4) ; + + for( auto _iter = _tnew.head(); + _iter != _tnew.tend(); ++_iter ) { push_face(_mesh, _geom , - _hfun,*_iter , - _fdat, _fscr , + _hfun,*_iter , + _fdat, _fscr , _fset, _nfac , - _ndup, + _ndup, _pass, _opts) ; } } /*------------- push any new restricted trias created */ - if (_dim0 <= tria_mode && + if (_dim0 <= tria_mode && _dim1 >= tria_mode ) { - + //typename + // mesh_type::tria_list _tset ( + //typename mesh_type::tria_hash(), + //typename mesh_type::tria_pred(), + // +.8, _mesh._tset.get_alloc(), + // _tnew.count() * +1) ; + + bool_type _safe = true ; + + if (_dim0 > +0) _safe = false ; + //if (_nfac >= +1) _safe = false ; if (_ndup >= +1) _safe = false ; - - /*-------------------------- compute cavity tria cost */ - for( auto _iter = _tnew.head(); - _iter != _tnew.tend(); + + for( auto _iter = _tnew.head(); + _iter != _tnew.tend(); ++_iter ) { _sign = (!_safe) ? -1 : _sign ; push_tria(_mesh, _geom , - _hfun,*_iter , - _sign, _tdat , - _tscr, _tset , - _ntri, + _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 77ef20f..9df2451 100644 --- a/src/libcpp/rdel_mesh/rdel_update_topo_2.inc +++ b/src/libcpp/rdel_mesh/rdel_update_topo_2.inc @@ -1,37 +1,37 @@ /* -------------------------------------------------------- - * RDEL-UPDATE-2: update nodes for topo. checks. + * RDEL-UPDATE-2: update nodes for topo. checks. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 24 January, 2019 + * Last updated: 03 July, 2019 * * Copyright 2013-2019 * Darren Engwirda @@ -40,13 +40,13 @@ * -------------------------------------------------------- */ - + // from rdel_mesh_2.hpp - - + + /* -------------------------------------------------------- - * FILL-TOPO: enqueue node for topo. + * FILL-TOPO: enqueue node for topo. -------------------------------------------------------- */ @@ -64,68 +64,68 @@ if (_opts.top1()) { if (_eold.count() == +0) - { + { _emrk.set_count ( - _mesh._tria._nset.count(), + _mesh._tria._nset.count(), containers::loose_alloc , -1) ; - + /*------------------------- add all: everything "new" */ node_data _ndat ; - for (auto _iter = _enew.head(); + for (auto _iter = _enew.head(); _iter != _enew.tend(); ++_iter ) - { + { _ndat._pass = _pass ; - + if (_emrk[_iter->_node[0]] == -1) { _emrk[_iter->_node[0]] = +1; - - _ndat. _node[0] = + + _ndat. _node[0] = _iter->_node[0] ; - - _etpq.push(_ndat) ; + + _etpq.push(_ndat) ; } - + if (_emrk[_iter->_node[1]] == -1) { _emrk[_iter->_node[1]] = +1; - - _ndat. _node[0] = + + _ndat. _node[0] = _iter->_node[1] ; - - _etpq.push(_ndat) ; + + _etpq.push(_ndat) ; } } } else { _emrk.set_count ( - _mesh._tria._nset.count(), + _mesh._tria._nset.count(), containers::loose_alloc , -1) ; - + { /*------------------------- init. for local hash obj. */ - typename + typename mesh_type::edge_list _eset ( typename mesh_type::edge_hash(), - typename mesh_type::edge_pred(), + typename mesh_type::edge_pred(), +.8, _mesh._eset.get_alloc()) ; - + /*------------------------- push alloc. for hash obj. */ - _eset._lptr.set_count ( - _enew.count() * 2 , - containers::loose_alloc, nullptr); + _eset.set_slots ( + _enew.count() * 2 , + containers::tight_alloc) ; /*------------------------- add "old" absent in "new" */ node_data _ndat ; - for (auto _iter = _enew.head(); + for (auto _iter = _enew.head(); _iter != _enew.tend(); ++_iter ) { _eset.push(*_iter) ; } - for (auto _iter = _eold.head(); + for (auto _iter = _eold.head(); _iter != _eold.tend(); ++_iter ) { @@ -135,53 +135,53 @@ item_type *_mptr = nullptr ; if(!_eset.find(*_iter, _mptr)) { - + if (_emrk[_iter->_node[0]] == -1) { _emrk[_iter->_node[0]] = +1; - - _ndat. _node[0] = + + _ndat. _node[0] = _iter->_node[0] ; - - _etpq.push(_ndat) ; + + _etpq.push(_ndat) ; } - + if (_emrk[_iter->_node[1]] == -1) { _emrk[_iter->_node[1]] = +1; - - _ndat. _node[0] = + + _ndat. _node[0] = _iter->_node[1] ; - - _etpq.push(_ndat) ; + + _etpq.push(_ndat) ; } - + } } } - + { /*------------------------- init. for local hash obj. */ - typename + typename mesh_type::edge_list _eset ( typename mesh_type::edge_hash(), - typename mesh_type::edge_pred(), + typename mesh_type::edge_pred(), +.8, _mesh._eset.get_alloc()) ; - + /*------------------------- push alloc. for hash obj. */ - _eset._lptr.set_count ( - _eold.count() * 2 , - containers::loose_alloc, nullptr); + _eset.set_slots ( + _eold.count() * 2 , + containers::tight_alloc) ; /*------------------------- add "new" absent in "old" */ node_data _ndat ; - for (auto _iter = _eold.head(); + for (auto _iter = _eold.head(); _iter != _eold.tend(); ++_iter ) { _eset.push(*_iter) ; } - for (auto _iter = _enew.head(); + for (auto _iter = _enew.head(); _iter != _enew.tend(); ++_iter ) { @@ -191,33 +191,33 @@ item_type *_mptr = nullptr ; if(!_eset.find(*_iter, _mptr)) { - + if (_emrk[_iter->_node[0]] == -1) { _emrk[_iter->_node[0]] = +1; - - _ndat. _node[0] = + + _ndat. _node[0] = _iter->_node[0] ; - - _etpq.push(_ndat) ; + + _etpq.push(_ndat) ; } - + if (_emrk[_iter->_node[1]] == -1) { _emrk[_iter->_node[1]] = +1; - - _ndat. _node[0] = + + _ndat. _node[0] = _iter->_node[1] ; - - _etpq.push(_ndat) ; + + _etpq.push(_ndat) ; } - + } } - } + } } } } - - - + + + diff --git a/src/libcpp/rdel_mesh/rdel_update_topo_3.inc b/src/libcpp/rdel_mesh/rdel_update_topo_3.inc index 7cdab0d..c4c51e8 100644 --- a/src/libcpp/rdel_mesh/rdel_update_topo_3.inc +++ b/src/libcpp/rdel_mesh/rdel_update_topo_3.inc @@ -1,37 +1,37 @@ /* -------------------------------------------------------- - * RDEL-UPDATE-3: update nodes for topo. checks. + * RDEL-UPDATE-3: update nodes for topo. checks. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 24 January, 2019 + * Last updated: 03 July, 2019 * * Copyright 2013-2019 * Darren Engwirda @@ -40,13 +40,13 @@ * -------------------------------------------------------- */ - + // from rdel_mesh_3.hpp - - + + /* -------------------------------------------------------- - * FILL-TOPO: enqueue node for topo. + * FILL-TOPO: enqueue node for topo. -------------------------------------------------------- */ @@ -69,68 +69,68 @@ { /*----------------------------- check nodes adj. to edges */ if (_eold.count() == +0) - { + { _emrk.set_count ( - _mesh._tria._nset.count(), + _mesh._tria._nset.count(), containers::loose_alloc , -1) ; - + /*------------------------- add all: everything "new" */ node_data _ndat ; - for (auto _iter = _enew.head(); + for (auto _iter = _enew.head(); _iter != _enew.tend(); ++_iter ) - { + { _ndat._pass = _pass ; - + if (_emrk[_iter->_node[0]] == -1) { _emrk[_iter->_node[0]] = +1; - - _ndat. _node[0] = + + _ndat. _node[0] = _iter->_node[0] ; - - _etpq.push(_ndat) ; + + _etpq.push(_ndat) ; } - + if (_emrk[_iter->_node[1]] == -1) { _emrk[_iter->_node[1]] = +1; - - _ndat. _node[0] = + + _ndat. _node[0] = _iter->_node[1] ; - - _etpq.push(_ndat) ; + + _etpq.push(_ndat) ; } } } else { _emrk.set_count ( - _mesh._tria._nset.count(), + _mesh._tria._nset.count(), containers::loose_alloc , -1) ; - + { /*------------------------- init. for local hash obj. */ - typename + typename mesh_type::edge_list _eset ( typename mesh_type::edge_hash(), - typename mesh_type::edge_pred(), + typename mesh_type::edge_pred(), +.8, _mesh._eset.get_alloc()) ; - + /*------------------------- push alloc. for hash obj. */ - _eset._lptr.set_count ( - _enew.count() * 2 , - containers::loose_alloc, nullptr); + _eset.set_slots ( + _enew.count() * 2 , + containers::tight_alloc) ; /*------------------------- add "old" absent in "new" */ node_data _ndat ; - for (auto _iter = _enew.head(); + for (auto _iter = _enew.head(); _iter != _enew.tend(); ++_iter ) { _eset.push(*_iter) ; } - for (auto _iter = _eold.head(); + for (auto _iter = _eold.head(); _iter != _eold.tend(); ++_iter ) { @@ -140,53 +140,53 @@ item_type *_mptr = nullptr ; if(!_eset.find(*_iter, _mptr)) { - + if (_emrk[_iter->_node[0]] == -1) { _emrk[_iter->_node[0]] = +1; - - _ndat. _node[0] = + + _ndat. _node[0] = _iter->_node[0] ; - - _etpq.push(_ndat) ; + + _etpq.push(_ndat) ; } - + if (_emrk[_iter->_node[1]] == -1) { _emrk[_iter->_node[1]] = +1; - - _ndat. _node[0] = + + _ndat. _node[0] = _iter->_node[1] ; - - _etpq.push(_ndat) ; + + _etpq.push(_ndat) ; } - + } } } - + { /*------------------------- init. for local hash obj. */ - typename + typename mesh_type::edge_list _eset ( typename mesh_type::edge_hash(), - typename mesh_type::edge_pred(), + typename mesh_type::edge_pred(), +.8, _mesh._eset.get_alloc()) ; - + /*------------------------- push alloc. for hash obj. */ - _eset._lptr.set_count ( - _eold.count() * 2 , - containers::loose_alloc, nullptr); + _eset.set_slots ( + _eold.count() * 2 , + containers::tight_alloc) ; /*------------------------- add "new" absent in "old" */ node_data _ndat ; - for (auto _iter = _eold.head(); + for (auto _iter = _eold.head(); _iter != _eold.tend(); ++_iter ) { _eset.push(*_iter) ; } - for (auto _iter = _enew.head(); + for (auto _iter = _enew.head(); _iter != _enew.tend(); ++_iter ) { @@ -196,109 +196,109 @@ item_type *_mptr = nullptr ; if(!_eset.find(*_iter, _mptr)) { - + if (_emrk[_iter->_node[0]] == -1) { _emrk[_iter->_node[0]] = +1; - - _ndat. _node[0] = + + _ndat. _node[0] = _iter->_node[0] ; - - _etpq.push(_ndat) ; + + _etpq.push(_ndat) ; } - + if (_emrk[_iter->_node[1]] == -1) { _emrk[_iter->_node[1]] = +1; - - _ndat. _node[0] = + + _ndat. _node[0] = _iter->_node[1] ; - - _etpq.push(_ndat) ; + + _etpq.push(_ndat) ; } - + } } - } + } } } - + if (_opts.top2()) { /*----------------------------- check nodes adj. to faces */ if (_fold.count() == +0) - { + { _fmrk.set_count ( - _mesh._tria._nset.count(), + _mesh._tria._nset.count(), containers::loose_alloc , -1) ; - + /*------------------------- add all: everything "new" */ node_data _ndat ; - for (auto _iter = _fnew.head(); + for (auto _iter = _fnew.head(); _iter != _fnew.tend(); ++_iter ) - { + { _ndat._pass = _pass ; - + if (_fmrk[_iter->_node[0]] == -1) { _fmrk[_iter->_node[0]] = +1; - - _ndat. _node[0] = + + _ndat. _node[0] = _iter->_node[0] ; - - _ftpq.push(_ndat) ; + + _ftpq.push(_ndat) ; } - + if (_fmrk[_iter->_node[1]] == -1) { _fmrk[_iter->_node[1]] = +1; - - _ndat. _node[0] = + + _ndat. _node[0] = _iter->_node[1] ; - - _ftpq.push(_ndat) ; + + _ftpq.push(_ndat) ; } - + if (_fmrk[_iter->_node[2]] == -1) { _fmrk[_iter->_node[2]] = +1; - - _ndat. _node[0] = + + _ndat. _node[0] = _iter->_node[2] ; - - _ftpq.push(_ndat) ; + + _ftpq.push(_ndat) ; } } } else { _fmrk.set_count ( - _mesh._tria._nset.count(), + _mesh._tria._nset.count(), containers::loose_alloc , -1) ; - + { /*------------------------- init. for local hash obj. */ - typename + typename mesh_type::face_list _fset ( typename mesh_type::face_hash(), - typename mesh_type::face_pred(), + typename mesh_type::face_pred(), +.8, _mesh._fset.get_alloc()) ; - + /*------------------------- push alloc. for hash obj. */ - _fset._lptr.set_count ( - _fnew.count() * 2 , - containers::loose_alloc, nullptr); + _fset.set_slots ( + _fnew.count() * 2 , + containers::tight_alloc) ; /*------------------------- add "old" absent in "new" */ node_data _ndat ; - for (auto _iter = _fnew.head(); + for (auto _iter = _fnew.head(); _iter != _fnew.tend(); ++_iter ) { _fset.push(*_iter) ; } - for (auto _iter = _fold.head(); + for (auto _iter = _fold.head(); _iter != _fold.tend(); ++_iter ) { @@ -308,63 +308,63 @@ item_type *_mptr = nullptr ; if(!_fset.find(*_iter, _mptr)) { - + if (_fmrk[_iter->_node[0]] == -1) { _fmrk[_iter->_node[0]] = +1; - - _ndat. _node[0] = + + _ndat. _node[0] = _iter->_node[0] ; - - _ftpq.push(_ndat) ; + + _ftpq.push(_ndat) ; } - + if (_fmrk[_iter->_node[1]] == -1) { _fmrk[_iter->_node[1]] = +1; - - _ndat. _node[0] = + + _ndat. _node[0] = _iter->_node[1] ; - - _ftpq.push(_ndat) ; + + _ftpq.push(_ndat) ; } - + if (_fmrk[_iter->_node[2]] == -1) { _fmrk[_iter->_node[2]] = +1; - - _ndat. _node[0] = + + _ndat. _node[0] = _iter->_node[2] ; - - _ftpq.push(_ndat) ; + + _ftpq.push(_ndat) ; } - + } } } - + { /*------------------------- init. for local hash obj. */ - typename + typename mesh_type::face_list _fset ( typename mesh_type::face_hash(), - typename mesh_type::face_pred(), + typename mesh_type::face_pred(), +.8, _mesh._fset.get_alloc()) ; - + /*------------------------- push alloc. for hash obj. */ - _fset._lptr.set_count ( - _fold.count() * 2 , - containers::loose_alloc, nullptr); + _fset.set_slots ( + _fold.count() * 2 , + containers::tight_alloc) ; /*------------------------- add "new" absent in "old" */ node_data _ndat ; - for (auto _iter = _fold.head(); + for (auto _iter = _fold.head(); _iter != _fold.tend(); ++_iter ) { _fset.push(*_iter) ; } - for (auto _iter = _fnew.head(); + for (auto _iter = _fnew.head(); _iter != _fnew.tend(); ++_iter ) { @@ -374,43 +374,43 @@ item_type *_mptr = nullptr ; if(!_fset.find(*_iter, _mptr)) { - + if (_fmrk[_iter->_node[0]] == -1) { _fmrk[_iter->_node[0]] = +1; - - _ndat. _node[0] = + + _ndat. _node[0] = _iter->_node[0] ; - - _ftpq.push(_ndat) ; + + _ftpq.push(_ndat) ; } - + if (_fmrk[_iter->_node[1]] == -1) { _fmrk[_iter->_node[1]] = +1; - - _ndat. _node[0] = + + _ndat. _node[0] = _iter->_node[1] ; - - _ftpq.push(_ndat) ; + + _ftpq.push(_ndat) ; } - + if (_fmrk[_iter->_node[2]] == -1) { _fmrk[_iter->_node[2]] = +1; - - _ndat. _node[0] = + + _ndat. _node[0] = _iter->_node[2] ; - - _ftpq.push(_ndat) ; + + _ftpq.push(_ndat) ; } - + } } - } + } } } } - - - + + + diff --git a/src/libcpp/rdel_mesh/rvor_mesh_2.hpp b/src/libcpp/rdel_mesh/rvor_mesh_2.hpp index 08bbc30..048e5b3 100644 --- a/src/libcpp/rdel_mesh/rvor_mesh_2.hpp +++ b/src/libcpp/rdel_mesh/rvor_mesh_2.hpp @@ -1,32 +1,32 @@ /* -------------------------------------------------------- - * RVOR-MESH-2: restricted voronoi mesh-gen. in R^2. + * RVOR-MESH-2: restricted voronoi mesh-gen. in R^2. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- @@ -47,7 +47,7 @@ # define __RVOR_MESH_2__ namespace mesh { - + template < typename M , typename P , @@ -56,28 +56,28 @@ typename A = allocators::basic_alloc > class rvor_mesh_2d - { - public : - - /*--------- restricted voronoi mesh-generation in R^2 */ - + { + public : + + /*--------- restricted voronoi mesh-generation in R^2 */ + typedef M mesh_type ; typedef P mesh_pred ; typedef G geom_type ; typedef H hfun_type ; typedef A allocator ; - typedef typename + typedef typename mesh_type::real_type real_type ; - typedef typename + typedef typename mesh_type::iptr_type iptr_type ; - + char_type static constexpr null_ball = +0 ; char_type static constexpr feat_ball = +1 ; char_type static constexpr voro_ball = +2 ; typedef char_type mode_type ; - + char_type static constexpr null_mode = +0 ; char_type static constexpr feat_mode = +1 ; char_type static constexpr edge_mode = +2 ; @@ -85,9 +85,9 @@ char_type static constexpr ball_mode = +4 ; char_type static constexpr tria_mode = +5 ; - class node_pred ; class ball_pred ; + class node_pred ; class ball_pred ; class edge_pred ; class tria_pred ; - + class edge_cost : public mesh_pred::edge_data { public : @@ -101,17 +101,17 @@ iptr_type _pass; } ; - typedef typename + typedef typename mesh_type::node_data node_data ; - typedef typename + typedef typename mesh_type::ball_data ball_data ; - typedef typename + typedef typename mesh_type::edge_data edge_data ; - typedef typename + typedef typename mesh_type::tria_data tria_data ; typedef mesh::rdel_params < - real_type, + real_type, iptr_type > rdel_opts ; typedef containers::array < @@ -120,37 +120,37 @@ /*------------------------------------------ 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 ; /*------------------------------------------ refine lists */ typedef containers::priorityset < - node_data, + node_data, node_pred > node_heap ; typedef containers::priorityset < - edge_cost, + edge_cost, edge_pred > edge_heap ; typedef containers::priorityset < - tria_cost, + tria_cost, tria_pred > tria_heap ; - + /*------------------------------------------ collar lists */ typedef containers::array < ball_data > ball_list ; - + typedef containers::priorityset < - ball_data, + ball_data, ball_pred > ball_heap ; - + class node_pred { /*---------------------- "less-than" for node objects */ @@ -159,7 +159,7 @@ node_data const& _idat, node_data const& _jdat ) const - { return _idat._pass < _jdat._pass ; + { return _idat._pass < _jdat._pass ; } } ; class ball_pred @@ -170,8 +170,8 @@ ball_data const& _idat, ball_data const& _jdat ) const - { return _idat._ball[2] > - _jdat._ball[2] ; + { return _idat._ball[2] > + _jdat._ball[2] ; } } ; class edge_pred @@ -198,26 +198,26 @@ ::tria_pred(_idat, _jdat) ; } } ; - - + + /* -------------------------------------------------------- - * RVOR-UPDATE: update the restricted-tria. + * RVOR-UPDATE: update the restricted-tria. -------------------------------------------------------- */ - + //#include "rvor_update_face_2.inc" - - - - + + + + /* -------------------------------------------------------- - * INIT-RDEL: init. face-set in rDT. + * INIT-RDEL: init. face-set in rDT. -------------------------------------------------------- */ - __static_call + __static_call __normal_call void_type init_rdel ( geom_type &_geom , hfun_type &_hfun , @@ -236,10 +236,10 @@ { /*-------------------- mark all existing elem. as new */ iptr_type _npos = 0, _tpos = 0 ; - for (auto _iter = - _bnds._tria._nset.head() ; - _iter != - _bnds._tria._nset.tend() ; + for (auto _iter = + _bnds._tria._nset.head() ; + _iter != + _bnds._tria._nset.tend() ; ++_iter , ++_npos) { if (_iter->mark() >= +0) @@ -247,10 +247,10 @@ _nnew. push_tail( _npos) ; } } - for (auto _iter = - _bnds._tria._tset.head() ; - _iter != - _bnds._tria._tset.tend() ; + for (auto _iter = + _bnds._tria._tset.head() ; + _iter != + _bnds._tria._tset.tend() ; ++_iter , ++_tpos) { if (_iter->mark() >= +0) @@ -260,23 +260,23 @@ } /*-------------------- init. restricted triangulation */ /* - push_rdel( _geom, _hfun, - _bnds, _nnew, _tnew, + push_rdel( _geom, _hfun, + _bnds, _nnew, _tnew, _escr, _ecav, - _tscr, _tcav, - _nbal, _vbal, + _tscr, _tcav, + _nbal, _vbal, -1, _pass, _fdim, _fdim, _args) ; */ } - + /* -------------------------------------------------------- - * INIT-RVOR: init. face-set in rVT. + * INIT-RVOR: init. face-set in rVT. -------------------------------------------------------- */ - __static_call + __static_call __normal_call void_type init_rvor ( geom_type &_geom , hfun_type &_hfun , @@ -292,10 +292,10 @@ { /*-------------------- mark all existing elem. as new */ iptr_type _npos = 0, _tpos = 0 ; - for (auto _iter = - _mesh._tria._nset.head() ; - _iter != - _mesh._tria._nset.tend() ; + for (auto _iter = + _mesh._tria._nset.head() ; + _iter != + _mesh._tria._nset.tend() ; ++_iter , ++_npos) { if (_iter->mark() >= +0) @@ -303,10 +303,10 @@ _NNEW. push_tail( _npos) ; } } - for (auto _iter = - _mesh._tria._tset.head() ; - _iter != - _mesh._tria._tset.tend() ; + for (auto _iter = + _mesh._tria._tset.head() ; + _iter != + _mesh._tria._tset.tend() ; ++_iter , ++_tpos) { if (_iter->mark() >= +0) @@ -315,19 +315,19 @@ } } /*-------------------- init. restricted triangulation */ - + /* - push_rvor( _geom, _hfun, - _mesh, _NNEW, _TNEW, - _TSCR, _TCAV, + push_rvor( _geom, _hfun, + _mesh, _NNEW, _TNEW, + _TSCR, _TCAV, -1, _pass, _fdim, _fdim, _args) ; */ } - + /* -------------------------------------------------------- - * INIT-BNDS: init. the bounding DT. + * INIT-BNDS: init. the bounding DT. -------------------------------------------------------- */ @@ -348,26 +348,26 @@ /*------------------------------ initialise mesh bbox */ real_type _plen[ +2]; - _plen[ 0] = _geom._bmax[ 0] - + _plen[ 0] = _geom._bmax[ 0] - _geom._bmin[ 0] ; - _plen[ 1] = _geom._bmax[ 1] - + _plen[ 1] = _geom._bmax[ 1] - _geom._bmin[ 1] ; - + _plen[ 0]*= (real_type)+2.0 ; _plen[ 1]*= (real_type)+2.0 ; - + real_type _pmin[ +2]; real_type _pmax[ +2]; - _pmin[ 0] = _geom._bmin[ 0] - + _pmin[ 0] = _geom._bmin[ 0] - _plen[ 0] ; - _pmin[ 1] = _geom._bmin[ 1] - + _pmin[ 1] = _geom._bmin[ 1] - _plen[ 1] ; - - _pmax[ 0] = _geom._bmax[ 0] + + + _pmax[ 0] = _geom._bmax[ 0] + _plen[ 0] ; - _pmax[ 1] = _geom._bmax[ 1] + + _pmax[ 1] = _geom._bmax[ 1] + _plen[ 1] ; - + _bnds. _tria.push_root(_pmin, _pmax) ; @@ -378,31 +378,31 @@ _tria.node(+1)->fdim() = +3 ; _bnds. _tria.node(+2)->fdim() = +3 ; - + _bnds. _tria.node(+0)->feat() = +0 ; _bnds. _tria.node(+1)->feat() = +0 ; _bnds. _tria.node(+2)->feat() = +0 ; - + _bnds. _tria.node(+0)->topo() = +0 ; _bnds. _tria.node(+1)->topo() = +0 ; _bnds. _tria.node(+2)->topo() = +0 ; - + /*------------------------------ seed feat from geom. */ _geom.seed_feat(_bnds, _opts) ; - + /*------------------------------ seed bnds from geom. */ - _geom.seed_mesh(_bnds, _opts) ; + _geom.seed_mesh(_bnds, _opts) ; } - + /* -------------------------------------------------------- - * INIT-MESH: init. the bounding DT. + * INIT-MESH: init. the bounding DT. -------------------------------------------------------- */ @@ -422,26 +422,26 @@ /*------------------------------ initialise mesh bbox */ real_type _plen[ +2]; - _plen[ 0] = _geom._bmax[ 0] - + _plen[ 0] = _geom._bmax[ 0] - _geom._bmin[ 0] ; - _plen[ 1] = _geom._bmax[ 1] - + _plen[ 1] = _geom._bmax[ 1] - _geom._bmin[ 1] ; - + _plen[ 0]*= (real_type)+2.0 ; _plen[ 1]*= (real_type)+2.0 ; - + real_type _pmin[ +2]; real_type _pmax[ +2]; - _pmin[ 0] = _geom._bmin[ 0] - + _pmin[ 0] = _geom._bmin[ 0] - _plen[ 0] ; - _pmin[ 1] = _geom._bmin[ 1] - + _pmin[ 1] = _geom._bmin[ 1] - _plen[ 1] ; - - _pmax[ 0] = _geom._bmax[ 0] + + + _pmax[ 0] = _geom._bmax[ 0] + _plen[ 0] ; - _pmax[ 1] = _geom._bmax[ 1] + + _pmax[ 1] = _geom._bmax[ 1] + _plen[ 1] ; - + _mesh. _tria.push_root(_pmin, _pmax) ; @@ -452,25 +452,25 @@ _tria.node(+1)->fdim() = +3 ; _mesh. _tria.node(+2)->fdim() = +3 ; - + _mesh. _tria.node(+0)->feat() = +0 ; _mesh. _tria.node(+1)->feat() = +0 ; _mesh. _tria.node(+2)->feat() = +0 ; - + _mesh. _tria.node(+0)->topo() = +0 ; _mesh. _tria.node(+1)->topo() = +0 ; _mesh. _tria.node(+2)->topo() = +0 ; - + /*------------------------------ seed mesh from init. */ - for (auto _node = - _init._mesh._set1.head(); - _node != + for (auto _node = + _init._mesh._set1.head(); + _node != _init._mesh._set1.tend(); ++_node ) { @@ -482,21 +482,21 @@ { _mesh._tria.node (_npos)->fdim() = +0 ; - + _mesh._tria.node (_npos)->feat() = +0 ; - + _mesh._tria.node - (_npos)->topo() = +0 ; - - } + (_npos)->topo() = +0 ; + } - } + } + } } - + /* -------------------------------------------------------- - * RVOR-MESH: build an rVT mesh in R^2. + * RVOR-MESH: build an rVT mesh in R^2. -------------------------------------------------------- */ @@ -514,28 +514,28 @@ rdel_opts &_args , jlog_file &_dump ) - { + { mode_type _mode = null_mode ; - + /*------------------------------ push log-file header */ _dump.push ( "#------------------------------------------------------------\n" "# |ITER.| |DEL-1| |DEL-2| \n" "#------------------------------------------------------------\n" ) ; - - /*------------------------------ ensure deterministic */ + + /*------------------------------ ensure deterministic */ std::srand( +1 ) ; - + /*------------------------------ init. list workspace */ iptr_list _nnew, _nold ; iptr_list _NNEW, _NOLD ; iptr_list _tnew, _told ; iptr_list _TNEW, _TOLD ; - + escr_list _escr ; tscr_list _TSCR ; - + edat_list _edat, _etmp ; tdat_list _TDAT ; ball_list _nbal, _vbal ; @@ -546,81 +546,81 @@ node_heap _etpq ; ball_heap _nbpq ; ball_heap _vbpq ; - + /*------------------------------ alloc. for hash obj. */ _mesh._eset._lptr. set_count ( - _mesh._tria._tset.count()*+3 , + _mesh._tria._tset.count()*+3 , containers::loose_alloc, nullptr); - + _mesh._tset._lptr. set_count ( - _mesh._tria._tset.count()*+1 , + _mesh._tria._tset.count()*+1 , containers::loose_alloc, nullptr); /*------------------------------ init. topo hash obj. */ - typename + typename mesh_type::node_list _etin ( typename mesh_type::node_hash(), - typename mesh_type::node_pred(), + typename mesh_type::node_pred(), +.8,_mesh._nset.get_alloc()) ; - - typename + + typename mesh_type::edge_list _pedg ( typename mesh_type::edge_hash(), - typename mesh_type::edge_pred(), + typename mesh_type::edge_pred(), +.8,_mesh._eset.get_alloc()) ; - + /*------------------------------ init. point counters */ containers:: fixed_array< iptr_type , rdel_opts::last_kind> _enod; - + _enod.fill( +0 ) ; - + containers:: fixed_array< - iptr_type , + iptr_type , rdel_opts::last_kind> _tnod; _tnod.fill( +0 ) ; /*------------------------------ initialise mesh obj. */ - init_bnds( _geom , _init, _hfun, + init_bnds( _geom , _init, _hfun, _bnds, _args ) ; - - init_mesh( _geom , _init, _hfun, + + init_mesh( _geom , _init, _hfun, _mesh, _args ) ; - /*-------------------- init. data for seed ball/nodes */ - - for (auto _node = - _bnds._tria._nset.head() ; - _node != + /*-------------------- init. data for seed ball/nodes */ + + for (auto _node = + _bnds._tria._nset.head() ; + _node != _bnds._tria._nset.tend() ; ++_node ) { if (_node->mark() >= +0) { - _node->idxh() = + _node->idxh() = hfun_type::null_hint() ; } } - - for (auto _node = - _mesh._tria._nset.head() ; - _node != + + for (auto _node = + _mesh._tria._nset.head() ; + _node != _mesh._tria._nset.tend() ; ++_node ) { if (_node->mark() >= +0) { - _node->idxh() = + _node->idxh() = hfun_type::null_hint() ; } } /*-------------------- main: refine edges/faces/trias */ - + iptr_type _pass = +0 ; - + for(bool_type _done=false; !_done ; ) { iptr_type _trim_freq = +10000 ; @@ -631,207 +631,207 @@ # endif if(++_pass>_args.iter()) break; - + /*------------------------- init. array workspace */ _nnew.set_count( +0) ; _nold.set_count( +0) ; // for rDT _tnew.set_count( +0) ; _told.set_count( +0) ; - + _etmp.set_count( +0) ; _edat.set_count( +0) ; _escr.set_count( +0) ; - + _nbal.set_count( +0) ; _vbal.set_count( +0) ; - + _NNEW.set_count( +0) ; // for rVT _NOLD.set_count( +0) ; _TNEW.set_count( +0) ; _TOLD.set_count( +0) ; - + _TDAT.set_count( +0) ; _TSCR.set_count( +0) ; - + /*--------- calc. "restricted-ness" incrementally */ if (_mode == null_mode ) { /*------------------------- init. protecting ball */ _mode = feat_mode ; - + /* - init_rdel( _geom, _hfun, - _bnds, _nnew, _tnew, - _edat, _escr, - _tdat, _tscr, - _nbal, _pass, + init_rdel( _geom, _hfun, + _bnds, _nnew, _tnew, + _edat, _escr, + _tdat, _tscr, + _nbal, _pass, _mode, _args) ; - */ + */ } - + if (_mode == feat_mode && _nbpq. empty() && _nbal. empty() ) { /*------------------------- init. restricted edge */ _mode = edge_mode ; - + /* - init_rdel( _geom, _hfun, - _bnds, _nnew, _tnew, - _edat, _escr, - _tdat, _tscr, - _nbal, _pass, + init_rdel( _geom, _hfun, + _bnds, _nnew, _tnew, + _edat, _escr, + _tdat, _tscr, + _nbal, _pass, _mode, _args) ; */ - } - if (_mode == edge_mode && + } + if (_mode == edge_mode && _eepq. empty() && _edat. empty() ) { /*------------------------- init. restricted topo */ _mode = topo_mode ; } - - if (_mode == topo_mode && + + if (_mode == topo_mode && _etpq. empty() && _edat. empty() ) { /*------------------------- init. restricted dual */ _mode = tria_mode ; - + /* init_rvor( _geom, _hfun, //!! different t/n sets? - _mesh, _nnew, _tnew, + _mesh, _nnew, _tnew, _tdat, _tscr, _pass, _mode, _args) ; */ } - - - - - + + + + + /*--------------------------- update faces in rDT */ - + for (auto _npos = _nold.head() ; - _npos != _nold.tend() ; + _npos != _nold.tend() ; ++_npos ) { ball_data _ball, _same; _ball._node[0] = *_npos; - _ball._kind = feat_ball; + _ball._kind = feat_ball; _bnds. _pop_ball( _ball, _same) ; - + _ball._node[0] = *_npos; - _ball._kind = voro_ball; + _ball._kind = voro_ball; _bnds. _pop_ball( _ball, _same) ; } - + for (auto _tpos = _told.head() ; - _tpos != _told.tend() ; + _tpos != _told.tend() ; ++_tpos ) { _pop_edge(_bnds, *_tpos) ; } for (auto _tpos = _told.head() ; - _tpos != _told.tend() ; + _tpos != _told.tend() ; ++_tpos ) { _bnds. _tria._put_tria( *_tpos) ; } - + for (auto _iter = _nbal.head() ; - _iter != _nbal.tend() ; + _iter != _nbal.tend() ; ++_iter ) { _nbpq .push( *_iter ) ; } for (auto _iter = _vbal.head() ; - _iter != _vbal.tend() ; + _iter != _vbal.tend() ; ++_iter ) { _vbpq .push( *_iter ) ; } for (auto _iter = _escr.head() ; - _iter != _escr.tend() ; + _iter != _escr.tend() ; ++_iter ) { _eepq .push( *_iter ) ; } - + for (auto _iter = _nbal.head() ; - _iter != _nbal.tend() ; + _iter != _nbal.tend() ; ++_iter ) { _bnds.push_ball( *_iter) ; } for (auto _iter = _vbal.head() ; - _iter != _vbal.tend() ; + _iter != _vbal.tend() ; ++_iter ) { _bnds.push_ball( *_iter) ; } for (auto _iter = _edat.head() ; - _iter != _edat.tend() ; + _iter != _edat.tend() ; ++_iter ) { _bnds.push_edge( *_iter) ; - } - + } + /*--------------------------- update faces in rVT */ - + for (auto _tpos = _TOLD.head() ; - _tpos != _TOLD.tend() ; + _tpos != _TOLD.tend() ; ++_tpos ) { _pop_tria(_mesh, *_tpos) ; } for (auto _tpos = _TOLD.head() ; - _tpos != _TOLD.tend() ; + _tpos != _TOLD.tend() ; ++_tpos ) { _mesh. _tria._put_tria( *_tpos) ; } - + for (auto _iter = _TSCR.head() ; - _iter != _TSCR.tend() ; + _iter != _TSCR.tend() ; ++_iter ) { _TTPQ .push( *_iter ) ; } for (auto _iter = _TDAT.head() ; - _iter != _TDAT.tend() ; + _iter != _TDAT.tend() ; ++_iter ) { _mesh.push_tria( *_iter) ; } - + } /* if (_args.verb() >= +2 ) { - + //-------------------- push refinement memory metrics * - + _dump.push("\n") ; _dump.push(" MEMORY statistics... \n") ; _dump.push("\n") ; - + } */ - + if (_args.verb() >= +2 ) { - + /*-------------------- push refinement scheme metrics */ - + _dump.push("\n") ; _dump.push(" REFINE statistics... \n") ; _dump.push("\n") ; @@ -866,18 +866,18 @@ _dump.push(std::to_string( _tnod[rdel_opts::sink_kind])); _dump.push("\n") ; - + } - + _dump.push("\n") ; - } - + } + } ; - + } - -# endif //__RVOR_MESH_2__ - - - + +# endif //__RVOR_MESH_2__ + + + diff --git a/src/libcpp/rdel_mesh/rvor_mesh_3.hpp b/src/libcpp/rdel_mesh/rvor_mesh_3.hpp index dec71bf..75e6ff1 100644 --- a/src/libcpp/rdel_mesh/rvor_mesh_3.hpp +++ b/src/libcpp/rdel_mesh/rvor_mesh_3.hpp @@ -1,32 +1,32 @@ /* -------------------------------------------------------- - * RVOR-MESH-3: restricted voronoi mesh-gen. in R^3. + * RVOR-MESH-3: restricted voronoi mesh-gen. in R^3. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- @@ -47,7 +47,7 @@ # define __RVOR_MESH_3__ namespace mesh { - + template < typename M , typename P , @@ -56,29 +56,29 @@ typename A = allocators::basic_alloc > class rvor_mesh_3d - { - public : - - /*--------- restricted voronoi mesh-generation in R^3 */ - + { + public : + + /*--------- restricted voronoi mesh-generation in R^3 */ + typedef M mesh_type ; typedef P mesh_pred ; typedef G geom_type ; typedef H hfun_type ; typedef A allocator ; - typedef typename + typedef typename mesh_type::real_type real_type ; - typedef typename + typedef typename mesh_type::iptr_type iptr_type ; - - + + } ; - + } - -# endif //__RVOR_MESH_3__ - - - + +# endif //__RVOR_MESH_3__ + + + diff --git a/src/libcpp/rdel_mesh/rvor_update_face_2.inc b/src/libcpp/rdel_mesh/rvor_update_face_2.inc index 37e7c95..f6f9292 100644 --- a/src/libcpp/rdel_mesh/rvor_update_face_2.inc +++ b/src/libcpp/rdel_mesh/rvor_update_face_2.inc @@ -1,32 +1,32 @@ /* -------------------------------------------------------- - * RVOR-UPDATE-2: update restricted voronoi in R^2. + * RVOR-UPDATE-2: update restricted voronoi in R^2. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- @@ -40,17 +40,17 @@ * -------------------------------------------------------- */ - + // from rvor_mesh_2.hpp - - + + /* -------------------------------------------------------- - * _POP-EDGE: delete edge from restricted-tria. + * _POP-EDGE: delete edge from restricted-tria. -------------------------------------------------------- */ - - __static_call + + __static_call __normal_call void_type _pop_edge ( mesh_type &_mesh , iptr_type _tpos @@ -69,7 +69,7 @@ tria(_tpos)->node(_tnod[1]); algorithms::isort ( - &_tnod[0], &_tnod[2], + &_tnod[0], &_tnod[2], std::less()); edge_data _edat, _same ; @@ -80,13 +80,13 @@ _mesh._pop_edge(_edat, _same) ; } } - + /* -------------------------------------------------------- * INIT-BALL: add new ball to restricted-tria. -------------------------------------------------------- */ - + __static_call __normal_call void_type init_ball ( mesh_type &_mesh, @@ -102,7 +102,7 @@ { __unreferenced (_geom) ; __unreferenced (_opts) ; - + if (_kind == feat_ball) { if (_mesh._tria. @@ -111,23 +111,23 @@ /*---------- push protecting ball for "hard" features */ ball_data _ball ; _ball._node[0] = _npos; - + _ball._pass = _pass; _ball._kind = _kind; - + _ball._ball[0] = _mesh. _tria.node(_npos)->pval(0) ; _ball._ball[1] = _mesh. _tria.node(_npos)->pval(1) ; - + real_type _rbal = _hfun.eval ( &_mesh._tria. node(_npos)->pval(0) , _mesh._tria. node(_npos)->idxh()) ; - + _ball._ball[2] = _rbal * _rbal ; - + _bset.push_tail (_ball) ; _bscr.push_tail (_ball) ; } @@ -138,36 +138,36 @@ /*---------- push protecting ball for voronoi "cover" */ ball_data _ball ; _ball._node[0] = _npos; - + _ball._pass = _pass; _ball._kind = _kind; - + _ball._ball[0] = _mesh. _tria.node(_npos)->pval(0) ; _ball._ball[1] = _mesh. _tria.node(_npos)->pval(1) ; - + real_type _rbal = _hfun.eval ( &_mesh._tria. node(_npos)->pval(0) , _mesh._tria. node(_npos)->idxh()) ; - + _rbal *= (real_type).67 ; - + _ball._ball[2] = _rbal * _rbal ; - + _bset.push_tail (_ball) ; _bscr.push_tail (_ball) ; } } - + /* -------------------------------------------------------- * PUSH-BALL: add new ball to restricted-tria. -------------------------------------------------------- */ - + __static_call __normal_call void_type push_ball ( mesh_type &_mesh , @@ -176,7 +176,7 @@ iptr_type _tpos , ball_list &_bset , ball_list &_bscr , - typename + typename mesh_type::ball_list & _ball_test , iptr_type &_nbal , char_type _kind , @@ -187,54 +187,54 @@ /*-------------------------------- check "restricted" */ for(char_type _npos =+3; _npos-- != +0; ) { - iptr_type _node = + iptr_type _node = _mesh._tria. tria( _tpos)->node(_npos) ; - + ball_data _bdat ; _bdat._node[0] = _node; _bdat._kind = _kind; _bdat._pass = _pass; - + typename mesh_type:: node_list:: item_type *_mptr = nullptr; if(_ball_test. - find (_bdat, _mptr) ) - { + find (_bdat, _mptr) ) + { /*--------------------------- don't test repeats! */ continue ; } _ball_test.push (_bdat) ; - + /*--------------------------- call ball predicate */ mesh_pred::ball_cost ( - _geom,_hfun, - _mesh, + _geom,_hfun, + _mesh, _node,_kind, - - + + _flag) ; - + /*--------------------------- push edge onto mesh */ - if (_flag + if (_flag == mesh::ring_item) _bscr. push_tail(_bdat) ; - if (_flag + if (_flag != mesh::null_item) _nbal += +1 ; } // for(iptr_type _npos = +3 ; _npos-- != +0 ; ) } - + /* -------------------------------------------------------- * PUSH-EDGE: add new edge to restricted-tria. -------------------------------------------------------- */ - + __static_call __normal_call void_type push_edge ( mesh_type &_mesh , @@ -243,7 +243,7 @@ iptr_type _tpos , edat_list &_eset , escr_list &_escr , - typename + typename mesh_type::edge_list & _edge_test , iptr_type &_nedg , iptr_type &_ndup , @@ -251,7 +251,7 @@ rdel_opts &_opts ) { - /*-------------------------------- correct node dims? */ + /*-------------------------------- correct node dims? */ iptr_type _fdim =+0 ; for(iptr_type _node =+3; _node-- != +0; ) { @@ -275,7 +275,7 @@ 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 || @@ -284,7 +284,7 @@ continue ; algorithms::isort ( - &_tnod[0], &_tnod[2], + &_tnod[0], &_tnod[2], std::less()) ; edge_data _fdat; @@ -299,12 +299,12 @@ edge_list:: item_type *_mptr = nullptr; if(_edge_test. - find( _fdat, _mptr) ) + find( _fdat, _mptr) ) { /*--------------------------- count bnd. repeats! */ - _ndup += + _ndup += _mptr->_data._dups; - + /*--------------------------- don't test repeats! */ continue ; } @@ -316,14 +316,14 @@ _fdat._eadj = _fpos; _fdat._dups = +0; // count num. dup's // only in hash-set - + /*--------------------------- call face predicate */ char_type _feat, _topo; real_type _fbal[ 3]; real_type _sbal[ 3]; mesh_pred::edge_cost ( - _geom,_hfun, - _mesh, + _geom,_hfun, + _mesh, _fdat._tadj, _fdat._eadj, _opts,_cdat, @@ -331,22 +331,22 @@ _feat,_topo, _fdat._kind, _fbal,_sbal) ; - + /*--------------------------- push edge onto mesh */ - if (_fdat._kind + if (_fdat._kind == mesh::ring_item) _escr. push_tail(_cdat) ; - if (_fdat._kind + if (_fdat._kind != mesh::null_item) _nedg += +1 ; - if (_fdat._kind + if (_fdat._kind != mesh::null_item) _fdat. _dups = +1 ; - if (_fdat._kind + if (_fdat._kind != mesh::null_item) _eset. push_tail(_fdat) ; @@ -355,13 +355,13 @@ } // for(iptr_type _fpos = +3 ; _fpos-- != +0 ; ) } - + /* -------------------------------------------------------- * PUSH-TRIA: add new tria to restricted-tria. -------------------------------------------------------- */ - + __static_call __normal_call void_type push_tria ( mesh_type &_mesh , @@ -371,7 +371,7 @@ iptr_type &_sign , tdat_list &_tset , tscr_list &_tscr , - typename + typename mesh_type::tria_list & _tria_test , iptr_type &_ntri , iptr_type _pass , @@ -381,7 +381,7 @@ /*-------------------------------- check "restricted" */ { iptr_type _tnod[ +3] ; - _tnod[0] = _mesh. + _tnod[0] = _mesh. _tria.tria(_tpos)->node(0); _tnod[1] = _mesh. _tria.tria(_tpos)->node(1); @@ -414,7 +414,7 @@ item_type *_mptr=nullptr; if(_tria_test. find( _tdat, _mptr) ) - { + { /*--------------------------- don't test repeats! */ return ; } @@ -428,8 +428,8 @@ _tdat._pass = _pass ; mesh_pred::tria_cost ( - _geom,_hfun, - _mesh, + _geom,_hfun, + _mesh, _tdat._tadj, _opts,_cdat, _tdat._part, @@ -438,20 +438,20 @@ _sign = _tdat. _part ; /*--------------------------- push edge onto mesh */ - if (_tdat._kind + if (_tdat._kind == mesh::ring_item) _tscr. push_tail(_cdat) ; - if (_tdat._kind + if (_tdat._kind != mesh::null_item) _ntri += +1 ; - if (_tdat._kind + if (_tdat._kind != mesh::null_item) _tset. push_tail(_tdat) ; } } - + /* -------------------------------------------------------- * TRIA-CIRC: calc. circumball for tria. @@ -474,21 +474,21 @@ } ; algorithms::isort( - &_tnod[0], &_tnod[3], + &_tnod[0], &_tnod[3], std::less()) ; - + /*---------------------- calc. ball in floating-point */ real_type _tbal[3] ; geometry::circ_ball_2d ( - _tbal , + _tbal , &_mesh._tria. - node(_tnod[0])->pval(0) , + node(_tnod[0])->pval(0) , &_mesh._tria. node(_tnod[1])->pval(0) , &_mesh._tria. node(_tnod[2])->pval(0) ) ; - + _mesh._tria.tria( _tpos)->circ(0) = _tbal[0] ; _mesh._tria.tria( @@ -520,104 +520,104 @@ ) { __unreferenced( _sign) ; - + /*------------------------- init. for local hash obj. */ - typename + typename mesh_type::node_list _bset ( typename mesh_type::ball_hash(), - typename mesh_type::ball_pred(), + typename mesh_type::ball_pred(), +.8, _mesh._bset.get_alloc()) ; - typename + typename mesh_type::edge_list _eset ( typename mesh_type::edge_hash(), - typename mesh_type::edge_pred(), + typename mesh_type::edge_pred(), +.8, _mesh._eset.get_alloc()) ; - + /*------------------------- push alloc. for hash obj. */ _bset._lptr.set_count ( - _tnew.count() * +3 , + _tnew.count() * +3 , containers::loose_alloc, nullptr); _eset._lptr.set_count ( - _tnew.count() * +3 , + _tnew.count() * +3 , containers::loose_alloc, nullptr); - + /*------------------------- no. "restricted" subfaces */ iptr_type _nedg = +0 ; iptr_type _nbal = +0 ; iptr_type _ntri = +0 ; - + iptr_type _ndup = +0 ; /*------------------------- calc. voronoi-dual points */ - for( auto _iter = _tnew.head(); - _iter != _tnew.tend(); + for( auto _iter = _tnew.head(); + _iter != _tnew.tend(); ++_iter ) { tria_circ(_mesh,*_iter) ; } - + /*------------- push any new protecting balls created */ if (_dim0 <= feat_mode && _dim1 >= feat_mode ) { - for( auto _iter = _nnew.head(); - _iter != _nnew.tend(); + for( auto _iter = _nnew.head(); + _iter != _nnew.tend(); ++_iter ) - { + { char_type _kind = feat_ball; - + init_ball(_mesh, _geom , - _hfun,*_iter , - _bdat, _bscr , + _hfun,*_iter , + _bdat, _bscr , _kind, _pass, _opts) ; - } + } } /*------------- push any new restricted edges created */ if (_dim0 <= edge_mode && _dim1 >= edge_mode ) { - for( auto _iter = _tnew.head(); - _iter != _tnew.tend(); + for( auto _iter = _tnew.head(); + _iter != _tnew.tend(); ++_iter ) - { + { push_edge(_mesh, _geom , - _hfun,*_iter , - _edat, _escr , - _eset, _nedg , - _ndup, + _hfun,*_iter , + _edat, _escr , + _eset, _nedg , + _ndup, _pass, _opts) ; - } + } } /*------------- push any new restricted balls created */ if (_dim0 <= ball_mode && _dim1 >= ball_mode ) { - for( auto _iter = _nnew.head(); - _iter != _nnew.tend(); + for( auto _iter = _nnew.head(); + _iter != _nnew.tend(); ++_iter ) - { + { char_type _kind = voro_ball; - + init_ball(_mesh, _geom , - _hfun,*_iter , - _bdat, _bscr , + _hfun,*_iter , + _bdat, _bscr , _kind, _pass, _opts) ; } - for( auto _iter = _tnew.head(); - _iter != _tnew.tend(); + for( auto _iter = _tnew.head(); + _iter != _tnew.tend(); ++_iter ) - { + { push_ball(_mesh, _geom , - _hfun,*_iter , + _hfun,*_iter , _bdat, _bscr , - _bset, + _bset, _pass, _opts) ; - } + } } } - + /* -------------------------------------------------------- * PUSH-RVOR: push faces onto restricted dual. @@ -639,46 +639,46 @@ ) { __unreferenced( _sign) ; - + /*------------------------- init. for local hash obj. */ - typename + typename mesh_type::tria_list _tset ( typename mesh_type::tria_hash(), - typename mesh_type::tria_pred(), + typename mesh_type::tria_pred(), +.8, _mesh._tset.get_alloc()) ; - + /*------------------------- push alloc. for hash obj. */ _tset._lptr.set_count ( - _tnew.count() * +1 , + _tnew.count() * +1 , containers::loose_alloc, nullptr); - + /*------------------------- no. "restricted" subfaces */ iptr_type _ntri = +0 ; - + /*------------------------- calc. voronoi-dual points */ - for( auto _iter = _tnew.head(); - _iter != _tnew.tend(); + for( auto _iter = _tnew.head(); + _iter != _tnew.tend(); ++_iter ) { tria_circ(_mesh,*_iter) ; } - + /*------------- push any new restricted edges created */ if (_dim0 <= tria_mode && _dim1 >= tria_mode ) { - for( auto _iter = _tnew.head(); - _iter != _tnew.tend(); + for( auto _iter = _tnew.head(); + _iter != _tnew.tend(); ++_iter ) - { + { push_tria(_mesh, _geom , - _hfun,*_iter , - _tdat, _tscr , - _tset, _ntri , + _hfun,*_iter , + _tdat, _tscr , + _tset, _ntri , _pass, _opts) ; - } + } } } - - - + + + diff --git a/src/libcpp/rdelmesh.hpp b/src/libcpp/rdelmesh.hpp index 1e1c0cf..9379fe2 100644 --- a/src/libcpp/rdelmesh.hpp +++ b/src/libcpp/rdelmesh.hpp @@ -1,32 +1,32 @@ -/* +/* ------------------------------------------------------------ - * restricted delaunay mesh generation in R^d. + * restricted delaunay mesh generation in R^d. ------------------------------------------------------------ * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * ------------------------------------------------------------ @@ -45,19 +45,19 @@ # ifndef __RDELMESH__ # define __RDELMESH__ - + namespace mesh { /*-------------------------- classification of mesh items */ char_type constexpr null_item = 0 ; char_type constexpr void_item = 1 ; char_type constexpr ring_item = 2 ; - char_type constexpr good_item = 3 ; - + char_type constexpr good_item = 3 ; + char_type constexpr null_ball = 0 ; char_type constexpr feat_ball = 1 ; } - + # include "containers.hpp" # include "algorithms.hpp" @@ -73,7 +73,6 @@ # include "rdel_mesh/rdel_complex_2.hpp" # include "rdel_mesh/rdel_complex_3.hpp" -# include "rdel_mesh/rdel_params.hpp" # include "rdel_mesh/rdel_timers.hpp" # include "rdel_mesh/rdel_filt_k.hpp" @@ -93,8 +92,8 @@ # include "rdel_mesh/rdel_make_2.hpp" # include "rdel_mesh/rdel_make_3.hpp" -# include "rdel_mesh/rvor_mesh_2.hpp" -# include "rdel_mesh/rvor_mesh_3.hpp" +// include "rdel_mesh/rvor_mesh_2.hpp" +// include "rdel_mesh/rvor_mesh_3.hpp" # endif//__RDELMESH__ diff --git a/src/libcpp/tessellate.hpp b/src/libcpp/tessellate.hpp index 032f3b2..8553ba8 100644 --- a/src/libcpp/tessellate.hpp +++ b/src/libcpp/tessellate.hpp @@ -1,32 +1,32 @@ -/* +/* ------------------------------------------------------------ - * algorithms for delaunay tessellation in R^d. + * algorithms for delaunay tessellation in R^d. ------------------------------------------------------------ * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * ------------------------------------------------------------ @@ -45,7 +45,7 @@ # ifndef __TESSELLATE__ # define __TESSELLATE__ - + # include "containers.hpp" # include "algorithms.hpp" diff --git a/src/libcpp/tessellate/del_tri_euclidean_2.hpp b/src/libcpp/tessellate/del_tri_euclidean_2.hpp index d4642a6..30a2073 100644 --- a/src/libcpp/tessellate/del_tri_euclidean_2.hpp +++ b/src/libcpp/tessellate/del_tri_euclidean_2.hpp @@ -1,32 +1,32 @@ -/* +/* ------------------------------------------------------------ * DEL-TRI-EUCLIDEAN-2: kernel for 2-dim. delaunay tria. ------------------------------------------------------------ * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * ------------------------------------------------------------ @@ -56,7 +56,7 @@ * REAL-TYPE - floating-point typedef. ------------------------------------------------------------ */ - + template < typename I, typename R @@ -83,14 +83,14 @@ __inline_call real_type lensqr_kd ( __const_ptr ( real_type) _ipos, __const_ptr ( real_type) _jpos - ) + ) { return ( geometry::lensqr_2d ( - _ipos, - _jpos) ) ; + _ipos, + _jpos) ) ; } - + template class near_pred - { + { /*------------------------------------ walk--simplex test */ public : __inline_call bool_type operator() ( @@ -101,7 +101,7 @@ iptr_type _tpos, iptr_type &_fmin ) const - { + { bool_type _done = true ; iptr_type _fpos; iptr_type _fadj; @@ -131,28 +131,28 @@ */ _fnod[2] = _mesh. tria(_tadj)->node(_fnod[2]); - - iptr_type _apex = _fnod[2] ; - + + iptr_type _apex = _fnod[2] ; + real_type _dsqr = lensqr_kd ( - _ppos, + _ppos, &_mesh.node(_fnod[2])->pval(0)); - + if (_dsqr < _dmin) { _done = false; - _dmin = _dsqr; + _dmin = _dsqr; _nmin = _apex; _fmin = _fpos; - } } - + } + return _done ; } } ; - + template class walk_pred - { + { /*------------------------------------ walk--simplex test */ public : __inline_call bool_type operator() ( @@ -161,14 +161,14 @@ iptr_type _tpos, iptr_type &_fpos ) const - { + { double _xpos[2]; _xpos[0] = _ppos[0]; _xpos[1] = _ppos[1]; - + for(_fpos = 3; _fpos-- != 0; ) { - /*--------------- test orientation wrt. k-th face */ + /*--------------- test orientation wrt. k-th face */ iptr_type _fnod[ 3] ; mesh_type::tria_type:: face_node(_fnod, _fpos, 2, 1) ; @@ -176,7 +176,7 @@ tria(_tpos)->node(_fnod[0]); _fnod[1] = _mesh. tria(_tpos)->node(_fnod[1]); - + double _ipos[2] = { _mesh.node(_fnod[0])->pval(0) , _mesh.node(_fnod[0])->pval(1) @@ -185,23 +185,23 @@ _mesh.node(_fnod[1])->pval(0) , _mesh.node(_fnod[1])->pval(1) } ; - - double _sign; + + double _sign; _sign = geompred::orient2d ( &_ipos[ 0] , &_jpos[ 0] , &_xpos[ 0] ) ; - + if (_sign < (double) +0.00 ) - return false ; + return false ; } - + return true ; } } ; - + template class circ_pred - { + { /*------------------------------------ in-circumball test */ public : __const_ptr ( real_type) _ppos ; @@ -210,7 +210,7 @@ __inline_call circ_pred ( __const_ptr ( real_type) _psrc ) : _ppos( _psrc ) { ; } - + __inline_call bool_type operator()( mesh_type &_mesh, iptr_type _tpos, @@ -222,11 +222,11 @@ _mesh.tria(_tpos )->node(1) , _mesh.tria(_tpos )->node(2) } ; - + double _xpos[2] ; _xpos[0] = this->_ppos[0] ; _xpos[1] = this->_ppos[1] ; - + double _ipos[2] = { _mesh.node(_tnod[0])->pval(0) , _mesh.node(_tnod[0])->pval(1) @@ -239,17 +239,17 @@ _mesh.node(_tnod[2])->pval(0) , _mesh.node(_tnod[2])->pval(1) } ; - - double _sign; + + double _sign; _sign = geompred::incircle ( &_ipos[ 0] , &_jpos[ 0] , &_kpos[ 0] , &_xpos[ 0] ) ; - + return (_sign >= (double)+0.) ; } - } ; + } ; class face_ptrs { @@ -257,11 +257,11 @@ public : containers::fixed_array < iptr_type, +2 > _node ; - + iptr_type _tadj ; iptr_type _fadj ; } ; - + class face_same { /*------------------------------ face indexing comparison */ @@ -277,28 +277,28 @@ _fj._node[1] ; } } ; - + class face_hash { /*------------------------------ face indexing hash-value */ public : - __inline_call iptr_type operator() ( + __inline_call uint32_t operator() ( face_ptrs const&_ff ) const { return hash::hashword ( - (uint32_t*)&_ff._node[ 0], - +2* sizeof(iptr_type) + (uint32_t*)&_ff._node[ 0], + +2* sizeof(iptr_type) / sizeof( uint32_t),13); } - } ; - + } ; + } ; - + } - -# endif //__DELAUNAY_TRI_EUCLIDEAN_2__ + +# endif //__DELAUNAY_TRI_EUCLIDEAN_2__ diff --git a/src/libcpp/tessellate/del_tri_euclidean_3.hpp b/src/libcpp/tessellate/del_tri_euclidean_3.hpp index ebc04ca..4f84503 100644 --- a/src/libcpp/tessellate/del_tri_euclidean_3.hpp +++ b/src/libcpp/tessellate/del_tri_euclidean_3.hpp @@ -1,32 +1,32 @@ -/* +/* ------------------------------------------------------------ * DEL-TRI-EUCLIDEAN-3: kernel for 3-dim. delaunay tria. ------------------------------------------------------------ * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * ------------------------------------------------------------ @@ -56,7 +56,7 @@ * REAL-TYPE - floating-point typedef. ------------------------------------------------------------ */ - + template < typename I, typename R @@ -83,14 +83,14 @@ __inline_call real_type lensqr_kd ( __const_ptr ( real_type) _ipos, __const_ptr ( real_type) _jpos - ) + ) { return ( geometry::lensqr_3d ( - _ipos, - _jpos) ) ; + _ipos, + _jpos) ) ; } - + template class near_pred - { + { /*------------------------------------ walk--simplex test */ public : __inline_call bool_type operator() ( @@ -101,12 +101,12 @@ iptr_type _tpos, iptr_type &_fmin ) const - { + { bool_type _done = true ; iptr_type _fpos; iptr_type _fadj; iptr_type _tadj; - iptr_type _fnod[4] = {0}; + iptr_type _fnod[4] = {0}; for(_fpos = 4; _fpos-- != 0; ) { @@ -120,7 +120,7 @@ if(_tadj == _mesh.null_flag()) continue ; - + mesh_type::tria_type:: face_node(_fnod, _fadj, 3, 2) ; /* @@ -133,28 +133,28 @@ */ _fnod[3] = _mesh. tria(_tadj)->node(_fnod[3]); - - iptr_type _apex = _fnod[3] ; - + + iptr_type _apex = _fnod[3] ; + real_type _dsqr = lensqr_kd ( - _ppos, + _ppos, &_mesh.node(_fnod[3])->pval(0)); - + if (_dsqr < _dmin) { _done = false; - _dmin = _dsqr; + _dmin = _dsqr; _nmin = _apex; _fmin = _fpos; - } } - + } + return _done ; } } ; - + template class walk_pred - { + { /*------------------------------------ walk--simplex test */ public : __inline_call bool_type operator() ( @@ -163,15 +163,15 @@ iptr_type _tpos, iptr_type &_fpos ) const - { + { double _xpos[3]; _xpos[0] = _ppos[0]; _xpos[1] = _ppos[1]; _xpos[2] = _ppos[2]; - + for(_fpos = 4; _fpos-- != 0; ) { - /*--------------- test orientation wrt. k-th face */ + /*--------------- test orientation wrt. k-th face */ iptr_type _fnod[ 4] ; mesh_type::tria_type:: face_node(_fnod, _fpos, 3, 2) ; @@ -181,7 +181,7 @@ tria(_tpos)->node(_fnod[1]); _fnod[2] = _mesh. tria(_tpos)->node(_fnod[2]); - + double _ipos[3] = { _mesh.node(_fnod[0])->pval(0) , _mesh.node(_fnod[0])->pval(1) , @@ -197,24 +197,24 @@ _mesh.node(_fnod[2])->pval(1) , _mesh.node(_fnod[2])->pval(2) } ; - - double _sign; + + double _sign; _sign = geompred::orient3d ( &_ipos[ 0] , &_jpos[ 0] , &_kpos[ 0] , &_xpos[ 0] ) ; - + if (_sign > (double) +0.00 ) - return false ; + return false ; } - + return true ; } } ; - + template class circ_pred - { + { /*------------------------------------ in-circumball test */ public : __const_ptr ( real_type) _ppos ; @@ -223,7 +223,7 @@ __inline_call circ_pred ( __const_ptr ( real_type) _psrc ) : _ppos( _psrc ) { ; } - + __inline_call bool_type operator()( mesh_type &_mesh, iptr_type _tpos, @@ -236,12 +236,12 @@ _mesh.tria(_tpos )->node(2) , _mesh.tria(_tpos )->node(3) } ; - + double _xpos[3] ; _xpos[0] = this->_ppos[0] ; _xpos[1] = this->_ppos[1] ; _xpos[2] = this->_ppos[2] ; - + double _ipos[3] = { _mesh.node(_tnod[0])->pval(0) , _mesh.node(_tnod[0])->pval(1) , @@ -262,18 +262,18 @@ _mesh.node(_tnod[3])->pval(1) , _mesh.node(_tnod[3])->pval(2) } ; - - double _sign; + + double _sign; _sign = geompred::insphere ( &_ipos[ 0] , &_jpos[ 0] , &_kpos[ 0] , &_lpos[ 0] , &_xpos[ 0] ) ; - + return (_sign <= (double)0.0) ; } - } ; + } ; class face_ptrs { @@ -281,11 +281,11 @@ public : containers::fixed_array < iptr_type, +3 > _node ; - + iptr_type _tadj ; iptr_type _fadj ; } ; - + class face_same { /*------------------------------ face indexing comparison */ @@ -303,28 +303,28 @@ _fj._node[2] ; } } ; - + class face_hash { /*------------------------------ face indexing hash-value */ public : - __inline_call iptr_type operator() ( + __inline_call uint32_t operator() ( face_ptrs const&_ff ) const { return hash::hashword ( - (uint32_t*)&_ff._node[ 0], - +3* sizeof(iptr_type) + (uint32_t*)&_ff._node[ 0], + +3* sizeof(iptr_type) / sizeof( uint32_t),13); } - } ; - + } ; + } ; - - + + } - -# endif //__DELAUNAY_TRI_EUCLIDEAN_3__ - - - + +# endif //__DELAUNAY_TRI_EUCLIDEAN_3__ + + + diff --git a/src/libcpp/tessellate/delaunay_scan_tria.inc b/src/libcpp/tessellate/delaunay_scan_tria.inc index 3a2a140..ac0d628 100644 --- a/src/libcpp/tessellate/delaunay_scan_tria.inc +++ b/src/libcpp/tessellate/delaunay_scan_tria.inc @@ -4,29 +4,29 @@ * SCAN-TRIA-LIST: breadth-first-search about tria. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- @@ -42,35 +42,35 @@ */ // from delaunay_tri_k.hpp - + /* -------------------------------------------------------- * SCAN-TRIA-LIST: breadth-first-search about tria. -------------------------------------------------------- */ - + template < typename func_type > __normal_call void_type scan_tria_list ( iptr_type _elem, - fptr_type _flag, + char_type _flag, func_type &_pred, iptr_list &_list ) { _list.push_tail(_elem); - + __mark(_elem)+= _flag ; - + /*--------- traversal about _elem while _pred is true */ for (typename iptr_list:: - size_type _iter = +0 ; + size_type _iter = +0 ; _iter != _list.count(); ++_iter) { /*--------- scan all faces within current element */ - for(iptr_type _fpos = tria_pred::_dims + 1; + for(iptr_type _fpos = tria_pred::_dims + 1; _fpos-- != +0 ; ) { /*--------- find neighbour about current edge */ @@ -94,13 +94,13 @@ } /*------------------------------ need for degeneracy? */ - algorithms::qsort(_list.head(), - _list.tend(), + algorithms::qsort(_list.head(), + _list.tend(), std::less()) ; - + /*------------------------------ unmark list of trias */ for (typename iptr_list:: - size_type _iter = +0 ; + size_type _iter = +0 ; _iter != _list.count(); ++_iter) { __mark( _list[_iter]) -=_flag ; diff --git a/src/libcpp/tessellate/delaunay_star_void.inc b/src/libcpp/tessellate/delaunay_star_void.inc index 4c03a79..f57143f 100644 --- a/src/libcpp/tessellate/delaunay_star_void.inc +++ b/src/libcpp/tessellate/delaunay_star_void.inc @@ -4,36 +4,36 @@ * STAR-TRIA-VOID: triangulate a star-shaped cavity. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 12 May, 2017 + * Last updated: 03 July, 2019 * - * Copyright 2013-2017 + * Copyright 2013-2019 * Darren Engwirda * de2363@columbia.edu * https://github.com/dengwirda/ @@ -42,19 +42,19 @@ */ // from delaunay_tri_k.hpp - + /* -------------------------------------------------------- * STAR-TRIA-VOID: re-tria. star-shaped cavity. -------------------------------------------------------- */ - + template < - typename list_type + typename list_type > __normal_call void_type star_tria_void ( - iptr_list &_tset , + iptr_list &_vset , iptr_type _npos , char_type _flag , list_type *_tnew = nullptr , @@ -62,8 +62,8 @@ ) { /*---------------------- mark list of trias in cavity */ - for(auto _iter = _tset.head(); - _iter != _tset.tend(); + for(auto _iter = _vset.head(); + _iter != _vset.tend(); ++_iter ) { __mark(*_iter) += _flag ; @@ -72,27 +72,30 @@ /*---------------------- scan list of trias in cavity */ iptr_type static constexpr FACE_SIZE = tria_pred::_dims+1; - - this->_fset._lptr.set_count ( - _tset.count()*tria_dims , - containers::loose_alloc, nullptr) ; - for(auto _iter = _tset.head() ; - _iter != _tset.tend() ; + this->_fset.set_slots ( + _vset.count()* tria_dims ) ; + + __assert ( + this->_fset.count() == +0 && + "star-tria-void: hashtable non-empty!" ) ; + + for(auto _iter = _vset.head() ; + _iter != _vset.tend() ; ++_iter ) { if (__mark(*_iter)<_flag) continue ; /*-------------------------- scan for cavity face */ - for(iptr_type _fpos = tria_dims +1 ; + for(iptr_type _fpos = tria_dims +1 ; _fpos-- != +0 ; ) { iptr_type _tadj, _fadj, _fmrk ; - find_pair(*_iter, _tadj, + find_pair(*_iter, _tadj, _fpos, _fadj, _fmrk) ; /*--------------- continue if cavity face */ - if (_tadj == this->null_flag() || + if (_tadj == this->null_flag() || __mark(_tadj) < _flag ) { @@ -107,12 +110,12 @@ iptr_type _tnod[FACE_SIZE]; tria_type::face_node( _tnod,_fpos , - tria_dims-0, tria_dims-1) ; + tria_dims-0, tria_dims-1) ; iptr_type _inod; - for(_inod = tria_dims + 0 ; + for(_inod = tria_dims + 0 ; _inod-- != +0 ; ) { - _tnod[ _inod] = + _tnod[ _inod] = tria( *_iter)-> node(_tnod[ _inod]); } @@ -125,32 +128,32 @@ node( _tnod[_inod])->next()=_tria ; } - for(_inod = tria_dims + 1 ; + for(_inod = tria_dims + 1 ; _inod-- != +0 ; ) { tria(_tria)-> node(_inod) = _tnod[_inod]; } - + /*---------------- push about cavity boundary */ - push_pair(_tria, _tadj, 0 , + push_pair(_tria, _tadj, 0 , _fadj, _fmrk) ; /*---------------- face indexing for new tria */ - for(iptr_type _posf = tria_dims + 1; + for(iptr_type _posf = tria_dims + 1; _posf-- != +1 ; ) { iptr_type _fnod[FACE_SIZE]; tria_type::face_node( _fnod,_posf , tria_dims-0, tria_dims-1) ; - + face_ptrs _fdat, _same ; - for(_inod = tria_dims + 0 ; + for(_inod = tria_dims + 0 ; _inod-- != +0 ; ) { - _fdat._node[_inod] = - tria(_tria)-> + _fdat._node[_inod] = + tria(_tria)-> node(_fnod[_inod]) ; } _fdat._tadj = _tria ; @@ -168,8 +171,8 @@ else { push_pair(_fdat._tadj , - _same._tadj, - _fdat._fadj, + _same._tadj, + _fdat._fadj, _same._fadj, +1 ) ; } } @@ -178,14 +181,14 @@ } /*------------------------------ un-mark cavity trias */ - for(auto _iter = _tset.head() ; - _iter != _tset.tend() ; + for(auto _iter = _vset.head() ; + _iter != _vset.tend() ; ++_iter ) { if (__mark(*_iter) >= _flag) { __mark(*_iter) -= _flag; - + if (_told != nullptr) { /*------------------ push "old" tria list */ @@ -201,6 +204,6 @@ /*------------------------------ mesh is now delaunay */ } - - - + + + diff --git a/src/libcpp/tessellate/delaunay_tri_k.hpp b/src/libcpp/tessellate/delaunay_tri_k.hpp index 0ef6511..0bc0a9a 100644 --- a/src/libcpp/tessellate/delaunay_tri_k.hpp +++ b/src/libcpp/tessellate/delaunay_tri_k.hpp @@ -1,37 +1,37 @@ - /* + /* -------------------------------------------------------- * a "k"-dimensional delaunay triangulation object. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 18 February, 2019 + * Last updated: 03 July, 2019 * * Copyright 2013-2019 * Darren Engwirda @@ -44,26 +44,26 @@ * supporting incremental insertion. This is a Bowyer- * Watson type implemetation, based on: * - * A. Bowyer, (1981): "Computing Dirichlet - * Tessellations", Comput. J. 24 (2), pp. 162-166, + * A. Bowyer, (1981): "Computing Dirichlet + * Tessellations", Comput. J. 24 (2), pp. 162-166, * https://doi.org/10.1093/comjnl/24.2.162 * - * D. Watson, (1981): "Computing the n-dimensional - * Delaunay tessellation with application to Voronoi - * polytopes". Comput. J. 24 (2), pp. 167-172, + * D. Watson, (1981): "Computing the n-dimensional + * Delaunay tessellation with application to Voronoi + * polytopes". Comput. J. 24 (2), pp. 167-172, * https://doi.org/10.1093/comjnl/24.2.167 * - * J.D. Boissonnat, O. Devillers, S. Pion, M. Teillaud, - * M. Yvinec, (2002): "Triangulations in CGAL". Comput. + * J.D. Boissonnat, O. Devillers, S. Pion, M. Teillaud, + * M. Yvinec, (2002): "Triangulations in CGAL". Comput. * Geom. Theory Appl., 22, pp. 5-19, - * https://doi.org/10.1016/S0925-7721(01)00054-2 + * https://doi.org/10.1016/S0925-7721(01)00054-2 * * My implementation is described here: * * D. Engwirda, (2014): "Locally-optimal Delaunay- - * refinement and optimisation-based mesh generation", - * Ph.D. Thesis, School of Mathematics and Statistics, - * Univ. of Sydney. + * refinement and optimisation-based mesh generation", + * Ph.D. Thesis, School of Mathematics and Statistics, + * Univ. of Sydney. * http://hdl.handle.net/2123/13148 * -------------------------------------------------------- @@ -75,7 +75,7 @@ # define __DELAUNAY_TRI_K__ namespace mesh { - + /* -------------------------------------------------------- * DELAUNAY-TRI-K: a k-dim. delaunay tri. object. @@ -91,48 +91,48 @@ typename N , typename T , typename P , - typename A = allocators::basic_alloc + typename A = allocators::basic_alloc > class delaunay_tri_k - { + { /*------------------------- delaunay triangulation in R^k */ public : - + typedef N node_type ; typedef T tria_type ; typedef A allocator ; typedef P tria_pred ; - typedef typename + typedef typename node_type::real_type real_type ; - typedef typename + typedef typename tria_type::iptr_type iptr_type ; typedef char_type fptr_type ; /*------------------------- alternative to "static const" */ - + iptr_type static constexpr null_mark = +0 ; iptr_type static constexpr tria_dims = tria_pred::_dims; - + __static_call __inline_call iptr_type null_flag ( - ) + ) { return std::numeric_limits::max()- 2 ; } typedef mesh::delaunay_tri_k < - node_type, - tria_type, - tria_pred, + node_type, + tria_type, + tria_pred, allocator > self_type ; - typedef typename + typedef typename tria_pred::face_ptrs face_ptrs ; - typedef typename + typedef typename tria_pred::face_hash face_hash ; - typedef typename + typedef typename tria_pred::face_same face_same ; iptr_type static constexpr pool_byte_size = 96*1024 ; @@ -151,90 +151,90 @@ pool_wrap > hash_list ; typedef containers::block_array < - node_type , + node_type , allocator > node_list ; typedef containers::block_array < - tria_type , + tria_type , allocator > tria_list ; typedef containers::array < - iptr_type , + iptr_type , allocator > iptr_list ; public : - + pool_base _fpol ; hash_list _fset ; node_list _nset ; tria_list _tset ; - - iptr_list _ftri ; - iptr_list _fnod ; + + iptr_list _tpop ; + iptr_list _npop ; iptr_list _work ; public : # define __mark(__ti) tria((__ti))->mark() - + /* -------------------------------------------------------- * NODE/TRIA "get" and "set" access. -------------------------------------------------------- */ - + __inline_call node_type * node ( iptr_type _ipos ) { return &this->_nset[_ipos] ; } - + __inline_call tria_type * tria ( iptr_type _ipos ) { return &this->_tset[_ipos] ; } - + __inline_call node_type const* node ( iptr_type _ipos ) const { return &this->_nset[_ipos] ; } - + __inline_call tria_type const* tria ( iptr_type _ipos ) const { return &this->_tset[_ipos] ; } - + /* -------------------------------------------------------- * PUT-NODE: "delete" node from active set. -------------------------------------------------------- */ - + __inline_call void_type _put_node ( iptr_type _ipos ) { - this->_fnod.push_tail(_ipos); + this->_npop.push_tail(_ipos); this->_nset[_ipos].mark()=-1; } - + /* -------------------------------------------------------- * PUT-TRIA: "delete" tria from active set. -------------------------------------------------------- */ - + __inline_call void_type _put_tria ( iptr_type _ipos ) { - this->_ftri.push_tail(_ipos); + this->_tpop.push_tail(_ipos); this->_tset[_ipos].mark()=-1; } @@ -243,16 +243,16 @@ * GET-NODE: "create" node into active set. -------------------------------------------------------- */ - + __inline_call iptr_type _get_node ( ) { iptr_type _ipos = -1; - if (this->_fnod.count() != +0 ) + if (this->_npop.count() != +0 ) { /*------------------------ recycle from free list */ this-> - _fnod._pop_tail(_ipos) ; + _npop._pop_tail(_ipos) ; } else { @@ -266,22 +266,22 @@ return ( _ipos ) ; } - + /* -------------------------------------------------------- * GET-TRIA: "create" tria into active set. -------------------------------------------------------- */ - + __inline_call iptr_type _get_tria ( ) { iptr_type _ipos = -1; - if (this->_ftri.count() != +0 ) + if (this->_tpop.count() != +0 ) { /*------------------------ recycle from free list */ this-> - _ftri._pop_tail(_ipos) ; + _tpop._pop_tail(_ipos) ; } else { @@ -295,13 +295,13 @@ return ( _ipos ) ; } - + /* -------------------------------------------------------- * FIND-PAIR: return adjacent tria/face indexing. -------------------------------------------------------- */ - + __inline_call void_type find_pair ( iptr_type _ipos, iptr_type &_jpos, @@ -313,21 +313,21 @@ /*---------------- unwind face adjacency pointers */ _jfac = __unflip( tria(_ipos)->fpos(_ifac)) ; - + _jpos = __unflip( tria(_ipos)->next(_ifac)) ; - + _flag = __isflip( - tria(_ipos)->next(_ifac)) + tria(_ipos)->next(_ifac)) ? -1 : +1 ; - } - + } + /* -------------------------------------------------------- * PUSH-PAIR: encode adjacent tria/face indexing. -------------------------------------------------------- */ - + __inline_call void_type push_pair ( iptr_type _itri, iptr_type _jtri, @@ -345,11 +345,11 @@ else tria(_itri)-> next(_ifac)=__doflip(_jtri) ; - + tria(_itri)-> fpos(_ifac) = (char_type)_jfac; } - + if (_jtri != this->null_flag()) { if (_flag >= +0) @@ -358,28 +358,28 @@ else tria(_jtri)-> next(_jfac)=__doflip(_itri) ; - + tria(_jtri)-> fpos(_jfac) = (char_type)_ifac; - } - } - + } + } + /* -------------------------------------------------------- * SCAN-TRIA-LIST: breadth-first-search about tria. -------------------------------------------------------- */ - -# include "delaunay_scan_tria.inc" - - + +# include "delaunay_scan_tria.inc" + + /* -------------------------------------------------------- * WALK-TRIA-NEAR: "nearest" tria. via walking. * WALK-NODE-NEAR: "nearest" vert. via walking. -------------------------------------------------------- */ - + # include "delaunay_walk_mesh.inc" @@ -388,41 +388,63 @@ * STAR-TRIA-VOID: re-tria. star-shaped cavity. -------------------------------------------------------- */ - + # include "delaunay_star_void.inc" - + public : - + /* -------------------------------------------------------- * CONSTRUCT: create a del.-tri. obj. from alloc. -------------------------------------------------------- */ - + __inline_call delaunay_tri_k ( allocator const& _asrc = allocator () ) : _fpol(sizeof( typename hash_list::item_type)) , - _fset(face_hash(), - face_same(), - +.9, (pool_wrap(&_fpol))) , + _fset(face_hash(), + face_same(), + +.8, (pool_wrap(&_fpol))) , _nset( _asrc), _tset( _asrc), - _ftri( _asrc), - _fnod( _asrc), + _tpop( _asrc), + _npop( _asrc), _work( _asrc) { tria_pred::exactinit() ; // init. predicates } - + + /* + -------------------------------------------------------- + * CLEAR: clear/dealloc internal data-structures. + -------------------------------------------------------- + */ + + __normal_call void_type clear ( + containers::alloc_types _alloc = + containers::loose_alloc + ) + { + this->_nset.clear(_alloc) ; + this->_tset.clear(_alloc) ; + + this->_npop.clear(_alloc) ; + this->_tpop.clear(_alloc) ; + + this->_work.clear(_alloc) ; + + this->_fset.clear(_alloc) ; + } + /* -------------------------------------------------------- * PUSH-ROOT: push the bounding "super" triangle. -------------------------------------------------------- */ - + __normal_call void_type push_root ( __const_ptr(real_type) _pmin, __const_ptr(real_type) _pmax @@ -433,87 +455,87 @@ this->_tset.clear() ; /*---------------------------- scale initial tria */ - real_type static constexpr _scal = + real_type static constexpr _scal = (real_type)+tria_pred::_dims ; real_type _pmid[tria_pred::_dims]; real_type _pdel = (real_type)+.0 ; - for (auto _idim = tria_pred::_dims + 0 ; + for (auto _idim = tria_pred::_dims + 0 ; _idim-- != + 0 ; ) { - real_type _xdel=_pmax[_idim] - - _pmin[_idim] ; - - _pdel = + real_type _xdel=_pmax[_idim] - + _pmin[_idim] ; + + _pdel = std::max(_pdel,_xdel) ; - - _pmid[_idim] = + + _pmid[_idim] = _pmax[_idim] *(real_type)+.5 + _pmin[_idim] *(real_type)+.5 ; } /*---------------------------- push tria indexing */ iptr_type _itri = _get_tria() ; - for (auto _inod = tria_pred::_dims + 1 ; + for (auto _inod = tria_pred::_dims + 1 ; _inod-- != + 0 ; ) { tria(_itri)->node(_inod) =_inod; - + tria(_itri)->fpos(_inod) = -1; - + tria(_itri)->next(_inod) = __doflip(this->null_flag()); } /*------------------------- push node coordinates */ - for (auto _inod = tria_pred::_dims + 1 ; + for (auto _inod = tria_pred::_dims + 1 ; _inod-- != + 0 ; ) { iptr_type _jnod = _get_node() ; node(_jnod)->next() = _itri; - for (auto _idim = tria_pred::_dims + 0 ; + for (auto _idim = tria_pred::_dims + 0 ; _idim-- != + 0 ; ) { if (_idim != _jnod - 1 ) - node(_jnod)->pval(_idim) = - _pmid[_idim] - + node(_jnod)->pval(_idim) = + _pmid[_idim] - (real_type).5*_pdel ; else - node(_jnod)->pval(_idim) = - _pmid[_idim] + + node(_jnod)->pval(_idim) = + _pmid[_idim] + (real_type)1.*_pdel*_scal ; } } } - + /* -------------------------------------------------------- * FIND-TRIA: find "nearest" triangle for a point. -------------------------------------------------------- */ - + __inline_call bool_type find_tria ( __const_ptr(real_type) _ppos, iptr_type &_tpos, iptr_type _hint = null_flag() ) - { + { return walk_tria_near ( _ppos, _tpos, _hint) ; } - + /* -------------------------------------------------------- * FIND-NODE: find the "nearest" vert. to a point. -------------------------------------------------------- */ - + __inline_call bool_type find_node ( __const_ptr(real_type) _ppos, iptr_type &_npos, iptr_type _hint = null_flag() ) - { + { return walk_node_near ( _ppos, _npos, _hint) ; } @@ -523,7 +545,7 @@ * CIRC-LIST: find "conflict" triangles for point. -------------------------------------------------------- */ - + template < typename list_type > @@ -539,20 +561,20 @@ if (walk_mesh_node(_ppos, _elem, _hint)) { /*------------------------------ bfs about cavity */ - typename tria_pred:: + typename tria_pred:: template circ_pred< self_type >_pred( _ppos) ; - - scan_tria_list (_elem, +1, + + scan_tria_list (_elem, +1, _pred, _work) ; - + /*------------------------------ push index lists */ _list.push_tail (_work.head(), _work.tend()) ; - + return ( true ) ; } - + return ( false ) ; } @@ -561,7 +583,7 @@ * PUSH-NODE: push a new node into a triangulation. -------------------------------------------------------- */ - + __inline_call bool_type push_node ( __const_ptr(real_type) _ppos, iptr_type &_node, @@ -573,7 +595,7 @@ (iptr_list*)nullptr, (iptr_list*)nullptr, (iptr_list*)nullptr) ; - + return ( _pass ) ; } @@ -598,26 +620,26 @@ /*--------------------------- push new node onto list */ _node = _get_node() ; - for (auto _idim = tria_pred::_dims + 0 ; + for (auto _idim = tria_pred::_dims + 0 ; _idim-- != +0 ; ) { node(_node)->pval(_idim) = _ppos[_idim]; - } + } /*--------------------------- grab enclosing indexing */ iptr_type _tnod[ +1 + tria_pred::_dims]; - for (auto _inod = tria_pred::_dims + 1 ; + for (auto _inod = tria_pred::_dims + 1 ; _inod-- != +0 ; ) { _tnod[_inod] = tria(_elem)->node(_inod); } /*--------------------------- test for node duplicate */ - real_type _dist = + real_type _dist = std::numeric_limits ::infinity() ; - - for (auto _inod = tria_pred::_dims + 1 ; + + for (auto _inod = tria_pred::_dims + 1 ; _inod-- != +0 ; ) { _dist = std::min(_dist, @@ -636,31 +658,31 @@ typename tria_pred:: template circ_pred< self_type> _pred( _ppos) ; - + if (_circ == nullptr) - scan_tria_list(_elem, +1 , + scan_tria_list(_elem, +1 , _pred, _work) ; else - _work.push_tail(_circ->head() , + _work.push_tail(_circ->head() , _circ->tend() ) ; - - star_tria_void(_work, _node, + + star_tria_void(_work, _node, +1, _tnew, _told) ; /*-------------------- delaunay topology is recovered */ return ( true ) ; } - + return ( false ) ; } - + /* -------------------------------------------------------- * ROLL-BACK: "roll-back" an update. -------------------------------------------------------- */ - + template < typename list_type > @@ -675,7 +697,7 @@ _tpos != _tnew.tend(); ++_tpos ) { - for (_npos = tria_pred::_dims+1; + for (_npos = tria_pred::_dims+1; _npos-- != +0 ; ) { node(tria(*_tpos ) @@ -683,12 +705,12 @@ ->next() = null_flag(); } } - + for (auto _tpos = _told.head(); _tpos != _told.tend(); ++_tpos ) { - for (_npos = tria_pred::_dims+1; + for (_npos = tria_pred::_dims+1; _npos-- != +0 ; ) { node(tria(*_tpos ) @@ -696,17 +718,17 @@ ->next() = *_tpos ; } - for (_fpos = tria_pred::_dims+1; + for (_fpos = tria_pred::_dims+1; _fpos-- != +0 ; ) { iptr_type _tadj; iptr_type _fadj; iptr_type _flag; - find_pair(*_tpos, _tadj , + find_pair(*_tpos, _tadj , _fpos, _fadj, _flag ) ; - push_pair(*_tpos, _tadj , - _fpos, _fadj , + push_pair(*_tpos, _tadj , + _fpos, _fadj , _flag) ; } } @@ -715,11 +737,11 @@ _tpos != _tnew.tend(); ++_tpos ) { - for (_npos = tria_pred::_dims+1; + for (_npos = tria_pred::_dims+1; _npos-- != +0 ; ) { if (node(tria(*_tpos ) - ->node( _npos)) + ->node( _npos)) ->mark()>= +0 ) if (node(tria(*_tpos ) ->node( _npos)) @@ -730,7 +752,7 @@ } } } - + for (auto _tpos = _tnew.head(); _tpos != _tnew.tend(); ++_tpos ) @@ -738,13 +760,13 @@ _put_tria(*_tpos) ; } } - + /* -------------------------------------------------------- * WALK-NODE: do breadth-first-search about node. -------------------------------------------------------- */ - + template < typename tria_pred , typename list_type @@ -761,7 +783,7 @@ this->_work.clear() ; /*----------------------------------- bfs about _node */ scan_tria_list ( - node(_node)->next(), + node(_node)->next(), +1 , _pred, _work) ; /*----------------------------------- push index list */ @@ -769,13 +791,13 @@ _work.tend()) ; } } - + /* -------------------------------------------------------- * WALK-TRIA: do breadth-first-search about tria. -------------------------------------------------------- */ - + template < typename tria_pred, typename list_type @@ -786,23 +808,23 @@ list_type &_list ) { - this->_work.clear() ; + this->_work.clear() ; /*----------------------------------- bfs about _tria */ - scan_tria_list (_tria, +1, + scan_tria_list (_tria, +1, _pred, _work) ; - + /*----------------------------------- push index list */ _list.push_tail (_work.head(), _work.tend()) ; } - -# undef __mark - + +# undef __mark + } ; - + } - + # endif //__DELAUNAY_TRI_K__ diff --git a/src/libcpp/tessellate/delaunay_tri_type_2.hpp b/src/libcpp/tessellate/delaunay_tri_type_2.hpp index c2ffb87..3411f82 100644 --- a/src/libcpp/tessellate/delaunay_tri_type_2.hpp +++ b/src/libcpp/tessellate/delaunay_tri_type_2.hpp @@ -1,45 +1,45 @@ -/* ------------------------------------------------------------- - * DEL-TRI-TYPE-2: data-types for 2-dim. delaunay tria. ------------------------------------------------------------- - * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) - * - * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The - * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be - * used at your own risk. - * ------------------------------------------------------------- - * - * Last updated: 12 May, 2017 - * - * Copyright 2013-2017 - * Darren Engwirda - * de2363@columbia.edu - * https://github.com/dengwirda/ - * ------------------------------------------------------------- - */ + /* + -------------------------------------------------------- + * DEL-TRI-TYPE-2: datatypes for 2-dim. delaunay tria. + -------------------------------------------------------- + * + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) + * + * Disclaimer: Neither I nor: Columbia University, The + * Massachusetts Institute of Technology, The + * University of Sydney, nor The National Aeronautics + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be + * used at your own risk. + * + -------------------------------------------------------- + * + * Last updated: 12 May, 2017 + * + * Copyright 2013-2017 + * Darren Engwirda + * de2363@columbia.edu + * https://github.com/dengwirda/ + * + -------------------------------------------------------- + */ # pragma once @@ -48,15 +48,15 @@ namespace mesh { -/* ------------------------------------------------------------- - * DELAUNAY-TRI-NODE-2: node for delaunay tria. in R^2. ------------------------------------------------------------- - * IPTR-TYPE - signed-integer typedef. - * REAL-TYPE - floating-point typedef. ------------------------------------------------------------- - */ - + /* + -------------------------------------------------------- + * DELAUNAY-TRI-NODE-2: node for delaunay tria. in R^2. + -------------------------------------------------------- + * IPTR-TYPE - signed-integer typedef. + * REAL-TYPE - floating-point typedef. + -------------------------------------------------------- + */ + template < typename I, typename R @@ -73,10 +73,10 @@ /*------------------------------------ local data members */ containers:: fixed_array _pval ; // node coord - + containers:: fixed_array _flag ; // kind, mark - + iptr_type _next ; /*---------------------------------------- "write access" */ @@ -111,15 +111,15 @@ } ; -/* ------------------------------------------------------------- - * DELAUNAY-TRI-TRIA-2: tria for delaunay tria. in R^2. ------------------------------------------------------------- - * IPTR-TYPE - signed-integer typedef. - * REAL-TYPE - floating-point typedef. ------------------------------------------------------------- - */ - + /* + -------------------------------------------------------- + * DELAUNAY-TRI-TRIA-2: tria for delaunay tria. in R^2. + -------------------------------------------------------- + * IPTR-TYPE - signed-integer typedef. + * REAL-TYPE - floating-point typedef. + -------------------------------------------------------- + */ + template < typename I, typename R @@ -136,13 +136,13 @@ /*------------------------------------ local data members */ containers:: fixed_array _ndat ; // node indexing - + containers:: fixed_array _edat ; // edge neighbour - + containers:: fixed_array _epos ; // edge neighbour - + containers:: fixed_array _flag ; // kind, mark @@ -219,25 +219,31 @@ case 0 : { _fnod[0] = 0 ; - _fnod[1] = 1 ; + _fnod[1] = 1 ; _fnod[2] = 2 ; break ; } case 1 : { _fnod[0] = 1 ; - _fnod[1] = 2 ; + _fnod[1] = 2 ; _fnod[2] = 0 ; break ; } case 2 : { _fnod[0] = 2 ; - _fnod[1] = 0 ; + _fnod[1] = 0 ; _fnod[2] = 1 ; break ; } + default: + { // suppress compiler warnings + _fnod[0] =-1 ; + _fnod[1] =-1 ; + _fnod[2] =-1 ; break ; + } } } __static_call - __inline_call void_type face_node ( + __inline_call void_type face_node ( iptr_type *_fnod, iptr_type _fpos, iptr_type _from, @@ -250,13 +256,19 @@ /* index INTO 2-dim faces */ if (_into == +2) { - faceind22(_fnod, _fpos); + faceind22(_fnod, _fpos); return ; } /* index INTO 1-dim faces */ else if (_into == +1) { - faceind21(_fnod, _fpos); + faceind21(_fnod, _fpos); return ; + } + else + { + _fnod[0] = -1; // suppress compiler warnings + _fnod[1] = -1; + _fnod[2] = -1; return ; } } /* index FROM 1-dim faces */ @@ -266,17 +278,26 @@ /* index INTO 1-dim faces */ if (_into == +1) { - faceind11(_fnod, _fpos); + faceind11(_fnod, _fpos); return ; + } + else + { + _fnod[0] = -1; // suppress compiler warnings + _fnod[1] = -1; return ; } } + else + { + _fnod[0] = -1; // suppress compiler warnings + } } } ; } - -# endif//__DELAUNAY_TRI_TYPE_2__ - - - + +# endif // __DELAUNAY_TRI_TYPE_2__ + + + diff --git a/src/libcpp/tessellate/delaunay_tri_type_3.hpp b/src/libcpp/tessellate/delaunay_tri_type_3.hpp index 12af353..ebe855d 100644 --- a/src/libcpp/tessellate/delaunay_tri_type_3.hpp +++ b/src/libcpp/tessellate/delaunay_tri_type_3.hpp @@ -1,32 +1,32 @@ -/* +/* ------------------------------------------------------------ * DEL-TRI-TYPE-3: data-types for 3-dim. delaunay tria. ------------------------------------------------------------ * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * ------------------------------------------------------------ @@ -56,7 +56,7 @@ * REAL-TYPE - floating-point typedef. ------------------------------------------------------------ */ - + template < typename I, typename R @@ -73,10 +73,10 @@ /*------------------------------------ local data members */ containers:: fixed_array _pval ; // node coord - + containers:: fixed_array _flag ; // kind, mark - + iptr_type _next ; /*---------------------------------------- "write" access */ @@ -110,7 +110,7 @@ } } ; - + /* ------------------------------------------------------------ * DELAUNAY-TRI-TRIA-3: tria for delaunay tria. in R^3. @@ -119,13 +119,13 @@ * REAL-TYPE - floating-point typedef. ------------------------------------------------------------ */ - + template < typename I, - typename R + typename R > class delaunay_tri_tria_3 - { + { /*----------- tria-type for delaunay triangulation in R^3 */ public: typedef R real_type ; @@ -136,13 +136,13 @@ /*------------------------------------ local data members */ containers:: fixed_array _ndat ; // node indexing - + containers:: fixed_array _fdat ; // edge neighbour - + containers:: fixed_array _fpos ; // edge neighbour - + containers:: fixed_array _flag ; // kind, mark @@ -228,33 +228,40 @@ switch (_fpos) { case 0 : - { + { _fnod[0] = 0 ; _fnod[1] = 1 ; - _fnod[2] = 2 ; + _fnod[2] = 2 ; _fnod[3] = 3 ; break ; } case 1 : { _fnod[0] = 0 ; _fnod[1] = 3 ; - _fnod[2] = 1 ; + _fnod[2] = 1 ; _fnod[3] = 2 ; break ; } case 2 : { _fnod[0] = 1 ; _fnod[1] = 3 ; - _fnod[2] = 2 ; + _fnod[2] = 2 ; _fnod[3] = 0 ; break ; } case 3 : { _fnod[0] = 2 ; _fnod[1] = 3 ; - _fnod[2] = 0 ; + _fnod[2] = 0 ; _fnod[3] = 1 ; break ; } + default: + { // suppress compiler warnings + _fnod[0] =-1 ; + _fnod[1] =-1 ; + _fnod[2] =-1 ; + _fnod[3] =-1 ; break ; + } } } __static_call @@ -295,6 +302,11 @@ _fnod[0] = 2 ; _fnod[1] = 3 ; break ; } + default: + { // suppress compiler warnings + _fnod[0] =-1 ; + _fnod[1] =-1 ; break ; + } } } __static_call @@ -308,21 +320,27 @@ case 0 : { _fnod[0] = 0 ; - _fnod[1] = 1 ; + _fnod[1] = 1 ; _fnod[2] = 2 ; break ; } case 1 : { _fnod[0] = 1 ; - _fnod[1] = 2 ; + _fnod[1] = 2 ; _fnod[2] = 0 ; break ; } case 2 : { _fnod[0] = 2 ; - _fnod[1] = 0 ; + _fnod[1] = 0 ; _fnod[2] = 1 ; break ; } + default: + { // suppress compiler warnings + _fnod[0] =-1 ; + _fnod[1] =-1 ; + _fnod[2] =-1 ; break ; + } } } @@ -336,23 +354,30 @@ { /* index FROM 3-dim faces */ if (_from == +3) - { + { /* index INTO 3-dim faces */ if (_into == +3) { - faceind33(_fnod, _fpos); + faceind33(_fnod, _fpos); return ; } /* index INTO 2-dim faces */ else if (_into == +2) { - faceind32(_fnod, _fpos); + faceind32(_fnod, _fpos); return ; } /* index INTO 1-dim faces */ else if (_into == +1) { - faceind31(_fnod, _fpos); + faceind31(_fnod, _fpos); return ; + } + else + { + _fnod[0] = -1; // suppress compiler warnings + _fnod[1] = -1; + _fnod[2] = -1; + _fnod[3] = -1; return ; } } /* index FROM 2-dim faces */ @@ -362,13 +387,19 @@ /* index INTO 2-dim faces */ if (_into == +2) { - faceind22(_fnod, _fpos); + faceind22(_fnod, _fpos); return ; } /* index INTO 1-dim faces */ else if (_into == +1) { - faceind21(_fnod, _fpos); + faceind21(_fnod, _fpos); return ; + } + else + { + _fnod[0] = -1; // suppress compiler warnings + _fnod[1] = -1; + _fnod[2] = -1; return ; } } /* index FROM 1-dim faces */ @@ -378,17 +409,26 @@ /* index INTO 1-dim faces */ if (_into == +1) { - faceind11(_fnod, _fpos); + faceind11(_fnod, _fpos); return ; + } + else + { + _fnod[0] = -1; // suppress compiler warnings + _fnod[1] = -1; return ; } } + else + { + _fnod[0] = -1; // suppress compiler warnings + } } } ; - + } - -# endif//__DELAUNAY_TRI_TYPE_3__ - - - + +# endif//__DELAUNAY_TRI_TYPE_3__ + + + diff --git a/src/libcpp/tessellate/delaunay_walk_mesh.inc b/src/libcpp/tessellate/delaunay_walk_mesh.inc index 1a3ccbd..fc5d0b6 100644 --- a/src/libcpp/tessellate/delaunay_walk_mesh.inc +++ b/src/libcpp/tessellate/delaunay_walk_mesh.inc @@ -4,29 +4,29 @@ * DELAUNAY-WALK-MESH: find node/cell via traversal. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- @@ -42,14 +42,14 @@ */ // from delaunay_tri_k.hpp - + /* -------------------------------------------------------- * WALK-TRIA-NEAR: find "nearest" tria. via traversal. -------------------------------------------------------- */ - + __normal_call bool_type walk_tria_near ( __const_ptr(real_type) _ppos, iptr_type &_elem, @@ -59,7 +59,7 @@ /*------------- walk mesh until we find nearest tria. */ bool_type _done = false; bool_type _scan = false; - iptr_type _ntri = + iptr_type _ntri = (iptr_type)this->_tset.count () ; if (this->_nset.count() == +0 || @@ -89,41 +89,41 @@ /*------------- randomised scan: locate initial _elem */ if (_scan) { - - real_type _best = + + real_type _best = +std::numeric_limits::infinity() ; - + /*--------------------- scale no. iter with dims. */ iptr_type _imax = (iptr_type) - std::pow ((double) _ntri, + std::pow ((double) _ntri, +1.0 / tria_pred::_dims) / 4 + 1 ; for (auto _iter = _imax; _iter-- != +0; ) { /*----------------------- randomise selection */ iptr_type _ipos = - (iptr_type)std::rand() + (iptr_type)std::rand() % this->_nset.count(); /*----------------------- reject "null" nodes */ if (node(_ipos)->mark() < +0) - { + { continue ; } /*----------------------- calc. dist. to node */ - real_type _dist = - tria_pred::lensqr_kd(_ppos, + real_type _dist = + tria_pred::lensqr_kd(_ppos, &node(_ipos)->pval(0)); if (_best > _dist) { /*----------------------- keep closest so far */ _best = _dist; - + _elem = node(_ipos)->next() ; } } - + } /*------------- ensure that we have a non--null _elem */ @@ -135,9 +135,9 @@ /*------------- walk elements toward _ppos from _elem */ iptr_type _next = +0 ; iptr_type _face = +0 ; - - for (auto _iter = this->_tset.count () ; - _iter-- != +0; + + for (auto _iter = this->_tset.count () ; + _iter-- != +0; _elem = _next) { /*--------------- test node-in-tria condition */ @@ -145,7 +145,7 @@ template walk_pred() ( *this, _ppos, _elem, _face) ; - + if(!_done ) { /*--------------- push next element onto walk */ @@ -164,13 +164,13 @@ return ( _done ) ; } - + /* -------------------------------------------------------- * WALK-NODE-NEAR: find "nearest" vert. via traversal. -------------------------------------------------------- */ - + __normal_call bool_type walk_node_near ( __const_ptr(real_type) _ppos, iptr_type &_node, @@ -180,7 +180,7 @@ /*------------- walk mesh until we find nearest vert. */ bool_type _done = false; iptr_type _elem ; - iptr_type _nnod = + iptr_type _nnod = (iptr_type)this->_nset.count () ; if (this->_nset.count() == +0 || @@ -211,14 +211,14 @@ /*----------------------------- nearest from cell */ real_type _dmin = +std :: numeric_limits::infinity () ; - - for (auto _inod = tria_pred::_dims + 1 ; + + for (auto _inod = tria_pred::_dims + 1 ; _inod-- != +0 ; ) { auto _next = tria(_elem) ->node(_inod) ; - auto _dsqr = + auto _dsqr = tria_pred::lensqr_kd( _ppos , &node(_next)->pval(0)) ; @@ -228,13 +228,13 @@ _node = _next; } } - + /*------------- walk elements toward _ppos from _elem */ iptr_type _next = +0 ; iptr_type _face = +0 ; - - for (auto _iter = this->_tset.count (); - _iter-- != +0 ; + + for (auto _iter = this->_tset.count (); + _iter-- != +0 ; _elem = _next) { /*--------------- test nearest-node condition */ @@ -243,7 +243,7 @@ *this, _ppos, _dmin, _node, _elem, _face) ; - + if(!_done ) { /*--------------- push next element onto walk */ @@ -260,8 +260,8 @@ else break ; } - return ( _done ) ; + return ( _done ) ; } - - - + + + diff --git a/src/libcpp/tree_mesh/tree_base_2.hpp b/src/libcpp/tree_mesh/tree_base_2.hpp new file mode 100644 index 0000000..e69de29 diff --git a/src/libcpp/tree_mesh/tree_base_3.hpp b/src/libcpp/tree_mesh/tree_base_3.hpp new file mode 100644 index 0000000..e69de29 diff --git a/src/libcpp/tree_mesh/tree_complex_2.hpp b/src/libcpp/tree_mesh/tree_complex_2.hpp new file mode 100644 index 0000000..e69de29 diff --git a/src/libcpp/tree_mesh/tree_complex_3.hpp b/src/libcpp/tree_mesh/tree_complex_3.hpp new file mode 100644 index 0000000..e69de29 diff --git a/src/libcpp/tree_mesh/tree_mesh_2.hpp b/src/libcpp/tree_mesh/tree_mesh_2.hpp new file mode 100644 index 0000000..98592ee --- /dev/null +++ b/src/libcpp/tree_mesh/tree_mesh_2.hpp @@ -0,0 +1,192 @@ + + /* + -------------------------------------------------------- + * TREE-MESH-2: tree-like bisection for 2-manifolds. + -------------------------------------------------------- + * + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) + * + * Disclaimer: Neither I nor: Columbia University, The + * Massachusetts Institute of Technology, The + * University of Sydney, nor The National Aeronautics + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be + * used at your own risk. + * + -------------------------------------------------------- + * + * Last updated: 22 November, 2019 + * + * Copyright 2013-2019 + * Darren Engwirda + * de2363@columbia.edu + * https://github.com/dengwirda/ + * + -------------------------------------------------------- + */ + + # pragma once + +# ifndef __TREE_MESH_2__ +# define __TREE_MESH_2__ + + namespace mesh { + + template < + typename M , + typename P , + typename G , + typename H , + typename I , + typename A = allocators::basic_alloc + > + class tree_mesh_2d + { + public : + + /*--------------- tree-like bisection for 2-manifolds */ + + typedef M mesh_type ; + typedef P pred_type ; + typedef G geom_type ; + typedef H hfun_type ; + typedef I init_type ; + typedef A allocator ; + + typedef typename + mesh_type::real_type real_type ; + typedef typename + mesh_type::iptr_type iptr_type ; + + typedef typename + allocator::size_type uint_type ; + + + typedef mesh::mesh_params < + real_type, + iptr_type > tree_opts ; + + typedef mesh::tree_timers < + real_type , + iptr_type > tree_stat ; + + + + + /* + -------------------------------------------------------- + * TREE-MESH: subdivide a 2-manifold mesh. + -------------------------------------------------------- + */ + + template < + typename jlog_file + > + __static_call + __normal_call void_type tree_mesh ( + geom_type &_geom , + init_type &_init , + hfun_type &_hfun , + mesh_type &_mesh , + tree_opts &_args , + jlog_file &_dump + ) + { + //!!mode_type _mode = null_mode ; + + /*------------------------------ push log-file header */ + if (_args.verb() >= 0 ) + { + _dump.push( + "#------------------------------------------------------------\n" + "# |ITER.| |CEL-1| |CEL-2| \n" + "#------------------------------------------------------------\n" + ) ; + } + + # 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 + + /*------------------------------ ensure deterministic */ + std::srand( +1 ) ; + + tree_stat _tcpu ; + + + __unreferenced(_geom) ; + __unreferenced(_init) ; + __unreferenced(_hfun) ; + __unreferenced(_mesh) ; + + + /*------------------------------ calc. hfun. at seeds */ + + /* + for (auto _node = + _mesh._tria._nset.head() ; + _node != + _mesh._tria._nset.tend() ; + ++_node ) + { + if (_node->mark() >= +0) + { + _node->idxh() = + hfun_type::null_hint () ; + } + } + */ + + + /*-------------------- MAIN: refine edges/faces/cells */ + + // push all cells onto queues + + // keep doing passes until queues empty + + // get list of unique edges/faces/etc from active sets + + // determine which edges to refine: + // actually -- farm this out to a predicate, like rdel-mesh? + // an edge is refined if it's too big (sample at midpoint + vertices) + // or if it's hausdorf error is too big, a'la rdel-mesh + + // any elements + + + } + + } ; + + + } + +# endif //__TREE_MESH_2__ + + + diff --git a/src/libcpp/tree_mesh/tree_mesh_3.hpp b/src/libcpp/tree_mesh/tree_mesh_3.hpp new file mode 100644 index 0000000..e69de29 diff --git a/src/libcpp/tree_mesh/tree_pred_2.hpp b/src/libcpp/tree_mesh/tree_pred_2.hpp new file mode 100644 index 0000000..e69de29 diff --git a/src/libcpp/tree_mesh/tree_pred_3.hpp b/src/libcpp/tree_mesh/tree_pred_3.hpp new file mode 100644 index 0000000..e69de29 diff --git a/src/libcpp/tree_mesh/tree_timers.hpp b/src/libcpp/tree_mesh/tree_timers.hpp new file mode 100644 index 0000000..dbad604 --- /dev/null +++ b/src/libcpp/tree_mesh/tree_timers.hpp @@ -0,0 +1,110 @@ + + /* + -------------------------------------------------------- + * TREE-TIMERS: CPU timers for TREE-MESH-K. + -------------------------------------------------------- + * + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) + * + * Disclaimer: Neither I nor: Columbia University, The + * Massachusetts Institute of Technology, The + * University of Sydney, nor The National Aeronautics + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be + * used at your own risk. + * + -------------------------------------------------------- + * + * Last updated: 27 November, 2019 + * + * Copyright 2013-2019 + * Darren Engwirda + * de2363@columbia.edu + * https://github.com/dengwirda/ + * + -------------------------------------------------------- + */ + +# pragma once + +# ifndef __TREE_TIMERS__ +# define __TREE_TIMERS__ + + namespace mesh { + + /* + -------------------------------------------------------- + * TREE-TIMERS: cpu timers for TREE-MESH-K + -------------------------------------------------------- + */ + + template < + typename R , + typename I + > + class tree_timers + { + public : + + typedef R real_type ; + typedef I iptr_type ; + + typedef tree_timers self_type ; + + real_type _mesh_seed = (real_type) +0. ; + real_type _node_init = (real_type) +0. ; + real_type _node_rule = (real_type) +0. ; + real_type _edge_init = (real_type) +0. ; + real_type _edge_rule = (real_type) +0. ; + real_type _face_init = (real_type) +0. ; + real_type _face_rule = (real_type) +0. ; + real_type _tria_init = (real_type) +0. ; + real_type _tria_rule = (real_type) +0. ; + + public : + + /*-------------------------------------- elapsed time */ + + # ifdef __use_timers + + __inline_call double time_span ( + typename std:: + chrono::high_resolution_clock + ::time_point const& _ttic, + typename std:: + chrono::high_resolution_clock + ::time_point const& _ttoc + ) + { + return (double)( + std::chrono::duration_cast< + std::chrono::microseconds > + (_ttoc-_ttic).count()) / +1.0E+06 ; + } + + # endif//__use_timers + + } ; + + } + +# endif // __TREE_TIMERS__ + + + diff --git a/src/libcpp/treemesh.hpp b/src/libcpp/treemesh.hpp new file mode 100644 index 0000000..e02bd24 --- /dev/null +++ b/src/libcpp/treemesh.hpp @@ -0,0 +1,76 @@ + +/* +------------------------------------------------------------ + * methods for "tree-like" mesh refinement +------------------------------------------------------------ + * + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) + * + * Disclaimer: Neither I nor: Columbia University, The + * Massachusetts Institute of Technology, The + * University of Sydney, nor The National Aeronautics + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be + * used at your own risk. + * +------------------------------------------------------------ + * + * Last updated: 25 November, 2019 + * + * Copyright 2013-2019 + * Darren Engwirda + * de2363@columbia.edu + * https://github.com/dengwirda/ + * +------------------------------------------------------------ + */ + +# pragma once + +# ifndef __TREEMESH__ +# define __TREEMESH__ + +# include "containers.hpp" +# include "algorithms.hpp" + +# include "geometry.hpp" +# include "hashfunc.hpp" + +# include "geomtype.hpp" +# include "meshfunc.hpp" +# include "meshtype.hpp" + +# include "tree_mesh/tree_complex_2.hpp" +# include "tree_mesh/tree_complex_3.hpp" + +# include "tree_mesh/tree_timers.hpp" + +# include "tree_mesh/tree_base_2.hpp" +# include "tree_mesh/tree_base_3.hpp" + +# include "tree_mesh/tree_pred_2.hpp" +# include "tree_mesh/tree_pred_3.hpp" + +# include "tree_mesh/tree_mesh_2.hpp" +# include "tree_mesh/tree_mesh_3.hpp" + +# endif//__TREEMESH__ + + + diff --git a/src/libcpp/useropts.hpp b/src/libcpp/useropts.hpp new file mode 100644 index 0000000..756ccb3 --- /dev/null +++ b/src/libcpp/useropts.hpp @@ -0,0 +1,55 @@ + +/* +------------------------------------------------------------ + * user-defined options for back-end kernels. +------------------------------------------------------------ + * + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) + * + * Disclaimer: Neither I nor: Columbia University, The + * Massachusetts Institute of Technology, The + * University of Sydney, nor The National Aeronautics + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be + * used at your own risk. + * +------------------------------------------------------------ + * + * Last updated: 27 November, 2019 + * + * Copyright 2013-2019 + * Darren Engwirda + * de2363@columbia.edu + * https://github.com/dengwirda/ + * +------------------------------------------------------------ + */ + +# pragma once + +# ifndef __PARAMETERS__ +# define __PARAMETERS__ + +# include "parameters/mesh_params.hpp" +# include "parameters/iter_params.hpp" + +# endif//__PARAMETERS__ + + + diff --git a/src/liblib/init_jig_t.hpp b/src/liblib/init_jig_t.hpp index 142d609..b94e7f7 100644 --- a/src/liblib/init_jig_t.hpp +++ b/src/liblib/init_jig_t.hpp @@ -4,34 +4,34 @@ * INIT-JIG_T: init. jig_t for lib_jigsaw. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 10 April, 2019 + * Last updated: 29 October, 2019 * * Copyright 2013-2019 * Darren Engwirda @@ -62,72 +62,74 @@ { /*------------------------------------- MISC keywords */ _jcfg->_verbosity = (indx_t) +0 ; - + /*------------------------------------- BNDS keywords */ _jcfg->_bnds_kern = JIGSAW_BNDS_TRIACELL ; - + /*------------------------------------- GEOM keywords */ _jcfg->_geom_seed = (indx_t) +8 ; - + _jcfg->_geom_feat = (indx_t) +0 ; _jcfg->_geom_eta1 = (real_t) +45.0 ; _jcfg->_geom_eta2 = (real_t) +45.0 ; - /*------------------------------------- INIT keywords */ + /*------------------------------------- INIT keywords */ _jcfg->_init_near = (real_t) +1.E-8; /*------------------------------------- HFUN keywords */ _jcfg->_hfun_scal = JIGSAW_HFUN_RELATIVE ; _jcfg->_hfun_hmax = (real_t) +0.02 ; _jcfg->_hfun_hmin = (real_t) +0.00 ; - + /*------------------------------------- MESH keywords */ _jcfg->_mesh_kern = JIGSAW_KERN_DELFRONT ; _jcfg->_mesh_dims = (indx_t) +3 ; - _jcfg->_mesh_iter = (indx_t) + _jcfg->_mesh_iter = (indx_t) std::numeric_limits::max(); - + _jcfg->_mesh_top1 = (indx_t) +0 ; _jcfg->_mesh_top2 = (indx_t) +0 ; - + _jcfg->_mesh_rad2 = (real_t) +1.05 ; _jcfg->_mesh_rad3 = (real_t) +2.05 ; _jcfg->_mesh_off2 = (real_t) +0.90 ; _jcfg->_mesh_off3 = (real_t) +1.10 ; - + real_t _SIZ1 = +1. * 4./3. ; real_t _SIZ2 = +.5 * (4./3. + 2. / (1.+std::sqrt(1./3.))) ; real_t _SIZ3 = +.5 * (4./3. + 2. / (1.+std::sqrt(3./8.))) ; - + _jcfg->_mesh_siz1 = (real_t) _SIZ1 ; _jcfg->_mesh_siz2 = (real_t) _SIZ2 ; _jcfg->_mesh_siz3 = (real_t) _SIZ3 ; - + _jcfg->_mesh_snk2 = (real_t) +0.20 ; _jcfg->_mesh_snk3 = (real_t) +0.33 ; - + _jcfg->_mesh_eps1 = (real_t) +0.33 ; _jcfg->_mesh_eps2 = (real_t) +0.33 ; - + _jcfg->_mesh_vol3 = (real_t) +0.00 ; - + /*------------------------------------- OPTM keywords */ + _jcfg->_optm_kern = JIGSAW_KERN_ODT_DQDX ; + _jcfg->_optm_iter = (indx_t) +16; - + _jcfg->_optm_qtol = (real_t) +1.E-04 ; - _jcfg->_optm_qlim = (real_t) +0.9375 ; - + _jcfg->_optm_qlim = (real_t) +0.9375 ; + _jcfg->_optm_tria = (indx_t) +1 ; - _jcfg->_optm_dual = (indx_t) +0 ; + _jcfg->_optm_dual = (indx_t) +0 ; _jcfg->_optm_div_ = (indx_t) +1 ; - _jcfg->_optm_zip_ = (indx_t) +1 ; + _jcfg->_optm_zip_ = (indx_t) +1 ; } # endif//__lib_jigsaw # endif - - - + + + diff --git a/src/liblib/init_msh_t.hpp b/src/liblib/init_msh_t.hpp index b4266d5..2024ba2 100644 --- a/src/liblib/init_msh_t.hpp +++ b/src/liblib/init_msh_t.hpp @@ -4,34 +4,34 @@ * INIT-MSH_T: init. msh_t for lib_jigsaw. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 19 June, 2019 + * Last updated: 28 June, 2019 * * Copyright 2013-2019 * Darren Engwirda @@ -53,7 +53,7 @@ */ # ifdef __lib_jigsaw - + void jigsaw_init_msh_t ( // init. msh_t jigsaw_msh_t *_mesh ) @@ -61,52 +61,55 @@ if (_mesh != nullptr) { _mesh->_flags = JIGSAW_NULL_FLAG ; - + _mesh->_vert2._size = +0 ; _mesh->_vert2._data = nullptr ; - + _mesh->_vert3._size = +0 ; _mesh->_vert3._data = nullptr ; - + _mesh->_radii._size = +0 ; _mesh->_radii._data = nullptr ; - + _mesh->_power._size = +0 ; _mesh->_power._data = nullptr ; - + _mesh->_edge2._size = +0 ; _mesh->_edge2._data = nullptr ; - + _mesh->_tria3._size = +0 ; _mesh->_tria3._data = nullptr ; - + _mesh->_quad4._size = +0 ; _mesh->_quad4._data = nullptr ; - + _mesh->_tria4._size = +0 ; _mesh->_tria4._data = nullptr ; - + _mesh->_hexa8._size = +0 ; _mesh->_hexa8._data = nullptr ; - + _mesh->_wedg6._size = +0 ; _mesh->_wedg6._data = nullptr ; - + _mesh->_pyra5._size = +0 ; _mesh->_pyra5._data = nullptr ; - + _mesh->_bound._size = +0 ; _mesh->_bound._data = nullptr ; - + _mesh->_value._size = +0 ; _mesh->_value._data = nullptr ; - + + _mesh->_slope._size = +0 ; + _mesh->_slope._data = nullptr ; + _mesh->_xgrid._size = +0 ; _mesh->_xgrid._data = nullptr ; - + _mesh->_ygrid._size = +0 ; _mesh->_ygrid._data = nullptr ; - + _mesh->_zgrid._size = +0 ; _mesh->_zgrid._data = nullptr ; } @@ -120,9 +123,9 @@ * FREE-MSH_T: _free msh_t for lib_jigsaw. -------------------------------------------------------- */ - + # ifdef __lib_jigsaw - + void jigsaw_free_msh_t ( // free-alloc jigsaw_msh_t *_mesh ) @@ -131,25 +134,25 @@ if (_mesh != nullptr) { _mesh->_flags = JIGSAW_NULL_FLAG ; - + jigsaw_free_vert2( &_mesh->_vert2) ; jigsaw_free_vert3( &_mesh->_vert3) ; jigsaw_free_reals( &_mesh->_power) ; - + jigsaw_free_reals( &_mesh->_radii) ; - + jigsaw_free_edge2( &_mesh->_edge2) ; - + jigsaw_free_tria3( &_mesh->_tria3) ; jigsaw_free_quad4( &_mesh->_quad4) ; - + jigsaw_free_tria4( &_mesh->_tria4) ; jigsaw_free_hexa8( @@ -158,22 +161,24 @@ &_mesh->_wedg6) ; jigsaw_free_pyra5( &_mesh->_pyra5) ; - + jigsaw_free_bound( &_mesh->_bound) ; - + jigsaw_free_reals( &_mesh->_xgrid) ; jigsaw_free_reals( &_mesh->_ygrid) ; jigsaw_free_reals( &_mesh->_zgrid) ; - + jigsaw_free_reals( &_mesh->_value) ; - } + jigsaw_free_reals( + &_mesh->_slope) ; + } } - + # endif//__lib_jigsaw /* @@ -183,43 +188,43 @@ */ # ifdef __lib_jigsaw - + void jigsaw_alloc_vert2 ( // _new-alloc jigsaw_VERT2_array_t *_vert2 , size_t _size ) { - _vert2->_size = _size ; - _vert2->_data =(jigsaw_VERT2_t*) + _vert2->_size = _size ; + _vert2->_data =(jigsaw_VERT2_t*) std::malloc( _size * sizeof (jigsaw_VERT2_t)) ; - - for (size_t _item = (size_t) +0 ; - _item != _size ; + + for (size_t _item = (size_t) +0 ; + _item != _size ; ++_item ) { _vert2->_data[_item]. _ppos[ 0 ] = (real_t) +0.; _vert2->_data[_item]. _ppos[ 1 ] = (real_t) +0.; - + _vert2->_data[_item]. _itag = (indx_t) +0 ; - } + } } - + void jigsaw_alloc_vert3 ( // _new-alloc jigsaw_VERT3_array_t *_vert3 , size_t _size ) { - _vert3->_size = _size ; - _vert3->_data =(jigsaw_VERT3_t*) + _vert3->_size = _size ; + _vert3->_data =(jigsaw_VERT3_t*) std::malloc( _size * sizeof (jigsaw_VERT3_t)) ; - - for (size_t _item = (size_t) +0 ; - _item != _size ; + + for (size_t _item = (size_t) +0 ; + _item != _size ; ++_item ) { _vert3->_data[_item]. @@ -228,48 +233,48 @@ _ppos[ 1 ] = (real_t) +0.; _vert3->_data[_item]. _ppos[ 2 ] = (real_t) +0.; - + _vert3->_data[_item]. _itag = (indx_t) +0 ; - } + } } - + void jigsaw_alloc_edge2 ( // _new-alloc jigsaw_EDGE2_array_t *_edge2 , size_t _size ) { - _edge2->_size = _size ; - _edge2->_data =(jigsaw_EDGE2_t*) + _edge2->_size = _size ; + _edge2->_data =(jigsaw_EDGE2_t*) std::malloc( - _size * sizeof (jigsaw_EDGE2_t)) ; - - for (size_t _item = (size_t) +0 ; - _item != _size ; + _size * sizeof (jigsaw_EDGE2_t)) ; + + for (size_t _item = (size_t) +0 ; + _item != _size ; ++_item ) { _edge2->_data[_item]. _node[ 0 ] = (indx_t) +0 ; _edge2->_data[_item]. _node[ 1 ] = (indx_t) +0 ; - + _edge2->_data[_item]. _itag = (indx_t) +0 ; } } - + void jigsaw_alloc_tria3 ( // _new-alloc jigsaw_TRIA3_array_t *_tria3 , size_t _size ) { - _tria3->_size = _size ; - _tria3->_data =(jigsaw_TRIA3_t*) + _tria3->_size = _size ; + _tria3->_data =(jigsaw_TRIA3_t*) std::malloc( _size * sizeof (jigsaw_TRIA3_t)) ; - - for (size_t _item = (size_t) +0 ; - _item != _size ; + + for (size_t _item = (size_t) +0 ; + _item != _size ; ++_item ) { _tria3->_data[_item]. @@ -278,24 +283,24 @@ _node[ 1 ] = (indx_t) +0 ; _tria3->_data[_item]. _node[ 2 ] = (indx_t) +0 ; - + _tria3->_data[_item]. _itag = (indx_t) +0 ; - } + } } - + void jigsaw_alloc_quad4 ( // _new-alloc jigsaw_QUAD4_array_t *_quad4 , size_t _size ) { - _quad4->_size = _size ; - _quad4->_data =(jigsaw_QUAD4_t*) + _quad4->_size = _size ; + _quad4->_data =(jigsaw_QUAD4_t*) std::malloc( _size * sizeof (jigsaw_QUAD4_t)) ; - - for (size_t _item = (size_t) +0 ; - _item != _size ; + + for (size_t _item = (size_t) +0 ; + _item != _size ; ++_item ) { _quad4->_data[_item]. @@ -306,24 +311,24 @@ _node[ 2 ] = (indx_t) +0 ; _quad4->_data[_item]. _node[ 3 ] = (indx_t) +0 ; - + _quad4->_data[_item]. _itag = (indx_t) +0 ; - } + } } - + void jigsaw_alloc_tria4 ( // _new-alloc jigsaw_TRIA4_array_t *_tria4 , size_t _size ) { - _tria4->_size = _size ; - _tria4->_data =(jigsaw_TRIA4_t*) + _tria4->_size = _size ; + _tria4->_data =(jigsaw_TRIA4_t*) std::malloc( _size * sizeof (jigsaw_TRIA4_t)) ; - - for (size_t _item = (size_t) +0 ; - _item != _size ; + + for (size_t _item = (size_t) +0 ; + _item != _size ; ++_item ) { _tria4->_data[_item]. @@ -334,24 +339,24 @@ _node[ 2 ] = (indx_t) +0 ; _tria4->_data[_item]. _node[ 3 ] = (indx_t) +0 ; - + _tria4->_data[_item]. _itag = (indx_t) +0 ; } } - + void jigsaw_alloc_hexa8 ( // _new-alloc jigsaw_HEXA8_array_t *_hexa8 , size_t _size ) { - _hexa8->_size = _size ; - _hexa8->_data =(jigsaw_HEXA8_t*) + _hexa8->_size = _size ; + _hexa8->_data =(jigsaw_HEXA8_t*) std::malloc( _size * sizeof (jigsaw_HEXA8_t)) ; - - for (size_t _item = (size_t) +0 ; - _item != _size ; + + for (size_t _item = (size_t) +0 ; + _item != _size ; ++_item ) { _hexa8->_data[_item]. @@ -370,24 +375,24 @@ _node[ 6 ] = (indx_t) +0 ; _hexa8->_data[_item]. _node[ 7 ] = (indx_t) +0 ; - + _hexa8->_data[_item]. _itag = (indx_t) +0 ; } } - + void jigsaw_alloc_wedg6 ( // _new-alloc jigsaw_WEDG6_array_t *_wedg6 , size_t _size ) { - _wedg6->_size = _size ; - _wedg6->_data =(jigsaw_WEDG6_t*) + _wedg6->_size = _size ; + _wedg6->_data =(jigsaw_WEDG6_t*) std::malloc( _size * sizeof (jigsaw_WEDG6_t)) ; - - for (size_t _item = (size_t) +0 ; - _item != _size ; + + for (size_t _item = (size_t) +0 ; + _item != _size ; ++_item ) { _wedg6->_data[_item]. @@ -402,24 +407,24 @@ _node[ 4 ] = (indx_t) +0 ; _wedg6->_data[_item]. _node[ 5 ] = (indx_t) +0 ; - + _wedg6->_data[_item]. _itag = (indx_t) +0 ; } } - + void jigsaw_alloc_pyra5 ( // _new-alloc jigsaw_PYRA5_array_t *_pyra5 , size_t _size ) { - _pyra5->_size = _size ; - _pyra5->_data =(jigsaw_PYRA5_t*) + _pyra5->_size = _size ; + _pyra5->_data =(jigsaw_PYRA5_t*) std::malloc( _size * sizeof (jigsaw_PYRA5_t)) ; - - for (size_t _item = (size_t) +0 ; - _item != _size ; + + for (size_t _item = (size_t) +0 ; + _item != _size ; ++_item ) { _pyra5->_data[_item]. @@ -432,24 +437,24 @@ _node[ 3 ] = (indx_t) +0 ; _pyra5->_data[_item]. _node[ 4 ] = (indx_t) +0 ; - + _pyra5->_data[_item]. _itag = (indx_t) +0 ; } } - + void jigsaw_alloc_bound ( // _new-alloc jigsaw_BOUND_array_t *_bound , size_t _size ) { - _bound->_size = _size ; - _bound->_data =(jigsaw_BOUND_t*) + _bound->_size = _size ; + _bound->_data =(jigsaw_BOUND_t*) std::malloc( _size * sizeof (jigsaw_BOUND_t)) ; - - for (size_t _item = (size_t) +0 ; - _item != _size ; + + for (size_t _item = (size_t) +0 ; + _item != _size ; ++_item ) { _bound->_data[_item]. @@ -466,13 +471,13 @@ size_t _size ) { - _index->_size = _size ; - _index->_data = (indx_t *) + _index->_size = _size ; + _index->_data = (indx_t *) std::malloc ( _size * sizeof (indx_t)) ; - - for (size_t _item = (size_t) +0 ; - _item != _size ; + + for (size_t _item = (size_t) +0 ; + _item != _size ; ++_item ) { _index-> @@ -485,30 +490,30 @@ size_t _size ) { - _reals->_size = _size ; - _reals->_data = (real_t *) + _reals->_size = _size ; + _reals->_data = (real_t *) std::malloc ( _size * sizeof (real_t)) ; - - for (size_t _item = (size_t) +0 ; - _item != _size ; + + for (size_t _item = (size_t) +0 ; + _item != _size ; ++_item ) { _reals-> _data[_item] = (real_t) +0.; } } - -# endif//__lib_jigsaw - + +# endif//__lib_jigsaw + /* -------------------------------------------------------- * FREE-MSH_T: _free msh_t for lib_jigsaw. -------------------------------------------------------- */ - + # ifdef __lib_jigsaw - + void jigsaw_free_vert2 ( // free-alloc jigsaw_VERT2_array_t *_vert2 ) @@ -520,7 +525,7 @@ std::free(_vert2->_data) ; } } - + void jigsaw_free_vert3 ( // free-alloc jigsaw_VERT3_array_t *_vert3 ) @@ -532,7 +537,7 @@ std::free(_vert3->_data) ; } } - + void jigsaw_free_edge2 ( // free-alloc jigsaw_EDGE2_array_t *_edge2 ) @@ -544,7 +549,7 @@ std::free(_edge2->_data) ; } } - + void jigsaw_free_tria3 ( // free-alloc jigsaw_TRIA3_array_t *_tria3 ) @@ -556,7 +561,7 @@ std::free(_tria3->_data) ; } } - + void jigsaw_free_quad4 ( // free-alloc jigsaw_QUAD4_array_t *_quad4 ) @@ -568,7 +573,7 @@ std::free(_quad4->_data) ; } } - + void jigsaw_free_tria4 ( // free-alloc jigsaw_TRIA4_array_t *_tria4 ) @@ -580,7 +585,7 @@ std::free(_tria4->_data) ; } } - + void jigsaw_free_hexa8 ( // free-alloc jigsaw_HEXA8_array_t *_hexa8 ) @@ -592,7 +597,7 @@ std::free(_hexa8->_data) ; } } - + void jigsaw_free_wedg6 ( // free-alloc jigsaw_WEDG6_array_t *_wedg6 ) @@ -604,7 +609,7 @@ std::free(_wedg6->_data) ; } } - + void jigsaw_free_pyra5 ( // free-alloc jigsaw_PYRA5_array_t *_pyra5 ) @@ -616,7 +621,7 @@ std::free(_pyra5->_data) ; } } - + void jigsaw_free_bound ( // free-alloc jigsaw_BOUND_array_t *_bound ) @@ -628,7 +633,7 @@ std::free(_bound->_data) ; } } - + void jigsaw_free_index ( // free-alloc jigsaw_INDEX_array_t *_index ) @@ -640,7 +645,7 @@ std::free(_index->_data) ; } } - + void jigsaw_free_reals ( // free-alloc jigsaw_REALS_array_t *_reals ) @@ -652,9 +657,9 @@ std::free(_reals->_data) ; } } - + # endif//__lib_jigsaw - + # endif diff --git a/src/liblib/load_jig_t.hpp b/src/liblib/load_jig_t.hpp index 07731f5..e5d7f2f 100644 --- a/src/liblib/load_jig_t.hpp +++ b/src/liblib/load_jig_t.hpp @@ -4,34 +4,34 @@ * LOAD-JIG_T: load jig_t for lib_jigsaw. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 10 April, 2019 + * Last updated: 29 October, 2019 * * Copyright 2013-2019 * Darren Engwirda @@ -61,288 +61,296 @@ jigsaw_jig_t *_jcfg ) { - class jcfg_loader: + class jcfg_loader: public jcfg_reader_base { public : jigsaw_jig_t *_jjig; - + public : /*------------------------------------- create loader */ __normal_call jcfg_loader ( jigsaw_jig_t *_jsrc = nullptr ) : _jjig( _jsrc ) {} - + /*------------------------------------- MISC keywords */ __normal_call void_type push_verbosity ( std::int32_t _verb - ) - { + ) + { this-> - _jjig->_verbosity = _verb; - } - - /*------------------------------------- GEOM keywords */ + _jjig->_verbosity = _verb; + } + + /*------------------------------------- GEOM keywords */ __normal_call void_type push_geom_seed ( std::int32_t _seed - ) + ) { this-> - _jjig->_geom_seed = _seed; + _jjig->_geom_seed = _seed; } __normal_call void_type push_geom_feat ( bool _feat - ) + ) { this-> - _jjig->_geom_feat = _feat; + _jjig->_geom_feat = _feat; } __normal_call void_type push_geom_eta1 ( double _eta1 - ) + ) { this-> - _jjig->_geom_eta1 = _eta1; + _jjig->_geom_eta1 = _eta1; } __normal_call void_type push_geom_eta2 ( double _eta2 - ) + ) { this-> - _jjig->_geom_eta2 = _eta2; + _jjig->_geom_eta2 = _eta2; } /*------------------------------------- INIT keywords */ __normal_call void_type push_init_near ( double _near - ) + ) { this-> - _jjig->_init_near = _near; + _jjig->_init_near = _near; } - + /*------------------------------------- HFUN keywords */ __normal_call void_type push_hfun_scal ( std::int32_t _scal - ) + ) { this-> - _jjig->_hfun_scal = _scal; + _jjig->_hfun_scal = _scal; } __normal_call void_type push_hfun_hmax ( double _hmax - ) + ) { this-> - _jjig->_hfun_hmax = _hmax; + _jjig->_hfun_hmax = _hmax; } __normal_call void_type push_hfun_hmin ( double _hmin - ) + ) { this-> - _jjig->_hfun_hmin = _hmin; + _jjig->_hfun_hmin = _hmin; } - - /*------------------------------------- KERN keywords */ + + /*------------------------------------- BNDS keywords */ __normal_call void_type push_bnds_kern ( std::int32_t _kern - ) - { + ) + { this-> _jjig->_bnds_kern = _kern; } - + + /*------------------------------------- MESH keywords */ __normal_call void_type push_mesh_kern ( std::int32_t _kern - ) + ) { this-> _jjig->_mesh_kern = _kern; } - - /*------------------------------------- MESH keywords */ + __normal_call void_type push_mesh_dims ( std::int32_t _dims - ) - { + ) + { this-> _jjig->_mesh_dims = _dims; } __normal_call void_type push_mesh_iter ( std::int32_t _iter - ) - { + ) + { this-> _jjig->_mesh_iter = _iter; } __normal_call void_type push_mesh_siz1 ( double _siz1 - ) - { + ) + { this-> _jjig->_mesh_siz1 = _siz1; } __normal_call void_type push_mesh_siz2 ( double _siz2 - ) - { + ) + { this-> _jjig->_mesh_siz2 = _siz2; } __normal_call void_type push_mesh_siz3 ( double _siz3 - ) + ) { this-> - _jjig->_mesh_siz3 = _siz3; - } + _jjig->_mesh_siz3 = _siz3; + } __normal_call void_type push_mesh_top1 ( bool _top1 - ) - { + ) + { this-> _jjig->_mesh_top1 = _top1; } __normal_call void_type push_mesh_top2 ( bool _top2 - ) + ) { this-> - _jjig->_mesh_top2 = _top2; + _jjig->_mesh_top2 = _top2; } __normal_call void_type push_mesh_rad2 ( double _rad2 - ) + ) { this-> - _jjig->_mesh_rad2 = _rad2; + _jjig->_mesh_rad2 = _rad2; } __normal_call void_type push_mesh_rad3 ( double _rad3 - ) + ) { this-> - _jjig->_mesh_rad3 = _rad3; + _jjig->_mesh_rad3 = _rad3; } __normal_call void_type push_mesh_off2 ( double _off2 - ) - { + ) + { this-> _jjig->_mesh_off2 = _off2; } __normal_call void_type push_mesh_off3 ( double _off3 - ) + ) { this-> - _jjig->_mesh_off3 = _off3; + _jjig->_mesh_off3 = _off3; } __normal_call void_type push_mesh_snk2 ( double _snk2 - ) + ) { this-> - _jjig->_mesh_snk2 = _snk2; + _jjig->_mesh_snk2 = _snk2; } __normal_call void_type push_mesh_snk3 ( double _snk3 - ) + ) { this-> - _jjig->_mesh_snk3 = _snk3; + _jjig->_mesh_snk3 = _snk3; } __normal_call void_type push_mesh_eps1 ( double _eps1 - ) + ) { this-> - _jjig->_mesh_eps1 = _eps1; + _jjig->_mesh_eps1 = _eps1; } __normal_call void_type push_mesh_eps2 ( double _eps2 - ) + ) { this-> - _jjig->_mesh_eps2 = _eps2; + _jjig->_mesh_eps2 = _eps2; } __normal_call void_type push_mesh_vol3 ( double _vol3 - ) + ) { this-> - _jjig->_mesh_vol3 = _vol3; + _jjig->_mesh_vol3 = _vol3; } - + /*------------------------------------- OPTM keywords */ + __normal_call void_type push_optm_kern ( + std::int32_t _kern + ) + { + this-> + _jjig->_optm_kern = _kern; + } + __normal_call void_type push_optm_iter ( std::int32_t _iter - ) + ) { this-> - _jjig->_optm_iter = _iter; + _jjig->_optm_iter = _iter; } __normal_call void_type push_optm_qtol ( double _qtol - ) + ) { this-> - _jjig->_optm_qtol = _qtol; + _jjig->_optm_qtol = _qtol; } __normal_call void_type push_optm_qlim ( double _qlim - ) + ) { this-> - _jjig->_optm_qlim = _qlim; + _jjig->_optm_qlim = _qlim; } __normal_call void_type push_optm_tria ( bool _flag - ) + ) { this-> - _jjig->_optm_tria = _flag; + _jjig->_optm_tria = _flag; } __normal_call void_type push_optm_dual ( bool _flag - ) + ) { this-> - _jjig->_optm_dual = _flag; + _jjig->_optm_dual = _flag; } __normal_call void_type push_optm_div_ ( bool _flag - ) + ) { this-> - _jjig->_optm_div_ = _flag; + _jjig->_optm_div_ = _flag; } __normal_call void_type push_optm_zip_ ( bool _flag - ) + ) { this-> - _jjig->_optm_zip_ = _flag; + _jjig->_optm_zip_ = _flag; } - + } ; - + /*---------------------------------- parse JIG_T file */ iptr_type _errv = __no_error ; - + try { jcfg_reader _read ; std::ifstream _file ; - + std::string _fstr(_fchr) ; std::string _path ; std::string _name ; std::string _fext ; - file_part(_fstr, + file_part(_fstr, _path, _name, _fext) ; - + _file.open( _fstr, std::ifstream:: in) ; @@ -352,10 +360,10 @@ _file, jcfg_loader(_jcfg)) ; } else - { + { _errv = __file_not_located ; } - + _file.close (); if(!_read._errs.empty()) @@ -370,7 +378,7 @@ /*---------------------------------- return read flag */ return _errv ; - + } # endif//__lib_jigsaw diff --git a/src/liblib/load_msh_t.hpp b/src/liblib/load_msh_t.hpp index 77c8b4f..31db039 100644 --- a/src/liblib/load_msh_t.hpp +++ b/src/liblib/load_msh_t.hpp @@ -4,34 +4,34 @@ * LOAD-MSH_T: load msh_t for lib_jigsaw. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 19 June, 2019 + * Last updated: 1 October, 2019 * * Copyright 2013-2019 * Darren Engwirda @@ -61,87 +61,87 @@ jigsaw_msh_t *_jmsh ) { - class msht_reader: + class msht_reader: public jmsh_reader_base { public : jigsaw_msh_t *_jmsh ; - + std::int32_t _errv ; - + std::int32_t _ftag ; jmsh_kind:: enum_data _kind ; std:: size_t _ndim ; std:: size_t _nval ; - + public : __normal_call msht_reader ( jigsaw_msh_t *_jsrc = nullptr - ) : _jmsh(_jsrc) , - _errv( +0 ) {} + ) : _jmsh(_jsrc) , + _errv( +0 ) {} /*-------------------------------- read MSHID section */ __normal_call void_type push_mshid ( - std::int32_t _ftag , - jmsh_kind::enum_data _kind + std::int32_t _FTAG , + jmsh_kind::enum_data _KIND ) - { - this->_ftag = _ftag ; - this->_kind = _kind ; - + { + this->_ftag = _FTAG ; + this->_kind = _KIND ; + this->_jmsh->_flags = JIGSAW_NULL_FLAG; - - if (_kind == + + if (_KIND == jmsh_kind::euclidean_mesh) - this->_jmsh->_flags = + this->_jmsh->_flags = JIGSAW_EUCLIDEAN_MESH ; else - if (_kind == + if (_KIND == jmsh_kind::euclidean_grid) - this->_jmsh->_flags = + this->_jmsh->_flags = JIGSAW_EUCLIDEAN_GRID ; else - if (_kind == + if (_KIND == jmsh_kind::ellipsoid_mesh) - this->_jmsh->_flags = + this->_jmsh->_flags = JIGSAW_ELLIPSOID_MESH ; else - if (_kind == + if (_KIND == jmsh_kind::ellipsoid_grid) - this->_jmsh->_flags = + this->_jmsh->_flags = JIGSAW_ELLIPSOID_GRID ; } /*-------------------------------- read NDIMS section */ __normal_call void_type push_ndims ( - std:: size_t _ndim + std:: size_t _NDIM ) - { - this->_ndim = _ndim ; + { + this->_ndim = _NDIM ; } /*-------------------------------- read RADII section */ __normal_call void_type push_radii ( double *_erad - ) - { + ) + { jigsaw_alloc_reals ( &this->_jmsh->_radii, +3 ) ; - + this->_jmsh-> _radii._data[0] = _erad[0] ; this->_jmsh-> _radii._data[1] = _erad[1] ; this->_jmsh-> _radii._data[2] = _erad[2] ; - } + } /*-------------------------------- open POINT section */ __normal_call void_type open_point ( std:: size_t _nrow - ) - { - if (this->_kind == + ) + { + if (this->_kind == jmsh_kind:: euclidean_mesh) { - + if (this->_ndim == +2) jigsaw_alloc_vert2 ( &this->_jmsh->_vert2, _nrow) ; @@ -149,16 +149,16 @@ if (this->_ndim == +3) jigsaw_alloc_vert3 ( &this->_jmsh->_vert3, _nrow) ; - + jigsaw_alloc_reals ( &this->_jmsh->_power, _nrow) ; - + } else - if (this->_kind == + if (this->_kind == jmsh_kind:: ellipsoid_mesh) { - + if (this->_ndim == +2) jigsaw_alloc_vert2 ( &this->_jmsh->_vert2, _nrow) ; @@ -166,10 +166,10 @@ if (this->_ndim == +3) jigsaw_alloc_vert3 ( &this->_jmsh->_vert3, _nrow) ; - + jigsaw_alloc_reals ( &this->_jmsh->_power, _nrow) ; - + } } /*-------------------------------- read POINT section */ @@ -181,31 +181,31 @@ { if (this->_ndim == +2 ) { - + if (_ipos < this->_jmsh->_vert2._size) { this->_jmsh->_vert2._data[_ipos]. _ppos[0] = _pval[0] ; this->_jmsh->_vert2._data[_ipos]. _ppos[1] = _pval[1] ; - + this->_jmsh->_vert2. _data[_ipos]._itag = _itag ; - + this->_jmsh-> _power._data[_ipos] = +0.00 ; } else { this->_errv =__invalid_argument ; - } - - } + } + + } else if (this->_ndim == +3 ) { - - if (_ipos < this->_jmsh->_vert2._size) + + if (_ipos < this->_jmsh->_vert3._size)// fix #28 { this->_jmsh->_vert3._data[_ipos]. _ppos[0] = _pval[0] ; @@ -213,10 +213,10 @@ _ppos[1] = _pval[1] ; this->_jmsh->_vert3._data[_ipos]. _ppos[2] = _pval[2] ; - + this->_jmsh->_vert3. _data[_ipos]._itag = _itag ; - + this->_jmsh-> _power._data[_ipos] = +0.00 ; } @@ -224,18 +224,18 @@ { this->_errv =__invalid_argument ; } - + } - } + } /*-------------------------------- read POWER section */ __normal_call void_type push_power ( std:: size_t _ipos, double * _xpwr - ) - { + ) + { if (this->_ndim == +2 ) { - + if (_ipos < this->_jmsh->_vert2._size) { this->_jmsh->_power. @@ -244,13 +244,13 @@ else { this->_errv =__invalid_argument ; - } - - } + } + + } else if (this->_ndim == +3 ) { - + if (_ipos < this->_jmsh->_vert3._size) { this->_jmsh->_power. @@ -260,15 +260,15 @@ { this->_errv =__invalid_argument ; } - + } - } + } /*-------------------------------- open COORD section */ __normal_call void_type open_coord ( std:: size_t _idim, std:: size_t _nrow ) - { + { if (_idim == +1) jigsaw_alloc_reals ( &this->_jmsh->_xgrid, _nrow) ; @@ -279,7 +279,7 @@ else if (_idim == +3) jigsaw_alloc_reals ( - &this->_jmsh->_zgrid, _nrow) ; + &this->_jmsh->_zgrid, _nrow) ; } /*-------------------------------- read COORD section */ __normal_call void_type push_coord ( @@ -290,7 +290,7 @@ { if (_idim == +1) { - + if (_ipos < this->_jmsh->_xgrid._size) { this->_jmsh->_xgrid. @@ -300,12 +300,12 @@ { this->_errv = __invalid_argument ; } - + } else if (_idim == +2) { - + if (_ipos < this->_jmsh->_ygrid._size) { this->_jmsh->_ygrid. @@ -315,12 +315,12 @@ { this->_errv = __invalid_argument ; } - + } else if (_idim == +3) { - + if (_ipos < this->_jmsh->_zgrid._size) { this->_jmsh->_zgrid. @@ -330,13 +330,13 @@ { this->_errv = __invalid_argument ; } - - } + + } } /*-------------------------------- open EDGE2 section */ __normal_call void_type open_edge2 ( std:: size_t _nrow - ) + ) { jigsaw_alloc_edge2 ( &this->_jmsh->_edge2, _nrow) ; @@ -346,15 +346,15 @@ std:: size_t _ipos, std::int32_t* _node, std::int32_t _itag - ) - { + ) + { if (_ipos < this->_jmsh->_edge2._size) { this->_jmsh->_edge2._data[_ipos]. _node[0] = _node[0] ; this->_jmsh->_edge2._data[_ipos]. _node[1] = _node[1] ; - + this->_jmsh->_edge2. _data[_ipos]._itag = _itag ; } @@ -366,7 +366,7 @@ /*-------------------------------- open TRIA3 section */ __normal_call void_type open_tria3 ( std:: size_t _nrow - ) + ) { jigsaw_alloc_tria3 ( &this->_jmsh->_tria3, _nrow) ; @@ -376,8 +376,8 @@ std:: size_t _ipos, std::int32_t* _node, std::int32_t _itag - ) - { + ) + { if (_ipos < this->_jmsh->_tria3._size) { this->_jmsh->_tria3._data[_ipos]. @@ -386,7 +386,7 @@ _node[1] = _node[1] ; this->_jmsh->_tria3._data[_ipos]. _node[2] = _node[2] ; - + this->_jmsh->_tria3. _data[_ipos]._itag = _itag ; } @@ -398,7 +398,7 @@ /*-------------------------------- open TRIA4 section */ __normal_call void_type open_tria4 ( std:: size_t _nrow - ) + ) { jigsaw_alloc_tria4 ( &this->_jmsh->_tria4, _nrow) ; @@ -408,8 +408,8 @@ std:: size_t _ipos, std::int32_t* _node, std::int32_t _itag - ) - { + ) + { if (_ipos < this->_jmsh->_tria4._size) { this->_jmsh->_tria4._data[_ipos]. @@ -420,7 +420,7 @@ _node[2] = _node[2] ; this->_jmsh->_tria4._data[_ipos]. _node[3] = _node[3] ; - + this->_jmsh->_tria4. _data[_ipos]._itag = _itag ; } @@ -429,21 +429,21 @@ this->_errv =__invalid_argument ; } } - + /*-------------------------------- open BOUND section */ __normal_call void_type open_bound ( std:: size_t _nrow - ) + ) { jigsaw_alloc_bound ( &this->_jmsh->_bound, _nrow) ; - } + } /*-------------------------------- push BOUND section */ __normal_call void_type push_bound ( std:: size_t _ipos, std::int32_t _itag, std::int32_t _inum, - std::int32_t _kind + std::int32_t _KIND ) { if (_ipos < this->_jmsh->_bound._size) @@ -453,67 +453,102 @@ this->_jmsh->_bound. _data[_ipos]._indx = _inum ; this->_jmsh->_bound. - _data[_ipos]._kind = _kind ; - + _data[_ipos]._kind = _KIND ; + } else { this->_errv =__invalid_argument ; } } - + /*-------------------------------- open VALUE section */ __normal_call void_type open_value ( std:: size_t _nrow, - std:: size_t _nval - ) - { - this->_nval = _nval; + std:: size_t _NVAL + ) + { + this->_nval = _NVAL; jigsaw_alloc_reals ( &this-> - _jmsh->_value , _nrow * _nval ) ; + _jmsh->_value , _nrow * _NVAL ) ; } /*-------------------------------- push VALUE section */ __normal_call void_type push_value ( std:: size_t _ipos, double * _vdat - ) - { + ) + { if (_ipos < this->_jmsh->_value._size) { - - for (auto _ival = +0u ; + + for (auto _ival = +0u ; _ival< this->_nval; ++_ival) { this->_jmsh->_value. _data[_ipos*(_ival+1)] = _vdat[_ival]; } - + } else { this->_errv = __invalid_argument; } } - + + /*-------------------------------- open SLOPE section */ + __normal_call void_type open_slope ( + std:: size_t _nrow, + std:: size_t _NVAL + ) + { + this->_nval = _NVAL; + + jigsaw_alloc_reals ( + &this-> + _jmsh->_slope , _nrow * _NVAL ) ; + } + /*-------------------------------- push SLOPE section */ + __normal_call void_type push_slope ( + std:: size_t _ipos, + double * _vdat + ) + { + if (_ipos < this->_jmsh->_slope._size) + { + + for (auto _ival = +0u ; + _ival< this->_nval; ++_ival) + { + this->_jmsh->_slope. + _data[_ipos*(_ival+1)] = _vdat[_ival]; + } + + } + else + { + this->_errv = __invalid_argument; + } + } + } ; - + /*---------------------------------- parse MSH_T file */ iptr_type _errv = __no_error ; - + try { jmsh_reader _read ; std::ifstream _file ; - + std::string _fstr(_fchr) ; std::string _path ; std::string _name ; std::string _fext ; - file_part(_fstr, + file_part(_fstr, _path, _name, _fext) ; - + _file.open( _fstr, std::ifstream:: in) ; @@ -523,10 +558,10 @@ _file, msht_reader(_jmsh)) ; } else - { + { _errv = __file_not_located ; } - + _file.close (); if(!_read._errs.empty()) diff --git a/src/liblib/save_jig_t.hpp b/src/liblib/save_jig_t.hpp index e09fa94..e9ac9f3 100644 --- a/src/liblib/save_jig_t.hpp +++ b/src/liblib/save_jig_t.hpp @@ -4,34 +4,34 @@ * SAVE-JIG_T: save jig_t for lib_jigsaw. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 10 April, 2019 + * Last updated: 29 October, 2019 * * Copyright 2013-2019 * Darren Engwirda @@ -60,7 +60,7 @@ ) { iptr_type _errv = __no_error ; - + try { std::ofstream _file ; @@ -68,147 +68,158 @@ std::string _fstr(_fchr) ; std::string _path ; std::string _name ; - std::string _fext ; + std::string _fext ; file_part( _fstr, _path, _name, _fext) ; _file.open( _fstr, std::ofstream::out ) ; - + if (_file.is_open()) { _file << "# " << _name << ".jig" << "; created by " ; _file << __JGSWVSTR "\n" ; - + /*--------------------------------- MISC keywords */ - _file << "VERBOSITY = " << + _file << "VERBOSITY = " << _jcfg->_verbosity << "\n" ; - + /*--------------------------------- GEOM keywords */ - _file << "GEOM_SEED = " << + _file << "GEOM_SEED = " << _jcfg->_geom_seed << "\n" ; - - _file << "GEOM_FEAT = " << + + _file << "GEOM_FEAT = " << _jcfg->_geom_feat << "\n" ; - - _file << "GEOM_ETA1 = " << + + _file << "GEOM_ETA1 = " << _jcfg->_geom_eta1 << "\n" ; - _file << "GEOM_ETA2 = " << + _file << "GEOM_ETA2 = " << _jcfg->_geom_eta2 << "\n" ; - _file << "INIT_NEAR = " << + _file << "INIT_NEAR = " << _jcfg->_init_near << "\n" ; - + /*--------------------------------- HFUN keywords */ - if (_jcfg->_hfun_scal == + if (_jcfg->_hfun_scal == JIGSAW_HFUN_RELATIVE) - _file << "HFUN_SCAL = " + _file << "HFUN_SCAL = " << "RELATIVE\n" ; else - if (_jcfg->_hfun_scal == + if (_jcfg->_hfun_scal == JIGSAW_HFUN_ABSOLUTE) - _file << "HFUN_SCAL = " + _file << "HFUN_SCAL = " << "ABSOLUTE\n" ; - - _file << "HFUN_HMIN = " << + + _file << "HFUN_HMIN = " << _jcfg->_hfun_hmax << "\n" ; - _file << "HFUN_HMAX = " << + _file << "HFUN_HMAX = " << _jcfg->_hfun_hmin << "\n" ; - + /*--------------------------------- BNDS keywords */ - if (_jcfg->_bnds_kern == + if (_jcfg->_bnds_kern == JIGSAW_BNDS_TRIACELL) - _file << "BNDS_KERN = " + _file << "BNDS_KERN = " << "BND-TRIA\n" ; else - if (_jcfg->_bnds_kern == + if (_jcfg->_bnds_kern == JIGSAW_BNDS_DUALCELL) - _file << "BNDS_KERN = " + _file << "BNDS_KERN = " << "BND-DUAL\n" ; - + /*--------------------------------- MESH keywords */ - if (_jcfg->_mesh_kern == + if (_jcfg->_mesh_kern == JIGSAW_KERN_DELFRONT) - _file << "MESH_KERN = " + _file << "MESH_KERN = " << "DELFRONT\n" ; else - if (_jcfg->_mesh_kern == + if (_jcfg->_mesh_kern == JIGSAW_KERN_DELAUNAY) - _file << "MESH_KERN = " + _file << "MESH_KERN = " << "DELAUNAY\n" ; - + /*--------------------------------- MESH keywords */ - _file << "MESH_DIMS = " << + _file << "MESH_DIMS = " << _jcfg->_mesh_dims << "\n" ; - - _file << "MESH_ITER = " << + + _file << "MESH_ITER = " << _jcfg->_mesh_iter << "\n" ; - - _file << "MESH_SIZ1 = " << + + _file << "MESH_SIZ1 = " << _jcfg->_mesh_siz1 << "\n" ; - _file << "MESH_SIZ2 = " << + _file << "MESH_SIZ2 = " << _jcfg->_mesh_siz2 << "\n" ; - _file << "MESH_SIZ3 = " << + _file << "MESH_SIZ3 = " << _jcfg->_mesh_siz3 << "\n" ; - - _file << "MESH_TOP1 = " << + + _file << "MESH_TOP1 = " << _jcfg->_mesh_top1 << "\n" ; - _file << "MESH_TOP2 = " << + _file << "MESH_TOP2 = " << _jcfg->_mesh_top2 << "\n" ; - - _file << "MESH_RAD2 = " << + + _file << "MESH_RAD2 = " << _jcfg->_mesh_rad2 << "\n" ; - _file << "MESH_RAD3 = " << + _file << "MESH_RAD3 = " << _jcfg->_mesh_rad3 << "\n" ; - - _file << "MESH_OFF2 = " << + + _file << "MESH_OFF2 = " << _jcfg->_mesh_off2 << "\n" ; _file << "MESH_OFF3 = " << _jcfg->_mesh_off3 << "\n" ; - - _file << "MESH_SNK2 = " << + + _file << "MESH_SNK2 = " << _jcfg->_mesh_snk2 << "\n" ; - _file << "MESH_SNK3 = " << + _file << "MESH_SNK3 = " << _jcfg->_mesh_snk3 << "\n" ; - - _file << "MESH_EPS1 = " << + + _file << "MESH_EPS1 = " << _jcfg->_mesh_eps1 << "\n" ; - _file << "MESH_EPS2 = " << + _file << "MESH_EPS2 = " << _jcfg->_mesh_eps2 << "\n" ; - + _file << "MESH_VOL3 = " << _jcfg->_mesh_vol3 << "\n" ; - + /*--------------------------------- OPTM keywords */ - _file << "OPTM_ITER = " << + if (_jcfg->_optm_kern == + JIGSAW_KERN_ODT_DQDX) + _file << "OPTM_KERN = " + << "ODT+DQDX\n" ; + else + if (_jcfg->_optm_kern == + JIGSAW_KERN_CVT_DQDX) + _file << "OPTM_KERN = " + << "CVT+DQDX\n" ; + + /*--------------------------------- OPTM keywords */ + _file << "OPTM_ITER = " << _jcfg->_optm_iter << "\n" ; - - _file << "OPTM_QTOL = " << + + _file << "OPTM_QTOL = " << _jcfg->_optm_qtol << "\n" ; - _file << "OPTM_QLIM = " << - _jcfg->_optm_qlim << "\n" ; - - _file << "OPTM_TRIA = " << + _file << "OPTM_QLIM = " << + _jcfg->_optm_qlim << "\n" ; + + _file << "OPTM_TRIA = " << _jcfg->_optm_tria << "\n" ; - _file << "OPTM_DUAL = " << + _file << "OPTM_DUAL = " << _jcfg->_optm_dual << "\n" ; - _file << "OPTM_DIV_ = " << + _file << "OPTM_DIV_ = " << _jcfg->_optm_div_ << "\n" ; - _file << "OPTM_ZIP_ = " << + _file << "OPTM_ZIP_ = " << _jcfg->_optm_zip_ << "\n" ; } else { _errv = __file_not_created ; } - + } catch (...) { _errv = __unknown_error ; } - + return _errv ; } diff --git a/src/liblib/save_msh_t.hpp b/src/liblib/save_msh_t.hpp index 5528a98..6aa0b54 100644 --- a/src/liblib/save_msh_t.hpp +++ b/src/liblib/save_msh_t.hpp @@ -4,29 +4,29 @@ * SAVE-MSH_T: save msh_t for lib_jigsaw. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- @@ -63,10 +63,10 @@ __unreferenced(_fchr) ; __unreferenced(_jmsh) ; - + //!! TODO - - + + return _errv ; } diff --git a/src/marche.hpp b/src/marche.hpp index 77e3bad..c233c9a 100644 --- a/src/marche.hpp +++ b/src/marche.hpp @@ -2,19 +2,19 @@ /* -------------------------------------------------------- * - * ,o, ,o, / + * ,o, ,o, / * ` ` e88~88e d88~\ /~~~8e Y88b e / - * 888 888 88 88 C888 88b Y88b d8b / - * 888 888 "8b_d8" Y88b e88~-888 Y888/Y88b/ - * 888 888 / 888D C88 888 Y8/ Y8/ - * 88P 888 Cb \_88P "8b_-888 Y Y - * \_8" Y8""8D + * 888 888 88 88 C888 88b Y88b d8b / + * 888 888 "8b_d8" Y88b e88~-888 Y888/Y88b/ + * 888 888 / 888D C88 888 Y8/ Y8/ + * 88P 888 Cb \_88P "8b_-888 Y Y + * \_8" Y8""8D * -------------------------------------------------------- - * MARCHE: "fast-marching" eikonal eqn. solver. + * MARCHE: "fast-marching" eikonal equation solver. -------------------------------------------------------- * - * Last updated: 22 January, 2019 + * Last updated: 28 June, 2019 * * Copyright 2013 -- 2019 * Darren Engwirda @@ -22,44 +22,38 @@ * https://github.com/dengwirda * -------------------------------------------------------- - * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor the National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- */ - - template < - typename jlog_data - > - __normal_call void_type marche_banner ( - jlog_data &_jlog - ) - { - /*-- NB: silliness re. escape sequences */ - _jlog.push ( + + namespace MARCHE { + + std::string asciibanner = " \n" "#------------------------------------------------------------\n" "#\n" @@ -72,13 +66,13 @@ "# \\_8\" Y8\"\"8D \n" "#\n" "#------------------------------------------------------------\n" - "# MARCHE: \"fast-marching\" eikonal eqn. solver. \n" + "# MARCHE: \"fast-marching\" eikonal equation solver. \n" "#------------------------------------------------------------\n" " \n" - " " __JGSWVSTR "\n\n" - ) ; + " " __JGSWVSTR "\n\n" ; + } - + # ifdef __lib_jigsaw # include "liblib/init_jig_t.hpp" @@ -89,19 +83,19 @@ # include "liblib/save_jig_t.hpp" # include "liblib/save_msh_t.hpp" - + __normal_call iptr_type marche ( // lib-jigsaw jigsaw_jig_t *_jjig , jigsaw_msh_t *_fmsh ) { iptr_type _retv = +0; - + __unreferenced(_fmsh) ; hfun_data _ffun ; // FUNC data jcfg_data _jcfg ; - + # ifdef __use_timers typename std ::chrono:: high_resolution_clock:: @@ -111,35 +105,36 @@ time_point _ttoc ; typename std ::chrono:: high_resolution_clock _time; - + __unreferenced(_time) ; # endif//__use_timers - + /*--------------------------------- setup *.JLOG data */ if (_jjig != nullptr ) { _jcfg._verbosity = _jjig->_verbosity ; } - jlog_null _jlog(_jcfg) ; - marche_banner (_jlog) ; - + jlog_null _jlog(_jcfg) ; + _jlog.push(MARCHE:: + asciibanner) ; + /*--------------------------------- parse *.JCFG data */ if (_jjig != nullptr ) { _jlog.push ( " Reading CFG. data...\n\n" ) ; -# ifdef __use_timers +# ifdef __use_timers _ttic = _time.now(); # endif//__use_timers - + if ((_retv = copy_jcfg ( - _jcfg, + _jcfg, _jlog,*_jjig)) != __no_error) { return _retv ; - } - + } + if ((_retv = test_jcfg ( _jcfg, _jlog)) != __no_error) { @@ -155,12 +150,120 @@ return _retv ; } -# ifdef __use_timers +# ifdef __use_timers + _ttoc = _time.now(); + _jlog.push(dump_time(_ttic, _ttoc)); +# endif//__use_timers + } + + if (_fmsh != nullptr ) + { + /*--------------------------------- parse *.HFUN data */ + _jlog.push ( __jloglndv "\n" ) ; + _jlog.push ( + " Reading FFUN data...\n\n" ) ; + +# ifdef __use_timers + _ttic = _time.now(); +# endif//__use_timers + + if ((_retv = copy_hfun ( + _jcfg, _jlog , + _ffun,*_fmsh)) != __no_error) + { + return _retv ; + } + + if ((_retv = test_hfun ( + _jcfg, + _jlog, _ffun)) != __no_error) + { + return _retv ; + } + +# ifdef __use_timers _ttoc = _time.now(); _jlog.push(dump_time(_ttic, _ttoc)); # endif//__use_timers } - + + if (_fmsh != nullptr ) + { + /*--------------------------------- assemble size-fun */ + _jlog.push ( __jloglndv "\n" ) ; + _jlog.push ( + " Forming FFUN data...\n\n" ) ; + +# ifdef __use_timers + _ttic = _time.now(); +# endif//__use_timers + + _ffun.init_hfun(_jcfg, true) ; + + if (_jcfg._verbosity > 0 ) + { + + _jlog.push ( + " FFUN data summary...\n\n" ) ; + + if ((_retv = echo_hfun ( + _jcfg, + _jlog, _ffun)) != __no_error) + { + return _retv ; + } + + } + +# ifdef __use_timers + _ttoc = _time.now(); + _jlog.push(dump_time(_ttic, _ttoc)); +# endif//__use_timers + } + + if (_fmsh != nullptr ) + { + /*--------------------------------- call h-jac solver */ + _jlog.push ( __jloglndv "\n" ) ; + _jlog.push ( + " Fast-march solver...\n\n" ) ; + +# ifdef __use_timers + _ttic = _time.now(); +# endif//__use_timers + + _ffun.clip_hfun(_jcfg) ; + +# ifdef __use_timers + _ttoc = _time.now(); + _jlog.push(dump_time(_ttic, _ttoc)); +# endif//__use_timers + } + + if (_fmsh != nullptr ) + { + /*--------------------------------- dump mesh to file */ + _jlog.push ( __jloglndv "\n" ) ; + _jlog.push ( + " Writing FFUN data...\n\n" ) ; + +# ifdef __use_timers + _ttic = _time.now(); +# endif//__use_timers + + if ((_retv = save_hfun ( + _jcfg, _jlog, + _ffun,*_fmsh)) != __no_error) + { + return _retv ; + } + +# ifdef __use_timers + _ttoc = _time.now(); + _jlog.push(dump_time(_ttic, _ttoc)); +# endif//__use_timers + } + /*-------------------------- success, if we got here! */ return ( _retv ) ; @@ -171,12 +274,12 @@ # if defined(__cmd_marche) __normal_call iptr_type main ( // cmd-marche - int _argc , + int _argc , char **_argv ) { hfun_data _ffun ; // FUNC data - + # ifdef __use_timers typename std ::chrono:: high_resolution_clock:: @@ -186,33 +289,50 @@ time_point _ttoc ; typename std ::chrono:: high_resolution_clock _time; - + __unreferenced(_time) ; # endif//__use_timers - - /*-------------------------- find *.JFCG file in args */ + + /*-------------------------- find *.JFCG file in args */ iptr_type _retv = -1 ; jcfg_data _jcfg ; for (; _argc-- != +0; ) { std::string _ssrc(_argv[_argc]) ; - - std::string _path ; - std::string _name ; - std::string _fext ; - file_part ( _ssrc , - _path , _name , _fext) ; - if (_ssrc.find("-whoami") == 0) + if (_ssrc.find("-h") == 0 || + _ssrc.find( + "--help") == 0 ) + { + _retv = -2 ; + + std::cout << + "run marche jigname.jig"; + std::cout << std::endl ; + + break ; + } + + if (_ssrc.find("-v") == 0 || + _ssrc.find( + "--version") == 0 || + _ssrc.find( + "-whoami") == 0 ) { _retv = -2 ; - + std::cout << __JGSWVSTR ; std::cout << std::endl ; - + break ; } + std::string _path ; + std::string _name ; + std::string _fext ; + file_part ( _ssrc , + _path , _name , _fext ) ; + if (_fext.find("jig") == 0) { _retv = +0 ; @@ -228,25 +348,26 @@ if (_retv != +0) return ( _retv ) ; /*--------------------------------- setup *.JLOG file */ - jlog_text _jlog(_jcfg) ; - marche_banner (_jlog) ; - + jlog_text _jlog(_jcfg) ; + _jlog.push(MARCHE:: + asciibanner) ; + if(!_jcfg._jcfg_file.empty()) { /*--------------------------------- parse *.JCFG file */ _jlog.push ( " Reading CFG. file...\n\n" ) ; - + # ifdef __use_timers _ttic = _time.now(); # endif//__use_timers - + if ((_retv = read_jcfg ( _jcfg, _jlog)) != __no_error) { return _retv ; - } - + } + if ((_retv = test_jcfg ( _jcfg, _jlog)) != __no_error) { @@ -261,21 +382,129 @@ { return _retv ; } - + +# ifdef __use_timers + _ttoc = _time.now(); + _jlog.push(dump_time(_ttic, _ttoc)); +# endif//__use_timers + } + + if(!_jcfg._hfun_file.empty()) + { + /*--------------------------------- parse *.HFUN file */ + _jlog.push ( __jloglndv "\n" ) ; + _jlog.push ( + " Reading FFUN file...\n\n" ) ; + +# ifdef __use_timers + _ttic = _time.now(); +# endif//__use_timers + + if ((_retv = read_hfun ( + _jcfg, + _jlog, _ffun)) != __no_error) + { + return _retv ; + } + + if ((_retv = test_hfun ( + _jcfg, + _jlog, _ffun)) != __no_error) + { + return _retv ; + } + # ifdef __use_timers _ttoc = _time.now(); _jlog.push(dump_time(_ttic, _ttoc)); # endif//__use_timers } - -/*-------------------------- success, if we got here! */ - return ( _retv ) ; + if(!_jcfg._hfun_file.empty()) + { + /*--------------------------------- assemble size-fun */ + _jlog.push ( __jloglndv "\n" ) ; + _jlog.push ( + " Forming FFUN data...\n\n" ) ; + +# ifdef __use_timers + _ttic = _time.now(); +# endif//__use_timers + + _ffun.init_hfun(_jcfg, true) ; + + if (_jcfg._verbosity > 0 ) + { + + _jlog.push ( + " FFUN data summary...\n\n" ) ; + + if ((_retv = echo_hfun ( + _jcfg, + _jlog, _ffun)) != __no_error) + { + return _retv ; + } + + } + +# ifdef __use_timers + _ttoc = _time.now(); + _jlog.push(dump_time(_ttic, _ttoc)); +# endif//__use_timers + } + + if(!_jcfg._hfun_file.empty()) + { + /*--------------------------------- call h-jac solver */ + _jlog.push ( __jloglndv "\n" ) ; + _jlog.push ( + " Fast-march solver...\n\n" ) ; + +# ifdef __use_timers + _ttic = _time.now(); +# endif//__use_timers + + _ffun.clip_hfun(_jcfg) ; + +# ifdef __use_timers + _ttoc = _time.now(); + _jlog.push(dump_time(_ttic, _ttoc)); +# endif//__use_timers + } + + if(!_jcfg._hfun_file.empty()) + { + /*--------------------------------- dump mesh to file */ + _jlog.push ( __jloglndv "\n" ) ; + _jlog.push ( + " Writing FFUN file...\n\n" ) ; + +# ifdef __use_timers + _ttic = _time.now(); +# endif//__use_timers + + if ((_retv = save_hfun ( + _jcfg, + _jlog, _ffun)) != __no_error) + { + return _retv ; + } + +# ifdef __use_timers + _ttoc = _time.now(); + _jlog.push(dump_time(_ttic, _ttoc)); +# endif//__use_timers + } + + /*-------------------------- success, if we got here! */ + + return ( _retv ) ; } - + # endif //__cmd_marche -# endif //__lib_jigsaw - - - +# endif //__lib_jigsaw + + + diff --git a/src/msh_copy.hpp b/src/msh_copy.hpp index 8073db7..2d2549d 100644 --- a/src/msh_copy.hpp +++ b/src/msh_copy.hpp @@ -4,36 +4,36 @@ * MSH-COPY: copy MESH data into a tria-complex. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 10 September, 2018 + * Last updated: 05 July, 2019 * - * Copyright 2013-2018 + * Copyright 2013-2019 * Darren Engwirda * de2363@columbia.edu * https://github.com/dengwirda/ @@ -51,7 +51,7 @@ * COPY-MESH: copy rdel-complex to tria-complex. -------------------------------------------------------- */ - + template < typename jlog_data > @@ -66,41 +66,18 @@ __unreferenced(_jcfg) ; __unreferenced(_jlog) ; - - //!! need to free memory here as well somehow? - + if (_rdel._ndim == +2 && _rdel._kind == jmsh_kind::euclidean_mesh) { - + /*---------------------------------- copy 2-dim. mesh */ _mesh._euclidean_mesh_2d._mesh. clear(containers::loose_alloc) ; - + _mesh._kind = _rdel._kind ; _mesh._ndim = _rdel._ndim ; - - _mesh._euclidean_mesh_2d._mesh. - _map1._lptr.set_count ( - (_rdel._euclidean_rdel_2d. - _tria._nset.count()*5)/4, - containers::loose_alloc, nullptr); - - _mesh._euclidean_mesh_2d._mesh. - _map2._lptr.set_count ( - (_rdel._euclidean_rdel_2d. - _eset.count()*5) / 4 + - (_rdel._euclidean_rdel_2d. - _tset.count()*7) / 3 , - containers::loose_alloc, nullptr); - - _mesh._euclidean_mesh_2d._mesh. - _map3._lptr.set_count ( - (_rdel._euclidean_rdel_2d. - _tset.count()*5) / 4 , - containers::loose_alloc, nullptr); - - + for (auto _iter = _rdel. _euclidean_rdel_2d._tria._nset.head() ; _iter != _rdel. @@ -113,20 +90,23 @@ euclidean_mesh_2d:: mesh_type::node_type _node ; _node.pval(0) = _iter->pval(0) ; - _node.pval(1) = _iter->pval(1) ; - + _node.pval(1) = _iter->pval(1) ; + _node.pval(2) = (real_type)+0. ; - + _node.hidx () = _iter->idxh () ; - + _node.fdim () = _iter->fdim () ; _node.feat () = _iter->feat () ; - + _mesh._euclidean_mesh_2d. - _mesh.push_node (_node) ; + _mesh.push_node (_node, false) ; } } - + + _rdel._euclidean_rdel_2d._tria. + clear(containers::tight_alloc) ; + for (auto _iter = _rdel. _euclidean_rdel_2d._eset._lptr.head() ; _iter != _rdel. @@ -142,20 +122,23 @@ typename mesh_data:: euclidean_mesh_2d:: mesh_type::edge_type _face; - _face.node(0) = + _face.node(0) = _item->_data._node[0] ; - _face.node(1) = + _face.node(1) = _item->_data._node[1] ; - - _face.itag () = + + _face.itag () = _item->_data._part; - + _mesh._euclidean_mesh_2d. - _mesh.push_edge (_face) ; + _mesh.push_edge (_face, false) ; } } } - + + _rdel._euclidean_rdel_2d._eset. + clear(containers::tight_alloc) ; + for (auto _iter = _rdel. _euclidean_rdel_2d._tset._lptr.head() ; _iter != _rdel. @@ -171,66 +154,44 @@ typename mesh_data:: euclidean_mesh_2d:: mesh_type::tri3_type _face; - _face.node(0) = + _face.node(0) = _item->_data._node[0] ; - _face.node(1) = + _face.node(1) = _item->_data._node[1] ; - _face.node(2) = + _face.node(2) = _item->_data._node[2] ; - - _face.itag () = + + _face.itag () = _item->_data._part; - + _mesh._euclidean_mesh_2d. - _mesh.push_tri3 (_face) ; + _mesh.push_tri3 (_face, false) ; } } } - + + _rdel._euclidean_rdel_2d._tset. + clear(containers::tight_alloc) ; + + _rdel._euclidean_rdel_2d. + clear(containers::tight_alloc) ; + + _mesh._euclidean_mesh_2d. + _mesh.make_link () ; + } else if (_rdel._ndim == +3 && _rdel._kind == jmsh_kind::euclidean_mesh) { - + /*---------------------------------- copy 3-dim. mesh */ _mesh._euclidean_mesh_3d._mesh. clear(containers::loose_alloc) ; - + _mesh._kind = _rdel._kind ; _mesh._ndim = _rdel._ndim ; - - _mesh._euclidean_mesh_3d._mesh. - _map1._lptr.set_count ( - (_rdel._euclidean_rdel_3d. - _tria._nset.count()*5)/4, - containers::loose_alloc, nullptr); - - _mesh._euclidean_mesh_3d._mesh. - _map2._lptr.set_count ( - (_rdel._euclidean_rdel_3d. - _eset.count()*5) / 4 + - (_rdel._euclidean_rdel_3d. - _fset.count()*7) / 3 + - (_rdel._euclidean_rdel_3d. - _tset.count()*9) / 2 , - containers::loose_alloc, nullptr); - - _mesh._euclidean_mesh_3d._mesh. - _map3._lptr.set_count ( - (_rdel._euclidean_rdel_3d. - _fset.count()*5) / 4 + - (_rdel._euclidean_rdel_3d. - _tset.count()*8) / 3 , - containers::loose_alloc, nullptr); - - _mesh._euclidean_mesh_3d._mesh. - _map4._lptr.set_count ( - (_rdel._euclidean_rdel_3d. - _tset.count()*5) / 4 , - containers::loose_alloc, nullptr); - - + for (auto _iter = _rdel. _euclidean_rdel_3d._tria._nset.head() ; _iter != _rdel. @@ -245,19 +206,22 @@ _node.pval(0) = _iter->pval(0) ; _node.pval(1) = _iter->pval(1) ; _node.pval(2) = _iter->pval(2) ; - + _node.pval(3) = (real_type)+0. ; - + _node.hidx () = _iter->idxh () ; - + _node.fdim () = _iter->fdim () ; _node.feat () = _iter->feat () ; - + _mesh._euclidean_mesh_3d. - _mesh.push_node (_node) ; + _mesh.push_node (_node, false) ; } } - + + _rdel._euclidean_rdel_3d._tria. + clear(containers::tight_alloc) ; + for (auto _iter = _rdel. _euclidean_rdel_3d._eset._lptr.head() ; _iter != _rdel. @@ -273,20 +237,23 @@ typename mesh_data:: euclidean_mesh_3d:: mesh_type::edge_type _face; - _face.node(0) = + _face.node(0) = _item->_data._node[0] ; - _face.node(1) = + _face.node(1) = _item->_data._node[1] ; - - _face.itag () = + + _face.itag () = _item->_data._part; - + _mesh._euclidean_mesh_3d. - _mesh.push_edge (_face) ; + _mesh.push_edge (_face, false) ; } } } - + + _rdel._euclidean_rdel_3d._eset. + clear(containers::tight_alloc) ; + for (auto _iter = _rdel. _euclidean_rdel_3d._fset._lptr.head() ; _iter != _rdel. @@ -302,22 +269,25 @@ typename mesh_data:: euclidean_mesh_3d:: mesh_type::tri3_type _face; - _face.node(0) = + _face.node(0) = _item->_data._node[0] ; - _face.node(1) = + _face.node(1) = _item->_data._node[1] ; - _face.node(2) = + _face.node(2) = _item->_data._node[2] ; - - _face.itag () = + + _face.itag () = _item->_data._part; - + _mesh._euclidean_mesh_3d. - _mesh.push_tri3 (_face) ; + _mesh.push_tri3 (_face, false) ; } } } - + + _rdel._euclidean_rdel_3d._fset. + clear(containers::tight_alloc) ; + for (auto _iter = _rdel. _euclidean_rdel_3d._tset._lptr.head() ; _iter != _rdel. @@ -333,31 +303,40 @@ typename mesh_data:: euclidean_mesh_3d:: mesh_type::tri4_type _face; - _face.node(0) = + _face.node(0) = _item->_data._node[0] ; - _face.node(1) = + _face.node(1) = _item->_data._node[1] ; - _face.node(2) = + _face.node(2) = _item->_data._node[2] ; - _face.node(3) = + _face.node(3) = _item->_data._node[3] ; - - _face.itag () = + + _face.itag () = _item->_data._part; - + _mesh._euclidean_mesh_3d. - _mesh.push_tri4 (_face) ; + _mesh.push_tri4 (_face, false) ; } } } - + + _rdel._euclidean_rdel_3d._tset. + clear(containers::tight_alloc) ; + + _rdel._euclidean_rdel_3d. + clear(containers::tight_alloc) ; + + _mesh._euclidean_mesh_3d. + _mesh.make_link () ; + } - + return ( _errv ) ; } - - + + # endif //__MSH_COPY__ - + diff --git a/src/msh_init.hpp b/src/msh_init.hpp index bca7554..04d58fe 100644 --- a/src/msh_init.hpp +++ b/src/msh_init.hpp @@ -4,29 +4,29 @@ * MSH-INIT: init MESH data-structures. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- @@ -40,18 +40,18 @@ * -------------------------------------------------------- */ - + # pragma once # ifndef __MSH_INIT__ -# define __MSH_INIT__ - +# define __MSH_INIT__ + /* -------------------------------------------------------- * INIT-MESH: initialise MESH data. -------------------------------------------------------- */ - + template < typename jlog_data > @@ -78,24 +78,24 @@ ++_iter ) { if (_iter->mark() < 0) continue ; - - if (_iter->feat() + + if (_iter->feat() == mesh::null_feat) _iter->fdim() = 2 ; else - if (_iter->feat() + if (_iter->feat() == mesh::user_feat) _iter->fdim() = 2 ; else - if (_iter->feat() + if (_iter->feat() == mesh::soft_feat) _iter->fdim() = 0 ; else - if (_iter->feat() + if (_iter->feat() == mesh::hard_feat) _iter->fdim() = 0 ; } - + for (auto _iter = _mesh. _euclidean_mesh_2d._mesh._set3.head() ; _iter != _mesh. @@ -103,17 +103,17 @@ ++_iter ) { if (_iter->mark() < 0) continue ; - + auto _head = _mesh. _euclidean_mesh_2d._mesh._set1.head() ; - - auto _inod = + + auto _inod = _head+_iter->node( +0) ; - auto _jnod = + auto _jnod = _head+_iter->node( +1) ; - auto _knod = + auto _knod = _head+_iter->node( +2) ; - + if (_inod->fdim() > 2) _inod->fdim() = 2 ; if (_jnod->fdim() > 2) @@ -121,7 +121,7 @@ if (_knod->fdim() > 2) _knod->fdim() = 2 ; } - + for (auto _iter = _mesh. _euclidean_mesh_2d._mesh._set2.head() ; _iter != _mesh. @@ -129,15 +129,15 @@ ++_iter ) { if (_iter->mark() < 0) continue ; - + auto _head = _mesh. _euclidean_mesh_2d._mesh._set1.head() ; - - auto _inod = + + auto _inod = _head+_iter->node( +0) ; - auto _jnod = + auto _jnod = _head+_iter->node( +1) ; - + if (_inod->fdim() > 1) _inod->fdim() = 1 ; if (_jnod->fdim() > 1) @@ -157,24 +157,24 @@ ++_iter ) { if (_iter->mark() < 0) continue ; - - if (_iter->feat() + + if (_iter->feat() == mesh::null_feat) _iter->fdim() = 3 ; else - if (_iter->feat() + if (_iter->feat() == mesh::user_feat) _iter->fdim() = 3 ; else - if (_iter->feat() + if (_iter->feat() == mesh::soft_feat) _iter->fdim() = 0 ; else - if (_iter->feat() + if (_iter->feat() == mesh::hard_feat) _iter->fdim() = 0 ; } - + for (auto _iter = _mesh. _euclidean_mesh_3d._mesh._set4.head() ; _iter != _mesh. @@ -182,19 +182,19 @@ ++_iter ) { if (_iter->mark() < 0) continue ; - + auto _head = _mesh. _euclidean_mesh_3d._mesh._set1.head() ; - - auto _inod = + + auto _inod = _head+_iter->node( +0) ; - auto _jnod = + auto _jnod = _head+_iter->node( +1) ; - auto _knod = + auto _knod = _head+_iter->node( +2) ; - auto _lnod = + auto _lnod = _head+_iter->node( +3) ; - + if (_inod->fdim() > 3) _inod->fdim() = 3 ; if (_jnod->fdim() > 3) @@ -202,9 +202,9 @@ if (_knod->fdim() > 3) _knod->fdim() = 3 ; if (_lnod->fdim() > 3) - _lnod->fdim() = 3 ; + _lnod->fdim() = 3 ; } - + for (auto _iter = _mesh. _euclidean_mesh_3d._mesh._set3.head() ; _iter != _mesh. @@ -212,17 +212,17 @@ ++_iter ) { if (_iter->mark() < 0) continue ; - + auto _head = _mesh. _euclidean_mesh_3d._mesh._set1.head() ; - - auto _inod = + + auto _inod = _head+_iter->node( +0) ; - auto _jnod = + auto _jnod = _head+_iter->node( +1) ; - auto _knod = + auto _knod = _head+_iter->node( +2) ; - + if (_inod->fdim() > 2) _inod->fdim() = 2 ; if (_jnod->fdim() > 2) @@ -230,7 +230,7 @@ if (_knod->fdim() > 2) _knod->fdim() = 2 ; } - + for (auto _iter = _mesh. _euclidean_mesh_3d._mesh._set2.head() ; _iter != _mesh. @@ -238,26 +238,26 @@ ++_iter ) { if (_iter->mark() < 0) continue ; - + auto _head = _mesh. _euclidean_mesh_3d._mesh._set1.head() ; - - auto _inod = + + auto _inod = _head+_iter->node( +0) ; - auto _jnod = + auto _jnod = _head+_iter->node( +1) ; - + if (_inod->fdim() > 1) _inod->fdim() = 1 ; if (_jnod->fdim() > 1) _jnod->fdim() = 1 ; } - } - - return ( _errv ) ; + } + + return ( _errv ) ; } - + # endif //__MSH_INIT__ - - - + + + diff --git a/src/msh_read.hpp b/src/msh_read.hpp index 698c926..51f80e0 100644 --- a/src/msh_read.hpp +++ b/src/msh_read.hpp @@ -4,34 +4,34 @@ * MSH-READ: parse *.MSH file into mesh data. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 19 June, 2019 + * Last updated: 28 June, 2019 * * Copyright 2013-2019 * Darren Engwirda @@ -140,6 +140,14 @@ std:: size_t /*_irow*/, double * /*_vdat*/ ) { } + __normal_call void_type open_slope ( + std:: size_t /*_nrow*/, + std:: size_t /*_nval*/ + ) { } + __normal_call void_type push_slope ( + std:: size_t /*_irow*/, + double * /*_vdat*/ + ) { } __normal_call void_type open_bound ( std:: size_t /*_nrow*/ ) { } @@ -157,7 +165,7 @@ std:: size_t /*_idim*/, std:: size_t /*_irow*/, double /*_ppos*/ - ) { } + ) { } } ; /* @@ -169,17 +177,17 @@ class jmsh_reader { public : - + typedef containers::array < std::string > string_tokens; - + string_tokens _errs ; - + std::int32_t _ftag ; std:: size_t _ndim ; - + jmsh_kind::enum_data _kind ; - + public : /* @@ -198,56 +206,56 @@ ) { __unreferenced (_ffid) ; - + if (_stok.count() == +2) { this->_ftag = std::stol(_stok[1]) ; - this->_kind = + this->_kind = jmsh_kind::euclidean_mesh ; - - _dest.push_mshid(this->_ftag , + + _dest.push_mshid(this->_ftag , this->_kind ) ; } else if (_stok.count() == +3) { - + this->_ftag = std::stol(_stok[1]) ; - + if (_stok[2] == "EUCLIDEAN-MESH") { - this->_kind = + this->_kind = jmsh_kind::euclidean_mesh ; } else if (_stok[2] == "EUCLIDEAN-GRID") { - this->_kind = + this->_kind = jmsh_kind::euclidean_grid ; } else if (_stok[2] == "EUCLIDEAN-DUAL") { - this->_kind = + this->_kind = jmsh_kind::euclidean_dual ; } else if (_stok[2] == "ELLIPSOID-MESH") { - this->_kind = + this->_kind = jmsh_kind::ellipsoid_mesh ; } else if (_stok[2] == "ELLIPSOID-GRID") { - this->_kind = + this->_kind = jmsh_kind::ellipsoid_grid ; } else if (_stok[2] == "ELLIPSOID-DUAL") { - this->_kind = + this->_kind = jmsh_kind::ellipsoid_dual ; } else @@ -255,11 +263,11 @@ this->_errs. push_tail("Invalid MSHID!") ; } - - _dest.push_mshid(this->_ftag , + + _dest.push_mshid(this->_ftag , this->_kind ) ; - + } else { @@ -267,13 +275,13 @@ push_tail("Invalid MSHID!") ; } } - + /* -------------------------------------------------------- * READ-NDIMS: read NDIMS data section -------------------------------------------------------- */ - + template < typename dest_type > @@ -284,12 +292,12 @@ ) { __unreferenced (_ffid) ; - + if (_stok.count() == +2) { this-> _ndim = std::stoi( _stok[1]); - + _dest. push_ndims (this->_ndim) ; } @@ -299,13 +307,13 @@ push_tail("Invalid NDIMS!"); } } - + /* -------------------------------------------------------- * READ-RADII: read RADII data section -------------------------------------------------------- */ - + template < typename dest_type > @@ -316,17 +324,17 @@ ) { __unreferenced (_ffid) ; - + double _erad[ +3] ; if (_stok.count() == +4) { - _erad[ 0] = + _erad[ 0] = std::stod(_stok[ 1]) ; - _erad[ 1] = + _erad[ 1] = std::stod(_stok[ 2]) ; - _erad[ 2] = + _erad[ 2] = std::stod(_stok[ 3]) ; - + _dest.push_radii(_erad); } else @@ -341,7 +349,7 @@ * READ-POINT: read POINT data section -------------------------------------------------------- */ - + template < typename dest_type > @@ -351,6 +359,9 @@ dest_type &_dest ) { + containers:: + array< std::string > _tstr ; + /*----------------------------------------- read head */ std:: size_t _nrow = +0; std:: size_t _irow = +0; @@ -363,37 +374,36 @@ this->_errs. push_tail("Invalid POINT!"); } - + _dest.open_point(_nrow); - + /*----------------------------------------- read data */ std::string _line; while (std::getline(_ffid, _line)) { + _tstr.clear(); + try { - containers:: - array _tstr ; - find_toks (_line, ";", _tstr); - + if (_tstr.count() == this->_ndim+1) { - std:: size_t static + std:: size_t static constexpr _VMAX = +16; - + double _pval[_VMAX]; std::int32_t _itag ; for (auto _ipos = this->_ndim ; _ipos-- != +0; ) { - _pval[_ipos] = + _pval[_ipos] = std::stod(_tstr[_ipos]); } - + _itag = std::stol( _tstr[this->_ndim]); - + _dest.push_point ( _irow, _pval, _itag); } @@ -401,25 +411,77 @@ { this->_errs.push_tail(_line); } - + + } + catch (...) + { + this->_errs.push_tail(_line); + } + + _irow += +1 ; + + if (--_nrow == +0) break ; + } + } + + /* + -------------------------------------------------------- + * READ-COORD: read COORD data section + -------------------------------------------------------- + */ + + template < + typename dest_type + > + __normal_call void_type read_coord ( + std::ifstream&_ffid , + string_tokens&_stok , + dest_type &_dest + ) + { + /*----------------------------------------- read head */ + std:: size_t _nrow = +0; + std:: size_t _idim = +0; + std:: size_t _irow = +0; + if (_stok.count() == +3) + { + _idim = std::stol(_stok[1]); + _nrow = std::stol(_stok[2]); + } + else + { + this->_errs. + push_tail("Invalid COORD!"); + } + + _dest.open_coord(_idim, _nrow) ; + + /*----------------------------------------- read data */ + std::string _line; + while (std::getline(_ffid, _line)) + { + try + { + _dest.push_coord ( _idim, + _irow, std::stod(_line)); } catch (...) { this->_errs.push_tail(_line); } - + _irow += +1 ; - + if (--_nrow == +0) break ; - } + } } - + /* -------------------------------------------------------- * READ-POWER: read POWER data section -------------------------------------------------------- */ - + template < typename dest_type > @@ -429,6 +491,9 @@ dest_type &_dest ) { + containers:: + array< std::string > _tstr ; + /*----------------------------------------- read head */ std:: size_t _nrow = +0; std:: size_t _npwr = +0; @@ -443,33 +508,32 @@ this->_errs. push_tail("Invalid POWER!"); } - + _dest.open_power(_nrow , _npwr); - + /*----------------------------------------- read data */ std::string _line; while (std::getline(_ffid, _line)) { + _tstr.clear(); + try { - containers:: - array _tstr ; - find_toks (_line, ";", _tstr); - + if (_npwr == _tstr.count ()) { - std:: size_t static + std:: size_t static constexpr _VMAX = +16; - + double _vpwr[_VMAX]; for (auto _ipos = _npwr; _ipos-- != +0; ) { - _vpwr[_ipos] = + _vpwr[_ipos] = std::stod(_tstr[_ipos]); } - + _dest. push_power(_irow, _vpwr); } @@ -477,86 +541,115 @@ { this->_errs.push_tail(_line); } - + } catch (...) { this->_errs.push_tail(_line); } - + _irow += +1 ; - + if (--_nrow == +0) break ; - } + } } - + /* -------------------------------------------------------- - * READ-COORD: read COORD data section + * READ-VALUE: read VALUE data section -------------------------------------------------------- */ - + template < typename dest_type > - __normal_call void_type read_coord ( + __normal_call void_type read_value ( std::ifstream&_ffid , string_tokens&_stok , dest_type &_dest ) { + containers:: + array< std::string > _tstr ; + /*----------------------------------------- read head */ std:: size_t _nrow = +0; - std:: size_t _idim = +0; + std:: size_t _nval = +0; std:: size_t _irow = +0; if (_stok.count() == +3) { - _idim = std::stol(_stok[1]); - _nrow = std::stol(_stok[2]); + _nrow = std::stol(_stok[1]); + _nval = std::stol(_stok[2]); } else { this->_errs. - push_tail("Invalid COORD!"); + push_tail("Invalid VALUE!"); } - - _dest.open_coord(_idim, _nrow) ; - + + _dest.open_value (_nrow, _nval); + /*----------------------------------------- read data */ std::string _line; while (std::getline(_ffid, _line)) { + _tstr.clear(); + try { - _dest.push_coord ( _idim , - _irow, std::stod(_line)); + find_toks (_line, ";", _tstr); + + if (_nval == _tstr.count ()) + { + std:: size_t static + constexpr _VMAX = +16; + + double _vval[_VMAX]; + for (auto _ipos = _nval; + _ipos-- != +0; ) + { + _vval[_ipos] = + std::stod(_tstr[_ipos]); + } + + _dest. + push_value(_irow, _vval); + } + else + { + this->_errs.push_tail(_line); + } + } catch (...) { this->_errs.push_tail(_line); } - + _irow += +1 ; - + if (--_nrow == +0) break ; - } + } } /* -------------------------------------------------------- - * READ-VALUE: read VALUE data section + * READ-SLOPE: read SLOPE data section -------------------------------------------------------- */ - + template < typename dest_type > - __normal_call void_type read_value ( + __normal_call void_type read_slope ( std::ifstream&_ffid , string_tokens&_stok , dest_type &_dest ) { + containers:: + array< std::string > _tstr ; + /*----------------------------------------- read head */ std:: size_t _nrow = +0; std:: size_t _nval = +0; @@ -569,53 +662,52 @@ else { this->_errs. - push_tail("Invalid VALUE!"); + push_tail("Invalid SLOPE!"); } - - _dest.open_value(_nrow, _nval) ; - + + _dest.open_slope (_nrow, _nval); + /*----------------------------------------- read data */ std::string _line; while (std::getline(_ffid, _line)) { + _tstr.clear(); + try { - containers:: - array _tstr ; - find_toks (_line, ";", _tstr); - + if (_nval == _tstr.count ()) { - std:: size_t static + std:: size_t static constexpr _VMAX = +16; - - double _vval[_VMAX]; + + double _vals[_VMAX]; for (auto _ipos = _nval; _ipos-- != +0; ) { - _vval[_ipos] = + _vals[_ipos] = std::stod(_tstr[_ipos]); } - + _dest. - push_value(_irow, _vval); + push_slope(_irow, _vals); } else { this->_errs.push_tail(_line); } - + } catch (...) { this->_errs.push_tail(_line); } - + _irow += +1 ; - + if (--_nrow == +0) break ; - } + } } /* @@ -633,6 +725,9 @@ dest_type &_dest ) { + containers:: + array< std::string > _tstr ; + /*----------------------------------------- read head */ std:: size_t _nrow = +0; std:: size_t _irow = +0; @@ -645,20 +740,19 @@ this->_errs. push_tail("Invalid EDGE2!"); } - + _dest.open_edge2(_nrow); - + /*----------------------------------------- read data */ std::string _line; while (std::getline(_ffid, _line)) { + _tstr.clear(); + try { - containers:: - array _tstr ; - find_toks (_line, ";", _tstr); - + if (_tstr.count() == +3) { std::int32_t _node[2], _itag; @@ -666,10 +760,10 @@ std::stol(_tstr[0]); _node[1] = std::stol(_tstr[1]); - + _itag = std::stol(_tstr[2]); - + _dest.push_edge2 ( _irow, _node, _itag); } @@ -677,25 +771,25 @@ { this->_errs.push_tail(_line); } - + } catch (...) { this->_errs.push_tail(_line); } - + _irow += +1 ; - + if (--_nrow == +0) break ; - } + } } - + /* -------------------------------------------------------- * READ-TRIA3: read TRIA3 data section -------------------------------------------------------- */ - + template < typename dest_type > @@ -705,6 +799,9 @@ dest_type &_dest ) { + containers:: + array< std::string > _tstr ; + /*----------------------------------------- read head */ std:: size_t _nrow = +0; std:: size_t _irow = +0; @@ -717,20 +814,19 @@ this->_errs. push_tail("Invalid TRIA3!"); } - + _dest.open_tria3(_nrow); - + /*----------------------------------------- read data */ std::string _line; while (std::getline(_ffid, _line)) { + _tstr.clear(); + try { - containers:: - array _tstr ; - find_toks (_line, ";", _tstr); - + if (_tstr.count() == +4) { std::int32_t _node[3], _itag; @@ -740,10 +836,10 @@ std::stol(_tstr[1]); _node[2] = std::stol(_tstr[2]); - + _itag = std::stol(_tstr[3]); - + _dest.push_tria3 ( _irow, _node, _itag); } @@ -751,25 +847,25 @@ { this->_errs.push_tail(_line); } - + } catch (...) { this->_errs.push_tail(_line); } - + _irow += +1 ; - + if (--_nrow == +0) break ; - } + } } - + /* -------------------------------------------------------- * READ-QUAD4: read QUAD4 data section -------------------------------------------------------- */ - + template < typename dest_type > @@ -779,6 +875,9 @@ dest_type &_dest ) { + containers:: + array< std::string > _tstr ; + /*----------------------------------------- read head */ std:: size_t _nrow = +0; std:: size_t _irow = +0; @@ -791,20 +890,19 @@ this->_errs. push_tail("Invalid QUAD4!"); } - + _dest.open_quad4(_nrow); - + /*----------------------------------------- read data */ std::string _line; while (std::getline(_ffid, _line)) { + _tstr.clear(); + try { - containers:: - array _tstr ; - find_toks (_line, ";", _tstr); - + if (_tstr.count() == +5) { std::int32_t _node[4], _itag; @@ -816,10 +914,10 @@ std::stol(_tstr[2]); _node[3] = std::stol(_tstr[3]); - + _itag = std::stol(_tstr[4]); - + _dest.push_quad4 ( _irow, _node, _itag); } @@ -827,25 +925,25 @@ { this->_errs.push_tail(_line); } - + } catch (...) { this->_errs.push_tail(_line); } - + _irow += +1 ; - + if (--_nrow == +0) break ; - } + } } - + /* -------------------------------------------------------- * READ-TRIA4: read TRIA4 data section -------------------------------------------------------- */ - + template < typename dest_type > @@ -855,6 +953,9 @@ dest_type &_dest ) { + containers:: + array< std::string > _tstr ; + /*----------------------------------------- read head */ std:: size_t _nrow = +0; std:: size_t _irow = +0; @@ -867,20 +968,19 @@ this->_errs. push_tail("Invalid TRIA4!"); } - + _dest.open_tria4(_nrow); - + /*----------------------------------------- read data */ std::string _line; while (std::getline(_ffid, _line)) { + _tstr.clear(); + try { - containers:: - array _tstr ; - find_toks (_line, ";", _tstr); - + if (_tstr.count() == +5) { std::int32_t _node[4], _itag; @@ -892,10 +992,10 @@ std::stol(_tstr[2]); _node[3] = std::stol(_tstr[3]); - + _itag = std::stol(_tstr[4]); - + _dest.push_tria4 ( _irow, _node, _itag); } @@ -903,25 +1003,25 @@ { this->_errs.push_tail(_line); } - + } catch (...) { this->_errs.push_tail(_line); } - + _irow += +1 ; - + if (--_nrow == +0) break ; - } + } } - + /* -------------------------------------------------------- * READ-HEXA8: read HEXA8 data section -------------------------------------------------------- */ - + template < typename dest_type > @@ -931,6 +1031,9 @@ dest_type &_dest ) { + containers:: + array< std::string > _tstr ; + /*----------------------------------------- read head */ std:: size_t _nrow = +0; std:: size_t _irow = +0; @@ -943,20 +1046,19 @@ this->_errs. push_tail("Invalid HEXA8!"); } - + _dest.open_hexa8(_nrow); - + /*----------------------------------------- read data */ std::string _line; while (std::getline(_ffid, _line)) { + _tstr.clear(); + try { - containers:: - array _tstr ; - find_toks (_line, ";", _tstr); - + if (_tstr.count() == +9) { std::int32_t _node[8], _itag; @@ -976,10 +1078,10 @@ std::stol(_tstr[6]); _node[7] = std::stol(_tstr[7]); - + _itag = std::stol(_tstr[8]); - + _dest.push_hexa8 ( _irow, _node, _itag); } @@ -987,17 +1089,17 @@ { this->_errs.push_tail(_line); } - + } catch (...) { this->_errs.push_tail(_line); } - + _irow += +1 ; - + if (--_nrow == +0) break ; - } + } } /* @@ -1005,7 +1107,7 @@ * READ-WEDG6: read WEDG6 data section -------------------------------------------------------- */ - + template < typename dest_type > @@ -1015,6 +1117,9 @@ dest_type &_dest ) { + containers:: + array< std::string > _tstr ; + /*----------------------------------------- read head */ std:: size_t _nrow = +0; std:: size_t _irow = +0; @@ -1027,20 +1132,19 @@ this->_errs. push_tail("Invalid WEDG6!"); } - + _dest.open_wedg6(_nrow); - + /*----------------------------------------- read data */ std::string _line; while (std::getline(_ffid, _line)) { + _tstr.clear(); + try { - containers:: - array _tstr ; - find_toks (_line, ";", _tstr); - + if (_tstr.count() == +7) { std::int32_t _node[6], _itag; @@ -1056,10 +1160,10 @@ std::stol(_tstr[4]); _node[5] = std::stol(_tstr[5]); - + _itag = std::stol(_tstr[6]); - + _dest.push_wedg6 ( _irow, _node, _itag); } @@ -1067,25 +1171,25 @@ { this->_errs.push_tail(_line); } - + } catch (...) { this->_errs.push_tail(_line); } - + _irow += +1 ; - + if (--_nrow == +0) break ; - } + } } - + /* -------------------------------------------------------- * READ-PYRA5: read PYRA5 data section -------------------------------------------------------- */ - + template < typename dest_type > @@ -1095,6 +1199,9 @@ dest_type &_dest ) { + containers:: + array< std::string > _tstr ; + /*----------------------------------------- read head */ std:: size_t _nrow = +0; std:: size_t _irow = +0; @@ -1107,20 +1214,19 @@ this->_errs. push_tail("Invalid PYRA5!"); } - + _dest.open_pyra5(_nrow); - + /*----------------------------------------- read data */ std::string _line; while (std::getline(_ffid, _line)) { + _tstr.clear(); + try { - containers:: - array _tstr ; - find_toks (_line, ";", _tstr); - + if (_tstr.count() == +6) { std::int32_t _node[5], _itag; @@ -1134,10 +1240,10 @@ std::stol(_tstr[3]); _node[4] = std::stol(_tstr[4]); - + _itag = std::stol(_tstr[5]); - + _dest.push_pyra5 ( _irow, _node, _itag); } @@ -1145,25 +1251,25 @@ { this->_errs.push_tail(_line); } - + } catch (...) { this->_errs.push_tail(_line); } - + _irow += +1 ; - + if (--_nrow == +0) break ; - } + } } - + /* -------------------------------------------------------- * READ-BOUND: read BOUND data section -------------------------------------------------------- */ - + template < typename dest_type > @@ -1173,6 +1279,9 @@ dest_type &_dest ) { + containers:: + array< std::string > _tstr ; + /*----------------------------------------- read head */ std:: size_t _nrow = +0; std:: size_t _irow = +0; @@ -1185,49 +1294,48 @@ this->_errs. push_tail("Invalid BOUND!"); } - + _dest.open_bound(_nrow); - + /*----------------------------------------- read data */ std::string _line; while (std::getline(_ffid, _line)) { + _tstr.clear(); + try { - containers:: - array _tstr ; - find_toks (_line, ";", _tstr); - + if (_tstr.count() == +3) { std::int32_t _itag = std::stol(_tstr[0]); - + std::int32_t _inum = std::stol(_tstr[1]); - - std::int32_t _kind = + + std::int32_t _KIND = std::stol(_tstr[2]); - + _dest.push_bound ( - _irow, _itag , _inum, _kind); + _irow, _itag, _inum, _KIND); } else { this->_errs.push_tail(_line); } - + } catch (...) { this->_errs.push_tail(_line); } - + _irow += +1 ; - + if (--_nrow == +0) break ; - } + } } /* @@ -1246,34 +1354,34 @@ { this->_ftag = -1 ; this->_ndim = +0 ; - + std::string _line; while (std::getline(_ffid, _line)) { _line = trim(_line) ; - + if (_line.size() <= 0) continue ; if (_line[ +0] == '#') continue ; - + try { - std::transform(_line.begin() , - _line. end() , - _line.begin() , - [](unsigned char c){ return + std::transform(_line.begin() , + _line. end() , + _line.begin() , + [](unsigned char c){ return (unsigned char)::toupper(c); } ) ; - + containers:: array _stok ; - + find_toks(_line, "=;", _stok); - + for (auto _iter = _stok.head() ; _iter != _stok.tend() ; ++_iter ) /*---------------------------- trim on each token */ *_iter = trim( *_iter ) ; - + if (_stok[0] == "MSHID") { read_mshid(_ffid, _stok, @@ -1294,85 +1402,91 @@ else if (_stok[0] == "POINT") { - read_point(_ffid, _stok, - _dest) ; + read_point(_ffid, _stok, + _dest) ; } else - if (_stok[0] == "POWER") + if (_stok[0] == "COORD") { - read_power(_ffid, _stok, - _dest) ; + read_coord(_ffid, _stok, + _dest) ; } else - if (_stok[0] == "COORD") + if (_stok[0] == "POWER") { - read_coord(_ffid, _stok, - _dest) ; + read_power(_ffid, _stok, + _dest) ; } else if (_stok[0] == "VALUE") { - read_value(_ffid, _stok, - _dest) ; + read_value(_ffid, _stok, + _dest) ; + } + else + if (_stok[0] == "SLOPE") + { + read_slope(_ffid, _stok, + _dest) ; } else if (_stok[0] == "EDGE2") { - read_edge2(_ffid, _stok, + read_edge2(_ffid, _stok, _dest) ; } else if (_stok[0] == "TRIA3") { - read_tria3(_ffid, _stok, + read_tria3(_ffid, _stok, _dest) ; } else if (_stok[0] == "QUAD4") { - read_quad4(_ffid, _stok, + read_quad4(_ffid, _stok, _dest) ; } else if (_stok[0] == "TRIA4") { - read_tria4(_ffid, _stok, + read_tria4(_ffid, _stok, _dest) ; } else if (_stok[0] == "HEXA8") { - read_hexa8(_ffid, _stok, + read_hexa8(_ffid, _stok, _dest) ; } else if (_stok[0] == "WEDG6") { - read_wedg6(_ffid, _stok, + read_wedg6(_ffid, _stok, _dest) ; } else if (_stok[0] == "PYRA5") { - read_pyra5(_ffid, _stok, + read_pyra5(_ffid, _stok, _dest) ; } else if (_stok[0] == "BOUND") { - read_bound(_ffid, _stok, + read_bound(_ffid, _stok, _dest) ; } - + } catch (...) { this-> _errs.push_tail (_line) ; - } + } } } - + } ; # endif //__MSH_READ__ diff --git a/src/msh_save.hpp b/src/msh_save.hpp index f929284..affdde1 100644 --- a/src/msh_save.hpp +++ b/src/msh_save.hpp @@ -1,37 +1,37 @@ /* -------------------------------------------------------- - * MSH-SAVE: parse MESH data into *.MSH file. + * MSH-SAVE: parse MESH data into *.MSH / MSH_t. -------------------------------------------------------- * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- * - * Last updated: 18 June, 2019 + * Last updated: 1 October, 2019 * * Copyright 2013-2019 * Darren Engwirda @@ -48,14 +48,14 @@ /* -------------------------------------------------------- - * SAVE-JMSH: save *.JMSH output file. + * SAVE-RDEL: save *.MSH output file. -------------------------------------------------------- */ - + template < typename jlog_data > - __normal_call iptr_type save_jmsh ( + __normal_call iptr_type save_rdel ( jcfg_data &_jcfg , jlog_data &_jlog , rdel_data &_rdel @@ -68,20 +68,20 @@ try { containers::array _nmap; - + std::ofstream _file ; std::string _path ; std::string _name ; - std::string _fext ; + std::string _fext ; file_part( - _jcfg._mesh_file, + _jcfg._mesh_file, _path, _name, _fext); _file.open( - _jcfg._mesh_file, + _jcfg._mesh_file, std::ofstream::out ); - + if (_file.is_open()) { if (_rdel._ndim == +2 && @@ -96,13 +96,13 @@ _file << "NDIMS=2 \n" ; _file << std::scientific ; - _file << + _file << std::setprecision(16); /*------------ index mapping for active nodes */ _nmap.set_count(_rdel. - _euclidean_rdel_2d._tria._nset.count() , - containers::tight_alloc, -1) ; + _euclidean_rdel_2d._tria._nset.count() , + containers::tight_alloc , -1); for (auto _iter = _rdel. _euclidean_rdel_2d._eset._lptr.head(); @@ -111,13 +111,15 @@ ++_iter ) { if ( *_iter == nullptr) continue ; - + for (auto _item = *_iter ; _item != nullptr; _item = _item->_next ) { - _nmap[_item->_data._node[0]]=1 ; - _nmap[_item->_data._node[1]]=1 ; + _nmap[_item-> + _data._node[0]] = 1 ; + _nmap[_item-> + _data._node[1]] = 1 ; } } @@ -128,14 +130,17 @@ ++_iter ) { if ( *_iter == nullptr) continue ; - + for (auto _item = *_iter ; _item != nullptr; _item = _item->_next ) { - _nmap[_item->_data._node[0]]=1 ; - _nmap[_item->_data._node[1]]=1 ; - _nmap[_item->_data._node[2]]=1 ; + _nmap[_item-> + _data._node[0]] = 1 ; + _nmap[_item-> + _data._node[1]] = 1 ; + _nmap[_item-> + _data._node[2]] = 1 ; } } @@ -153,11 +158,11 @@ if (_rdel._euclidean_rdel_2d. _tria._nset.count() > 0) { - /*-------------------------- write POINT data */ + /*-------------------------- write POINT data */ _file << "POINT=" << _last << "\n" ; - + iptr_type _npos = +0 ; - + for (auto _iter = _rdel. _euclidean_rdel_2d._tria._nset.head(); _iter != _rdel. @@ -173,18 +178,18 @@ } } } - + if (_jcfg._iter_opts.dual() ) { if (_rdel._euclidean_rdel_2d. _tria._nset.count() > 0) { - /*-------------------------- write POWER data */ - _file << "POWER=" + /*-------------------------- write POWER data */ + _file << "POWER=" << _last << ";1" << "\n" ; - + iptr_type _npos = +0 ; - + for (auto _iter = _rdel. _euclidean_rdel_2d._tria._nset.head(); _iter != _rdel. @@ -199,15 +204,15 @@ } } } - + if (_rdel._euclidean_rdel_2d. _eset.count() > +0) { - /*-------------------------- write EDGE2 data */ - _file << "EDGE2=" << + /*-------------------------- write EDGE2 data */ + _file << "EDGE2=" << _rdel._euclidean_rdel_2d. _eset.count() << "\n" ; - + for (auto _iter = _rdel. _euclidean_rdel_2d._eset._lptr.head(); _iter != _rdel. @@ -215,29 +220,29 @@ ++_iter ) { if ( *_iter == nullptr) continue ; - + for (auto _item = *_iter ; _item != nullptr; _item = _item->_next ) { - _file << + _file << _nmap[_item->_data._node[0]] - << ";" << + << ";" << _nmap[_item->_data._node[1]] - << ";" << - _item->_data._part << "\n" ; + << ";" << + _item->_data._part << "\n" ; } } } - + if (_rdel._euclidean_rdel_2d. _tset.count() > +0) { - /*-------------------------- write TRIA3 data */ - _file << "TRIA3=" << + /*-------------------------- write TRIA3 data */ + _file << "TRIA3=" << _rdel._euclidean_rdel_2d. _tset.count() << "\n" ; - + for (auto _iter = _rdel. _euclidean_rdel_2d._tset._lptr.head(); _iter != _rdel. @@ -245,28 +250,28 @@ ++_iter ) { if ( *_iter == nullptr) continue ; - + for (auto _item = *_iter ; _item != nullptr; _item = _item->_next ) { - _file << + _file << _nmap[_item->_data._node[0]] - << ";" << + << ";" << _nmap[_item->_data._node[1]] - << ";" << + << ";" << _nmap[_item->_data._node[2]] - << ";" << + << ";" << _item->_data._part << "\n" ; } } } - + } else if (_rdel._ndim == +3 && - _rdel._kind == - jmsh_kind::euclidean_mesh) + _rdel._kind == + jmsh_kind::euclidean_mesh) { /*-------------------------- save 3-dim. mesh */ _file << "# " << _name << ".msh" @@ -274,14 +279,14 @@ _file << __JGSWVSTR "\n" ; _file << "MSHID=2;EUCLIDEAN-MESH \n" ; _file << "NDIMS=3 \n" ; - + _file << std::scientific ; - _file << + _file << std::setprecision(16); - + /*------------ index mapping for active nodes */ _nmap.set_count(_rdel. - _euclidean_rdel_3d._tria._nset.count() , + _euclidean_rdel_3d._tria._nset.count() , containers::tight_alloc, -1) ; for (auto _iter = _rdel. @@ -291,13 +296,15 @@ ++_iter ) { if ( *_iter == nullptr) continue ; - + for (auto _item = *_iter ; _item != nullptr; _item = _item->_next ) { - _nmap[_item->_data._node[0]]=1 ; - _nmap[_item->_data._node[1]]=1 ; + _nmap[_item-> + _data._node[0]] = 1 ; + _nmap[_item-> + _data._node[1]] = 1 ; } } @@ -308,14 +315,17 @@ ++_iter ) { if ( *_iter == nullptr) continue ; - + for (auto _item = *_iter ; _item != nullptr; _item = _item->_next ) { - _nmap[_item->_data._node[0]]=1 ; - _nmap[_item->_data._node[1]]=1 ; - _nmap[_item->_data._node[2]]=1 ; + _nmap[_item-> + _data._node[0]] = 1 ; + _nmap[_item-> + _data._node[1]] = 1 ; + _nmap[_item-> + _data._node[2]] = 1 ; } } @@ -326,15 +336,19 @@ ++_iter ) { if ( *_iter == nullptr) continue ; - + for (auto _item = *_iter ; _item != nullptr; _item = _item->_next ) { - _nmap[_item->_data._node[0]]=1 ; - _nmap[_item->_data._node[1]]=1 ; - _nmap[_item->_data._node[2]]=1 ; - _nmap[_item->_data._node[3]]=1 ; + _nmap[_item-> + _data._node[0]] = 1 ; + _nmap[_item-> + _data._node[1]] = 1 ; + _nmap[_item-> + _data._node[2]] = 1 ; + _nmap[_item-> + _data._node[3]] = 1 ; } } @@ -352,11 +366,11 @@ if (_rdel._euclidean_rdel_3d. _tria._nset.count() > 0) { - /*-------------------------- write POINT data */ + /*-------------------------- write POINT data */ _file << "POINT=" << _last << "\n" ; - + iptr_type _npos = +0 ; - + for (auto _iter = _rdel. _euclidean_rdel_3d._tria._nset.head(); _iter != _rdel. @@ -373,18 +387,18 @@ } } } - + if (_jcfg._iter_opts.dual() ) { if (_rdel._euclidean_rdel_3d. _tria._nset.count() > 0) { - /*-------------------------- write POWER data */ - _file << "POWER=" + /*-------------------------- write POWER data */ + _file << "POWER=" << _last << ";1" << "\n" ; - + iptr_type _npos = +0 ; - + for (auto _iter = _rdel. _euclidean_rdel_3d._tria._nset.head(); _iter != _rdel. @@ -399,15 +413,15 @@ } } } - + if (_rdel._euclidean_rdel_3d. _eset.count() > +0) { - /*-------------------------- write EDGE2 data */ - _file << "EDGE2=" << + /*-------------------------- write EDGE2 data */ + _file << "EDGE2=" << _rdel._euclidean_rdel_3d. _eset.count() << "\n" ; - + for (auto _iter = _rdel. _euclidean_rdel_3d._eset._lptr.head(); _iter != _rdel. @@ -415,29 +429,29 @@ ++_iter ) { if ( *_iter == nullptr) continue ; - + for (auto _item = *_iter ; _item != nullptr; _item = _item->_next ) { - _file << + _file << _nmap[_item->_data._node[0]] - << ";" << + << ";" << _nmap[_item->_data._node[1]] - << ";" << + << ";" << _item->_data._part << "\n" ; } } } - + if (_rdel._euclidean_rdel_3d. _fset.count() > +0) { - /*-------------------------- write TRIA3 data */ - _file << "TRIA3=" << + /*-------------------------- write TRIA3 data */ + _file << "TRIA3=" << _rdel._euclidean_rdel_3d. _fset.count() << "\n" ; - + for (auto _iter = _rdel. _euclidean_rdel_3d._fset._lptr.head(); _iter != _rdel. @@ -445,31 +459,31 @@ ++_iter ) { if ( *_iter == nullptr) continue ; - + for (auto _item = *_iter ; _item != nullptr; _item = _item->_next ) { - _file << + _file << _nmap[_item->_data._node[0]] - << ";" << + << ";" << _nmap[_item->_data._node[1]] - << ";" << + << ";" << _nmap[_item->_data._node[2]] - << ";" << + << ";" << _item->_data._part << "\n" ; } } } - + if (_rdel._euclidean_rdel_3d. _tset.count() > +0) { - /*-------------------------- write TRIA4 data */ - _file << "TRIA4=" << + /*-------------------------- write TRIA4 data */ + _file << "TRIA4=" << _rdel._euclidean_rdel_3d. _tset.count() << "\n" ; - + for (auto _iter = _rdel. _euclidean_rdel_3d._tset._lptr.head(); _iter != _rdel. @@ -477,33 +491,33 @@ ++_iter ) { if ( *_iter == nullptr) continue ; - + for (auto _item = *_iter ; _item != nullptr; _item = _item->_next ) { - _file << + _file << _nmap[_item->_data._node[0]] - << ";" << + << ";" << _nmap[_item->_data._node[1]] - << ";" << + << ";" << _nmap[_item->_data._node[2]] - << ";" << + << ";" << _nmap[_item->_data._node[3]] - << ";" << + << ";" << _item->_data._part << "\n" ; } } } - + } } else { - _errv = __file_not_located ; + _errv = __file_not_created ; } - + _file.close(); } @@ -514,79 +528,76 @@ return ( _errv ) ; } - + /* -------------------------------------------------------- - * SAVE-TRIA: save *.JMSH output file. + * SAVE-RDEL: save MSH_t output data. -------------------------------------------------------- */ - + template < typename jlog_data > - __normal_call iptr_type save_tria ( + __normal_call iptr_type save_rdel ( jcfg_data &_jcfg , jlog_data &_jlog , - rdel_data &_rdel + rdel_data &_rdel , + jigsaw_msh_t &_mmsh ) { iptr_type _errv = __no_error ; - __unreferenced(_jlog) ; - try { containers::array _nmap; - - std::ofstream _file ; - std::string _path ; - std::string _name ; - std::string _fext ; - file_part( - _jcfg._tria_file, - _path, _name, _fext); + __unreferenced (_jlog) ; + __unreferenced (_jcfg) ; - _file.open( - _jcfg._tria_file, - std::ofstream::out ); - - if (_file.is_open()) - { - if (_rdel._ndim == +2 && + if (_rdel._ndim == +2 && // save 2-dim. mesh _rdel._kind == jmsh_kind::euclidean_mesh) { - /*-------------------------- save 2-dim. mesh */ - _file << "# " << _name << ".msh" - << "; created by " ; - _file << __JGSWVSTR "\n" ; - _file << "MSHID=2;EUCLIDEAN-MESH \n" ; - _file << "NDIMS=2 \n" ; - - _file << std::scientific ; - _file << - std::setprecision(16); + _mmsh._flags = JIGSAW_EUCLIDEAN_MESH ; /*------------ index mapping for active nodes */ _nmap.set_count(_rdel. - _euclidean_rdel_2d._tria._nset.count() , + _euclidean_rdel_2d._tria._nset.count() , containers::tight_alloc, -1) ; - iptr_type _ntri = +0; for (auto _iter = _rdel. - _euclidean_rdel_2d._tria._tset.head(); + _euclidean_rdel_2d._eset._lptr.head(); _iter != _rdel. - _euclidean_rdel_2d._tria._tset.tend(); + _euclidean_rdel_2d._eset._lptr.tend(); ++_iter ) { - if (_iter->mark() < +0) continue ; - - _ntri += +1 ; - - _nmap[_iter->node(0)]=1; - _nmap[_iter->node(1)]=1; - _nmap[_iter->node(2)]=1; + if ( *_iter == nullptr) continue ; + + for (auto _item = *_iter ; + _item != nullptr; + _item = _item->_next ) + { + _nmap[_item->_data._node[0]]=1 ; + _nmap[_item->_data._node[1]]=1 ; + } + } + + for (auto _iter = _rdel. + _euclidean_rdel_2d._tset._lptr.head(); + _iter != _rdel. + _euclidean_rdel_2d._tset._lptr.tend(); + ++_iter ) + { + if ( *_iter == nullptr) continue ; + + for (auto _item = *_iter ; + _item != nullptr; + _item = _item->_next ) + { + _nmap[_item->_data._node[0]]=1 ; + _nmap[_item->_data._node[1]]=1 ; + _nmap[_item->_data._node[2]]=1 ; + } } iptr_type _last = +0; @@ -603,10 +614,15 @@ if (_rdel._euclidean_rdel_2d. _tria._nset.count() > 0) { - /*-------------------------- write POINT data */ - _file << "POINT=" << _last << "\n" ; - + /*-------------------------- write POINT data */ + jigsaw_alloc_vert2 ( + &_mmsh._vert2, _last) ; + + jigsaw_alloc_reals ( + &_mmsh._power, _last) ; + iptr_type _npos = +0 ; + iptr_type _nout = +0 ; for (auto _iter = _rdel. _euclidean_rdel_2d._tria._nset.head(); _iter != _rdel. @@ -614,374 +630,138 @@ ++_iter, ++_npos) { if (_iter->mark() >= 0 && - _nmap[_npos ] >= 0) + _nmap[_npos ] >= 0 ) { - _file << _iter->pval(0) << ";" - << _iter->pval(1) << ";" - << +0 << "\n" ; + _mmsh._vert2._data[_nout]. + _ppos[0] = _iter->pval(0) ; + _mmsh._vert2._data[_nout]. + _ppos[1] = _iter->pval(1) ; + + _mmsh._vert2. + _data[_nout]._itag = 0 ; + + _mmsh._power. + _data[_nout] = (real_type)+0. ; + + _nout = _nout + 1 ; } } + + _rdel._euclidean_rdel_2d._tria. + clear(containers::tight_alloc); + } - + if (_rdel._euclidean_rdel_2d. - _tria._tset.count() > 0) + _eset.count() > +0) { - /*-------------------------- write TRIA3 data */ - _file << "TRIA3=" << _ntri << "\n" ; - + /*-------------------------- write EDGE2 data */ + jigsaw_alloc_edge2 ( + &_mmsh._edge2,_rdel. + _euclidean_rdel_2d._eset.count()) ; + + iptr_type _eout = +0 ; for (auto _iter = _rdel. - _euclidean_rdel_2d._tria._tset.head(); + _euclidean_rdel_2d._eset._lptr.head(); _iter != _rdel. - _euclidean_rdel_2d._tria._tset.tend(); + _euclidean_rdel_2d._eset._lptr.tend(); ++_iter ) { - if (_iter->mark() < +0) continue ; - - _file << - _nmap[_iter->node(0)] << ";" << - _nmap[_iter->node(1)] << ";" << - _nmap[_iter->node(2)] << ";" << - +0 << "\n" ; + if ( *_iter == nullptr) continue ; + + for (auto _item = *_iter ; + _item != nullptr; + _item = _item->_next ) + { + _mmsh._edge2._data[_eout]. + _node[0] = + _nmap[_item->_data._node[0]] ; + _mmsh._edge2._data[_eout]. + _node[1] = + _nmap[_item->_data._node[1]] ; + + _mmsh._edge2._data[_eout]. + _itag = _item->_data._part ; + + _eout = _eout + 1 ; + } + } + + _rdel._euclidean_rdel_2d._eset. + clear(containers::tight_alloc) ; + + } + + if (_rdel._euclidean_rdel_2d. + _tset.count() > +0) + { + /*-------------------------- write TRIA3 data */ + jigsaw_alloc_tria3 ( + &_mmsh._tria3,_rdel. + _euclidean_rdel_2d._tset.count()) ; + + iptr_type _tout = +0 ; + for (auto _iter = _rdel. + _euclidean_rdel_2d._tset._lptr.head(); + _iter != _rdel. + _euclidean_rdel_2d._tset._lptr.tend(); + ++_iter ) + { + if ( *_iter == nullptr) continue ; + + for (auto _item = *_iter ; + _item != nullptr; + _item = _item->_next ) + { + _mmsh._tria3._data[_tout]. + _node[0] = + _nmap[_item->_data._node[0]] ; + _mmsh._tria3._data[_tout]. + _node[1] = + _nmap[_item->_data._node[1]] ; + _mmsh._tria3._data[_tout]. + _node[2] = + _nmap[_item->_data._node[2]] ; + + _mmsh._tria3._data[_tout]. + _itag = _item->_data._part ; + + _tout = _tout + 1 ; + } } + + _rdel._euclidean_rdel_2d._tset. + clear(containers::tight_alloc) ; + } - + } else - if (_rdel._ndim == +3 && - _rdel._kind == - jmsh_kind::euclidean_mesh) + if (_rdel._ndim == +3 && // save 3-dim. mesh + _rdel._kind == + jmsh_kind::euclidean_mesh) { - /*-------------------------- save 3-dim. mesh */ - _file << "# " << _name << ".msh" - << "; created by " ; - _file << __JGSWVSTR "\n" ; - _file << "MSHID=2;EUCLIDEAN-MESH \n" ; - _file << "NDIMS=3 \n" ; - - _file << std::scientific ; - _file << - std::setprecision(16); - + _mmsh._flags = JIGSAW_EUCLIDEAN_MESH ; + /*------------ index mapping for active nodes */ _nmap.set_count(_rdel. - _euclidean_rdel_3d._tria._nset.count() , + _euclidean_rdel_3d._tria._nset.count() , containers::tight_alloc, -1) ; - iptr_type _ntri = +0; for (auto _iter = _rdel. - _euclidean_rdel_3d._tria._tset.head(); + _euclidean_rdel_3d._eset._lptr.head(); _iter != _rdel. - _euclidean_rdel_3d._tria._tset.tend(); + _euclidean_rdel_3d._eset._lptr.tend(); ++_iter ) { - if (_iter->mark() < +0) continue ; - - _ntri += +1 ; - - _nmap[_iter->node(0)]=1; - _nmap[_iter->node(1)]=1; - _nmap[_iter->node(2)]=1; - _nmap[_iter->node(3)]=1; - } + if ( *_iter == nullptr) continue ; - iptr_type _last = +0; - for (auto _iter = _nmap.head() ; - _iter != _nmap.tend() ; - ++_iter ) - { - if ( *_iter >= +0) + for (auto _item = *_iter ; + _item != nullptr; + _item = _item->_next ) { - *_iter = _last ++ ; - } - } - - if (_rdel._euclidean_rdel_3d. - _tria._nset.count() > 0) - { - /*-------------------------- write POINT data */ - _file << "POINT=" << _last << "\n" ; - - iptr_type _npos = +0 ; - for (auto _iter = _rdel. - _euclidean_rdel_3d._tria._nset.head(); - _iter != _rdel. - _euclidean_rdel_3d._tria._nset.tend(); - ++_iter, ++_npos) - { - if (_iter->mark() >= 0 && - _nmap[_npos ] >= 0) - { - _file << _iter->pval(0) << ";" - << _iter->pval(1) << ";" - << _iter->pval(2) << ";" - << +0 << "\n" ; - } - } - } - - if (_rdel._euclidean_rdel_3d. - _tria._tset.count() > 0) - { - /*-------------------------- write TRIA3 data */ - _file << "TRIA4=" << _ntri << "\n" ; - - for (auto _iter = _rdel. - _euclidean_rdel_3d._tria._tset.head(); - _iter != _rdel. - _euclidean_rdel_3d._tria._tset.tend(); - ++_iter ) - { - if (_iter->mark() < +0) continue ; - - _file << - _nmap[_iter->node(0)] << ";" << - _nmap[_iter->node(1)] << ";" << - _nmap[_iter->node(2)] << ";" << - _nmap[_iter->node(3)] << ";" << - +0 << "\n" ; - } - } - - } - - } - else - { - _errv = __file_not_located ; - } - - _file.close(); - - } - catch (...) - { - _errv = __unknown_error ; - } - - return ( _errv ) ; - } - - /* - -------------------------------------------------------- - * SAVE-MSHT: save MSH_T output data. - -------------------------------------------------------- - */ - - template < - typename jlog_data - > - __normal_call iptr_type save_msht ( - jcfg_data &_jcfg , - jlog_data &_jlog , - rdel_data &_rdel , - jigsaw_msh_t &_mmsh - ) - { - iptr_type _errv = __no_error ; - - try - { - containers::array _nmap; - - __unreferenced (_jlog) ; - __unreferenced (_jcfg) ; - - if (_rdel._ndim == +2 && // save 2-dim. mesh - _rdel._kind == - jmsh_kind::euclidean_mesh) - { - _mmsh._flags = JIGSAW_EUCLIDEAN_MESH ; - - /*------------ index mapping for active nodes */ - _nmap.set_count(_rdel. - _euclidean_rdel_2d._tria._nset.count() , - containers::tight_alloc, -1) ; - - for (auto _iter = _rdel. - _euclidean_rdel_2d._eset._lptr.head(); - _iter != _rdel. - _euclidean_rdel_2d._eset._lptr.tend(); - ++_iter ) - { - if ( *_iter == nullptr) continue ; - - for (auto _item = *_iter ; - _item != nullptr; - _item = _item->_next ) - { - _nmap[_item->_data._node[0]]=1 ; - _nmap[_item->_data._node[1]]=1 ; - } - } - - for (auto _iter = _rdel. - _euclidean_rdel_2d._tset._lptr.head(); - _iter != _rdel. - _euclidean_rdel_2d._tset._lptr.tend(); - ++_iter ) - { - if ( *_iter == nullptr) continue ; - - for (auto _item = *_iter ; - _item != nullptr; - _item = _item->_next ) - { - _nmap[_item->_data._node[0]]=1 ; - _nmap[_item->_data._node[1]]=1 ; - _nmap[_item->_data._node[2]]=1 ; - } - } - - iptr_type _last = +0; - for (auto _iter = _nmap.head() ; - _iter != _nmap.tend() ; - ++_iter ) - { - if ( *_iter >= +0) - { - *_iter = _last ++ ; - } - } - - if (_rdel._euclidean_rdel_2d. - _tria._nset.count() > 0) - { - /*-------------------------- write POINT data */ - jigsaw_alloc_vert2 ( - &_mmsh._vert2, _last) ; - - jigsaw_alloc_reals ( - &_mmsh._power, _last) ; - - iptr_type _npos = +0 ; - iptr_type _nout = +0 ; - for (auto _iter = _rdel. - _euclidean_rdel_2d._tria._nset.head(); - _iter != _rdel. - _euclidean_rdel_2d._tria._nset.tend(); - ++_iter, ++_npos) - { - if (_iter->mark() >= 0 && - _nmap[_npos ] >= 0 ) - { - _mmsh._vert2._data[_nout]. - _ppos[0] = _iter->pval(0) ; - _mmsh._vert2._data[_nout]. - _ppos[1] = _iter->pval(1) ; - - _mmsh._vert2. - _data[_nout]._itag = 0 ; - - _mmsh._power. - _data[_nout] = (real_type)+0. ; - - _nout = _nout + 1 ; - } - } - } - - if (_rdel._euclidean_rdel_2d. - _eset.count() > +0) - { - /*-------------------------- write EDGE2 data */ - jigsaw_alloc_edge2 ( - &_mmsh._edge2,_rdel. - _euclidean_rdel_2d._eset.count()) ; - - iptr_type _eout = +0 ; - for (auto _iter = _rdel. - _euclidean_rdel_2d._eset._lptr.head(); - _iter != _rdel. - _euclidean_rdel_2d._eset._lptr.tend(); - ++_iter ) - { - if ( *_iter == nullptr) continue ; - - for (auto _item = *_iter ; - _item != nullptr; - _item = _item->_next ) - { - _mmsh._edge2._data[_eout]. - _node[0] = - _nmap[_item->_data._node[0]] ; - _mmsh._edge2._data[_eout]. - _node[1] = - _nmap[_item->_data._node[1]] ; - - _mmsh._edge2._data[_eout]. - _itag = _item->_data._part ; - - _eout = _eout + 1 ; - } - } - } - - if (_rdel._euclidean_rdel_2d. - _tset.count() > +0) - { - /*-------------------------- write TRIA3 data */ - jigsaw_alloc_tria3 ( - &_mmsh._tria3,_rdel. - _euclidean_rdel_2d._tset.count()) ; - - iptr_type _tout = +0 ; - for (auto _iter = _rdel. - _euclidean_rdel_2d._tset._lptr.head(); - _iter != _rdel. - _euclidean_rdel_2d._tset._lptr.tend(); - ++_iter ) - { - if ( *_iter == nullptr) continue ; - - for (auto _item = *_iter ; - _item != nullptr; - _item = _item->_next ) - { - _mmsh._tria3._data[_tout]. - _node[0] = - _nmap[_item->_data._node[0]] ; - _mmsh._tria3._data[_tout]. - _node[1] = - _nmap[_item->_data._node[1]] ; - _mmsh._tria3._data[_tout]. - _node[2] = - _nmap[_item->_data._node[2]] ; - - _mmsh._tria3._data[_tout]. - _itag = _item->_data._part ; - - _tout = _tout + 1 ; - } - } - } - - } - else - if (_rdel._ndim == +3 && // save 3-dim. mesh - _rdel._kind == - jmsh_kind::euclidean_mesh) - { - _mmsh._flags = JIGSAW_EUCLIDEAN_MESH ; - - /*------------ index mapping for active nodes */ - _nmap.set_count(_rdel. - _euclidean_rdel_3d._tria._nset.count() , - containers::tight_alloc, -1) ; - - for (auto _iter = _rdel. - _euclidean_rdel_3d._eset._lptr.head(); - _iter != _rdel. - _euclidean_rdel_3d._eset._lptr.tend(); - ++_iter ) - { - if ( *_iter == nullptr) continue ; - - for (auto _item = *_iter ; - _item != nullptr; - _item = _item->_next ) - { - _nmap[_item->_data._node[0]]=1 ; - _nmap[_item->_data._node[1]]=1 ; + _nmap[_item->_data._node[0]]=1 ; + _nmap[_item->_data._node[1]]=1 ; } } @@ -992,14 +772,14 @@ ++_iter ) { if ( *_iter == nullptr) continue ; - + for (auto _item = *_iter ; _item != nullptr; _item = _item->_next ) { _nmap[_item->_data._node[0]]=1 ; _nmap[_item->_data._node[1]]=1 ; - _nmap[_item->_data._node[2]]=1 ; + _nmap[_item->_data._node[2]]=1 ; } } @@ -1010,15 +790,15 @@ ++_iter ) { if ( *_iter == nullptr) continue ; - + for (auto _item = *_iter ; _item != nullptr; _item = _item->_next ) { _nmap[_item->_data._node[0]]=1 ; _nmap[_item->_data._node[1]]=1 ; - _nmap[_item->_data._node[2]]=1 ; - _nmap[_item->_data._node[3]]=1 ; + _nmap[_item->_data._node[2]]=1 ; + _nmap[_item->_data._node[3]]=1 ; } } @@ -1036,13 +816,13 @@ if (_rdel._euclidean_rdel_3d. _tria._nset.count() > 0) { - /*-------------------------- write POINT data */ + /*-------------------------- write POINT data */ jigsaw_alloc_vert3 ( &_mmsh._vert3 , _last); - + jigsaw_alloc_reals ( &_mmsh._power , _last); - + iptr_type _npos = +0 ; iptr_type _nout = +0 ; for (auto _iter = _rdel. @@ -1060,26 +840,31 @@ _ppos[1] = _iter->pval(1) ; _mmsh._vert3._data[_nout]. _ppos[2] = _iter->pval(2) ; - + _mmsh._vert3. _data[_nout]._itag = 0 ; - + _mmsh._power. _data[_nout] = (real_type)+0. ; - + _nout = _nout + 1 ; } } + + _rdel._euclidean_rdel_3d._tria. + clear(containers::tight_alloc); + } + if (_rdel._euclidean_rdel_3d. _eset.count() > +0) { - /*-------------------------- write EDGE2 data */ + /*-------------------------- write EDGE2 data */ jigsaw_alloc_edge2 ( &_mmsh._edge2,_rdel. _euclidean_rdel_3d._eset.count()) ; - - iptr_type _eout = +0 ; + + iptr_type _eout = +0 ; for (auto _iter = _rdel. _euclidean_rdel_3d._eset._lptr.head(); _iter != _rdel. @@ -1087,35 +872,39 @@ ++_iter ) { if ( *_iter == nullptr) continue ; - + for (auto _item = *_iter ; _item != nullptr; _item = _item->_next ) { _mmsh._edge2._data[_eout]. - _node[0] = + _node[0] = _nmap[_item->_data._node[0]] ; _mmsh._edge2._data[_eout]. - _node[1] = + _node[1] = _nmap[_item->_data._node[1]] ; - + _mmsh._edge2._data[_eout]. _itag = _item->_data._part ; - + _eout = _eout + 1 ; } } + + _rdel._euclidean_rdel_3d._eset. + clear(containers::tight_alloc) ; + } - + if (_rdel._euclidean_rdel_3d. _fset.count() > +0) { - /*-------------------------- write TRIA3 data */ + /*-------------------------- write TRIA3 data */ jigsaw_alloc_tria3 ( &_mmsh._tria3,_rdel. _euclidean_rdel_3d._fset.count()) ; - - iptr_type _fout = +0 ; + + iptr_type _fout = +0 ; for (auto _iter = _rdel. _euclidean_rdel_3d._fset._lptr.head(); _iter != _rdel. @@ -1123,37 +912,41 @@ ++_iter ) { if ( *_iter == nullptr) continue ; - + for (auto _item = *_iter ; _item != nullptr; _item = _item->_next ) { _mmsh._tria3._data[_fout]. - _node[0] = + _node[0] = _nmap[_item->_data._node[0]] ; _mmsh._tria3._data[_fout]. - _node[1] = + _node[1] = _nmap[_item->_data._node[1]] ; _mmsh._tria3._data[_fout]. - _node[2] = + _node[2] = _nmap[_item->_data._node[2]] ; - + _mmsh._tria3._data[_fout]. _itag = _item->_data._part ; - - _fout = _fout + 1 ; + + _fout = _fout + 1 ; } } + + _rdel._euclidean_rdel_3d._fset. + clear(containers::tight_alloc) ; + } - + if (_rdel._euclidean_rdel_3d. _tset.count() > +0) { - /*-------------------------- write TRIA4 data */ + /*-------------------------- write TRIA4 data */ jigsaw_alloc_tria4 ( &_mmsh._tria4,_rdel. _euclidean_rdel_3d._tset.count()) ; - + iptr_type _tout = +0 ; for (auto _iter = _rdel. _euclidean_rdel_3d._tset._lptr.head(); @@ -1162,34 +955,38 @@ ++_iter ) { if ( *_iter == nullptr) continue ; - + for (auto _item = *_iter ; _item != nullptr; _item = _item->_next ) { _mmsh._tria4._data[_tout]. - _node[0] = + _node[0] = _nmap[_item->_data._node[0]] ; _mmsh._tria4._data[_tout]. - _node[1] = + _node[1] = _nmap[_item->_data._node[1]] ; _mmsh._tria4._data[_tout]. - _node[2] = + _node[2] = _nmap[_item->_data._node[2]] ; _mmsh._tria4._data[_tout]. - _node[3] = + _node[3] = _nmap[_item->_data._node[3]] ; - + _mmsh._tria4._data[_tout]. _itag = _item->_data._part ; - - _tout = _tout + 1 ; + + _tout = _tout + 1 ; } } + + _rdel._euclidean_rdel_3d._tset. + clear(containers::tight_alloc) ; + } - + } - + } catch (...) { @@ -1198,20 +995,20 @@ return ( _errv ) ; } - + /* -------------------------------------------------------- - * SAVE-JMSH: save *.JMSH output file. + * SAVE-TRIA: save *.MSH output file. -------------------------------------------------------- */ - + template < typename jlog_data > - __normal_call iptr_type save_jmsh ( + __normal_call iptr_type save_tria ( jcfg_data &_jcfg , jlog_data &_jlog , - mesh_data &_mesh + rdel_data &_rdel ) { iptr_type _errv = __no_error ; @@ -1221,98 +1018,80 @@ try { containers::array _nmap; - + std::ofstream _file ; std::string _path ; std::string _name ; - std::string _fext ; + std::string _fext ; file_part( - _jcfg._mesh_file, + _jcfg._tria_file, _path, _name, _fext); _file.open( - _jcfg._mesh_file, + _jcfg._tria_file, std::ofstream::out ); - + if (_file.is_open()) { - if (_mesh._ndim == +2 && - _mesh._kind == + if (_rdel._ndim == +2 && + _rdel._kind == jmsh_kind::euclidean_mesh) { /*-------------------------- save 2-dim. mesh */ _file << "# " << _name << ".msh" << "; created by " ; _file << __JGSWVSTR "\n" ; - _file << "MSHID=3;EUCLIDEAN-MESH \n" ; + _file << "MSHID=2;EUCLIDEAN-MESH \n" ; _file << "NDIMS=2 \n" ; _file << std::scientific ; - _file << + _file << std::setprecision(16); /*------------ index mapping for active nodes */ - _nmap.set_count(_mesh. - _euclidean_mesh_2d._mesh._set1.count() , + _nmap.set_count(_rdel. + _euclidean_rdel_2d._tria._nset.count() , containers::tight_alloc, -1) ; - iptr_type _nnum = +0 ; - iptr_type _enum = +0 ; - iptr_type _tnum = +0 ; - - for (auto _iter = _mesh. - _euclidean_mesh_2d._mesh._set2.head() ; - _iter != _mesh. - _euclidean_mesh_2d._mesh._set2.tend() ; + iptr_type _ntri = +0; + for (auto _iter = _rdel. + _euclidean_rdel_2d._tria._tset.head(); + _iter != _rdel. + _euclidean_rdel_2d._tria._tset.tend(); ++_iter ) { - if (_iter->mark() >= +0 && - _iter->self() >= +1 ) - { - _nmap[_iter->node(0)] = +1 ; - _nmap[_iter->node(1)] = +1 ; - _enum += +1 ; - } - } + if (_iter->mark() < +0) continue ; - for (auto _iter = _mesh. - _euclidean_mesh_2d._mesh._set3.head() ; - _iter != _mesh. - _euclidean_mesh_2d._mesh._set3.tend() ; - ++_iter ) - { - if (_iter->mark() >= +0 && - _iter->self() >= +1 ) - { - _nmap[_iter->node(0)] = +1 ; - _nmap[_iter->node(1)] = +1 ; - _nmap[_iter->node(2)] = +1 ; - _tnum += +1 ; - } + _ntri += +1 ; + + _nmap[_iter->node(0)]=1; + _nmap[_iter->node(1)]=1; + _nmap[_iter->node(2)]=1; } - for (auto _iter = _nmap.head(); - _iter != _nmap.tend(); + iptr_type _last = +0; + for (auto _iter = _nmap.head() ; + _iter != _nmap.tend() ; ++_iter ) { if ( *_iter >= +0) { - *_iter = _nnum ++ ; + *_iter = _last ++ ; } } - if (_nnum > +0) + if (_rdel._euclidean_rdel_2d. + _tria._nset.count() > 0) { - /*-------------------------- write POINT data */ - _file << "POINT=" << _nnum << "\n" ; - - iptr_type _npos = +0; - - for (auto _iter = _mesh. - _euclidean_mesh_2d._mesh._set1.head() ; - _iter != _mesh. - _euclidean_mesh_2d._mesh._set1.tend() ; + /*-------------------------- write POINT data */ + _file << "POINT=" << _last << "\n" ; + + iptr_type _npos = +0 ; + for (auto _iter = _rdel. + _euclidean_rdel_2d._tria._nset.head(); + _iter != _rdel. + _euclidean_rdel_2d._tria._nset.tend(); ++_iter, ++_npos) { if (_iter->mark() >= 0 && @@ -1324,178 +1103,90 @@ } } } - - if (_nnum > +0) - { - /*-------------------------- write POWER data */ - if (_jcfg._iter_opts.dual() ) - { - _file << "POWER=" - << _nnum << ";1" << "\n" ; - - iptr_type _npos = +0; - - for (auto _iter = _mesh. - _euclidean_mesh_2d._mesh._set1.head() ; - _iter != _mesh. - _euclidean_mesh_2d._mesh._set1.tend() ; - ++_iter, ++_npos) - { - if (_iter->mark() >= 0 && - _nmap[_npos ] >= 0) - { - _file << _iter->pval(2) << "\n" ; - } - } - } - } - - if (_enum > +0) - { - /*-------------------------- write EDGE2 data */ - _file << "EDGE2=" << _enum << "\n" ; - - for (auto _iter = _mesh. - _euclidean_mesh_2d._mesh._set2.head() ; - _iter != _mesh. - _euclidean_mesh_2d._mesh._set2.tend() ; - ++_iter ) - { - if (_iter->mark() >= 0 && - _iter->self() >= 1 ) - { - _file << - _nmap[_iter->node(0)] << ";" - << - _nmap[_iter->node(1)] << ";" - << - _iter->itag() << "\n" ; - } - } - } - - if (_tnum > +0) + + if (_rdel._euclidean_rdel_2d. + _tria._tset.count() > 0) { - /*-------------------------- write TRIA3 data */ - _file << "TRIA3=" << _tnum << "\n" ; - - for (auto _iter = _mesh. - _euclidean_mesh_2d._mesh._set3.head() ; - _iter != _mesh. - _euclidean_mesh_2d._mesh._set3.tend() ; + /*-------------------------- write TRIA3 data */ + _file << "TRIA3=" << _ntri << "\n" ; + + for (auto _iter = _rdel. + _euclidean_rdel_2d._tria._tset.head(); + _iter != _rdel. + _euclidean_rdel_2d._tria._tset.tend(); ++_iter ) { - if (_iter->mark() >= 0 && - _iter->self() >= 1 ) - { - _file << - _nmap[_iter->node(0)] << ";" - << - _nmap[_iter->node(1)] << ";" - << - _nmap[_iter->node(2)] << ";" - << - _iter->itag() << "\n" ; - } + if (_iter->mark() < +0) continue ; + + _file << + _nmap[_iter->node(0)] << ";" << + _nmap[_iter->node(1)] << ";" << + _nmap[_iter->node(2)] << ";" << + +0 << "\n" ; } } - + } else - if (_mesh._ndim == +3 && - _mesh._kind == + if (_rdel._ndim == +3 && + _rdel._kind == jmsh_kind::euclidean_mesh) { /*-------------------------- save 3-dim. mesh */ - _file << "# " << _name << ".msh" + _file << "# " << _name << ".msh" << "; created by " ; _file << __JGSWVSTR "\n" ; - _file << "MSHID=3;EUCLIDEAN-MESH \n" ; + _file << "MSHID=2;EUCLIDEAN-MESH \n" ; _file << "NDIMS=3 \n" ; - + _file << std::scientific ; - _file << + _file << std::setprecision(16); /*------------ index mapping for active nodes */ - _nmap.set_count(_mesh. - _euclidean_mesh_3d._mesh._set1.count() , + _nmap.set_count(_rdel. + _euclidean_rdel_3d._tria._nset.count() , containers::tight_alloc, -1) ; - iptr_type _nnum = +0 ; - iptr_type _enum = +0 ; - iptr_type _fnum = +0 ; - iptr_type _tnum = +0 ; - - for (auto _iter = _mesh. - _euclidean_mesh_3d._mesh._set2.head() ; - _iter != _mesh. - _euclidean_mesh_3d._mesh._set2.tend() ; + iptr_type _ntri = +0; + for (auto _iter = _rdel. + _euclidean_rdel_3d._tria._tset.head(); + _iter != _rdel. + _euclidean_rdel_3d._tria._tset.tend(); ++_iter ) { - if (_iter->mark() >= +0 && - _iter->self() >= +1 ) - { - _nmap[_iter->node(0)] = +1 ; - _nmap[_iter->node(1)] = +1 ; - _enum += +1 ; - } - } + if (_iter->mark() < +0) continue ; - for (auto _iter = _mesh. - _euclidean_mesh_3d._mesh._set3.head() ; - _iter != _mesh. - _euclidean_mesh_3d._mesh._set3.tend() ; - ++_iter ) - { - if (_iter->mark() >= +0 && - _iter->self() >= +1 ) - { - _nmap[_iter->node(0)] = +1 ; - _nmap[_iter->node(1)] = +1 ; - _nmap[_iter->node(2)] = +1 ; - _fnum += +1 ; - } - } - - for (auto _iter = _mesh. - _euclidean_mesh_3d._mesh._set4.head() ; - _iter != _mesh. - _euclidean_mesh_3d._mesh._set4.tend() ; - ++_iter ) - { - if (_iter->mark() >= +0 && - _iter->self() >= +1 ) - { - _nmap[_iter->node(0)] = +1 ; - _nmap[_iter->node(1)] = +1 ; - _nmap[_iter->node(2)] = +1 ; - _nmap[_iter->node(3)] = +1 ; - _tnum += +1 ; - } + _ntri += +1 ; + + _nmap[_iter->node(0)]=1; + _nmap[_iter->node(1)]=1; + _nmap[_iter->node(2)]=1; + _nmap[_iter->node(3)]=1; } - for (auto _iter = _nmap.head(); - _iter != _nmap.tend(); + iptr_type _last = +0; + for (auto _iter = _nmap.head() ; + _iter != _nmap.tend() ; ++_iter ) { if ( *_iter >= +0) { - *_iter = _nnum ++ ; + *_iter = _last ++ ; } - } - - if (_nnum > +0) + } + + if (_rdel._euclidean_rdel_3d. + _tria._nset.count() > 0) { - /*-------------------------- write POINT data */ - _file << "POINT=" << _nnum << "\n" ; - - iptr_type _npos = +0; - - for (auto _iter = _mesh. - _euclidean_mesh_3d._mesh._set1.head() ; - _iter != _mesh. - _euclidean_mesh_3d._mesh._set1.tend() ; + /*-------------------------- write POINT data */ + _file << "POINT=" << _last << "\n" ; + + iptr_type _npos = +0 ; + for (auto _iter = _rdel. + _euclidean_rdel_3d._tria._nset.head(); + _iter != _rdel. + _euclidean_rdel_3d._tria._nset.tend(); ++_iter, ++_npos) { if (_iter->mark() >= 0 && @@ -1508,118 +1199,38 @@ } } } - - if (_nnum > +0) - { - /*-------------------------- write POWER data */ - if (_jcfg._iter_opts.dual() ) + + if (_rdel._euclidean_rdel_3d. + _tria._tset.count() > 0) { - _file << "POWER=" - << _nnum << ";1" << "\n" ; - - iptr_type _npos = +0; - - for (auto _iter = _mesh. - _euclidean_mesh_3d._mesh._set1.head() ; - _iter != _mesh. - _euclidean_mesh_3d._mesh._set1.tend() ; - ++_iter, ++_npos) - { - if (_iter->mark() >= 0 && - _nmap[_npos ] >= 0) - { - _file << _iter->pval(3) << "\n" ; - } - } - } - } - - if (_enum > +0) - { - /*-------------------------- write EDGE2 data */ - _file << "EDGE2=" << _enum << "\n" ; - - for (auto _iter = _mesh. - _euclidean_mesh_3d._mesh._set2.head() ; - _iter != _mesh. - _euclidean_mesh_3d._mesh._set2.tend() ; - ++_iter ) - { - if (_iter->mark() >= 0 && - _iter->self() >= 1 ) - { - _file << - _nmap[_iter->node(0)] << ";" - << - _nmap[_iter->node(1)] << ";" - << - _iter->itag() << "\n" ; - } - } - } - - if (_fnum > +0) - { - /*-------------------------- write TRIA3 data */ - _file << "TRIA3=" << _fnum << "\n" ; - - for (auto _iter = _mesh. - _euclidean_mesh_3d._mesh._set3.head() ; - _iter != _mesh. - _euclidean_mesh_3d._mesh._set3.tend() ; - ++_iter ) - { - if (_iter->mark() >= 0 && - _iter->self() >= 1 ) - { - _file << - _nmap[_iter->node(0)] << ";" - << - _nmap[_iter->node(1)] << ";" - << - _nmap[_iter->node(2)] << ";" - << - _iter->itag() << "\n" ; - } - } - } - - if (_tnum > +0) - { - /*-------------------------- write TRIA3 data */ - _file << "TRIA4=" << _tnum << "\n" ; - - for (auto _iter = _mesh. - _euclidean_mesh_3d._mesh._set4.head() ; - _iter != _mesh. - _euclidean_mesh_3d._mesh._set4.tend() ; + /*-------------------------- write TRIA3 data */ + _file << "TRIA4=" << _ntri << "\n" ; + + for (auto _iter = _rdel. + _euclidean_rdel_3d._tria._tset.head(); + _iter != _rdel. + _euclidean_rdel_3d._tria._tset.tend(); ++_iter ) { - if (_iter->mark() >= 0 && - _iter->self() >= 1 ) - { - _file << - _nmap[_iter->node(0)] << ";" - << - _nmap[_iter->node(1)] << ";" - << - _nmap[_iter->node(2)] << ";" - << - _nmap[_iter->node(3)] << ";" - << - _iter->itag() << "\n" ; - } + if (_iter->mark() < +0) continue ; + + _file << + _nmap[_iter->node(0)] << ";" << + _nmap[_iter->node(1)] << ";" << + _nmap[_iter->node(2)] << ";" << + _nmap[_iter->node(3)] << ";" << + +0 << "\n" ; } } - + } } else { - _errv = __file_not_located ; + _errv = __file_not_created ; } - + _file.close(); } @@ -1633,17 +1244,17 @@ /* -------------------------------------------------------- - * SAVE-MSHT: save MSH_T output data. + * SAVE-TRIA: save MSH_t output data. -------------------------------------------------------- */ template < typename jlog_data > - __normal_call iptr_type save_msht ( + __normal_call iptr_type save_tria ( jcfg_data &_jcfg , jlog_data &_jlog , - mesh_data &_mesh , + rdel_data &_rdel , jigsaw_msh_t &_mmsh ) { @@ -1651,83 +1262,65 @@ try { - containers::array _nmap ; - - __unreferenced (_jcfg) ; + containers::array _nmap; + __unreferenced (_jlog) ; - - if (_mesh._ndim == +2 && // save 2-dim. mesh - _mesh._kind == + __unreferenced (_jcfg) ; + + if (_rdel._ndim == +2 && // save 2-dim. mesh + _rdel._kind == jmsh_kind::euclidean_mesh) { _mmsh._flags = JIGSAW_EUCLIDEAN_MESH ; - + /*------------ index mapping for active nodes */ - _nmap.set_count(_mesh. - _euclidean_mesh_2d._mesh._set1.count() , + _nmap.set_count(_rdel. + _euclidean_rdel_2d._tria._nset.count() , containers::tight_alloc, -1) ; - iptr_type _nnum = +0 ; - iptr_type _enum = +0 ; - iptr_type _tnum = +0 ; - - for (auto _iter = _mesh. - _euclidean_mesh_2d._mesh._set2.head() ; - _iter != _mesh. - _euclidean_mesh_2d._mesh._set2.tend() ; + iptr_type _ntri = +0; + for (auto _iter = _rdel. + _euclidean_rdel_2d._tria._tset.head(); + _iter != _rdel. + _euclidean_rdel_2d._tria._tset.tend(); ++_iter ) { - if (_iter->mark() >= +0 && - _iter->self() >= +1 ) - { - _nmap[_iter->node(0)] = +1 ; - _nmap[_iter->node(1)] = +1 ; - _enum += +1 ; - } - } + if (_iter->mark() < +0) continue ; - for (auto _iter = _mesh. - _euclidean_mesh_2d._mesh._set3.head() ; - _iter != _mesh. - _euclidean_mesh_2d._mesh._set3.tend() ; - ++_iter ) - { - if (_iter->mark() >= +0 && - _iter->self() >= +1 ) - { - _nmap[_iter->node(0)] = +1 ; - _nmap[_iter->node(1)] = +1 ; - _nmap[_iter->node(2)] = +1 ; - _tnum += +1 ; - } + _ntri += +1 ; + + _nmap[_iter->node(0)]=1; + _nmap[_iter->node(1)]=1; + _nmap[_iter->node(2)]=1; } - for (auto _iter = _nmap.head(); - _iter != _nmap.tend(); + iptr_type _last = +0; + for (auto _iter = _nmap.head() ; + _iter != _nmap.tend() ; ++_iter ) { if ( *_iter >= +0) { - *_iter = _nnum ++ ; + *_iter = _last ++ ; } } - if (_nnum > +0) + if (_rdel._euclidean_rdel_2d. + _tria._nset.count() > 0) { - /*-------------------------- write POINT data */ + /*-------------------------- write POINT data */ jigsaw_alloc_vert2 ( - &_mmsh._vert2, _nnum) ; + &_mmsh._vert2, _last) ; jigsaw_alloc_reals ( - &_mmsh._power, _nnum) ; + &_mmsh._power, _last) ; iptr_type _npos = +0 ; iptr_type _nout = +0 ; - - for (auto _iter = _mesh. - _euclidean_mesh_2d._mesh._set1.head() ; - _iter != _mesh. - _euclidean_mesh_2d._mesh._set1.tend() ; + for (auto _iter = _rdel. + _euclidean_rdel_2d._tria._nset.head(); + _iter != _rdel. + _euclidean_rdel_2d._tria._nset.tend(); ++_iter, ++_npos) { if (_iter->mark() >= 0 && @@ -1737,122 +1330,266 @@ _ppos[0] = _iter->pval(0) ; _mmsh._vert2._data[_nout]. _ppos[1] = _iter->pval(1) ; - + _mmsh._vert2. _data[_nout]._itag = 0 ; - + _mmsh._power. - _data[_nout] = _iter->pval(2) ; - + _data[_nout] = (real_type)+0. ; + _nout = _nout + 1 ; } } + + _rdel._euclidean_rdel_2d. + _tria._nset. + clear(containers::tight_alloc); + } - - if (_enum > +0) - { - /*-------------------------- write EDGE2 data */ - jigsaw_alloc_edge2 ( - &_mmsh._edge2, _enum) ; - - iptr_type _eout = +0 ; - for (auto _iter = _mesh. - _euclidean_mesh_2d._mesh._set2.head() ; - _iter != _mesh. - _euclidean_mesh_2d._mesh._set2.tend() ; - ++_iter ) - { - if (_iter->mark() >= 0 && - _iter->self() >= 1 ) - { - _mmsh._edge2. - _data[_eout]._node[0] - = _nmap[_iter->node(0)] ; - _mmsh._edge2. - _data[_eout]._node[1] - = _nmap[_iter->node(1)] ; - - _mmsh._edge2. - _data[_eout]. - _itag = _iter->itag() ; - - _eout = _eout + 1 ; - } - } - } - - if (_tnum > +0) + + if (_rdel._euclidean_rdel_2d. + _tria._tset.count() > +0) { - /*-------------------------- write TRIA3 data */ + /*-------------------------- write TRIA3 data */ jigsaw_alloc_tria3 ( - &_mmsh._tria3, _tnum) ; - + &_mmsh._tria3, _ntri) ; + iptr_type _tout = +0 ; - for (auto _iter = _mesh. - _euclidean_mesh_2d._mesh._set3.head() ; - _iter != _mesh. - _euclidean_mesh_2d._mesh._set3.tend() ; + for (auto _iter = _rdel. + _euclidean_rdel_2d._tria._tset.head(); + _iter != _rdel. + _euclidean_rdel_2d._tria._tset.tend(); ++_iter ) { - if (_iter->mark() >= 0 && - _iter->self() >= 1 ) + if (_iter->mark() >= 0) { + _mmsh._tria3._data[_tout]. + _node[0] = + _nmap[_iter->node(0)]; + _mmsh._tria3._data[_tout]. + _node[1] = + _nmap[_iter->node(1)]; + _mmsh._tria3._data[_tout]. + _node[2] = + _nmap[_iter->node(2)]; + _mmsh._tria3. - _data[_tout]._node[0] - = _nmap[_iter->node(0)] ; - _mmsh._tria3. - _data[_tout]._node[1] - = _nmap[_iter->node(1)] ; - _mmsh._tria3. - _data[_tout]._node[2] - = _nmap[_iter->node(2)] ; - - _mmsh._tria3. - _data[_tout]. - _itag = _iter->itag() ; - + _data[_tout]._itag = 0 ; + _tout = _tout + 1 ; } } + + _rdel._euclidean_rdel_2d. + _tria._tset. + clear(containers::tight_alloc) ; + } - + } else - if (_mesh._ndim == +3 && // save 3-dim. mesh - _mesh._kind == + if (_rdel._ndim == +3 && // save 3-dim. mesh + _rdel._kind == jmsh_kind::euclidean_mesh) { _mmsh._flags = JIGSAW_EUCLIDEAN_MESH ; - + /*------------ index mapping for active nodes */ - _nmap.set_count(_mesh. - _euclidean_mesh_3d._mesh._set1.count() , + _nmap.set_count(_rdel. + _euclidean_rdel_3d._tria._nset.count() , containers::tight_alloc, -1) ; - iptr_type _nnum = +0 ; - iptr_type _enum = +0 ; - iptr_type _fnum = +0 ; - iptr_type _tnum = +0 ; + iptr_type _ntri = +0; + for (auto _iter = _rdel. + _euclidean_rdel_3d._tria._tset.head(); + _iter != _rdel. + _euclidean_rdel_3d._tria._tset.tend(); + ++_iter ) + { + if (_iter->mark() < +0) continue ; - for (auto _iter = _mesh. - _euclidean_mesh_3d._mesh._set2.head() ; - _iter != _mesh. - _euclidean_mesh_3d._mesh._set2.tend() ; + _ntri += +1 ; + + _nmap[_iter->node(0)]=1; + _nmap[_iter->node(1)]=1; + _nmap[_iter->node(2)]=1; + _nmap[_iter->node(3)]=1; + } + + iptr_type _last = +0; + for (auto _iter = _nmap.head() ; + _iter != _nmap.tend() ; ++_iter ) { - if (_iter->mark() >= +0 && - _iter->self() >= +1 ) + if ( *_iter >= +0) { - _nmap[_iter->node(0)] = +1 ; - _nmap[_iter->node(1)] = +1 ; - _enum += +1 ; + *_iter = _last ++ ; } } - for (auto _iter = _mesh. - _euclidean_mesh_3d._mesh._set3.head() ; - _iter != _mesh. - _euclidean_mesh_3d._mesh._set3.tend() ; + if (_rdel._euclidean_rdel_3d. + _tria._nset.count() > 0) + { + /*-------------------------- write POINT data */ + jigsaw_alloc_vert3 ( + &_mmsh._vert3 , _last); + + jigsaw_alloc_reals ( + &_mmsh._power , _last); + + iptr_type _npos = +0 ; + iptr_type _nout = +0 ; + for (auto _iter = _rdel. + _euclidean_rdel_3d._tria._nset.head(); + _iter != _rdel. + _euclidean_rdel_3d._tria._nset.tend(); + ++_iter, ++_npos) + { + if (_iter->mark() >= 0 && + _nmap[_npos ] >= 0 ) + { + _mmsh._vert3._data[_nout]. + _ppos[0] = _iter->pval(0) ; + _mmsh._vert3._data[_nout]. + _ppos[1] = _iter->pval(1) ; + _mmsh._vert3._data[_nout]. + _ppos[2] = _iter->pval(2) ; + + _mmsh._vert3. + _data[_nout]._itag = 0 ; + + _mmsh._power. + _data[_nout] = (real_type)+0. ; + + _nout = _nout + 1 ; + } + } + + _rdel._euclidean_rdel_3d. + _tria._nset. + clear(containers::tight_alloc); + + } + + if (_rdel._euclidean_rdel_3d. + _tria._tset.count() > +0) + { + /*-------------------------- write TRIA3 data */ + jigsaw_alloc_tria4 ( + &_mmsh._tria4, _ntri) ; + + iptr_type _tout = +0 ; + for (auto _iter = _rdel. + _euclidean_rdel_3d._tria._tset.head(); + _iter != _rdel. + _euclidean_rdel_3d._tria._tset.tend(); + ++_iter ) + { + if (_iter->mark() >= 0) + { + _mmsh._tria4._data[_tout]. + _node[0] = + _nmap[_iter->node(0)]; + _mmsh._tria4._data[_tout]. + _node[1] = + _nmap[_iter->node(1)]; + _mmsh._tria4._data[_tout]. + _node[2] = + _nmap[_iter->node(2)]; + _mmsh._tria4._data[_tout]. + _node[3] = + _nmap[_iter->node(3)]; + + _mmsh._tria4. + _data[_tout]._itag = 0 ; + + _tout = _tout + 1 ; + } + } + + _rdel._euclidean_rdel_3d. + _tria._tset. + clear(containers::tight_alloc) ; + + } + + } + + } + catch (...) + { + _errv = __unknown_error ; + } + + return ( _errv ) ; + } + + /* + -------------------------------------------------------- + * SAVE-MESH: save *.MSH output file. + -------------------------------------------------------- + */ + + template < + typename jlog_data + > + __normal_call iptr_type save_mesh ( + jcfg_data &_jcfg , + jlog_data &_jlog , + mesh_data &_mesh + ) + { + iptr_type _errv = __no_error ; + + __unreferenced(_jlog) ; + + try + { + containers::array _nmap; + + std::ofstream _file ; + + std::string _path ; + std::string _name ; + std::string _fext ; + file_part( + _jcfg._mesh_file, + _path, _name, _fext); + + _file.open( + _jcfg._mesh_file, + std::ofstream::out ); + + if (_file.is_open()) + { + if (_mesh._ndim == +2 && + _mesh._kind == + jmsh_kind::euclidean_mesh) + { + /*-------------------------- save 2-dim. mesh */ + _file << "# " << _name << ".msh" + << "; created by " ; + _file << __JGSWVSTR "\n" ; + _file << "MSHID=3;EUCLIDEAN-MESH \n" ; + _file << "NDIMS=2 \n" ; + + _file << std::scientific ; + _file << + std::setprecision(16); + + /*------------ index mapping for active nodes */ + _nmap.set_count(_mesh. + _euclidean_mesh_2d._mesh._set1.count() , + containers::tight_alloc, -1) ; + + iptr_type _nnum = +0 ; + iptr_type _enum = +0 ; + iptr_type _tnum = +0 ; + + for (auto _iter = _mesh. + _euclidean_mesh_2d._mesh._set2.head() ; + _iter != _mesh. + _euclidean_mesh_2d._mesh._set2.tend() ; ++_iter ) { if (_iter->mark() >= +0 && @@ -1860,15 +1597,14 @@ { _nmap[_iter->node(0)] = +1 ; _nmap[_iter->node(1)] = +1 ; - _nmap[_iter->node(2)] = +1 ; - _fnum += +1 ; + _enum += +1 ; } } - + for (auto _iter = _mesh. - _euclidean_mesh_3d._mesh._set4.head() ; + _euclidean_mesh_2d._mesh._set3.head() ; _iter != _mesh. - _euclidean_mesh_3d._mesh._set4.tend() ; + _euclidean_mesh_2d._mesh._set3.tend() ; ++_iter ) { if (_iter->mark() >= +0 && @@ -1877,7 +1613,6 @@ _nmap[_iter->node(0)] = +1 ; _nmap[_iter->node(1)] = +1 ; _nmap[_iter->node(2)] = +1 ; - _nmap[_iter->node(3)] = +1 ; _tnum += +1 ; } } @@ -1891,153 +1626,1661 @@ *_iter = _nnum ++ ; } } - + if (_nnum > +0) { - /*-------------------------- write POINT data */ - jigsaw_alloc_vert3 ( - &_mmsh._vert3, _nnum) ; - - jigsaw_alloc_reals ( - &_mmsh._power, _nnum) ; + /*-------------------------- write POINT data */ + _file << "POINT=" << _nnum << "\n" ; + + iptr_type _npos = +0; - iptr_type _npos = +0 ; - iptr_type _nout = +0 ; - for (auto _iter = _mesh. - _euclidean_mesh_3d._mesh._set1.head() ; + _euclidean_mesh_2d._mesh._set1.head() ; _iter != _mesh. - _euclidean_mesh_3d._mesh._set1.tend() ; + _euclidean_mesh_2d._mesh._set1.tend() ; ++_iter, ++_npos) { if (_iter->mark() >= 0 && - _nmap[_npos ] >= 0 ) + _nmap[_npos ] >= 0) { - _mmsh._vert3._data[_nout]. - _ppos[0] = _iter->pval(0) ; - _mmsh._vert3._data[_nout]. - _ppos[1] = _iter->pval(1) ; - _mmsh._vert3._data[_nout]. - _ppos[2] = _iter->pval(2) ; - - _mmsh._vert3. - _data[_nout]._itag = 0 ; - - _mmsh._power. - _data[_nout] = _iter->pval(3) ; - - _nout = _nout + 1 ; + _file << _iter->pval(0) << ";" + << _iter->pval(1) << ";" + << +0 << "\n" ; } } } - - if (_enum > +0) + + if (_nnum > +0) { - /*-------------------------- write EDGE2 data */ - jigsaw_alloc_edge2 ( - &_mmsh._edge2, _enum) ; - - iptr_type _eout = +0 ; + /*-------------------------- write POWER data */ + if (_jcfg._iter_opts.dual() ) + { + _file << "POWER=" + << _nnum << ";1" << "\n" ; + + iptr_type _npos = +0; + for (auto _iter = _mesh. - _euclidean_mesh_3d._mesh._set2.head() ; + _euclidean_mesh_2d._mesh._set1.head() ; _iter != _mesh. - _euclidean_mesh_3d._mesh._set2.tend() ; - ++_iter ) + _euclidean_mesh_2d._mesh._set1.tend() ; + ++_iter, ++_npos) { if (_iter->mark() >= 0 && - _iter->self() >= 1 ) + _nmap[_npos ] >= 0) { - _mmsh._edge2. - _data[_eout]._node[0] - = _nmap[_iter->node(0)] ; - _mmsh._edge2. - _data[_eout]._node[1] - = _nmap[_iter->node(1)] ; - - _mmsh._edge2. - _data[_eout]. - _itag = _iter->itag() ; - - _eout = _eout + 1 ; + _file << _iter->pval(2) << "\n" ; } } } - - if (_fnum > +0) + } + + if (_enum > +0) { - /*-------------------------- write TRIA3 data */ - jigsaw_alloc_tria3 ( - &_mmsh._tria3, _fnum) ; - - iptr_type _fout = +0 ; + /*-------------------------- write EDGE2 data */ + _file << "EDGE2=" << _enum << "\n" ; + for (auto _iter = _mesh. - _euclidean_mesh_3d._mesh._set3.head() ; + _euclidean_mesh_2d._mesh._set2.head() ; _iter != _mesh. - _euclidean_mesh_3d._mesh._set3.tend() ; + _euclidean_mesh_2d._mesh._set2.tend() ; ++_iter ) { if (_iter->mark() >= 0 && _iter->self() >= 1 ) { - _mmsh._tria3. - _data[_fout]._node[0] - = _nmap[_iter->node(0)] ; - _mmsh._tria3. - _data[_fout]._node[1] - = _nmap[_iter->node(1)] ; - _mmsh._tria3. - _data[_fout]._node[2] - = _nmap[_iter->node(2)] ; - - _mmsh._tria3. - _data[_fout]. - _itag = _iter->itag() ; - - _fout = _fout + 1 ; + _file << + _nmap[_iter->node(0)] << ";" + << + _nmap[_iter->node(1)] << ";" + << + _iter->itag() << "\n" ; } } } - + if (_tnum > +0) { - /*-------------------------- write TRIA3 data */ - jigsaw_alloc_tria4 ( - &_mmsh._tria4, _tnum) ; - - iptr_type _tout = +0 ; + /*-------------------------- write TRIA3 data */ + _file << "TRIA3=" << _tnum << "\n" ; + for (auto _iter = _mesh. - _euclidean_mesh_3d._mesh._set4.head() ; + _euclidean_mesh_2d._mesh._set3.head() ; _iter != _mesh. - _euclidean_mesh_3d._mesh._set4.tend() ; + _euclidean_mesh_2d._mesh._set3.tend() ; ++_iter ) { if (_iter->mark() >= 0 && _iter->self() >= 1 ) { - _mmsh._tria4. - _data[_tout]._node[0] - = _nmap[_iter->node(0)] ; - _mmsh._tria4. - _data[_tout]._node[1] - = _nmap[_iter->node(1)] ; - _mmsh._tria4. - _data[_tout]._node[2] - = _nmap[_iter->node(2)] ; - _mmsh._tria4. - _data[_tout]._node[3] - = _nmap[_iter->node(3)] ; - - _mmsh._tria4. - _data[_tout]. - _itag = _iter->itag() ; - - _tout = _tout + 1 ; + _file << + _nmap[_iter->node(0)] << ";" + << + _nmap[_iter->node(1)] << ";" + << + _nmap[_iter->node(2)] << ";" + << + _iter->itag() << "\n" ; } } } - + } - + else + if (_mesh._ndim == +3 && + _mesh._kind == + jmsh_kind::euclidean_mesh) + { + /*-------------------------- save 3-dim. mesh */ + _file << "# " << _name << ".msh" + << "; created by " ; + _file << __JGSWVSTR "\n" ; + _file << "MSHID=3;EUCLIDEAN-MESH \n" ; + _file << "NDIMS=3 \n" ; + + _file << std::scientific ; + _file << + std::setprecision(16); + + /*------------ index mapping for active nodes */ + _nmap.set_count(_mesh. + _euclidean_mesh_3d._mesh._set1.count() , + containers::tight_alloc, -1) ; + + iptr_type _nnum = +0 ; + iptr_type _enum = +0 ; + iptr_type _fnum = +0 ; + iptr_type _tnum = +0 ; + + for (auto _iter = _mesh. + _euclidean_mesh_3d._mesh._set2.head() ; + _iter != _mesh. + _euclidean_mesh_3d._mesh._set2.tend() ; + ++_iter ) + { + if (_iter->mark() >= +0 && + _iter->self() >= +1 ) + { + _nmap[_iter->node(0)] = +1 ; + _nmap[_iter->node(1)] = +1 ; + _enum += +1 ; + } + } + + for (auto _iter = _mesh. + _euclidean_mesh_3d._mesh._set3.head() ; + _iter != _mesh. + _euclidean_mesh_3d._mesh._set3.tend() ; + ++_iter ) + { + if (_iter->mark() >= +0 && + _iter->self() >= +1 ) + { + _nmap[_iter->node(0)] = +1 ; + _nmap[_iter->node(1)] = +1 ; + _nmap[_iter->node(2)] = +1 ; + _fnum += +1 ; + } + } + + for (auto _iter = _mesh. + _euclidean_mesh_3d._mesh._set4.head() ; + _iter != _mesh. + _euclidean_mesh_3d._mesh._set4.tend() ; + ++_iter ) + { + if (_iter->mark() >= +0 && + _iter->self() >= +1 ) + { + _nmap[_iter->node(0)] = +1 ; + _nmap[_iter->node(1)] = +1 ; + _nmap[_iter->node(2)] = +1 ; + _nmap[_iter->node(3)] = +1 ; + _tnum += +1 ; + } + } + + for (auto _iter = _nmap.head(); + _iter != _nmap.tend(); + ++_iter ) + { + if ( *_iter >= +0) + { + *_iter = _nnum ++ ; + } + } + + if (_nnum > +0) + { + /*-------------------------- write POINT data */ + _file << "POINT=" << _nnum << "\n" ; + + iptr_type _npos = +0; + + for (auto _iter = _mesh. + _euclidean_mesh_3d._mesh._set1.head() ; + _iter != _mesh. + _euclidean_mesh_3d._mesh._set1.tend() ; + ++_iter, ++_npos) + { + if (_iter->mark() >= 0 && + _nmap[_npos ] >= 0) + { + _file << _iter->pval(0) << ";" + << _iter->pval(1) << ";" + << _iter->pval(2) << ";" + << +0 << "\n" ; + } + } + } + + if (_nnum > +0) + { + /*-------------------------- write POWER data */ + if (_jcfg._iter_opts.dual() ) + { + _file << "POWER=" + << _nnum << ";1" << "\n" ; + + iptr_type _npos = +0; + + for (auto _iter = _mesh. + _euclidean_mesh_3d._mesh._set1.head() ; + _iter != _mesh. + _euclidean_mesh_3d._mesh._set1.tend() ; + ++_iter, ++_npos) + { + if (_iter->mark() >= 0 && + _nmap[_npos ] >= 0) + { + _file << _iter->pval(3) << "\n" ; + } + } + } + } + + if (_enum > +0) + { + /*-------------------------- write EDGE2 data */ + _file << "EDGE2=" << _enum << "\n" ; + + for (auto _iter = _mesh. + _euclidean_mesh_3d._mesh._set2.head() ; + _iter != _mesh. + _euclidean_mesh_3d._mesh._set2.tend() ; + ++_iter ) + { + if (_iter->mark() >= 0 && + _iter->self() >= 1 ) + { + _file << + _nmap[_iter->node(0)] << ";" + << + _nmap[_iter->node(1)] << ";" + << + _iter->itag() << "\n" ; + } + } + } + + if (_fnum > +0) + { + /*-------------------------- write TRIA3 data */ + _file << "TRIA3=" << _fnum << "\n" ; + + for (auto _iter = _mesh. + _euclidean_mesh_3d._mesh._set3.head() ; + _iter != _mesh. + _euclidean_mesh_3d._mesh._set3.tend() ; + ++_iter ) + { + if (_iter->mark() >= 0 && + _iter->self() >= 1 ) + { + _file << + _nmap[_iter->node(0)] << ";" + << + _nmap[_iter->node(1)] << ";" + << + _nmap[_iter->node(2)] << ";" + << + _iter->itag() << "\n" ; + } + } + } + + if (_tnum > +0) + { + /*-------------------------- write TRIA3 data */ + _file << "TRIA4=" << _tnum << "\n" ; + + for (auto _iter = _mesh. + _euclidean_mesh_3d._mesh._set4.head() ; + _iter != _mesh. + _euclidean_mesh_3d._mesh._set4.tend() ; + ++_iter ) + { + if (_iter->mark() >= 0 && + _iter->self() >= 1 ) + { + _file << + _nmap[_iter->node(0)] << ";" + << + _nmap[_iter->node(1)] << ";" + << + _nmap[_iter->node(2)] << ";" + << + _nmap[_iter->node(3)] << ";" + << + _iter->itag() << "\n" ; + } + } + } + + } + + } + else + { + _errv = __file_not_created ; + } + + _file.close(); + + } + catch (...) + { + _errv = __unknown_error ; + } + + return ( _errv ) ; + } + + /* + -------------------------------------------------------- + * SAVE-MESH: save MSH_t output data. + -------------------------------------------------------- + */ + + template < + typename jlog_data + > + __normal_call iptr_type save_mesh ( + jcfg_data &_jcfg , + jlog_data &_jlog , + mesh_data &_mesh , + jigsaw_msh_t &_mmsh + ) + { + iptr_type _errv = __no_error ; + + try + { + containers::array _nmap ; + + __unreferenced (_jcfg) ; + __unreferenced (_jlog) ; + + if (_mesh._ndim == +2 && // save 2-dim. mesh + _mesh._kind == + jmsh_kind::euclidean_mesh) + { + _mmsh._flags = JIGSAW_EUCLIDEAN_MESH ; + + /*------------ index mapping for active nodes */ + _nmap.set_count(_mesh. + _euclidean_mesh_2d._mesh._set1.count() , + containers::tight_alloc, -1) ; + + iptr_type _nnum = +0 ; + iptr_type _enum = +0 ; + iptr_type _tnum = +0 ; + + for (auto _iter = _mesh. + _euclidean_mesh_2d._mesh._set2.head() ; + _iter != _mesh. + _euclidean_mesh_2d._mesh._set2.tend() ; + ++_iter ) + { + if (_iter->mark() >= +0 && + _iter->self() >= +1 ) + { + _nmap[_iter->node(0)] = +1 ; + _nmap[_iter->node(1)] = +1 ; + _enum += +1 ; + } + } + + for (auto _iter = _mesh. + _euclidean_mesh_2d._mesh._set3.head() ; + _iter != _mesh. + _euclidean_mesh_2d._mesh._set3.tend() ; + ++_iter ) + { + if (_iter->mark() >= +0 && + _iter->self() >= +1 ) + { + _nmap[_iter->node(0)] = +1 ; + _nmap[_iter->node(1)] = +1 ; + _nmap[_iter->node(2)] = +1 ; + _tnum += +1 ; + } + } + + for (auto _iter = _nmap.head(); + _iter != _nmap.tend(); + ++_iter ) + { + if ( *_iter >= +0) + { + *_iter = _nnum ++ ; + } + } + + if (_nnum > +0) + { + /*-------------------------- write POINT data */ + jigsaw_alloc_vert2 ( + &_mmsh._vert2, _nnum) ; + + jigsaw_alloc_reals ( + &_mmsh._power, _nnum) ; + + iptr_type _npos = +0 ; + iptr_type _nout = +0 ; + + for (auto _iter = _mesh. + _euclidean_mesh_2d._mesh._set1.head() ; + _iter != _mesh. + _euclidean_mesh_2d._mesh._set1.tend() ; + ++_iter, ++_npos) + { + if (_iter->mark() >= 0 && + _nmap[_npos ] >= 0 ) + { + _mmsh._vert2._data[_nout]. + _ppos[0] = _iter->pval(0) ; + _mmsh._vert2._data[_nout]. + _ppos[1] = _iter->pval(1) ; + + _mmsh._vert2. + _data[_nout]._itag = 0 ; + + _mmsh._power. + _data[_nout] = _iter->pval(2) ; + + _nout = _nout + 1 ; + } + } + + _mesh._euclidean_mesh_2d._mesh._set1. + clear(containers::tight_alloc); + + _mesh._euclidean_mesh_2d._mesh._adj1. + clear(containers::tight_alloc); + + } + + if (_enum > +0) + { + /*-------------------------- write EDGE2 data */ + jigsaw_alloc_edge2 ( + &_mmsh._edge2, _enum) ; + + iptr_type _eout = +0 ; + for (auto _iter = _mesh. + _euclidean_mesh_2d._mesh._set2.head() ; + _iter != _mesh. + _euclidean_mesh_2d._mesh._set2.tend() ; + ++_iter ) + { + if (_iter->mark() >= 0 && + _iter->self() >= 1 ) + { + _mmsh._edge2. + _data[_eout]._node[0] + = _nmap[_iter->node(0)] ; + _mmsh._edge2. + _data[_eout]._node[1] + = _nmap[_iter->node(1)] ; + + _mmsh._edge2. + _data[_eout]. + _itag = _iter->itag() ; + + _eout = _eout + 1 ; + } + } + + _mesh._euclidean_mesh_2d._mesh._set2. + clear(containers::tight_alloc); + + _mesh._euclidean_mesh_2d._mesh._adj2. + clear(containers::tight_alloc); + + _mesh._euclidean_mesh_2d._mesh._map2. + clear(containers::tight_alloc); + + } + + if (_tnum > +0) + { + /*-------------------------- write TRIA3 data */ + jigsaw_alloc_tria3 ( + &_mmsh._tria3, _tnum) ; + + iptr_type _tout = +0 ; + for (auto _iter = _mesh. + _euclidean_mesh_2d._mesh._set3.head() ; + _iter != _mesh. + _euclidean_mesh_2d._mesh._set3.tend() ; + ++_iter ) + { + if (_iter->mark() >= 0 && + _iter->self() >= 1 ) + { + _mmsh._tria3. + _data[_tout]._node[0] + = _nmap[_iter->node(0)] ; + _mmsh._tria3. + _data[_tout]._node[1] + = _nmap[_iter->node(1)] ; + _mmsh._tria3. + _data[_tout]._node[2] + = _nmap[_iter->node(2)] ; + + _mmsh._tria3. + _data[_tout]. + _itag = _iter->itag() ; + + _tout = _tout + 1 ; + } + } + + _mesh._euclidean_mesh_2d._mesh._set3. + clear(containers::tight_alloc); + + _mesh._euclidean_mesh_2d._mesh._adj3. + clear(containers::tight_alloc); + + _mesh._euclidean_mesh_2d._mesh._map3. + clear(containers::tight_alloc); + + } + + } + else + if (_mesh._ndim == +3 && // save 3-dim. mesh + _mesh._kind == + jmsh_kind::euclidean_mesh) + { + _mmsh._flags = JIGSAW_EUCLIDEAN_MESH ; + + /*------------ index mapping for active nodes */ + _nmap.set_count(_mesh. + _euclidean_mesh_3d._mesh._set1.count() , + containers::tight_alloc, -1) ; + + iptr_type _nnum = +0 ; + iptr_type _enum = +0 ; + iptr_type _fnum = +0 ; + iptr_type _tnum = +0 ; + + for (auto _iter = _mesh. + _euclidean_mesh_3d._mesh._set2.head() ; + _iter != _mesh. + _euclidean_mesh_3d._mesh._set2.tend() ; + ++_iter ) + { + if (_iter->mark() >= +0 && + _iter->self() >= +1 ) + { + _nmap[_iter->node(0)] = +1 ; + _nmap[_iter->node(1)] = +1 ; + _enum += +1 ; + } + } + + for (auto _iter = _mesh. + _euclidean_mesh_3d._mesh._set3.head() ; + _iter != _mesh. + _euclidean_mesh_3d._mesh._set3.tend() ; + ++_iter ) + { + if (_iter->mark() >= +0 && + _iter->self() >= +1 ) + { + _nmap[_iter->node(0)] = +1 ; + _nmap[_iter->node(1)] = +1 ; + _nmap[_iter->node(2)] = +1 ; + _fnum += +1 ; + } + } + + for (auto _iter = _mesh. + _euclidean_mesh_3d._mesh._set4.head() ; + _iter != _mesh. + _euclidean_mesh_3d._mesh._set4.tend() ; + ++_iter ) + { + if (_iter->mark() >= +0 && + _iter->self() >= +1 ) + { + _nmap[_iter->node(0)] = +1 ; + _nmap[_iter->node(1)] = +1 ; + _nmap[_iter->node(2)] = +1 ; + _nmap[_iter->node(3)] = +1 ; + _tnum += +1 ; + } + } + + for (auto _iter = _nmap.head(); + _iter != _nmap.tend(); + ++_iter ) + { + if ( *_iter >= +0) + { + *_iter = _nnum ++ ; + } + } + + if (_nnum > +0) + { + /*-------------------------- write POINT data */ + jigsaw_alloc_vert3 ( + &_mmsh._vert3, _nnum) ; + + jigsaw_alloc_reals ( + &_mmsh._power, _nnum) ; + + iptr_type _npos = +0 ; + iptr_type _nout = +0 ; + + for (auto _iter = _mesh. + _euclidean_mesh_3d._mesh._set1.head() ; + _iter != _mesh. + _euclidean_mesh_3d._mesh._set1.tend() ; + ++_iter, ++_npos) + { + if (_iter->mark() >= 0 && + _nmap[_npos ] >= 0 ) + { + _mmsh._vert3._data[_nout]. + _ppos[0] = _iter->pval(0) ; + _mmsh._vert3._data[_nout]. + _ppos[1] = _iter->pval(1) ; + _mmsh._vert3._data[_nout]. + _ppos[2] = _iter->pval(2) ; + + _mmsh._vert3. + _data[_nout]._itag = 0 ; + + _mmsh._power. + _data[_nout] = _iter->pval(3) ; + + _nout = _nout + 1 ; + } + } + + _mesh._euclidean_mesh_3d._mesh._set1. + clear(containers::tight_alloc); + + _mesh._euclidean_mesh_3d._mesh._adj1. + clear(containers::tight_alloc); + + } + + if (_enum > +0) + { + /*-------------------------- write EDGE2 data */ + jigsaw_alloc_edge2 ( + &_mmsh._edge2, _enum) ; + + iptr_type _eout = +0 ; + for (auto _iter = _mesh. + _euclidean_mesh_3d._mesh._set2.head() ; + _iter != _mesh. + _euclidean_mesh_3d._mesh._set2.tend() ; + ++_iter ) + { + if (_iter->mark() >= 0 && + _iter->self() >= 1 ) + { + _mmsh._edge2. + _data[_eout]._node[0] + = _nmap[_iter->node(0)] ; + _mmsh._edge2. + _data[_eout]._node[1] + = _nmap[_iter->node(1)] ; + + _mmsh._edge2. + _data[_eout]. + _itag = _iter->itag() ; + + _eout = _eout + 1 ; + } + } + + _mesh._euclidean_mesh_3d._mesh._set2. + clear(containers::tight_alloc); + + _mesh._euclidean_mesh_3d._mesh._adj2. + clear(containers::tight_alloc); + + _mesh._euclidean_mesh_3d._mesh._map2. + clear(containers::tight_alloc); + + } + + if (_fnum > +0) + { + /*-------------------------- write TRIA3 data */ + jigsaw_alloc_tria3 ( + &_mmsh._tria3, _fnum) ; + + iptr_type _fout = +0 ; + for (auto _iter = _mesh. + _euclidean_mesh_3d._mesh._set3.head() ; + _iter != _mesh. + _euclidean_mesh_3d._mesh._set3.tend() ; + ++_iter ) + { + if (_iter->mark() >= 0 && + _iter->self() >= 1 ) + { + _mmsh._tria3. + _data[_fout]._node[0] + = _nmap[_iter->node(0)] ; + _mmsh._tria3. + _data[_fout]._node[1] + = _nmap[_iter->node(1)] ; + _mmsh._tria3. + _data[_fout]._node[2] + = _nmap[_iter->node(2)] ; + + _mmsh._tria3. + _data[_fout]. + _itag = _iter->itag() ; + + _fout = _fout + 1 ; + } + } + + _mesh._euclidean_mesh_3d._mesh._set3. + clear(containers::tight_alloc); + + _mesh._euclidean_mesh_3d._mesh._adj3. + clear(containers::tight_alloc); + + _mesh._euclidean_mesh_3d._mesh._map3. + clear(containers::tight_alloc); + + } + + if (_tnum > +0) + { + /*-------------------------- write TRIA3 data */ + jigsaw_alloc_tria4 ( + &_mmsh._tria4, _tnum) ; + + iptr_type _tout = +0 ; + for (auto _iter = _mesh. + _euclidean_mesh_3d._mesh._set4.head() ; + _iter != _mesh. + _euclidean_mesh_3d._mesh._set4.tend() ; + ++_iter ) + { + if (_iter->mark() >= 0 && + _iter->self() >= 1 ) + { + _mmsh._tria4. + _data[_tout]._node[0] + = _nmap[_iter->node(0)] ; + _mmsh._tria4. + _data[_tout]._node[1] + = _nmap[_iter->node(1)] ; + _mmsh._tria4. + _data[_tout]._node[2] + = _nmap[_iter->node(2)] ; + _mmsh._tria4. + _data[_tout]._node[3] + = _nmap[_iter->node(3)] ; + + _mmsh._tria4. + _data[_tout]. + _itag = _iter->itag() ; + + _tout = _tout + 1 ; + } + } + + _mesh._euclidean_mesh_3d._mesh._set4. + clear(containers::tight_alloc); + + _mesh._euclidean_mesh_3d._mesh._adj4. + clear(containers::tight_alloc); + + _mesh._euclidean_mesh_3d._mesh._map4. + clear(containers::tight_alloc); + + } + + } + + } + catch (...) + { + _errv = __unknown_error ; + } + + return ( _errv ) ; + } + + /* + -------------------------------------------------------- + * SAVE-HFUN: save *.MSH output file. + -------------------------------------------------------- + */ + + template < + typename jlog_data + > + __normal_call iptr_type save_hfun ( + jcfg_data &_jcfg , + jlog_data &_jlog , + hfun_data &_ffun + ) + { + iptr_type _errv = __no_error ; + + // NB. this routine handles output for MARCHE --- this + // will *overwrite* the hfun-file input... + + __unreferenced(_jlog) ; + + try + { + std::ofstream _file ; + + std::string _path ; + std::string _name ; + std::string _fext ; + file_part( + _jcfg._hfun_file, + _path, _name, _fext); + + _file.open( + _jcfg._hfun_file, + std::ofstream::out ); + + if (_file.is_open()) + { + if (_ffun._ndim == +2 && + _ffun._kind == + jmsh_kind::euclidean_mesh) + { + /*-------------------------- save 2-dim. mesh */ + _file << "# " << _name << ".msh" + << "; created by " ; + _file << __JGSWVSTR "\n" ; + _file << "MSHID=3;EUCLIDEAN-MESH \n" ; + _file << "NDIMS=2 \n" ; + + _file << std::scientific ; + _file << + std::setprecision(16); + + /*-------------------------- count mesh items */ + iptr_type _nnum = +0 ; + iptr_type _tnum = +0 ; + + for (auto _iter = _ffun. + _euclidean_mesh_2d._mesh._set1.head() ; + _iter != _ffun. + _euclidean_mesh_2d._mesh._set1.tend() ; + ++_iter ) + { + if (_iter->mark() >= +0 && + _iter->self() >= +1 ) + { + _nnum += +1 ; + } + } + + for (auto _iter = _ffun. + _euclidean_mesh_2d._mesh._set3.head() ; + _iter != _ffun. + _euclidean_mesh_2d._mesh._set3.tend() ; + ++_iter ) + { + if (_iter->mark() >= +0 && + _iter->self() >= +1 ) + { + _tnum += +1 ; + } + } + + if (_nnum > +0) + { + /*-------------------------- write POINT data */ + _file << "POINT=" << _nnum << "\n" ; + + iptr_type _npos = +0; + + for (auto _iter = _ffun. + _euclidean_mesh_2d._mesh._set1.head() ; + _iter != _ffun. + _euclidean_mesh_2d._mesh._set1.tend() ; + ++_iter, ++_npos) + { + if (_iter->mark() >= 0) + { + _file << _iter->pval(0) << ";" + << _iter->pval(1) << ";" + << +0 << "\n" ; + } + } + } + + if (_nnum > +0) + { + /*-------------------------- write VALUE data */ + _file << "VALUE=" + << _nnum << ";1" << "\n" ; + + for (auto _iter = _ffun. + _euclidean_mesh_2d._hval.head() ; + _iter != _ffun. + _euclidean_mesh_2d._hval.tend() ; + ++_iter ) + { + _file << *_iter << "\n" ; + } + } + + if (_tnum > +0) + { + /*-------------------------- write TRIA3 data */ + _file << "TRIA3=" << _tnum << "\n" ; + + for (auto _iter = _ffun. + _euclidean_mesh_2d._mesh._set3.head() ; + _iter != _ffun. + _euclidean_mesh_2d._mesh._set3.tend() ; + ++_iter ) + { + if (_iter->mark() >= 0 && + _iter->self() >= 1 ) + { + _file << _iter->node(0) << ";" + << _iter->node(1) << ";" + << _iter->node(2) << ";" + << +0 << "\n" ; + } + } + } + + } + else + if (_ffun._ndim == +3 && + _ffun._kind == + jmsh_kind::euclidean_mesh) + { + /*-------------------------- save 3-dim. mesh */ + _file << "# " << _name << ".msh" + << "; created by " ; + _file << __JGSWVSTR "\n" ; + _file << "MSHID=3;EUCLIDEAN-MESH \n" ; + _file << "NDIMS=3 \n" ; + + _file << std::scientific ; + _file << + std::setprecision(16); + + /*-------------------------- count mesh items */ + iptr_type _nnum = +0 ; + iptr_type _tnum = +0 ; + + for (auto _iter = _ffun. + _euclidean_mesh_3d._mesh._set1.head() ; + _iter != _ffun. + _euclidean_mesh_3d._mesh._set1.tend() ; + ++_iter ) + { + if (_iter->mark() >= +0 && + _iter->self() >= +1 ) + { + _nnum += +1 ; + } + } + + for (auto _iter = _ffun. + _euclidean_mesh_3d._mesh._set4.head() ; + _iter != _ffun. + _euclidean_mesh_3d._mesh._set4.tend() ; + ++_iter ) + { + if (_iter->mark() >= +0 && + _iter->self() >= +1 ) + { + _tnum += +1 ; + } + } + + if (_nnum > +0) + { + /*-------------------------- write POINT data */ + _file << "POINT=" << _nnum << "\n" ; + + iptr_type _npos = +0; + + for (auto _iter = _ffun. + _euclidean_mesh_3d._mesh._set1.head() ; + _iter != _ffun. + _euclidean_mesh_3d._mesh._set1.tend() ; + ++_iter, ++_npos) + { + if (_iter->mark() >= 0) + { + _file << _iter->pval(0) << ";" + << _iter->pval(1) << ";" + << _iter->pval(2) << ";" + << +0 << "\n" ; + } + } + } + + if (_nnum > +0) + { + /*-------------------------- write VALUE data */ + _file << "VALUE=" + << _nnum << ";1" << "\n" ; + + for (auto _iter = _ffun. + _euclidean_mesh_3d._hval.head() ; + _iter != _ffun. + _euclidean_mesh_3d._hval.tend() ; + ++_iter ) + { + _file << *_iter << "\n" ; + } + } + + if (_tnum > +0) + { + /*-------------------------- write TRIA3 data */ + _file << "TRIA4=" << _tnum << "\n" ; + + for (auto _iter = _ffun. + _euclidean_mesh_3d._mesh._set4.head() ; + _iter != _ffun. + _euclidean_mesh_3d._mesh._set4.tend() ; + ++_iter ) + { + if (_iter->mark() >= 0 && + _iter->self() >= 1 ) + { + _file << _iter->node(0) << ";" + << _iter->node(1) << ";" + << _iter->node(2) << ";" + << _iter->node(3) << ";" + << +0 << "\n" ; + } + } + } + + } + else + if (_ffun._ndim == +2 && + _ffun._kind == + jmsh_kind::ellipsoid_mesh) + { + /*-------------------------- save 3-dim. mesh */ + _file << "# " << _name << ".msh" + << "; created by " ; + _file << __JGSWVSTR "\n" ; + _file << "MSHID=3;ELLIPSOID-MESH \n" ; + _file << "NDIMS=2 \n" ; + + _file << std::scientific ; + _file << + std::setprecision(16); + + /*-------------------------- write class data */ + + _file << "RADII=" << + _ffun._ellipsoid_mesh_3d._radA + << ";" << + _ffun._ellipsoid_mesh_3d._radB + << ";" << + _ffun._ellipsoid_mesh_3d._radC + << "\n" ; + + /*-------------------------- count mesh items */ + iptr_type _nnum = +0 ; + iptr_type _tnum = +0 ; + + for (auto _iter = _ffun. + _ellipsoid_mesh_3d._mesh._set1.head() ; + _iter != _ffun. + _ellipsoid_mesh_3d._mesh._set1.tend() ; + ++_iter ) + { + if (_iter->mark() >= +0 && + _iter->self() >= +1 ) + { + _nnum += +1 ; + } + } + + for (auto _iter = _ffun. + _ellipsoid_mesh_3d._mesh._set3.head() ; + _iter != _ffun. + _ellipsoid_mesh_3d._mesh._set3.tend() ; + ++_iter ) + { + if (_iter->mark() >= +0 && + _iter->self() >= +1 ) + { + _tnum += +1 ; + } + } + + if (_nnum > +0) + { + /*-------------------------- write POINT data */ + _file << "POINT=" << _nnum << "\n" ; + + iptr_type _npos = +0 ; + iptr_type _itag = +0 ; + + real_type _ppos[3] ; + real_type _apos[2] ; + for (auto _iter = _ffun. + _ellipsoid_mesh_3d._mesh._set1.head() ; + _iter != _ffun. + _ellipsoid_mesh_3d._mesh._set1.tend() ; + ++_iter, ++_npos) + { + if (_iter->mark() >= +0) + { + _ppos[0] =_iter->pval(0); + _ppos[1] =_iter->pval(1); + _ppos[2] =_iter->pval(2); + + _ffun._ellipsoid_mesh_3d. + toS2(_ppos, _apos); + + _file << _apos[0] << ";" + << _apos[1] << ";" + << _itag <<"\n"; + } + } + } + + if (_nnum > +0) + { + /*-------------------------- write VALUE data */ + _file << "VALUE=" + << _nnum << ";1" << "\n" ; + + for (auto _iter = _ffun. + _ellipsoid_mesh_3d._hval.head() ; + _iter != _ffun. + _ellipsoid_mesh_3d._hval.tend() ; + ++_iter ) + { + _file << *_iter << "\n" ; + } + } + + if (_tnum > +0) + { + /*-------------------------- write TRIA3 data */ + _file << "TRIA3=" << _tnum << "\n" ; + + for (auto _iter = _ffun. + _ellipsoid_mesh_3d._mesh._set3.head() ; + _iter != _ffun. + _ellipsoid_mesh_3d._mesh._set3.tend() ; + ++_iter ) + { + if (_iter->mark() >= 0 && + _iter->self() >= 1 ) + { + _file << _iter->node(0) << ";" + << _iter->node(1) << ";" + << _iter->node(2) << ";" + << +0 << "\n" ; + } + } + } + + } + else + if (_ffun._ndim == +2 && + _ffun._kind == + jmsh_kind::euclidean_grid) + { + /*-------------------------- save 2-dim. grid */ + _file << "# " << _name << ".msh" + << "; created by " ; + _file << __JGSWVSTR "\n" ; + _file << "MSHID=3;EUCLIDEAN-GRID \n" ; + _file << "NDIMS=2 \n" ; + + _file << std::scientific ; + _file << + std::setprecision(16); + + /*-------------------------- write class data */ + + if (_ffun._euclidean_grid_2d. + _xpos.count() > +0) + { + /*-------------------------- write COORD data */ + _file << "COORD=1;" << + _ffun._euclidean_grid_2d. + _xpos.count() << "\n" ; + + for (auto _iter = _ffun. + _euclidean_grid_2d._xpos.head(); + _iter != _ffun. + _euclidean_grid_2d._xpos.tend(); + ++_iter ) + { + _file << *_iter << "\n" ; + } + } + + if (_ffun._euclidean_grid_2d. + _ypos.count() > +0) + { + /*-------------------------- write COORD data */ + _file << "COORD=2;" << + _ffun._euclidean_grid_2d. + _ypos.count() << "\n" ; + + for (auto _iter = _ffun. + _euclidean_grid_2d._ypos.head(); + _iter != _ffun. + _euclidean_grid_2d._ypos.tend(); + ++_iter ) + { + _file << *_iter << "\n" ; + } + } + + if (_ffun._euclidean_grid_2d. + _hmat.count() > +0) + { + /*-------------------------- write VALUE data */ + _file << "VALUE=" << + _ffun._euclidean_grid_2d. + _hmat.count() << ";1" "\n" ; + + for (auto _iter = _ffun. + _euclidean_grid_2d._hmat.head(); + _iter != _ffun. + _euclidean_grid_2d._hmat.tend(); + ++_iter ) + { + _file << *_iter << "\n" ; + } + } + + } + else + if (_ffun._ndim == +3 && + _ffun._kind == + jmsh_kind::euclidean_grid) + { + /*-------------------------- save 3-dim. grid */ + _file << "# " << _name << ".msh" + << "; created by " ; + _file << __JGSWVSTR "\n" ; + _file << "MSHID=3;EUCLIDEAN-GRID \n" ; + _file << "NDIMS=3 \n" ; + + _file << std::scientific ; + _file << + std::setprecision(16); + + /*-------------------------- write class data */ + + if (_ffun._euclidean_grid_3d. + _xpos.count() > +0) + { + /*-------------------------- write COORD data */ + _file << "COORD=1;" << + _ffun._euclidean_grid_3d. + _xpos.count() << "\n" ; + + for (auto _iter = _ffun. + _euclidean_grid_3d._xpos.head(); + _iter != _ffun. + _euclidean_grid_3d._xpos.tend(); + ++_iter ) + { + _file << *_iter << "\n" ; + } + } + + if (_ffun._euclidean_grid_3d. + _ypos.count() > +0) + { + /*-------------------------- write COORD data */ + _file << "COORD=2;" << + _ffun._euclidean_grid_3d. + _ypos.count() << "\n" ; + + for (auto _iter = _ffun. + _euclidean_grid_3d._ypos.head(); + _iter != _ffun. + _euclidean_grid_3d._ypos.tend(); + ++_iter ) + { + _file << *_iter << "\n" ; + } + } + + if (_ffun._euclidean_grid_3d. + _zpos.count() > +0) + { + /*-------------------------- write COORD data */ + _file << "COORD=3;" << + _ffun._euclidean_grid_3d. + _zpos.count() << "\n" ; + + for (auto _iter = _ffun. + _euclidean_grid_3d._zpos.head(); + _iter != _ffun. + _euclidean_grid_3d._zpos.tend(); + ++_iter ) + { + _file << *_iter << "\n" ; + } + } + + if (_ffun._euclidean_grid_3d. + _hmat.count() > +0) + { + /*-------------------------- write VALUE data */ + _file << "VALUE=" << + _ffun._euclidean_grid_3d. + _hmat.count() << ";1" "\n" ; + + for (auto _iter = _ffun. + _euclidean_grid_3d._hmat.head(); + _iter != _ffun. + _euclidean_grid_3d._hmat.tend(); + ++_iter ) + { + _file << *_iter << "\n" ; + } + } + + } + else + if (_ffun._ndim == +2 && + _ffun._kind == + jmsh_kind::ellipsoid_grid) + { + /*-------------------------- save 3-dim. mesh */ + _file << "# " << _name << ".msh" + << "; created by " ; + _file << __JGSWVSTR "\n" ; + _file << "MSHID=3;ELLIPSOID-GRID \n" ; + _file << "NDIMS=2 \n" ; + + _file << std::scientific ; + _file << + std::setprecision(16); + + /*-------------------------- write class data */ + + _file << "RADII=" << + _ffun._ellipsoid_grid_3d._radA + << ";" << + _ffun._ellipsoid_grid_3d._radB + << ";" << + _ffun._ellipsoid_grid_3d._radC + << "\n" ; + + if (_ffun._ellipsoid_grid_3d. + _xpos.count() > +0) + { + /*-------------------------- write COORD data */ + _file << "COORD=1;" << + _ffun._ellipsoid_grid_3d. + _xpos.count() << "\n" ; + + for (auto _iter = _ffun. + _ellipsoid_grid_3d._xpos.head(); + _iter != _ffun. + _ellipsoid_grid_3d._xpos.tend(); + ++_iter ) + { + _file << *_iter << "\n" ; + } + } + + if (_ffun._ellipsoid_grid_3d. + _ypos.count() > +0) + { + /*-------------------------- write COORD data */ + _file << "COORD=2;" << + _ffun._ellipsoid_grid_3d. + _ypos.count() << "\n" ; + + for (auto _iter = _ffun. + _ellipsoid_grid_3d._ypos.head(); + _iter != _ffun. + _ellipsoid_grid_3d._ypos.tend(); + ++_iter ) + { + _file << *_iter << "\n" ; + } + } + + if (_ffun._ellipsoid_grid_3d. + _hmat.count() > +0) + { + /*-------------------------- write VALUE data */ + _file << "VALUE=" << + _ffun._ellipsoid_grid_3d. + _hmat.count() << ";1" "\n" ; + + for (auto _iter = _ffun. + _ellipsoid_grid_3d._hmat.head(); + _iter != _ffun. + _ellipsoid_grid_3d._hmat.tend(); + ++_iter ) + { + _file << *_iter << "\n" ; + } + } + + } + + } + else + { + _errv = __file_not_created ; + } + + _file.close(); + + } + catch (...) + { + _errv = __unknown_error ; + } + + return ( _errv ) ; + } + + /* + -------------------------------------------------------- + * SAVE-MESH: save MSH_t output data. + -------------------------------------------------------- + */ + + template < + typename jlog_data + > + __normal_call iptr_type save_hfun ( + jcfg_data &_jcfg , + jlog_data &_jlog , + hfun_data &_ffun , + jigsaw_msh_t &_fmsh + ) + { + iptr_type _errv = __no_error ; + + // NB. this routine handles output for MARCHE --- only + // *overwriting* the "value" arrays in FMSH, since all + // else is passed read-only... + + try + { + __unreferenced (_jcfg) ; + __unreferenced (_jlog) ; + + if (_ffun._ndim == +2 && // save 2-dim. mesh + _ffun._kind == + jmsh_kind::euclidean_mesh) + { + _fmsh._flags = JIGSAW_EUCLIDEAN_MESH ; + + if (_ffun._euclidean_mesh_2d. + _hval.count() > +0) + { + /*-------------------------- write VALUE data */ + __assert( _fmsh._value._size == + _ffun._euclidean_mesh_2d. + _hval.count() && + "savemsh: inconsistent VALUE array") ; + + iptr_type _ipos = +0 ; + for (auto _iter = _ffun. + _euclidean_mesh_2d._hval.head(); + _iter != _ffun. + _euclidean_mesh_2d._hval.tend(); + ++_iter, ++_ipos) + { + _fmsh._value. + _data[_ipos] = *_iter ; + } + } + + } + else + if (_ffun._ndim == +3 && // save 3-dim. mesh + _ffun._kind == + jmsh_kind::euclidean_mesh) + { + _fmsh._flags = JIGSAW_EUCLIDEAN_MESH ; + + if (_ffun._euclidean_mesh_3d. + _hval.count() > +0) + { + /*-------------------------- write VALUE data */ + __assert( _fmsh._value._size == + _ffun._euclidean_mesh_3d. + _hval.count() && + "savemsh: inconsistent VALUE array") ; + + iptr_type _ipos = +0 ; + for (auto _iter = _ffun. + _euclidean_mesh_3d._hval.head(); + _iter != _ffun. + _euclidean_mesh_3d._hval.tend(); + ++_iter, ++_ipos) + { + _fmsh._value. + _data[_ipos] = *_iter ; + } + } + + } + else + if (_ffun._ndim == +2 && // save 2-sph. mesh + _ffun._kind == + jmsh_kind::ellipsoid_mesh) + { + _fmsh._flags = JIGSAW_ELLIPSOID_MESH ; + + if (_ffun._ellipsoid_mesh_3d. + _hval.count() > +0) + { + /*-------------------------- write VALUE data */ + __assert( _fmsh._value._size == + _ffun._ellipsoid_mesh_3d. + _hval.count() && + "savemsh: inconsistent VALUE array") ; + + iptr_type _ipos = +0 ; + for (auto _iter = _ffun. + _ellipsoid_mesh_3d._hval.head(); + _iter != _ffun. + _ellipsoid_mesh_3d._hval.tend(); + ++_iter, ++_ipos) + { + _fmsh._value. + _data[_ipos] = *_iter ; + } + } + + } + else + if (_ffun._ndim == +2 && // save 2-dim. grid + _ffun._kind == + jmsh_kind::euclidean_grid) + { + _fmsh._flags = JIGSAW_EUCLIDEAN_GRID ; + + if (_ffun._euclidean_grid_2d. + _hmat.count() > +0) + { + /*-------------------------- write VALUE data */ + __assert( _fmsh._value._size == + _ffun._euclidean_grid_2d. + _hmat.count() && + "savemsh: inconsistent VALUE array") ; + + iptr_type _ipos = +0 ; + for (auto _iter = _ffun. + _euclidean_grid_2d._hmat.head(); + _iter != _ffun. + _euclidean_grid_2d._hmat.tend(); + ++_iter, ++_ipos) + { + _fmsh._value. + _data[_ipos] = *_iter ; + } + } + + } + else + if (_ffun._ndim == +3 && // save 3-dim. grid + _ffun._kind == + jmsh_kind::euclidean_grid) + { + _fmsh._flags = JIGSAW_EUCLIDEAN_GRID ; + + if (_ffun._euclidean_grid_3d. + _hmat.count() > +0) + { + /*-------------------------- write VALUE data */ + __assert( _fmsh._value._size == + _ffun._euclidean_grid_3d. + _hmat.count() && + "savemsh: inconsistent VALUE array") ; + + iptr_type _ipos = +0 ; + for (auto _iter = _ffun. + _euclidean_grid_3d._hmat.head(); + _iter != _ffun. + _euclidean_grid_3d._hmat.tend(); + ++_iter, ++_ipos) + { + _fmsh._value. + _data[_ipos] = *_iter ; + } + } + + } + else + if (_ffun._ndim == +2 && // save 2-sph. grid + _ffun._kind == + jmsh_kind::ellipsoid_grid) + { + _fmsh._flags = JIGSAW_ELLIPSOID_GRID ; + + if (_ffun._ellipsoid_grid_3d. + _hmat.count() > +0) + { + /*-------------------------- write VALUE data */ + __assert( _fmsh._value._size == + _ffun._ellipsoid_grid_3d. + _hmat.count() && + "savemsh: inconsistent VALUE array") ; + + iptr_type _ipos = +0 ; + for (auto _iter = _ffun. + _ellipsoid_grid_3d._hmat.head(); + _iter != _ffun. + _ellipsoid_grid_3d._hmat.tend(); + ++_iter, ++_ipos) + { + _fmsh._value. + _data[_ipos] = *_iter ; + } + } + + } + } catch (...) { diff --git a/src/run_iter.hpp b/src/run_iter.hpp deleted file mode 100644 index 02724b1..0000000 --- a/src/run_iter.hpp +++ /dev/null @@ -1,408 +0,0 @@ - - /* - -------------------------------------------------------- - * RUN-ITER: do the mesh-optimisation step. - -------------------------------------------------------- - * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) - * - * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The - * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be - * used at your own risk. - * - -------------------------------------------------------- - * - * Last updated: 18 April, 2019 - * - * Copyright 2013-2019 - * Darren Engwirda - * de2363@columbia.edu - * https://github.com/dengwirda/ - * - -------------------------------------------------------- - */ - -# pragma once - -# ifndef __RUN_ITER__ -# define __RUN_ITER__ - - /* - -------------------------------------------------------- - * Call the 2-dimensional mesh optimiser. - -------------------------------------------------------- - */ - - template < - typename geom_type , - typename hfun_type , - typename mesh_type , - typename jlog_data - > - __normal_call void_type iter_euclidean_2d ( - geom_type &_geom , - hfun_type &_hfun , - mesh_type &_mesh , - jcfg_data &_args , - jlog_data &_jlog - ) - { - if (true) /* kernel? */ - { - typedef mesh:: - iter_pred_euclidean_2d < - real_type , - iptr_type > pred_type ; - - typedef mesh::iter_mesh_2 < - geom_type , - typename - mesh_type:: - mesh_type , - hfun_type , - pred_type > iter_func ; - - typedef - jcfg_data::iter_opts iter_opts ; - - iter_opts *_opts = - &_args._iter_opts; - - pred_type _pred ; - iter_func::iter_mesh( - _geom, _hfun , - _mesh. _mesh, - _pred, - *_opts, _jlog ) ; - } - } - - template < - typename geom_type , - typename hfun_type , - typename mesh_type , - typename jlog_data - > - __normal_call void_type iter_ellipsoid_3d ( - geom_type &_geom , - hfun_type &_hfun , - mesh_type &_mesh , - jcfg_data &_args , - jlog_data &_jlog - ) - { - if (true) /* kernel? */ - { - typedef mesh:: - iter_pred_ellipsoid_3d < - real_type , - iptr_type > pred_type ; - - typedef mesh::iter_mesh_2 < - geom_type , - typename - mesh_type:: - mesh_type , - hfun_type , - pred_type > iter_func ; - - typedef - jcfg_data::iter_opts iter_opts ; - - iter_opts *_opts = - &_args._iter_opts; - - pred_type _pred ; - iter_func::iter_mesh( - _geom, _hfun , - _mesh. _mesh, - _pred, - *_opts, _jlog ) ; - } - } - - /* - -------------------------------------------------------- - * Call the 3-dimensional mesh optimiser. - -------------------------------------------------------- - */ - - template < - typename geom_type , - typename hfun_type , - typename mesh_type , - typename jlog_data - > - __normal_call void_type iter_euclidean_3d ( - geom_type &_geom , - hfun_type &_hfun , - mesh_type &_mesh , - jcfg_data &_args , - jlog_data &_jlog - ) - { - - //!! yup... - - } - - /* - -------------------------------------------------------- - * ITER-MESH: call mesh optimiser. - -------------------------------------------------------- - */ - - template < - typename jlog_data - > - __normal_call iptr_type iter_mesh ( - jcfg_data &_args, - jlog_data &_jlog, - geom_data &_geom, - hfun_data &_hfun, - mesh_data &_mesh - ) - { - iptr_type _errv = __no_error ; - - try - { - if (_geom._ndim == +2 && - _geom._kind == - jmsh_kind::euclidean_mesh) - { - /*----------- have euclidean-mesh GEOM kernel */ - - if (_hfun._ndim == +0 ) - { - /*----------- with constant-value HFUN kernel */ - _mesh._kind = - jmsh_kind::euclidean_mesh; - - _mesh._ndim = +2 ; - - iter_euclidean_2d ( - _geom._euclidean_mesh_2d, - _hfun._constant_value_kd, - _mesh._euclidean_mesh_2d, - _args, _jlog) ; - } - else - if (_hfun._ndim == +2 && - _hfun._kind == - jmsh_kind::euclidean_mesh) - { - /*----------- with euclidean-mesh HFUN kernel */ - _mesh._kind = - jmsh_kind::euclidean_mesh; - - _mesh._ndim = +2 ; - - iter_euclidean_2d ( - _geom._euclidean_mesh_2d, - _hfun._euclidean_mesh_2d, - _mesh._euclidean_mesh_2d, - _args, _jlog) ; - } - else - if (_hfun._ndim == +2 && - _hfun._kind == - jmsh_kind::euclidean_grid) - { - /*----------- with euclidean-grid HFUN kernel */ - _mesh._kind = - jmsh_kind::euclidean_mesh; - - _mesh._ndim = +2 ; - - iter_euclidean_2d ( - _geom._euclidean_mesh_2d, - _hfun._euclidean_grid_2d, - _mesh._euclidean_mesh_2d, - _args, _jlog) ; - } - - } - else - if (_geom._ndim == +3 && - _geom._kind == - jmsh_kind::euclidean_mesh) - { - /*----------- have euclidean-mesh GEOM kernel */ - - if (_hfun._ndim == +0 ) - { - /*----------- with constant-value HFUN kernel */ - _mesh._kind = - jmsh_kind::euclidean_mesh; - - _mesh._ndim = +3 ; - - /* - iter_euclidean_3d ( - _geom._euclidean_mesh_3d, - _hfun._constant_value_kd, - _mesh._euclidean_mesh_3d, - _args, _jlog) ; - */ - } - else - if (_hfun._ndim == +3 && - _hfun._kind == - jmsh_kind::euclidean_mesh) - { - /*----------- with euclidean-mesh HFUN kernel */ - _mesh._kind = - jmsh_kind::euclidean_mesh; - - _mesh._ndim = +3 ; - - /* - iter_euclidean_3d ( - _geom._euclidean_mesh_3d, - _hfun._euclidean_mesh_3d, - _mesh._euclidean_mesh_3d, - _args, _jlog) ; - */ - } - else - if (_hfun._ndim == +3 && - _hfun._kind == - jmsh_kind::euclidean_grid) - { - /*----------- with euclidean-grid HFUN kernel */ - _mesh._kind = - jmsh_kind::euclidean_mesh; - - _mesh._ndim = +3 ; - - /* - iter_euclidean_3d ( - _geom._euclidean_mesh_3d, - _hfun._euclidean_grid_3d, - _mesh._euclidean_mesh_3d, - _args, _jlog) ; - */ - } - - } - if (_geom._kind == - jmsh_kind::ellipsoid_mesh) - { - /*----------- have ellipsoid-mesh GEOM kernel */ - - if (_hfun._ndim == +0 ) - { - /*----------- with constant-value HFUN kernel */ - _mesh._kind = - jmsh_kind::euclidean_mesh; - - _mesh._ndim = +3 ; - - iter_ellipsoid_3d ( - _geom._ellipsoid_mesh_3d, - _hfun._constant_value_kd, - _mesh._euclidean_mesh_3d, - _args, _jlog) ; - } - else - if (_hfun._kind == - jmsh_kind::ellipsoid_grid) - { - /*----------- with ellipsoid-grid HFUN kernel */ - _mesh._kind = - jmsh_kind::euclidean_mesh; - - _mesh._ndim = +3 ; - - iter_ellipsoid_3d ( - _geom._ellipsoid_mesh_3d, - _hfun._ellipsoid_grid_3d, - _mesh._euclidean_mesh_3d, - _args, _jlog) ; - } - else - if (_hfun._kind == - jmsh_kind::ellipsoid_mesh) - { - /*----------- with ellipsoid-mesh HFUN kernel */ - _mesh._kind = - jmsh_kind::euclidean_mesh; - - _mesh._ndim = +3 ; - - iter_ellipsoid_3d ( - _geom._ellipsoid_mesh_3d, - _hfun._ellipsoid_mesh_3d, - _mesh._euclidean_mesh_3d, - _args, _jlog) ; - } - else - if (_hfun._ndim == +3 && - _hfun._kind == - jmsh_kind::euclidean_mesh) - { - /*----------- with euclidean-mesh HFUN kernel */ - _mesh._kind = - jmsh_kind::euclidean_mesh; - - _mesh._ndim = +3 ; - - iter_ellipsoid_3d ( - _geom._ellipsoid_mesh_3d, - _hfun._euclidean_mesh_3d, - _mesh._euclidean_mesh_3d, - _args, _jlog) ; - } - else - if (_hfun._ndim == +3 && - _hfun._kind == - jmsh_kind::euclidean_grid) - { - /*----------- with euclidean-grid HFUN kernel */ - _mesh._kind = - jmsh_kind::euclidean_mesh; - - _mesh._ndim = +3 ; - - iter_ellipsoid_3d ( - _geom._ellipsoid_mesh_3d, - _hfun._euclidean_grid_3d, - _mesh._euclidean_mesh_3d, - _args, _jlog) ; - } - - } - } - catch (...) - { - _errv = __unknown_error ; - } - - return ( _errv ) ; - } - - -# endif //__RUN_ITER__ - - - diff --git a/src/run_mesh.hpp b/src/run_mesh.hpp deleted file mode 100644 index ab1c920..0000000 --- a/src/run_mesh.hpp +++ /dev/null @@ -1,454 +0,0 @@ - - /* - -------------------------------------------------------- - * RUN-MESH: do the mesh-generation step. - -------------------------------------------------------- - * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) - * - * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The - * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be - * used at your own risk. - * - -------------------------------------------------------- - * - * Last updated: 18 April, 2019 - * - * Copyright 2013-2019 - * Darren Engwirda - * de2363@columbia.edu - * https://github.com/dengwirda/ - * - -------------------------------------------------------- - */ - -# pragma once - -# ifndef __RUN_MESH__ -# define __RUN_MESH__ - - /* - -------------------------------------------------------- - * Call the 2-dimensional mesh generator. - -------------------------------------------------------- - */ - - template < - typename geom_type , - typename init_type , - typename hfun_type , - typename mesh_type , - typename jlog_data - > - __normal_call void_type mesh_euclidean_2d ( - geom_type &_geom, - init_type &_init, - hfun_type &_hfun, - mesh_type &_mesh, - jcfg_data &_args, - jlog_data &_jlog - ) - { - if (_args._mesh_pred == - jcfg_data::mesh_pred::delaunay) - { - /*-------------------------- call DELAUNAY kernel */ - typedef - mesh::rdel_delaunay_2d < - geom_type , - hfun_type , - mesh_type > rdel_pred ; - - typedef mesh::rdel_mesh_2d < - mesh_type , - rdel_pred , - geom_type , - hfun_type > rdel_func ; - - typedef - jcfg_data::rdel_opts rdel_opts ; - - rdel_opts *_opts = - &_args._rdel_opts; - - rdel_func::rdel_mesh( - _geom, _init , - _hfun, _mesh , - *_opts, _jlog ) ; - } - else - if (_args._mesh_pred == - jcfg_data::mesh_pred::delfront) - { - /*-------------------------- call DELFRONT kernel */ - typedef - mesh::rdel_delfront_2d < - geom_type , - hfun_type , - mesh_type > rdel_pred ; - - typedef mesh::rdel_mesh_2d < - mesh_type , - rdel_pred , - geom_type , - hfun_type > rdel_func ; - - typedef - jcfg_data::rdel_opts rdel_opts ; - - rdel_opts *_opts = - &_args._rdel_opts; - - rdel_func::rdel_mesh( - _geom, _init , - _hfun, _mesh , - *_opts, _jlog ) ; - } - } - - /* - -------------------------------------------------------- - * Call the 3-dimensional mesh generator. - -------------------------------------------------------- - */ - - template < - typename geom_type , - typename init_type , - typename hfun_type , - typename mesh_type , - typename jlog_data - > - __normal_call void_type mesh_euclidean_3d ( - geom_type &_geom, - init_type &_init, - hfun_type &_hfun, - mesh_type &_mesh, - jcfg_data &_args, - jlog_data &_jlog - ) - { - if (_args._mesh_pred == - jcfg_data::mesh_pred::delaunay) - { - /*-------------------------- call DELAUNAY kernel */ - typedef - mesh::rdel_delaunay_3d < - geom_type , - hfun_type , - mesh_type > rdel_pred ; - - typedef mesh::rdel_mesh_3d < - mesh_type , - rdel_pred , - geom_type , - hfun_type > rdel_func ; - - typedef - jcfg_data::rdel_opts rdel_opts ; - - rdel_opts *_opts = - &_args._rdel_opts; - - rdel_func::rdel_mesh( - _geom, _init , - _hfun, _mesh , - *_opts, _jlog ) ; - } - else - if (_args._mesh_pred == - jcfg_data::mesh_pred::delfront) - { - /*-------------------------- call DELFRONT kernel */ - typedef - mesh::rdel_delfront_3d < - geom_type , - hfun_type , - mesh_type > rdel_pred ; - - typedef mesh::rdel_mesh_3d < - mesh_type , - rdel_pred , - geom_type , - hfun_type > rdel_func ; - - typedef - jcfg_data::rdel_opts rdel_opts ; - - rdel_opts *_opts = - &_args._rdel_opts; - - rdel_func::rdel_mesh( - _geom, _init , - _hfun, _mesh , - *_opts, _jlog ) ; - } - } - - /* - -------------------------------------------------------- - * MAKE-MESH: call mesh generator. - -------------------------------------------------------- - */ - - template < - typename jlog_data - > - __normal_call iptr_type make_mesh ( - jcfg_data &_args, - jlog_data &_jlog, - geom_data &_geom, - mesh_data &_init, - hfun_data &_hfun, - rdel_data &_rdel - ) - { - iptr_type _errv = __no_error ; - - try - { - if (_geom._ndim == +2 && - _geom._kind == - jmsh_kind::euclidean_mesh) - { - /*----------- have euclidean-mesh GEOM kernel */ - - if (_hfun._ndim == +0 ) - { - /*----------- with constant-value HFUN kernel */ - _rdel._kind = - jmsh_kind::euclidean_mesh; - - _rdel._ndim = +2 ; - - mesh_euclidean_2d ( - _geom._euclidean_mesh_2d, - _init._euclidean_mesh_2d, - _hfun._constant_value_kd, - _rdel._euclidean_rdel_2d, - _args, _jlog) ; - } - else - if (_hfun._ndim == +2 && - _hfun._kind == - jmsh_kind::euclidean_mesh) - { - /*----------- with euclidean-mesh HFUN kernel */ - _rdel._kind = - jmsh_kind::euclidean_mesh; - - _rdel._ndim = +2 ; - - mesh_euclidean_2d ( - _geom._euclidean_mesh_2d, - _init._euclidean_mesh_2d, - _hfun._euclidean_mesh_2d, - _rdel._euclidean_rdel_2d, - _args, _jlog) ; - } - else - if (_hfun._ndim == +2 && - _hfun._kind == - jmsh_kind::euclidean_grid) - { - /*----------- with euclidean-grid HFUN kernel */ - _rdel._kind = - jmsh_kind::euclidean_mesh; - - _rdel._ndim = +2 ; - - mesh_euclidean_2d ( - _geom._euclidean_mesh_2d, - _init._euclidean_mesh_2d, - _hfun._euclidean_grid_2d, - _rdel._euclidean_rdel_2d, - _args, _jlog) ; - } - - } - else - if (_geom._ndim == +3 && - _geom._kind == - jmsh_kind::euclidean_mesh) - { - /*----------- have euclidean-mesh GEOM kernel */ - - if (_hfun._ndim == +0 ) - { - /*----------- with constant-value HFUN kernel */ - _rdel._kind = - jmsh_kind::euclidean_mesh; - - _rdel._ndim = +3 ; - - mesh_euclidean_3d ( - _geom._euclidean_mesh_3d, - _init._euclidean_mesh_3d, - _hfun._constant_value_kd, - _rdel._euclidean_rdel_3d, - _args, _jlog) ; - } - else - if (_hfun._ndim == +3 && - _hfun._kind == - jmsh_kind::euclidean_mesh) - { - /*----------- with euclidean-mesh HFUN kernel */ - _rdel._kind = - jmsh_kind::euclidean_mesh; - - _rdel._ndim = +3 ; - - mesh_euclidean_3d ( - _geom._euclidean_mesh_3d, - _init._euclidean_mesh_3d, - _hfun._euclidean_mesh_3d, - _rdel._euclidean_rdel_3d, - _args, _jlog) ; - } - else - if (_hfun._ndim == +3 && - _hfun._kind == - jmsh_kind::euclidean_grid) - { - /*----------- with euclidean-grid HFUN kernel */ - _rdel._kind = - jmsh_kind::euclidean_mesh; - - _rdel._ndim = +3 ; - - mesh_euclidean_3d ( - _geom._euclidean_mesh_3d, - _init._euclidean_mesh_3d, - _hfun._euclidean_grid_3d, - _rdel._euclidean_rdel_3d, - _args, _jlog) ; - } - - } - else - if (_geom._kind == - jmsh_kind::ellipsoid_mesh) - { - /*----------- have ellipsoid-mesh GEOM kernel */ - - if (_hfun._ndim == +0 ) - { - /*----------- with constant-value HFUN kernel */ - _rdel._kind = - jmsh_kind::euclidean_mesh; - - _rdel._ndim = +3 ; - - mesh_euclidean_3d ( - _geom._ellipsoid_mesh_3d, - _init._euclidean_mesh_3d, - _hfun._constant_value_kd, - _rdel._euclidean_rdel_3d, - _args, _jlog) ; - } - else - if (_hfun._kind == - jmsh_kind::ellipsoid_grid) - { - /*----------- with ellipsoid-grid HFUN kernel */ - _rdel._kind = - jmsh_kind::euclidean_mesh; - - _rdel._ndim = +3 ; - - mesh_euclidean_3d ( - _geom._ellipsoid_mesh_3d, - _init._euclidean_mesh_3d, - _hfun._ellipsoid_grid_3d, - _rdel._euclidean_rdel_3d, - _args, _jlog) ; - } - else - if (_hfun._kind == - jmsh_kind::ellipsoid_mesh) - { - /*----------- with ellipsoid-mesh HFUN kernel */ - _rdel._kind = - jmsh_kind::euclidean_mesh; - - _rdel._ndim = +3 ; - - mesh_euclidean_3d ( - _geom._ellipsoid_mesh_3d, - _init._euclidean_mesh_3d, - _hfun._ellipsoid_mesh_3d, - _rdel._euclidean_rdel_3d, - _args, _jlog) ; - } - else - if (_hfun._ndim == +3 && - _hfun._kind == - jmsh_kind::euclidean_mesh) - { - /*----------- with euclidean-mesh HFUN kernel */ - _rdel._kind = - jmsh_kind::euclidean_mesh; - - _rdel._ndim = +3 ; - - mesh_euclidean_3d ( - _geom._ellipsoid_mesh_3d, - _init._euclidean_mesh_3d, - _hfun._euclidean_mesh_3d, - _rdel._euclidean_rdel_3d, - _args, _jlog) ; - } - else - if (_hfun._ndim == +3 && - _hfun._kind == - jmsh_kind::euclidean_grid) - { - /*----------- with euclidean-grid HFUN kernel */ - _rdel._kind = - jmsh_kind::euclidean_mesh; - - _rdel._ndim = +3 ; - - mesh_euclidean_3d ( - _geom._ellipsoid_mesh_3d, - _init._euclidean_mesh_3d, - _hfun._euclidean_grid_3d, - _rdel._euclidean_rdel_3d, - _args, _jlog) ; - } - - } - } - catch (...) - { - _errv = __unknown_error ; - } - - return ( _errv ) ; - } - - -# endif //__RUN_MESH__ - - - diff --git a/src/run_tria.hpp b/src/run_tria.hpp deleted file mode 100644 index 0040dbe..0000000 --- a/src/run_tria.hpp +++ /dev/null @@ -1,205 +0,0 @@ - - - /* - -------------------------------------------------------- - * RUN-TRIA: do the restricted tessellation step. - -------------------------------------------------------- - * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) - * - * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The - * University of Sydney, nor The National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be - * used at your own risk. - * - -------------------------------------------------------- - * - * Last updated: 28 December, 2018 - * - * Copyright 2013-2018 - * Darren Engwirda - * de2363@columbia.edu - * https://github.com/dengwirda/ - * - -------------------------------------------------------- - */ - -# pragma once - -# ifndef __RUN_TRIA__ -# define __RUN_TRIA__ - - /* - -------------------------------------------------------- - * Call the 2-dimensional tessellator. - -------------------------------------------------------- - */ - - template < - typename geom_type , - typename init_type , - typename rdel_type , - typename jlog_data - > - __normal_call void_type rdel_euclidean_2d ( - geom_type &_geom, - init_type &_init, - rdel_type &_rdel, - jcfg_data &_args, - jlog_data &_jlog - ) - { - /*------------------------------ call rDEL kernel */ - typedef mesh::rdel_make_2d < - rdel_type , - geom_type > rdel_func ; - - typedef - jcfg_data::rdel_opts rdel_opts ; - - rdel_opts *_opts = - &_args._rdel_opts ; - - rdel_func::rdel_make ( - _geom, _init , - _rdel, *_opts , _jlog ) ; - } - - /* - -------------------------------------------------------- - * Call the 3-dimensional tessellator. - -------------------------------------------------------- - */ - - template < - typename geom_type , - typename init_type , - typename rdel_type , - typename jlog_data - > - __normal_call void_type rdel_euclidean_3d ( - geom_type &_geom, - init_type &_init, - rdel_type &_rdel, - jcfg_data &_args, - jlog_data &_jlog - ) - { - /*------------------------------ call rDEL kernel */ - typedef mesh::rdel_make_3d < - rdel_type , - geom_type > rdel_func ; - - typedef - jcfg_data::rdel_opts rdel_opts ; - - rdel_opts *_opts = - &_args._rdel_opts ; - - rdel_func::rdel_make ( - _geom, _init , - _rdel, *_opts , _jlog ) ; - } - - /* - -------------------------------------------------------- - * MAKE-RDEL: call the tessellator. - -------------------------------------------------------- - */ - - template < - typename jlog_data - > - __normal_call iptr_type make_rdel ( - jcfg_data &_args, - jlog_data &_jlog, - mesh_data &_init, - geom_data &_geom, - rdel_data &_rdel - ) - { - iptr_type _errv = __no_error ; - - try - { - if (_geom._ndim == +2 && - _geom._kind == - jmsh_kind::euclidean_mesh) - { - /*----------- have euclidean-mesh GEOM kernel */ - _rdel._kind = - jmsh_kind::euclidean_mesh; - - _rdel._ndim = +2 ; - - rdel_euclidean_2d ( - _geom._euclidean_mesh_2d, - _init._euclidean_mesh_2d, - _rdel._euclidean_rdel_2d, - _args, _jlog) ; - } - else - if (_geom._ndim == +3 && - _geom._kind == - jmsh_kind::euclidean_mesh) - { - /*----------- have euclidean-mesh GEOM kernel */ - _rdel._kind = - jmsh_kind::euclidean_mesh; - - _rdel._ndim = +3 ; - - rdel_euclidean_3d ( - _geom._euclidean_mesh_3d, - _init._euclidean_mesh_3d, - _rdel._euclidean_rdel_3d, - _args, _jlog) ; - } - else - if (_geom._kind == - jmsh_kind::ellipsoid_mesh) - { - /*----------- have ellipsoid-mesh GEOM kernel */ - _rdel._kind = - jmsh_kind::euclidean_mesh; - - _rdel._ndim = +3 ; - - rdel_euclidean_3d ( - _geom._ellipsoid_mesh_3d, - _init._euclidean_mesh_3d, - _rdel._euclidean_rdel_3d, - _args, _jlog) ; - } - } - catch (...) - { - _errv = __unknown_error ; - } - - return ( _errv ) ; - } - - -# endif // __RUN_TRIA__ - - - diff --git a/src/tripod.hpp b/src/tripod.hpp index 1480cab..8551fb8 100644 --- a/src/tripod.hpp +++ b/src/tripod.hpp @@ -2,19 +2,19 @@ /* -------------------------------------------------------- * - * ,o, ,o, / + * ,o, ,o, / * ` ` e88~88e d88~\ /~~~8e Y88b e / - * 888 888 88 88 C888 88b Y88b d8b / - * 888 888 "8b_d8" Y88b e88~-888 Y888/Y88b/ - * 888 888 / 888D C88 888 Y8/ Y8/ - * 88P 888 Cb \_88P "8b_-888 Y Y - * \_8" Y8""8D + * 888 888 88 88 C888 88b Y88b d8b / + * 888 888 "8b_d8" Y88b e88~-888 Y888/Y88b/ + * 888 888 / 888D C88 888 Y8/ Y8/ + * 88P 888 Cb \_88P "8b_-888 Y Y + * \_8" Y8""8D * -------------------------------------------------------- * TRIPOD: a "restricted" delaunay tessellator. -------------------------------------------------------- * - * Last updated: 19 January, 2019 + * Last updated: 02 July, 2019 * * Copyright 2013 -- 2019 * Darren Engwirda @@ -22,44 +22,38 @@ * https://github.com/dengwirda * -------------------------------------------------------- - * - * This program may be freely redistributed under the - * condition that the copyright notices (including this - * entire header) are not removed, and no compensation - * is received through use of the software. Private, - * research, and institutional use is free. You may - * distribute modified versions of this code UNDER THE - * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE - * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE - * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE - * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR - * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution - * of this code as part of a commercial system is - * permissible ONLY BY DIRECT ARRANGEMENT WITH THE - * AUTHOR. (If you are not directly supplying this - * code to a customer, and you are instead telling them - * how they can obtain it for free, then you are not - * required to make any arrangement with me.) + * + * This program may be freely redistributed under the + * condition that the copyright notices (including this + * entire header) are not removed, and no compensation + * is received through use of the software. Private, + * research, and institutional use is free. You may + * distribute modified versions of this code UNDER THE + * CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE + * TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE + * ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE + * MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR + * NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution + * of this code as part of a commercial system is + * permissible ONLY BY DIRECT ARRANGEMENT WITH THE + * AUTHOR. (If you are not directly supplying this + * code to a customer, and you are instead telling them + * how they can obtain it for free, then you are not + * required to make any arrangement with me.) * * Disclaimer: Neither I nor: Columbia University, The - * Massachusetts Institute of Technology, The + * Massachusetts Institute of Technology, The * University of Sydney, nor the National Aeronautics - * and Space Administration warrant this code in any - * way whatsoever. This code is provided "as-is" to be + * and Space Administration warrant this code in any + * way whatsoever. This code is provided "as-is" to be * used at your own risk. * -------------------------------------------------------- */ - - template < - typename jlog_data - > - __normal_call void_type tripod_banner ( - jlog_data &_jlog - ) - { - /*-- NB: silliness re. escape sequences */ - _jlog.push ( + + namespace TRIPOD { + + std::string asciibanner = " \n" "#------------------------------------------------------------\n" "#\n" @@ -75,10 +69,167 @@ "# TRIPOD: a \"restricted\" delaunay tessellator. \n" "#------------------------------------------------------------\n" " \n" - " " __JGSWVSTR "\n\n" - ) ; + " " __JGSWVSTR "\n\n" ; + + /* + -------------------------------------------------------- + * Call the 2-dimensional tessellator. + -------------------------------------------------------- + */ + + template < + typename geom_type , + typename init_type , + typename rdel_type , + typename jlog_data + > + __normal_call void_type rdel_euclidean_2d ( + geom_type &_geom, + init_type &_init, + rdel_type &_rdel, + jcfg_data &_args, + jlog_data &_jlog + ) + { + { + /*------------------------------ call rDEL kernel */ + typedef mesh::rdel_make_2d < + rdel_type , + geom_type , + init_type > rdel_func ; + + typedef + jcfg_data::mesh_opts rdel_opts ; + + rdel_opts *_opts = + &_args._mesh_opts ; + + rdel_func::rdel_make ( + _geom, _init , + _rdel, *_opts , _jlog ) ; + } + } + + /* + -------------------------------------------------------- + * Call the 3-dimensional tessellator. + -------------------------------------------------------- + */ + + template < + typename geom_type , + typename init_type , + typename rdel_type , + typename jlog_data + > + __normal_call void_type rdel_euclidean_3d ( + geom_type &_geom, + init_type &_init, + rdel_type &_rdel, + jcfg_data &_args, + jlog_data &_jlog + ) + { + { + /*------------------------------ call rDEL kernel */ + typedef mesh::rdel_make_3d < + rdel_type , + geom_type , + init_type > rdel_func ; + + typedef + jcfg_data::mesh_opts rdel_opts ; + + rdel_opts *_opts = + &_args._mesh_opts ; + + rdel_func::rdel_make ( + _geom, _init , + _rdel, *_opts , _jlog ) ; + } } - + + /* + -------------------------------------------------------- + * Call the k-dimensional tessellator. + -------------------------------------------------------- + */ + + template < + typename jlog_data + > + __normal_call iptr_type rdel_impl ( + jcfg_data &_args, + jlog_data &_jlog, + mesh_data &_init, + geom_data &_geom, + rdel_data &_rdel + ) + { + iptr_type _errv = __no_error ; + + try + { + if (_geom._ndim == +2 && + _geom._kind == + jmsh_kind::euclidean_mesh) + { + /*----------- have euclidean-mesh GEOM kernel */ + _rdel._kind = + jmsh_kind::euclidean_mesh; + + _rdel._ndim = +2 ; + + rdel_euclidean_2d ( + _geom._euclidean_mesh_2d, + _init._euclidean_mesh_2d, + _rdel._euclidean_rdel_2d, + _args, _jlog) ; + } + else + if (_geom._ndim == +3 && + _geom._kind == + jmsh_kind::euclidean_mesh) + { + /*----------- have euclidean-mesh GEOM kernel */ + _rdel._kind = + jmsh_kind::euclidean_mesh; + + _rdel._ndim = +3 ; + + rdel_euclidean_3d ( + _geom._euclidean_mesh_3d, + _init._euclidean_mesh_3d, + _rdel._euclidean_rdel_3d, + _args, _jlog) ; + } + else + if (_geom._kind == + jmsh_kind::ellipsoid_mesh) + { + /*----------- have ellipsoid-mesh GEOM kernel */ + _rdel._kind = + jmsh_kind::euclidean_mesh; + + _rdel._ndim = +3 ; + + rdel_euclidean_3d ( + _geom._ellipsoid_mesh_3d, + _init._euclidean_mesh_3d, + _rdel._euclidean_rdel_3d, + _args, _jlog) ; + } + } + catch (...) + { + _errv = __unknown_error ; + } + + return ( _errv ) ; + } + + } + # ifdef __lib_jigsaw # include "liblib/init_jig_t.hpp" @@ -89,7 +240,7 @@ # include "liblib/save_jig_t.hpp" # include "liblib/save_msh_t.hpp" - + __normal_call iptr_type tripod ( // lib-jigsaw jigsaw_jig_t *_jjig , jigsaw_msh_t *_imsh , @@ -98,12 +249,12 @@ ) { iptr_type _retv = +0; - + mesh_data _init ; // INIT data geom_data _geom ; // GEOM data rdel_data _rdel ; // TRIA data jcfg_data _jcfg ; - + # ifdef __use_timers typename std ::chrono:: high_resolution_clock:: @@ -113,38 +264,39 @@ time_point _ttoc ; typename std ::chrono:: high_resolution_clock _time; - + __unreferenced(_time) ; # endif//__use_timers - - /*--------------------------------- init. output data */ + + /*--------------------------------- init. output data */ jigsaw_init_msh_t(_mmsh) ; - + /*--------------------------------- setup *.JLOG data */ if (_jjig != nullptr ) { _jcfg._verbosity = _jjig->_verbosity ; } - jlog_null _jlog(_jcfg) ; - tripod_banner (_jlog) ; - + jlog_null _jlog(_jcfg) ; + _jlog.push(TRIPOD:: + asciibanner) ; + /*--------------------------------- parse *.JCFG data */ if (_jjig != nullptr ) { _jlog.push ( " Reading CFG. data...\n\n" ) ; -# ifdef __use_timers +# ifdef __use_timers _ttic = _time.now(); # endif//__use_timers - + if ((_retv = copy_jcfg ( - _jcfg, + _jcfg, _jlog,*_jjig)) != __no_error) { return _retv ; - } - + } + if ((_retv = test_jcfg ( _jcfg, _jlog)) != __no_error) { @@ -160,58 +312,58 @@ return _retv ; } -# ifdef __use_timers +# ifdef __use_timers _ttoc = _time.now(); _jlog.push(dump_time(_ttic, _ttoc)); # endif//__use_timers } - + if (_imsh != nullptr ) { /*--------------------------------- parse *.INIT data */ _jlog.push ( __jloglndv "\n" ) ; _jlog.push ( " Reading INIT data...\n\n" ) ; - + # ifdef __use_timers _ttic = _time.now(); # endif//__use_timers if ((_retv = copy_init ( - _jcfg, _jlog, + _jcfg, _jlog, _init,*_imsh)) != __no_error) { return _retv ; } if ((_retv = test_init ( - _jcfg, + _jcfg, _jlog, _init)) != __no_error) { return _retv ; } - + # ifdef __use_timers _ttoc = _time.now(); _jlog.push(dump_time(_ttic, _ttoc)); # endif//__use_timers } - + if (_imsh != nullptr ) { /*--------------------------------- assemble init-con */ _jlog.push ( __jloglndv "\n" ) ; _jlog.push ( " Forming INIT data...\n\n" ) ; - + # ifdef __use_timers _ttic = _time.now(); # endif//__use_timers - _init._euclidean_mesh_2d. - _mesh.make_ptrs(); - _init._euclidean_mesh_3d. - _mesh.make_ptrs(); + //_init._euclidean_mesh_2d. + // _mesh.make_link(); + //_init._euclidean_mesh_3d. + // _mesh.make_link(); if (_jcfg._verbosity > 0 ) { @@ -220,64 +372,64 @@ " INIT data summary...\n\n" ) ; if ((_retv = echo_init ( - _jcfg, + _jcfg, _jlog, _init)) != __no_error) { return _retv ; } - + } - + # ifdef __use_timers _ttoc = _time.now(); _jlog.push(dump_time(_ttic, _ttoc)); # endif//__use_timers } - + if (_gmsh != nullptr ) { /*--------------------------------- parse *.GEOM data */ _jlog.push ( __jloglndv "\n" ) ; _jlog.push ( " Reading GEOM data...\n\n" ) ; - + # ifdef __use_timers _ttic = _time.now(); # endif//__use_timers if ((_retv = copy_geom ( - _jcfg, _jlog , + _jcfg, _jlog , _geom,*_gmsh)) != __no_error) { return _retv ; } - + if ((_retv = test_geom ( - _jcfg, + _jcfg, _jlog, _geom)) != __no_error) { return _retv ; } - + # ifdef __use_timers _ttoc = _time.now(); _jlog.push(dump_time(_ttic, _ttoc)); # endif//__use_timers } - + if (_gmsh != nullptr ) { /*--------------------------------- parse *.GEOM data */ _jlog.push ( __jloglndv "\n" ) ; _jlog.push ( " Forming GEOM data...\n\n" ) ; - + # ifdef __use_timers _ttic = _time.now(); # endif//__use_timers _geom.init_geom(_jcfg) ; - + if (_jcfg._verbosity > 0 ) { @@ -285,12 +437,12 @@ " GEOM data summary...\n\n" ) ; if ((_retv = echo_geom ( - _jcfg, + _jcfg, _jlog, _geom)) != __no_error) { return _retv ; } - + } # ifdef __use_timers @@ -298,7 +450,7 @@ _jlog.push(dump_time(_ttic, _ttoc)); # endif//__use_timers } - + if (_imsh != nullptr ) { /*--------------------------------- call rDEL routine */ @@ -310,44 +462,61 @@ _ttic = _time.now(); # endif//__use_timers - if ((_retv = make_rdel ( + if ((_retv = + TRIPOD ::rdel_impl ( _jcfg, _jlog , - _init, + _init, _geom, _rdel)) != __no_error) { return _retv ; } -# ifdef __use_timers +# ifdef __use_timers _ttoc = _time.now(); _jlog.push(dump_time(_ttic, _ttoc)); # endif//__use_timers } - + if (_mmsh != nullptr ) { /*--------------------------------- dump mesh to data */ _jlog.push ( __jloglndv "\n" ) ; _jlog.push ( - " Writing MESH file...\n\n" ) ; + " Writing MESH data...\n\n" ) ; # ifdef __use_timers _ttic = _time.now(); # endif//__use_timers - if ((_retv = save_msht ( - _jcfg, _jlog , + if (_jcfg._mesh_opts.dims() >= +1) + { + + if ((_retv = save_rdel ( + _jcfg, _jlog , + _rdel,*_mmsh)) != __no_error) + { + return _retv ; + } + + } + else + { + + if ((_retv = save_tria ( + _jcfg, _jlog , _rdel,*_mmsh)) != __no_error) { return _retv ; } - -# ifdef __use_timers + + } + +# ifdef __use_timers _ttoc = _time.now(); _jlog.push(dump_time(_ttic, _ttoc)); # endif//__use_timers } - + /*-------------------------- success, if we got here! */ return ( _retv ) ; @@ -358,14 +527,14 @@ # if defined(__cmd_tripod) __normal_call iptr_type main ( // cmd-tripod - int _argc , + int _argc , char **_argv ) { mesh_data _init ; // INIT data geom_data _geom ; // GEOM data rdel_data _rdel ; // TRIA data - + # ifdef __use_timers typename std ::chrono:: high_resolution_clock:: @@ -375,33 +544,50 @@ time_point _ttoc ; typename std ::chrono:: high_resolution_clock _time; - + __unreferenced(_time) ; # endif//__use_timers - - /*-------------------------- find *.JFCG file in args */ + + /*-------------------------- find *.JFCG file in args */ iptr_type _retv = -1 ; jcfg_data _jcfg ; for (; _argc-- != +0; ) { std::string _ssrc(_argv[_argc]) ; - - std::string _path ; - std::string _name ; - std::string _fext ; - file_part ( _ssrc , - _path , _name , _fext) ; - if (_ssrc.find("-whoami") == 0) + if (_ssrc.find("-h") == 0 || + _ssrc.find( + "--help") == 0 ) { _retv = -2 ; - + + std::cout << + "run tripod jigname.jig"; + std::cout << std::endl ; + + break ; + } + + if (_ssrc.find("-v") == 0 || + _ssrc.find( + "--version") == 0 || + _ssrc.find( + "-whoami") == 0 ) + { + _retv = -2 ; + std::cout << __JGSWVSTR ; std::cout << std::endl ; - + break ; } + std::string _path ; + std::string _name ; + std::string _fext ; + file_part ( _ssrc , + _path , _name , _fext ) ; + if (_fext.find("jig") == 0) { _retv = +0 ; @@ -417,25 +603,26 @@ if (_retv != +0) return ( _retv ) ; /*--------------------------------- setup *.JLOG file */ - jlog_text _jlog(_jcfg) ; - tripod_banner (_jlog) ; - + jlog_text _jlog(_jcfg) ; + _jlog.push(TRIPOD:: + asciibanner) ; + if(!_jcfg._jcfg_file.empty()) { /*--------------------------------- parse *.JCFG file */ _jlog.push ( " Reading CFG. file...\n\n" ) ; - + # ifdef __use_timers _ttic = _time.now(); # endif//__use_timers - + if ((_retv = read_jcfg ( _jcfg, _jlog)) != __no_error) { return _retv ; - } - + } + if ((_retv = test_jcfg ( _jcfg, _jlog)) != __no_error) { @@ -450,59 +637,59 @@ { return _retv ; } - + # ifdef __use_timers _ttoc = _time.now(); _jlog.push(dump_time(_ttic, _ttoc)); # endif//__use_timers } - + if(!_jcfg._init_file.empty()) { /*--------------------------------- parse *.INIT file */ _jlog.push ( __jloglndv "\n" ) ; _jlog.push ( " Reading INIT file...\n\n" ) ; - + # ifdef __use_timers _ttic = _time.now(); # endif//__use_timers if ((_retv = read_init ( - _jcfg, + _jcfg, _jlog, _init)) != __no_error) { return _retv ; } if ((_retv = test_init ( - _jcfg, + _jcfg, _jlog, _init)) != __no_error) { return _retv ; } - + # ifdef __use_timers _ttoc = _time.now(); _jlog.push(dump_time(_ttic, _ttoc)); # endif//__use_timers } - + if(!_jcfg._init_file.empty()) { /*--------------------------------- assemble init-con */ _jlog.push ( __jloglndv "\n" ) ; _jlog.push ( " Forming INIT data...\n\n" ) ; - + # ifdef __use_timers _ttic = _time.now(); # endif//__use_timers - _init._euclidean_mesh_2d. - _mesh.make_ptrs(); - _init._euclidean_mesh_3d. - _mesh.make_ptrs(); + //_init._euclidean_mesh_2d. + // _mesh.make_link(); + //_init._euclidean_mesh_3d. + // _mesh.make_link(); if (_jcfg._verbosity > 0 ) { @@ -511,40 +698,40 @@ " INIT data summary...\n\n" ) ; if ((_retv = echo_init ( - _jcfg, + _jcfg, _jlog, _init)) != __no_error) { return _retv ; } - + } - + # ifdef __use_timers _ttoc = _time.now(); _jlog.push(dump_time(_ttic, _ttoc)); # endif//__use_timers } - + if(!_jcfg._geom_file.empty()) { /*--------------------------------- parse *.GEOM file */ _jlog.push ( __jloglndv "\n" ) ; _jlog.push ( " Reading GEOM file...\n\n" ) ; - + # ifdef __use_timers _ttic = _time.now(); # endif//__use_timers if ((_retv = read_geom ( - _jcfg, + _jcfg, _jlog, _geom)) != __no_error) { return _retv ; } if ((_retv = test_geom ( - _jcfg, + _jcfg, _jlog, _geom)) != __no_error) { return _retv ; @@ -562,13 +749,13 @@ _jlog.push ( __jloglndv "\n" ) ; _jlog.push ( " Forming GEOM data...\n\n" ) ; - + # ifdef __use_timers _ttic = _time.now(); # endif//__use_timers _geom.init_geom(_jcfg) ; - + if (_jcfg._verbosity > 0 ) { @@ -576,12 +763,12 @@ " GEOM data summary...\n\n" ) ; if ((_retv = echo_geom ( - _jcfg, + _jcfg, _jlog, _geom)) != __no_error) { return _retv ; } - + } # ifdef __use_timers @@ -589,7 +776,7 @@ _jlog.push(dump_time(_ttic, _ttoc)); # endif//__use_timers } - + if(!_jcfg._init_file.empty()) { /*--------------------------------- call rDEL routine */ @@ -601,20 +788,21 @@ _ttic = _time.now(); # endif//__use_timers - if ((_retv = make_rdel ( + if ((_retv = + TRIPOD ::rdel_impl ( _jcfg, _jlog , - _init, + _init, _geom, _rdel)) != __no_error) { return _retv ; } -# ifdef __use_timers +# ifdef __use_timers _ttoc = _time.now(); _jlog.push(dump_time(_ttic, _ttoc)); # endif//__use_timers } - + if(!_jcfg._tria_file.empty()) { /*--------------------------------- dump tria to file */ @@ -627,18 +815,18 @@ # endif//__use_timers if ((_retv = save_tria ( - _jcfg, + _jcfg, _jlog, _rdel)) != __no_error) { return _retv ; } - -# ifdef __use_timers + +# ifdef __use_timers _ttoc = _time.now(); _jlog.push(dump_time(_ttic, _ttoc)); # endif//__use_timers } - + if(!_jcfg._init_file.empty() && !_jcfg._mesh_file.empty() ) { @@ -651,27 +839,43 @@ _ttic = _time.now(); # endif//__use_timers - if ((_retv = save_jmsh ( - _jcfg, + if (_jcfg._mesh_opts.dims() >= +1) + { + + if ((_retv = save_rdel ( + _jcfg, + _jlog, _rdel)) != __no_error) + { + return _retv ; + } + + } + else + { + + if ((_retv = save_tria ( + _jcfg, _jlog, _rdel)) != __no_error) { return _retv ; } - -# ifdef __use_timers + + } + +# ifdef __use_timers _ttoc = _time.now(); _jlog.push(dump_time(_ttic, _ttoc)); # endif//__use_timers } - + /*-------------------------- success, if we got here! */ - return ( _retv ) ; + return ( _retv ) ; } - + # endif //__cmd_tripod # endif //__lib_jigsaw - - - + + + diff --git a/uni/CMakeLists.txt b/uni/CMakeLists.txt index afee926..9007bed 100644 --- a/uni/CMakeLists.txt +++ b/uni/CMakeLists.txt @@ -45,3 +45,18 @@ add_executable (test_6 test_6.c) target_link_libraries (test_6 ${LIBJIGSAW}) set_target_properties(test_6 PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE) install (TARGETS test_6 DESTINATION "${PROJECT_SOURCE_DIR}") + +add_executable (test_7 test_7.c) +target_link_libraries (test_7 ${LIBJIGSAW}) +set_target_properties(test_7 PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE) +install (TARGETS test_7 DESTINATION "${PROJECT_SOURCE_DIR}") + +add_executable (test_8 test_8.c) +target_link_libraries (test_8 ${LIBJIGSAW}) +set_target_properties(test_8 PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE) +install (TARGETS test_8 DESTINATION "${PROJECT_SOURCE_DIR}") + +add_executable (test_9 test_9.c) +target_link_libraries (test_9 ${LIBJIGSAW}) +set_target_properties(test_9 PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE) +install (TARGETS test_9 DESTINATION "${PROJECT_SOURCE_DIR}") diff --git a/uni/test_6.c b/uni/test_6.c index 4f32da2..488f573 100644 --- a/uni/test_6.c +++ b/uni/test_6.c @@ -82,10 +82,9 @@ { {.5, .5}, +0 } } ; - jigsaw_EDGE2_t _edges[3] = { + jigsaw_EDGE2_t _edges[2] = { { {+0, +1}, -1 } , // -1 => "un-refinable" - { {+1, +2}, -1 } , - { {+2, +3}, -1 } + { {+1, +2}, -1 } } ; _init._flags @@ -95,7 +94,7 @@ _init._vert2._size = +4 ; _init._edge2._data = &_edges[0] ; - _init._edge2._size = +3 ; + _init._edge2._size = +2 ; /*-------------------------------- build JIGSAW tria. */ diff --git a/uni/test_7.c b/uni/test_7.c new file mode 100644 index 0000000..d5f99fa --- /dev/null +++ b/uni/test_7.c @@ -0,0 +1,111 @@ + +// gcc -Wall test_7.c +// -Xlinker -rpath=../lib +// -L ../lib -ljigsaw -o test_7 + +// Use MARCHE to set "gradient-limits" on mesh-spacing data + +# include "../inc/lib_jigsaw.h" + +# include "stdio.h" + + int main ( + int _argc , + char **_argv + ) + { + int _retv = 0; + + /*-------------------------------- setup JIGSAW types */ + jigsaw_jig_t _jjig ; + jigsaw_init_jig_t(&_jjig) ; + + jigsaw_msh_t _hfun ; + jigsaw_init_msh_t(&_hfun) ; + + /* + -------------------------------------------------------- + * JIGSAW's "mesh" is a piecewise linear complex: + -------------------------------------------------------- + * + * v:3 o---------------o v:2 + * | \ t:2 / | + * | \ / | + * | \ 4 / | + * | t:3 o t:1 | + * | / \ | + * | / \ | + * | / t:0 \ | + * v:0 o---------------o v:1 + * + -------------------------------------------------------- + */ + + jigsaw_VERT2_t _hfun_vert2[5] = { // setup hfun. + { {0., 0.}, +0 } , + { {1., 0.}, +0 } , + { {1., 1.}, +0 } , + { {0., 1.}, +0 } , + { {.5, .5}, +0 } + } ; + + jigsaw_TRIA3_t _hfun_tria3[4] = { + { {+0, +1, +4}, +0 } , + { {+1, +2, +4}, +0 } , + { {+2, +3, +4}, +4 } , + { {+3, +0, +4}, +0 } + } ; + + real_t _hfun_value[5] = { + 2., 2., 2., 2., 1. + } ; + + real_t _hfun_slope[1] = { + .1 + } ; + + _hfun._flags + = JIGSAW_EUCLIDEAN_MESH; + + _hfun._vert2._data = &_hfun_vert2[0] ; + _hfun._vert2._size = +5 ; + + _hfun._tria3._data = &_hfun_tria3[0] ; + _hfun._tria3._size = +4 ; + + _hfun._value._data = &_hfun_value[0] ; + _hfun._value._size = +5 ; + + _hfun._slope._data = &_hfun_slope[0] ; + _hfun._slope._size = +1 ; + + /*-------------------------------- build MARCHE hfun. */ + + _jjig._verbosity = +1 ; + + _retv = marche ( + &_jjig , // the config. opts + &_hfun ) ; // the spacing h(x) + + /*-------------------------------- print MARCHE hfun. */ + + printf("\n VALUE: \n\n") ; + + for (indx_t _ipos = +0; + _ipos != _hfun._value._size ; + ++_ipos ) + { + printf("%1.4f\n", + _hfun._value._data[_ipos] + ) ; + } + + printf ( + "MARCHE returned code : %d \n",_retv); + + + return _retv ; + } + + + diff --git a/uni/test_8.c b/uni/test_8.c new file mode 100644 index 0000000..343e5e6 --- /dev/null +++ b/uni/test_8.c @@ -0,0 +1,108 @@ + +// gcc -Wall test_8.c +// -Xlinker -rpath=../lib +// -L ../lib -ljigsaw -o test_8 + +// Use MARCHE to set "gradient-limits" on mesh-spacing data + +# include "../inc/lib_jigsaw.h" + +# include "stdio.h" + + int main ( + int _argc , + char **_argv + ) + { + int _retv = 0; + + /*-------------------------------- setup JIGSAW types */ + jigsaw_jig_t _jjig ; + jigsaw_init_jig_t(&_jjig) ; + + jigsaw_msh_t _hfun ; + jigsaw_init_msh_t(&_hfun) ; + + /* + -------------------------------------------------------- + * JIGSAW's "grid" uses a column-major numbering: + -------------------------------------------------------- + * + * v:5 + * v:2 o-------o-------o v:8 + * | | | + * | | | + * | v:4 | + * v:1 o-------o-------o v:7 + * | | | + * | | | + * | | | + * v:0 o-------o-------o v:6 + * v:3 + * + -------------------------------------------------------- + */ + + real_t _hfun_xgrid[3] = { // setup hfun. + 0., .5, 1. + } ; + + real_t _hfun_ygrid[3] = { + 0., .5, 1. + } ; + + real_t _hfun_value[9] = { + 2., 2., 2., 2., 1., 2., 2., + 2., 2. + } ; + + real_t _hfun_slope[9] = { + .4, .4, .4, .4, .1, .4, .4, + .4, .4 + } ; + + _hfun._flags + = JIGSAW_EUCLIDEAN_GRID; + + _hfun._xgrid._data = &_hfun_xgrid[0] ; + _hfun._xgrid._size = +3 ; + + _hfun._ygrid._data = &_hfun_ygrid[0] ; + _hfun._ygrid._size = +3 ; + + _hfun._value._data = &_hfun_value[0] ; + _hfun._value._size = +9 ; + + _hfun._slope._data = &_hfun_slope[0] ; + _hfun._slope._size = +9 ; + + /*-------------------------------- build MARCHE hfun. */ + + _jjig._verbosity = +1 ; + + _retv = marche ( + &_jjig , // the config. opts + &_hfun ) ; // the spacing h(x) + + /*-------------------------------- print MARCHE hfun. */ + + printf("\n VALUE: \n\n") ; + + for (indx_t _ipos = +0; + _ipos != _hfun._value._size ; + ++_ipos ) + { + printf("%1.4f\n", + _hfun._value._data[_ipos] + ) ; + } + + printf ( + "MARCHE returned code : %d \n",_retv); + + + return _retv ; + } + + + diff --git a/uni/test_9.c b/uni/test_9.c new file mode 100644 index 0000000..e187ee2 --- /dev/null +++ b/uni/test_9.c @@ -0,0 +1,103 @@ + +// gcc -Wall test_9.c +// -Xlinker -rpath=../lib +// -L ../lib -ljigsaw -o test_9 + +// Use JIGSAW to generate a uniform mesh for a spheroidal +// domain. + +# include "../inc/lib_jigsaw.h" + +# include "stdio.h" + + int main ( + int _argc , + char **_argv + ) + { + int _retv = 0; + + /*-------------------------------- setup JIGSAW types */ + jigsaw_jig_t _jjig ; + jigsaw_init_jig_t(&_jjig) ; + + jigsaw_msh_t _geom ; + jigsaw_init_msh_t(&_geom) ; + + jigsaw_msh_t _mesh ; + jigsaw_init_msh_t(&_mesh) ; + + /*-------------------------------- setup JIGSAW geom. */ + + real_t _radii[3] = {+1., +1., +1. + } ; + + _geom._flags = + JIGSAW_ELLIPSOID_MESH ; + + _geom._radii._data = &_radii[0] ; + _geom._radii._size = +3 ; + + /*-------------------------------- build JIGSAW tria. */ + + _jjig._verbosity = +1 ; + + _jjig._hfun_hmax = 0.80 ; + _jjig._hfun_scal = + JIGSAW_HFUN_ABSOLUTE; + + _jjig._mesh_dims = +2 ; + + _retv = jigsaw ( + &_jjig , // the config. opts + &_geom , // geom. data + NULL , // empty init. data + NULL , // empty hfun. data + &_mesh ) ; + + /*-------------------------------- print JIGSAW tria. */ + + printf("\n VERT3: \n\n") ; + + for (indx_t _ipos = +0; + _ipos != _mesh._vert3._size ; + ++_ipos ) + { + printf( + "%1.4f, %1.4f, %1.4f\n", + _mesh._vert3. + _data[_ipos]._ppos[0], + _mesh._vert3. + _data[_ipos]._ppos[1], + _mesh._vert3. + _data[_ipos]._ppos[2] + ) ; + } + + printf("\n TRIA3: \n\n") ; + + for (indx_t _ipos = +0; + _ipos != _mesh._tria3._size ; + ++_ipos ) + { + printf("%d, %d, %d\n", + _mesh._tria3. + _data[_ipos]._node[0], + _mesh._tria3. + _data[_ipos]._node[1], + _mesh._tria3. + _data[_ipos]._node[2] + ) ; + } + + jigsaw_free_msh_t(&_mesh); + + printf ( + "JIGSAW returned code : %d \n",_retv); + + + return _retv ; + } + + + diff --git a/version.txt b/version.txt index cccf296..6898a84 100644 --- a/version.txt +++ b/version.txt @@ -13,6 +13,33 @@ # JIGSAW: an unstructured mesh generation library #------------------------------------------------------------ + * Version 0.9.12: + -------------- + + - Support for "gradient-limiting" of mesh-spacing + data via the cmd-line utility MARCHE. This tool + solves a variant of the Eikonal equation + + MAX(|dh/dx|,g) = g, + + where g = g(x) is a gradient threshold to be + applied to the distribution h(x). MARCHE can be + used to construct smooth mesh-spacing functions + from noisy input data. MARCHE shares common I/O + protocols, options, etc with JIGSAW. + + - Optimisation of various low-level functionality + throughout. 0.9.12.x should use less memory and + be slightly faster overall. + + - rDT//ODT meshing kernels will more aggressively + respond to user-defined mesh-spacing functions + that incorporate non-uniform spatial structure. + + - Support for both ODT and CVT style optimisation + kernels. ODT should still usually be preferred. + + * Version 0.9.11: --------------