Skip to content
Snippets Groups Projects
Commit 1719f95b authored by Célestin Marot's avatar Célestin Marot
Browse files

update hxt

 - Some cosmetic changes to the CMakeLists
 - add executables code in tetMesh. This allows you to run *_CLI independently
 - the core has got more features to simplify includes
parent d60a15a0
Branches
Tags
No related merge requests found
Showing
with 1651 additions and 81 deletions
......@@ -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)
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()
......@@ -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
}
......
......
// 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
......@@ -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
......
......
......@@ -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
This diff is collapsed.
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}/include/predicates.h")
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 !
......
......
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()
#################################################################################
# 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,8 +34,7 @@ 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})
......@@ -32,7 +44,7 @@ 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)
......
......
......@@ -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);
......
......
#include "hxt_curvature.h"
#include "hxt_tools.h"
#include <math.h>
#include <stdio.h>
// #include <time.h> // for commented timings
......
......
#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;
......
......
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include "hxt_tools.h"
#include "hxt_linear_system_lu.h"
......
......
......@@ -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
......
......
#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;
......
......
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}/include/hxt_boundary_recovery.h")
if(HXT_TETBR_OBJECT_ONLY)
add_library(hxt_tetBR OBJECT ${HXT_TETBR_SRC})
......@@ -24,5 +36,11 @@ target_include_directories(hxt_tetBR
PRIVATE src)
target_link_libraries(hxt_tetBR
PUBLIC hxt_core
PRIVATE hxt_predicates)
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
......@@ -6,7 +6,6 @@ extern "C" {
}
#include <assert.h>
#include <math.h>
#include <set>
#include <vector>
#include <time.h>
......
......
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
// 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
// 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;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment