diff --git a/contrib/hxt/CMakeLists.txt b/contrib/hxt/CMakeLists.txt index cfbbe652bbc1039879fdfbcbe71138fae6702aeb..d69f0a0cce9d4b9855cb7e90a046ff09cfc626cf 100644 --- a/contrib/hxt/CMakeLists.txt +++ b/contrib/hxt/CMakeLists.txt @@ -11,7 +11,10 @@ # Fixme: HXT should rather be included using simple target_link_library calls, # as for external libraries -# === HXT core + +################################################################################# +# HXT core +################################################################################# set(SRC hxt_bbox.c hxt_mesh.c @@ -34,7 +37,10 @@ list(APPEND HXT_INC_DIRS contrib/hxt/core/src contrib/hxt/core/include) -# === HXT reparam + +################################################################################# +# HXT reparam +################################################################################# set(SRC hxt_class_macro.h hxt_curvature.c @@ -62,13 +68,19 @@ list(APPEND HXT_INC_DIRS contrib/hxt/reparam/src contrib/hxt/reparam/include) -# === HXT sizeField + +################################################################################# +# HXT sizeField +################################################################################# if(HAVE_P4EST) append_gmsh_src(contrib/hxt/sizeField "hxt_octree.cpp;hxt_octree.h" ) list(APPEND HXT_INC_DIRS contrib/hxt/sizeField) endif() -# === HXT predicates + +################################################################################# +# HXT predicates +################################################################################# # do not use arithmetic contraction in predicates.c if(MSVC OR (CMAKE_C_COMPILER_ID STREQUAL "Intel" AND WIN32)) set_source_files_properties("${CMAKE_CURRENT_SOURCE_DIR}/predicates/src/predicates.c" @@ -93,7 +105,9 @@ list(APPEND HXT_INC_DIRS contrib/hxt/predicates/include) -# === HXT tetBR +################################################################################# +# HXT tetBR +################################################################################# append_gmsh_src(contrib/hxt/tetBR/src hxt_boundary_recovery.cxx) append_gmsh_src(contrib/hxt/tetBR/include hxt_boundary_recovery.h) list(APPEND HXT_INC_DIRS @@ -101,30 +115,56 @@ list(APPEND HXT_INC_DIRS contrib/hxt/tetBR/include) -# === HXT tetMesh +################################################################################# +# HXT tetMesh +################################################################################# set(SRC hxt_edgeRemoval.c + hxt_edgeRemoval.h hxt_smoothing.c + hxt_smoothing.h HXTSPR.c + HXTSPR.h hxt_tetColor.c + hxt_tetColor.h hxt_tetDelaunay.c hxt_tetFlag.c hxt_tetMesh.c hxt_tetNodalSize.c + hxt_tetNodalSize.h hxt_tetOpti.c + hxt_tetOptiUtils.h + hxt_tetPartition.h hxt_tetQuality.c + hxt_tetQuality.h hxt_tetRefine.c + hxt_tetRefine.h hxt_tetRepair.c hxt_tetSync.c + hxt_tetSync.h hxt_tetUtils.c + hxt_tetUtils.h hxt_vertices.c ) +set(INC + hxt_tetDelaunay.h + hxt_tetFlag.h + hxt_tetMesh.h + hxt_tetOpti.h + hxt_tetRepair.h + hxt_vertices.h + ) + append_gmsh_src(contrib/hxt/tetMesh/src "${SRC}") -append_gmsh_src(contrib/hxt/tetMesh/include hxt_tetMesh.h) +append_gmsh_src(contrib/hxt/tetMesh/include "${INC}") + list(APPEND HXT_INC_DIRS contrib/hxt/tetMesh/src contrib/hxt/tetMesh/include) -# this variable should be available in the parent CMakeLists + +################################################################################# +# propagate HXT_INC_DIRS to parent CMakeLists +################################################################################# set(HXT_INC_DIRS ${HXT_INC_DIRS} PARENT_SCOPE) diff --git a/contrib/hxt/core/CMakeLists.txt b/contrib/hxt/core/CMakeLists.txt index d88337ed53339f682ad35b4509afeb9f1ebd1045..7d85959ecf16a0025612468468df8db4c52b8fc2 100644 --- a/contrib/hxt/core/CMakeLists.txt +++ b/contrib/hxt/core/CMakeLists.txt @@ -1,25 +1,36 @@ cmake_minimum_required(VERSION 3.9) project(hxt_core C) +# include guard for CMake: +# if you plan to include multiple directory that depend on this one, +# you need to include this directory first if(TARGET hxt_core) - # header guard for CMake. You need to include this directory first return() endif() + +################################################################################# +# Options +################################################################################# option(HXT_ENABLE_OPENMP "Enable OpenMP" ON) option(HXT_ALIGN_ALLOCATIONS "Align allocation" OFF) -option(HXT_CORE_FILEIO "Compile HXT core with file I/O" OFF) option(HXT_CORE_OBJECT_ONLY "Do not create hxt_core library" ON) + +################################################################################# +# Library definition +################################################################################# set(HXT_CORE_SRC "${CMAKE_CURRENT_SOURCE_DIR}/src/hxt_bbox.c" "${CMAKE_CURRENT_SOURCE_DIR}/src/hxt_mesh.c" "${CMAKE_CURRENT_SOURCE_DIR}/src/hxt_message.c" + "${CMAKE_CURRENT_SOURCE_DIR}/src/hxt_opt.c" "${CMAKE_CURRENT_SOURCE_DIR}/src/hxt_sort.c" "${CMAKE_CURRENT_SOURCE_DIR}/include/hxt_bbox.h" "${CMAKE_CURRENT_SOURCE_DIR}/include/hxt_mesh.h" "${CMAKE_CURRENT_SOURCE_DIR}/include/hxt_message.h" "${CMAKE_CURRENT_SOURCE_DIR}/include/hxt_omp.h" + "${CMAKE_CURRENT_SOURCE_DIR}/include/hxt_opt.h" "${CMAKE_CURRENT_SOURCE_DIR}/include/hxt_sort.h" "${CMAKE_CURRENT_SOURCE_DIR}/include/hxt_tools.h" ) @@ -30,7 +41,6 @@ if(HXT_CORE_OBJECT_ONLY) else() add_library(hxt_core ${HXT_CORE_SRC}) endif() - target_include_directories(hxt_core PUBLIC include) target_compile_features(hxt_core PRIVATE c_std_99) @@ -41,10 +51,10 @@ if(HXT_ENABLE_OPENMP) endif() endif() + +################################################################################# +# Compilation flags corresponding to options +################################################################################# if(HXT_ALIGN_ALLOCATIONS) target_compile_definitions(hxt_core PUBLIC HXT_ALIGN_ALLOCATIONS) endif() - -if(HXT_ENABLE_FILEIO) - target_compile_definitions(hxt_core PUBLIC HXT_CORE_FILEIO) -endif() diff --git a/contrib/hxt/core/include/hxt_mesh.h b/contrib/hxt/core/include/hxt_mesh.h index 46134e32743bd42d60c341e760a124bf5247c28e..9616c5fd3ca5d1e419bf4e228a1d7addf3a09b44 100644 --- a/contrib/hxt/core/include/hxt_mesh.h +++ b/contrib/hxt/core/include/hxt_mesh.h @@ -134,10 +134,10 @@ typedef struct { HXTStatus hxtMeshCreate ( HXTMesh** mesh); HXTStatus hxtMeshDelete ( HXTMesh** meshPtr); -#ifdef HXT_CORE_FILEIO +// mesh I/O HXTStatus hxtMeshReadGmsh ( HXTMesh* mesh, const char* filename); HXTStatus hxtMeshWriteGmsh ( HXTMesh* mesh, const char* filename); -#endif + #ifdef __cplusplus } diff --git a/contrib/hxt/core/include/hxt_opt.h b/contrib/hxt/core/include/hxt_opt.h new file mode 100644 index 0000000000000000000000000000000000000000..d7f069e05686c9e75540d7cc786814e46e42265b --- /dev/null +++ b/contrib/hxt/core/include/hxt_opt.h @@ -0,0 +1,179 @@ +// Hxt - Copyright (C) +// 2016 - 2020 UCLouvain +// +// See the LICENSE.txt file for license information. +// +// Contributor(s): +// Célestin Marot + +#ifndef __HXT_OPT_H__ +#define __HXT_OPT_H__ + +#include "hxt_message.h" +#include <stdio.h> + +#ifdef __cplusplus +extern "C" { +#endif + + +/**************************************************************************************** + * argument type: the type of the argument that must be given to the option + * or HXT[_NO]_FLAG to indicate that the option doesn't have an argument + ***************************************************************************************/ +typedef enum { +// flags + // no argument must be given, the value must be an integer set to 0 (it is set to 1 when option is called) + HXT_FLAG, + // no argument must be given, the value must be an integer set to 1 (it is set to 0 when option is called) + HXT_NO_FLAG, + +// floating point values: + HXT_DOUBLE, + HXT_FLOAT, + +// integer values + HXT_INT, + HXT_I64, + HXT_I32, + HXT_I16, + +// unsigned integer values + HXT_UNSIGNED, + HXT_U64, + HXT_U32, + HXT_U16, + +// strings values + HXT_STRING, + HXT_EXISTING_FILENAME, + HXT_NEW_FILENAME, + HXT_ASK_TO_ERASE_FILENAME +} HXTOptionArgumentType; + +/************************************************************************************* + * Constraints on the accepted range of the value given in argument * + ************************************************************************************/ +typedef struct { + // acceptable range for floating-point values + double doubleMin; + double doubleMax; + + // acceptable range for integer values + long long int intMin; + long long int intMax; + + // acceptable range for unsigned integer values + unsigned long long unsignedMin; + unsigned long long unsignedMax; + + // required prefix and suffix to the string (NULL pointer are omitted) + const char* stringPrefix; + const char* stringSuffix; + + // character allowed, required or forbidden (NULL pointer are omitted) + const char* stringCharAllowed; +} HXTOptionArgumentConstraints; + +#define HXT_ALPHA_LOWERCASE_CHARACTERS "abcdefghijklmnopqrstuvwxyz" +#define HXT_ALPHA_UPPERCASE_CHARACTERS "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +#define HXT_ALPHA_CHARACTERS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" +#define HXT_NUMERIC_CHARACTERS "0123456789" +#define HXT_ALPHANUMERIC_LOWERCASE_CHARACTERS "abcdefghijklmnopqrstuvwxyz0123456789" +#define HXT_ALPHANUMERIC_UPPERCASE_CHARACTERS "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" +#define HXT_ALPHANUMERIC_CHARACTERS \ + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" +#define HXT_PRINTABLE_VISIBLE_CHARACTERS \ + "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~" +#define HXT_PRINTABLE_CHARACTERS \ + "\t\n !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~" + +// built-in hxtOptionArg +extern const HXTOptionArgumentConstraints HXT_POSITIVE_RANGE; + +extern const HXTOptionArgumentConstraints HXT_ALPHA_LOWERCASE_RANGE; +extern const HXTOptionArgumentConstraints HXT_ALPHA_UPPERCASE_RANGE; +extern const HXTOptionArgumentConstraints HXT_ALPHA_RANGE; +extern const HXTOptionArgumentConstraints HXT_NUMERIC_RANGE; +extern const HXTOptionArgumentConstraints HXT_ALPHANUMERIC_LOWERCASE_RANGE; +extern const HXTOptionArgumentConstraints HXT_ALPHANUMERIC_UPPERCASE_RANGE; +extern const HXTOptionArgumentConstraints HXT_ALPHANUMERIC_RANGE; +extern const HXTOptionArgumentConstraints HXT_PRINTABLE_VISIBLE_RANGE; +extern const HXTOptionArgumentConstraints HXT_PRINTABLE_RANGE; + +extern const HXTOptionArgumentConstraints HXT_0_1_RANGE; +extern const HXTOptionArgumentConstraints HXT_0_2_RANGE; +extern const HXTOptionArgumentConstraints HXT_0_3_RANGE; +extern const HXTOptionArgumentConstraints HXT_0_4_RANGE; +extern const HXTOptionArgumentConstraints HXT_0_5_RANGE; +extern const HXTOptionArgumentConstraints HXT_0_10_RANGE; +extern const HXTOptionArgumentConstraints HXT_0_20_RANGE; +extern const HXTOptionArgumentConstraints HXT_0_50_RANGE; +extern const HXTOptionArgumentConstraints HXT_0_100_RANGE; +extern const HXTOptionArgumentConstraints HXT_0_1000_RANGE; + + +HXTStatus hxtAddOption(char short_name, + const char* longName, + const char* description, + HXTOptionArgumentType valueType, + const HXTOptionArgumentConstraints* constraints, + void* valuePtr); + +/* Trailing options are options without an option name. + * the order in which they are added is important ! + * by default, the last trailing option is optional + * you can add an empty trailing option (a trailing option with valuePtr==NULL) at the end to make the last trailing option required + * example: + * + * const char* input = NULL; + * HXT_CHECK(hxtAddTrailingOption("INPUT_MESH", HXT_EXISTING_FILENAME, NULL, &input)); + * + * // without the next line, the user would be allowed not giving an input mesh file in the command line + * + * HXT_CHECK(hxtAddTrailingOption(NULL, 0, NULL, NULL)); + * + * // this empty trailing option option ensure that an input mesh file is required +*/ +static inline HXTStatus hxtAddTrailingOption( + const char* argumentName, // name to use in the usage line ./program [Options] trailingArg1 trailingArg2 ... + HXTOptionArgumentType valueType, + const HXTOptionArgumentConstraints* constraints, + void* valuePtr) +{ + HXT_CHECK( hxtAddOption('\0', NULL, argumentName, valueType, constraints, valuePtr) ); + return HXT_STATUS_OK; +} + +// use the HXT_PARSE_COMMAND_LINE macro instead +HXTStatus hxtGetOptionHelp(char message[16384], + const char* programName, + const char* programDescription, + const char* additionalInfo); + +// use the HXT_PARSE_COMMAND_LINE macro instead +HXTStatus hxtParseOptions(const int argc, char* argv[]); + +// This macro should be placed in the main, after all options are added ! +#define HXT_PARSE_COMMAND_LINE(argc, argv, programName, programDescription, additionalInfo) \ +do{ \ + char help[16384]; \ + HXTStatus status = hxtGetOptionHelp(help, programName, programDescription, additionalInfo); \ + if(status==HXT_STATUS_OK) \ + status = hxtParseOptions(argc, argv); \ + if(status!=HXT_STATUS_OK && status!=HXT_STATUS_INTERNAL) { \ + HXT_TRACE(status); \ + puts("\n ==> Help on Error\n\n ---\n"); \ + } \ + if(status!=HXT_STATUS_OK) { \ + printf("%s", help); \ + return status!=HXT_STATUS_INTERNAL?status:0; \ + } \ +} while(0); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/contrib/hxt/core/include/hxt_tools.h b/contrib/hxt/core/include/hxt_tools.h index cefd41eda89f2c6c9cdd193f52d42fa0f546fcd6..12fbee85eea3379279eecfc13456b38f0aea49b9 100644 --- a/contrib/hxt/core/include/hxt_tools.h +++ b/contrib/hxt/core/include/hxt_tools.h @@ -16,6 +16,10 @@ extern "C" { #include "hxt_message.h" #include <string.h> #include <stdint.h> +#include <math.h> +#ifndef M_PI + #define M_PI 3.14159265358979323846264338327950 +#endif // !M_PI /* define SIMD ALIGNMENT */ #ifndef SIMD_ALIGN diff --git a/contrib/hxt/core/src/hxt_mesh.c b/contrib/hxt/core/src/hxt_mesh.c index acc2980767fb3e533340d6609085b867b70b2aa9..bf07c31e9e2458a0eb9c9b5c339597e1d83d2bff 100644 --- a/contrib/hxt/core/src/hxt_mesh.c +++ b/contrib/hxt/core/src/hxt_mesh.c @@ -96,13 +96,6 @@ HXTStatus hxtMeshDelete ( HXTMesh** mesh) { } - - - - - -#ifdef HXT_CORE_FILEIO - // TODO: more checking of fgets HXTStatus ReadNodesFromGmsh(FILE *fp, HXTMesh* m){ rewind (fp); @@ -583,5 +576,3 @@ HXTStatus hxtMeshWriteGmsh ( HXTMesh* mesh , const char *filename) { return HXT_STATUS_OK; } -#endif - diff --git a/contrib/hxt/core/src/hxt_opt.c b/contrib/hxt/core/src/hxt_opt.c new file mode 100644 index 0000000000000000000000000000000000000000..ba9b7e6c4d7d56832d1ec90479866da455ad4a45 --- /dev/null +++ b/contrib/hxt/core/src/hxt_opt.c @@ -0,0 +1,819 @@ +// Hxt - Copyright (C) +// 2016 - 2020 UCLouvain +// +// See the LICENSE.txt file for license information. +// +// Contributor(s): +// Célestin Marot + +#include "hxt_opt.h" +#include "hxt_tools.h" +#include <float.h> +#include <errno.h> +#include <limits.h> + + + +const HXTOptionArgumentConstraints HXT_POSITIVE_RANGE = { + 0, DBL_MAX, + 0, LLONG_MAX, + 0, ULLONG_MAX, + NULL, NULL, NULL +}; +const HXTOptionArgumentConstraints HXT_ALPHA_LOWERCASE_RANGE = { + -DBL_MAX, DBL_MAX, + LLONG_MIN, LLONG_MAX, + 0, ULLONG_MAX, + NULL, NULL, HXT_ALPHA_LOWERCASE_CHARACTERS +}; +const HXTOptionArgumentConstraints HXT_ALPHA_UPPERCASE_RANGE = { + -DBL_MAX, DBL_MAX, + LLONG_MIN, LLONG_MAX, + 0, ULLONG_MAX, + NULL, NULL, HXT_ALPHA_UPPERCASE_CHARACTERS +}; +const HXTOptionArgumentConstraints HXT_ALPHA_RANGE = { + -DBL_MAX, DBL_MAX, + LLONG_MIN, LLONG_MAX, + 0, ULLONG_MAX, + NULL, NULL, HXT_ALPHA_CHARACTERS +}; +const HXTOptionArgumentConstraints HXT_NUMERIC_RANGE = { + -DBL_MAX, DBL_MAX, + LLONG_MIN, LLONG_MAX, + 0, ULLONG_MAX, + NULL, NULL, HXT_NUMERIC_CHARACTERS +}; +const HXTOptionArgumentConstraints HXT_ALPHANUMERIC_LOWERCASE_RANGE = { + -DBL_MAX, DBL_MAX, + LLONG_MIN, LLONG_MAX, + 0, ULLONG_MAX, + NULL, NULL, HXT_ALPHANUMERIC_LOWERCASE_CHARACTERS +}; +const HXTOptionArgumentConstraints HXT_ALPHANUMERIC_UPPERCASE_RANGE = { + -DBL_MAX, DBL_MAX, + LLONG_MIN, LLONG_MAX, + 0, ULLONG_MAX, + NULL, NULL, HXT_ALPHANUMERIC_UPPERCASE_CHARACTERS +}; +const HXTOptionArgumentConstraints HXT_ALPHANUMERIC_RANGE = { + -DBL_MAX, DBL_MAX, + LLONG_MIN, LLONG_MAX, + 0, ULLONG_MAX, + NULL, NULL, HXT_ALPHANUMERIC_CHARACTERS +}; +const HXTOptionArgumentConstraints HXT_PRINTABLE_VISIBLE_RANGE = {// between space and ~ + -DBL_MAX, DBL_MAX, + LLONG_MIN, LLONG_MAX, + 0, ULLONG_MAX, + NULL, NULL, HXT_PRINTABLE_VISIBLE_CHARACTERS +}; +const HXTOptionArgumentConstraints HXT_PRINTABLE_RANGE = { + -DBL_MAX, DBL_MAX, + LLONG_MIN, LLONG_MAX, + 0, ULLONG_MAX, + NULL, NULL, HXT_PRINTABLE_CHARACTERS +}; +const HXTOptionArgumentConstraints HXT_0_1_RANGE = { + 0., 1., + 0, 1, + 0, 1, + NULL, NULL, NULL +}; +const HXTOptionArgumentConstraints HXT_0_2_RANGE = { + 0., 2., + 0, 2, + 0, 2, + NULL, NULL, NULL +}; +const HXTOptionArgumentConstraints HXT_0_3_RANGE = { + 0., 3., + 0, 3, + 0, 3, + NULL, NULL, NULL +}; +const HXTOptionArgumentConstraints HXT_0_4_RANGE = { + 0., 4., + 0, 4, + 0, 4, + NULL, NULL, NULL +}; +const HXTOptionArgumentConstraints HXT_0_5_RANGE = { + 0., 5., + 0, 5, + 0, 5, + NULL, NULL, NULL +}; +const HXTOptionArgumentConstraints HXT_0_10_RANGE = { + 0., 10., + 0, 10, + 0, 10, + NULL, NULL, NULL +}; +const HXTOptionArgumentConstraints HXT_0_20_RANGE = { + 0., 20., + 0, 20, + 0, 20, + NULL, NULL, NULL +}; +const HXTOptionArgumentConstraints HXT_0_50_RANGE = { + 0., 50., + 0, 50, + 0, 50, + NULL, NULL, NULL +}; +const HXTOptionArgumentConstraints HXT_0_100_RANGE = { + 0., 100., + 0, 100, + 0, 100, + NULL, NULL, NULL +}; +const HXTOptionArgumentConstraints HXT_0_1000_RANGE = { + 0., 1000., + 0, 1000, + 0, 1000, + NULL, NULL, NULL +}; + + +typedef struct HXTOptionStruct { + char shortName; + const char* longName; + const char* description; + const HXTOptionArgumentConstraints* constraints; + HXTOptionArgumentType valueType; + void* valuePtr; +} HXTOption; + +static HXTOption helpOption = {'h', "help", "Display this help message", NULL, HXT_FLAG, NULL}; +static HXTOption* optionList = NULL; +static int optionListLength = 0; +static int optionListSize = 0; + + +#define MAX(a,b) (((a)>(b))?(a):(b)) + + +static HXTStatus optionListReserve(int n) +{ + if(optionList==NULL) { + optionListSize = MAX(16,n); + HXT_CHECK( hxtMalloc(&optionList, optionListSize*sizeof(HXTOption)) ); + optionList[0] = helpOption; + optionListLength = 1; + } + else if(optionListLength + n > optionListSize) { + optionListSize = MAX(2*optionListSize, optionListLength + n); + HXT_CHECK( hxtRealloc(&optionList, optionListSize) ); + } + return HXT_STATUS_OK; +} + + +HXTStatus hxtAddOption(char shortName, + const char* longName, + const char* description, + HXTOptionArgumentType valueType, + const HXTOptionArgumentConstraints* constraints, + void* valuePtr) +{ + HXT_CHECK( optionListReserve(1) ); + +#ifndef NDEBUG + if(valuePtr==NULL && (shortName!='\0' || longName!=NULL || description!=NULL)) + return HXT_ERROR_MSG(HXT_STATUS_ERROR, "Adding a non-empty option with a NULL value pointer makes no sense"); + for (int i=0; i<optionListLength; i++) { + if(shortName!='\0' && shortName==optionList[i].shortName) + return HXT_ERROR_MSG(HXT_STATUS_ERROR, "-%c is already the short name of another option", shortName); + } + if(longName!=NULL) { + if(longName[0]=='\0') + return HXT_ERROR_MSG(HXT_STATUS_ERROR, "Cannot use empty string as a long option name. Use NULL pointer if you do not want a long option name."); + if(longName[0]=='-') + return HXT_ERROR_MSG(HXT_STATUS_ERROR, "long option \"%s\" cannot begin with a '-'", longName); + for (int i=0; longName[i]!='\0'; i++) { + if(longName[i]<=' ') + return HXT_ERROR_MSG(HXT_STATUS_ERROR, "long option \"%s\" should only contain printable characters", longName); + } + for (int i=0; i<optionListLength; i++) { + if(optionList[i].longName!=NULL && strcmp(longName, optionList[i].longName)==0) + return HXT_ERROR_MSG(HXT_STATUS_ERROR, "--%s is already the long name of another option", longName); + } + } +#endif + + if(shortName=='\0' && (longName==NULL || longName[0]=='\0') && + (valueType==HXT_FLAG || valueType==HXT_NO_FLAG) && valuePtr!=NULL) { + return HXT_ERROR_MSG(HXT_STATUS_ERROR, "A flag must have an option name. Therefore, it can not be a trailing option"); + } + + optionList[optionListLength].shortName = shortName; + optionList[optionListLength].longName = longName; + optionList[optionListLength].description = description; + optionList[optionListLength].valueType = valueType; + optionList[optionListLength].constraints = constraints; + optionList[optionListLength].valuePtr = valuePtr; + optionListLength++; + + return HXT_STATUS_OK; +} + + +/********************************************************************* +* search a long option inside the list * +*********************************************************************/ +static int searchLongOption(const char* string) +{ + for (int i=0; i<optionListLength; i++) { + if(optionList[i].longName!=NULL && + strcmp(optionList[i].longName, string)==0) { + return i; + } + } + + return -1; +} + + +/********************************************************************* +* search a short option inside the list * +*********************************************************************/ +static int searchShortOption(char c) +{ + for (int i=0; i<optionListLength; i++) { + if(c==optionList[i].shortName) { + return i; + } + } + return -1; +} + + +int fileExists(const char *fname) +{ + FILE *file; + if ((file = fopen(fname, "r"))) + { + fclose(file); + return 1; + } + return 0; +} + + +static const char* getArgTypeName(HXTOptionArgumentType t){ + switch(t) { + case HXT_FLAG: + case HXT_NO_FLAG: + return "(none)"; + case HXT_DOUBLE: + return "a double"; + case HXT_FLOAT: + return "a float"; + case HXT_INT: + return "an integer "; + case HXT_I64: + return "a 64-bit integer"; + case HXT_I32: + return "a 32-bit integer"; + case HXT_I16: + return "a 16-bit integer"; + case HXT_UNSIGNED: + return "an unsigned integer "; + case HXT_U64: + return "a 64-bit unsigned integer"; + case HXT_U32: + return "a 32-bit unsigned integer"; + case HXT_U16: + return "a 16-bit unsigned integer"; + default: + return "a string"; + } +} + + +/********************************************************************* +* scan the argument and verify its validity * +*********************************************************************/ +static HXTStatus doOption(HXTOption* opt, + const char* arg, + const char* optName) +{ + if(opt->valueType==HXT_FLAG) { + *(int*) opt->valuePtr = 1; + return HXT_STATUS_OK; + } + if(opt->valueType==HXT_NO_FLAG) { + *(int*) opt->valuePtr = 0; + return HXT_STATUS_OK; + } + + char* endptr = NULL; + double r = 0; + unsigned long long u = 0; + long long int i = 0; + const char* s = NULL; + + int isDouble = 0, isInteger = 0, isUnsigned = 0; + + if(opt->valueType==HXT_DOUBLE || opt->valueType==HXT_FLOAT) { + isDouble = 1; + r = strtod(arg, &endptr); + } + else if(opt->valueType==HXT_INT || + opt->valueType==HXT_I64 || + opt->valueType==HXT_I32 || + opt->valueType==HXT_I16) { + isInteger = 1; + i = strtoll(arg, &endptr, 10); + } + else if(opt->valueType==HXT_UNSIGNED || + opt->valueType==HXT_U64 || + opt->valueType==HXT_U32 || + opt->valueType==HXT_U16) { + isUnsigned = 1; + u = strtoull(arg, &endptr, 10); + } + else { + s = arg; + } + + // verify the validity + if(errno == ERANGE){ +range_error: + return HXT_ERROR_MSG(HXT_STATUS_RANGE_ERROR, + "cannot convert argument \"%s\" of option \"%s\" to %s (range overflow)", + arg, optName, getArgTypeName(opt->valueType)); + } + else if (arg == endptr) + { + return HXT_ERROR_MSG(HXT_STATUS_FORMAT_ERROR, + "cannot convert argument \"%s\" of option \"%s\" to %s (no digit)", + arg, optName, getArgTypeName(opt->valueType)); + } + else if(endptr!=NULL && *endptr!='\0') { + return HXT_ERROR_MSG(HXT_STATUS_FORMAT_ERROR, + "cannot convert argument \"%s\" of option \"%s\" to %s (trailing unvalid characters)", + arg, optName, getArgTypeName(opt->valueType)); + } + + // verify the conversion is possible + switch(opt->valueType) { + // floating point values: + case HXT_DOUBLE: + *(double*) opt->valuePtr = r; + break; + case HXT_FLOAT: + if((float)r!=r) goto range_error; + *(float*) opt->valuePtr = r; + break; + // integer values + case HXT_INT: + if((int)i!=i) goto range_error; + *(int*) opt->valuePtr = i; + break; + case HXT_I64: + if((int64_t)i!=i) goto range_error; + *(int64_t*) opt->valuePtr = i; + break; + case HXT_I32: + if((int32_t)i!=i) goto range_error; + *(int32_t*) opt->valuePtr = i; + break; + case HXT_I16: + if((int16_t)i!=i) goto range_error; + *(int16_t*) opt->valuePtr = i; + break; + // unsigned integer values + case HXT_UNSIGNED: + if((unsigned)u!=u) goto range_error; + *(unsigned*) opt->valuePtr = u; + break; + case HXT_U64: + if((uint64_t)u!=u) goto range_error; + *(uint64_t*) opt->valuePtr = u; + break; + case HXT_U32: + if((uint32_t)u!=u) goto range_error; + *(uint32_t*) opt->valuePtr = u; + break; + case HXT_U16: + if((uint16_t)u!=u) goto range_error; + *(uint16_t*) opt->valuePtr = u; + break; + // string values + case HXT_EXISTING_FILENAME: + if(!fileExists(s)) + return HXT_ERROR_MSG(HXT_STATUS_FILE_CANNOT_BE_OPENED, + "file \"%s\" does not exist", s); + *(const char**) opt->valuePtr = s; + break; + case HXT_NEW_FILENAME: + if(fileExists(s)) + return HXT_ERROR_MSG(HXT_STATUS_FILE_CANNOT_BE_OPENED, + "file \"%s\" already exists", s); + *(const char**) opt->valuePtr = s; + break; + case HXT_ASK_TO_ERASE_FILENAME: + if(fileExists(s)) { + char memory[64]; + HXT_INFO("file \"%s\" already exists\n do you want to overwrite it ? y/N", s); + char* string = fgets(memory, 64, stdin); + if(string==NULL || (string[0]!='y' && string[0]!='Y') ) + return HXT_ERROR_MSG(HXT_STATUS_FILE_CANNOT_BE_OPENED, "aborting"); + } + /* fall through */ + + default: + *(const char**) opt->valuePtr = s; + break; + } + + if(opt->constraints==NULL) + return HXT_STATUS_OK; + + + if(isDouble){ + if(r < opt->constraints->doubleMin || r > opt->constraints->doubleMax) + return HXT_ERROR_MSG(HXT_STATUS_RANGE_ERROR, + "cannot convert argument \"%s\" of option \"%s\" " + "to %s between %g and %g (range overflow)", + arg, optName, getArgTypeName(opt->valueType), + opt->constraints->doubleMin, opt->constraints->doubleMax); + } + else if(isInteger){ + if(i < opt->constraints->intMin || i > opt->constraints->intMax) + return HXT_ERROR_MSG(HXT_STATUS_RANGE_ERROR, + "cannot convert argument \"%s\" of option \"%s\" " + "to %s between %lld and %lld (range overflow)", + arg, optName, getArgTypeName(opt->valueType), + opt->constraints->intMin, opt->constraints->intMax); + } + else if(isUnsigned){ + if(u < opt->constraints->unsignedMin || u > opt->constraints->unsignedMax) + return HXT_ERROR_MSG(HXT_STATUS_RANGE_ERROR, + "cannot convert argument \"%s\" of option \"%s\" " + "to %s between %llu and %llu (range overflow)", + arg, optName, getArgTypeName(opt->valueType), + opt->constraints->unsignedMin, opt->constraints->unsignedMax); + } + else { + if(opt->constraints->stringPrefix!=NULL) { + const char* prefix = opt->constraints->stringPrefix; + size_t lenpre = strlen(prefix), lens = strlen(s); + if(lens < lenpre || strncmp(prefix, s, lenpre) != 0) + return HXT_ERROR_MSG(HXT_STATUS_ERROR, "argument \"%s\" of option \"%s\" is not prefixed by \"%s\"", arg, optName, prefix); + } + if(opt->constraints->stringSuffix!=NULL) { + const char* suffix = opt->constraints->stringSuffix; + size_t lensuf = strlen(suffix), lens = strlen(s); + if(lens < lensuf || strcmp(suffix, s + lens - lensuf) != 0) + return HXT_ERROR_MSG(HXT_STATUS_ERROR, "argument \"%s\" of option \"%s\" is not suffixed by \"%s\"", arg, optName, suffix); + } + if(opt->constraints->stringCharAllowed!=NULL) { + const char* allowed = opt->constraints->stringCharAllowed; + for (int j=0; s[j]!='\0'; j++) { + int found = 0; + int special = 0; + if(opt->constraints==&HXT_ALPHA_LOWERCASE_RANGE + || opt->constraints==&HXT_ALPHA_RANGE + || opt->constraints==&HXT_ALPHANUMERIC_LOWERCASE_RANGE + || opt->constraints==&HXT_ALPHANUMERIC_RANGE) { + special = 1; + if(s[j]>='a' && s[j]<='z') found = 1; + } + if(opt->constraints==&HXT_ALPHA_UPPERCASE_RANGE + || opt->constraints==&HXT_ALPHA_RANGE + || opt->constraints==&HXT_ALPHANUMERIC_UPPERCASE_RANGE + || opt->constraints==&HXT_ALPHANUMERIC_RANGE) { + special = 1; + if(s[j]>='A' && s[j]<='Z') found = 1; + } + if(opt->constraints==&HXT_NUMERIC_RANGE + || opt->constraints==&HXT_ALPHANUMERIC_LOWERCASE_RANGE + || opt->constraints==&HXT_ALPHANUMERIC_UPPERCASE_RANGE + || opt->constraints==&HXT_ALPHANUMERIC_RANGE) { + special = 1; + if(s[j]>='0' && s[j]<='9') found = 1; + } + if(opt->constraints==&HXT_PRINTABLE_VISIBLE_RANGE + || opt->constraints==&HXT_PRINTABLE_RANGE) { + special = 1; + if(s[j]>' ' && s[j]<='~') found = 1; + } + if(opt->constraints==&HXT_PRINTABLE_RANGE) { + special = 1; + if(s[j]==' ' || s[j]=='\t' || s[j]=='\n') found = 1; + } + if(special!=1) { + for (int k=0; allowed[k]!='\0'; k++) { + if(s[j]==allowed[k]){ + found = 1; + break; + } + } + } + + if(found==0) + return HXT_ERROR_MSG(HXT_STATUS_FORMAT_ERROR, "argument \"%s\" of option \"%s\" contain the unvalid character %c", s[j]); + } + } + } + + return HXT_STATUS_OK; +} + + +static int getNextTrailingOption(int n) { + for (int i=n+1; i<optionListLength; i++) { + if(optionList[i].shortName=='\0' && optionList[i].longName==NULL) { + return i; + } + } + return -1; +} + + +HXTStatus hxtParseOptions(const int argc, char* argv[]) +{ + int dashdash = 0; + int trailing = getNextTrailingOption(0); + for (int i=1; i<argc; i++) { + const char *arg = NULL; + HXTOption* opt = NULL; + + if(dashdash || argv[i][0]!='-' || (argv[i][0]=='-' && argv[i][1]=='\0')){ + if(trailing==-1 || optionList[trailing].valuePtr==NULL) + return HXT_ERROR_MSG(HXT_STATUS_FORMAT_ERROR, + "Additional argument \"%s\" does not correspond to any option", + argv[i]); + else + HXT_CHECK( doOption(&optionList[trailing], argv[i], optionList[trailing].description) ); + + trailing = getNextTrailingOption(trailing); + } + else if(argv[i][1]=='-') { /* long opt */ + if(argv[i][2]=='\0') /* -- terminate argument parsing, + everything from now on is a trailing option */ { + dashdash = 1; + continue; + } + + char* equalSign = strchr(argv[i]+2,'='); + + if(equalSign!=NULL){ + *equalSign = '\0'; + arg = equalSign + 1; + } + + int num = searchLongOption(argv[i]+2); + if(num<0){ + return HXT_ERROR_MSG(HXT_STATUS_FORMAT_ERROR, + "option \"%s\" not found", argv[i]); + } + opt = &optionList[num]; + + if(equalSign!=NULL){ + *equalSign = '='; + if(opt->valueType==HXT_FLAG || opt->valueType==HXT_NO_FLAG){ + return HXT_ERROR_MSG(HXT_STATUS_FORMAT_ERROR, + "option \"%s\" takes no argument", argv[i]); + } + } + else{ + if(num==0) { // it's the help option + return HXT_STATUS_INTERNAL; + } + if(opt->valueType!=HXT_FLAG && opt->valueType!=HXT_NO_FLAG) { + if(argc<=i+1) { + return HXT_ERROR_MSG(HXT_STATUS_FORMAT_ERROR, + "options \"%s\" requires an argument", argv[i]); + } + else { + arg = argv[i+1]; + i++; + } + } + } + + HXT_CHECK( doOption(opt, arg, argv[i]) ); + } + else{ /* short option */ + int cond = argv[i][1]; + for(int j=1; cond; j++){ + int num = searchShortOption(argv[i][j]); + if(num<0){ + return HXT_ERROR_MSG(HXT_STATUS_FORMAT_ERROR, + "option \'%c\' in \"%s\" not found", argv[i][j], argv[i]); + } + + char optName[] = "- "; + optName[1] = argv[i][j]; + cond = argv[i][j+1]; + + if(num==0){ + return HXT_STATUS_INTERNAL; + } + + opt = &optionList[num]; + + if(opt->valueType!=HXT_FLAG && opt->valueType!=HXT_NO_FLAG){ + if(cond){ + arg = argv[i] + j+1; + cond = 0; // stop the loop + } + else if(argc<=i+1) { + return HXT_ERROR_MSG(HXT_STATUS_FORMAT_ERROR, + "options \'%c\' in \"%s\" requires an argument", argv[i][j], argv[i]); + } + else { + arg = argv[i+1]; + i++; + } + } + + HXT_CHECK( doOption(opt, arg, optName) ); + } + } + } + + if(trailing!=-1) { + if(getNextTrailingOption(trailing)!=-1) + return HXT_ERROR_MSG(HXT_STATUS_FORMAT_ERROR, "No \"%s\" given", optionList[trailing].description); + } + + HXT_CHECK( hxtFree(&optionList) ); + + return HXT_STATUS_OK; +} + + +#define MY_SPRINTF(...) *offset+=snprintf(text+ *offset, 16384- *offset, ## __VA_ARGS__ ) + +static const char* getHelpValueName(HXTOption* opt) { + switch(opt->valueType) { + case HXT_DOUBLE: + case HXT_FLOAT: + return "VAL"; + case HXT_INT: + case HXT_I64: + case HXT_I32: + case HXT_I16: + case HXT_UNSIGNED: + case HXT_U64: + case HXT_U32: + case HXT_U16: + return "NUM"; + case HXT_STRING: + return "TEXT"; + case HXT_EXISTING_FILENAME: + case HXT_NEW_FILENAME: + case HXT_ASK_TO_ERASE_FILENAME: + return "FILENAME"; + default: + return "(none)"; + } +} + + +static void printOptionLine(HXTOption* opt, char text[16384], int* offset) +{ + const int char_max = 30; + int oldOffset = *offset; + MY_SPRINTF(" "); + + if(opt->shortName!='\0'){ + if(opt->longName!=NULL){ + MY_SPRINTF("-%c, ", opt->shortName); + } + else{ + MY_SPRINTF("-%c", opt->shortName); + } + } + + if(opt->longName!=NULL){ + if(opt->valueType==HXT_FLAG || opt->valueType==HXT_NO_FLAG) + MY_SPRINTF("--%s", opt->longName); + else + MY_SPRINTF("--%s=%s", opt->longName, getHelpValueName(opt)); + + + } + + int char_count = *offset - oldOffset; + if(char_count<char_max) + MY_SPRINTF("%*c", char_max - char_count, ' '); + else + MY_SPRINTF("\n%*c", char_max, ' '); + + // description + { + int i,k; + for (i=0,k=0; opt->description[i+1]!='\0'; i++, k++) { + if(opt->description[i]=='\n'){ + if(opt->description[i+1]=='\n' || opt->description[i+1]=='\0') + MY_SPRINTF("%.*s\n", k, opt->description+i-k); + else + MY_SPRINTF("%.*s\n%*c", k, opt->description+i-k, char_max+2, ' '); + k=-1; + } + } + MY_SPRINTF("%s", opt->description+i-k); + } + + // default argument + if(opt->valueType!=HXT_FLAG && opt->valueType!=HXT_NO_FLAG) + { + double r = 0; + unsigned long long u = 0; + long long int i = 0; + MY_SPRINTF("\n%*cdefault: %s=", char_max+1, ' ', getHelpValueName(opt)); + switch(opt->valueType) { + case HXT_DOUBLE: + MY_SPRINTF("%g", *(double*) opt->valuePtr); + break; + case HXT_FLOAT: + r = *(float*) opt->valuePtr; + MY_SPRINTF("%g", r); + break; + case HXT_INT: + MY_SPRINTF("%d", *(int*) opt->valuePtr); + break; + case HXT_I64: + i = *(int64_t*) opt->valuePtr; + MY_SPRINTF("%lld", i); + break; + case HXT_I32: + i = *(int32_t*) opt->valuePtr; + MY_SPRINTF("%lld", i); + break; + case HXT_I16: + i = *(int16_t*) opt->valuePtr; + MY_SPRINTF("%lld", i); + break; + case HXT_UNSIGNED: + MY_SPRINTF("%u", *(unsigned*) opt->valuePtr); + break; + case HXT_U64: + u = *(uint64_t*) opt->valuePtr; + MY_SPRINTF("%llu", u); + break; + case HXT_U32: + u = *(uint32_t*) opt->valuePtr; + MY_SPRINTF("%llu", u); + break; + case HXT_U16: + u = *(uint16_t*) opt->valuePtr; + MY_SPRINTF("%llu", u); + break; + case HXT_STRING: + case HXT_EXISTING_FILENAME: + case HXT_NEW_FILENAME: + case HXT_ASK_TO_ERASE_FILENAME: + if(opt->valuePtr!=NULL) + MY_SPRINTF("%s", *(const char**) opt->valuePtr); + break; + default: + break; + } + } + + MY_SPRINTF("\n"); +} + + +HXTStatus hxtGetOptionHelp(char text[16384], + const char* programName, + const char* programDescription, + const char* additionalInfo) +{ + int offsetval = 0; + int* offset = &offsetval; + if(programName!=NULL) { + MY_SPRINTF("Usage: %s [OPTION]...", programName); + int n = getNextTrailingOption(0); + while(n!=-1 && optionList[n].valuePtr!=NULL) { + int n2 = getNextTrailingOption(n); + if(optionList[n].shortName=='\0' && optionList[n].longName==NULL && optionList[n].description!=NULL) { + if(n2==-1) + MY_SPRINTF(" [%s]", optionList[n].description); + else + MY_SPRINTF(" %s", optionList[n].description); + } + n=n2; + } + } + + if(programDescription!=NULL) + MY_SPRINTF("\n\n%s", programDescription); + MY_SPRINTF("\n\n"); + + for (int i=0; i<optionListLength; i++) { + if(optionList[i].shortName!='\0' || optionList[i].longName!=NULL) + printOptionLine(&optionList[i], text, offset); + } + + if(additionalInfo) + MY_SPRINTF("%s\n", additionalInfo); + return HXT_STATUS_OK; +} \ No newline at end of file diff --git a/contrib/hxt/predicates/CMakeLists.txt b/contrib/hxt/predicates/CMakeLists.txt index 6b12f414f1708905f194387488f8c815bab2dc01..b53b60341333a66ed2a02f4d4af8f4d0f92fb674 100644 --- a/contrib/hxt/predicates/CMakeLists.txt +++ b/contrib/hxt/predicates/CMakeLists.txt @@ -1,32 +1,53 @@ cmake_minimum_required(VERSION 3.9) project(hxt_predicates C) +# include guard for CMake: +# if you plan to include multiple directory that depend on this one, +# you need to include this directory first if(TARGET hxt_predicates) - # header guard for CMake. You need to include this directory first return() endif() + +################################################################################# +# Options (other than inherited ones) +################################################################################# +option(HXT_PREDICATES_OBJECT_ONLY "Do not create hxt_predicates library" ON) + + +################################################################################# +# Library definition +################################################################################# set(HXT_PREDICATES_SRC - "${CMAKE_CURRENT_SOURCE_DIR}/src/predicates.c" - "${CMAKE_CURRENT_SOURCE_DIR}/include/predicates.h" - ) + "${CMAKE_CURRENT_SOURCE_DIR}/src/predicates.c" + "${CMAKE_CURRENT_SOURCE_DIR}/include/predicates.h") -# make an object library (no archive) -add_library(hxt_predicates OBJECT ${HXT_PREDICATES_SRC}) +if(HXT_PREDICATES_OBJECT_ONLY) + # make an object library (no archive) + add_library(hxt_predicates OBJECT ${HXT_PREDICATES_SRC}) +else() + add_library(hxt_predicates ${HXT_PREDICATES_SRC}) +endif() target_include_directories(hxt_predicates INTERFACE include) +target_link_libraries(hxt_predicates m) # link with the math library + -# do not use extended double precision or arithmetic contraction in predicates.c +################################################################################# +# Compilation flags to ensure robustness +################################################################################# if(MSVC OR (CMAKE_C_COMPILER_ID STREQUAL "Intel" AND WIN32)) target_compile_options(hxt_predicates PRIVATE "/fp:strict") elseif(CMAKE_C_COMPILER_ID STREQUAL "Intel") - target_compile_options(${target} ${keyword} "-fp-model" "strict") + target_compile_options(hxt_predicates PRIVATE "-fp-model=strict") elseif(CMAKE_C_COMPILER_ID MATCHES "GNU|Clang") - target_compile_options(hxt_predicates PRIVATE "-fno-unsafe-math-optimizations" "-ffp-contract=off") + target_compile_options(hxt_predicates + PRIVATE + "-fno-unsafe-math-optimizations" "-ffp-contract=off") else() message(WARNING - "Unsupported compiler ! - Make sure compiled functions from predicates.c - do NOT use extended double precision and follow IEEE754 standard. - It is crucial for the robustness of geometric predicates.") + "Unsupported compiler ! + Make sure compiled functions from predicates.c + do NOT use extended double precision and follow IEEE754 standard. + It is crucial for the robustness of geometric predicates.") endif() diff --git a/contrib/hxt/reparam/CMakeLists.txt b/contrib/hxt/reparam/CMakeLists.txt index 498faf3150952c5297591524a8055c5ee0875c05..caa1e03cca5a83b08a1e41b6fd66465af295d174 100644 --- a/contrib/hxt/reparam/CMakeLists.txt +++ b/contrib/hxt/reparam/CMakeLists.txt @@ -1,11 +1,24 @@ cmake_minimum_required(VERSION 3.9) project(hxt_reparam C) -# most options are inherited from hxt_core (see ../core/CMakeList.txt) +# include guard for CMake: +# if you plan to include multiple directory that depend on this one, +# you need to include this directory first +if(TARGET hxt_reparam) + return() +endif() + -option(HXT_ENABLE_PETSC "USE PETSc as linear solver (requires petsc compile without mpi and for real numbers)" ON) +################################################################################# +# Options +################################################################################# +option(HXT_ENABLE_PETSC "USE PETSc as linear solver (requires petsc compile without mpi and for real numbers)" ON) option(HXT_REPARAM_OBJECT_ONLY "Do not create hxt_reparam library" OFF) + +################################################################################# +# Library definition +################################################################################# set(HXT_REPARAM_SRC "${CMAKE_CURRENT_SOURCE_DIR}/src/hxt_edge.c" "${CMAKE_CURRENT_SOURCE_DIR}/src/hxt_curvature.c" @@ -21,26 +34,25 @@ set(HXT_REPARAM_SRC "${CMAKE_CURRENT_SOURCE_DIR}/include/hxt_curvature.h" "${CMAKE_CURRENT_SOURCE_DIR}/include/hxt_edge.h" "${CMAKE_CURRENT_SOURCE_DIR}/include/hxt_linear_system.h" - "${CMAKE_CURRENT_SOURCE_DIR}/include/hxt_mean_values.h" - ) + "${CMAKE_CURRENT_SOURCE_DIR}/include/hxt_mean_values.h") if(HXT_REPARAM_OBJECT_ONLY) - add_library(hxt_reparam OBJECT ${HXT_REPARAM_SRC}) + add_library(hxt_reparam OBJECT ${HXT_REPARAM_SRC}) else() - add_library(hxt_reparam ${HXT_REPARAM_SRC}) + add_library(hxt_reparam ${HXT_REPARAM_SRC}) endif() add_subdirectory(../core "${CMAKE_CURRENT_BINARY_DIR}/core") -target_link_libraries(hxt_reparam PUBLIC hxt_core) +target_link_libraries(hxt_reparam PUBLIC hxt_core PRIVATE m) target_compile_features(hxt_reparam PRIVATE c_std_99) target_include_directories(hxt_reparam PUBLIC include) if(ENABLE_PETSC) - list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") - find_package(PETSc REQUIRED) - target_include_directories(hxt_reparam PRIVATE "${PETSC_INC}") - target_link_libraries(hxt_reparam PRIVATE "${PETSC_LIBS}") - target_compile_definitions(hxt_reparam PRIVATE HXT_HAVE_PETSC) + list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") + find_package(PETSc REQUIRED) + target_include_directories(hxt_reparam PRIVATE "${PETSC_INC}") + target_link_libraries(hxt_reparam PRIVATE "${PETSC_LIBS}") + target_compile_definitions(hxt_reparam PRIVATE HXT_HAVE_PETSC) endif() diff --git a/contrib/hxt/reparam/include/hxt_edge.h b/contrib/hxt/reparam/include/hxt_edge.h index 8857d9b0c4cb799444f59f4118ba1875586fa419..4334bc99d89b14031b6fa1b4457d7a0e0a2ec1f9 100644 --- a/contrib/hxt/reparam/include/hxt_edge.h +++ b/contrib/hxt/reparam/include/hxt_edge.h @@ -44,6 +44,7 @@ HXTStatus hxtEdgesSetBoundaries(HXTEdges *edges, HXTBoundaries **boundaries); HXTStatus hxtEdgesCreate(HXTMesh *mesh, HXTEdges** edges); +HXTStatus hxtEdgesCreateNonManifold(HXTMesh *mesh, HXTEdges** edges); HXTStatus hxtEdgesDelete(HXTEdges **edges); int hxtEdgesIsBoundary (HXTEdges *edges, uint32_t *e); diff --git a/contrib/hxt/reparam/src/hxt_curvature.c b/contrib/hxt/reparam/src/hxt_curvature.c index 84236357b536fccbce4ea8b272388f36c21755c4..550797ccbeede37f45dde2e9e0996f21ae1ce69c 100644 --- a/contrib/hxt/reparam/src/hxt_curvature.c +++ b/contrib/hxt/reparam/src/hxt_curvature.c @@ -1,6 +1,5 @@ #include "hxt_curvature.h" #include "hxt_tools.h" -#include <math.h> #include <stdio.h> // #include <time.h> // for commented timings diff --git a/contrib/hxt/reparam/src/hxt_edge.c b/contrib/hxt/reparam/src/hxt_edge.c index 99538a974a827edc1a51f67eba0ddda6ed12a029..70cc9c6c926499ea1e53e8e6591461fce52932d3 100644 --- a/contrib/hxt/reparam/src/hxt_edge.c +++ b/contrib/hxt/reparam/src/hxt_edge.c @@ -1,7 +1,5 @@ #include "hxt_edge.h" #include "hxt_tools.h" -#include <string.h> -#include <math.h> struct hxtLineLoopStruct{ double length; @@ -23,6 +21,7 @@ double hxtEdgesLength(const HXTEdges *edges,uint32_t ie){ int i1 = edges->node[2*ie+0]; int i2 = edges->node[2*ie+1];; + double *x1 = mesh->vertices.coord+i1*4; double *x2 = mesh->vertices.coord+i2*4; double dx = x1[0]-x2[0]; @@ -357,10 +356,131 @@ HXTStatus hxtEdgesCreate(HXTMesh *mesh, HXTEdges** edges) for(uint64_t i=0; i<nTriangles; i++){ for(uint64_t j=0; j<3; j++){ uint32_t e = tri2edg[i*3+j]; + if(edg2tri[e*2+0] == (uint64_t)-1) + edg2tri[e*2+0] = i; + else + if(edg2tri[e*2+1] == (uint64_t)-1) + edg2tri[e*2+1] = i; + else + return HXT_ERROR_MSG( HXT_STATUS_ASSERTION_FAILED,"hxt_edge.c:\t topology is wrong for edge creation \n\t At least three triangles (%lu;%lu,%lu) share the same edge\n",i,edg2tri[e*2+0],edg2tri[e*2+1]); + + } + } + (*edges)->edg2tri = edg2tri; + + // compute the total number of boundary edges + int edgesBdryTotal = 0; + for(uint32_t i=0; i<(*edges)->numEdges; i++) + if((*edges)->edg2tri[2*i+1] == (uint64_t)-1 || + hxtEdgesIsBoundary ((*edges), &((*edges)->node[2*i]) )) + edgesBdryTotal++; + (*edges)->edgesBdryTotal = edgesBdryTotal; + + return HXT_STATUS_OK; + +} + + +HXTStatus hxtEdgesCreateNonManifold(HXTMesh *mesh, HXTEdges** edges) +{ + + uint64_t nTriangles = mesh->triangles.num; + + HXT_CHECK( hxtMalloc (edges,sizeof(HXTEdges)) ); + + // build edges of the boundary simply by copying the edges of the + // mesh. We prefer to copy because they are sorted + uint64_t nEdgesBdry = mesh->lines.num; + uint32_t *bdryedges; + HXT_CHECK(hxtMalloc(&bdryedges,2*(nEdgesBdry+1)*sizeof(uint32_t))); // allocate at least one :-) + (*edges)->bdryedges = bdryedges; + memcpy ( bdryedges, mesh->lines.node, 2*nEdgesBdry*sizeof(uint32_t)); + qsort(bdryedges,nEdgesBdry,2*sizeof(uint32_t),halfedgecmp); + (*edges)->nEdgesBdry = nEdgesBdry; + + (*edges)->numEdges = 0; + (*edges)->global = NULL; + (*edges)->node = NULL; + (*edges)->color = NULL; + (*edges)->edg2tri = NULL; + (*edges)->tri2edg = NULL; + + (*edges)->edg2mesh = mesh; + + + // build edge + uint32_t *halfedges; + HXT_CHECK(hxtMalloc(&halfedges,3*3*nTriangles*sizeof(uint32_t))); + for(uint64_t i = 0; i<nTriangles; i++) { + for(int j=0; j<3; j++){ + halfedges[i*9+j*3+0] = mesh->triangles.node[3*i+j];//first node of an edge + halfedges[i*9+j*3+1] = mesh->triangles.node[3*i+(j+1)%3];//second node of an edge + halfedges[i*9+j*3+2] = (uint32_t) i;//triangle having this edge + } + } + qsort(halfedges,nTriangles*3,3*sizeof(uint32_t),halfedgecmp); + uint32_t *tri2edg; + HXT_CHECK(hxtMalloc(&tri2edg,3*nTriangles*sizeof(uint32_t))); + uint32_t nEdges = 0; + for(uint64_t i=0; i< nTriangles*3; i++){ + uint32_t *he = halfedges+i*3; + for(int k=0; k<3; k++) + if (mesh->triangles.node[he[2]*3+k] == he[0]) + tri2edg[he[2]*3+k] = nEdges; + if (i+1 == nTriangles*3 || halfedgecmp(he,he+3) != 0) + nEdges++; + } + (*edges)->numEdges = nEdges; + (*edges)->tri2edg = tri2edg; + + + uint32_t *node; + HXT_CHECK(hxtMalloc(&node,2*nEdges*sizeof(uint32_t))); + int p=0; + for(uint64_t i=0; i<nTriangles*3; i++){ + uint32_t *he = halfedges+i*3; + if(i+1 == nTriangles*3 || halfedgecmp(he,he+3) != 0){ + node[p*2+0] = he[0]; + node[p*2+1] = he[1]; + p++; + } + } + (*edges)->node = node; + HXT_CHECK(hxtFree(&halfedges)); + uint64_t *edg2tri; + HXT_CHECK(hxtMalloc(&edg2tri,2*nEdges*sizeof(uint64_t))); + for(uint32_t i=0; i<nEdges*2; i++) + edg2tri[i] = -1; + + for(uint64_t i=0; i<nTriangles; i++){ + for(uint64_t j=0; j<3; j++){ + uint32_t e = tri2edg[i*3+j]; + if(edg2tri[e*2+0] == (uint64_t)-1) edg2tri[e*2+0] = i; else edg2tri[e*2+1] = i; + + // ATTENTION TODO non manifold case fix + + /*if(edg2tri[e*2+1] == (uint64_t)-1)*/ + /*edg2tri[e*2+1] = i;*/ + /*else{*/ + /*printf("%lu %lu %lu \n",i+mesh->points.num+mesh->lines.num+1,*/ + /*edg2tri[e*2+0]+mesh->points.num+mesh->lines.num+1,*/ + /*edg2tri[e*2+1]+mesh->points.num+mesh->lines.num+1);*/ + /*printf("%d %d %d \n", mesh->triangles.colors[i],*/ + /*mesh->triangles.colors[edg2tri[e*2+0]],*/ + /*mesh->triangles.colors[edg2tri[e*2+1]]);*/ + /*uint64_t t1 = edg2tri[2*e+0];*/ + /*uint64_t t2 = edg2tri[2*e+1];*/ + /*printf("%d %d %d %d \n", tri2edg[3*i +0], tri2edg[3*i +1], tri2edg[3*i +2], mesh->triangles.colors[i]);*/ + /*printf("%d %d %d %d \n", tri2edg[3*t1+0], tri2edg[3*t1+1], tri2edg[3*t1+2], mesh->triangles.colors[t1]);*/ + /*printf("%d %d %d %d \n", tri2edg[3*t2+0], tri2edg[3*t2+1], tri2edg[3*t2+2], mesh->triangles.colors[t2]);*/ + /*return HXT_ERROR_MSG( HXT_STATUS_ASSERTION_FAILED,*/ + /*"hxt_edge.c:\t topology is wrong for edge creation \n\t At least three triangles (%lu,%lu,%lu) share the same edge\n",i,edg2tri[e*2+0],edg2tri[e*2+1]);*/ + /*}*/ + } } (*edges)->edg2tri = edg2tri; diff --git a/contrib/hxt/reparam/src/hxt_linear_system_lu.c b/contrib/hxt/reparam/src/hxt_linear_system_lu.c index 7e530e0c654eaa9910ed53ea5fabecf0e5d2e00a..a8186defc1043383ad61101f762005c62dce9c79 100644 --- a/contrib/hxt/reparam/src/hxt_linear_system_lu.c +++ b/contrib/hxt/reparam/src/hxt_linear_system_lu.c @@ -1,7 +1,3 @@ -#include <math.h> -#include <stdlib.h> -#include <stdio.h> - #include "hxt_tools.h" #include "hxt_linear_system_lu.h" diff --git a/contrib/hxt/reparam/src/hxt_mean_values.c b/contrib/hxt/reparam/src/hxt_mean_values.c index bc7a24fee46d557031709c2a080fdc65930b281c..582da898d39b73a359c06ff88b621f529b99e12d 100644 --- a/contrib/hxt/reparam/src/hxt_mean_values.c +++ b/contrib/hxt/reparam/src/hxt_mean_values.c @@ -4,13 +4,6 @@ #include "hxt_tools.h" -#include <math.h> -#ifndef M_PI - #define M_PI 3.14159265358979323846264338327950 -#endif // !M_PI - - - struct HXTMeanValuesStruct{ HXTEdges *initialEdges; double *uv;// parametrization coordinates diff --git a/contrib/hxt/reparam/src/hxt_non_linear_solver.c b/contrib/hxt/reparam/src/hxt_non_linear_solver.c index ac15117d3f7c3eb5a24e9b5e054a65f5a003dcc2..14331de74c3b58f2920ce62ae9bddf556bced05f 100644 --- a/contrib/hxt/reparam/src/hxt_non_linear_solver.c +++ b/contrib/hxt/reparam/src/hxt_non_linear_solver.c @@ -1,6 +1,5 @@ #include "hxt_non_linear_solver.h" #include "hxt_tools.h" -#include <math.h> HXTStatus hxtNewtonRaphson(HXTLinearSystem *nrSys, double *solution, int size, int maxiter, double tol, HXTNonLinearSolverCallbackF *fcb, HXTNonLinearSolverCallbackDF *dfcb, void *data) { double *delta, *rhs; diff --git a/contrib/hxt/tetBR/CMakeLists.txt b/contrib/hxt/tetBR/CMakeLists.txt index c7feef927c1484c374997d5cddca04bb13900b55..8dcf06c806be3fdb6941143624a190c9204dea2f 100644 --- a/contrib/hxt/tetBR/CMakeLists.txt +++ b/contrib/hxt/tetBR/CMakeLists.txt @@ -1,14 +1,26 @@ cmake_minimum_required(VERSION 3.9) project(hxt_tetBR CXX) -# options are inherited from hxt_core (see ../core/CMakeList.txt) +# include guard for CMake: +# if you plan to include multiple directory that depend on this one, +# you need to include this directory first +if(TARGET hxt_tetBR) + return() +endif() + +################################################################################# +# Options +################################################################################# option(HXT_TETBR_OBJECT_ONLY "Do not create hxt_tetBR library" OFF) + +################################################################################# +# Library definition +################################################################################# set(HXT_TETBR_SRC - "${CMAKE_CURRENT_SOURCE_DIR}/src/hxt_boundary_recovery.cxx" - "${CMAKE_CURRENT_SOURCE_DIR}/include/hxt_boundary_recovery.h" - ) + "${CMAKE_CURRENT_SOURCE_DIR}/src/hxt_boundary_recovery.cxx" + "${CMAKE_CURRENT_SOURCE_DIR}/include/hxt_boundary_recovery.h") if(HXT_TETBR_OBJECT_ONLY) add_library(hxt_tetBR OBJECT ${HXT_TETBR_SRC}) @@ -23,6 +35,12 @@ target_include_directories(hxt_tetBR PUBLIC include PRIVATE src) target_link_libraries(hxt_tetBR - PUBLIC hxt_core - PRIVATE hxt_predicates) + PUBLIC hxt_core + PRIVATE hxt_predicates m) +if(HXT_ENABLE_OPENMP) + find_package(OpenMP 4) + if(OpenMP_CXX_FOUND) + target_link_libraries(hxt_tetBR PUBLIC OpenMP::OpenMP_CXX) + endif() +endif() \ No newline at end of file diff --git a/contrib/hxt/tetBR/src/hxt_boundary_recovery.cxx b/contrib/hxt/tetBR/src/hxt_boundary_recovery.cxx index 808634e06ebaf97df6aa1cf182d45a4ec6893793..1d34160a87921cdfe1eeb230d733f1f91cae0d58 100644 --- a/contrib/hxt/tetBR/src/hxt_boundary_recovery.cxx +++ b/contrib/hxt/tetBR/src/hxt_boundary_recovery.cxx @@ -6,7 +6,6 @@ extern "C" { } #include <assert.h> -#include <math.h> #include <set> #include <vector> #include <time.h> diff --git a/contrib/hxt/tetMesh/CMakeLists.txt b/contrib/hxt/tetMesh/CMakeLists.txt index b44b63b5cfcf43416271001f318f7526bad27d4e..29bc5b077e89bfc268c661d0b3d8c46b12c6f56c 100644 --- a/contrib/hxt/tetMesh/CMakeLists.txt +++ b/contrib/hxt/tetMesh/CMakeLists.txt @@ -1,9 +1,24 @@ cmake_minimum_required(VERSION 3.9) -project(hxt_tetMesh C) +project(hxt_tetMesh C CXX) -# most options are inherited from hxt_core (see ../core/CMakeList.txt) +# include guard for CMake: +# if you plan to include multiple directory that depend on this one, +# you need to include this directory first +if(TARGET hxt_tetMesh) + return() +endif() + + +################################################################################# +# Options +################################################################################# option(HXT_TETMESH_OBJECT_ONLY "Do not create hxt_tetMesh library" OFF) +option(HXT_TETMESH_BUILD_CLI "build hxt_tetMesh CLI tools" ON) + +################################################################################# +# Library definition +################################################################################# set(HXT_TETMESH_SRC "${CMAKE_CURRENT_SOURCE_DIR}/src/HXTSPR.c" "${CMAKE_CURRENT_SOURCE_DIR}/src/hxt_tetFlag.c" @@ -21,22 +36,22 @@ set(HXT_TETMESH_SRC "${CMAKE_CURRENT_SOURCE_DIR}/src/hxt_tetDelaunay.c" "${CMAKE_CURRENT_SOURCE_DIR}/src/hxt_tetNodalSize.c" "${CMAKE_CURRENT_SOURCE_DIR}/src/HXTSPR.h" - "${CMAKE_CURRENT_SOURCE_DIR}/src/hxt_tetFlag.h" - "${CMAKE_CURRENT_SOURCE_DIR}/src/hxt_tetOpti.h" "${CMAKE_CURRENT_SOURCE_DIR}/src/hxt_tetSync.h" "${CMAKE_CURRENT_SOURCE_DIR}/src/hxt_tetColor.h" "${CMAKE_CURRENT_SOURCE_DIR}/src/hxt_tetUtils.h" - "${CMAKE_CURRENT_SOURCE_DIR}/src/hxt_vertices.h" "${CMAKE_CURRENT_SOURCE_DIR}/src/hxt_smoothing.h" "${CMAKE_CURRENT_SOURCE_DIR}/src/hxt_tetRefine.h" - "${CMAKE_CURRENT_SOURCE_DIR}/src/hxt_tetRepair.h" "${CMAKE_CURRENT_SOURCE_DIR}/src/hxt_tetQuality.h" "${CMAKE_CURRENT_SOURCE_DIR}/src/hxt_edgeRemoval.h" - "${CMAKE_CURRENT_SOURCE_DIR}/src/hxt_tetDelaunay.h" "${CMAKE_CURRENT_SOURCE_DIR}/src/hxt_tetNodalSize.h" "${CMAKE_CURRENT_SOURCE_DIR}/src/hxt_tetOptiUtils.h" "${CMAKE_CURRENT_SOURCE_DIR}/src/hxt_tetPartition.h" + "${CMAKE_CURRENT_SOURCE_DIR}/include/hxt_tetDelaunay.h" + "${CMAKE_CURRENT_SOURCE_DIR}/include/hxt_tetFlag.h" "${CMAKE_CURRENT_SOURCE_DIR}/include/hxt_tetMesh.h" + "${CMAKE_CURRENT_SOURCE_DIR}/include/hxt_tetOpti.h" + "${CMAKE_CURRENT_SOURCE_DIR}/include/hxt_tetRepair.h" + "${CMAKE_CURRENT_SOURCE_DIR}/include/hxt_vertices.h" ) if(HXT_TETMESH_OBJECT_ONLY) @@ -53,6 +68,27 @@ target_include_directories(hxt_tetMesh PRIVATE src) target_link_libraries(hxt_tetMesh PUBLIC hxt_core - PRIVATE hxt_predicates) + PRIVATE hxt_predicates m) target_compile_features(hxt_tetMesh PRIVATE c_std_99) + + +################################################################################# +# Executable definition +################################################################################# +if(HXT_TETMESH_BUILD_CLI) + # tetMesh_CLI + add_executable(tetMesh_CLI "${CMAKE_CURRENT_SOURCE_DIR}/exe/tetMesh_CLI.c") + + add_subdirectory(../tetBR "${CMAKE_CURRENT_BINARY_DIR}/tetBR") + + target_link_libraries(tetMesh_CLI hxt_core hxt_predicates hxt_tetMesh hxt_tetBR) + + # # Delaunay_CLI + add_executable(Delaunay_CLI "${CMAKE_CURRENT_SOURCE_DIR}/exe/Delaunay_CLI.c") + target_link_libraries(Delaunay_CLI hxt_core hxt_predicates hxt_tetMesh) + + # tetOpti_CLI + add_executable(tetOpti_CLI "${CMAKE_CURRENT_SOURCE_DIR}/exe/tetOpti_CLI.c") + target_link_libraries(tetOpti_CLI hxt_core hxt_predicates hxt_tetMesh) +endif() \ No newline at end of file diff --git a/contrib/hxt/tetMesh/exe/Delaunay_CLI.c b/contrib/hxt/tetMesh/exe/Delaunay_CLI.c new file mode 100644 index 0000000000000000000000000000000000000000..61a316299eed2eac30e86b65194922fb458f31fb --- /dev/null +++ b/contrib/hxt/tetMesh/exe/Delaunay_CLI.c @@ -0,0 +1,214 @@ +// Hxt - Copyright (C) +// 2016 - 2020 UCLouvain +// +// See the LICENSE.txt file for license information. +// +// Contributor(s): +// Célestin Marot + +#include "hxt_tetDelaunay.h" +#include "hxt_opt.h" +#include "hxt_omp.h" + + +int main(int argc, char** argv) { + + const char* input = NULL; + const char* output = NULL; + int nthreads = 0; + int reproducible = 0; + int verbosity = 1; + int stat = 0; + int preserve_order = 0; + uint32_t nvert = 0; + + + HXT_CHECK( hxtAddOption('i', "input", "Input file in the MSH ASCII file format", HXT_EXISTING_FILENAME, NULL, &input)); + HXT_CHECK( hxtAddOption('G', "generate", + "Generate N random points following a uniform\n" + "distribution inside the unit cube.\n" + "This option is ignored if an input file is given", HXT_U32, NULL, &nvert) ); + HXT_CHECK( hxtAddOption('t', "threads", + "Number of threads to use.\n" + " * NUM=0 use OMP_NUM_THREADS\n" + " * NUM<0 use OMP_NUM_PROCS", HXT_INT, NULL, &nthreads) ); + HXT_CHECK( hxtAddOption('r', "reproducible", + "Delaunay will always produce the same tetrahedra\n" + "given the same points in the same order.\n" + "However, the order in which tetrahedra end up\n" + "can differ when using multiple threads.\n" + "This option re-order tetrahedra to obtain\n" + "a reproducible ouput mesh", HXT_FLAG, NULL, &reproducible) ); + HXT_CHECK( hxtAddOption('v', "verbosity", + "Verbosity level of output messages\n" + " * NUM=0 : print no information\n" + " * NUM=1 : print some information\n" + " * NUM=2 or ommited : print all information", HXT_INT, &HXT_0_2_RANGE, &verbosity)); + HXT_CHECK( hxtAddOption('s', "stat", + "Print timing for each portion of the program", HXT_FLAG, NULL, &stat) ); + HXT_CHECK( hxtAddOption('p', "preserve-pts-order", + "Do not optimize points ordering\n" + "The initial ordering of points is preserved\nbut the program is slower", HXT_FLAG, NULL, &preserve_order) ); + + HXT_CHECK( hxtAddTrailingOption("OUTPUT_FILE", HXT_STRING, NULL, &output)); + + HXT_PARSE_COMMAND_LINE(argc, argv, + "hxtDelaunay", + "Compute the Delaunay of a set of points. The tetrahedral mesh OUTPUT_FILE is written in the MSH ASCII format", + "Example:\n\thxtDelaunay -st4 input.msh output.msh\n--\nContact: celestin.marot@uclouvain.be"); + + if(input==NULL && nvert<=0){ + return HXT_ERROR_MSG(HXT_STATUS_ERROR ,"No point to triangulate (use -h or --help for help message)"); + } + + /******************************************************************************* + * All options were verified, we can do the Delaunay now... + ******************************************************************************/ + + double t0=0,t1=0,t2=0,t3=0; + + if(stat) + t0 = omp_get_wtime(); + + HXTMesh *mesh; + HXT_CHECK(hxtMeshCreate(&mesh)); + + if(input!=NULL) { + HXT_INFO_COND(verbosity>0, "Reading \"%s\"", input); + HXT_CHECK(hxtMeshReadGmsh(mesh, input) ); + + if(mesh->tetrahedra.num!=0){ + HXT_WARNING("Mesh file \"%s\" already contains volumes. We delete them",input); + + //tetrahedra + HXT_CHECK( hxtAlignedFree(&mesh->tetrahedra.colors) ); + HXT_CHECK( hxtAlignedFree(&mesh->tetrahedra.node) ); + mesh->tetrahedra.num = 0; + mesh->tetrahedra.size = 0; + + // hexahedra + HXT_CHECK( hxtAlignedFree(&mesh->hexahedra.colors) ); + HXT_CHECK( hxtAlignedFree(&mesh->hexahedra.flag) ); + HXT_CHECK( hxtAlignedFree(&mesh->hexahedra.node) ); + HXT_CHECK( hxtAlignedFree(&mesh->hexahedra.neigh) ); + HXT_CHECK( hxtAlignedFree(&mesh->hexahedra.neighType) ); + mesh->hexahedra.num = 0; + mesh->hexahedra.size = 0; + + // prisms + HXT_CHECK( hxtAlignedFree(&mesh->prisms.colors) ); + HXT_CHECK( hxtAlignedFree(&mesh->prisms.flag) ); + HXT_CHECK( hxtAlignedFree(&mesh->prisms.node) ); + HXT_CHECK( hxtAlignedFree(&mesh->prisms.neigh) ); + HXT_CHECK( hxtAlignedFree(&mesh->prisms.neighType) ); + mesh->prisms.num = 0; + mesh->prisms.size = 0; + + // pyramids + HXT_CHECK( hxtAlignedFree(&mesh->pyramids.colors) ); + HXT_CHECK( hxtAlignedFree(&mesh->pyramids.flag) ); + HXT_CHECK( hxtAlignedFree(&mesh->pyramids.node) ); + HXT_CHECK( hxtAlignedFree(&mesh->pyramids.neigh) ); + HXT_CHECK( hxtAlignedFree(&mesh->pyramids.neighType) ); + mesh->pyramids.num = 0; + mesh->pyramids.size = 0; + + // quads + HXT_CHECK( hxtAlignedFree(&mesh->quads.node) ); + HXT_CHECK( hxtAlignedFree(&mesh->quads.colors) ); + mesh->quads.num = 0; + mesh->quads.num = 0; + + } + if((mesh->lines.num!=0 || mesh->triangles.num!=0) && !preserve_order) { + HXT_WARNING("Mesh file \"%s\" contains triangles and/or lines.\n" + "\tWe delete them unless the -p/--preserve-pts-order option is specified", input); + // triangles + HXT_CHECK( hxtAlignedFree(&mesh->triangles.node) ); + HXT_CHECK( hxtAlignedFree(&mesh->triangles.colors) ); + mesh->triangles.num = 0; + mesh->triangles.size = 0; + + // lines + HXT_CHECK( hxtAlignedFree(&mesh->lines.node) ); + HXT_CHECK( hxtAlignedFree(&mesh->lines.colors) ); + mesh->lines.num = 0; + mesh->lines.size = 0; + } + } + else { + HXT_INFO_COND(verbosity>0, "Creating %d random vertices", nvert); + HXT_CHECK( hxtAlignedMalloc(&mesh->vertices.coord, nvert*4*sizeof(double)) ); + + for (uint32_t i=0; i<nvert; i++) { + for (int j=0; j<3; j++) { + mesh->vertices.coord[4*i+j] = (double) rand()/RAND_MAX; + } + } + + mesh->vertices.num = nvert; + mesh->vertices.size = nvert; + } + + if(stat) + t1 = omp_get_wtime(); + + HXTDelaunayOptions delOptions = { + .bbox = NULL, + .nodalSizes = NULL, + .numVerticesInMesh = 0, + .partitionability = 0, + .verbosity = verbosity, + .reproducible = reproducible, + .delaunayThreads = nthreads + }; + + if(preserve_order) { + hxtNodeInfo* nodeInfo; + HXT_CHECK( hxtAlignedMalloc(&nodeInfo, sizeof(hxtNodeInfo)*mesh->vertices.num) ); + + #pragma omp parallel for simd aligned(nodeInfo:SIMD_ALIGN) + for (uint32_t i=0; i<mesh->vertices.num; i++) { + nodeInfo[i].node = i; + nodeInfo[i].status = HXT_STATUS_TRYAGAIN; + } + HXT_CHECK( hxtDelaunaySteadyVertices(mesh, &delOptions, nodeInfo, mesh->vertices.num) ); + HXT_CHECK( hxtAlignedFree(&nodeInfo) ); + } + else + HXT_CHECK( hxtDelaunay(mesh, &delOptions) ); + + if(stat) + t2 = omp_get_wtime(); + + if(output!=NULL){ + HXT_INFO_COND(verbosity>0, "Writing result to \"%s\"", output); + #pragma omp parallel for + for (uint64_t i=0; i<mesh->tetrahedra.num; i++) { + mesh->tetrahedra.colors[i] = 0; + } + HXT_CHECK( hxtMeshWriteGmsh(mesh, output) ); + } + + if(stat){ + t3 = omp_get_wtime(); + HXT_INFO("\n\t========== Statistics =========="); + HXT_INFO("Mesh contains %" HXTu64 " tetrahedra and %u vertices", + mesh->tetrahedra.num, + mesh->vertices.num); + if(input) + HXT_INFO("Reading file \"%s\" took %.2f seconds", input, t1-t0); + else + HXT_INFO("Creating random points took %.2f seconds", t1-t0); + HXT_INFO("Init + BRIO + Delaunay took %.2f seconds (%.2f Mtet/s)", t2-t1, 0.000001*mesh->tetrahedra.num/(t2-t1)); + if(output) + HXT_INFO("Writing file \"%s\" took %.2f seconds",output, t3-t2); + } + + + putchar('\n'); + + HXT_CHECK( hxtMeshDelete(&mesh) ); + + return 0; +} \ No newline at end of file diff --git a/contrib/hxt/tetMesh/exe/tetMesh_CLI.c b/contrib/hxt/tetMesh/exe/tetMesh_CLI.c new file mode 100644 index 0000000000000000000000000000000000000000..088197b9a2289b8d7109af2792a9833aba1cecf4 --- /dev/null +++ b/contrib/hxt/tetMesh/exe/tetMesh_CLI.c @@ -0,0 +1,119 @@ +// Hxt - Copyright (C) +// 2016 - 2020 UCLouvain +// +// See the LICENSE.txt file for license information. +// +// Contributor(s): +// Célestin Marot + +#include "hxt_tetMesh.h" +#include "hxt_boundary_recovery.h" +#include "hxt_opt.h" +#include "hxt_tools.h" +#include "hxt_omp.h" + + +static HXTStatus recoveryFun(HXTMesh* mesh, void* userData) { + HXT_UNUSED(userData); + HXT_CHECK( hxt_boundary_recovery(mesh) ); + return HXT_STATUS_OK; +} + +int main(int argc, char** argv) { + + const char* input = NULL; + const char* output = NULL; + const char* geoFile = NULL; + + HXTTetMeshOptions options = {.refine=1, .optimize=1, .verbosity=1, .qualityMin=0.35, .recoveryFun=recoveryFun}; + + HXT_CHECK( hxtAddOption('t', "omp_num_threads", + "Number of threads used for parallel work.\n" + "If NUM<=0, use OMP_NUM_THREADS environment variable", HXT_INT, NULL, &options.defaultThreads)); + HXT_CHECK( hxtAddOption('d', "delaunay_threads", + "Overrides the maximum number of threads for Delaunay insertion\n" + " * NUM>0: use NUM threads\n" + " * NUM=0: use the default nbr. of threads (see `-t` option)\n" + " * NUM<0: use OMP_NUM_PROCS", HXT_INT, NULL, &options.delaunayThreads)); + HXT_CHECK( hxtAddOption('o', "opti_threads", + "Overrides the maximum number of threads for mesh optimizations\n" + " * NUM>0: use NUM threads\n" + " * NUM=0: use the default nbr. of threads (see `-t` option)\n" + " * NUM<0: use OMP_NUM_PROCS", HXT_INT, NULL, &options.improveThreads)); + HXT_CHECK( hxtAddOption('r', "reproducible", + "Reproducible mesh:\n" + "The output mesh will be identical with this option\n" + "if given\n" + " - the same vertices in the same order\n" + " - the same number of threads\n" + "WARNING: This option slows down the mesh generation\n" + "except with 1 thread", HXT_FLAG, NULL, &options.reproducible)); + HXT_CHECK( hxtAddOption('v', "verbosity", + "Verbosity level of output messages\n" + " * NUM=0: print no information\n" + " * NUM=1: print some information\n" + " * NUM=2: print all information", HXT_INT, &HXT_0_2_RANGE, &options.verbosity)); + HXT_CHECK( hxtAddOption('s', "stat", "Print timing for each portion of the program", HXT_FLAG, NULL, &options.stat)); + HXT_CHECK( hxtAddOption('n', "no-refinement", "Do not refine the mesh => no vertices are added", HXT_NO_FLAG, NULL, &options.refine)); + HXT_CHECK( hxtAddOption('N', "no-improvement", "Do not optimize the mesh quality", HXT_NO_FLAG, NULL, &options.optimize) ); + HXT_CHECK( hxtAddOption('a', "aspect-ratio-min", "The threshold on the aspect-ratio used during the optimization", HXT_DOUBLE, &HXT_0_1_RANGE, &options.qualityMin)); + + const HXTOptionArgumentConstraints geoSuffix = {.stringSuffix=".geo"}; + HXT_CHECK( hxtAddOption('g', "generate-geo", "Write a .geo file that describe the volumes from the input surface mesh", HXT_ASK_TO_ERASE_FILENAME, &geoSuffix, &geoFile)); + + HXT_CHECK( hxtAddTrailingOption("INPUT_FILE", HXT_EXISTING_FILENAME, NULL, &input)); + HXT_CHECK( hxtAddTrailingOption("OUTPUT_FILE", HXT_STRING, NULL, &output)); + + HXT_PARSE_COMMAND_LINE(argc, argv, + "hxtMesh3d", + "Compute a mesh from the surface mesh in INPUT_FILE", + "--\nContact: celestin.marot@uclouvain.be"); + + if(options.verbosity) + { + const char* T = "true"; + const char* F = "false"; + printf("\ninput: %s\noutput: %s\n" + "Number of threads: %d\nDelaunay threads: %d\nOptim. threads: %d\n" + "reproducible: %s\nverbosity level: %d\nshow statistics: %s\n" + "refine: %s\noptimize : %s\nmin aspect ratio: %.3f\n\n", + input?input:"-", output?output:"-", options.defaultThreads<=0?omp_get_max_threads():options.defaultThreads, + options.delaunayThreads, options.improveThreads, + options.reproducible?T:F, (int) options.verbosity, options.stat?T:F, options.refine?T:F, options.optimize?T:F, options.qualityMin); + } + + + /******************* ^ all argument were processed *********************/ + HXTMesh *mesh; + HXT_CHECK( hxtMeshCreate(&mesh) ); + + HXT_INFO_COND(options.verbosity>0, "Reading \"%s\"\n", input); + HXT_CHECK( hxtMeshReadGmsh(mesh, input) ); + + HXT_CHECK( hxtTetMesh(mesh, &options) ); + + if(output){ + HXT_INFO_COND(options.verbosity>0, "Writing result to \"%s\"", output); + HXT_CHECK(hxtMeshWriteGmsh(mesh, output)); + } + + if(geoFile) { + // generate a .geo file + HXT_INFO_COND(options.verbosity>0, "Writing .geo file to \"%s\"", geoFile); + FILE* fp = fopen(geoFile, "w"); + fprintf(fp, "Merge \"%s\"; // loads the 2d mesh of the volume\n", input); + + uint16_t surf = 0; + for(uint16_t i=0; i<mesh->brep.numVolumes; i++) { + fprintf(fp, "Surface Loop(%u) = {%u", i+1, mesh->brep.surfacesPerVolume[surf++]); + for(uint16_t j=1; j<mesh->brep.numSurfacesPerVolume[i]; j++) { + fprintf(fp, ",%u", mesh->brep.surfacesPerVolume[surf++]); + } + fprintf(fp, "};\nVolume(%u) = {%u};\n", i+1, i+1); + } + fclose(fp); + } + + HXT_CHECK( hxtMeshDelete(&mesh) ); + return HXT_STATUS_OK; +} diff --git a/contrib/hxt/tetMesh/exe/tetOpti_CLI.c b/contrib/hxt/tetMesh/exe/tetOpti_CLI.c new file mode 100644 index 0000000000000000000000000000000000000000..7772044f9962b267ee75e528963654dbc171de3b --- /dev/null +++ b/contrib/hxt/tetMesh/exe/tetOpti_CLI.c @@ -0,0 +1,103 @@ +// Hxt - Copyright (C) +// 2016 - 2020 UCLouvain +// +// See the LICENSE.txt file for license information. +// +// Contributor(s): +// Célestin Marot + +#include "hxt_tetOpti.h" +#include "hxt_tetRepair.h" +#include "hxt_tetFlag.h" +#include "hxt_opt.h" +#include "hxt_tools.h" +#include "hxt_omp.h" + +int main(int argc, char** argv) { + + const char* input = NULL; + const char* output = NULL; + + int maxThreads = 0; + + HXTOptimizeOptions options = {.qualityMin=0.35, .reproducible=1, .verbosity=2}; + + HXT_CHECK( hxtAddOption('t', "omp_num_threads", + "Number of threads used for parallel work.\n" + "If NUM<=0, use OMP_NUM_THREADS environment variable", HXT_INT, NULL, &maxThreads)); + HXT_CHECK( hxtAddOption('o', "opti_threads", + "Overrides the maximum number of threads for mesh improvement\n" + " * NUM>0: use NUM threads\n" + " * NUM=0: use the default nbr. of threads (see `-t` option)\n" + " * NUM<0: use OMP_NUM_PROCS", HXT_INT, NULL, &options.numThreads)); + HXT_CHECK( hxtAddOption('v', "verbosity", + "Verbosity level of output messages\n" + " * NUM=0: print no information\n" + " * NUM=1: print some information\n" + " * NUM=2: print all information", HXT_INT, &HXT_0_2_RANGE, &options.verbosity)); + HXT_CHECK( hxtAddOption('a', "aspect-ratio-min", "The threshold on the aspect-ratio used during the optimization", HXT_DOUBLE, &HXT_0_1_RANGE, &options.qualityMin)); + + HXT_CHECK( hxtAddTrailingOption("INPUT_FILE", HXT_EXISTING_FILENAME, NULL, &input)); + HXT_CHECK( hxtAddTrailingOption("OUTPUT_FILE", HXT_STRING, NULL, &output)); + + HXT_PARSE_COMMAND_LINE(argc, argv, + "hxtTetOpti", + "Improve an existing tet mesh", + "--\nContact: celestin.marot@uclouvain.be"); + + if(maxThreads>0) { + omp_set_num_threads(maxThreads); + } + + /******************* ^ all argument were processed *********************/ + HXTMesh *mesh; + HXT_CHECK( hxtMeshCreate(&mesh) ); + + HXT_INFO_COND(options.verbosity>0, "Reading \"%s\"\n", input); + HXT_CHECK( hxtMeshReadGmsh(mesh, input) ); + HXT_INFO("%u points, %" HXTu64 " tets", mesh->vertices.num, mesh->tetrahedra.num); + + if(mesh->tetrahedra.num==0) + return HXT_ERROR_MSG(HXT_STATUS_ERROR, "No tetrahedron to optimize"); + + HXT_INFO("Computing adjacencies"); + HXT_CHECK( hxtTetAdjacencies(mesh) ); + +#ifdef DEBUG + HXT_CHECK( hxtTetVerify(mesh) ); +#endif + + HXT_INFO("Creating mesh->tetrahedra.flag"); + HXT_CHECK( hxtAlignedMalloc(&mesh->tetrahedra.flag, sizeof(uint16_t) * mesh->tetrahedra.size) ); + + HXT_INFO("Initializing flags and setting constraint"); + #pragma omp parallel for + for(uint64_t i=0; i<mesh->tetrahedra.num; i++) { + mesh->tetrahedra.flag[i] = 0; + for(int j=0; j<4; j++) { + if(mesh->tetrahedra.neigh[4*i+j]==HXT_NO_ADJACENT) + setFacetConstraint(mesh, i, j); + } + } + +#ifdef DEBUG + HXT_CHECK( hxtTetVerify(mesh) ); +#endif + + + HXT_INFO("Improving the quality of bad tet."); + HXT_CHECK( hxtOptimizeTetrahedra(mesh, &options) ); + +#ifdef DEBUG + HXT_CHECK( hxtTetVerify(mesh) ); +#endif + + + if(output){ + HXT_INFO_COND(options.verbosity>0, "Writing result to \"%s\"", output); + HXT_CHECK(hxtMeshWriteGmsh(mesh, output)); + } + + HXT_CHECK( hxtMeshDelete(&mesh) ); + return HXT_STATUS_OK; +} diff --git a/contrib/hxt/tetMesh/src/hxt_tetDelaunay.h b/contrib/hxt/tetMesh/include/hxt_tetDelaunay.h similarity index 97% rename from contrib/hxt/tetMesh/src/hxt_tetDelaunay.h rename to contrib/hxt/tetMesh/include/hxt_tetDelaunay.h index 885cc79d0e433de9fa62adc2e268b8fb8090d5a6..70093ed7a6a9d0d7e6d7b396ef88d9c57536d5c2 100644 --- a/contrib/hxt/tetMesh/src/hxt_tetDelaunay.h +++ b/contrib/hxt/tetMesh/include/hxt_tetDelaunay.h @@ -13,7 +13,9 @@ extern "C" { #endif -#include "hxt_tetPartition.h" +#include "hxt_mesh.h" +#include "hxt_vertices.h" +#include "hxt_bbox.h" /** * \file hxt_tetDelaunay.h Delaunay tetrahedrization @@ -136,9 +138,6 @@ HXTStatus hxtDelaunay(HXTMesh* mesh, HXTDelaunayOptions* options); // HXTStatus hxtDelaunayFreeBuffer(void** buffer); -HXTStatus walking2Cavity(HXTMesh* mesh, HXTPartition* partition, uint64_t* __restrict__ curTet, const uint32_t vta); - - #ifdef __cplusplus } #endif diff --git a/contrib/hxt/tetMesh/src/hxt_tetFlag.h b/contrib/hxt/tetMesh/include/hxt_tetFlag.h similarity index 100% rename from contrib/hxt/tetMesh/src/hxt_tetFlag.h rename to contrib/hxt/tetMesh/include/hxt_tetFlag.h diff --git a/contrib/hxt/tetMesh/src/hxt_tetOpti.h b/contrib/hxt/tetMesh/include/hxt_tetOpti.h similarity index 100% rename from contrib/hxt/tetMesh/src/hxt_tetOpti.h rename to contrib/hxt/tetMesh/include/hxt_tetOpti.h diff --git a/contrib/hxt/tetMesh/src/hxt_tetRepair.h b/contrib/hxt/tetMesh/include/hxt_tetRepair.h similarity index 100% rename from contrib/hxt/tetMesh/src/hxt_tetRepair.h rename to contrib/hxt/tetMesh/include/hxt_tetRepair.h diff --git a/contrib/hxt/tetMesh/src/hxt_vertices.h b/contrib/hxt/tetMesh/include/hxt_vertices.h similarity index 100% rename from contrib/hxt/tetMesh/src/hxt_vertices.h rename to contrib/hxt/tetMesh/include/hxt_vertices.h diff --git a/contrib/hxt/tetMesh/src/HXTSPR.c b/contrib/hxt/tetMesh/src/HXTSPR.c index 25073f1f34b4c771a4dee2b4b53e08b090224b7c..1e8966fd3387cbac5c057f5ee9e419bb45f67315 100644 --- a/contrib/hxt/tetMesh/src/HXTSPR.c +++ b/contrib/hxt/tetMesh/src/HXTSPR.c @@ -7,7 +7,7 @@ // Célestin Marot #include "HXTSPR.h" -#include <math.h> +#include "hxt_tetOptiUtils.h" #include "hxt_tetFlag.h" #include "predicates.h" diff --git a/contrib/hxt/tetMesh/src/hxt_tetDelaunay.c b/contrib/hxt/tetMesh/src/hxt_tetDelaunay.c index 263239aca99e2466a620684b0f7a800bcca5e1e2..8816d9e94023370cf0bfb9d94f0eb28d7a73b433 100644 --- a/contrib/hxt/tetMesh/src/hxt_tetDelaunay.c +++ b/contrib/hxt/tetMesh/src/hxt_tetDelaunay.c @@ -7,6 +7,7 @@ // Célestin Marot #include "hxt_tetDelaunay.h" +#include "hxt_tetPartition.h" #include "predicates.h" #include "hxt_tetSync.h" #include "hxt_tetFlag.h" @@ -505,7 +506,7 @@ static int tetInsphere(HXTMesh* mesh, const uint64_t curTet, const uint32_t vta) /*********************************** * walk to cavity ***********************************/ -HXTStatus walking2Cavity(HXTMesh* mesh, HXTPartition* partition, uint64_t* __restrict__ curTet, const uint32_t vta) +static inline HXTStatus walking2Cavity(HXTMesh* mesh, HXTPartition* partition, uint64_t* __restrict__ curTet, const uint32_t vta) { uint64_t nextTet = *curTet; HXTVertex* vertices = (HXTVertex*) mesh->vertices.coord; @@ -1275,6 +1276,7 @@ static HXTStatus insertion(HXT2Sync* shared2sync, if(local->ball.num > local->deleted.num){ HXT_CHECK( createNewDeleted(shared2sync, &local->deleted, local->ball.num) ); + HXT_ASSERT(local->deleted.num >= local->ball.num); } HXT_CHECK( fillingACavity(mesh, local, verticesID, curTet, vta, color) ); diff --git a/contrib/hxt/tetMesh/src/hxt_tetNodalSize.c b/contrib/hxt/tetMesh/src/hxt_tetNodalSize.c index e0f17e1ac32747dc295425ee74c6d7fabff0e703..acab5f1b1db1c48dfcf43e376f899a471cc3babb 100644 --- a/contrib/hxt/tetMesh/src/hxt_tetNodalSize.c +++ b/contrib/hxt/tetMesh/src/hxt_tetNodalSize.c @@ -7,7 +7,6 @@ // Célestin Marot #include "hxt_vertices.h" -#include <math.h> HXTStatus hxtCreateNodalSize(HXTMesh* mesh, double** nodalSizes_ptr) { diff --git a/contrib/hxt/tetMesh/src/hxt_tetNodalSize.h b/contrib/hxt/tetMesh/src/hxt_tetNodalSize.h index 46a3d64ab2a95d31df49d0d9fe3a7492794dc424..b0cc072c2d4e1179d2715bc0811c9965d922ce4b 100644 --- a/contrib/hxt/tetMesh/src/hxt_tetNodalSize.h +++ b/contrib/hxt/tetMesh/src/hxt_tetNodalSize.h @@ -12,7 +12,7 @@ #include "hxt_mesh.h" HXTStatus hxtCreateNodalSize(HXTMesh* mesh, double** nodalSizes_ptr); -HXTStatus hxtDestroyNodalsize(double** nodalSize); +HXTStatus hxtDestroyNodalSize(double** nodalSize); /// Compute sizes at vertices of the mesh from meshSizeFun HXTStatus hxtComputeNodalSizeFromFunction(HXTMesh* mesh, double* nodalSize, @@ -21,8 +21,8 @@ HXTStatus hxtComputeNodalSizeFromFunction(HXTMesh* mesh, double* nodalSize, void* meshSizeData); /// Compute sizes at vertices of the mesh from existing edges -HXTStatus hxtComputeNodalsizeFromTrianglesAndLines(HXTMesh* mesh, double* nodalSize); -HXTStatus hxtComputeNodalsizeFromMesh(HXTMesh* mesh, double* nodalSize); +HXTStatus hxtComputeNodalSizeFromTrianglesAndLines(HXTMesh* mesh, double* nodalSize); +HXTStatus hxtComputeNodalSizeFromMesh(HXTMesh* mesh, double* nodalSize); diff --git a/contrib/hxt/tetMesh/src/hxt_tetOptiUtils.h b/contrib/hxt/tetMesh/src/hxt_tetOptiUtils.h index fedf57f2e9c411d2b51124e5abe24e0b4ded0f7b..c5baec79724a05568d7a68ca462841cb07263300 100644 --- a/contrib/hxt/tetMesh/src/hxt_tetOptiUtils.h +++ b/contrib/hxt/tetMesh/src/hxt_tetOptiUtils.h @@ -36,7 +36,7 @@ typedef struct { } Statistic; -typedef struct +typedef struct { /*** located here ***/ // list of deleted tet. Added when the cavity is created, removed when the cavity is filled diff --git a/contrib/hxt/tetMesh/src/hxt_tetQuality.c b/contrib/hxt/tetMesh/src/hxt_tetQuality.c index 31b876c3f07e67f75c00ce48cfc018d1429765f5..0b8427d7f7db153ed0dcba80c93624ab5f9cbd48 100644 --- a/contrib/hxt/tetMesh/src/hxt_tetQuality.c +++ b/contrib/hxt/tetMesh/src/hxt_tetQuality.c @@ -6,7 +6,6 @@ // Contributor(s): // Célestin Marot -#include <math.h> #include "hxt_tools.h" //!\ this function does not return the aspect ratio 'r'. It returns 'r^2/24' diff --git a/contrib/hxt/tetMesh/src/hxt_tetRefine.c b/contrib/hxt/tetMesh/src/hxt_tetRefine.c index e6be20467a5e5dc2e2b11a6ac1d16e151a0313ae..6f2c1faa16f000f6f840d0b706ff70b657270659 100644 --- a/contrib/hxt/tetMesh/src/hxt_tetRefine.c +++ b/contrib/hxt/tetMesh/src/hxt_tetRefine.c @@ -6,7 +6,6 @@ // Contributor(s): // Célestin Marot -#include <math.h> #include "hxt_tetDelaunay.h" #include "predicates.h" #include "hxt_tetFlag.h" diff --git a/contrib/hxt/tetMesh/src/hxt_tetSync.c b/contrib/hxt/tetMesh/src/hxt_tetSync.c index 2458194f712fc7fd57486a667ba6a0aa9065d671..91551a7f693a1b58b17d5b3e92beaa1d58c95ee0 100644 --- a/contrib/hxt/tetMesh/src/hxt_tetSync.c +++ b/contrib/hxt/tetMesh/src/hxt_tetSync.c @@ -101,6 +101,6 @@ HXTStatus createNewDeleted(HXT2Sync* shared, } deleted->createdNew = 1; - deleted->num = DELETED_BUFFER_SIZE; + deleted->num += needed; return HXT_STATUS_OK; } \ No newline at end of file diff --git a/contrib/hxt/tetMesh/src/hxt_vertices.c b/contrib/hxt/tetMesh/src/hxt_vertices.c index 09c34bc45a6ef93ca91f18fbefd2f538d9d01c73..76b93ac40f85cb418042bd9afa441a4badbc462d 100644 --- a/contrib/hxt/tetMesh/src/hxt_vertices.c +++ b/contrib/hxt/tetMesh/src/hxt_vertices.c @@ -7,9 +7,10 @@ // Célestin Marot #include "hxt_omp.h" -#include <string.h> #include "hxt_vertices.h" #include "hxt_sort.h" +#include <string.h> + #if defined( __BMI2__ ) || defined( __AVX2__ ) || (defined(__AVX512F__) && defined(__AVX512VL__)) #include <immintrin.h>