stardis-solver

Solve coupled heat transfers
git clone git://git.meso-star.fr/stardis-solver.git
Log | Files | Refs | README | LICENSE

commit 863b0ef8f4fae8935a5f991f32f435cf3659c9d7
parent 1a2b6ef0f7459e2541e56be74ef2a7749fd1d52d
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Thu, 23 Jul 2020 11:23:01 +0200

Merge branch 'feature_closest_point' into develop

Diffstat:
Mcmake/CMakeLists.txt | 4++--
Msrc/sdis.h | 17++++++++++++++++-
Msrc/sdis_scene.c | 19++++++++++++++++++-
Msrc/sdis_scene_Xd.h | 59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/test_sdis_scene.c | 77++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------
Msrc/test_sdis_utils.h | 12++++++------
6 files changed, 169 insertions(+), 19 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -29,8 +29,8 @@ CMAKE_DEPENDENT_OPTION(ALL_TESTS # Check dependencies ############################################################################### find_package(RCMake 0.4 REQUIRED) -find_package(Star2D 0.3.1 REQUIRED) -find_package(Star3D 0.6.2 REQUIRED) +find_package(Star2D 0.4 REQUIRED) +find_package(Star3D 0.7 REQUIRED) find_package(StarSP 0.8 REQUIRED) find_package(StarEnc2D 0.5 REQUIRED) find_package(StarEnc3D 0.5 REQUIRED) diff --git a/src/sdis.h b/src/sdis.h @@ -43,6 +43,7 @@ #define SDIS_VOLUMIC_POWER_NONE 0 /* <=> No volumic power */ #define SDIS_FLUX_NONE DBL_MAX /* <=> No flux */ +#define SDIS_PRIMITIVE_NONE SIZE_MAX /* Invalid primitive */ /* Forward declaration of external opaque data types */ struct logger; @@ -809,6 +810,20 @@ sdis_scene_get_aabb double lower[3], double upper[3]); +/* Search the point onto the scene geometry that is the closest of `pos'. The + * `radius' parameter controls the maximum search distance around `pos'. The + * returned closest point is expressed locally to the geometric primitive onto + * which it lies. If not found, the returned primitive is SDIS_PRIMITIVE_NONE. + * Note that even though only one point is returned, several position can have + * the same minimal distance to the queried position. */ +SDIS_API res_T +sdis_scene_find_closest_point + (const struct sdis_scene* scn, + const double pos[3], /* Query position */ + const double radius, /* Maximum search distance around pos */ + size_t* iprim, /* Primitive index onto which the closest point lies */ + double uv[2]); /* Parametric cordinate onto the primitive */ + /* Define the world space position of a point onto the primitive `iprim' whose * parametric coordinate is uv. */ SDIS_API res_T @@ -818,7 +833,7 @@ sdis_scene_get_boundary_position const double uv[2], /* Parametric coordinate onto the primitive */ double pos[3]); /* World space position */ -/* Project a world space position onto a primitive wrt its normal and compute +/* roject a world space position onto a primitive wrt its normal and compute * the parametric coordinates of the projected point onto the primitive. This * function may help to define the probe position onto a boundary as expected * by the sdis_solve_probe_boundary function. diff --git a/src/sdis_scene.c b/src/sdis_scene.c @@ -24,6 +24,7 @@ #include "sdis.h" #include "sdis_scene_c.h" +#include <float.h> #include <limits.h> /******************************************************************************* @@ -182,6 +183,22 @@ sdis_scene_get_aabb } res_T +sdis_scene_find_closest_point + (const struct sdis_scene* scn, + const double pos[3], + const double radius, + size_t* iprim, + double uv[2]) +{ + if(!scn) return RES_BAD_ARG; + if(scene_is_2d(scn)) { + return scene_find_closest_point_2d(scn, pos, radius, iprim, uv); + } else { + return scene_find_closest_point_3d(scn, pos, radius, iprim, uv); + } +} + +res_T sdis_scene_get_boundary_position (const struct sdis_scene* scn, const size_t iprim, @@ -333,7 +350,7 @@ sdis_scene_get_medium_spread } } *out_spread = spread; - + exit: return res; error: diff --git a/src/sdis_scene_Xd.h b/src/sdis_scene_Xd.h @@ -24,6 +24,7 @@ #include "sdis_scene_c.h" #include <star/ssp.h> +#include <rsys/cstr.h> #include <rsys/float22.h> #include <rsys/float33.h> #include <rsys/rsys.h> @@ -957,6 +958,64 @@ error: goto exit; } +static res_T +XD(scene_find_closest_point) + (const struct sdis_scene* scn, + const double pos[3], + const double radius, + size_t* iprim, + double uv[2]) +{ + struct sXd(hit) hit; + float query_pos[DIM]; + float query_radius; + res_T res = RES_OK; + + if(!scn || !pos || radius <= 0 || !iprim || !uv + || scene_is_2d(scn) != (DIM == 2)) { + res = RES_BAD_ARG; + goto error; + } + + /* Avoid a null query radius due to casting in single-precision */ + query_radius = MMAX((float)radius, FLT_MIN); + + fX_set_dX(query_pos, pos); + res = sXd(scene_view_closest_point) + (scn->sXd(view), query_pos, query_radius, NULL, &hit); + if(res != RES_OK) { +#if DIM == 2 + log_err(scn->dev, + "%s: error querying the closest position at {%g, %g} " + "for a radius of %g -- %s.\n", + FUNC_NAME, SPLIT2(query_pos), query_radius, res_to_cstr(res)); +#else + log_err(scn->dev, + "%s: error querying the closest position at {%g, %g, %g} " + "for a radius of %g -- %s.\n", + FUNC_NAME, SPLIT3(query_pos), query_radius, res_to_cstr(res)); +#endif + goto error; + } + + if(SXD_HIT_NONE(&hit)) { + *iprim = SDIS_PRIMITIVE_NONE; + } else { + *iprim = hit.prim.scene_prim_id; +#if DIM == 2 + uv[0] = hit.u; +#else + uv[0] = hit.uv[0]; + uv[1] = hit.uv[1]; +#endif + } + +exit: + return res; +error: + goto exit; +} + /******************************************************************************* * Local functions ******************************************************************************/ diff --git a/src/test_sdis_scene.c b/src/test_sdis_scene.c @@ -89,17 +89,19 @@ get_interface(const size_t itri, struct sdis_interface** bound, void* context) static void test_scene_3d(struct sdis_device* dev, struct sdis_interface* interf) { - struct sdis_scene* scn = NULL; + size_t duplicated_indices[] = { 0, 1, 2, 0, 2, 1 }; + size_t degenerated_indices[] = { 0, 1, 1 }; + double duplicated_vertices[] = { 0, 0, 0, 1, 1, 1, 0, 0, 0 }; double lower[3], upper[3]; - double uv0[2], uv1[2], pos[3], pos1[3]; + double uv0[2], uv1[2], uv2[2], pos[3], pos1[3]; struct context ctx; struct senc2d_scene* scn2d; struct senc3d_scene* scn3d; + struct sdis_scene* scn = NULL; size_t ntris, npos; + size_t iprim; size_t i; - size_t duplicated_indices[] = { 0, 1, 2, 0, 2, 1 }; - size_t degenerated_indices[] = { 0, 1, 1 }; - double duplicated_vertices[] = { 0, 0, 0, 1, 1, 1, 0, 0, 0 }; + double dst = 0; size_t dup_vrtx_indices[] = { 0, 1, 2 }; enum sdis_scene_dimension dim; @@ -172,7 +174,32 @@ test_scene_3d(struct sdis_device* dev, struct sdis_interface* interf) BA(sdis_scene_boundary_project_position(scn, 6, pos, NULL)); OK(sdis_scene_boundary_project_position(scn, 6, pos, uv1)); + BA(sdis_scene_find_closest_point(NULL, pos, INF, &iprim, uv2)); + BA(sdis_scene_find_closest_point(scn, NULL, INF, &iprim, uv2)); + BA(sdis_scene_find_closest_point(scn, pos, 0, &iprim, uv2)); + BA(sdis_scene_find_closest_point(scn, pos, INF, NULL, uv2)); + BA(sdis_scene_find_closest_point(scn, pos, INF, &iprim, NULL)); + OK(sdis_scene_find_closest_point(scn, pos, INF, &iprim, uv2)); + + CHK(iprim == 6); CHK(d2_eq_eps(uv0, uv1, 1.e-6)); + CHK(d2_eq_eps(uv1, uv2, 1.e-6)); + + pos[0] = 0.5; + pos[1] = 0.1; + pos[2] = 0.25; + OK(sdis_scene_find_closest_point(scn, pos, INF, &iprim, uv2)); + CHK(iprim == 10); + + OK(sdis_scene_boundary_project_position(scn, 10, pos, uv0)); + CHK(d2_eq_eps(uv0, uv2, 1.e-6)); + + OK(sdis_scene_get_boundary_position(scn, iprim, uv2, pos1)); + dst = d3_len(d3_sub(pos1, pos, pos1)); + CHK(eq_eps(dst, 0.1, 1.e-6)); + + OK(sdis_scene_find_closest_point(scn, pos, 0.09, &iprim, uv2)); + CHK(iprim == SDIS_PRIMITIVE_NONE); FOR_EACH(i, 0, 64) { uv0[0] = rand_canonic(); @@ -180,7 +207,10 @@ test_scene_3d(struct sdis_device* dev, struct sdis_interface* interf) OK(sdis_scene_get_boundary_position(scn, 4, uv0, pos)); OK(sdis_scene_boundary_project_position(scn, 4, pos, uv1)); + OK(sdis_scene_find_closest_point(scn, pos, INF, &iprim, uv2)); CHK(d2_eq_eps(uv0, uv1, 1.e-6)); + CHK(d2_eq_eps(uv1, uv2, 1.e-6)); + CHK(iprim == 4); } pos[0] = 10; @@ -208,17 +238,19 @@ test_scene_3d(struct sdis_device* dev, struct sdis_interface* interf) static void test_scene_2d(struct sdis_device* dev, struct sdis_interface* interf) { + size_t duplicated_indices[] = { 0, 1, 1, 0 }; + size_t degenerated_indices[] = { 0, 0 }; + double duplicated_vertices[] = { 0, 0, 0, 0 }; struct sdis_scene* scn = NULL; double lower[2], upper[2]; - double u0, u1, pos[2]; + double u0, u1, u2, pos[2], pos1[2]; + double dst; struct context ctx; struct senc2d_scene* scn2d; struct senc3d_scene* scn3d; size_t nsegs, npos; size_t i; - size_t duplicated_indices[] = { 0, 1, 1, 0 }; - size_t degenerated_indices[] = { 0, 0 }; - double duplicated_vertices[] = { 0, 0, 0, 0 }; + size_t iprim; size_t dup_vrtx_indices[] = { 0, 1 }; enum sdis_scene_dimension dim; @@ -288,14 +320,41 @@ test_scene_2d(struct sdis_device* dev, struct sdis_interface* interf) BA(sdis_scene_boundary_project_position(scn, 1, pos, NULL)); OK(sdis_scene_boundary_project_position(scn, 1, pos, &u1)); + BA(sdis_scene_find_closest_point(NULL, pos, INF, &iprim, &u2)); + BA(sdis_scene_find_closest_point(scn, NULL, INF, &iprim, &u2)); + BA(sdis_scene_find_closest_point(scn, pos, 0, &iprim, &u2)); + BA(sdis_scene_find_closest_point(scn, pos, INF, NULL, &u2)); + BA(sdis_scene_find_closest_point(scn, pos, INF, &iprim, NULL)); + OK(sdis_scene_find_closest_point(scn, pos, INF, &iprim, &u2)); + CHK(eq_eps(u0, u1, 1.e-6)); + CHK(eq_eps(u1, u2, 1.e-6)); + CHK(iprim == 1); + + pos[0] = 0.5; + pos[1] = 0.1; + OK(sdis_scene_find_closest_point(scn, pos, INF, &iprim, &u2)); + CHK(iprim == 0); + + OK(sdis_scene_boundary_project_position(scn, 0, pos, &u0)); + CHK(eq_eps(u0, u2, 1.e-6)); + + OK(sdis_scene_get_boundary_position(scn, iprim, &u2, pos1)); + dst = d2_len(d2_sub(pos1, pos, pos1)); + CHK(eq_eps(dst, 0.1, 1.e-6)); + + OK(sdis_scene_find_closest_point(scn, pos, 0.09, &iprim, &u2)); + CHK(iprim == SDIS_PRIMITIVE_NONE); FOR_EACH(i, 0, 64) { u0 = rand_canonic(); OK(sdis_scene_get_boundary_position(scn, 2, &u0, pos)); OK(sdis_scene_boundary_project_position(scn, 2, pos, &u1)); + OK(sdis_scene_find_closest_point(scn, pos, INF, &iprim, &u2)); CHK(eq_eps(u0, u1, 1.e-6)); + CHK(eq_eps(u1, u2, 1.e-6)); + CHK(iprim == 2); } d2(pos, 5, 0.5); diff --git a/src/test_sdis_utils.h b/src/test_sdis_utils.h @@ -52,12 +52,12 @@ static const size_t box_nvertices = sizeof(box_vertices) / sizeof(double[3]); * Front, right Back, left and Z * and Top faces bottom faces */ static const size_t box_indices[12/*#triangles*/*3/*#indices per triangle*/] = { - 0, 2, 1, 1, 2, 3, /* Front face */ - 0, 4, 2, 2, 4, 6, /* Left face*/ - 4, 5, 6, 6, 5, 7, /* Back face */ - 3, 7, 1, 1, 7, 5, /* Right face */ - 2, 6, 3, 3, 6, 7, /* Top face */ - 0, 1, 4, 4, 1, 5 /* Bottom face */ + 0, 2, 1, 1, 2, 3, /* -Z */ + 0, 4, 2, 2, 4, 6, /* -X */ + 4, 5, 6, 6, 5, 7, /* +Z */ + 3, 7, 5, 5, 1, 3, /* +X */ + 2, 6, 7, 7, 3, 2, /* +Y */ + 0, 1, 5, 5, 4, 0 /* -Y */ }; static const size_t box_ntriangles = sizeof(box_indices) / sizeof(size_t[3]);