stardis-solver

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

commit 74edf309a4297dcdec319c131908e7eba2039fc6
parent d99d9c0bce611814c963b8ec0379bca52b33d61a
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Wed,  8 Jul 2020 10:12:52 +0200

Merge branch 'release_0.9'

Diffstat:
MREADME.md | 19+++++++++++++++----
Mcmake/CMakeLists.txt | 41++++++++++++++++++++++++-----------------
Msrc/sdis.h | 426++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------
Msrc/sdis_Xd_begin.h | 4++--
Msrc/sdis_Xd_end.h | 4++--
Msrc/sdis_camera.c | 2+-
Msrc/sdis_camera.h | 2+-
Msrc/sdis_data.c | 3++-
Msrc/sdis_device.c | 120++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------------
Msrc/sdis_device_c.h | 38+++++++++++++-------------------------
Msrc/sdis_estimator.c | 31++++++++++++++++++++++++++++++-
Msrc/sdis_estimator_buffer.c | 35+++++++++++++++++++++++++++++++++--
Msrc/sdis_estimator_buffer_c.h | 7++++++-
Msrc/sdis_estimator_c.h | 13++++++++++---
Msrc/sdis_green.c | 12+++++-------
Msrc/sdis_green.h | 2+-
Msrc/sdis_heat_path.c | 2+-
Msrc/sdis_heat_path.h | 2+-
Msrc/sdis_heat_path_boundary_Xd.h | 20++++++++++----------
Msrc/sdis_heat_path_conductive_Xd.h | 14+++++++-------
Msrc/sdis_heat_path_convective_Xd.h | 17++++++++++-------
Msrc/sdis_heat_path_radiative_Xd.h | 5+++--
Msrc/sdis_interface.c | 3++-
Msrc/sdis_interface_c.h | 2+-
Asrc/sdis_log.c | 119+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/sdis_log.h | 72++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/sdis_medium.c | 3++-
Msrc/sdis_medium_c.h | 2+-
Msrc/sdis_misc.h | 2+-
Msrc/sdis_realisation.c | 2+-
Msrc/sdis_realisation.h | 2+-
Msrc/sdis_realisation_Xd.h | 15++++++++-------
Msrc/sdis_scene.c | 45+++++++++++++++++----------------------------
Msrc/sdis_scene_Xd.h | 235+++++++++++++++++++++++++++++--------------------------------------------------
Msrc/sdis_scene_c.h | 6+++---
Msrc/sdis_solve.c | 236++++++++++++++++++++++++++++++-------------------------------------------------
Msrc/sdis_solve_boundary_Xd.h | 229+++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------
Msrc/sdis_solve_medium_Xd.h | 89+++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------
Msrc/sdis_solve_probe_Xd.h | 88+++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------
Msrc/sdis_solve_probe_boundary_Xd.h | 193+++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------
Dsrc/sdis_solve_radiative.c | 20--------------------
Msrc/test_sdis_accum_buffer.c | 2+-
Msrc/test_sdis_camera.c | 2+-
Msrc/test_sdis_conducto_radiative.c | 31++++++++++++++++++-------------
Msrc/test_sdis_conducto_radiative_2d.c | 29+++++++++++++++++------------
Msrc/test_sdis_convection.c | 37++++++++++++++++++++++---------------
Msrc/test_sdis_convection_non_uniform.c | 38+++++++++++++++++++++++---------------
Msrc/test_sdis_data.c | 2+-
Msrc/test_sdis_device.c | 2+-
Msrc/test_sdis_flux.c | 20++++++++++++++------
Msrc/test_sdis_interface.c | 2+-
Msrc/test_sdis_medium.c | 2+-
Msrc/test_sdis_scene.c | 90++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------
Msrc/test_sdis_solid_random_walk_robustness.c | 36++++++++++++++++++++++--------------
Msrc/test_sdis_solve_boundary.c | 251++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------------
Msrc/test_sdis_solve_boundary_flux.c | 140++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------
Msrc/test_sdis_solve_camera.c | 94++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
Msrc/test_sdis_solve_medium.c | 92++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------
Msrc/test_sdis_solve_medium_2d.c | 37+++++++++++++++++++++----------------
Msrc/test_sdis_solve_probe.c | 98+++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------
Msrc/test_sdis_solve_probe2.c | 26++++++++++++++------------
Msrc/test_sdis_solve_probe2_2d.c | 34++++++++++++++++++----------------
Msrc/test_sdis_solve_probe3.c | 26++++++++++++++------------
Msrc/test_sdis_solve_probe3_2d.c | 23++++++++++++-----------
Msrc/test_sdis_solve_probe_2d.c | 24+++++++++++++-----------
Msrc/test_sdis_utils.c | 6+++---
Msrc/test_sdis_utils.h | 2+-
Msrc/test_sdis_volumic_power.c | 18+++++++++++++-----
Msrc/test_sdis_volumic_power2.c | 16++++++++++------
Msrc/test_sdis_volumic_power2_2d.c | 14+++++++++-----
Msrc/test_sdis_volumic_power3_2d.c | 10++++++++--
Msrc/test_sdis_volumic_power4.c | 15+++++++++++----
72 files changed, 2103 insertions(+), 1298 deletions(-)

diff --git a/README.md b/README.md @@ -11,13 +11,13 @@ It also depends on the [RSys](https://gitlab.com/vaplv/rsys/), [Star-2D](https://gitlab.com/meso-star/star-2d/), [Star-3D](https://gitlab.com/meso-star/star-3d/), -[Star-Enclosures](https://gitlab.com/meso-star/star-enclosures/), -[Star-Enclosures2D](https://gitlab.com/meso-star/star-enclosures-2d/) and +[Star-Enclosures-3D](https://gitlab.com/meso-star/star-enclosures-3d/), +[Star-Enclosures-2D](https://gitlab.com/meso-star/star-enclosures-2d/) and [Star-SP](https://gitlab.com/meso-star/star-sp/) libraries as well as on the [OpenMP](http://www.openmp.org) 2.0 specification to parallelize its computations. -First ensure that CMake and a compiler that implements the OpenMP 1.2 +First ensure that CMake and a C compiler that implements the OpenMP 2.0 specification are installed on your system. Then install the RCMake package as well as all the aforementioned prerequisites. Finally generate the project from the `cmake/CMakeLists.txt` file by appending to the `CMAKE_PREFIX_PATH` @@ -25,6 +25,17 @@ variable the install directories of its dependencies. ## Release notes +### Version 0.9.0 + +- Update the API of the solve functions: the parameters of the simulation are + now grouped into a unique data structure rather than separately submitted as + function arguments. Thank to this structure and its default value, updating + input parameters should now affect marginally the calling code. +- Improve the logger. Add a prefix to the printed text to indicate the type of + the message (info, error or warning). Add a progress message during + simulation. +- Bump the version of the Star-Enclosures <2D|3D> dependencies to 0.5 + ### Version 0.8.2 - Fix an issue when the `sdis_solve_boundary_flux` function was invoked on a @@ -213,7 +224,7 @@ First version and implementation of the Stardis solver API. ## License -Copyright (C) 2016-2019 |Meso|Star> (<contact@meso-star.com>). Stardis is free +Copyright (C) 2016-2020 |Meso|Star> (<contact@meso-star.com>). Stardis is free software released under the GPLv3+ license: GNU GPL version 3 or later. You are welcome to redistribute it under certain conditions; refer to the COPYING files for details. diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2016-2019 |Meso|Star> +# Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -25,15 +25,15 @@ option(NO_TEST "Do not build tests" OFF) CMAKE_DEPENDENT_OPTION(ALL_TESTS "Perform basic and advanced tests" OFF "NOT NO_TEST" OFF) -################################################################################ +############################################################################### # Check dependencies -################################################################################ +############################################################################### find_package(RCMake 0.4 REQUIRED) find_package(Star2D 0.3.1 REQUIRED) find_package(Star3D 0.6.2 REQUIRED) find_package(StarSP 0.8 REQUIRED) -find_package(StarEnc 0.4.2 REQUIRED) -find_package(StarEnc2D 0.4.2 REQUIRED) +find_package(StarEnc2D 0.5 REQUIRED) +find_package(StarEnc3D 0.5 REQUIRED) find_package(RSys 0.8.1 REQUIRED) find_package(OpenMP 2.0 REQUIRED) @@ -45,18 +45,19 @@ include_directories( ${Star2D_INCLUDE_DIR} ${Star3D_INCLUDE_DIR} ${StarSP_INCLUDE_DIR} - ${StarEnc_INCLUDE_DIR} ${StarEnc2D_INCLUDE_DIR} + ${StarEnc3D_INCLUDE_DIR} ${RSys_INCLUDE_DIR}) -rcmake_append_runtime_dirs(_runtime_dirs RSys Star3D StarSP StarEnc StarEnc2D) +rcmake_append_runtime_dirs(_runtime_dirs + RSys Star2D Star3D StarSP StarEnc2D StarEnc3D) -################################################################################ +############################################################################### # Configure and define targets -################################################################################ +############################################################################### set(VERSION_MAJOR 0) -set(VERSION_MINOR 8) -set(VERSION_PATCH 2) +set(VERSION_MINOR 9) +set(VERSION_PATCH 0) set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}) set(SDIS_FILES_SRC @@ -68,6 +69,7 @@ set(SDIS_FILES_SRC sdis_green.c sdis_heat_path.c sdis_interface.c + sdis_log.c sdis_medium.c sdis_realisation.c sdis_scene.c @@ -87,6 +89,7 @@ set(SDIS_FILES_INC sdis_heat_path_convective_Xd.h sdis_heat_path_radiative_Xd.h sdis_interface_c.h + sdis_log.h sdis_medium_c.h sdis_realisation.h sdis_realisation_Xd.h @@ -115,7 +118,8 @@ if(MSVC) ### disable verbose warnings: # warning C4127: conditional expression is constant set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4127") - # warning C4204: nonstandard extension used : non-constant aggregate initializer + # warning C4204: + # nonstandard extension used : non-constant aggregate initializer set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4204") # warning C4938: Floating point reduction variable may cause inconsistent # results under /fp:strict or #pragma fenv_access @@ -126,7 +130,8 @@ add_library(sdis SHARED ${SDIS_FILES_SRC} ${SDIS_FILES_INC} ${SDIS_FILES_INC_API}) -target_link_libraries(sdis RSys Star2D Star3D StarSP StarEnc StarEnc2D ${MATH_LIB}) +target_link_libraries(sdis + RSys Star2D Star3D StarSP StarEnc2D StarEnc3D ${MATH_LIB}) set_target_properties(sdis PROPERTIES DEFINE_SYMBOL SDIS_SHARED_BUILD @@ -141,9 +146,9 @@ endif() rcmake_setup_devel(sdis Stardis ${VERSION} sdis_version.h) -################################################################################ +############################################################################### # Add tests -################################################################################ +############################################################################### if(NOT NO_TEST) find_package(Star3DUT REQUIRED 0.2.0) @@ -208,12 +213,14 @@ if(NOT NO_TEST) target_link_libraries(test_sdis_solve_probe3 Star3DUT) target_link_libraries(test_sdis_solve_probe3_2d ${MATH_LIB}) target_link_libraries(test_sdis_solve_camera Star3DUT) + + rcmake_copy_runtime_libraries(test_sdis_solid_random_walk_robustness) endif() -################################################################################ +############################################################################### # Define output & install directories -################################################################################ +############################################################################### install(TARGETS sdis ARCHIVE DESTINATION bin LIBRARY DESTINATION lib diff --git a/src/sdis.h b/src/sdis.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -47,8 +47,9 @@ /* Forward declaration of external opaque data types */ struct logger; struct mem_allocator; -struct senc2d_descriptor; -struct senc_descriptor; +struct senc2d_scene; +struct senc3d_scene; +struct ssp_rng; /* Forward declaration of the Stardis opaque data types. These data types are * ref counted. Once created the caller implicitly owns the created data, i.e. @@ -69,49 +70,20 @@ struct sdis_scene; /* Forward declaration of non ref counted types */ struct sdis_heat_path; +/******************************************************************************* + * Miscellaneous data types + ******************************************************************************/ enum sdis_side { SDIS_FRONT, SDIS_BACK, SDIS_SIDE_NULL__ }; -enum sdis_medium_type { - SDIS_FLUID, - SDIS_SOLID, - SDIS_MEDIUM_TYPES_COUNT__ -}; - -enum sdis_estimator_type { - SDIS_ESTIMATOR_TEMPERATURE, - SDIS_ESTIMATOR_FLUX, - SDIS_ESTIMATOR_TYPES_COUNT__ -}; - enum sdis_scene_dimension { SDIS_SCENE_2D, SDIS_SCENE_3D }; -enum sdis_point_type { - SDIS_FRAGMENT, - SDIS_VERTEX, - SDIS_POINT_TYPES_COUNT__, - SDIS_POINT_NONE = SDIS_POINT_TYPES_COUNT__ -}; - -enum sdis_heat_vertex_type { - SDIS_HEAT_VERTEX_CONDUCTION, - SDIS_HEAT_VERTEX_CONVECTION, - SDIS_HEAT_VERTEX_RADIATIVE -}; - -enum sdis_heat_path_flag { - SDIS_HEAT_PATH_SUCCEED = BIT(0), - SDIS_HEAT_PATH_FAILED = BIT(1), - SDIS_HEAT_PATH_ALL = SDIS_HEAT_PATH_SUCCEED | SDIS_HEAT_PATH_FAILED, - SDIS_HEAT_PATH_NONE = 0 -}; - /* Random walk vertex, i.e. a spatiotemporal position at a given step of the * random walk. */ struct sdis_rwalk_vertex { @@ -137,6 +109,15 @@ struct sdis_interface_fragment { static const struct sdis_interface_fragment SDIS_INTERFACE_FRAGMENT_NULL = SDIS_INTERFACE_FRAGMENT_NULL__; +/******************************************************************************* + * Estimation data types + ******************************************************************************/ +enum sdis_estimator_type { + SDIS_ESTIMATOR_TEMPERATURE, + SDIS_ESTIMATOR_FLUX, + SDIS_ESTIMATOR_TYPES_COUNT__ +}; + /* Monte-Carlo estimation */ struct sdis_mc { double E; /* Expected value */ @@ -146,6 +127,15 @@ struct sdis_mc { #define SDIS_MC_NULL__ {0, 0, 0} static const struct sdis_mc SDIS_MC_NULL = SDIS_MC_NULL__; +/******************************************************************************* + * Data type used to describe physical properties + ******************************************************************************/ +enum sdis_medium_type { + SDIS_FLUID, + SDIS_SOLID, + SDIS_MEDIUM_TYPES_COUNT__ +}; + /* Functor type used to retrieve the spatio temporal physical properties of a * medium. */ typedef double @@ -236,6 +226,22 @@ struct sdis_interface_shader { static const struct sdis_interface_shader SDIS_INTERFACE_SHADER_NULL = SDIS_INTERFACE_SHADER_NULL__; +/******************************************************************************* + * Registered heat path data types + ******************************************************************************/ +enum sdis_heat_vertex_type { + SDIS_HEAT_VERTEX_CONDUCTION, + SDIS_HEAT_VERTEX_CONVECTION, + SDIS_HEAT_VERTEX_RADIATIVE +}; + +enum sdis_heat_path_flag { + SDIS_HEAT_PATH_SUCCESS = BIT(0), + SDIS_HEAT_PATH_FAILURE = BIT(1), + SDIS_HEAT_PATH_ALL = SDIS_HEAT_PATH_SUCCESS | SDIS_HEAT_PATH_FAILURE, + SDIS_HEAT_PATH_NONE = 0 +}; + /* Vertex of heat path v*/ struct sdis_heat_vertex { double P[3]; @@ -247,6 +253,28 @@ struct sdis_heat_vertex { static const struct sdis_heat_vertex SDIS_HEAT_VERTEX_NULL = SDIS_HEAT_VERTEX_NULL__; +/* Functor used to process a heat path registered against the estimator */ +typedef res_T +(*sdis_process_heat_path_T) + (const struct sdis_heat_path* path, + void* context); + +/* Functor used to process the vertices of a heat path */ +typedef res_T +(*sdis_process_heat_vertex_T) + (const struct sdis_heat_vertex* vertex, + void* context); + +/******************************************************************************* + * Green function data types + ******************************************************************************/ +enum sdis_point_type { + SDIS_FRAGMENT, + SDIS_VERTEX, + SDIS_POINT_TYPES_COUNT__, + SDIS_POINT_NONE = SDIS_POINT_TYPES_COUNT__ +}; + /* Path used to estimate the green function */ struct sdis_green_path { /* Internal data. Should not be accessed */ @@ -257,16 +285,17 @@ struct sdis_green_path { static const struct sdis_green_path SDIS_GREEN_PATH_NULL = SDIS_GREEN_PATH_NULL__; +/* Spatio temporal point */ struct sdis_point { union { struct { struct sdis_medium* medium; struct sdis_rwalk_vertex vertex; - } mdmvert; + } mdmvert; /* Medium and a vertex into it */ struct { struct sdis_interface* intface; struct sdis_interface_fragment fragment; - } itfrag; + } itfrag; /* Interface and a fragmetn onto it */ } data; enum sdis_point_type type; }; @@ -296,17 +325,181 @@ typedef res_T const double flux_term, void* context); -/* Functor used to process a heat path registered against the estimator */ -typedef res_T -(*sdis_process_heat_path_T) - (const struct sdis_heat_path* path, - void* context); - -/* Functor used to process the vertices of a heat path */ -typedef res_T -(*sdis_process_heat_vertex_T) - (const struct sdis_heat_vertex* vertex, - void* context); +/******************************************************************************* + * Data types of the input simulation parameters + ******************************************************************************/ +struct sdis_solve_probe_args { + size_t nrealisations; /* #realisations */ + double position[3]; /* Probe position */ + double time_range[2]; /* Observation time */ + double fp_to_meter; /* Scale from floating point units to meters */ + double ambient_radiative_temperature; /* In Kelvin */ + double reference_temperature; /* In Kelvin */ + int register_paths; /* Combination of enum sdis_heat_path_flag */ + struct ssp_rng* rng_state; /* Initial RNG state. May be NULL */ +}; +#define SDIS_SOLVE_PROBE_ARGS_DEFAULT__ { \ + 10000, /* #realisations */ \ + {0,0,0}, /* Position */ \ + {DBL_MAX,DBL_MAX}, /* Time range */ \ + 1.0, /* FP to meter */ \ + -1, /* Ambient radiative temperature */ \ + -1, /* Reference temperature */ \ + SDIS_HEAT_PATH_NONE, /* Register paths mask */ \ + NULL /* RNG state */ \ +} +static const struct sdis_solve_probe_args SDIS_SOLVE_PROBE_ARGS_DEFAULT = + SDIS_SOLVE_PROBE_ARGS_DEFAULT__; + +/* Arguments of a probe simulation */ +struct sdis_solve_probe_boundary_args { + size_t nrealisations; /* #realisations */ + size_t iprim; /* Identifier of the primitive on which the probe lies */ + double uv[2]; /* Parametric coordinates of the probe onto the primitve */ + double time_range[2]; /* Observation time */ + enum sdis_side side; /* Side of iprim on which the probe lies */ + double fp_to_meter; /* Scale from floating point units to meters */ + double ambient_radiative_temperature; /* In Kelvin */ + double reference_temperature; /* In Kelvin */ + int register_paths; /* Combination of enum sdis_heat_path_flag */ + struct ssp_rng* rng_state; /* Initial RNG state. May be NULL */ +}; +#define SDIS_SOLVE_PROBE_BOUNDARY_ARGS_DEFAULT__ { \ + 10000, /* #realisations */ \ + 0, /* Primitive identifier */ \ + {0,0}, /* UV */ \ + {DBL_MAX,DBL_MAX}, /* Time range */ \ + SDIS_SIDE_NULL__, \ + 1, /* FP to meter */ \ + -1, /* Ambient radiative temperature */ \ + -1, /* Reference temperature */ \ + SDIS_HEAT_PATH_NONE, \ + NULL /* RNG state */ \ +} +static const struct sdis_solve_probe_boundary_args +SDIS_SOLVE_PROBE_BOUNDARY_ARGS_DEFAULT = + SDIS_SOLVE_PROBE_BOUNDARY_ARGS_DEFAULT__; + +struct sdis_solve_boundary_args { + size_t nrealisations; /* #realisations */ + const size_t* primitives; /* List of boundary primitives to handle */ + const enum sdis_side* sides; /* Per primitive side to consider */ + size_t nprimitives; /* #primitives */ + double time_range[2]; /* Observation time */ + double fp_to_meter; /* Scale from floating point units to meters */ + double ambient_radiative_temperature; /* In Kelvin */ + double reference_temperature; /* In Kelvin */ + int register_paths; /* Combination of enum sdis_heat_path_flag */ + struct ssp_rng* rng_state; /* Initial RNG state. May be NULL */ +}; +#define SDIS_SOLVE_BOUNDARY_ARGS_DEFAULT__ { \ + 10000, /* #realisations */ \ + NULL, /* List or primitive ids */ \ + NULL, /* Per primitive side */ \ + 0, /* #primitives */ \ + {DBL_MAX,DBL_MAX}, /* Time range */ \ + 1, /* FP to meter */ \ + -1, /* Ambient radiative temperature */ \ + -1, /* Reference temperature */ \ + SDIS_HEAT_PATH_NONE, \ + NULL /* RNG state */ \ +} +static const struct sdis_solve_boundary_args SDIS_SOLVE_BOUNDARY_ARGS_DEFAULT = + SDIS_SOLVE_BOUNDARY_ARGS_DEFAULT__; + +struct sdis_solve_medium_args { + size_t nrealisations; /* #realisations */ + struct sdis_medium* medium; /* Medium to solve */ + double time_range[2]; /* Observation time */ + double fp_to_meter; /* Scale from floating point units to meters */ + double ambient_radiative_temperature; /* In Kelvin */ + double reference_temperature; /* In Kelvin */ + int register_paths; /* Combination of enum sdis_heat_path_flag */ + struct ssp_rng* rng_state; /* Initial RNG state. May be NULL */ +}; +#define SDIS_SOLVE_MEDIUM_ARGS_DEFAULT__ { \ + 10000, /* #realisations */ \ + NULL, /* Medium */ \ + {DBL_MAX,DBL_MAX}, /* Time range */ \ + 1, /* FP to meter */ \ + -1, /* Ambient radiative temperature */ \ + -1, /* Reference temperature */ \ + SDIS_HEAT_PATH_NONE, \ + NULL /* RNG state */ \ +} +static const struct sdis_solve_medium_args SDIS_SOLVE_MEDIUM_ARGS_DEFAULT = + SDIS_SOLVE_MEDIUM_ARGS_DEFAULT__; + +struct sdis_solve_probe_boundary_flux_args { + size_t nrealisations; /* #realisations */ + size_t iprim; /* Identifier of the primitive on which the probe lies */ + double uv[2]; /* Parametric coordinates of the probe onto the primitve */ + double time_range[2]; /* Observation time */ + double fp_to_meter; /* Scale from floating point units to meters */ + double ambient_radiative_temperature; /* In Kelvin */ + double reference_temperature; /* In Kelvin */ + struct ssp_rng* rng_state; /* Initial RNG state. May be NULL */ +}; +#define SDIS_SOLVE_PROBE_BOUNDARY_FLUX_ARGS_DEFAULT__ { \ + 10000, /* #realisations */ \ + 0, /* Primitive identifier */ \ + {0,0}, /* UV */ \ + {DBL_MAX,DBL_MAX}, /* Time range */ \ + 1, /* FP to meter */ \ + -1, /* Ambient radiative temperature */ \ + -1, /* Reference temperature */ \ + NULL /* RNG state */ \ +} +static const struct sdis_solve_probe_boundary_flux_args +SDIS_SOLVE_PROBE_BOUNDARY_FLUX_ARGS_DEFAULT = + SDIS_SOLVE_PROBE_BOUNDARY_FLUX_ARGS_DEFAULT__; + +struct sdis_solve_boundary_flux_args { + size_t nrealisations; /* #realisations */ + const size_t* primitives; /* List of boundary primitives to handle */ + size_t nprimitives; /* #primitives */ + double time_range[2]; /* Observation time */ + double fp_to_meter; /* Scale from floating point units to meters */ + double ambient_radiative_temperature; /* In Kelvin */ + double reference_temperature; /* In Kelvin */ + struct ssp_rng* rng_state; /* Initial RNG state. May be NULL */ +}; +#define SDIS_SOLVE_BOUNDARY_FLUX_ARGS_DEFAULT__ { \ + 10000, /* #realisations */ \ + NULL, /* List or primitive ids */ \ + 0, /* #primitives */ \ + {DBL_MAX,DBL_MAX}, /* Time range */ \ + 1, /* FP to meter */ \ + -1, /* Ambient radiative temperature */ \ + -1, /* Reference temperature */ \ + NULL /* RNG state */ \ +} +static const struct sdis_solve_boundary_flux_args +SDIS_SOLVE_BOUNDARY_FLUX_ARGS_DEFAULT = + SDIS_SOLVE_BOUNDARY_FLUX_ARGS_DEFAULT__; + +struct sdis_solve_camera_args { + struct sdis_camera* cam; /* Point of view */ + double time_range[2]; /* Observation time */ + double fp_to_meter; /* Scale from floating point units to meters */ + double ambient_radiative_temperature; /* In Kelvin */ + double reference_temperature; /* In Kelvin */ + size_t image_resolution[2]; /* Image resolution */ + size_t spp; /* #samples per pixel */ + int register_paths; /* Combination of enum sdis_heat_path_flag */ +}; +#define SDIS_SOLVE_CAMERA_ARGS_DEFAULT__ { \ + NULL, /* Camera */ \ + {DBL_MAX,DBL_MAX}, /* Time range */ \ + 1, /* FP to meter */ \ + -1, /* Ambient radiative temperature */ \ + -1, /* Reference temperature */ \ + {512,512}, /* Image resolution */ \ + 256, /* #realisations per pixel */ \ + SDIS_HEAT_PATH_NONE \ +} +static const struct sdis_solve_camera_args SDIS_SOLVE_CAMERA_ARGS_DEFAULT = + SDIS_SOLVE_CAMERA_ARGS_DEFAULT__; BEGIN_DECLS @@ -394,7 +587,7 @@ sdis_camera_look_at const double up[3]); /******************************************************************************* - * An estimator buffer is 2D array of estimators + * An estimator buffer is 2D array of estimators ******************************************************************************/ SDIS_API res_T sdis_estimator_buffer_ref_get @@ -436,6 +629,11 @@ sdis_estimator_buffer_get_realisation_time (const struct sdis_estimator_buffer* buf, struct sdis_mc* time); +SDIS_API res_T +sdis_estimator_buffer_get_rng_state + (const struct sdis_estimator_buffer* buf, + struct ssp_rng** rng_state); + /******************************************************************************* * A medium encapsulates the properties of either a fluid or a solid. ******************************************************************************/ @@ -525,6 +723,9 @@ sdis_interface_get_id * references an absolute 3D position. The physical properties of an interface * is defined by the interface of the triangle. * + * No duplicate is allowed, either vertex or triangle. No degenerated triangle + * is allowed. + * * Note that each triangle has 2 sides: a front and a back side. By convention, * the front side of a triangle is the side where its vertices are clock wise * ordered. The back side of a triangle is the exact opposite: it is the side @@ -537,9 +738,9 @@ sdis_scene_create (struct sdis_device* dev, const size_t ntris, /* #triangles */ void (*indices) /* Retrieve the indices toward the vertices of `itri' */ - (const size_t itri, size_t ids[3], void*), + (const size_t itri, size_t ids[3], void* ctx), void (*interf) /* Get the interface of the triangle `itri' */ - (const size_t itri, struct sdis_interface** bound, void*), + (const size_t itri, struct sdis_interface** bound, void* ctx), const size_t nverts, /* #vertices */ void (*position) /* Retrieve the position of the vertex `ivert' */ (const size_t ivert, double pos[3], void* ctx), @@ -551,6 +752,9 @@ sdis_scene_create * references an absolute 2D position. The physical properties of an interface * is defined by the interface of the segment. * + * No duplicate is allowed, either vertex or segment. No degenerated segment is + * allowed. + * * Note that each segment has 2 sides: a front and a back side. By convention, * the front side of a segment is the side where its vertices are clock wise * ordered. The back side of a segment is the exact opposite: it is the side @@ -563,9 +767,9 @@ sdis_scene_2d_create (struct sdis_device* dev, const size_t nsegs, /* #segments */ void (*indices) /* Retrieve the indices toward the vertices of `iseg' */ - (const size_t iseg, size_t ids[2], void*), + (const size_t iseg, size_t ids[2], void* ctx), void (*interf) /* Get the interface of the segment `iseg' */ - (const size_t iseg, struct sdis_interface** bound, void*), + (const size_t iseg, struct sdis_interface** bound, void* ctx), const size_t nverts, /* #vertices */ void (*position) /* Retrieve the position of the vertex `ivert' */ (const size_t ivert, double pos[2], void* ctx), @@ -630,23 +834,17 @@ sdis_scene_boundary_project_position const double pos[3], double uv[]); -/* Get the descriptor of the 3D scene's enclosures */ +/* Get the 2D scene's enclosures. Only defined for a 2D scene. */ SDIS_API res_T -sdis_scene_get_analysis +sdis_scene_get_senc2d_scene (struct sdis_scene* scn, - struct senc_descriptor** descriptor); + struct senc2d_scene** senc2d_scn); -/* Get the descriptor of the 2D scene's enclosures */ +/* Get the 3D scene's enclosures. Only defined for a 3D scene. */ SDIS_API res_T -sdis_scene_2d_get_analysis +sdis_scene_get_senc3d_scene (struct sdis_scene* scn, - struct senc2d_descriptor** descriptor); - -/* Release the descriptor of the scene's enclosures; subsequent attempts to get - * it will fail. */ -SDIS_API res_T -sdis_scene_release_analysis - (struct sdis_scene* scn); + struct senc3d_scene** senc3d_scn); SDIS_API res_T sdis_scene_get_dimension @@ -730,6 +928,14 @@ sdis_estimator_for_each_path sdis_process_heat_path_T func, void* context); +/* Retrieve the RNG state at the end of the simulation. */ +SDIS_API res_T +sdis_estimator_get_rng_state + (const struct sdis_estimator* estimator, + /* The returned value may be NULL as for instance an estimator retrieved + * from an estimator buffer */ + struct ssp_rng** rng_state); + /******************************************************************************* * The green function saves the estimation of the propagator ******************************************************************************/ @@ -838,91 +1044,43 @@ sdis_heat_path_for_each_vertex SDIS_API res_T sdis_solve_probe (struct sdis_scene* scn, - const size_t nrealisations, /* #realisations */ - const double position[3], /* Probe position */ - const double time_range[2], /* Observation time */ - const double fp_to_meter, /* Scale from floating point units to meters */ - const double ambient_radiative_temperature, /* In Kelvin */ - const double reference_temperature, /* In Kelvin */ - const int register_paths, /* Combination of enum sdis_heat_path_flag */ + const struct sdis_solve_probe_args* args, struct sdis_estimator** estimator); SDIS_API res_T sdis_solve_probe_boundary (struct sdis_scene* scn, - const size_t nrealisations, /* #realisations */ - const size_t iprim, /* Identifier of the primitive on which the probe lies */ - const double uv[2], /* Parametric coordinates of the probe onto the primitve */ - const double time_range[2], /* Observation time */ - const enum sdis_side side, /* Side of iprim on which the probe lies */ - const double fp_to_meter, /* Scale from floating point units to meters */ - const double ambient_radiative_temperature, /* In Kelvin */ - const double reference_temperature, /* In Kelvin */ - const int register_paths, /* Combination of enum sdis_heat_path_flag */ + const struct sdis_solve_probe_boundary_args* args, struct sdis_estimator** estimator); SDIS_API res_T sdis_solve_boundary (struct sdis_scene* scn, - const size_t nrealisations, /* #realisations */ - const size_t primitives[], /* List of boundary primitives to handle */ - const enum sdis_side sides[], /* Per primitive side to consider */ - const size_t nprimitives, /* #primitives */ - const double time_range[2], /* Observation time */ - const double fp_to_meter, /* Scale from floating point units to meters */ - const double ambient_radiative_temperature, /* In Kelvin */ - const double reference_temperature, /* In Kelvin */ - const int register_paths, /* Combination of enum sdis_heat_path_flag */ + const struct sdis_solve_boundary_args* args, struct sdis_estimator** estimator); SDIS_API res_T sdis_solve_probe_boundary_flux (struct sdis_scene* scn, - const size_t nrealisations, /* #realisations */ - const size_t iprim, /* Identifier of the primitive on which the probe lies */ - const double uv[2], /* Parametric coordinates of the probe onto the primitve */ - const double time_range[2], /* Observation time */ - const double fp_to_meter, /* Scale from floating point units to meters */ - const double ambient_radiative_temperature, /* In Kelvin */ - const double reference_temperature, /* In Kelvin */ + const struct sdis_solve_probe_boundary_flux_args* args, struct sdis_estimator** estimator); SDIS_API res_T sdis_solve_boundary_flux (struct sdis_scene* scn, - const size_t nrealisations, /* #realisations */ - const size_t primitives[], /* List of boundary primitives to handle */ - const size_t nprimitives, /* #primitives */ - const double time_range[2], /* Observation time */ - const double fp_to_meter, /* Scale from floating point units to meters */ - const double ambient_radiative_temperature, /* In Kelvin */ - const double reference_temperature, /* In Kelvin */ + const struct sdis_solve_boundary_flux_args* args, struct sdis_estimator** estimator); SDIS_API res_T sdis_solve_camera (struct sdis_scene* scn, - const struct sdis_camera* cam, /* Point of view */ - const double time_range[2], /* Observation time */ - const double fp_to_meter, /* Scale from floating point units to meters */ - const double ambient_radiative_temperature, /* In Kelvin */ - const double reference_temperature, /* In Kelvin */ - const size_t width, /* Image definition in in X */ - const size_t height, /* Image definition in Y */ - const size_t spp, /* #samples per pixel */ - const int register_paths, /* Combination of enum sdis_heat_path_flag */ + const struct sdis_solve_camera_args* args, struct sdis_estimator_buffer** buf); SDIS_API res_T sdis_solve_medium (struct sdis_scene* scn, - const size_t nrealisations, /* #realisations */ - struct sdis_medium* medium, /* Medium to solve */ - const double time_range[2], /* Observation time */ - const double fp_to_meter, /* Scale from floating point units to meters */ - const double ambient_radiative_temperature, /* In Kelvin */ - const double reference_temperature, /* In Kelvin */ - const int register_paths, /* Combination of enum sdis_heat_path_flag */ + const struct sdis_solve_medium_args* args, struct sdis_estimator** estimator); /******************************************************************************* @@ -949,45 +1107,25 @@ sdis_solve_medium SDIS_API res_T sdis_solve_probe_green_function (struct sdis_scene* scn, - const size_t nrealisations, /* #realisations */ - const double position[3], /* Probe position */ - const double fp_to_meter, /* Scale from floating point units to meters */ - const double ambient_radiative_temperature, /* In Kelvin */ - const double reference_temperature, /* In Kelvin */ + const struct sdis_solve_probe_args* args, struct sdis_green_function** green); SDIS_API res_T sdis_solve_probe_boundary_green_function (struct sdis_scene* scn, - const size_t nrealisations, /* #realisations */ - const size_t iprim, /* Identifier of the primitive on which the probe lies */ - const double uv[2], /* Parametric coordinates of the probe onto the primitve */ - const enum sdis_side side, /* Side of iprim on which the probe lies */ - const double fp_to_meter, /* Scale from floating point units to meters */ - const double ambient_radiative_temperature, /* In Kelvin */ - const double reference_temperature, /* In Kelvin */ + const struct sdis_solve_probe_boundary_args* args, struct sdis_green_function** green); SDIS_API res_T sdis_solve_boundary_green_function (struct sdis_scene* scn, - const size_t nrealisations, /* #realisations */ - const size_t primitives[], /* List of boundary primitives to handle */ - const enum sdis_side sides[], /* Per primitive side to consider */ - const size_t nprimitives, /* #primitives */ - const double fp_to_meter, /* Scale from floating point units to meters */ - const double ambient_radiative_temperature, /* In Kelvin */ - const double reference_temperature, /* In Kelvin */ + const struct sdis_solve_boundary_args* args, struct sdis_green_function** green); SDIS_API res_T sdis_solve_medium_green_function (struct sdis_scene* scn, - const size_t nrealisations, /* #realisations */ - struct sdis_medium* medium, /* Medium to solve */ - const double fp_to_meter, /* Scale from floating point units to meters */ - const double ambient_radiative_temperature, /* In Kelvin */ - const double reference_temperature, /* In Kelvin */ + const struct sdis_solve_medium_args* args, struct sdis_green_function** green); END_DECLS diff --git a/src/sdis_Xd_begin.h b/src/sdis_Xd_begin.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -60,7 +60,6 @@ static const struct rwalk_context RWALK_CONTEXT_NULL = RWALK_CONTEXT_NULL__; /* Star-XD macros generic to SDIS_XD_DIMENSION */ #define sXd(Name) CONCAT(CONCAT(CONCAT(s, DIM), d_), Name) -#define sXd_dev CONCAT(CONCAT(s, DIM), d) #define SXD_HIT_NONE CONCAT(CONCAT(S,DIM), D_HIT_NONE) #define SXD_HIT_NULL CONCAT(CONCAT(S,DIM), D_HIT_NULL) #define SXD_HIT_NULL__ CONCAT(CONCAT(S, DIM), D_HIT_NULL__) @@ -70,6 +69,7 @@ static const struct rwalk_context RWALK_CONTEXT_NULL = RWALK_CONTEXT_NULL__; #define SXD CONCAT(CONCAT(S, DIM), D) #define SXD_FLOAT2 CONCAT(CONCAT(S, DIM), D_FLOAT2) #define SXD_FLOAT3 CONCAT(CONCAT(S, DIM), D_FLOAT3) +#define SXD_FLOATX CONCAT(CONCAT(CONCAT(S,DIM), D_FLOAT), DIM) #define SXD_SAMPLE CONCAT(CONCAT(S, DIM), D_SAMPLE) /* Vector macros generic to SDIS_XD_DIMENSION */ diff --git a/src/sdis_Xd_end.h b/src/sdis_Xd_end.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,7 +21,6 @@ #undef DIM #undef sXd -#undef sXd_dev #undef SXD_HIT_NONE #undef SXD_HIT_NULL #undef SXD_HIT_NULL__ @@ -31,6 +30,7 @@ #undef SXD #undef SXD_FLOAT2 #undef SXD_FLOAT3 +#undef SXD_FLOATX #undef SXD_SAMPLE #undef dX diff --git a/src/sdis_camera.c b/src/sdis_camera.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/sdis_camera.h b/src/sdis_camera.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/sdis_data.c b/src/sdis_data.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,6 +15,7 @@ #include "sdis.h" #include "sdis_device_c.h" +#include "sdis_log.h" #include <rsys/math.h> #include <rsys/mem_allocator.h> diff --git a/src/sdis_device.c b/src/sdis_device.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,12 +15,15 @@ #include "sdis.h" #include "sdis_device_c.h" +#include "sdis_log.h" +#include <rsys/cstr.h> #include <rsys/logger.h> #include <rsys/mem_allocator.h> #include <star/s2d.h> #include <star/s3d.h> +#include <star/ssp.h> #include <omp.h> @@ -28,28 +31,14 @@ * Helper functions ******************************************************************************/ static void -log_msg - (struct sdis_device* dev, - const enum log_type stream, - const char* msg, - va_list vargs) -{ - ASSERT(dev && msg); - if(dev->verbose) { - res_T res; (void)res; - res = logger_vprint(dev->logger, stream, msg, vargs); - ASSERT(res == RES_OK); - } -} - -static void device_release(ref_T* ref) { struct sdis_device* dev; ASSERT(ref); dev = CONTAINER_OF(ref, struct sdis_device, ref); - if(dev->s2d) S2D(device_ref_put(dev->s2d)); - if(dev->s3d) S3D(device_ref_put(dev->s3d)); + if(dev->s2d_dev) S2D(device_ref_put(dev->s2d_dev)); + if(dev->s3d_dev) S3D(device_ref_put(dev->s3d_dev)); + if(dev->logger == &dev->logger__) logger_release(&dev->logger__); ASSERT(flist_name_is_empty(&dev->interfaces_names)); ASSERT(flist_name_is_empty(&dev->media_names)); flist_name_release(&dev->interfaces_names); @@ -78,19 +67,21 @@ sdis_device_create goto error; } - log = logger ? logger : LOGGER_DEFAULT; allocator = mem_allocator ? mem_allocator : &mem_default_allocator; dev = MEM_CALLOC(allocator, 1, sizeof(struct sdis_device)); if(!dev) { if(verbose) { - /* Do not use helper log functions since dev is not initialised */ - CHK(logger_print(log, LOG_ERROR, - "%s: could not allocate the Stardis device.\n", FUNC_NAME) == RES_OK); + #define ERR_STR STR(FUNC_NAME)": could not allocate the Stardis device -- %s." + if(logger) { + logger_print(logger, LOG_ERROR, ERR_STR, res_to_cstr(res)); + } else { + fprintf(stderr, MSG_ERROR_PREFIX ERR_STR, res_to_cstr(res)); + } + #undef ERR_STR } res = RES_MEM_ERR; goto error; } - dev->logger = log; dev->allocator = allocator; dev->verbose = verbose; dev->nthreads = MMIN(nthreads_hint, (unsigned)omp_get_num_procs()); @@ -98,16 +89,26 @@ sdis_device_create flist_name_init(allocator, &dev->interfaces_names); flist_name_init(allocator, &dev->media_names); - res = s2d_device_create(log, allocator, 0, &dev->s2d); + if(logger) { + dev->logger = logger; + } else { + setup_log_default(dev); + } + log_info(dev, "Use %lu %s.\n", (unsigned long)dev->nthreads, + dev->nthreads == 1 ? "thread" : "threads"); + + res = s2d_device_create(log, allocator, 0, &dev->s2d_dev); if(res != RES_OK) { log_err(dev, - "%s: could not create the Star-2D device on Stardis.\n", FUNC_NAME); + "%s: could not create the Star-2D device on Stardis -- %s.\n", + FUNC_NAME, res_to_cstr(res)); } - res = s3d_device_create(log, allocator, 0, &dev->s3d); + res = s3d_device_create(log, allocator, 0, &dev->s3d_dev); if(res != RES_OK) { log_err(dev, - "%s: could not create the Star-3D device on Stardis.\n", FUNC_NAME); + "%s: could not create the Star-3D device on Stardis -- %s.\n", + FUNC_NAME, res_to_cstr(res)); goto error; } @@ -141,25 +142,56 @@ sdis_device_ref_put(struct sdis_device* dev) /******************************************************************************* * Local functions ******************************************************************************/ -void -log_err(struct sdis_device* dev, const char* msg, ...) +res_T +create_rng_from_rng_proxy + (struct sdis_device* dev, + const struct ssp_rng_proxy* proxy, + struct ssp_rng** out_rng) { - va_list vargs_list; - ASSERT(dev && msg); + struct ssp_rng_type rng_type; + struct ssp_rng* rng = NULL; + FILE* stream = NULL; + res_T res = RES_OK; + ASSERT(dev && proxy && out_rng); - va_start(vargs_list, msg); - log_msg(dev, LOG_ERROR, msg, vargs_list); - va_end(vargs_list); -} + stream = tmpfile(); + if(!stream) { + log_err(dev, + "Could not open a temporary stream to store the RNG state.\n"); + res = RES_IO_ERR; + goto error; + } -void -log_warn(struct sdis_device* dev, const char* msg, ...) -{ - va_list vargs_list; - ASSERT(dev && msg); + SSP(rng_proxy_get_type(proxy, &rng_type)); + res = ssp_rng_create(dev->allocator, &rng_type, &rng); + if(res != RES_OK) { + log_err(dev, "Could not create the RNG -- %s\n", res_to_cstr(res)); + goto error; + } - va_start(vargs_list, msg); - log_msg(dev, LOG_WARNING, msg, vargs_list); - va_end(vargs_list); -} + res = ssp_rng_proxy_write(proxy, stream); + if(res != RES_OK) { + log_err(dev, "Could not serialize the RNG state -- %s\n", + res_to_cstr(res)); + goto error; + } + + rewind(stream); + res = ssp_rng_read(rng, stream); + if(res != RES_OK) { + log_err(dev, "Could not read the serialized RNG state -- %s\n", + res_to_cstr(res)); + goto error; + } +exit: + if(out_rng) *out_rng = rng; + if(stream) fclose(stream); + return res; +error: + if(rng) { + SSP(rng_ref_put(rng)); + rng = NULL; + } + goto exit; +} diff --git a/src/sdis_device_c.h b/src/sdis_device_c.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,14 +20,20 @@ #include <rsys/dynamic_array.h> #include <rsys/free_list.h> +#include <rsys/logger.h> #include <rsys/ref_count.h> +/* Forward declarations */ +struct ssp_rng; +struct ssp_rng_proxy; + struct name { FITEM; }; #define FITEM_TYPE name #include <rsys/free_list.h> struct sdis_device { struct logger* logger; + struct logger logger__; /* Default logger */ struct mem_allocator* allocator; unsigned nthreads; int verbose; @@ -35,35 +41,17 @@ struct sdis_device { struct flist_name interfaces_names; struct flist_name media_names; - struct s2d_device* s2d; - struct s3d_device* s3d; + struct s2d_device* s2d_dev; + struct s3d_device* s3d_dev; ref_T ref; }; -/* Conditionally log a message on the LOG_ERROR stream of the device logger, - * with respect to the device verbose flag */ -extern LOCAL_SYM void -log_err - (struct sdis_device* dev, - const char* msg, - ...) -#ifdef COMPILER_GCC - __attribute((format(printf, 2, 3))) -#endif -; - -/* Conditionally log a message on the LOG_WARNING stream of the device logger, - * with respect to the device verbose flag */ -extern LOCAL_SYM void -log_warn +extern LOCAL_SYM res_T +create_rng_from_rng_proxy (struct sdis_device* dev, - const char* msg, - ...) -#ifdef COMPILER_GCC - __attribute((format(printf, 2, 3))) -#endif -; + const struct ssp_rng_proxy* proxy, + struct ssp_rng** out_rng); #endif /* SDIS_DEVICE_C_H */ diff --git a/src/sdis_estimator.c b/src/sdis_estimator.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,11 @@ #include "sdis.h" #include "sdis_device_c.h" #include "sdis_estimator_c.h" +#include "sdis_log.h" +#include <star/ssp.h> + +#include <rsys/cstr.h> #include <rsys/mutex.h> /******************************************************************************* @@ -32,6 +36,7 @@ estimator_release(ref_T* ref) dev = estimator->dev; darray_heat_path_release(&estimator->paths); if(estimator->mutex) mutex_destroy(estimator->mutex); + if(estimator->rng) SSP(rng_ref_put(estimator->rng)); MEM_RM(dev->allocator, estimator); SDIS(device_ref_put(dev)); } @@ -192,6 +197,16 @@ error: goto exit; } +res_T +sdis_estimator_get_rng_state + (const struct sdis_estimator* estimator, + struct ssp_rng** rng_state) +{ + if(!estimator || !rng_state) return RES_BAD_ARG; + *rng_state = estimator->rng; + return RES_OK; +} + /******************************************************************************* * Local functions ******************************************************************************/ @@ -268,3 +283,17 @@ error: goto exit; } +res_T +estimator_save_rng_state + (struct sdis_estimator* estimator, + const struct ssp_rng_proxy* proxy) +{ + ASSERT(estimator && proxy); + /* Release the previous RNG state if any */ + if(estimator->rng) { + SSP(rng_ref_put(estimator->rng)); + estimator->rng = NULL; + } + return create_rng_from_rng_proxy(estimator->dev, proxy, &estimator->rng); +} + diff --git a/src/sdis_estimator_buffer.c b/src/sdis_estimator_buffer.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,6 +17,9 @@ #include "sdis_device_c.h" #include "sdis_estimator_c.h" #include "sdis_estimator_buffer_c.h" +#include "sdis_log.h" + +#include <star/ssp.h> struct sdis_estimator_buffer { struct sdis_estimator** estimators; /* Row major per pixe lestimators */ @@ -28,6 +31,9 @@ struct sdis_estimator_buffer { size_t nrealisations; /* #successes */ size_t nfailures; + /* State of the RNG after the simulation */ + struct ssp_rng* rng; + ref_T ref; struct sdis_device* dev; }; @@ -53,6 +59,7 @@ estimator_buffer_release(ref_T* ref) MEM_RM(dev->allocator, buf->estimators); } + if(buf->rng) SSP(rng_ref_put(buf->rng)); MEM_RM(dev->allocator, buf); SDIS(device_ref_put(dev)); } @@ -135,13 +142,22 @@ sdis_estimator_buffer_get_temperature res_T sdis_estimator_buffer_get_realisation_time -(const struct sdis_estimator_buffer* buf, struct sdis_mc* mc) + (const struct sdis_estimator_buffer* buf, struct sdis_mc* mc) { if(!buf || !mc) return RES_BAD_ARG; SETUP_MC(mc, &buf->realisation_time); return RES_OK; } +res_T +sdis_estimator_buffer_get_rng_state + (const struct sdis_estimator_buffer* buf, struct ssp_rng** rng_state) +{ + if(!buf || !rng_state) return RES_BAD_ARG; + *rng_state = buf->rng; + return RES_OK; +} + #undef SETUP_MC /******************************************************************************* @@ -242,3 +258,18 @@ estimator_buffer_setup_realisation_time buf->realisation_time.count = buf->nrealisations; } +res_T +estimator_buffer_save_rng_state + (struct sdis_estimator_buffer* buf, + const struct ssp_rng_proxy* proxy) +{ + ASSERT(buf && proxy); + + /* Release the previous RNG state if any */ + if(buf->rng) { + SSP(rng_ref_put(buf->rng)); + buf->rng = NULL; + } + return create_rng_from_rng_proxy(buf->dev, proxy, &buf->rng); +} + diff --git a/src/sdis_estimator_buffer_c.h b/src/sdis_estimator_buffer_c.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -54,5 +54,10 @@ estimator_buffer_setup_realisation_time const double sum, const double sum2); +extern LOCAL_SYM res_T +estimator_buffer_save_rng_state + (struct sdis_estimator_buffer* buf, + const struct ssp_rng_proxy* proxy); + #endif /* SDIS_ESTIMATOR_BUFFER_C_H */ diff --git a/src/sdis_estimator_c.h b/src/sdis_estimator_c.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,6 +23,7 @@ #include <rsys/ref_count.h> /* Forward declarations */ +struct ssp_rng; struct sdis_device; struct sdis_estimator; enum sdis_estimator_type; @@ -44,13 +45,14 @@ struct sdis_estimator { struct mutex* mutex; struct darray_heat_path paths; /* Tracked paths */ + /* State of the RNG after the simulation */ + struct ssp_rng* rng; + enum sdis_estimator_type type; ref_T ref; struct sdis_device* dev; }; -struct sdis_estimator_handle; - /******************************************************************************* * Estimator local API ******************************************************************************/ @@ -66,6 +68,11 @@ estimator_add_and_release_heat_path (struct sdis_estimator* estimator, struct sdis_heat_path* path); +extern LOCAL_SYM res_T +estimator_save_rng_state + (struct sdis_estimator* estimator, + const struct ssp_rng_proxy* proxy); + /* Must be invoked before any others "estimator_setup" functions */ static INLINE void estimator_setup_realisations_count diff --git a/src/sdis_green.c b/src/sdis_green.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,6 +16,7 @@ #include "sdis_device_c.h" #include "sdis_estimator_c.h" #include "sdis_green.h" +#include "sdis_log.h" #include "sdis_medium_c.h" #include "sdis_misc.h" #include "sdis_interface_c.h" @@ -178,7 +179,7 @@ green_path_copy_and_release(struct green_path* dst, struct green_path* src) #define HTABLE_DATA struct sdis_interface* #include <rsys/hash_table.h> -/* Generate the hash table that maps and id to a medium */ +/* Generate the hash table that maps an id to a medium */ #define HTABLE_NAME medium #define HTABLE_KEY unsigned #define HTABLE_DATA struct sdis_medium* @@ -781,7 +782,6 @@ green_function_merge_and_clear size_t npaths_dst; size_t npaths; size_t i; - unsigned id; res_T res = RES_OK; ASSERT(dst && src); @@ -807,8 +807,7 @@ green_function_merge_and_clear while(!htable_medium_iterator_eq(&it_medium, &end_medium)) { struct sdis_medium* medium; medium = *htable_medium_iterator_data_get(&it_medium); - id = medium_get_id(medium); - res = htable_medium_set(&dst->media, &id, &medium); + res = ensure_medium_registration(dst, medium); if(res != RES_OK) goto error; htable_medium_iterator_next(&it_medium); } @@ -818,8 +817,7 @@ green_function_merge_and_clear while(!htable_interf_iterator_eq(&it_interf, &end_interf)) { struct sdis_interface* interf; interf = *htable_interf_iterator_data_get(&it_interf); - id = interface_get_id(interf); - res = htable_interf_set(&dst->interfaces, &id, &interf); + res = ensure_interface_registration(dst, interf); if(res != RES_OK) goto error; htable_interf_iterator_next(&it_interf); } diff --git a/src/sdis_green.h b/src/sdis_green.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/sdis_heat_path.c b/src/sdis_heat_path.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/sdis_heat_path.h b/src/sdis_heat_path.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/sdis_heat_path_boundary_Xd.h b/src/sdis_heat_path_boundary_Xd.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -114,9 +114,9 @@ XD(move_away_primitive_boundaries) float min_dst, max_dst; float cos_a1, cos_a2; float len; - int imax; - int imin; - int imid; + int imax = 0; + int imin = 0; + int imid = 0; int i; ASSERT(rwalk && delta > 0 && !S3D_HIT_NONE(&rwalk->hit)); @@ -300,7 +300,7 @@ XD(select_reinjection_dir) } while(dst0 == -1 && dst1 == -1 && ++iattempt < MAX_ATTEMPTS); if(dst0 == -1 && dst1 == -1) { /* No valid reinjection */ - log_err(scn->dev, "%s: no valid reinjection direction at {%g, %g, %g}.\n", + log_warn(scn->dev, "%s: no valid reinjection direction at {%g, %g, %g}.\n", FUNC_NAME, SPLIT3(rwalk->vtx.P)); res = RES_BAD_OP_IRRECOVERABLE; goto error; @@ -482,7 +482,7 @@ XD(solid_solid_boundary_path) float dir0[DIM], dir1[DIM], dir2[DIM], dir3[DIM]; float dir_front[DIM], dir_back[DIM]; float* dir; - float reinject_dst_front, reinject_dst_back; + float reinject_dst_front = 0, reinject_dst_back = 0; float reinject_dst; /* In 2D it is useless to try to resample a reinjection direction since there * is only one possible direction */ @@ -554,8 +554,8 @@ XD(solid_solid_boundary_path) /* Could not find a valid reinjection */ if(iattempt >= MAX_ATTEMPTS) { *rwalk = rwalk_saved; - log_err(scn->dev, - "%s: could not find a valid soid/solid reinjection at {%g, %g, %g}.\n", + log_warn(scn->dev, + "%s: could not find a valid solid/solid reinjection at {%g, %g, %g}.\n", FUNC_NAME, SPLIT3(rwalk->vtx.P)); res = RES_BAD_OP_IRRECOVERABLE; goto error; @@ -718,7 +718,7 @@ XD(solid_fluid_boundary_path) /* Could not find a valid reinjecton */ if(iattempt >= MAX_ATTEMPTS) { *rwalk = rwalk_saved; - log_err(scn->dev, + log_warn(scn->dev, "%s: could not find a valid solid/fluid reinjection at {%g, %g %g}.\n", FUNC_NAME, SPLIT3(rwalk->vtx.P)); res = RES_BAD_OP_IRRECOVERABLE; @@ -867,7 +867,7 @@ XD(solid_boundary_with_flux_path) /* Could not find a valid reinjecton */ if(iattempt >= MAX_ATTEMPTS) { *rwalk = rwalk_saved; - log_err(scn->dev, + log_warn(scn->dev, "%s: could not find a valid solid/fluid with flux reinjection " "at {%g, %g, %g}.\n", FUNC_NAME, SPLIT3(rwalk->vtx.P)); res = RES_BAD_OP_IRRECOVERABLE; diff --git a/src/sdis_heat_path_conductive_Xd.h b/src/sdis_heat_path_conductive_Xd.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -158,11 +158,11 @@ XD(sample_next_step_robust) if(current_mdm != mdm) { #if 0 #if DIM == 2 - log_err(scn->dev, + log_warn(scn->dev, "%s: inconsistent medium during the solid random walk at {%g, %g}.\n", FUNC_NAME, SPLIT2(pos)); #else - log_err(scn->dev, + log_warn(scn->dev, "%s: inconsistent medium during the solid random walk at {%g, %g, %g}.\n", FUNC_NAME, SPLIT3(pos)); #endif @@ -173,11 +173,11 @@ XD(sample_next_step_robust) /* Handle error */ if(iattempt >= MAX_ATTEMPTS) { #if DIM == 2 - log_err(scn->dev, + log_warn(scn->dev, "%s: could not find a next valid conductive step at {%g, %g}.\n", FUNC_NAME, SPLIT2(pos)); #else - log_err(scn->dev, + log_warn(scn->dev, "%s: could not find a next valid conductive step at {%g, %g, %g}.\n", FUNC_NAME, SPLIT3(pos)); #endif @@ -218,7 +218,7 @@ XD(conductive_path) /* Check the random walk consistency */ res = scene_get_medium_in_closed_boundaries(scn, rwalk->vtx.P, &mdm); if(res != RES_OK || mdm != rwalk->mdm) { - log_err(scn->dev, "%s: invalid solid random walk. " + log_warn(scn->dev, "%s: invalid solid random walk. " "Unexpected medium at {%g, %g, %g}.\n", FUNC_NAME, SPLIT3(rwalk->vtx.P)); res = RES_BAD_OP_IRRECOVERABLE; goto error; @@ -370,7 +370,7 @@ XD(conductive_path) /* The initial condition should have been reached */ log_err(scn->dev, "%s: undefined initial condition. " - "The time is %f but the temperature remains unknown.\n", + "The time is %g but the temperature remains unknown.\n", FUNC_NAME, t0); res = RES_BAD_OP; goto error; diff --git a/src/sdis_heat_path_convective_Xd.h b/src/sdis_heat_path_convective_Xd.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -86,6 +86,7 @@ XD(convective_path) double cp; /* Calorific capacity */ double tmp; double r; + int path_started_in_fluid; #if SDIS_XD_DIMENSION == 2 float st; #else @@ -112,7 +113,8 @@ XD(convective_path) goto exit; } - if(SXD_HIT_NONE(&rwalk->hit)) { /* The path begins in the fluid */ + path_started_in_fluid = SXD_HIT_NONE(&rwalk->hit); + if(path_started_in_fluid) { /* The path begins in the fluid */ const float range[2] = {0, FLT_MAX}; float dir[DIM] = {0}; float org[DIM]; @@ -123,7 +125,6 @@ XD(convective_path) /* Init the path hit field required to define the current enclosure and * fetch the interface data */ SXD(scene_view_trace_ray(scn->sXd(view), org, dir, range, NULL, &rwalk->hit)); - rwalk->hit_side = fX(dot)(rwalk->hit.normal, dir) < 0 ? SDIS_FRONT : SDIS_BACK; if(SXD_HIT_NONE(&rwalk->hit)) { log_err(scn->dev, @@ -132,6 +133,8 @@ XD(convective_path) res = RES_BAD_OP; goto error; } + + rwalk->hit_side = fX(dot)(rwalk->hit.normal, dir) < 0 ? SDIS_FRONT : SDIS_BACK; } /* Fetch the current interface and its associated enclosures */ @@ -166,7 +169,7 @@ XD(convective_path) * is the initial condition. */ if(enc->hc_upper_bound == 0) { /* Cannot be in the fluid without starting there. */ - ASSERT(SXD_HIT_NONE(&rwalk->hit)); + ASSERT(path_started_in_fluid); if(ctx->green_path) { log_err(scn->dev, @@ -185,11 +188,11 @@ XD(convective_path) goto exit; } - /* At t=0, the initial condition should have been reached. */ + /* At t=t0, the initial condition should have been reached. */ log_err(scn->dev, "%s: undefined initial condition. " - "Time is 0 but the temperature remains unknown.\n", - FUNC_NAME); + "Time is %g but the temperature remains unknown.\n", + FUNC_NAME, rwalk->vtx.time); res = RES_BAD_OP; goto error; } diff --git a/src/sdis_heat_path_radiative_Xd.h b/src/sdis_heat_path_radiative_Xd.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,6 +17,7 @@ #include "sdis_green.h" #include "sdis_heat_path.h" #include "sdis_interface_c.h" +#include "sdis_log.h" #include "sdis_medium_c.h" #include "sdis_misc.h" #include "sdis_scene_c.h" @@ -167,7 +168,7 @@ XD(trace_radiative_path) if(outside && chk_mdm->type == SDIS_FLUID) { rwalk->mdm = chk_mdm; } else { - log_err(scn->dev, "%s: inconsistent medium definition at `%g %g %g'.\n", + log_warn(scn->dev, "%s: inconsistent medium definition at `%g %g %g'.\n", FUNC_NAME, SPLIT3(rwalk->vtx.P)); res = RES_BAD_OP; goto error; diff --git a/src/sdis_interface.c b/src/sdis_interface.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,6 +16,7 @@ #include "sdis.h" #include "sdis_device_c.h" #include "sdis_interface_c.h" +#include "sdis_log.h" #include "sdis_scene_c.h" #include <rsys/double2.h> diff --git a/src/sdis_interface_c.h b/src/sdis_interface_c.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/sdis_log.c b/src/sdis_log.c @@ -0,0 +1,119 @@ +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#define _POSIX_C_SOURCE 200112L /* snprintf support */ + +#include "sdis_device_c.h" +#include "sdis_log.h" + +#include <rsys/logger.h> + +#include <stdarg.h> + +/******************************************************************************* + * Helper functions + ******************************************************************************/ +static void +log_msg + (const struct sdis_device* dev, + const enum log_type stream, + const char* msg, + va_list vargs) +{ + ASSERT(dev && msg); + if(dev->verbose) { + CHK(logger_vprint(dev->logger, stream, msg, vargs) == RES_OK); + } +} + +static void +print_info(const char* msg, void* ctx) +{ + (void)ctx; + fprintf(stderr, MSG_INFO_PREFIX"%s", msg); +} + +static void +print_err(const char* msg, void* ctx) +{ + (void)ctx; + fprintf(stderr, MSG_ERROR_PREFIX"%s", msg); +} + +static void +print_warn(const char* msg, void* ctx) +{ + (void)ctx; + fprintf(stderr, MSG_WARNING_PREFIX"%s", msg); +} + +/******************************************************************************* + * Local functions + ******************************************************************************/ +res_T +setup_log_default(struct sdis_device* dev) +{ + res_T res = RES_OK; + ASSERT(dev); + + res = logger_init(dev->allocator, &dev->logger__); + if(res != RES_OK) { + if(dev->verbose) print_err("Could not setup the logger.\n", NULL); + goto error; + } + logger_set_stream(&dev->logger__, LOG_OUTPUT, print_info, NULL); + logger_set_stream(&dev->logger__, LOG_ERROR, print_err, NULL); + logger_set_stream(&dev->logger__, LOG_WARNING, print_warn, NULL); + dev->logger = &dev->logger__; + +exit: + return res; +error: + goto exit; +} + +void +log_info(const struct sdis_device* dev, const char* msg, ...) +{ + va_list vargs_list; + ASSERT(dev && msg); + + va_start(vargs_list, msg); + log_msg(dev, LOG_OUTPUT, msg, vargs_list); + va_end(vargs_list); +} + +void +log_err(const struct sdis_device* dev, const char* msg, ...) +{ + va_list vargs_list; + ASSERT(dev && msg); + + va_start(vargs_list, msg); + log_msg(dev, LOG_ERROR, msg, vargs_list); + va_end(vargs_list); +} + +void +log_warn(const struct sdis_device* dev, const char* msg, ...) +{ + va_list vargs_list; + ASSERT(dev && msg); + + va_start(vargs_list, msg); + log_msg(dev, LOG_WARNING, msg, vargs_list); + va_end(vargs_list); +} + diff --git a/src/sdis_log.h b/src/sdis_log.h @@ -0,0 +1,72 @@ +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef SDIS_LOG_H +#define SDIS_LOG_H + +#include <rsys/rsys.h> + +#ifdef OS_UNIX + /* On UNIX assume a VT100-like terminal emulator */ + #define MSG_INFO_PREFIX "stardis-solver (\x1b[1m\x1b[32minfo\x1b[0m): " + #define MSG_ERROR_PREFIX "stardis-solver (\x1b[1m\x1b[31merror\x1b[0m): " + #define MSG_WARNING_PREFIX "stardis-solver (\x1b[1m\x1b[33mwarning\x1b[0m): " +#else + #define MSG_INFO_PREFIX "stardis-solver (info): " + #define MSG_ERROR_PREFIX "stardis-solver (error): " + #define MSG_WARNING_PREFIX "stardis-solver (warning): " +#endif + +extern LOCAL_SYM res_T +setup_log_default + (struct sdis_device* dev); + +/* Conditionally log a message on the LOG_OUTPUT stream of the sdis logger, + * with respect to its verbose flag */ +extern LOCAL_SYM void +log_info + (const struct sdis_device* dev, + const char* msg, + ...) +#ifdef COMPILER_GCC + __attribute((format(printf, 2, 3))) +#endif +; + +/* Conditionally log a message on the LOG_ERROR stream of the sdis logger, + * with respect to its verbose flag */ +extern LOCAL_SYM void +log_err + (const struct sdis_device* dev, + const char* msg, + ...) +#ifdef COMPILER_GCC + __attribute((format(printf, 2, 3))) +#endif +; + +/* Conditionally log a message on the LOG_WARNING stream of the sdis logger, + * with respect to its verbose flag */ +extern LOCAL_SYM void +log_warn + (const struct sdis_device* dev, + const char* msg, + ...) +#ifdef COMPILER_GCC + __attribute((format(printf, 2, 3))) +#endif +; + +#endif /* SDIS_LOG_H */ diff --git a/src/sdis_medium.c b/src/sdis_medium.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,6 +15,7 @@ #include "sdis.h" #include "sdis_device_c.h" +#include "sdis_log.h" #include "sdis_medium_c.h" #include <rsys/mem_allocator.h> diff --git a/src/sdis_medium_c.h b/src/sdis_medium_c.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/sdis_misc.h b/src/sdis_misc.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/sdis_realisation.c b/src/sdis_realisation.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/sdis_realisation.h b/src/sdis_realisation.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/sdis_realisation_Xd.h b/src/sdis_realisation_Xd.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,6 +16,7 @@ #include "sdis_device_c.h" #include "sdis_heat_path.h" #include "sdis_interface_c.h" +#include "sdis_log.h" #include "sdis_medium_c.h" #include "sdis_misc.h" #include "sdis_scene_c.h" @@ -80,10 +81,10 @@ XD(compute_temperature) * boundary. Indeed, one knows the "right" type of the first vertex only * after the boundary_path execution that defines the sub path to resolve * from the submitted boundary position. Note that if the boundary - * temperature is know, the type is let as it. */ - if(heat_vtx && !T->done) { - if(heat_path_get_last_vertex(ctx->heat_path) != heat_vtx) { - /* Path was reinjected into a solid */ + * temperature is known, the type is let as it. */ + if(heat_vtx && !T->done && T->func != XD(boundary_path)) { + heat_vtx = heat_path_get_last_vertex(ctx->heat_path); + if(T->func == XD(conductive_path)) { heat_vtx->type = SDIS_HEAT_VERTEX_CONDUCTION; } else if(T->func == XD(convective_path)) { heat_vtx->type = SDIS_HEAT_VERTEX_CONVECTION; @@ -174,7 +175,7 @@ XD(probe_realisation) /* The initial condition should have been reached */ log_err(scn->dev, "%s: undefined initial condition. " - "The time is %f but the temperature remains unknown.\n", + "The time is %g but the temperature remains unknown.\n", FUNC_NAME, t0); res = RES_BAD_OP; goto error; @@ -227,7 +228,7 @@ XD(boundary_realisation) float st[2]; #endif res_T res = RES_OK; - ASSERT(uv && fp_to_meter > 0 && weight && Tref >= 0 && time >= 0); + ASSERT(uv && fp_to_meter > 0 && weight && time >= 0); T.func = XD(boundary_path); rwalk.hit_side = side; diff --git a/src/sdis_scene.c b/src/sdis_scene.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -104,8 +104,8 @@ scene_release(ref_T * ref) htable_d_release(&scn->tmp_hc_ub); if(scn->s2d_view) S2D(scene_view_ref_put(scn->s2d_view)); if(scn->s3d_view) S3D(scene_view_ref_put(scn->s3d_view)); - if(scn->senc_descriptor) SENC(descriptor_ref_put(scn->senc_descriptor)); - if(scn->senc2d_descriptor) SENC2D(descriptor_ref_put(scn->senc2d_descriptor)); + if(scn->senc2d_scn) SENC2D(scene_ref_put(scn->senc2d_scn)); + if(scn->senc3d_scn) SENC3D(scene_ref_put(scn->senc3d_scn)); MEM_RM(dev->allocator, scn); SDIS(device_ref_put(dev)); } @@ -132,8 +132,8 @@ res_T sdis_scene_2d_create (struct sdis_device* dev, const size_t nsegs, /* #segments */ - void (*indices)(const size_t itri, size_t ids[2], void*), - void (*interf)(const size_t itri, struct sdis_interface** bound, void*), + void (*indices)(const size_t iseg, size_t ids[2], void*), + void (*interf)(const size_t iseg, struct sdis_interface** bound, void*), const size_t nverts, /* #vertices */ void (*position)(const size_t ivert, double pos[2], void* ctx), void* ctx, @@ -276,37 +276,26 @@ sdis_scene_boundary_project_position } res_T -sdis_scene_2d_get_analysis +sdis_scene_get_senc2d_scene (struct sdis_scene* scn, - struct senc2d_descriptor** descriptor) + struct senc2d_scene** senc2d_scn) { - if(!scn || !descriptor) return RES_BAD_ARG; - if(!scn->senc2d_descriptor) return RES_BAD_ARG; /* Scene is 3D */ - SENC2D(descriptor_ref_get(scn->senc2d_descriptor)); - *descriptor = scn->senc2d_descriptor; + if(!scn || !senc2d_scn) return RES_BAD_ARG; + if(!scn->senc2d_scn) return RES_BAD_ARG; /* Scene is 3D */ + SENC2D(scene_ref_get(scn->senc2d_scn)); + *senc2d_scn = scn->senc2d_scn; return RES_OK; } res_T -sdis_scene_get_analysis +sdis_scene_get_senc3d_scene (struct sdis_scene* scn, - struct senc_descriptor** descriptor) + struct senc3d_scene** senc3d_scn) { - if(!scn || !descriptor) return RES_BAD_ARG; - if(!scn->senc_descriptor) return RES_BAD_ARG; /* Scene is 2D */ - SENC(descriptor_ref_get(scn->senc_descriptor)); - *descriptor = scn->senc_descriptor; - return RES_OK; -} - -res_T -sdis_scene_release_analysis(struct sdis_scene* scn) -{ - if(!scn) return RES_BAD_ARG; - if(scn->senc2d_descriptor) SENC2D(descriptor_ref_put(scn->senc2d_descriptor)); - if(scn->senc_descriptor) SENC(descriptor_ref_put(scn->senc_descriptor)); - scn->senc_descriptor = NULL; - scn->senc2d_descriptor = NULL; + if(!scn || !senc3d_scn) return RES_BAD_ARG; + if(!scn->senc3d_scn) return RES_BAD_ARG; /* Scene is 2D */ + SENC3D(scene_ref_get(scn->senc3d_scn)); + *senc3d_scn = scn->senc3d_scn; return RES_OK; } diff --git a/src/sdis_scene_Xd.h b/src/sdis_scene_Xd.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,6 +19,7 @@ #define SDIS_SCENE_XD_H #include "sdis_interface_c.h" +#include "sdis_log.h" #include "sdis_medium_c.h" #include "sdis_scene_c.h" @@ -118,11 +119,12 @@ clear_properties(struct sdis_scene* scn) #include <limits.h> /* Check the submitted dimension and include its specific headers */ +#define SENCXD_DIM SDIS_SCENE_DIMENSION #if (SDIS_SCENE_DIMENSION == 2) - #include <star/senc2d.h> + #include <star/sencX2d.h> #include <star/s2d.h> #elif (SDIS_SCENE_DIMENSION == 3) - #include <star/senc.h> + #include <star/sencX3d.h> #include <star/s3d.h> #else #error "Invalid SDIS_SCENE_DIMENSION value." @@ -131,15 +133,6 @@ clear_properties(struct sdis_scene* scn) /* Syntactic sugar */ #define DIM SDIS_SCENE_DIMENSION -/* Star-Enc macros generic to the SDIS_SCENE_DIMENSION */ -#if DIM == 2 - #define sencXd(Name) CONCAT(senc2d_, Name) - #define SENCXD SENC2D -#else - #define sencXd(Name) CONCAT(senc_, Name) - #define SENCXD SENC -#endif - /* Star-XD macros generic to SDIS_SCENE_DIMENSION */ #define sXd(Name) CONCAT(CONCAT(CONCAT(s, DIM), d_), Name) #define SXD CONCAT(CONCAT(S, DIM), D) @@ -150,6 +143,7 @@ clear_properties(struct sdis_scene* scn) #define SXD_GET_PRIMITIVE CONCAT(CONCAT(S,DIM), D_GET_PRIMITIVE) #define SXD_HIT_NONE CONCAT(CONCAT(S,DIM), D_HIT_NONE) #define SXD_PRIMITIVE_EQ CONCAT(CONCAT(S,DIM), D_PRIMITIVE_EQ) +#define SXD_FLOATX CONCAT(CONCAT(CONCAT(S,DIM), D_FLOAT), DIM) /* Vector macros generic to SDIS_SCENE_DIMENSION */ #define fX(Func) CONCAT(CONCAT(CONCAT(f, DIM), _), Func) @@ -484,24 +478,20 @@ XD(geometry_position)(const unsigned ivert, double out_pos[DIM], void* data) /* Retrieve the indices of a primitive of a Star-EncXD descriptor */ static void -XD(descriptor_indices)(const unsigned iprim, unsigned ids[DIM], void* data) +XD(scene_indices)(const unsigned iprim, unsigned ids[DIM], void* data) { - struct sencXd(descriptor)* desc = data; -#if DIM == 2 - SENCXD(descriptor_get_global_segment(desc, iprim, ids)); -#else - SENCXD(descriptor_get_global_triangle(desc, iprim, ids)); -#endif + struct sencXd(scene)* scn = data; + SENCXD(scene_get_primitive(scn, iprim, ids)); } /* Retrieve the coordinates of a vertex of a Star-EncXD descriptor */ static void -XD(descriptor_position)(const unsigned ivert, float out_pos[DIM], void* data) +XD(scene_position)(const unsigned ivert, float out_pos[DIM], void* data) { - struct sencXd(descriptor)* desc = data; + struct sencXd(scene)* scn = data; double pos[3]; int i; - SENCXD(descriptor_get_global_vertex(desc, ivert, pos)); + SENCXD(scene_get_vertex(scn, ivert, pos)); FOR_EACH(i, 0, DIM) out_pos[i] = (float)pos[i]; } @@ -510,11 +500,7 @@ static void XD(enclosure_indices)(const unsigned iprim, unsigned ids[DIM], void* data) { struct sencXd(enclosure)* enc = data; -#if DIM == 2 - SENCXD(enclosure_get_segment(enc, iprim, ids)); -#else - SENCXD(enclosure_get_triangle(enc, iprim, ids)); -#endif + SENCXD(enclosure_get_primitive(enc, iprim, ids)); } /* Retrieve the coordinates of a vertex of a Star-EncXD encolsure */ @@ -542,54 +528,44 @@ XD(run_analyze) const size_t nverts, /* #vertices */ void (*position)(const size_t ivert, double pos[], void*), void* ctx, - struct sencXd(descriptor)** out_desc) + struct sencXd(scene)** out_scn) { struct geometry geom; struct sencXd(device)* senc = NULL; - struct sencXd(scene)* senc_scn = NULL; - struct sencXd(descriptor)* desc = NULL; + struct sencXd(scene)* senc3d_scn = NULL; + unsigned count; res_T res = RES_OK; - ASSERT(scn && nprims && indices && interf && nverts && position && out_desc); + ASSERT(scn && nprims && indices && interf && nverts && position && out_scn); res = sencXd(device_create)(scn->dev->logger, scn->dev->allocator, scn->dev->nthreads, scn->dev->verbose, &senc); if(res != RES_OK) goto error; - res = sencXd(scene_create)(senc, -#if DIM == 2 - SENC2D_CONVENTION_NORMAL_BACK | SENC2D_CONVENTION_NORMAL_OUTSIDE, -#else - SENC_CONVENTION_NORMAL_BACK | SENC_CONVENTION_NORMAL_OUTSIDE, -#endif - &senc_scn); - if(res != RES_OK) goto error; - /* Setup the geometry data */ geom.indices = indices; geom.interf = interf; geom.position = position; geom.data = ctx; - res = sencXd(scene_add_geometry) - (senc_scn, (unsigned)nprims, XD(geometry_indices), geometry_media, - (unsigned)nverts, XD(geometry_position), NULL, NULL, &geom); + res = sencXd(scene_create)(senc, + SENCXD_(CONVENTION_NORMAL_BACK) | SENCXD_(CONVENTION_NORMAL_OUTSIDE), + (unsigned)nprims, XD(geometry_indices), geometry_media, + (unsigned)nverts, XD(geometry_position), &geom, &senc3d_scn); if(res != RES_OK) goto error; - - /* Launch the scene analyze */ - res = sencXd(scene_analyze)(senc_scn, &desc); + /* With il-formed scenes, scene creation can success without being able + * to extract enclosures; in this case just fail */ + res = sencXd(scene_get_enclosure_count(senc3d_scn, &count)); if(res != RES_OK) goto error; exit: if(senc) SENCXD(device_ref_put(senc)); - if(senc_scn) SENCXD(scene_ref_put(senc_scn)); - if(out_desc) *out_desc = desc; + if(out_scn) *out_scn = senc3d_scn; return res; error: - if(desc) { - SENCXD(descriptor_ref_put(desc)); - desc = NULL; + if(senc3d_scn) { + SENCXD(scene_ref_put(senc3d_scn)); + senc3d_scn = NULL; } goto exit; - } /* Register the media and the interfaces, map each primitive to its interface @@ -598,45 +574,31 @@ error: static res_T XD(setup_properties) (struct sdis_scene* scn, - struct sencXd(descriptor)* desc, + struct sencXd(scene)* senc3d_scn, void (*interf)(const size_t itri, struct sdis_interface**, void*), void* ctx) { unsigned iprim, nprims; res_T res = RES_OK; - ASSERT(scn && interf); + ASSERT(scn && senc3d_scn && interf); clear_properties(scn); -#if DIM == 2 - SENCXD(descriptor_get_global_segments_count(desc, &nprims)); -#else - SENCXD(descriptor_get_global_triangles_count(desc, &nprims)); -#endif + SENCXD(scene_get_primitives_count(senc3d_scn, &nprims)); FOR_EACH(iprim, 0, nprims) { struct prim_prop* prim_prop; struct sdis_interface* itface; unsigned enclosures[2]; - unsigned iprim_adjusted; /* Primitive id in user space */ unsigned id; int i; double* enc_upper_bound; size_t ninterfaces; -#if DIM == 2 - /* Retrieve the segment id in user space */ - SENCXD(descriptor_get_global_segment_global_id(desc, iprim, &iprim_adjusted)); - /* Fetch the enclosures that the segment splits */ - SENCXD(descriptor_get_global_segment_enclosures(desc, iprim, enclosures)); -#else - /* Retrieve the triangle id in user space */ - SENCXD(descriptor_get_global_triangle_global_id(desc, iprim, &iprim_adjusted)); - /* Fetch the enclosures that the triangle splits */ - SENCXD(descriptor_get_global_triangle_enclosures(desc, iprim, enclosures)); -#endif + /* Fetch the enclosures that the segment/triangle splits */ + SENCXD(scene_get_primitive_enclosures(senc3d_scn, iprim, enclosures)); /* Fetch the interface of the primitive */ - interf(iprim_adjusted, &itface, ctx); + interf(iprim, &itface, ctx); /* Check that the interface is already registered against the scene */ id = interface_get_id(itface); @@ -689,7 +651,7 @@ error: /* Build the Star-XD scene view of the whole scene */ static res_T -XD(setup_scene_geometry)(struct sdis_scene* scn, struct sencXd(descriptor)* desc) +XD(setup_scene_geometry)(struct sdis_scene* scn, struct sencXd(scene)* senc3d_scn) { struct sXd(device)* sXd_dev = NULL; struct sXd(shape)* sXd_shape = NULL; @@ -697,36 +659,30 @@ XD(setup_scene_geometry)(struct sdis_scene* scn, struct sencXd(descriptor)* desc struct sXd(vertex_data) vdata = SXD_VERTEX_DATA_NULL; unsigned nprims, nverts; res_T res = RES_OK; - ASSERT(scn && desc); + ASSERT(scn && senc3d_scn); - SENCXD(descriptor_get_global_vertices_count(desc, &nverts)); + SENCXD(scene_get_vertices_count(senc3d_scn, &nverts)); /* Setup the vertex data */ vdata.usage = SXD_POSITION; -#if DIM == 2 - vdata.type = S2D_FLOAT2; -#else - vdata.type = S3D_FLOAT3; -#endif - vdata.get = XD(descriptor_position); + vdata.type = SXD_FLOATX; + vdata.get = XD(scene_position); /* Create the Star-XD geometry of the whole scene */ #define CALL(Func) { if(RES_OK != (res = Func)) goto error; } (void)0 + sXd_dev = scn->dev->sXd(dev); + SENCXD(scene_get_primitives_count(senc3d_scn, &nprims)); #if DIM == 2 - sXd_dev = scn->dev->s2d; - SENCXD(descriptor_get_global_segments_count(desc, &nprims)); CALL(sXd(shape_create_line_segments)(sXd_dev, &sXd_shape)); CALL(sXd(line_segments_set_hit_filter_function)(sXd_shape, XD(hit_filter_function), NULL)); CALL(sXd(line_segments_setup_indexed_vertices)(sXd_shape, nprims, - XD(descriptor_indices), nverts, &vdata, 1, desc)); + XD(scene_indices), nverts, &vdata, 1, senc3d_scn)); #else - sXd_dev = scn->dev->s3d; - SENCXD(descriptor_get_global_triangles_count(desc, &nprims)); CALL(sXd(shape_create_mesh)(sXd_dev, &sXd_shape)); CALL(sXd(mesh_set_hit_filter_function)(sXd_shape, XD(hit_filter_function), NULL)); - CALL(sXd(mesh_setup_indexed_vertices)(sXd_shape, nprims, XD(descriptor_indices), - nverts, &vdata, 1, desc)); + CALL(sXd(mesh_setup_indexed_vertices)(sXd_shape, nprims, XD(scene_indices), + nverts, &vdata, 1, senc3d_scn)); #endif CALL(sXd(scene_create)(sXd_dev, &sXd_scn)); CALL(sXd(scene_attach_shape)(sXd_scn, sXd_shape)); @@ -757,24 +713,15 @@ XD(setup_enclosure_geometry)(struct sdis_scene* scn, struct sencXd(enclosure)* e float S, V; double* p_ub; unsigned iprim, nprims, nverts; -#if DIM == 2 - struct senc2d_enclosure_header header; -#else - struct senc_enclosure_header header; -#endif + struct sencXd(enclosure_header) header; res_T res = RES_OK; ASSERT(scn && enc); enclosure_init(scn->dev->allocator, &enc_dummy); SENCXD(enclosure_get_header(enc, &header)); -#if DIM == 2 - sXd_dev = scn->dev->s2d; - nprims = header.segment_count; -#else - sXd_dev = scn->dev->s3d; - nprims = header.triangle_count; -#endif + sXd_dev = scn->dev->sXd(dev); + nprims = header.primitives_count; nverts = header.vertices_count; /* Register the enclosure into the scene. Use a dummy data on their @@ -791,11 +738,7 @@ XD(setup_enclosure_geometry)(struct sdis_scene* scn, struct sencXd(enclosure)* e /* Setup the vertex data */ vdata.usage = SXD_POSITION; -#if DIM == 2 - vdata.type = S2D_FLOAT2; -#else - vdata.type = S3D_FLOAT3; -#endif + vdata.type = SXD_FLOATX; vdata.get = XD(enclosure_position); /* Create the Star-XD geometry */ @@ -836,13 +779,8 @@ XD(setup_enclosure_geometry)(struct sdis_scene* scn, struct sencXd(enclosure)* e if(res != RES_OK) goto error; FOR_EACH(iprim, 0, nprims) { enum sencXd(side) side; -#if DIM == 2 - senc2d_enclosure_get_segment_global_id - (enc, iprim, darray_uint_data_get(&enc_data->local2global)+iprim, &side); -#else - senc_enclosure_get_triangle_global_id - (enc, iprim, darray_uint_data_get(&enc_data->local2global)+iprim, &side); -#endif + SENCXD(enclosure_get_primitive_id + (enc, iprim, darray_uint_data_get(&enc_data->local2global)+iprim, &side)); } /* Setup the medium id of the enclosure */ @@ -861,25 +799,21 @@ error: /* Build the Star-XD scene view and define its associated data of the finite * fluid enclosures */ static res_T -XD(setup_enclosures)(struct sdis_scene* scn, struct sencXd(descriptor)* desc) +XD(setup_enclosures)(struct sdis_scene* scn, struct sencXd(scene)* senc3d_scn) { struct sencXd(enclosure)* enc = NULL; unsigned ienc, nencs; unsigned enclosed_medium; int outer_found = 0; res_T res = RES_OK; - ASSERT(scn && desc); + ASSERT(scn && senc3d_scn); (void)outer_found; - SENCXD(descriptor_get_enclosure_count(desc, &nencs)); + SENCXD(scene_get_enclosure_count(senc3d_scn, &nencs)); FOR_EACH(ienc, 0, nencs) { -#if DIM == 2 - struct senc2d_enclosure_header header; -#else - struct senc_enclosure_header header; -#endif + struct sencXd(enclosure_header) header; - SENCXD(descriptor_get_enclosure(desc, ienc, &enc)); + SENCXD(scene_get_enclosure(senc3d_scn, ienc, &enc)); SENCXD(enclosure_get_header(enc, &header)); if(header.is_infinite) { @@ -891,37 +825,37 @@ XD(setup_enclosures)(struct sdis_scene* scn, struct sencXd(descriptor)* desc) /* As paths don't go in infinite enclosures we can accept models are broken * there. But nowhere else. */ if(header.enclosed_media_count != 1 && !header.is_infinite) { -#ifndef NDEBUG /* Dump the problematic enclosure. */ double tmp[DIM]; unsigned indices[DIM]; unsigned i; log_warn(scn->dev, "# Found internal enclosure with %u materials:\n", header.enclosed_media_count); - #if DIM == 2 + FOR_EACH(i, 0, header.enclosed_media_count) { + unsigned imed; + const struct sdis_medium* med; + SENCXD(enclosure_get_medium(enc, i, &imed)); + med = darray_medium_cdata_get(&scn->media)[imed]; + log_warn(scn->dev, "# %u (%s)\n", + imed, (med->type == SDIS_SOLID ? "solid" : "fluid")); + } FOR_EACH(i, 0, header.vertices_count) { SENCXD(enclosure_get_vertex(enc, i, tmp)); + #if DIM == 2 log_warn(scn->dev, "v %g %g\n", SPLIT2(tmp)); - } - FOR_EACH(i, 0, header.segment_count) { - ASSERT(senc2d_enclosure_get_segment(enc, i, indices) == RES_OK); - log_warn(scn->dev, "f %u %u\n", indices[0]+1, indices[1]+1); - } #else - FOR_EACH(i, 0, header.vertices_count) { - SENCXD(enclosure_get_vertex(enc, i, tmp)); log_warn(scn->dev, "v %g %g %g\n", SPLIT3(tmp)); + #endif } - FOR_EACH(i, 0, header.triangle_count) { - ASSERT(senc_enclosure_get_triangle(enc, i, indices) == RES_OK); + FOR_EACH(i, 0, header.primitives_count) { + SENCXD(enclosure_get_primitive(enc, i, indices)); + #if DIM == 2 + log_warn(scn->dev, "f %u %u\n", indices[0]+1, indices[1]+1); + #else log_warn(scn->dev, "f %u %u %u\n", indices[0]+1, indices[1]+1, indices[2]+1); - } #endif -#else - log_warn(scn->dev, "Found internal enclosure with %u materials.\n", - header.enclosed_media_count); -#endif + } SENCXD(enclosure_ref_put(enc)); enc = NULL; res = RES_BAD_ARG; @@ -961,7 +895,7 @@ XD(scene_create) void* ctx, struct sdis_scene** out_scn) { - struct sencXd(descriptor)* desc = NULL; + struct sencXd(scene)* senc3d_scn = NULL; struct sdis_scene* scn = NULL; res_T res = RES_OK; @@ -988,38 +922,34 @@ XD(scene_create) htable_enclosure_init(dev->allocator, &scn->enclosures); htable_d_init(dev->allocator, &scn->tmp_hc_ub); - res = XD(run_analyze)(scn, nprims, indices, interf, nverts, position, ctx, &desc); + res = XD(run_analyze)(scn, nprims, indices, interf, nverts, position, ctx, &senc3d_scn); if(res != RES_OK) { log_err(dev, "%s: error during the scene analysis.\n", FUNC_NAME); goto error; } - res = XD(setup_properties)(scn, desc, interf, ctx); + res = XD(setup_properties)(scn, senc3d_scn, interf, ctx); if(res != RES_OK) { log_err(dev, "%s: could not setup the scene interfaces and their media.\n", FUNC_NAME); goto error; } - res = XD(setup_scene_geometry)(scn, desc); + res = XD(setup_scene_geometry)(scn, senc3d_scn); if(res != RES_OK) { log_err(dev, "%s: could not setup the scene geometry.\n", FUNC_NAME); goto error; } - res = XD(setup_enclosures)(scn, desc); + res = XD(setup_enclosures)(scn, senc3d_scn); if(res != RES_OK) { log_err(dev, "%s: could not setup the enclosures.\n", FUNC_NAME); goto error; } -#if DIM==2 - scn->senc2d_descriptor = desc; -#else - scn->senc_descriptor = desc; -#endif + scn->sencXd(scn) = senc3d_scn; exit: if(out_scn) *out_scn = scn; return res; error: - if(desc) SENCXD(descriptor_ref_put(desc)); + if(senc3d_scn) SENCXD(scene_ref_put(senc3d_scn)); if(scn) { SDIS(scene_ref_put(scn)); scn = NULL; @@ -1237,10 +1167,14 @@ error: goto exit; } +#if (SDIS_SCENE_DIMENSION == 2) +#include <star/sencX2d_undefs.h> +#else /* SDIS_SCENE_DIMENSION == 3 */ +#include <star/sencX3d_undefs.h> +#endif + #undef SDIS_SCENE_DIMENSION #undef DIM -#undef sencXd -#undef SENCXD #undef sXd #undef SXD #undef SXD_VERTEX_DATA_NULL @@ -1251,6 +1185,7 @@ error: #undef SXD_GET_PRIMITIVE #undef SXD_HIT_NONE #undef SXD_PRIMITIVE_EQ +#undef SXD_FLOATX #undef fX #undef fX_set_dX #undef fXX_mulfX diff --git a/src/sdis_scene_c.h b/src/sdis_scene_c.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -200,8 +200,8 @@ struct sdis_scene { struct darray_prim_prop prim_props; /* Per primitive properties */ struct s2d_scene_view* s2d_view; struct s3d_scene_view* s3d_view; - struct senc_descriptor* senc_descriptor; - struct senc2d_descriptor* senc2d_descriptor; + struct senc2d_scene* senc2d_scn; + struct senc3d_scene* senc3d_scn; struct htable_d tmp_hc_ub; /* Map an enclosure id to its hc upper bound */ struct htable_enclosure enclosures; /* Map an enclosure id to its data */ diff --git a/src/sdis_solve.c b/src/sdis_solve.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -79,6 +79,7 @@ solve_pixel { struct accum acc_temp = ACCUM_NULL; struct accum acc_time = ACCUM_NULL; + struct sdis_heat_path* pheat_path = NULL; size_t irealisation; res_T res = RES_OK; ASSERT(scn && mdm && rng && cam && ipix && nrealisations && Tref >= 0); @@ -91,7 +92,6 @@ solve_pixel double ray_pos[3]; double ray_dir[3]; double w = 0; - struct sdis_heat_path* pheat_path = NULL; struct sdis_heat_path heat_path; double time; res_T res_simul = RES_OK; @@ -125,15 +125,17 @@ solve_pixel if(pheat_path) { pheat_path->status = res_simul == RES_OK - ? SDIS_HEAT_PATH_SUCCEED - : SDIS_HEAT_PATH_FAILED; + ? SDIS_HEAT_PATH_SUCCESS + : SDIS_HEAT_PATH_FAILURE; /* Check if the path must be saved regarding the register_paths mask */ if(!(register_paths & (int)pheat_path->status)) { heat_path_release(pheat_path); + pheat_path = NULL; } else { /* Register the sampled path */ res = estimator_add_and_release_heat_path(estimator, pheat_path); if(res != RES_OK) goto error; + pheat_path = NULL; } } @@ -155,6 +157,7 @@ solve_pixel estimator_setup_realisation_time(estimator, acc_time.sum, acc_time.sum2); exit: + if(pheat_path) heat_path_release(pheat_path); return res; error: goto exit; @@ -220,195 +223,119 @@ error: res_T sdis_solve_probe (struct sdis_scene* scn, - const size_t nrealisations, - const double position[3], - const double time_range[2], - const double fp_to_meter,/* Scale factor from floating point unit to meter */ - const double Tarad, /* Ambient radiative temperature */ - const double Tref, /* Reference temperature */ - const int register_paths, /* Combination of enum sdis_heat_path_flag */ + const struct sdis_solve_probe_args* args, struct sdis_estimator** out_estimator) { if(!scn) return RES_BAD_ARG; if(scene_is_2d(scn)) { - return solve_probe_2d(scn, nrealisations, position, time_range, - fp_to_meter, Tarad, Tref, register_paths, NULL, out_estimator); + return solve_probe_2d(scn, args, NULL, out_estimator); } else { - return solve_probe_3d(scn, nrealisations, position, time_range, - fp_to_meter, Tarad, Tref, register_paths, NULL, out_estimator); + return solve_probe_3d(scn, args, NULL, out_estimator); } } res_T sdis_solve_probe_green_function (struct sdis_scene* scn, - const size_t nrealisations, - const double position[3], - const double fp_to_meter,/* Scale factor from floating point unit to meter */ - const double Tarad, /* Ambient radiative temperature */ - const double Tref, /* Reference temperature */ + const struct sdis_solve_probe_args* args, struct sdis_green_function** out_green) { if(!scn) return RES_BAD_ARG; if(scene_is_2d(scn)) { - return solve_probe_2d(scn, nrealisations, position, NULL, - fp_to_meter, Tarad, Tref, SDIS_HEAT_PATH_NONE, out_green, NULL); + return solve_probe_2d(scn, args, out_green, NULL); } else { - return solve_probe_3d(scn, nrealisations, position, NULL, - fp_to_meter, Tarad, Tref, SDIS_HEAT_PATH_NONE, out_green, NULL); + return solve_probe_3d(scn, args, out_green, NULL); } } res_T sdis_solve_probe_boundary (struct sdis_scene* scn, - const size_t nrealisations, /* #realisations */ - const size_t iprim, /* Identifier of the primitive on which the probe lies */ - const double uv[2], /* Parametric coordinates of the probe onto the primitve */ - const double time_range[2], /* Observation time */ - const enum sdis_side side, /* Side of iprim on which the probe lies */ - const double fp_to_meter, /* Scale from floating point units to meters */ - const double Tarad, /* In Kelvin */ - const double Tref, /* In Kelvin */ - const int register_paths, /* Combination of enum sdis_heat_path_flag */ + const struct sdis_solve_probe_boundary_args* args, struct sdis_estimator** out_estimator) { if(!scn) return RES_BAD_ARG; if(scene_is_2d(scn)) { - return solve_probe_boundary_2d(scn, nrealisations, iprim, uv, time_range, - side, fp_to_meter, Tarad, Tref, register_paths, NULL, out_estimator); + return solve_probe_boundary_2d(scn, args, NULL, out_estimator); } else { - return solve_probe_boundary_3d(scn, nrealisations, iprim, uv, time_range, - side, fp_to_meter, Tarad, Tref, register_paths, NULL, out_estimator); + return solve_probe_boundary_3d(scn, args, NULL, out_estimator); } } res_T sdis_solve_probe_boundary_green_function (struct sdis_scene* scn, - const size_t nrealisations, /* #realisations */ - const size_t iprim, /* Identifier of the primitive on which the probe lies */ - const double uv[2], /* Parametric coordinates of the probe onto the primitve */ - const enum sdis_side side, /* Side of iprim on which the probe lies */ - const double fp_to_meter, /* Scale from floating point units to meters */ - const double Tarad, /* In Kelvin */ - const double Tref, /* In Kelvin */ + const struct sdis_solve_probe_boundary_args* args, struct sdis_green_function** green) { if(!scn) return RES_BAD_ARG; if(scene_is_2d(scn)) { - return solve_probe_boundary_2d(scn, nrealisations, iprim, uv, NULL, - side, fp_to_meter, Tarad, Tref, SDIS_HEAT_PATH_NONE, green, NULL); + return solve_probe_boundary_2d(scn, args, green, NULL); } else { - return solve_probe_boundary_3d(scn, nrealisations, iprim, uv, NULL, - side, fp_to_meter, Tarad, Tref, SDIS_HEAT_PATH_NONE, green, NULL); + return solve_probe_boundary_3d(scn, args, green, NULL); } } res_T sdis_solve_boundary (struct sdis_scene* scn, - const size_t nrealisations, /* #realisations */ - const size_t primitives[], /* List of boundary primitives to handle */ - const enum sdis_side sides[], /* Per primitive side to consider */ - const size_t nprimitives, /* #primitives */ - const double time_range[2], /* Observation time */ - const double fp_to_meter, /* Scale from floating point units to meters */ - const double Tarad, /* In Kelvin */ - const double Tref, /* In Kelvin */ - const int register_paths, /* Combination of enum sdis_heat_path_flag */ + const struct sdis_solve_boundary_args* args, struct sdis_estimator** out_estimator) { if(!scn) return RES_BAD_ARG; if(scene_is_2d(scn)) { - return solve_boundary_2d(scn, nrealisations, primitives, sides, nprimitives, - time_range, fp_to_meter, Tarad, Tref, register_paths, NULL, out_estimator); + return solve_boundary_2d(scn, args, NULL, out_estimator); } else { - return solve_boundary_3d(scn, nrealisations, primitives, sides, nprimitives, - time_range, fp_to_meter, Tarad, Tref, register_paths, NULL, out_estimator); + return solve_boundary_3d(scn, args, NULL, out_estimator); } } res_T sdis_solve_boundary_green_function (struct sdis_scene* scn, - const size_t nrealisations, /* #realisations */ - const size_t primitives[], /* List of boundary primitives to handle */ - const enum sdis_side sides[], /* Per primitive side to consider */ - const size_t nprimitives, /* #primitives */ - const double fp_to_meter, /* Scale from floating point units to meters */ - const double Tarad, /* In Kelvin */ - const double Tref, /* In Kelvin */ + const struct sdis_solve_boundary_args* args, struct sdis_green_function** green) { if(!scn) return RES_BAD_ARG; if(scene_is_2d(scn)) { - return solve_boundary_2d(scn, nrealisations, primitives, sides, - nprimitives, NULL, fp_to_meter, Tarad, Tref, SDIS_HEAT_PATH_NONE, green, - NULL); + return solve_boundary_2d(scn, args, green, NULL); } else { - return solve_boundary_3d(scn, nrealisations, primitives, sides, - nprimitives, NULL, fp_to_meter, Tarad, Tref, SDIS_HEAT_PATH_NONE, green, - NULL); + return solve_boundary_3d(scn, args, green, NULL); } } res_T sdis_solve_probe_boundary_flux (struct sdis_scene* scn, - const size_t nrealisations, /* #realisations */ - const size_t iprim, /* Identifier of the primitive on which the probe lies */ - const double uv[2], /* Parametric coordinates of the probe onto the primitve */ - const double time_range[2], /* Observation time */ - const double fp_to_meter, /* Scale from floating point units to meters */ - const double Tarad, /* In Kelvin */ - const double Tref, /* In Kelvin */ + const struct sdis_solve_probe_boundary_flux_args* args, struct sdis_estimator** out_estimator) { if(!scn) return RES_BAD_ARG; if(scene_is_2d(scn)) { - return solve_probe_boundary_flux_2d(scn, nrealisations, iprim, uv, - time_range, fp_to_meter, Tarad, Tref, out_estimator); + return solve_probe_boundary_flux_2d(scn, args, out_estimator); } else { - return solve_probe_boundary_flux_3d(scn, nrealisations, iprim, uv, - time_range, fp_to_meter, Tarad, Tref, out_estimator); + return solve_probe_boundary_flux_3d(scn, args, out_estimator); } } res_T sdis_solve_boundary_flux (struct sdis_scene* scn, - const size_t nrealisations, /* #realisations */ - const size_t primitives[], /* List of boundary primitives to handle */ - const size_t nprimitives, /* #primitives */ - const double time_range[2], /* Observation time */ - const double fp_to_meter, /* Scale from floating point units to meters */ - const double Tarad, /* In Kelvin */ - const double Tref, /* In Kelvin */ + const struct sdis_solve_boundary_flux_args* args, struct sdis_estimator** out_estimator) { if(!scn) return RES_BAD_ARG; if(scene_is_2d(scn)) { - return solve_boundary_flux_2d(scn, nrealisations, primitives, nprimitives, - time_range, fp_to_meter, Tarad, Tref, out_estimator); + return solve_boundary_flux_2d(scn, args, out_estimator); } else { - return solve_boundary_flux_3d(scn, nrealisations, primitives, nprimitives, - time_range, fp_to_meter, Tarad, Tref, out_estimator); + return solve_boundary_flux_3d(scn, args, out_estimator); } } res_T sdis_solve_camera (struct sdis_scene* scn, - const struct sdis_camera* cam, - const double time_range[2], - const double fp_to_meter, /* Scale from floating point units to meters */ - const double Tarad, /* In Kelvin */ - const double Tref, /* In Kelvin */ - const size_t width, /* #pixels in X */ - const size_t height, /* #pixels in Y */ - const size_t spp, /* #samples per pixel */ - const int register_paths, /* Combination of enum sdis_heat_path_flag */ + const struct sdis_solve_camera_args* args, struct sdis_estimator_buffer** out_buf) { #define TILE_SIZE 32 /* definition in X & Y of a tile */ @@ -427,30 +354,40 @@ sdis_solve_camera size_t nsuccesses; size_t ix, iy; size_t i; + int progress = 0; + ATOMIC nsolved_tiles = 0; ATOMIC res = RES_OK; - if(!scn || !cam || fp_to_meter <= 0 || Tref < 0 || !width || !height || !spp - || !out_buf) { + if(!scn + || !args + || !out_buf + || !args->cam + || args->fp_to_meter <= 0 + || !args->image_resolution[0] + || !args->image_resolution[1] + || !args->spp + || args->ambient_radiative_temperature < 0 + || args->reference_temperature < 0 + || args->time_range[0] < 0 + || args->time_range[1] < args->time_range[0] + || ( args->time_range[1] > DBL_MAX + && args->time_range[0] != args->time_range[1])) { res = RES_BAD_ARG; goto error; } + if(scene_is_2d(scn)) { log_err(scn->dev, "%s: 2D scene are not supported.\n", FUNC_NAME); goto error; } - if(!time_range || time_range[0] < 0 || time_range[1] < time_range[0] - || (time_range[1] > DBL_MAX && time_range[0] != time_range[1])) { - res = RES_BAD_ARG; - goto error; - } /* Retrieve the medium in which the submitted position lies */ - res = scene_get_medium(scn, cam->position, NULL, &medium); + res = scene_get_medium(scn, args->cam->position, NULL, &medium); if(res != RES_OK) goto error; if(medium->type != SDIS_FLUID) { log_err(scn->dev, "%s: the camera position `%g %g %g' is not in a fluid.\n", - FUNC_NAME, SPLIT3(cam->position)); + FUNC_NAME, SPLIT3(args->cam->position)); res = RES_BAD_ARG; goto error; } @@ -472,16 +409,17 @@ sdis_solve_camera if(res != RES_OK) goto error; } - ntiles_x = (width + (TILE_SIZE-1)/*ceil*/)/TILE_SIZE; - ntiles_y = (height + (TILE_SIZE-1)/*ceil*/)/TILE_SIZE; + ntiles_x = (args->image_resolution[0] + (TILE_SIZE-1)/*ceil*/)/TILE_SIZE; + ntiles_y = (args->image_resolution[1] + (TILE_SIZE-1)/*ceil*/)/TILE_SIZE; ntiles = round_up_pow2(MMAX(ntiles_x, ntiles_y)); ntiles *= ntiles; - pix_sz[0] = 1.0 / (double)width; - pix_sz[1] = 1.0 / (double)height; + pix_sz[0] = 1.0 / (double)args->image_resolution[0]; + pix_sz[1] = 1.0 / (double)args->image_resolution[1]; /* Create the global estimator */ - res = estimator_buffer_create(scn->dev, width, height, &buf); + res = estimator_buffer_create + (scn->dev, args->image_resolution[0], args->image_resolution[1], &buf); if(res != RES_OK) goto error; omp_set_num_threads((int)scn->dev->nthreads); @@ -491,6 +429,8 @@ sdis_solve_camera size_t tile_sz[2] = {0, 0}; const int ithread = omp_get_thread_num(); struct ssp_rng* rng = rngs[ithread]; + size_t n; + int pcent; res_T res_local = RES_OK; if(ATOMIC_GET(&res) != RES_OK) continue; @@ -503,24 +443,39 @@ sdis_solve_camera /* Setup the tile coordinates in the image plane */ tile_org[0] *= TILE_SIZE; tile_org[1] *= TILE_SIZE; - tile_sz[0] = MMIN(TILE_SIZE, width - tile_org[0]); - tile_sz[1] = MMIN(TILE_SIZE, height - tile_org[1]); + tile_sz[0] = MMIN(TILE_SIZE, args->image_resolution[0] - tile_org[0]); + tile_sz[1] = MMIN(TILE_SIZE, args->image_resolution[1] - tile_org[1]); /* Draw the tile */ - res_local = solve_tile(scn, rng, medium, cam, time_range, fp_to_meter, - Tarad, Tref, tile_org, tile_sz, spp, register_paths, pix_sz, buf); + res_local = solve_tile(scn, rng, medium, args->cam, args->time_range, + args->fp_to_meter, args->ambient_radiative_temperature, + args->reference_temperature, tile_org, tile_sz, args->spp, + args->register_paths, pix_sz, buf); if(res_local != RES_OK) { ATOMIC_SET(&res, res_local); continue; } + + /* Update progress */ + n = (size_t)ATOMIC_INCR(&nsolved_tiles); + pcent = (int)((double)n*100.0 / (double)(ntiles_x*ntiles_y) + 0.5/*round*/); + #pragma omp critical + if(pcent > progress) { + progress = pcent; + log_info(scn->dev, "Infrared rendering: %3d%%\r", progress); + } } + if(res != RES_OK) goto error; + + /* Add a new line after the progress status */ + log_info(scn->dev, "Infrared rendering: %3d%%\n", progress); /* Setup the accumulators of the whole estimator buffer */ acc_temp = ACCUM_NULL; acc_time = ACCUM_NULL; nsuccesses = 0; - FOR_EACH(iy, 0, height) { - FOR_EACH(ix, 0, width) { + FOR_EACH(iy, 0, args->image_resolution[1]) { + FOR_EACH(ix, 0, args->image_resolution[0]) { const struct sdis_estimator* estimator; SDIS(estimator_buffer_at(buf, ix, iy, &estimator)); acc_temp.sum += estimator->temperature.sum; @@ -533,12 +488,14 @@ sdis_solve_camera } } - nrealisations = width*height*spp; + nrealisations = args->image_resolution[0]*args->image_resolution[1]*args->spp; ASSERT(acc_temp.count == acc_time.count); ASSERT(acc_temp.count == nsuccesses); estimator_buffer_setup_realisations_count(buf, nrealisations, nsuccesses); estimator_buffer_setup_temperature(buf, acc_temp.sum, acc_temp.sum2); estimator_buffer_setup_realisation_time(buf, acc_time.sum, acc_time.sum2); + res = estimator_buffer_save_rng_state(buf, rng_proxy); + if(res != RES_OK) goto error; exit: if(rngs) { @@ -551,48 +508,35 @@ exit: if(out_buf) *out_buf = buf; return (res_T)res; error: + if(buf) SDIS(estimator_buffer_ref_put(buf)); goto exit; } res_T sdis_solve_medium (struct sdis_scene* scn, - const size_t nrealisations, /* #realisations */ - struct sdis_medium* medium, /* Medium to solve */ - const double time_range[2], /* Observation time */ - const double fp_to_meter, /* Scale from floating point units to meters */ - const double Tarad, /* In Kelvin */ - const double Tref, /* In Kelvin */ - const int register_paths, /* Combination of enum sdis_heat_path_flag */ + const struct sdis_solve_medium_args* args, struct sdis_estimator** estimator) { if(!scn) return RES_BAD_ARG; if(scene_is_2d(scn)) { - return solve_medium_2d(scn, nrealisations, medium, time_range, fp_to_meter, - Tarad, Tref, register_paths, NULL, estimator); + return solve_medium_2d(scn, args, NULL, estimator); } else { - return solve_medium_3d(scn, nrealisations, medium, time_range, fp_to_meter, - Tarad, Tref, register_paths, NULL, estimator); + return solve_medium_3d(scn, args, NULL, estimator); } } res_T sdis_solve_medium_green_function (struct sdis_scene* scn, - const size_t nrealisations, /* #realisations */ - struct sdis_medium* medium, /* Medium to solve */ - const double fp_to_meter, /* Scale from floating point units to meters */ - const double Tarad, /* In Kelvin */ - const double Tref, /* In Kelvin */ + const struct sdis_solve_medium_args* args, struct sdis_green_function** green) { if(!scn) return RES_BAD_ARG; if(scene_is_2d(scn)) { - return solve_medium_2d(scn, nrealisations, medium, NULL, fp_to_meter, Tarad, - Tref, SDIS_HEAT_PATH_NONE, green, NULL); + return solve_medium_2d(scn, args, green, NULL); } else { - return solve_medium_3d(scn, nrealisations, medium, NULL, fp_to_meter, Tarad, - Tref, SDIS_HEAT_PATH_NONE, green, NULL); + return solve_medium_3d(scn, args, green, NULL); } } diff --git a/src/sdis_solve_boundary_Xd.h b/src/sdis_solve_boundary_Xd.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -62,12 +62,11 @@ XD(boundary_get_position)(const unsigned ivert, float pos[DIM], void* context) iprim = (unsigned)ctx->primitives[iprim_id]; SXD(scene_view_get_primitive(ctx->view, iprim, &prim)); #if DIM == 2 - s2d_segment_get_vertex_attrib(&prim, iprim_vert, S2D_POSITION, &attr); - ASSERT(attr.type == S2D_FLOAT2); + s2d_segment_get_vertex_attrib(&prim, iprim_vert, SXD_POSITION, &attr); #else - s3d_triangle_get_vertex_attrib(&prim, iprim_vert, S3D_POSITION, &attr); - ASSERT(attr.type == S3D_FLOAT3); + s3d_triangle_get_vertex_attrib(&prim, iprim_vert, SXD_POSITION, &attr); #endif + ASSERT(attr.type == SXD_FLOATX); fX(set)(pos, attr.value); } @@ -77,15 +76,7 @@ XD(boundary_get_position)(const unsigned ivert, float pos[DIM], void* context) static res_T XD(solve_boundary) (struct sdis_scene* scn, - const size_t nrealisations, /* #realisations */ - const size_t primitives[], /* List of boundary primitives to handle */ - const enum sdis_side sides[], /* Per primitive side to consider */ - const size_t nprimitives, /* #primitives */ - const double time_range[2], /* Observation time */ - const double fp_to_meter, /* Scale from floating point units to meters */ - const double Tarad, /* In Kelvin */ - const double Tref, /* In Kelvin */ - const int register_paths, /* Combination of enum sdis_heat_path_flag */ + const struct sdis_solve_boundary_args* args, struct sdis_green_function** out_green, struct sdis_estimator** out_estimator) { @@ -101,13 +92,18 @@ XD(solve_boundary) struct ssp_rng** rngs = NULL; struct accum* acc_temps = NULL; struct accum* acc_times = NULL; + size_t nrealisations = 0; + int64_t irealisation = 0; size_t i; size_t view_nprims; - int64_t irealisation; + int progress = 0; + int register_paths = SDIS_HEAT_PATH_NONE; + ATOMIC nsolved_realisations = 0; ATOMIC res = RES_OK; - if(!scn || !nrealisations || nrealisations > INT64_MAX || !primitives - || !sides || !nprimitives || fp_to_meter <= 0 || Tref < 0) { + if(!scn || !args || !args->nrealisations || args->nrealisations > INT64_MAX + || !args->primitives || !args->sides || !args->nprimitives + || args->fp_to_meter <= 0) { res = RES_BAD_ARG; goto error; } @@ -116,8 +112,10 @@ XD(solve_boundary) goto error; } if(out_estimator) { - if(!time_range || time_range[0] < 0 || time_range[1] < time_range[0] - || (time_range[1] > DBL_MAX && time_range[0] != time_range[1])) { + if(args->time_range[0] < 0 + || args->time_range[1] < args->time_range[0] + || ( args->time_range[1] > DBL_MAX + && args->time_range[0] != args->time_range[1])) { res = RES_BAD_ARG; goto error; } @@ -130,45 +128,54 @@ XD(solve_boundary) #endif SXD(scene_view_primitives_count(scn->sXd(view), &view_nprims)); - FOR_EACH(i, 0, nprimitives) { - if(primitives[i] >= view_nprims) { + FOR_EACH(i, 0, args->nprimitives) { + if(args->primitives[i] >= view_nprims) { log_err(scn->dev, "%s: invalid primitive identifier `%lu'. It must be in the [0 %lu] range.\n", FUNC_NAME, - (unsigned long)primitives[i], + (unsigned long)args->primitives[i], (unsigned long)scene_get_primitives_count(scn)-1); res = RES_BAD_ARG; goto error; } + if((unsigned)args->sides[i] >= SDIS_SIDE_NULL__) { + log_err(scn->dev, + "%s: invalid side for the primitive `%lu'.\n", + FUNC_NAME, (unsigned long)args->primitives[i]); + res = RES_BAD_ARG; + goto error; + } } /* Create the Star-XD shape of the boundary */ #if SDIS_XD_DIMENSION == 2 - res = s2d_shape_create_line_segments(scn->dev->sXd_dev, &shape); + res = s2d_shape_create_line_segments(scn->dev->sXd(dev), &shape); #else - res = s3d_shape_create_mesh(scn->dev->sXd_dev, &shape); + res = s3d_shape_create_mesh(scn->dev->sXd(dev), &shape); #endif if(res != RES_OK) goto error; /* Initialise the boundary shape with the triangles/segments of the * submitted primitives */ - ctx.primitives = primitives; + ctx.primitives = args->primitives; ctx.view = scn->sXd(view); vdata.usage = SXD_POSITION; vdata.get = XD(boundary_get_position); #if SDIS_XD_DIMENSION == 2 vdata.type = S2D_FLOAT2; - res = s2d_line_segments_setup_indexed_vertices(shape, (unsigned)nprimitives, - boundary_get_indices_2d, (unsigned)(nprimitives*2), &vdata, 1, &ctx); + res = s2d_line_segments_setup_indexed_vertices(shape, + (unsigned)args->nprimitives, boundary_get_indices_2d, + (unsigned)(args->nprimitives*2), &vdata, 1, &ctx); #else vdata.type = S3D_FLOAT3; - res = s3d_mesh_setup_indexed_vertices(shape, (unsigned)nprimitives, - boundary_get_indices_3d, (unsigned)(nprimitives*3), &vdata, 1, &ctx); + res = s3d_mesh_setup_indexed_vertices(shape, + (unsigned)args->nprimitives, boundary_get_indices_3d, + (unsigned)(args->nprimitives*3), &vdata, 1, &ctx); #endif if(res != RES_OK) goto error; /* Create and setup the boundary Star-XD scene */ - res = sXd(scene_create)(scn->dev->sXd_dev, &scene); + res = sXd(scene_create)(scn->dev->sXd(dev), &scene); if(res != RES_OK) goto error; res = sXd(scene_attach_shape)(scene, shape); if(res != RES_OK) goto error; @@ -176,9 +183,15 @@ XD(solve_boundary) if(res != RES_OK) goto error; /* Create the proxy RNG */ - res = ssp_rng_proxy_create(scn->dev->allocator, &ssp_rng_mt19937_64, - scn->dev->nthreads, &rng_proxy); - if(res != RES_OK) goto error; + if(args->rng_state) { + res = ssp_rng_proxy_create_from_rng(scn->dev->allocator, args->rng_state, + scn->dev->nthreads, &rng_proxy); + if(res != RES_OK) goto error; + } else { + res = ssp_rng_proxy_create(scn->dev->allocator, &ssp_rng_mt19937_64, + scn->dev->nthreads, &rng_proxy); + if(res != RES_OK) goto error; + } /* Create the per thread RNG */ rngs = MEM_CALLOC(scn->dev->allocator, scn->dev->nthreads, sizeof(*rngs)); @@ -212,6 +225,8 @@ XD(solve_boundary) if(res != RES_OK) goto error; } + nrealisations = args->nrealisations; + register_paths = out_estimator ? args->register_paths : SDIS_HEAT_PATH_NONE; omp_set_num_threads((int)scn->dev->nthreads); #pragma omp parallel for schedule(static) for(irealisation=0; irealisation<(int64_t)nrealisations; ++irealisation) { @@ -231,6 +246,8 @@ XD(solve_boundary) double uv[DIM-1]; float st[DIM-1]; double time; + size_t n; + int pcent; res_T res_local = RES_OK; res_T res_simul = RES_OK; @@ -240,7 +257,7 @@ XD(solve_boundary) time_current(&t0); if(!out_green) { - time = sample_time(rng, time_range); + time = sample_time(rng, args->time_range); if(register_paths) { heat_path_init(scn->dev->allocator, &heat_path); pheat_path = &heat_path; @@ -250,7 +267,10 @@ XD(solve_boundary) * function. Simply takes 0 as relative time */ time = 0; res_local = green_function_create_path(greens[ithread], &green_path); - if(res_local != RES_OK) { ATOMIC_SET(&res, res_local); continue; } + if(res_local != RES_OK) { + ATOMIC_SET(&res, res_local); + goto error_it; + } pgreen_path = &green_path; } @@ -271,35 +291,44 @@ XD(solve_boundary) &prim, st); d2_set_f2(uv, st); #endif - if(res_local != RES_OK) { ATOMIC_SET(&res, res_local); continue; } + if(res_local != RES_OK) { + ATOMIC_SET(&res, res_local); + goto error_it; + } /* Map from boundary scene to sdis scene */ - ASSERT(prim.prim_id < nprimitives); - iprim = primitives[prim.prim_id]; - side = sides[prim.prim_id]; + ASSERT(prim.prim_id < args->nprimitives); + iprim = args->primitives[prim.prim_id]; + side = args->sides[prim.prim_id]; /* Invoke the boundary realisation */ res_simul = XD(boundary_realisation)(scn, rng, iprim, uv, time, side, - fp_to_meter, Tarad, Tref, pgreen_path, pheat_path, &w); + args->fp_to_meter, args->ambient_radiative_temperature, + args->reference_temperature, pgreen_path, pheat_path, &w); /* Fatal error */ if(res_simul != RES_OK && res_simul != RES_BAD_OP) { ATOMIC_SET(&res, res_simul); - continue; + goto error_it; } /* Register heat path */ if(pheat_path) { pheat_path->status = res_simul == RES_OK - ? SDIS_HEAT_PATH_SUCCEED - : SDIS_HEAT_PATH_FAILED; + ? SDIS_HEAT_PATH_SUCCESS + : SDIS_HEAT_PATH_FAILURE; /* Check if the path must be saved regarding the register_paths mask */ if(!(register_paths & (int)pheat_path->status)) { heat_path_release(pheat_path); + pheat_path = NULL; } else { /* Register the sampled path */ res_local = estimator_add_and_release_heat_path(estimator, pheat_path); - if(res_local != RES_OK) { ATOMIC_SET(&res, res_local); continue; } + if(res_local != RES_OK) { + ATOMIC_SET(&res, res_local); + goto error_it; + } + pheat_path = NULL; } } @@ -312,7 +341,25 @@ XD(solve_boundary) acc_temp->sum += w; acc_temp->sum2 += w*w; ++acc_temp->count; acc_time->sum += usec; acc_time->sum2 += usec*usec; ++acc_time->count; } + + /* Update progress */ + n = (size_t)ATOMIC_INCR(&nsolved_realisations); + pcent = (int)((double)n * 100.0 / (double)nrealisations + 0.5/*round*/); + #pragma omp critical + if(pcent > progress) { + progress = pcent; + log_info(scn->dev, "Solving boundary temperature: %3d%%\r", progress); + } + exit_it: + if(pheat_path) heat_path_release(pheat_path); + continue; + error_it: + goto exit_it; } + if(res != RES_OK) goto error; + + /* Add a new line after the progress status */ + log_info(scn->dev, "Solving boundary temperature: %3d%%\n", progress); /* Setup the estimated temperature */ if(out_estimator) { @@ -326,6 +373,8 @@ XD(solve_boundary) estimator_setup_realisations_count(estimator, nrealisations, acc_temp.count); estimator_setup_temperature(estimator, acc_temp.sum, acc_temp.sum2); estimator_setup_realisation_time(estimator, acc_time.sum, acc_time.sum2); + res = estimator_save_rng_state(estimator, rng_proxy); + if(res != RES_OK) goto error; } /* Setup the green function */ @@ -381,13 +430,7 @@ error: static res_T XD(solve_boundary_flux) (struct sdis_scene* scn, - const size_t nrealisations, /* #realisations */ - const size_t primitives[], /* List of boundary primitives to handle */ - const size_t nprimitives, /* #primitives */ - const double time_range[2], /* Observation time */ - const double fp_to_meter, /* Scale from floating point units to meters */ - const double Tarad, /* In Kelvin */ - const double Tref, /* In Kelvin */ + const struct sdis_solve_boundary_flux_args* args, struct sdis_estimator** out_estimator) { struct XD(boundary_context) ctx = XD(BOUNDARY_CONTEXT_NULL); @@ -403,15 +446,24 @@ XD(solve_boundary_flux) struct accum* acc_fl = NULL; /* Per thread flux accumulator */ struct accum* acc_fc = NULL; /* Per thread convective flux accumulator */ struct accum* acc_fr = NULL; /* Per thread radiative flux accumulator */ + size_t nrealisations = 0; + int64_t irealisation; size_t i; size_t view_nprims; - int64_t irealisation; + int progress = 0; + ATOMIC nsolved_realisations = 0; ATOMIC res = RES_OK; - if(!scn || !nrealisations || nrealisations > INT64_MAX || !primitives - || !time_range || time_range[0] < 0 || time_range[1] < time_range[0] - || (time_range[1] > DBL_MAX && time_range[0] != time_range[1]) - || !nprimitives || fp_to_meter < 0 || Tref < 0 + if(!scn + || !args + || !args->nrealisations + || args->nrealisations > INT64_MAX + || !args->primitives + || args->time_range[0] < 0 + || args->time_range[1] < args->time_range[0] + || (args->time_range[1] > DBL_MAX && args->time_range[0] != args->time_range[1]) + || !args->nprimitives + || args->fp_to_meter < 0 || !out_estimator) { res = RES_BAD_ARG; goto error; @@ -424,12 +476,12 @@ XD(solve_boundary_flux) #endif SXD(scene_view_primitives_count(scn->sXd(view), &view_nprims)); - FOR_EACH(i, 0, nprimitives) { - if(primitives[i] >= view_nprims) { + FOR_EACH(i, 0, args->nprimitives) { + if(args->primitives[i] >= view_nprims) { log_err(scn->dev, "%s: invalid primitive identifier `%lu'. It must be in the [0 %lu] range.\n", FUNC_NAME, - (unsigned long)primitives[i], + (unsigned long)args->primitives[i], (unsigned long)scene_get_primitives_count(scn)-1); res = RES_BAD_ARG; goto error; @@ -438,32 +490,33 @@ XD(solve_boundary_flux) /* Create the Star-XD shape of the boundary */ #if SDIS_XD_DIMENSION == 2 - res = s2d_shape_create_line_segments(scn->dev->s2d, &shape); + res = s2d_shape_create_line_segments(scn->dev->sXd(dev), &shape); #else - res = s3d_shape_create_mesh(scn->dev->s3d, &shape); + res = s3d_shape_create_mesh(scn->dev->sXd(dev), &shape); #endif if(res != RES_OK) goto error; /* Initialise the boundary shape with the triangles/segments of the * submitted primitives */ - ctx.primitives = primitives; + ctx.primitives = args->primitives; ctx.view = scn->sXd(view); vdata.get = XD(boundary_get_position); #if SDIS_XD_DIMENSION == 2 vdata.usage = S2D_POSITION; vdata.type = S2D_FLOAT2; - res = s2d_line_segments_setup_indexed_vertices(shape, (unsigned)nprimitives, - XD(boundary_get_indices), (unsigned)(nprimitives*2), &vdata, 1, &ctx); + res = s2d_line_segments_setup_indexed_vertices(shape, + (unsigned)args->nprimitives, XD(boundary_get_indices), + (unsigned)(args->nprimitives*2), &vdata, 1, &ctx); #else /* DIM == 3 */ vdata.usage = S3D_POSITION; vdata.type = S3D_FLOAT3; - res = s3d_mesh_setup_indexed_vertices(shape, (unsigned)nprimitives, - XD(boundary_get_indices), (unsigned)(nprimitives*3), &vdata, 1, &ctx); + res = s3d_mesh_setup_indexed_vertices(shape, (unsigned)args->nprimitives, + XD(boundary_get_indices), (unsigned)(args->nprimitives*3), &vdata, 1, &ctx); #endif if(res != RES_OK) goto error; /* Create and setup the boundary Star-XD scene */ - res = sXd(scene_create)(scn->dev->sXd_dev, &scene); + res = sXd(scene_create)(scn->dev->sXd(dev), &scene); if(res != RES_OK) goto error; res = sXd(scene_attach_shape)(scene, shape); if(res != RES_OK) goto error; @@ -471,9 +524,15 @@ XD(solve_boundary_flux) if(res != RES_OK) goto error; /* Create the proxy RNG */ - res = ssp_rng_proxy_create(scn->dev->allocator, &ssp_rng_mt19937_64, - scn->dev->nthreads, &rng_proxy); - if(res != RES_OK) goto error; + if(args->rng_state) { + res = ssp_rng_proxy_create_from_rng(scn->dev->allocator, args->rng_state, + scn->dev->nthreads, &rng_proxy); + if(res != RES_OK) goto error; + } else { + res = ssp_rng_proxy_create(scn->dev->allocator, &ssp_rng_mt19937_64, + scn->dev->nthreads, &rng_proxy); + if(res != RES_OK) goto error; + } /* Create the per thread RNG */ rngs = MEM_CALLOC(scn->dev->allocator, scn->dev->nthreads, sizeof(*rngs)); @@ -499,6 +558,7 @@ XD(solve_boundary_flux) res = estimator_create(scn->dev, SDIS_ESTIMATOR_FLUX, &estimator); if(res != RES_OK) goto error; + nrealisations = args->nrealisations; omp_set_num_threads((int)scn->dev->nthreads); #pragma omp parallel for schedule(static) for(irealisation = 0; irealisation < (int64_t)nrealisations; ++irealisation) { @@ -516,12 +576,16 @@ XD(solve_boundary_flux) const struct sdis_medium *fmd, *bmd; enum sdis_side solid_side, fluid_side; double T_brf[3] = { 0, 0, 0 }; + const double Tref = args->reference_temperature; + const double Tarad = args->ambient_radiative_temperature; double epsilon, hc, hr; size_t iprim; double uv[DIM - 1]; float st[DIM - 1]; double time; int flux_mask = 0; + size_t n; + int pcent; res_T res_local = RES_OK; res_T res_simul = RES_OK; @@ -530,7 +594,7 @@ XD(solve_boundary_flux) /* Begin time registration */ time_current(&t0); - time = sample_time(rng, time_range); + time = sample_time(rng, args->time_range); /* Sample a position onto the boundary */ #if SDIS_XD_DIMENSION == 2 @@ -552,8 +616,8 @@ XD(solve_boundary_flux) if(res_local != RES_OK) { ATOMIC_SET(&res, res_local); continue; } /* Map from boundary scene to sdis scene */ - ASSERT(prim.prim_id < nprimitives); - iprim = primitives[prim.prim_id]; + ASSERT(prim.prim_id < args->nprimitives); + iprim = args->primitives[prim.prim_id]; interf = scene_get_interface(scn, (unsigned)iprim); fmd = interface_get_medium(interf, SDIS_FRONT); @@ -585,12 +649,12 @@ XD(solve_boundary_flux) if(hc > 0) flux_mask |= FLUX_FLAG_CONVECTIVE; res_simul = XD(boundary_flux_realisation)(scn, rng, iprim, uv, time, - solid_side, fp_to_meter, Tarad, Tref, flux_mask, T_brf); + solid_side, args->fp_to_meter, Tarad, Tref, flux_mask, T_brf); /* Stop time registration */ time_sub(&t0, time_current(&t1), &t0); - if(res_simul != RES_OK && res_simul != RES_BAD_OP) { + if(res_simul != RES_OK && res_simul != RES_BAD_OP) { ATOMIC_SET(&res, res_simul); continue; } else if(res_simul == RES_OK) { /* Update accumulators */ @@ -622,9 +686,21 @@ XD(solve_boundary_flux) acc_frad->sum2 += w_rad*w_rad; ++acc_frad->count; } + + /* Update progress */ + n = (size_t)ATOMIC_INCR(&nsolved_realisations); + pcent = (int)((double)n * 100.0 / (double)nrealisations + 0.5/*round*/); + #pragma omp critical + if(pcent > progress) { + progress = pcent; + log_info(scn->dev, "Solving boundary flux: %3d%%\r", progress); + } } if(res != RES_OK) goto error; + /* Add a new line after the progress status */ + log_info(scn->dev, "Solving boundary flux: %3d%%\n", progress); + /* Redux the per thread accumulators */ sum_accums(acc_tp, scn->dev->nthreads, &acc_tp[0]); sum_accums(acc_ti, scn->dev->nthreads, &acc_ti[0]); @@ -644,6 +720,9 @@ XD(solve_boundary_flux) estimator_setup_flux(estimator, FLUX_RADIATIVE, acc_fr[0].sum, acc_fr[0].sum2); estimator_setup_flux(estimator, FLUX_TOTAL, acc_fl[0].sum, acc_fl[0].sum2); + res = estimator_save_rng_state(estimator, rng_proxy); + if(res != RES_OK) goto error; + exit: if(rngs) { FOR_EACH(i, 0, scn->dev->nthreads) { if(rngs[i]) SSP(rng_ref_put(rngs[i])); } diff --git a/src/sdis_solve_medium_Xd.h b/src/sdis_solve_medium_Xd.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -200,13 +200,7 @@ error: static res_T XD(solve_medium) (struct sdis_scene* scn, - const size_t nrealisations, - struct sdis_medium* mdm, - const double time_range[2], - const double fp_to_meter,/* Scale factor from floating point unit to meter */ - const double Tarad, /* Ambient radiative temperature */ - const double Tref, /* Reference temperature */ - const int register_paths, /* Combination of enum sdis_heat_path_flag */ + const struct sdis_solve_medium_args* args, struct sdis_green_function** out_green, /* May be NULL <=> No green func */ struct sdis_estimator** out_estimator) /* May be NULL <=> No estimator */ { @@ -218,13 +212,17 @@ XD(solve_medium) struct sdis_estimator* estimator = NULL; struct accum* acc_temps = NULL; struct accum* acc_times = NULL; + size_t nrealisations = 0; int64_t irealisation; int cumul_is_init = 0; size_t i; + int progress = 0; + int register_paths = SDIS_HEAT_PATH_NONE; + ATOMIC nsolved_realisations = 0; ATOMIC res = RES_OK; - if(!scn || !mdm || !nrealisations || nrealisations > INT64_MAX - || fp_to_meter <= 0 || Tref < 0) { + if(!scn || !args || !args->medium || !args->nrealisations + || args->nrealisations > INT64_MAX || args->fp_to_meter <= 0) { res = RES_BAD_ARG; goto error; } @@ -233,8 +231,10 @@ XD(solve_medium) goto error; } if(out_estimator) { - if(!time_range || time_range[0] < 0 || time_range[0] > time_range[1] - || (time_range[1] > DBL_MAX && time_range[0] != time_range[1])) { + if(args->time_range[0] < 0 + || args->time_range[0] > args->time_range[1] + || ( args->time_range[1] > DBL_MAX + && args->time_range[0] != args->time_range[1])) { res = RES_BAD_ARG; goto error; } @@ -247,9 +247,15 @@ XD(solve_medium) #endif /* Create the proxy RNG */ - res = ssp_rng_proxy_create(scn->dev->allocator, &ssp_rng_mt19937_64, - scn->dev->nthreads, &rng_proxy); - if(res != RES_OK) goto error; + if(args->rng_state) { + res = ssp_rng_proxy_create_from_rng(scn->dev->allocator, args->rng_state, + scn->dev->nthreads, &rng_proxy); + if(res != RES_OK) goto error; + } else { + res = ssp_rng_proxy_create(scn->dev->allocator, &ssp_rng_mt19937_64, + scn->dev->nthreads, &rng_proxy); + if(res != RES_OK) goto error; + } /* Create the per thread RNG */ rngs = MEM_CALLOC(scn->dev->allocator, scn->dev->nthreads, sizeof(*rngs)); @@ -270,7 +276,7 @@ XD(solve_medium) /* Compute the enclosure cumulative */ darray_enclosure_cumul_init(scn->dev->allocator, &cumul); cumul_is_init = 1; - res = compute_medium_enclosure_cumulative(scn, mdm, &cumul); + res = compute_medium_enclosure_cumulative(scn, args->medium, &cumul); if(res != RES_OK) goto error; if(out_green) { @@ -289,6 +295,8 @@ XD(solve_medium) if(res != RES_OK) goto error; } + nrealisations = args->nrealisations; + register_paths = out_estimator ? args->register_paths : SDIS_HEAT_PATH_NONE; omp_set_num_threads((int)scn->dev->nthreads); #pragma omp parallel for schedule(static) for(irealisation = 0; irealisation < (int64_t)nrealisations; ++irealisation) { @@ -305,6 +313,8 @@ XD(solve_medium) double weight; double time; double pos[DIM]; + size_t n; + int pcent; res_T res_local = RES_OK; res_T res_simul = RES_OK; @@ -314,7 +324,7 @@ XD(solve_medium) if(!out_green) { /* Sample the time */ - time = sample_time(rng, time_range); + time = sample_time(rng, args->time_range); /* Prepare path registration if necessary */ if(register_paths) { @@ -326,7 +336,10 @@ XD(solve_medium) * function. Simply takes 0 as relative time */ time = 0; res_local = green_function_create_path(greens[ithread], &green_path); - if(res_local != RES_OK) { ATOMIC_SET(&res, res_local); continue; } + if(res_local != RES_OK) { + ATOMIC_SET(&res, res_local); + goto error_it; + } pgreen_path = &green_path; } @@ -338,31 +351,38 @@ XD(solve_medium) if(res_local != RES_OK) { log_err(scn->dev, "%s: could not sample a medium position.\n", FUNC_NAME); ATOMIC_SET(&res, res_local); - continue; + goto error_it; } /* Run a probe realisation */ - res_simul = XD(probe_realisation)((size_t)irealisation, scn, rng, mdm, pos, - time, fp_to_meter, Tarad, Tref, pgreen_path, pheat_path, &weight); + res_simul = XD(probe_realisation)((size_t)irealisation, scn, rng, + args->medium, pos, time, args->fp_to_meter, + args->ambient_radiative_temperature, args->reference_temperature, + pgreen_path, pheat_path, &weight); if(res_simul != RES_OK && res_simul != RES_BAD_OP) { ATOMIC_SET(&res, res_simul); - continue; + goto error_it; } /* Finalize the registered path */ if(pheat_path) { pheat_path->status = res_simul == RES_OK - ? SDIS_HEAT_PATH_SUCCEED - : SDIS_HEAT_PATH_FAILED; + ? SDIS_HEAT_PATH_SUCCESS + : SDIS_HEAT_PATH_FAILURE; /* Check if the path must be saved regarding the register_paths mask */ if(!(register_paths & (int)pheat_path->status)) { heat_path_release(pheat_path); + pheat_path = NULL; } else { /* Register the sampled path */ res_local = estimator_add_and_release_heat_path(estimator, pheat_path); - if(res_local != RES_OK) { ATOMIC_SET(&res, res_local); continue; } + if(res_local != RES_OK) { + ATOMIC_SET(&res, res_local); + goto error_it; + } } + pheat_path = NULL; } /* Stop time registration */ @@ -374,9 +394,26 @@ XD(solve_medium) acc_temp->sum += weight; acc_temp->sum2 += weight*weight; ++acc_temp->count; acc_time->sum += usec; acc_time->sum2 += usec*usec; ++acc_time->count; } + + /* Update progress */ + n = (size_t)ATOMIC_INCR(&nsolved_realisations); + pcent = (int)((double)n * 100.0 / (double)nrealisations + 0.5/*round*/); + #pragma omp critical + if(pcent > progress) { + progress = pcent; + log_info(scn->dev, "Solving medium temperature: %3d%%\r", progress); + } + exit_it: + if(pheat_path) heat_path_release(pheat_path); + continue; + error_it: + goto exit_it; } if(res != RES_OK) goto error; + /* Add a new line after the progress status */ + log_info(scn->dev, "Solving medium temperature: %3d%%\n", progress); + /* Setup the estimated temperature */ if(out_estimator) { struct accum acc_temp; @@ -389,6 +426,8 @@ XD(solve_medium) estimator_setup_realisations_count(estimator, nrealisations, acc_temp.count); estimator_setup_temperature(estimator, acc_temp.sum, acc_temp.sum2); estimator_setup_realisation_time(estimator, acc_time.sum, acc_time.sum2); + res = estimator_save_rng_state(estimator, rng_proxy); + if(res != RES_OK) goto error; } if(out_green) { diff --git a/src/sdis_solve_probe_Xd.h b/src/sdis_solve_probe_Xd.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,6 +15,7 @@ #include "sdis_device_c.h" #include "sdis_estimator_c.h" +#include "sdis_log.h" #include "sdis_green.h" #include "sdis_misc.h" #include "sdis_realisation.h" @@ -32,13 +33,7 @@ static res_T XD(solve_probe) (struct sdis_scene* scn, - const size_t nrealisations, - const double position[3], - const double time_range[2], - const double fp_to_meter,/* Scale factor from floating point unit to meter */ - const double Tarad, /* Ambient radiative temperature */ - const double Tref, /* Reference temperature */ - const int register_paths, /* Combination of enum sdis_heat_path_flag */ + const struct sdis_solve_probe_args* args, struct sdis_green_function** out_green, /* May be NULL <=> No green func */ struct sdis_estimator** out_estimator) /* May be NULL <=> No estimator */ { @@ -50,12 +45,16 @@ XD(solve_probe) struct ssp_rng** rngs = NULL; struct accum* acc_temps = NULL; struct accum* acc_times = NULL; + size_t nrealisations = 0; int64_t irealisation = 0; size_t i; + int progress = 0; + int register_paths = SDIS_HEAT_PATH_NONE; + ATOMIC nsolved_realisations = 0; ATOMIC res = RES_OK; - if(!scn || !nrealisations || nrealisations > INT64_MAX || !position - || fp_to_meter <= 0 || Tref < 0) { + if(!scn || !args || !args->nrealisations || args->nrealisations > INT64_MAX + || args->fp_to_meter <= 0) { res = RES_BAD_ARG; goto error; } @@ -64,13 +63,16 @@ XD(solve_probe) goto error; } if(out_estimator) { - if(!time_range || time_range[0] < 0 || time_range[1] < time_range[0] - || (time_range[1] > DBL_MAX && time_range[0] != time_range[1])) { + if(args->time_range[0] < 0 + || args->time_range[1] < args->time_range[0] + || ( args->time_range[1] > DBL_MAX + && args->time_range[0] != args->time_range[1])) { res = RES_BAD_ARG; goto error; } } + #if SDIS_XD_DIMENSION == 2 if(scene_is_2d(scn) == 0) { res = RES_BAD_ARG; goto error; } #else @@ -78,9 +80,15 @@ XD(solve_probe) #endif /* Create the proxy RNG */ - res = ssp_rng_proxy_create(scn->dev->allocator, &ssp_rng_mt19937_64, - scn->dev->nthreads, &rng_proxy); - if(res != RES_OK) goto error; + if(args->rng_state) { + res = ssp_rng_proxy_create_from_rng(scn->dev->allocator, args->rng_state, + scn->dev->nthreads, &rng_proxy); + if(res != RES_OK) goto error; + } else { + res = ssp_rng_proxy_create(scn->dev->allocator, &ssp_rng_mt19937_64, + scn->dev->nthreads, &rng_proxy); + if(res != RES_OK) goto error; + } /* Create the per thread RNG */ rngs = MEM_CALLOC(scn->dev->allocator, scn->dev->nthreads, sizeof(*rngs)); @@ -99,7 +107,7 @@ XD(solve_probe) if(!acc_times) { res = RES_MEM_ERR; goto error; } /* Retrieve the medium in which the submitted position lies */ - res = scene_get_medium(scn, position, NULL, &medium); + res = scene_get_medium(scn, args->position, NULL, &medium); if(res != RES_OK) goto error; /* Create the per thread green function */ @@ -119,6 +127,8 @@ XD(solve_probe) } /* Here we go! Launch the Monte Carlo estimation */ + nrealisations = args->nrealisations; + register_paths = out_estimator ? args->register_paths : SDIS_HEAT_PATH_NONE; omp_set_num_threads((int)scn->dev->nthreads); #pragma omp parallel for schedule(static) for(irealisation = 0; irealisation < (int64_t)nrealisations; ++irealisation) { @@ -133,6 +143,8 @@ XD(solve_probe) struct sdis_heat_path heat_path; double w = NaN; double time; + size_t n; + int pcent; res_T res_local = RES_OK; res_T res_simul = RES_OK; @@ -142,7 +154,7 @@ XD(solve_probe) time_current(&t0); if(!out_green) { - time = sample_time(rng, time_range); + time = sample_time(rng, args->time_range); if(register_paths) { heat_path_init(scn->dev->allocator, &heat_path); pheat_path = &heat_path; @@ -152,31 +164,40 @@ XD(solve_probe) * function. Simply takes 0 as relative time */ time = 0; res_local = green_function_create_path(greens[ithread], &green_path); - if(res_local != RES_OK) { ATOMIC_SET(&res, res_local); continue; } - + if(res_local != RES_OK) { + ATOMIC_SET(&res, res_local); + goto error_it; + } pgreen_path = &green_path; } res_simul = XD(probe_realisation)((size_t)irealisation, scn, rng, medium, - position, time, fp_to_meter, Tarad, Tref, pgreen_path, pheat_path, &w); + args->position, time, args->fp_to_meter, + args->ambient_radiative_temperature, args->reference_temperature, + pgreen_path, pheat_path, &w); /* Handle fatal error */ if(res_simul != RES_OK && res_simul != RES_BAD_OP) { ATOMIC_SET(&res, res_simul); - continue; + goto error_it; } if(pheat_path) { pheat_path->status = res_simul == RES_OK - ? SDIS_HEAT_PATH_SUCCEED - : SDIS_HEAT_PATH_FAILED; + ? SDIS_HEAT_PATH_SUCCESS + : SDIS_HEAT_PATH_FAILURE; /* Check if the path must be saved regarding the register_paths mask */ if(!(register_paths & (int)pheat_path->status)) { heat_path_release(pheat_path); + pheat_path = NULL; } else { /* Register the sampled path */ res_local = estimator_add_and_release_heat_path(estimator, pheat_path); - if(res_local != RES_OK) { ATOMIC_SET(&res, res_local); continue; } + if(res_local != RES_OK) { + ATOMIC_SET(&res, res_local); + goto error_it; + } + pheat_path = NULL; } } @@ -189,9 +210,26 @@ XD(solve_probe) acc_temp->sum += w; acc_temp->sum2 += w*w; ++acc_temp->count; acc_time->sum += usec; acc_time->sum2 += usec*usec; ++acc_time->count; } + + /* Update progress */ + n = (size_t)ATOMIC_INCR(&nsolved_realisations); + pcent = (int)((double)n * 100.0 / (double)nrealisations + 0.5/*round*/); + #pragma omp critical + if(pcent > progress) { + progress = pcent; + log_info(scn->dev, "Solving probe temperature: %3d%%\r", progress); + } + exit_it: + if(pheat_path) heat_path_release(pheat_path); + continue; + error_it: + goto exit_it; } if(res != RES_OK) goto error; + /* Add a new line after the progress status */ + log_info(scn->dev, "Solving probe temperature: %3d%%\n", progress); + /* Setup the estimated temperature and per realisation time */ if(out_estimator) { struct accum acc_temp; @@ -204,6 +242,8 @@ XD(solve_probe) estimator_setup_realisations_count(estimator, nrealisations, acc_temp.count); estimator_setup_temperature(estimator, acc_temp.sum, acc_temp.sum2); estimator_setup_realisation_time(estimator, acc_time.sum, acc_time.sum2); + res = estimator_save_rng_state(estimator, rng_proxy); + if(res != RES_OK) goto error; } if(out_green) { diff --git a/src/sdis_solve_probe_boundary_Xd.h b/src/sdis_solve_probe_boundary_Xd.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,6 +15,7 @@ #include "sdis_device_c.h" #include "sdis_estimator_c.h" +#include "sdis_log.h" #include "sdis_medium_c.h" #include "sdis_misc.h" #include "sdis_realisation.h" @@ -32,15 +33,7 @@ static res_T XD(solve_probe_boundary) (struct sdis_scene* scn, - const size_t nrealisations, /* #realisations */ - const size_t iprim, /* Identifier of the primitive on which the probe lies */ - const double uv[2], /* Parametric coordinates of the probe onto the primitve */ - const double time_range[2], /* Observation time */ - const enum sdis_side side, /* Side of iprim on which the probe lies */ - const double fp_to_meter, /* Scale from floating point units to meters */ - const double Tarad, /* In Kelvin */ - const double Tref, /* In Kelvin */ - const int register_paths, /* Combination of enum sdis_heat_path_flag */ + const struct sdis_solve_probe_boundary_args* args, struct sdis_green_function** out_green, struct sdis_estimator** out_estimator) { @@ -51,12 +44,16 @@ XD(solve_probe_boundary) struct ssp_rng** rngs = NULL; struct accum* acc_temps = NULL; struct accum* acc_times = NULL; + size_t nrealisations = 0; int64_t irealisation = 0; size_t i; + int progress = 0; + int register_paths = SDIS_HEAT_PATH_NONE; + ATOMIC nsolved_realisations = 0; ATOMIC res = RES_OK; - if(!scn || !nrealisations || nrealisations > INT64_MAX || !uv - || fp_to_meter <= 0 || Tref < 0 || (side != SDIS_FRONT && side != SDIS_BACK)) { + if(!scn || !args || !args->nrealisations || args->nrealisations > INT64_MAX + || args->fp_to_meter <= 0 || ((unsigned)args->side >= SDIS_SIDE_NULL__)) { res = RES_BAD_ARG; goto error; } @@ -65,8 +62,10 @@ XD(solve_probe_boundary) goto error; } if(out_estimator) { - if(!time_range || time_range[0] < 0 || time_range[1] < time_range[0] - || (time_range[1] > DBL_MAX && time_range[0] != time_range[1])) { + if(args->time_range[0] < 0 + || args->time_range[1] < args->time_range[0] + || ( args->time_range[1] > DBL_MAX + && args->time_range[0] != args->time_range[1])) { res = RES_BAD_ARG; goto error; } @@ -79,12 +78,12 @@ XD(solve_probe_boundary) #endif /* Check the primitive identifier */ - if(iprim >= scene_get_primitives_count(scn)) { + if(args->iprim >= scene_get_primitives_count(scn)) { log_err(scn->dev, "%s: invalid primitive identifier `%lu'. " "It must be in the [0 %lu] range.\n", FUNC_NAME, - (unsigned long)iprim, + (unsigned long)args->iprim, (unsigned long)scene_get_primitives_count(scn)-1); res = RES_BAD_ARG; goto error; @@ -93,25 +92,25 @@ XD(solve_probe_boundary) /* Check parametric coordinates */ #if SDIS_XD_DIMENSION == 2 { - const double v = CLAMP(1.0 - uv[0], 0, 1); - if(uv[0] < 0 || uv[0] > 1 || !eq_eps(uv[0] + v, 1, 1.e-6)) { + const double v = CLAMP(1.0 - args->uv[0], 0, 1); + if(args->uv[0] < 0 || args->uv[0] > 1 || !eq_eps(args->uv[0]+v, 1, 1.e-6)) { log_err(scn->dev, "%s: invalid parametric coordinates %g." "u + (1-u) must be equal to 1 with u [0, 1].\n", - FUNC_NAME, uv[0]); + FUNC_NAME, args->uv[0]); res = RES_BAD_ARG; goto error; } } #else /* SDIS_XD_DIMENSION == 3 */ { - const double w = CLAMP(1 - uv[0] - uv[1], 0, 1); - if(uv[0] < 0 || uv[1] < 0 || uv[0] > 1 || uv[1] > 1 - || !eq_eps(w + uv[0] + uv[1], 1, 1.e-6)) { + const double w = CLAMP(1 - args->uv[0] - args->uv[1], 0, 1); + if(args->uv[0] < 0 || args->uv[1] < 0 || args->uv[0] > 1 || args->uv[1] > 1 + || !eq_eps(w + args->uv[0] + args->uv[1], 1, 1.e-6)) { log_err(scn->dev, "%s: invalid parametric coordinates [%g, %g]. " "u + v + (1-u-v) must be equal to 1 with u and v in [0, 1].\n", - FUNC_NAME, uv[0], uv[1]); + FUNC_NAME, args->uv[0], args->uv[1]); res = RES_BAD_ARG; goto error; } @@ -119,9 +118,15 @@ XD(solve_probe_boundary) #endif /* Create the proxy RNG */ - res = ssp_rng_proxy_create(scn->dev->allocator, &ssp_rng_mt19937_64, - scn->dev->nthreads, &rng_proxy); - if(res != RES_OK) goto error; + if(args->rng_state) { + res = ssp_rng_proxy_create_from_rng(scn->dev->allocator, args->rng_state, + scn->dev->nthreads, &rng_proxy); + if(res != RES_OK) goto error; + } else { + res = ssp_rng_proxy_create(scn->dev->allocator, &ssp_rng_mt19937_64, + scn->dev->nthreads, &rng_proxy); + if(res != RES_OK) goto error; + } /* Create the per thread RNG */ rngs = MEM_CALLOC @@ -157,6 +162,8 @@ XD(solve_probe_boundary) } /* Here we go! Launch the Monte Carlo estimation */ + nrealisations = args->nrealisations; + register_paths = out_estimator ? args->register_paths : SDIS_HEAT_PATH_NONE; omp_set_num_threads((int)scn->dev->nthreads); #pragma omp parallel for schedule(static) for(irealisation = 0; irealisation < (int64_t)nrealisations; ++irealisation) { @@ -171,6 +178,8 @@ XD(solve_probe_boundary) struct sdis_heat_path heat_path; double w = NaN; double time; + size_t n; + int pcent; res_T res_local = RES_OK; res_T res_simul = RES_OK; @@ -180,7 +189,7 @@ XD(solve_probe_boundary) time_current(&t0); if(!out_green) { - time = sample_time(rng, time_range); + time = sample_time(rng, args->time_range); if(register_paths) { heat_path_init(scn->dev->allocator, &heat_path); pheat_path = &heat_path; @@ -190,30 +199,40 @@ XD(solve_probe_boundary) * function. Simply takes 0 as relative time */ time = 0; res_local = green_function_create_path(greens[ithread], &green_path); - if(res_local != RES_OK) { ATOMIC_SET(&res, res_local); continue; } + if(res_local != RES_OK) { + ATOMIC_SET(&res, res_local); + goto error_it; + } pgreen_path = &green_path; } - res_simul = XD(boundary_realisation)(scn, rng, iprim, uv, time, side, - fp_to_meter, Tarad, Tref, pgreen_path, pheat_path, &w); + res_simul = XD(boundary_realisation)(scn, rng, args->iprim, args->uv, time, + args->side, args->fp_to_meter, args->ambient_radiative_temperature, + args->reference_temperature, pgreen_path, pheat_path, &w); /* Handle fatal error */ if(res_simul != RES_OK && res_simul != RES_BAD_OP) { ATOMIC_SET(&res, res_simul); - continue; + goto error_it; } if(pheat_path) { pheat_path->status = res_simul == RES_OK - ? SDIS_HEAT_PATH_SUCCEED - : SDIS_HEAT_PATH_FAILED; + ? SDIS_HEAT_PATH_SUCCESS + : SDIS_HEAT_PATH_FAILURE; /* Check if the path must be saved regarding the register_paths mask */ if(!(register_paths & (int)pheat_path->status)) { heat_path_release(pheat_path); - } else { /* Register the sampled path */ + pheat_path = NULL; + } else { + /* Register the sampled path */ res_local = estimator_add_and_release_heat_path(estimator, pheat_path); - if(res_local != RES_OK) { ATOMIC_SET(&res, res_local); continue; } + if(res_local != RES_OK) { + ATOMIC_SET(&res, res_local); + goto error_it; + } + pheat_path = NULL; } } @@ -226,9 +245,27 @@ XD(solve_probe_boundary) acc_temp->sum += w; acc_temp->sum2 += w*w; ++acc_temp->count; acc_time->sum += usec; acc_time->sum2 += usec*usec; ++acc_time->count; } + + /* Update progress */ + n = (size_t)ATOMIC_INCR(&nsolved_realisations); + pcent = (int)((double)n * 100.0 / (double)nrealisations + 0.5/*round*/); + #pragma omp critical + if(pcent > progress) { + progress = pcent; + log_info(scn->dev, "Solving probe boundary temperature: %3d%%\r", progress); + } + + exit_it: + if(pheat_path) heat_path_release(pheat_path); + continue; + error_it: + goto exit_it; } if(res != RES_OK) goto error; + /* Add a new line after the progress status */ + log_info(scn->dev, "Solving probe boundary temperature: %3d%%\n", progress); + /* Setup the estimated temperature and per realisation time */ if(out_estimator) { struct accum acc_temp; @@ -241,6 +278,8 @@ XD(solve_probe_boundary) estimator_setup_realisations_count(estimator, nrealisations, acc_temp.count); estimator_setup_temperature(estimator, acc_temp.sum, acc_temp.sum2); estimator_setup_realisation_time(estimator, acc_time.sum, acc_time.sum2); + res = estimator_save_rng_state(estimator, rng_proxy); + if(res != RES_OK) goto error; } if(out_green) { @@ -292,13 +331,7 @@ error: static res_T XD(solve_probe_boundary_flux) (struct sdis_scene* scn, - const size_t nrealisations, /* #realisations */ - const size_t iprim, /* Identifier of the primitive on which the probe lies */ - const double uv[2], /* Parametric coordinates of the probe onto the primitve */ - const double time_range[2], /* Observation time */ - const double fp_to_meter, /* Scale from floating point units to meters */ - const double Tarad, /* In Kelvin */ - const double Tref, /* In Kelvin */ + const struct sdis_solve_probe_boundary_flux_args* args, struct sdis_estimator** out_estimator) { struct sdis_estimator* estimator = NULL; @@ -313,15 +346,17 @@ XD(solve_probe_boundary_flux) struct accum* acc_fl = NULL; /* Per thread flux accumulator */ struct accum* acc_fc = NULL; /* Per thread convective flux accumulator */ struct accum* acc_fr = NULL; /* Per thread radiative flux accumulator */ + size_t nrealisations = 0; int64_t irealisation = 0; size_t i; + int progress = 0; + ATOMIC nsolved_realisations = 0; ATOMIC res = RES_OK; - if(!scn || !nrealisations || nrealisations > INT64_MAX || !uv - || !time_range || time_range[0] < 0 || time_range[1] < time_range[0] - || (time_range[1] > DBL_MAX && time_range[0] != time_range[1]) - || fp_to_meter <= 0 || Tref < 0 - || !out_estimator) { + if(!scn || !args || !args->nrealisations || args->nrealisations > INT64_MAX + || args->time_range[0] < 0 || args->time_range[1] < args->time_range[0] + || (args->time_range[1]>DBL_MAX && args->time_range[0] != args->time_range[1]) + || args->fp_to_meter <= 0 || !out_estimator) { res = RES_BAD_ARG; goto error; } @@ -333,12 +368,12 @@ XD(solve_probe_boundary_flux) #endif /* Check the primitive identifier */ - if(iprim >= scene_get_primitives_count(scn)) { + if(args->iprim >= scene_get_primitives_count(scn)) { log_err(scn->dev, "%s: invalid primitive identifier `%lu'. " "It must be in the [0 %lu] range.\n", FUNC_NAME, - (unsigned long)iprim, + (unsigned long)args->iprim, (unsigned long)scene_get_primitives_count(scn)-1); res = RES_BAD_ARG; goto error; @@ -346,29 +381,33 @@ XD(solve_probe_boundary_flux) /* Check parametric coordinates */ if(scene_is_2d(scn)) { - const double v = CLAMP(1.0 - uv[0], 0, 1); - if(uv[0] < 0 || uv[0] > 1 || !eq_eps(uv[0] + v, 1, 1.e-6)) { + const double v = CLAMP(1.0 - args->uv[0], 0, 1); + if(args->uv[0] < 0 || args->uv[0] > 1 + || !eq_eps(args->uv[0] + v, 1, 1.e-6)) { log_err(scn->dev, "%s: invalid parametric coordinates %g. " "u + (1-u) must be equal to 1 with u [0, 1].\n", - FUNC_NAME, uv[0]); + FUNC_NAME, args->uv[0]); res = RES_BAD_ARG; goto error; } } else { - const double w = CLAMP(1 - uv[0] - uv[1], 0, 1); - if(uv[0] < 0 || uv[1] < 0 || uv[0] > 1 || uv[1] > 1 - || !eq_eps(w + uv[0] + uv[1], 1, 1.e-6)) { + const double w = CLAMP(1 - args->uv[0] - args->uv[1], 0, 1); + if(args->uv[0] < 0 + || args->uv[1] < 0 + || args->uv[0] > 1 + || args->uv[1] > 1 + || !eq_eps(w + args->uv[0] + args->uv[1], 1, 1.e-6)) { log_err(scn->dev, "%s: invalid parametric coordinates [%g, %g]. " "u + v + (1-u-v) must be equal to 1 with u and v in [0, 1].\n", - FUNC_NAME, uv[0], uv[1]); + FUNC_NAME, args->uv[0], args->uv[1]); res = RES_BAD_ARG; goto error; } } /* Check medium is fluid on one side and solid on the other */ - interf = scene_get_interface(scn, (unsigned)iprim); + interf = scene_get_interface(scn, (unsigned)args->iprim); fmd = interface_get_medium(interf, SDIS_FRONT); bmd = interface_get_medium(interf, SDIS_BACK); if(!fmd || !bmd @@ -381,9 +420,15 @@ XD(solve_probe_boundary_flux) fluid_side = (fmd->type == SDIS_FLUID) ? SDIS_FRONT : SDIS_BACK; /* Create the proxy RNG */ - res = ssp_rng_proxy_create(scn->dev->allocator, &ssp_rng_mt19937_64, - scn->dev->nthreads, &rng_proxy); - if(res != RES_OK) goto error; + if(args->rng_state) { + res = ssp_rng_proxy_create_from_rng(scn->dev->allocator, args->rng_state, + scn->dev->nthreads, &rng_proxy); + if(res != RES_OK) goto error; + } else { + res = ssp_rng_proxy_create(scn->dev->allocator, &ssp_rng_mt19937_64, + scn->dev->nthreads, &rng_proxy); + if(res != RES_OK) goto error; + } /* Create the per thread RNG */ rngs = MEM_CALLOC @@ -408,7 +453,7 @@ XD(solve_probe_boundary_flux) /* Prebuild the interface fragment */ res = XD(build_interface_fragment) - (&frag, scn, (unsigned)iprim, uv, fluid_side); + (&frag, scn, (unsigned)args->iprim, args->uv, fluid_side); if(res != RES_OK) goto error; /* Create the estimator */ @@ -416,6 +461,7 @@ XD(solve_probe_boundary_flux) if(res != RES_OK) goto error; /* Here we go! Launch the Monte Carlo estimation */ + nrealisations = args->nrealisations; omp_set_num_threads((int)scn->dev->nthreads); #pragma omp parallel for schedule(static) for(irealisation = 0; irealisation < (int64_t)nrealisations; ++irealisation) { @@ -430,6 +476,10 @@ XD(solve_probe_boundary_flux) double time, epsilon, hc, hr; int flux_mask = 0; double T_brf[3] = { 0, 0, 0 }; + const double Tref = args->reference_temperature; + const double Tarad = args->ambient_radiative_temperature; + size_t n; + int pcent; res_T res_simul = RES_OK; if(ATOMIC_GET(&res) != RES_OK) continue; /* An error occurred */ @@ -437,7 +487,7 @@ XD(solve_probe_boundary_flux) /* Begin time registration */ time_current(&t0); - time = sample_time(rng, time_range); + time = sample_time(rng, args->time_range); /* Compute hr and hc */ frag.time = time; @@ -449,8 +499,8 @@ XD(solve_probe_boundary_flux) flux_mask = 0; if(hr > 0) flux_mask |= FLUX_FLAG_RADIATIVE; if(hc > 0) flux_mask |= FLUX_FLAG_CONVECTIVE; - res_simul = XD(boundary_flux_realisation)(scn, rng, iprim, uv, time, - solid_side, fp_to_meter, Tarad, Tref, flux_mask, T_brf); + res_simul = XD(boundary_flux_realisation)(scn, rng, args->iprim, args->uv, time, + solid_side, args->fp_to_meter, Tarad, Tref, flux_mask, T_brf); /* Stop time registration */ time_sub(&t0, time_current(&t1), &t0); @@ -487,9 +537,21 @@ XD(solve_probe_boundary_flux) acc_frad->sum2 += w_rad*w_rad; ++acc_frad->count; } + + /* Update progress */ + n = (size_t)ATOMIC_INCR(&nsolved_realisations); + pcent = (int)((double)n * 100.0 / (double)nrealisations + 0.5/*round*/); + #pragma omp critical + if(pcent > progress) { + progress = pcent; + log_info(scn->dev, "Solving probe boundary flux: %3d%%\r", progress); + } } if(res != RES_OK) goto error; + /* Add a new line after the progress status */ + log_info(scn->dev, "Solving probe boundary flux: %3d%%\n", progress); + /* Redux the per thread accumulators */ sum_accums(acc_tp, scn->dev->nthreads, &acc_tp[0]); sum_accums(acc_ti, scn->dev->nthreads, &acc_ti[0]); @@ -509,6 +571,9 @@ XD(solve_probe_boundary_flux) estimator_setup_flux(estimator, FLUX_RADIATIVE, acc_fr[0].sum, acc_fr[0].sum2); estimator_setup_flux(estimator, FLUX_TOTAL, acc_fl[0].sum, acc_fl[0].sum2); + res = estimator_save_rng_state(estimator, rng_proxy); + if(res != RES_OK) goto error; + exit: if(rngs) { FOR_EACH(i, 0, scn->dev->nthreads) {if(rngs[i]) SSP(rng_ref_put(rngs[i]));} diff --git a/src/sdis_solve_radiative.c b/src/sdis_solve_radiative.c @@ -1,20 +0,0 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. */ - -#define SDIS_XD_DIMENSION 2 -#include "sdis_solve_Xd_radiative.h" - -#define SDIS_XD_DIMENSION 3 -#include "sdis_solve_Xd_radiative.h" diff --git a/src/test_sdis_accum_buffer.c b/src/test_sdis_accum_buffer.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/test_sdis_camera.c b/src/test_sdis_camera.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/test_sdis_conducto_radiative.c b/src/test_sdis_conducto_radiative.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -388,27 +388,30 @@ main(int argc, char** argv) struct sdis_estimator* estimator; struct sdis_estimator* estimator2; struct sdis_green_function* green; - double pos[3]; - double time_range[2] = { INF, INF }; + struct sdis_solve_probe_args solve_args = SDIS_SOLVE_PROBE_ARGS_DEFAULT; double ref, u; size_t nreals = 0; size_t nfails = 0; const size_t N = 10000; - pos[0] = ssp_rng_uniform_double(rng, -0.9, 0.9); - pos[1] = ssp_rng_uniform_double(rng, -0.9, 0.9); - pos[2] = ssp_rng_uniform_double(rng, -0.9, 0.9); + solve_args.nrealisations = N; + solve_args.time_range[0] = INF; + solve_args.time_range[1] = INF; + solve_args.position[0] = ssp_rng_uniform_double(rng, -0.9, 0.9); + solve_args.position[1] = ssp_rng_uniform_double(rng, -0.9, 0.9); + solve_args.position[2] = ssp_rng_uniform_double(rng, -0.9, 0.9); + solve_args.reference_temperature = Tref; - OK(sdis_solve_probe(scn, N, pos, time_range, 1, -1, Tref, 0, &estimator)); + OK(sdis_solve_probe(scn, &solve_args, &estimator)); OK(sdis_estimator_get_realisation_count(estimator, &nreals)); OK(sdis_estimator_get_failure_count(estimator, &nfails)); OK(sdis_estimator_get_temperature(estimator, &T)); OK(sdis_estimator_get_realisation_time(estimator, &time)); - u = (pos[0] + 1) / thickness; + u = (solve_args.position[0] + 1) / thickness; ref = u * Ts1 + (1-u) * Ts0; printf("Temperature at (%g, %g, %g) = %g ~ %g +/- %g\n", - SPLIT3(pos), ref, T.E, T.SE); + SPLIT3(solve_args.position), ref, T.E, T.SE); printf("Time per realisation (in usec) = %g +/- %g\n", time.E, time.SE); printf("#failures = %lu/%lu\n", (unsigned long)nfails, (unsigned long)N); @@ -417,8 +420,8 @@ main(int argc, char** argv) CHK(eq_eps(T.E, ref, 3*T.SE) == 1); /* Check green function */ - OK(sdis_solve_probe_green_function(scn, N, pos, 1, -1, Tref, &green)); - OK(sdis_green_function_solve(green, time_range, &estimator2)); + OK(sdis_solve_probe_green_function(scn, &solve_args, &green)); + OK(sdis_green_function_solve(green, solve_args.time_range, &estimator2)); check_green_function(green); check_estimator_eq(estimator, estimator2); @@ -426,8 +429,10 @@ main(int argc, char** argv) OK(sdis_estimator_ref_put(estimator2)); OK(sdis_green_function_ref_put(green)); - OK(sdis_solve_probe(scn, 10, pos, time_range, 1, -1, Tref, - SDIS_HEAT_PATH_ALL, &estimator)); + solve_args.nrealisations = 10; + solve_args.register_paths = SDIS_HEAT_PATH_ALL; + + OK(sdis_solve_probe(scn, &solve_args, &estimator)); OK(sdis_estimator_ref_put(estimator)); printf("\n"); diff --git a/src/test_sdis_conducto_radiative_2d.c b/src/test_sdis_conducto_radiative_2d.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -394,26 +394,29 @@ main(int argc, char** argv) struct sdis_estimator* estimator; struct sdis_estimator* estimator2; struct sdis_green_function* green; - double pos[2]; - double time_range[2] = { INF, INF }; + struct sdis_solve_probe_args solve_args = SDIS_SOLVE_PROBE_ARGS_DEFAULT; double ref, u; size_t nreals = 0; size_t nfails = 0; const size_t N = 10000; - pos[0] = ssp_rng_uniform_double(rng, -0.9, 0.9); - pos[1] = ssp_rng_uniform_double(rng, -0.9, 0.9); + solve_args.nrealisations = N; + solve_args.position[0] = ssp_rng_uniform_double(rng, -0.9, 0.9); + solve_args.position[1] = ssp_rng_uniform_double(rng, -0.9, 0.9); + solve_args.time_range[0] = INF; + solve_args.time_range[1] = INF; + solve_args.reference_temperature = Tref; - OK(sdis_solve_probe(scn, 10000, pos, time_range, 1, -1, Tref, 0, &estimator)); + OK(sdis_solve_probe(scn, &solve_args, &estimator)); OK(sdis_estimator_get_realisation_count(estimator, &nreals)); OK(sdis_estimator_get_failure_count(estimator, &nfails)); OK(sdis_estimator_get_temperature(estimator, &T)); OK(sdis_estimator_get_realisation_time(estimator, &time)); - u = (pos[0] + 1) / thickness; + u = (solve_args.position[0] + 1) / thickness; ref = u * Ts1 + (1-u) * Ts0; printf("Temperature at (%g, %g) = %g ~ %g +/- %g\n", - SPLIT2(pos), ref, T.E, T.SE); + SPLIT2(solve_args.position), ref, T.E, T.SE); printf("Time per realisation (in usec) = %g +/- %g\n", time.E, time.SE); printf("#failures = %lu/%lu\n", (unsigned long)nfails, (unsigned long)N); @@ -422,8 +425,8 @@ main(int argc, char** argv) CHK(eq_eps(T.E, ref, 3*T.SE) == 1); /* Check green function */ - OK(sdis_solve_probe_green_function(scn, 10000, pos, 1, -1, Tref, &green)); - OK(sdis_green_function_solve(green, time_range, &estimator2)); + OK(sdis_solve_probe_green_function(scn, &solve_args, &green)); + OK(sdis_green_function_solve(green, solve_args.time_range, &estimator2)); check_green_function(green); check_estimator_eq(estimator, estimator2); @@ -431,8 +434,10 @@ main(int argc, char** argv) OK(sdis_estimator_ref_put(estimator2)); OK(sdis_green_function_ref_put(green)); - OK(sdis_solve_probe - (scn, 10, pos, time_range, 1, -1, Tref, SDIS_HEAT_PATH_ALL, &estimator)); + solve_args.nrealisations = 10; + solve_args.register_paths = SDIS_HEAT_PATH_ALL; + + OK(sdis_solve_probe(scn, &solve_args, &estimator)); OK(sdis_estimator_ref_put(estimator)); printf("\n"); diff --git a/src/test_sdis_convection.c b/src/test_sdis_convection.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -188,7 +188,7 @@ main(int argc, char** argv) struct sdis_interface_shader interf_shader = DUMMY_INTERFACE_SHADER; struct sdis_interface* box_interfaces[12/*#triangles*/]; struct sdis_interface* square_interfaces[4/*#segments*/]; - double pos[3]; + struct sdis_solve_probe_args solve_args = SDIS_SOLVE_PROBE_ARGS_DEFAULT; double ref; double Tinf; double nu; @@ -262,23 +262,28 @@ main(int argc, char** argv) OK(sdis_interface_ref_put(interf_T4)); OK(sdis_interface_ref_put(interf_T5)); - d3_splat(pos, 0.25); + solve_args.nrealisations = N; + solve_args.position[0] = 0.25; + solve_args.position[1] = 0.25; + solve_args.position[2] = 0.25; /* Test in 3D for various time values. */ nu = (6 * H) / (RHO*CP); Tinf = (H*(T0 + T1 + T2 + T3 + T4 + T5)) / (6 * H); - printf(">>> Temperature of the box at (%g %g %g)\n\n", SPLIT3(pos)); + printf(">>> Temperature of the box at (%g %g %g)\n\n", + SPLIT3(solve_args.position)); FOR_EACH(i, 0, 5) { double time = i ? (double)i / nu : INF; - double time_range[2]; - time_range[0] = time_range[1] = time; ref = Tf_0 * exp(-nu * time) + Tinf * (1 - exp(-nu * time)); + solve_args.time_range[0] = time; + solve_args.time_range[1] = time; + /* Setup stationary state */ *((int*)sdis_data_get(is_stationary)) = IS_INF(time); /* Solve in 3D */ - OK(sdis_solve_probe(box_scn, N, pos, time_range, 1.0, 0, 0, 0, &estimator)); + OK(sdis_solve_probe(box_scn, &solve_args, &estimator)); OK(sdis_estimator_get_temperature(estimator, &T)); OK(sdis_estimator_get_realisation_time(estimator, &mc_time)); OK(sdis_estimator_get_realisation_count(estimator, &nreals)); @@ -291,8 +296,8 @@ main(int argc, char** argv) CHK(eq_eps(T.E, ref, T.SE * 3)); if(IS_INF(time)) { /* Check green function */ - OK(sdis_solve_probe_green_function(box_scn, N, pos, 1.0, 0, 0, &green)); - OK(sdis_green_function_solve(green, time_range, &estimator2)); + OK(sdis_solve_probe_green_function(box_scn, &solve_args, &green)); + OK(sdis_green_function_solve(green, solve_args.time_range, &estimator2)); check_green_function(green); check_estimator_eq(estimator, estimator2); OK(sdis_estimator_ref_put(estimator2)); @@ -306,18 +311,20 @@ main(int argc, char** argv) /* Test in 2D for various time values. */ nu = (4 * H) / (RHO*CP); Tinf = (H * (T0 + T1 + T2 + T3)) / (4 * H); - printf(">>> Temperature of the square at (%g %g)\n\n", SPLIT2(pos)); + printf(">>> Temperature of the square at (%g %g)\n\n", + SPLIT2(solve_args.position)); FOR_EACH(i, 0, 5) { double time = i ? (double)i / nu : INF; - double time_range[2]; - time_range[0] = time_range[1] = time; ref = Tf_0 * exp(-nu * time) + Tinf * (1 - exp(-nu * time)); + solve_args.time_range[0] = time; + solve_args.time_range[1] = time; + /* Setup stationnary state */ *((int*)sdis_data_get(is_stationary)) = IS_INF(time); /* Solve in 2D */ - OK(sdis_solve_probe(square_scn, N, pos, time_range, 1.0, 0, 0, 0, &estimator)); + OK(sdis_solve_probe(square_scn, &solve_args, &estimator)); OK(sdis_estimator_get_realisation_count(estimator, &nreals)); OK(sdis_estimator_get_failure_count(estimator, &nfails)); CHK(nfails + nreals == N); @@ -330,8 +337,8 @@ main(int argc, char** argv) CHK(eq_eps(T.E, ref, T.SE * 3)); if(IS_INF(time)) { /* Check green function */ - OK(sdis_solve_probe_green_function(square_scn, N, pos, 1.0, 0, 0, &green)); - OK(sdis_green_function_solve(green, time_range, &estimator2)); + OK(sdis_solve_probe_green_function(square_scn, &solve_args, &green)); + OK(sdis_green_function_solve(green, solve_args.time_range, &estimator2)); check_green_function(green); check_estimator_eq(estimator, estimator2); OK(sdis_estimator_ref_put(estimator2)); diff --git a/src/test_sdis_convection_non_uniform.c b/src/test_sdis_convection_non_uniform.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -196,9 +196,9 @@ main(int argc, char** argv) struct sdis_fluid_shader fluid_shader = DUMMY_FLUID_SHADER; struct sdis_solid_shader solid_shader = DUMMY_SOLID_SHADER; struct sdis_interface_shader interf_shader = DUMMY_INTERFACE_SHADER; + struct sdis_solve_probe_args solve_args = SDIS_SOLVE_PROBE_ARGS_DEFAULT; struct sdis_interface* box_interfaces[12/*#triangles*/]; struct sdis_interface* square_interfaces[4/*#segments*/]; - double pos[3]; double ref; double Tinf; double nu; @@ -278,23 +278,28 @@ main(int argc, char** argv) OK(sdis_interface_ref_put(interf_T4)); OK(sdis_interface_ref_put(interf_T5)); - d3_splat(pos, 0.25); + solve_args.nrealisations = N; + solve_args.position[0] = 0.25; + solve_args.position[1] = 0.25; + solve_args.position[2] = 0.25; /* Test in 3D for various time values. */ nu = (HC0 + HC1 + HC2 + HC3 + HC4 + HC5) / (RHO * CP); Tinf = (HC0 * T0 + HC1 * T1 + HC2 * T2 + HC3 * T3 + HC4 * T4 + HC5 * T5) / (HC0 + HC1 + HC2 + HC3 + HC4 + HC5); - printf(">>> Temperature of the box at (%g %g %g)\n\n", SPLIT3(pos)); + printf(">>> Temperature of the box at (%g %g %g)\n\n", + SPLIT3(solve_args.position)); FOR_EACH(i, 0, 5) { double time = i ? (double)i / nu : INF; - double time_range[2]; - time_range[0] = time_range[1] = time; + solve_args.time_range[0] = time; + solve_args.time_range[1] = time; + ref = Tf_0 * exp(-nu * time) + Tinf * (1 - exp(-nu * time)); *((int*)sdis_data_get(is_stationary)) = IS_INF(time); /* Solve in 3D */ - OK(sdis_solve_probe(box_scn, N, pos, time_range, 1.0, 0, 0, 0, &estimator)); + OK(sdis_solve_probe(box_scn, &solve_args, &estimator)); OK(sdis_estimator_get_realisation_count(estimator, &nreals)); OK(sdis_estimator_get_failure_count(estimator, &nfails)); CHK(nfails + nreals == N); @@ -307,8 +312,8 @@ main(int argc, char** argv) CHK(eq_eps(T.E, ref, T.SE * 3)); if(IS_INF(time)) { /* Check green function */ - OK(sdis_solve_probe_green_function(box_scn, N, pos, 1.0, 0, 0, &green)); - OK(sdis_green_function_solve(green, time_range, &estimator2)); + OK(sdis_solve_probe_green_function(box_scn, &solve_args, &green)); + OK(sdis_green_function_solve(green, solve_args.time_range, &estimator2)); check_green_function(green); check_estimator_eq(estimator, estimator2); OK(sdis_estimator_ref_put(estimator2)); @@ -322,16 +327,19 @@ main(int argc, char** argv) /* Test in 2D for various time values. */ nu = (HC0 + HC1 + HC2 + HC3) / (RHO * CP); Tinf = (HC0 * T0 + HC1 * T1 + HC2 * T2 + HC3 * T3) / (HC0 + HC1 + HC2 + HC3); - printf(">>> Temperature of the square at (%g %g)\n\n", SPLIT2(pos)); + printf(">>> Temperature of the square at (%g %g)\n\n", + SPLIT2(solve_args.position)); FOR_EACH(i, 0, 5) { double time = i ? (double)i / nu : INF; - double time_range[2]; - time_range[0] = time_range[1] = time; + + solve_args.time_range[0] = time; + solve_args.time_range[1] = time; + ref = Tf_0 * exp(-nu * time) + Tinf * (1 - exp(-nu * time)); *((int*)sdis_data_get(is_stationary)) = IS_INF(time); - OK(sdis_solve_probe(square_scn, N, pos, time_range, 1.0, 0, 0, 0, &estimator)); + OK(sdis_solve_probe(square_scn, &solve_args, &estimator)); OK(sdis_estimator_get_realisation_count(estimator, &nreals)); OK(sdis_estimator_get_failure_count(estimator, &nfails)); CHK(nfails + nreals == N); @@ -344,8 +352,8 @@ main(int argc, char** argv) CHK(eq_eps(T.E, ref, T.SE * 3)); if(IS_INF(time)) { /* Check green function */ - OK(sdis_solve_probe_green_function(square_scn, N, pos, 1.0, 0, 0, &green)); - OK(sdis_green_function_solve(green, time_range, &estimator2)); + OK(sdis_solve_probe_green_function(square_scn, &solve_args, &green)); + OK(sdis_green_function_solve(green, solve_args.time_range, &estimator2)); check_green_function(green); check_estimator_eq(estimator, estimator2); OK(sdis_estimator_ref_put(estimator2)); diff --git a/src/test_sdis_data.c b/src/test_sdis_data.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/test_sdis_device.c b/src/test_sdis_device.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/test_sdis_flux.c b/src/test_sdis_flux.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -136,6 +136,7 @@ solve(struct sdis_scene* scn, const double pos[]) struct sdis_green_function* green; struct sdis_mc T; struct sdis_mc time; + struct sdis_solve_probe_args solve_args = SDIS_SOLVE_PROBE_ARGS_DEFAULT; size_t nreals; size_t nfails; double ref; @@ -145,8 +146,17 @@ solve(struct sdis_scene* scn, const double pos[]) ref = T0 + (1 - pos[0]) * PHI/LAMBDA; + OK(sdis_scene_get_dimension(scn, &dim)); + + solve_args.nrealisations = N; + solve_args.position[0] = pos[0]; + solve_args.position[1] = pos[1]; + solve_args.position[2] = dim == SDIS_SCENE_2D ? 0 : pos[2]; + solve_args.time_range[0] = INF; + solve_args.time_range[1] = INF; + time_current(&t0); - OK(sdis_solve_probe(scn, N, pos, time_range, 1.0, 0, 0, 0, &estimator)); + OK(sdis_solve_probe(scn, &solve_args, &estimator)); time_sub(&t0, time_current(&t1), &t0); time_dump(&t0, TIME_ALL, NULL, dump, sizeof(dump)); @@ -155,8 +165,6 @@ solve(struct sdis_scene* scn, const double pos[]) OK(sdis_estimator_get_temperature(estimator, &T)); OK(sdis_estimator_get_realisation_time(estimator, &time)); - OK(sdis_scene_get_dimension(scn, &dim)); - switch(dim) { case SDIS_SCENE_2D: printf("Temperature at (%g %g) = %g ~ %g +/- %g\n", @@ -177,7 +185,7 @@ solve(struct sdis_scene* scn, const double pos[]) CHK(eq_eps(T.E, ref, T.SE*3)); time_current(&t0); - OK(sdis_solve_probe_green_function(scn, N, pos, 1.0, 0, 0, &green)); + OK(sdis_solve_probe_green_function(scn, &solve_args, &green)); time_current(&t1); OK(sdis_green_function_solve(green, time_range, &estimator2)); time_current(&t2); @@ -241,7 +249,7 @@ main(int argc, char** argv) (void)argc, (void)argv; OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator)); - OK(sdis_device_create(NULL, &allocator, SDIS_NTHREADS_DEFAULT, 0, &dev)); + OK(sdis_device_create(NULL, &allocator, SDIS_NTHREADS_DEFAULT, 1, &dev)); /* Create the dummy fluid medium */ OK(sdis_fluid_create(dev, &fluid_shader, NULL, &fluid)); diff --git a/src/test_sdis_interface.c b/src/test_sdis_interface.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/test_sdis_medium.c b/src/test_sdis_medium.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/test_sdis_scene.c b/src/test_sdis_scene.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,8 +19,8 @@ #include <rsys/double2.h> #include <rsys/double3.h> #include <rsys/math.h> -#include<star/senc.h> #include<star/senc2d.h> +#include<star/senc3d.h> struct context { const double* positions; @@ -93,10 +93,14 @@ test_scene_3d(struct sdis_device* dev, struct sdis_interface* interf) double lower[3], upper[3]; double uv0[2], uv1[2], pos[3], pos1[3]; struct context ctx; - struct senc_descriptor* descriptor; - struct senc2d_descriptor* descriptor2d; + struct senc2d_scene* scn2d; + struct senc3d_scene* scn3d; size_t ntris, npos; 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 }; + size_t dup_vrtx_indices[] = { 0, 1, 2 }; enum sdis_scene_dimension dim; ctx.positions = box_vertices; @@ -116,6 +120,20 @@ test_scene_3d(struct sdis_device* dev, struct sdis_interface* interf) BA(CREATE(dev, ntris, IDS, NULL, npos, POS, &ctx, &scn)); BA(CREATE(dev, ntris, IDS, IFA, 0, POS, &ctx, &scn)); BA(CREATE(dev, ntris, IDS, IFA, npos, NULL, &ctx, &scn)); + /* Duplicated vertex */ + ctx.positions = duplicated_vertices; + ctx.indices = dup_vrtx_indices; + BA(CREATE(dev, 1, IDS, IFA, npos, POS, &ctx, &scn)); + /* Duplicated triangle */ + ctx.positions = box_vertices; + ctx.indices = duplicated_indices; + BA(CREATE(dev, 2, IDS, IFA, npos, POS, &ctx, &scn)); + /* Degenerated triangle */ + ctx.indices = degenerated_indices; + BA(CREATE(dev, 1, IDS, IFA, npos, POS, &ctx, &scn)); + + ctx.positions = box_vertices; + ctx.indices = box_indices; OK(CREATE(dev, ntris, IDS, IFA, npos, POS, &ctx, &scn)); #undef CREATE @@ -172,19 +190,13 @@ test_scene_3d(struct sdis_device* dev, struct sdis_interface* interf) OK(sdis_scene_get_boundary_position(scn, 6, uv1, pos1)); CHK(!d3_eq_eps(pos1, pos, 1.e-6)); - BA(sdis_scene_get_analysis(NULL, NULL)); - BA(sdis_scene_get_analysis(scn, NULL)); - BA(sdis_scene_get_analysis(NULL, &descriptor)); - OK(sdis_scene_get_analysis(scn, &descriptor)); - OK(senc_descriptor_ref_put(descriptor)); + BA(sdis_scene_get_senc3d_scene(NULL, NULL)); + BA(sdis_scene_get_senc3d_scene(scn, NULL)); + BA(sdis_scene_get_senc3d_scene(NULL, &scn3d)); + OK(sdis_scene_get_senc3d_scene(scn, &scn3d)); + OK(senc3d_scene_ref_put(scn3d)); /* No 2D available */ - BA(sdis_scene_2d_get_analysis(scn, &descriptor2d)); - BA(sdis_scene_release_analysis(NULL)); - OK(sdis_scene_release_analysis(scn)); - /* Already released */ - OK(sdis_scene_release_analysis(scn)); - /* Descriptor released: cannot get it anymore */ - BA(sdis_scene_get_analysis(scn, &descriptor)); + BA(sdis_scene_get_senc2d_scene(scn, &scn2d)); BA(sdis_scene_ref_get(NULL)); OK(sdis_scene_ref_get(scn)); @@ -200,10 +212,14 @@ test_scene_2d(struct sdis_device* dev, struct sdis_interface* interf) double lower[2], upper[2]; double u0, u1, pos[2]; struct context ctx; - struct senc2d_descriptor* descriptor; - struct senc_descriptor* descriptor3d; + 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 dup_vrtx_indices[] = { 0, 1 }; enum sdis_scene_dimension dim; ctx.positions = square_vertices; @@ -223,6 +239,20 @@ test_scene_2d(struct sdis_device* dev, struct sdis_interface* interf) BA(CREATE(dev, nsegs, IDS, NULL, npos, POS, &ctx, &scn)); BA(CREATE(dev, nsegs, IDS, IFA, 0, POS, &ctx, &scn)); BA(CREATE(dev, nsegs, IDS, IFA, npos, NULL, &ctx, &scn)); + /* Duplicated vertex */ + ctx.positions = duplicated_vertices; + ctx.indices = dup_vrtx_indices; + BA(CREATE(dev, 1, IDS, IFA, npos, POS, &ctx, &scn)); + /* Duplicated segment */ + ctx.positions = square_vertices; + ctx.indices = duplicated_indices; + BA(CREATE(dev, 2, IDS, IFA, npos, POS, &ctx, &scn)); + /* Degenerated segment */ + ctx.indices = degenerated_indices; + BA(CREATE(dev, 1, IDS, IFA, npos, POS, &ctx, &scn)); + + ctx.positions = square_vertices; + ctx.indices = square_indices; OK(CREATE(dev, nsegs, IDS, IFA, npos, POS, &ctx, &scn)); #undef CREATE @@ -280,20 +310,18 @@ test_scene_2d(struct sdis_device* dev, struct sdis_interface* interf) OK(sdis_scene_boundary_project_position(scn, 3, pos, &u0)); CHK(eq_eps(u0, 1, 1.e-6)); - BA(sdis_scene_2d_get_analysis(NULL, NULL)); - BA(sdis_scene_2d_get_analysis(scn, NULL)); - BA(sdis_scene_2d_get_analysis(NULL, &descriptor)); - OK(sdis_scene_2d_get_analysis(scn, &descriptor)); - OK(senc2d_descriptor_ref_put(descriptor)); + BA(sdis_scene_get_senc2d_scene(NULL, NULL)); + BA(sdis_scene_get_senc2d_scene(scn, NULL)); + BA(sdis_scene_get_senc2d_scene(NULL, &scn2d)); + OK(sdis_scene_get_senc2d_scene(scn, &scn2d)); + OK(senc2d_scene_ref_put(scn2d)); /* No 3D available */ - BA(sdis_scene_get_analysis(scn, &descriptor3d)); - BA(sdis_scene_release_analysis(NULL)); - OK(sdis_scene_release_analysis(scn)); - /* Already released */ - OK(sdis_scene_release_analysis(scn)); - /* Descriptor released: cannot get it anymore */ - BA(sdis_scene_2d_get_analysis(scn, &descriptor)); + BA(sdis_scene_get_senc3d_scene(scn, &scn3d)); + BA(sdis_scene_ref_get(NULL)); + OK(sdis_scene_ref_get(scn)); + BA(sdis_scene_ref_put(NULL)); + OK(sdis_scene_ref_put(scn)); OK(sdis_scene_ref_put(scn)); } @@ -313,7 +341,7 @@ main(int argc, char** argv) interface_shader.convection_coef = DUMMY_INTERFACE_SHADER.convection_coef; OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator)); - OK(sdis_device_create(NULL, &allocator, 1, 0, &dev)); + OK(sdis_device_create(NULL, &allocator, SDIS_NTHREADS_DEFAULT, 1, &dev)); OK(sdis_fluid_create(dev, &fluid_shader, NULL, &fluid)); OK(sdis_solid_create(dev, &solid_shader, NULL, &solid)); diff --git a/src/test_sdis_solid_random_walk_robustness.c b/src/test_sdis_solid_random_walk_robustness.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -273,14 +273,14 @@ main(int argc, char** argv) struct sdis_fluid_shader fluid_shader = DUMMY_FLUID_SHADER; struct sdis_solid_shader solid_shader = SDIS_SOLID_SHADER_NULL; struct sdis_interface_shader interf_shader = SDIS_INTERFACE_SHADER_NULL; + struct sdis_solve_probe_args solve_args = SDIS_SOLVE_PROBE_ARGS_DEFAULT; + struct sdis_solve_medium_args solve_mdm_args = SDIS_SOLVE_MEDIUM_ARGS_DEFAULT; struct interf* interf_param = NULL; struct solid* solid_param = NULL; struct context ctx; - double probe[3]; double lower[3]; double upper[3]; double size[3]; - const double time[2] = {DBL_MAX, DBL_MAX}; (void)argc, (void)argv; OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator)); @@ -347,30 +347,38 @@ main(int argc, char** argv) interf_param->upper[2] = upper[2]; interf_param->h = 1; - probe[0] = 0; - probe[1] = 0; - probe[2] = 0; + solve_args.nrealisations = Nreals; + solve_args.position[0] = 0; + solve_args.position[1] = 0; + solve_args.position[2] = 0; + solve_args.time_range[0] = INF; + solve_args.time_range[1] = INF; + solve_args.register_paths = SDIS_HEAT_PATH_FAILURE; /* Launch probe estimation with trilinear profile set at interfaces */ interf_param->profile = PROFILE_TRILINEAR; - OK(sdis_solve_probe(scn, Nreals, probe, time, 1.0, -1, 0, - SDIS_HEAT_PATH_FAILED, &estimator)); - print_estimation_result(estimator, trilinear_temperature(probe)); + OK(sdis_solve_probe(scn, &solve_args, &estimator)); + print_estimation_result + (estimator, trilinear_temperature(solve_args.position)); OK(sdis_estimator_ref_put(estimator)); /* Launch probe estimation with volumetric power profile set at interfaces */ interf_param->profile = PROFILE_VOLUMETRIC_POWER; solid_param->power = Pw; - OK(sdis_solve_probe(scn, Nreals, probe, time, 1.0, -1, 0, - SDIS_HEAT_PATH_FAILED, &estimator)); - print_estimation_result(estimator, volumetric_temperature(probe, upper)); + OK(sdis_solve_probe(scn, &solve_args, &estimator)); + print_estimation_result + (estimator, volumetric_temperature(solve_args.position, upper)); solid_param->power = SDIS_VOLUMIC_POWER_NONE; OK(sdis_estimator_ref_put(estimator)); /* Launch medium integration */ interf_param->profile = PROFILE_UNKNOWN; - OK(sdis_solve_medium(scn, Nreals, solid, time, 1.0, -1, 0, - SDIS_HEAT_PATH_FAILED, &estimator)); + solve_mdm_args.nrealisations = Nreals; + solve_mdm_args.medium = solid; + solve_mdm_args.time_range[0] = INF; + solve_mdm_args.time_range[1] = INF; + OK(sdis_solve_medium(scn, &solve_mdm_args, &estimator)); + print_estimation_result(estimator, Tfluid); /*dump_heat_paths(stdout, estimator);*/ OK(sdis_estimator_ref_put(estimator)); diff --git a/src/test_sdis_solve_boundary.c b/src/test_sdis_solve_boundary.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -191,20 +191,19 @@ main(int argc, char** argv) struct sdis_interface_shader interf_shader = SDIS_INTERFACE_SHADER_NULL; struct sdis_interface* box_interfaces[12 /*#triangles*/]; struct sdis_interface* square_interfaces[4/*#segments*/]; + struct sdis_solve_probe_boundary_args probe_args = + SDIS_SOLVE_PROBE_BOUNDARY_ARGS_DEFAULT; + struct sdis_solve_boundary_args bound_args = SDIS_SOLVE_BOUNDARY_ARGS_DEFAULT; struct interf* interf_props = NULL; struct fluid* fluid_param; - double uv[2]; double pos[3]; - double time_range[2] = { INF, INF }; - double tr[2]; double ref; size_t prims[4]; enum sdis_side sides[4]; - size_t iprim; (void)argc, (void)argv; OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator)); - OK(sdis_device_create(NULL, &allocator, SDIS_NTHREADS_DEFAULT, 0, &dev)); + OK(sdis_device_create(NULL, &allocator, SDIS_NTHREADS_DEFAULT, 1, &dev)); /* Temporary file used to dump heat paths */ CHK((fp = tmpfile()) != NULL); @@ -297,41 +296,57 @@ main(int argc, char** argv) #define SOLVE sdis_solve_probe_boundary #define GREEN sdis_solve_probe_boundary_green_function - #define F SDIS_FRONT - uv[0] = 0.3; - uv[1] = 0.3; - iprim = 6; - - BA(SOLVE(NULL, N, iprim, uv, time_range, F, 1.0, 0, 0, 0, &estimator)); - BA(SOLVE(box_scn, 0, iprim, uv, time_range, F, 1.0, 0, 0, 0, &estimator)); - BA(SOLVE(box_scn, N, 12, uv, time_range, F, 1.0, 0, 0, 0, &estimator)); - BA(SOLVE(box_scn, N, iprim, NULL, time_range, F, 1.0, 0, 0, 0, &estimator)); - BA(SOLVE(box_scn, N, iprim, uv, NULL, F, 1.0, 0, 0, 0, &estimator)); - BA(SOLVE(box_scn, N, iprim, uv, time_range, -1, 1.0, 0, 0, 0, &estimator)); - BA(SOLVE(box_scn, N, iprim, uv, time_range, F, 1.0, 0, 0, 0, NULL)); - tr[0] = tr[1] = -1; - BA(SOLVE(box_scn, N, iprim, uv, tr, F, 1.0, 0, 0, 0, NULL)); - tr[0] = 1; - BA(SOLVE(box_scn, N, iprim, uv, tr, F, 1.0, 0, 0, 0, NULL)); - tr[1] = 0; - BA(SOLVE(box_scn, N, iprim, uv, tr, F, 1.0, 0, 0, 0, NULL)); - - OK(SOLVE(box_scn, N, iprim, uv, time_range, F, 1.0, 0, 0, 0, &estimator)); - OK(sdis_scene_get_boundary_position(box_scn, iprim, uv, pos)); + + probe_args.nrealisations = N; + probe_args.uv[0] = 0.3; + probe_args.uv[1] = 0.3; + probe_args.iprim = 6; + probe_args.time_range[0] = INF; + probe_args.time_range[1] = INF; + probe_args.side = SDIS_FRONT; + + BA(SOLVE(NULL, &probe_args, &estimator)); + BA(SOLVE(box_scn, NULL, &estimator)); + BA(SOLVE(box_scn, &probe_args, NULL)); + probe_args.nrealisations = 0; + BA(SOLVE(box_scn, &probe_args, &estimator)); + probe_args.nrealisations = N; + probe_args.iprim = 12; + BA(SOLVE(box_scn, &probe_args, &estimator)); + probe_args.iprim = 6; + probe_args.side = SDIS_SIDE_NULL__; + BA(SOLVE(box_scn, &probe_args, &estimator)); + probe_args.side = SDIS_FRONT; + probe_args.time_range[0] = probe_args.time_range[1] = -1; + BA(SOLVE(box_scn, &probe_args, &estimator)); + probe_args.time_range[0] = 1; + BA(SOLVE(box_scn, &probe_args, &estimator)); + probe_args.time_range[1] = 0; + BA(SOLVE(box_scn, &probe_args, &estimator)); + probe_args.time_range[0] = probe_args.time_range[1] = INF; + + OK(SOLVE(box_scn, &probe_args, &estimator)); + OK(sdis_scene_get_boundary_position + (box_scn, probe_args.iprim, probe_args.uv, pos)); printf("Boundary temperature of the box at (%g %g %g) = ", SPLIT3(pos)); check_estimator(estimator, N, ref); - BA(GREEN(NULL, N, iprim, uv, F, 1, 0, 0, &green)); - BA(GREEN(box_scn, 0, iprim, uv, F, 1, 0, 0, &green)); - BA(GREEN(box_scn, N, 12, uv, F, 1, 0, 0, &green)); - BA(GREEN(box_scn, N, iprim, NULL, F, 1, 0, 0, &green)); - BA(GREEN(box_scn, N, iprim, uv, -1, 1, 0, 0, &green)); - BA(GREEN(box_scn, N, iprim, uv, F, 0, 0, 0, &green)); - BA(GREEN(box_scn, N, iprim, uv, F, 1, 0, 0, NULL)); + BA(GREEN(NULL, &probe_args, &green)); + BA(GREEN(box_scn, NULL, &green)); + BA(GREEN(box_scn, &probe_args, NULL)); + probe_args.nrealisations = 0; + BA(GREEN(box_scn, &probe_args, &green)); + probe_args.nrealisations = N; + probe_args.iprim = 12; + BA(GREEN(box_scn, &probe_args, &green)); + probe_args.iprim = 6; + probe_args.side = SDIS_SIDE_NULL__; + BA(GREEN(box_scn, &probe_args, &green)); + probe_args.side = SDIS_FRONT; + OK(GREEN(box_scn, &probe_args, &green)); - OK(GREEN(box_scn, N, iprim, uv, F, 1, 0, 0, &green)); check_green_function(green); - OK(sdis_green_function_solve(green, time_range, &estimator2)); + OK(sdis_green_function_solve(green, probe_args.time_range, &estimator2)); check_estimator(estimator2, N, ref); OK(sdis_green_function_ref_put(green)); @@ -339,27 +354,29 @@ main(int argc, char** argv) OK(sdis_estimator_ref_put(estimator2)); /* Dump paths */ - OK(SOLVE(box_scn, N_dump, iprim, uv, time_range, F, 1.0, 0, 0, - SDIS_HEAT_PATH_ALL, &estimator)); + probe_args.nrealisations = N_dump; + probe_args.register_paths = SDIS_HEAT_PATH_ALL; + OK(SOLVE(box_scn, &probe_args, &estimator)); dump_heat_paths(fp, estimator); OK(sdis_estimator_ref_put(estimator)); /* The external fluid cannot have an unknown temperature */ fluid_param->temperature = UNKNOWN_TEMPERATURE; - BA(SOLVE(box_scn, N, iprim, uv, time_range, F, 1.0, 0, 0, 0, &estimator)); + BA(SOLVE(box_scn, &probe_args, &estimator)); fluid_param->temperature = Tf; - uv[0] = 0.5; - iprim = 3; - BA(SOLVE(square_scn, N, 4, uv, time_range, F, 1.0, 0, 0, 0, &estimator)); - OK(SOLVE(square_scn, N, iprim, uv, time_range, F, 1.0, 0, 0, 0, &estimator)); - OK(sdis_scene_get_boundary_position(square_scn, iprim, uv, pos)); - printf("Boundary temperature of the square at (%g %g) = ", SPLIT2(pos)); - check_estimator(estimator, N, ref); + probe_args.nrealisations = N; + probe_args.register_paths = SDIS_HEAT_PATH_NONE; + probe_args.uv[0] = 0.5; + probe_args.iprim = 4; + + BA(SOLVE(square_scn, &probe_args, &estimator)); + probe_args.iprim = 3; + OK(SOLVE(square_scn, &probe_args, &estimator)); - OK(GREEN(square_scn, N, iprim, uv, F, 1, 0, 0, &green)); + OK(GREEN(square_scn, &probe_args, &green)); check_green_function(green); - OK(sdis_green_function_solve(green, time_range, &estimator2)); + OK(sdis_green_function_solve(green, probe_args.time_range, &estimator2)); check_estimator(estimator2, N, ref); OK(sdis_estimator_ref_put(estimator)); @@ -368,7 +385,7 @@ main(int argc, char** argv) /* The external fluid cannot have an unknown temperature */ fluid_param->temperature = UNKNOWN_TEMPERATURE; - BA(SOLVE(square_scn, N, iprim, uv, time_range, F, 1.0, 0, 0, 0, &estimator)); + BA(SOLVE(square_scn, &probe_args, &estimator)); fluid_param->temperature = Tf; #undef F @@ -380,40 +397,78 @@ main(int argc, char** argv) sides[2] = SDIS_FRONT; sides[3] = SDIS_FRONT; + bound_args.nrealisations = N; + bound_args.sides = sides; + bound_args.primitives = prims; + bound_args.nprimitives = 2; + bound_args.time_range[0] = INF; + bound_args.time_range[1] = INF; + #define SOLVE sdis_solve_boundary #define GREEN sdis_solve_boundary_green_function prims[0] = 6; prims[1] = 7; - BA(SOLVE(NULL, N, prims, sides, 2, time_range, 1.0, 0, 0, 0, &estimator)); - BA(SOLVE(box_scn, 0, prims, sides, 2, time_range, 1.0, 0, 0, 0, &estimator)); - BA(SOLVE(box_scn, N, NULL, sides, 2, time_range, 1.0, 0, 0, 0, &estimator)); - BA(SOLVE(box_scn, N, prims, NULL, 2, time_range, 1.0, 0, 0, 0, &estimator)); - BA(SOLVE(box_scn, N, prims, sides, 0, time_range, 1.0, 0, 0, 0, &estimator)); - BA(SOLVE(box_scn, N, prims, sides, 2, NULL, 1.0, 0, 0, 0, &estimator)); - BA(SOLVE(box_scn, N, prims, sides, 2, time_range, 1.0, 0, 0, 0, NULL)); - tr[0] = tr[1] = -1; - BA(SOLVE(box_scn, N, prims, sides, 2, tr, 1.0, 0, 0, 0, NULL)); - tr[0] = 1; - BA(SOLVE(box_scn, N, prims, sides, 2, tr, 1.0, 0, 0, 0, NULL)); - tr[1] = 0; - BA(SOLVE(box_scn, N, prims, sides, 2, tr, 1.0, 0, 0, 0, NULL)); + + BA(SOLVE(NULL, &bound_args, &estimator)); + BA(SOLVE(box_scn, NULL, &estimator)); + BA(SOLVE(box_scn, &bound_args, NULL)); + bound_args.nrealisations = 0; + BA(SOLVE(box_scn, &bound_args, &estimator)); + bound_args.nrealisations = N; + bound_args.primitives = NULL; + BA(SOLVE(box_scn, &bound_args, &estimator)); + bound_args.primitives = prims; + bound_args.sides = NULL; + BA(SOLVE(box_scn, &bound_args, &estimator)); + bound_args.sides = sides; + bound_args.nprimitives = 0; + BA(SOLVE(box_scn, &bound_args, &estimator)); + bound_args.nprimitives = 2; + prims[0] = 12; + BA(SOLVE(box_scn, &bound_args, &estimator)); + prims[0] = 6; + sides[0] = SDIS_SIDE_NULL__; + BA(SOLVE(box_scn, &bound_args, &estimator)); + sides[0] = SDIS_FRONT; + bound_args.time_range[0] = bound_args.time_range[1] = -1; + BA(SOLVE(box_scn, &bound_args, &estimator)); + bound_args.time_range[0] = 1; + BA(SOLVE(box_scn, &bound_args, &estimator)); + bound_args.time_range[1] = 0; + BA(SOLVE(box_scn, &bound_args, &estimator)); + bound_args.time_range[0] = bound_args.time_range[1] = INF; /* Average temperature on the right side of the box */ - OK(SOLVE(box_scn, N, prims, sides, 2, time_range, 1.0, 0, 0, 0, &estimator)); + OK(SOLVE(box_scn, &bound_args, &estimator)); printf("Average temperature of the right side of the box = "); check_estimator(estimator, N, ref); - BA(GREEN(NULL, N, prims, sides, 2, 1.0, 0, 0, &green)); - BA(GREEN(box_scn, 0, prims, sides, 2, 1.0, 0, 0, &green)); - BA(GREEN(box_scn, N, NULL, sides, 2, 1.0, 0, 0, &green)); - BA(GREEN(box_scn, N, prims, NULL, 2, 1.0, 0, 0, &green)); - BA(GREEN(box_scn, N, prims, sides, 0, 1.0, 0, 0, &green)); - BA(GREEN(box_scn, N, prims, sides, 2, 0.0, 0, 0, &green)); - BA(GREEN(box_scn, N, prims, sides, 2, 1.0, 0, 0, NULL)); + BA(GREEN(NULL, &bound_args, &green)); + BA(GREEN(box_scn, NULL, &green)); + BA(GREEN(box_scn, &bound_args, NULL)); + bound_args.nrealisations = 0; + BA(GREEN(box_scn, &bound_args, &green)); + bound_args.nrealisations = N; + bound_args.primitives = NULL; + BA(GREEN(box_scn, &bound_args, &green)); + bound_args.primitives = prims; + bound_args.sides = NULL; + BA(GREEN(box_scn, &bound_args, &green)); + bound_args.sides = sides; + bound_args.nprimitives = 0; + BA(GREEN(box_scn, &bound_args, &green)); + bound_args.nprimitives = 2; + prims[0] = 12; + BA(GREEN(box_scn, &bound_args, &green)); + prims[0] = 6; + sides[0] = SDIS_SIDE_NULL__; + BA(GREEN(box_scn, &bound_args, &green)); + sides[0] = SDIS_FRONT; + - OK(GREEN(box_scn, N, prims, sides, 2, 1.0, 0, 0, &green)); + OK(GREEN(box_scn, &bound_args, &green)); check_green_function(green); - OK(sdis_green_function_solve(green, time_range, &estimator2)); + OK(sdis_green_function_solve(green, bound_args.time_range, &estimator2)); check_estimator(estimator2, N, ref); OK(sdis_green_function_ref_put(green)); @@ -421,21 +476,35 @@ main(int argc, char** argv) OK(sdis_estimator_ref_put(estimator2)); /* Dump path */ - OK(SOLVE(box_scn, N_dump, prims, sides, 2, time_range, 1.0, 0, 0, - SDIS_HEAT_PATH_ALL, &estimator)); + bound_args.nrealisations = N_dump; + bound_args.register_paths = SDIS_HEAT_PATH_ALL; + + /* Check simulation error handling when paths are registered */ + fluid_param->temperature = UNKNOWN_TEMPERATURE; + BA(SOLVE(box_scn, &bound_args, &estimator)); + + /* Dump path */ + fluid_param->temperature = Tf; + OK(SOLVE(box_scn, &bound_args, &estimator)); dump_heat_paths(fp, estimator); OK(sdis_estimator_ref_put(estimator)); + /* Switch in 2D */ + bound_args.nrealisations = N; + bound_args.register_paths = SDIS_HEAT_PATH_NONE; + bound_args.nprimitives = 1; + prims[0] = 4; + BA(SOLVE(square_scn, &bound_args, &estimator)); + /* Average temperature on the right side of the square */ prims[0] = 3; - sides[0] = SDIS_FRONT; - OK(SOLVE(square_scn, N, prims, sides, 1, time_range, 1.0, 0, 0, 0, &estimator)); + OK(SOLVE(square_scn, &bound_args, &estimator)); printf("Average temperature of the right side of the square = "); check_estimator(estimator, N, ref); - OK(GREEN(square_scn, N, prims, sides, 1, 1.0, 0, 0, &green)); + OK(GREEN(square_scn, &bound_args, &green)); check_green_function(green); - OK(sdis_green_function_solve(green, time_range, &estimator2)); + OK(sdis_green_function_solve(green, bound_args.time_range, &estimator2)); check_estimator(estimator2, N, ref); OK(sdis_green_function_ref_put(green)); @@ -443,16 +512,14 @@ main(int argc, char** argv) OK(sdis_estimator_ref_put(estimator2)); /* Dump path */ - OK(SOLVE(square_scn, N_dump, prims, sides, 1, time_range, 1.0, 0, 0, - SDIS_HEAT_PATH_ALL, &estimator)); + bound_args.nrealisations = N_dump; + bound_args.register_paths = SDIS_HEAT_PATH_ALL; + OK(SOLVE(square_scn, &bound_args, &estimator)); dump_heat_paths(fp, estimator); OK(sdis_estimator_ref_put(estimator)); - /* Check out of bound prims */ - prims[0] = 12; - BA(SOLVE(box_scn, N, prims, sides, 2, time_range, 1.0, 0, 0, 0, &estimator)); - prims[0] = 4; - BA(SOLVE(square_scn, N, prims, sides, 1, time_range, 1.0, 0, 0, 0, &estimator)); + bound_args.register_paths = SDIS_HEAT_PATH_NONE; + bound_args.nrealisations = N; /* Average temperature on the left+right sides of the box */ prims[0] = 2; @@ -462,13 +529,14 @@ main(int argc, char** argv) ref = (ref + Tb) / 2; - OK(SOLVE(box_scn, N, prims, sides, 4, time_range, 1.0, 0, 0, 0, &estimator)); + bound_args.nprimitives = 4; + OK(SOLVE(box_scn, &bound_args, &estimator)); printf("Average temperature of the left+right sides of the box = "); check_estimator(estimator, N, ref); - OK(GREEN(box_scn, N, prims, sides, 4, 1.0, 0, 0, &green)); + OK(GREEN(box_scn, &bound_args, &green)); check_green_function(green); - OK(sdis_green_function_solve(green, time_range, &estimator2)); + OK(sdis_green_function_solve(green, bound_args.time_range, &estimator2)); check_estimator(estimator2, N, ref); OK(sdis_green_function_ref_put(green)); @@ -478,13 +546,14 @@ main(int argc, char** argv) /* Average temperature on the left+right sides of the square */ prims[0] = 1; prims[1] = 3; - OK(SOLVE(square_scn, N, prims, sides, 2, time_range, 1.0, 0, 0, 0, &estimator)); + bound_args.nprimitives = 2; + OK(SOLVE(square_scn, &bound_args, &estimator)); printf("Average temperature of the left+right sides of the square = "); check_estimator(estimator, N, ref); - OK(GREEN(square_scn, N, prims, sides, 2, 1.0, 0, 0, &green)); + OK(GREEN(square_scn, &bound_args, &green)); check_green_function(green); - OK(sdis_green_function_solve(green, time_range, &estimator2)); + OK(sdis_green_function_solve(green, bound_args.time_range, &estimator2)); check_estimator(estimator2, N, ref); OK(sdis_green_function_ref_put(green)); diff --git a/src/test_sdis_solve_boundary_flux.c b/src/test_sdis_solve_boundary_flux.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -234,16 +234,16 @@ main(int argc, char** argv) struct sdis_interface_shader interf_shader = SDIS_INTERFACE_SHADER_NULL; struct sdis_interface* box_interfaces[12 /*#triangles*/]; struct sdis_interface* square_interfaces[4/*#segments*/]; + struct sdis_solve_probe_boundary_flux_args probe_args = + SDIS_SOLVE_PROBE_BOUNDARY_FLUX_ARGS_DEFAULT; + struct sdis_solve_boundary_flux_args bound_args = + SDIS_SOLVE_BOUNDARY_FLUX_ARGS_DEFAULT; struct interf* interf_props = NULL; struct fluid* fluid_param; enum sdis_estimator_type type; - double uv[2]; double pos[3]; - double time_range[2] = { INF, INF }; - double tr[2]; double analyticT, analyticCF, analyticRF, analyticTF; size_t prims[2]; - size_t iprim; (void)argc, (void)argv; OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator)); @@ -345,81 +345,109 @@ main(int argc, char** argv) analyticTF = analyticCF + analyticRF; #define SOLVE sdis_solve_probe_boundary_flux - uv[0] = 0.3; - uv[1] = 0.3; - iprim = 6; - - BA(SOLVE(NULL, N, iprim, uv, time_range, 1.0, Trad, Tref, &estimator)); - BA(SOLVE(box_scn, 0, iprim, uv, time_range, 1.0, Trad, Tref, &estimator)); - BA(SOLVE(box_scn, N, 12, uv, time_range, 1.0, Trad, Tref, &estimator)); - BA(SOLVE(box_scn, N, iprim, NULL, time_range, 1.0, Trad, Tref, &estimator)); - BA(SOLVE(box_scn, N, iprim, uv, NULL, 1.0, Trad, Tref, &estimator)); - BA(SOLVE(box_scn, N, iprim, uv, time_range, 1.0, Trad, Tref, NULL)); - tr[0] = tr[1] = -1; - BA(SOLVE(box_scn, N, iprim, uv, tr, 1.0, Trad, Tref, &estimator)); - tr[0] = 1; - BA(SOLVE(box_scn, N, iprim, uv, tr, 1.0, Trad, Tref, &estimator)); - tr[1] = 0; - BA(SOLVE(box_scn, N, iprim, uv, tr, 1.0, Trad, Tref, &estimator)); - tr[1] = INF; - BA(SOLVE(box_scn, N, iprim, uv, tr, 1.0, Trad, Tref, &estimator)); - - OK(SOLVE(box_scn, N, iprim, uv, time_range, 1.0, Trad, Tref, &estimator)); + probe_args.nrealisations = N; + probe_args.iprim = 6; + probe_args.uv[0] = 0.3; + probe_args.uv[1] = 0.3; + probe_args.time_range[0] = INF; + probe_args.time_range[1] = INF; + probe_args.ambient_radiative_temperature = Trad; + probe_args.reference_temperature = Tref; + BA(SOLVE(NULL, &probe_args, &estimator)); + BA(SOLVE(box_scn, NULL, &estimator)); + BA(SOLVE(box_scn, &probe_args, NULL)); + probe_args.nrealisations = 0; + BA(SOLVE(box_scn, &probe_args, &estimator)); + probe_args.nrealisations = N; + probe_args.iprim = 12; + BA(SOLVE(box_scn, &probe_args, &estimator)); + probe_args.iprim = 6; + probe_args.uv[0] = probe_args.uv[1] = 1; + BA(SOLVE(box_scn, &probe_args, &estimator)); + probe_args.uv[0] = probe_args.uv[1] = 0.3; + probe_args.time_range[0] = probe_args.time_range[1] = -1; + BA(SOLVE(box_scn, &probe_args, &estimator)); + probe_args.time_range[0] = 1; + BA(SOLVE(box_scn, &probe_args, &estimator)); + probe_args.time_range[1] = 0; + BA(SOLVE(box_scn, &probe_args, &estimator)); + probe_args.time_range[1] = INF; + BA(SOLVE(box_scn, &probe_args, &estimator)); + probe_args.time_range[0] = INF; + OK(SOLVE(box_scn, &probe_args, &estimator)); + OK(sdis_estimator_get_type(estimator, &type)); CHK(type == SDIS_ESTIMATOR_FLUX); - OK(sdis_scene_get_boundary_position(box_scn, iprim, uv, pos)); + OK(sdis_scene_get_boundary_position + (box_scn, probe_args.iprim, probe_args.uv, pos)); printf("Boundary values of the box at (%g %g %g) = ", SPLIT3(pos)); check_estimator(estimator, N, analyticT, analyticCF, analyticRF, analyticTF); OK(sdis_estimator_ref_put(estimator)); - uv[0] = 0.5; - iprim = 3; - BA(SOLVE(square_scn, N, 4, uv, time_range, 1.0, Trad, Tref, &estimator)); - OK(SOLVE(square_scn, N, iprim, uv, time_range, 1.0, Trad, Tref, &estimator)); - OK(sdis_scene_get_boundary_position(square_scn, iprim, uv, pos)); + probe_args.uv[0] = 0.5; + probe_args.iprim = 4; + BA(SOLVE(square_scn, &probe_args, &estimator)); + probe_args.iprim = 3; + OK(SOLVE(square_scn, &probe_args, &estimator)); + OK(sdis_scene_get_boundary_position + (square_scn, probe_args.iprim, probe_args.uv, pos)); printf("Boundary values of the square at (%g %g) = ", SPLIT2(pos)); check_estimator(estimator, N, analyticT, analyticCF, analyticRF, analyticTF); OK(sdis_estimator_ref_put(estimator)); #undef F #undef SOLVE - + #define SOLVE sdis_solve_boundary_flux prims[0] = 6; prims[1] = 7; - BA(SOLVE(NULL, N, prims, 2, time_range, 1.0, Trad, Tref, &estimator)); - BA(SOLVE(box_scn, 0, prims, 2, time_range, 1.0, Trad, Tref, &estimator)); - BA(SOLVE(box_scn, N, NULL, 2, time_range, 1.0, Trad, Tref, &estimator)); - BA(SOLVE(box_scn, N, prims, 0, time_range, 1.0, Trad, Tref, &estimator)); - BA(SOLVE(box_scn, N, prims, 2, NULL, 1.0, Trad, Tref, &estimator)); - BA(SOLVE(box_scn, N, prims, 2, time_range, 1.0, Trad, Tref, NULL)); - tr[0] = tr[1] = -1; - BA(SOLVE(box_scn, N, prims, 2, tr, 1.0, Trad, Tref, NULL)); - tr[0] = 1; - BA(SOLVE(box_scn, N, prims, 2, tr, 1.0, Trad, Tref, NULL)); - tr[1] = 0; - BA(SOLVE(box_scn, N, prims, 2, tr, 1.0, Trad, Tref, NULL)); + bound_args.nrealisations = N; + bound_args.primitives = prims; + bound_args.nprimitives = 2; + bound_args.time_range[0] = INF; + bound_args.time_range[1] = INF; + bound_args.ambient_radiative_temperature = Trad; + bound_args.reference_temperature = Tref; + + BA(SOLVE(NULL, &bound_args, &estimator)); + BA(SOLVE(box_scn, NULL, &estimator)); + BA(SOLVE(box_scn, &bound_args, NULL)); + bound_args.primitives = NULL; + BA(SOLVE(box_scn, &bound_args, &estimator)); + bound_args.primitives = prims; + bound_args.nprimitives = 0; + BA(SOLVE(box_scn, &bound_args, &estimator)); + bound_args.nprimitives = 2; + bound_args.time_range[0] = bound_args.time_range[1] = -1; + BA(SOLVE(box_scn, &bound_args, &estimator)); + bound_args.time_range[0] = 1; + BA(SOLVE(box_scn, &bound_args, &estimator)); + bound_args.time_range[1] = 0; + BA(SOLVE(box_scn, &bound_args, &estimator)); + bound_args.time_range[1] = INF; + BA(SOLVE(box_scn, &bound_args, &estimator)); + bound_args.time_range[0] = INF; + prims[0] = 12; + BA(SOLVE(box_scn, &bound_args, &estimator)); + prims[0] = 6; + OK(SOLVE(box_scn, &bound_args, &estimator)); /* Average temperature on the right side of the box */ - OK(SOLVE(box_scn, N, prims, 2, time_range, 1.0, Trad, Tref, &estimator)); printf("Average values of the right side of the box = "); check_estimator(estimator, N, analyticT, analyticCF, analyticRF, analyticTF); OK(sdis_estimator_ref_put(estimator)); /* Average temperature on the right side of the square */ + prims[0] = 4; + bound_args.nprimitives = 1; + BA(SOLVE(square_scn, &bound_args, &estimator)); prims[0] = 3; - OK(SOLVE(square_scn, N, prims, 1, time_range, 1.0, Trad, Tref, &estimator)); + OK(SOLVE(square_scn, &bound_args, &estimator)); printf("Average values of the right side of the square = "); check_estimator(estimator, N, analyticT, analyticCF, analyticRF, analyticTF); OK(sdis_estimator_ref_put(estimator)); - - /* Check out of bound prims */ - prims[0] = 12; - BA(SOLVE(box_scn, N, prims, 2, time_range, 1.0, Trad, Tref, &estimator)); - prims[0] = 4; - BA(SOLVE(square_scn, N, prims, 1, time_range, 1.0, Trad, Tref, &estimator)); - + /* Average temperature on the left side of the box */ prims[0] = 2; prims[1] = 3; @@ -429,14 +457,16 @@ main(int argc, char** argv) analyticRF = Hrad * (analyticT - Trad); analyticTF = analyticCF + analyticRF; - OK(SOLVE(box_scn, N, prims, 2, time_range, 1.0, Trad, Tref, &estimator)); + bound_args.nprimitives = 2; + OK(SOLVE(box_scn, &bound_args, &estimator)); printf("Average values of the left side of the box = "); check_estimator(estimator, N, analyticT, analyticCF, analyticRF, analyticTF); OK(sdis_estimator_ref_put(estimator)); /* Average temperature on the left/right side of the square */ prims[0] = 1; - OK(SOLVE(square_scn, N, prims, 1, time_range, 1.0, Trad, Tref, &estimator)); + bound_args.nprimitives = 1; + OK(SOLVE(square_scn, &bound_args, &estimator)); printf("Average values of the left side of the square = "); check_estimator(estimator, N, analyticT, analyticCF, analyticRF, analyticTF); OK(sdis_estimator_ref_put(estimator)); diff --git a/src/test_sdis_solve_camera.c b/src/test_sdis_solve_camera.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -35,7 +35,7 @@ /* * The scene is composed of a solid cube whose temperature is unknown. The * emissivity of the cube is 1 and its convection coefficient with the - * surrounding fluid is null. At the center of the cube there is a spherical + * surrounding fluid at 300K is 0.1. At the center of the cube there is a spherical * fluid cavity whose temperature is 350K. The convection coefficient between * the solid and the cavity is 1 and the emissivity of this interface is null. * The ambient radiative temperature of the system is 300K. @@ -540,16 +540,18 @@ main(int argc, char** argv) struct sdis_interface* interf0 = NULL; struct sdis_interface* interf1 = NULL; struct sdis_scene* scn = NULL; + struct sdis_solve_camera_args solve_args = SDIS_SOLVE_CAMERA_ARGS_DEFAULT; + struct ssp_rng* rng_state = NULL; struct fluid fluid_param = FLUID_NULL; struct solid solid_param = SOLID_NULL; struct interf interface_param = INTERF_NULL; + struct fluid* pfluid_param = NULL; size_t ntris, npos; size_t nreals, nfails; size_t definition[2]; double pos[3]; double tgt[3]; double up[3]; - double trange[2] = {INF, INF}; (void)argc, (void)argv; OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator)); @@ -562,7 +564,7 @@ main(int argc, char** argv) create_fluid(dev, &fluid_param, &fluid0); /* Create the fluid1 */ - fluid_param.temperature = UNKOWN_TEMPERATURE; + fluid_param.temperature = 300; fluid_param.rho = 0; fluid_param.cp = 0; create_fluid(dev, &fluid_param, &fluid1); @@ -583,17 +585,12 @@ main(int argc, char** argv) create_interface(dev, solid, fluid0, &interface_param, &interf0); /* Create the fluid1/solid interface */ - interface_param.hc = 0; + interface_param.hc = 0.1; interface_param.epsilon = 1; interface_param.specular_fraction = 1; interface_param.temperature = UNKOWN_TEMPERATURE; create_interface(dev, fluid1, solid, &interface_param, &interf1); - /* Release the ownership onto the media */ - OK(sdis_medium_ref_put(solid)); - OK(sdis_medium_ref_put(fluid0)); - OK(sdis_medium_ref_put(fluid1)); - /* Setup the cube geometry */ OK(s3dut_create_cuboid(&allocator, 2, 2, 2, &msh)); OK(s3dut_mesh_get_data(msh, &msh_data)); @@ -633,36 +630,40 @@ main(int argc, char** argv) dump_mesh(stdout, geom.positions, npos, geom.indices, ntris); exit(0); #endif - BA(sdis_solve_camera(NULL, cam, trange, 1, 300, 300, IMG_WIDTH, IMG_HEIGHT, - SPP, SDIS_HEAT_PATH_NONE, &buf)); - BA(sdis_solve_camera(scn, NULL, trange, 1, 300, 300, IMG_WIDTH, IMG_HEIGHT, - SPP, SDIS_HEAT_PATH_NONE, &buf)); - BA(sdis_solve_camera(scn, cam, NULL, 1, 300, 300, IMG_WIDTH, IMG_HEIGHT, - SPP, SDIS_HEAT_PATH_NONE, &buf)); - BA(sdis_solve_camera(scn, cam, trange, 0, 300, 300, IMG_WIDTH, IMG_HEIGHT, - SPP, SDIS_HEAT_PATH_NONE, &buf)); - BA(sdis_solve_camera(scn, cam, trange, 1, 300, -1, IMG_WIDTH, IMG_HEIGHT, - SPP, SDIS_HEAT_PATH_NONE, &buf)); - BA(sdis_solve_camera(scn, cam, trange, 1, 300, 300, 0, IMG_HEIGHT, - SPP, SDIS_HEAT_PATH_NONE, &buf)); - BA(sdis_solve_camera(scn, cam, trange, 1, 300, 300, IMG_WIDTH, 0, - SPP, SDIS_HEAT_PATH_NONE, &buf)); - BA(sdis_solve_camera(scn, cam, trange, 1, 300, 300, IMG_WIDTH, IMG_HEIGHT, - 0, SDIS_HEAT_PATH_NONE, &buf)); - BA(sdis_solve_camera(scn, cam, trange, 1, 300, 300, IMG_WIDTH, IMG_HEIGHT, - SPP, SDIS_HEAT_PATH_NONE, NULL)); - - trange[0] = -1; - BA(sdis_solve_camera(scn, cam, trange, 1, 300, 300, IMG_WIDTH, IMG_HEIGHT, - SPP, SDIS_HEAT_PATH_NONE, &buf)); - trange[0] = 10; trange[1] = 1; - BA(sdis_solve_camera(scn, cam, trange, 1, 300, 300, IMG_WIDTH, IMG_HEIGHT, - SPP, SDIS_HEAT_PATH_NONE, &buf)); - trange[0] = trange[1] = INF; + solve_args.cam = cam; + solve_args.time_range[0] = INF; + solve_args.time_range[0] = INF; + solve_args.image_resolution[0] = IMG_WIDTH; + solve_args.image_resolution[1] = IMG_HEIGHT; + solve_args.ambient_radiative_temperature = 300; + solve_args.reference_temperature = 300; + solve_args.spp = SPP; + + BA(sdis_solve_camera(NULL, &solve_args, &buf)); + BA(sdis_solve_camera(scn, NULL, &buf)); + BA(sdis_solve_camera(scn, &solve_args, NULL)); + solve_args.cam = NULL; + BA(sdis_solve_camera(scn, &solve_args, &buf)); + solve_args.cam = cam; + solve_args.fp_to_meter = 0; + BA(sdis_solve_camera(scn, &solve_args, &buf)); + solve_args.fp_to_meter = 1; + solve_args.ambient_radiative_temperature = -1; + BA(sdis_solve_camera(scn, &solve_args, &buf)); + solve_args.ambient_radiative_temperature = 300; + solve_args.reference_temperature = -1; + BA(sdis_solve_camera(scn, &solve_args, &buf)); + solve_args.reference_temperature = 300; + solve_args.time_range[0] = solve_args.time_range[1] = -1; + BA(sdis_solve_camera(scn, &solve_args, &buf)); + solve_args.time_range[0] = 1; + BA(sdis_solve_camera(scn, &solve_args, &buf)); + solve_args.time_range[1] = 0; + BA(sdis_solve_camera(scn, &solve_args, &buf)); + solve_args.time_range[0] = solve_args.time_range[1] = INF; /* Launch the simulation */ - OK(sdis_solve_camera(scn, cam, trange, 1, 300, 300, IMG_WIDTH, IMG_HEIGHT, - SPP, SDIS_HEAT_PATH_NONE, &buf)); + OK(sdis_solve_camera(scn, &solve_args, &buf)); BA(sdis_estimator_buffer_get_realisation_count(NULL, &nreals)); BA(sdis_estimator_buffer_get_realisation_count(buf, NULL)); @@ -680,6 +681,10 @@ main(int argc, char** argv) BA(sdis_estimator_buffer_get_realisation_time(buf, NULL)); OK(sdis_estimator_buffer_get_realisation_time(buf, &time)); + BA(sdis_estimator_buffer_get_rng_state(NULL, &rng_state)); + BA(sdis_estimator_buffer_get_rng_state(buf, NULL)); + OK(sdis_estimator_buffer_get_rng_state(buf, &rng_state)); + CHK(nreals + nfails == IMG_WIDTH*IMG_HEIGHT*SPP); fprintf(stderr, "Overall temperature ~ %g +/- %g\n", T.E, T.SE); @@ -695,9 +700,20 @@ main(int argc, char** argv) /* Write the image */ dump_image(buf); + OK(sdis_estimator_buffer_ref_put(buf)); + + pfluid_param = sdis_data_get(sdis_medium_get_data(fluid1)); + pfluid_param->temperature = UNKOWN_TEMPERATURE; + + /* Check simulation error handling */ + BA(sdis_solve_camera(scn, &solve_args, &buf)); + solve_args.register_paths = SDIS_HEAT_PATH_ALL; + BA(sdis_solve_camera(scn, &solve_args, &buf)); /* Release memory */ - OK(sdis_estimator_buffer_ref_put(buf)); + OK(sdis_medium_ref_put(solid)); + OK(sdis_medium_ref_put(fluid0)); + OK(sdis_medium_ref_put(fluid1)); OK(sdis_scene_ref_put(scn)); OK(sdis_camera_ref_put(cam)); OK(sdis_interface_ref_put(interf0)); diff --git a/src/test_sdis_solve_medium.c b/src/test_sdis_solve_medium.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -223,8 +223,8 @@ main(int argc, char** argv) struct sdis_fluid_shader fluid_shader = DUMMY_FLUID_SHADER; struct sdis_solid_shader solid_shader = DUMMY_SOLID_SHADER; struct sdis_interface_shader interface_shader = SDIS_INTERFACE_SHADER_NULL; + struct sdis_solve_medium_args solve_args = SDIS_SOLVE_MEDIUM_ARGS_DEFAULT; struct context ctx; - const double trange[2] = {INF, INF}; double ref; double v, v0, v1; size_t nreals; @@ -352,13 +352,31 @@ main(int argc, char** argv) OK(sdis_scene_get_medium_spread(scn, fluid1, &v)); CHK(v == 0); - BA(sdis_solve_medium(NULL, N, solid0, trange, 1.f, -1, 0, 0, &estimator)); - BA(sdis_solve_medium(scn, 0, solid0, trange, 1.f, -1, 0, 0, &estimator)); - BA(sdis_solve_medium(scn, N, NULL, trange, 1.f, -1, 0, 0, &estimator)); - BA(sdis_solve_medium(scn, N, solid0, NULL, 1.f, -1, 0, 0, &estimator)); - BA(sdis_solve_medium(scn, N, solid0, trange, 0.f, -1, 0, 0, &estimator)); - BA(sdis_solve_medium(scn, N, solid0, trange, 1.f, -1, 0, 0, NULL)); - OK(sdis_solve_medium(scn, N, solid0, trange, 1.f, -1, 0, 0, &estimator)); + solve_args.nrealisations = N; + solve_args.medium = solid0; + solve_args.time_range[0] = INF; + solve_args.time_range[1] = INF; + + BA(sdis_solve_medium(NULL, &solve_args, &estimator)); + BA(sdis_solve_medium(scn, NULL, &estimator)); + BA(sdis_solve_medium(scn, &solve_args, NULL)); + solve_args.nrealisations = 0; + BA(sdis_solve_medium(scn, &solve_args, &estimator)); + solve_args.nrealisations = N; + solve_args.medium = NULL; + BA(sdis_solve_medium(scn, &solve_args, &estimator)); + solve_args.medium = solid0; + solve_args.fp_to_meter = 0; + BA(sdis_solve_medium(scn, &solve_args, &estimator)); + solve_args.fp_to_meter = 1; + solve_args.time_range[0] = solve_args.time_range[1] = -1; + BA(sdis_solve_medium(scn, &solve_args, &estimator)); + solve_args.time_range[0] = 1; + BA(sdis_solve_medium(scn, &solve_args, &estimator)); + solve_args.time_range[1] = 0; + BA(sdis_solve_medium(scn, &solve_args, &estimator)); + solve_args.time_range[0] = solve_args.time_range[1] = INF; + OK(sdis_solve_medium(scn, &solve_args, &estimator)); OK(sdis_estimator_get_realisation_count(estimator, &nreals)); OK(sdis_estimator_get_failure_count(estimator, &nfails)); @@ -371,7 +389,20 @@ main(int argc, char** argv) CHK(nreals + nfails == N); OK(sdis_estimator_ref_put(estimator)); - OK(sdis_solve_medium(scn, N, solid1, trange, 1.f, -1, 0, 0, &estimator)); + solve_args.medium = solid1; + + /* Check simulation error handling when paths are registered */ + solve_args.nrealisations = 10; + solve_args.register_paths = SDIS_HEAT_PATH_ALL; + fluid_param->temperature = -1; + BA(sdis_solve_medium(scn, &solve_args, &estimator)); + fluid_param->temperature = Tf1; + OK(sdis_solve_medium(scn, &solve_args, &estimator)); + OK(sdis_estimator_ref_put(estimator)); + solve_args.nrealisations = N; + solve_args.register_paths = SDIS_HEAT_PATH_NONE; + + OK(sdis_solve_medium(scn, &solve_args, &estimator)); OK(sdis_estimator_get_realisation_count(estimator, &nreals)); OK(sdis_estimator_get_failure_count(estimator, &nfails)); OK(sdis_estimator_get_temperature(estimator, &T)); @@ -383,13 +414,6 @@ main(int argc, char** argv) CHK(nreals + nfails == N); OK(sdis_estimator_ref_put(estimator)); -#if 0 - OK(sdis_solve_medium(scn, 1, solid1, trange, 1.f, -1, 0, - SDIS_HEAT_PATH_ALL, &estimator)); - dump_heat_paths(stderr, estimator); - OK(sdis_estimator_ref_put(estimator)); -#endif - /* Create a new scene with the same medium in the 2 super shapes */ OK(sdis_scene_ref_put(scn)); ctx.interf0 = solid0_fluid0; @@ -400,8 +424,11 @@ main(int argc, char** argv) OK(sdis_scene_get_medium_spread(scn, solid0, &v)); CHK(eq_eps(v, v0+v1, 1.e-6)); - BA(sdis_solve_medium(scn, N, solid1, trange, 1.f, -1, 0, 0, &estimator)); - OK(sdis_solve_medium(scn, Np, solid0, trange, 1.f, -1, 0, 0, &estimator)); + solve_args.medium = solid1; + BA(sdis_solve_medium(scn, &solve_args, &estimator)); + solve_args.medium = solid0; + solve_args.nrealisations = Np; + OK(sdis_solve_medium(scn, &solve_args, &estimator)); OK(sdis_estimator_get_temperature(estimator, &T)); OK(sdis_estimator_get_realisation_time(estimator, &time)); OK(sdis_estimator_get_realisation_count(estimator, &nreals)); @@ -413,16 +440,23 @@ main(int argc, char** argv) CHK(eq_eps(T.E, ref, T.SE*3)); /* Solve green */ - BA(sdis_solve_medium_green_function(NULL, Np, solid0, 1.0, 0, 0, &green)); - BA(sdis_solve_medium_green_function(scn, 0, solid0, 1.0, 0, 0, &green)); - BA(sdis_solve_medium_green_function(scn, Np, NULL, 1.0, 0, 0, &green)); - BA(sdis_solve_medium_green_function(scn, Np, solid0, 0.0, 0, 0, &green)); - BA(sdis_solve_medium_green_function(scn, Np, solid0, 1.0, 0, -1, &green)); - BA(sdis_solve_medium_green_function(scn, Np, solid0, 1.0, 0, 0, NULL)); - BA(sdis_solve_medium_green_function(scn, Np, solid1, 1.0, 0, 0, &green)); - OK(sdis_solve_medium_green_function(scn, Np, solid0, 1.0, 0, 0, &green)); - - OK(sdis_green_function_solve(green, trange, &estimator2)); + BA(sdis_solve_medium_green_function(NULL, &solve_args, &green)); + BA(sdis_solve_medium_green_function(scn, NULL, &green)); + BA(sdis_solve_medium_green_function(scn, &solve_args, NULL)); + solve_args.nrealisations = 0; + BA(sdis_solve_medium_green_function(scn, &solve_args, &green)); + solve_args.nrealisations = Np; + solve_args.medium = NULL; + BA(sdis_solve_medium_green_function(scn, &solve_args, &green)); + solve_args.medium = solid1; + BA(sdis_solve_medium_green_function(scn, &solve_args, &green)); + solve_args.medium = solid0; + solve_args.fp_to_meter = 0; + BA(sdis_solve_medium_green_function(scn, &solve_args, &green)); + solve_args.fp_to_meter = 1; + OK(sdis_solve_medium_green_function(scn, &solve_args, &green)); + + OK(sdis_green_function_solve(green, solve_args.time_range, &estimator2)); check_green_function(green); check_estimator_eq(estimator, estimator2); diff --git a/src/test_sdis_solve_medium_2d.c b/src/test_sdis_solve_medium_2d.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -208,8 +208,8 @@ main(int argc, char** argv) struct sdis_fluid_shader fluid_shader = DUMMY_FLUID_SHADER; struct sdis_solid_shader solid_shader = DUMMY_SOLID_SHADER; struct sdis_interface_shader interface_shader = SDIS_INTERFACE_SHADER_NULL; + struct sdis_solve_medium_args solve_args = SDIS_SOLVE_MEDIUM_ARGS_DEFAULT; struct context ctx; - const double trange[2] = {INF, INF}; double a, a0, a1; double ref; double* positions = NULL; @@ -334,8 +334,13 @@ main(int argc, char** argv) /* Rough estimation since the disk is coarsely discretized */ CHK(eq_eps(a1, PI, 1.e-1)); + solve_args.nrealisations = N; + solve_args.time_range[0] = INF; + solve_args.time_range[1] = INF; + /* Estimate the temperature of the square */ - OK(sdis_solve_medium(scn, N, solid0, trange, 1.f, -1, 0, 0, &estimator)); + solve_args.medium = solid0; + OK(sdis_solve_medium(scn, &solve_args, &estimator)); OK(sdis_estimator_get_temperature(estimator, &T)); OK(sdis_estimator_get_realisation_time(estimator, &time)); OK(sdis_estimator_get_realisation_count(estimator, &nreals)); @@ -348,7 +353,8 @@ main(int argc, char** argv) OK(sdis_estimator_ref_put(estimator)); /* Estimate the temperature of the disk */ - OK(sdis_solve_medium(scn, N, solid1, trange, 1.f, -1, 0, 0, &estimator)); + solve_args.medium = solid1; + OK(sdis_solve_medium(scn, &solve_args, &estimator)); OK(sdis_estimator_get_temperature(estimator, &T)); OK(sdis_estimator_get_realisation_time(estimator, &time)); OK(sdis_estimator_get_realisation_count(estimator, &nreals)); @@ -371,8 +377,11 @@ main(int argc, char** argv) CHK(eq_eps(a, a0+a1, 1.e-6)); /* Estimate the temperature of the square and disk shapes */ - BA(sdis_solve_medium(scn, N, solid1, trange, 1.f, -1, 0, 0, &estimator)); - OK(sdis_solve_medium(scn, Np, solid0, trange, 1.f, -1, 0, 0, &estimator)); + solve_args.medium = solid1; + solve_args.nrealisations = Np; + BA(sdis_solve_medium(scn, &solve_args, &estimator)); + solve_args.medium = solid0; + OK(sdis_solve_medium(scn, &solve_args, &estimator)); OK(sdis_estimator_get_temperature(estimator, &T)); OK(sdis_estimator_get_realisation_time(estimator, &time)); OK(sdis_estimator_get_realisation_count(estimator, &nreals)); @@ -385,16 +394,12 @@ main(int argc, char** argv) CHK(nreals + nfails == Np); /* Solve green */ - BA(sdis_solve_medium_green_function(NULL, Np, solid0, 1.0, 0, 0, &green)); - BA(sdis_solve_medium_green_function(scn, 0, solid0, 1.0, 0, 0, &green)); - BA(sdis_solve_medium_green_function(scn, Np, NULL, 1.0, 0, 0, &green)); - BA(sdis_solve_medium_green_function(scn, Np, solid0, 0.0, 0, 0, &green)); - BA(sdis_solve_medium_green_function(scn, Np, solid0, 1.0, 0, -1, &green)); - BA(sdis_solve_medium_green_function(scn, Np, solid0, 1.0, 0, 0, NULL)); - BA(sdis_solve_medium_green_function(scn, Np, solid1, 1.0, 0, 0, &green)); - OK(sdis_solve_medium_green_function(scn, Np, solid0, 1.0, 0, 0, &green)); - - OK(sdis_green_function_solve(green, trange, &estimator2)); + BA(sdis_solve_medium_green_function(NULL, &solve_args, &green)); + BA(sdis_solve_medium_green_function(scn, NULL, &green)); + BA(sdis_solve_medium_green_function(scn, &solve_args, NULL)); + OK(sdis_solve_medium_green_function(scn, &solve_args, &green)); + + OK(sdis_green_function_solve(green, solve_args.time_range, &estimator2)); check_green_function(green); check_estimator_eq(estimator, estimator2); diff --git a/src/test_sdis_solve_probe.c b/src/test_sdis_solve_probe.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,6 +16,7 @@ #include "sdis.h" #include "test_sdis_utils.h" +#include <star/ssp.h> #include <rsys/math.h> /* @@ -206,11 +207,11 @@ process_heat_path(const struct sdis_heat_path* path, void* context) BA(sdis_heat_path_get_status(NULL, &status)); BA(sdis_heat_path_get_status(path, NULL)); OK(sdis_heat_path_get_status(path, &status)); - CHK(status == SDIS_HEAT_PATH_SUCCEED || status == SDIS_HEAT_PATH_FAILED); + CHK(status == SDIS_HEAT_PATH_SUCCESS || status == SDIS_HEAT_PATH_FAILURE); switch(status) { - case SDIS_HEAT_PATH_FAILED: ++ctx->nfailures; break; - case SDIS_HEAT_PATH_SUCCEED: ++ctx->nsuccesses; break; + case SDIS_HEAT_PATH_FAILURE: ++ctx->nfailures; break; + case SDIS_HEAT_PATH_SUCCESS: ++ctx->nsuccesses; break; default: FATAL("Unreachable code.\n"); break; } @@ -263,14 +264,14 @@ main(int argc, char** argv) struct sdis_fluid_shader fluid_shader = DUMMY_FLUID_SHADER; struct sdis_solid_shader solid_shader = DUMMY_SOLID_SHADER; struct sdis_interface_shader interface_shader = SDIS_INTERFACE_SHADER_NULL; + struct sdis_solve_probe_args solve_args = SDIS_SOLVE_PROBE_ARGS_DEFAULT; struct dump_path_context dump_ctx = DUMP_PATH_CONTEXT_NULL; struct context ctx; struct fluid* fluid_param; struct solid* solid_param; struct interf* interface_param; + struct ssp_rng* rng_state = NULL; enum sdis_estimator_type type; - double pos[3]; - double time_range[2]; double ref; const size_t N = 1000; const size_t N_dump = 10; @@ -338,17 +339,30 @@ main(int argc, char** argv) OK(sdis_interface_ref_put(interf)); /* Test the solver */ - pos[0] = 0.5; - pos[1] = 0.5; - pos[2] = 0.5; - time_range[0] = time_range[1] = INF; - BA(sdis_solve_probe(NULL, N, pos, time_range, 1.0, 0, 0, 0, &estimator)); - BA(sdis_solve_probe(scn, 0, pos, time_range, 1.0, 0, 0, 0, &estimator)); - BA(sdis_solve_probe(scn, N, NULL, time_range, 1.0, 0, 0, 0, &estimator)); - BA(sdis_solve_probe(scn, N, pos, time_range, 0, 0, 0, 0, &estimator)); - BA(sdis_solve_probe(scn, N, pos, time_range, 0, 0, -1, 0, &estimator)); - BA(sdis_solve_probe(scn, N, pos, time_range, 1.0, 0, 0, 0, NULL)); - OK(sdis_solve_probe(scn, N, pos, time_range, 1.0, 0, 0, 0, &estimator)); + solve_args.nrealisations = N; + solve_args.position[0] = 0.5; + solve_args.position[1] = 0.5; + solve_args.position[2] = 0.5; + solve_args.time_range[0] = INF; + solve_args.time_range[1] = INF; + + BA(sdis_solve_probe(NULL, &solve_args, &estimator)); + BA(sdis_solve_probe(scn, NULL, &estimator)); + BA(sdis_solve_probe(scn, &solve_args, NULL)); + solve_args.nrealisations = 0; + BA(sdis_solve_probe(scn, &solve_args, &estimator)); + solve_args.nrealisations = N; + solve_args.fp_to_meter = 0; + BA(sdis_solve_probe(scn, &solve_args, &estimator)); + solve_args.fp_to_meter = 1; + solve_args.time_range[0] = solve_args.time_range[1] = -1; + BA(sdis_solve_probe(scn, &solve_args, &estimator)); + solve_args.time_range[0] = 1; + BA(sdis_solve_probe(scn, &solve_args, &estimator)); + solve_args.time_range[1] = 0; + BA(sdis_solve_probe(scn, &solve_args, &estimator)); + solve_args.time_range[0] = solve_args.time_range[1] = INF; + OK(sdis_solve_probe(scn, &solve_args, &estimator)); BA(sdis_estimator_get_type(estimator, NULL)); BA(sdis_estimator_get_type(NULL, &type)); @@ -384,9 +398,13 @@ main(int argc, char** argv) BA(sdis_estimator_get_realisation_time(NULL, &time)); OK(sdis_estimator_get_realisation_time(estimator, &time)); + BA(sdis_estimator_get_rng_state(NULL, &rng_state)); + BA(sdis_estimator_get_rng_state(estimator, NULL)); + OK(sdis_estimator_get_rng_state(estimator, &rng_state)); + ref = 300; printf("Temperature at (%g, %g, %g) = %g ~ %g +/- %g\n", - SPLIT3(pos), ref, T.E, T.SE); + SPLIT3(solve_args.position), ref, T.E, T.SE); printf("Time per realisation (in usec) = %g +/- %g\n", time.E, time.SE); printf("#failures = %lu/%lu\n", (unsigned long)nfails, (unsigned long)N); @@ -402,23 +420,26 @@ main(int argc, char** argv) /* The external fluid cannot have an unknown temperature */ fluid_param->temperature = -1; - BA(sdis_solve_probe(scn, N, pos, time_range, 1.0, 0, 0, 0, &estimator)); + BA(sdis_solve_probe(scn, &solve_args, &estimator)); fluid_param->temperature = 300; - OK(sdis_solve_probe(scn, N, pos, time_range, 1.0, 0, 0, 0, &estimator)); - - BA(sdis_solve_probe_green_function(NULL, N, pos, 1.0, 0, 0, &green)); - BA(sdis_solve_probe_green_function(scn, 0, pos, 1.0, 0, 0, &green)); - BA(sdis_solve_probe_green_function(scn, N, NULL, 1.0, 0, 0, &green)); - BA(sdis_solve_probe_green_function(scn, N, pos, 0.0, 0, 0, &green)); - BA(sdis_solve_probe_green_function(scn, N, pos, 1.0, 0, -1, &green)); - BA(sdis_solve_probe_green_function(scn, N, pos, 1.0, 0, 0, NULL)); - OK(sdis_solve_probe_green_function(scn, N, pos, 1.0, 0, 0, &green)); - - BA(sdis_green_function_solve(NULL, time_range, &estimator2)); + OK(sdis_solve_probe(scn, &solve_args, &estimator)); + + BA(sdis_solve_probe_green_function(NULL, &solve_args, &green)); + BA(sdis_solve_probe_green_function(scn, NULL, &green)); + BA(sdis_solve_probe_green_function(scn, &solve_args, NULL)); + solve_args.nrealisations = 0; + BA(sdis_solve_probe_green_function(scn, &solve_args, &green)); + solve_args.nrealisations = N; + solve_args.fp_to_meter = 0; + BA(sdis_solve_probe_green_function(scn, &solve_args, &green)); + solve_args.fp_to_meter = 1; + OK(sdis_solve_probe_green_function(scn, &solve_args, &green)); + + BA(sdis_green_function_solve(NULL, solve_args.time_range, &estimator2)); BA(sdis_green_function_solve(green, NULL, &estimator2)); - BA(sdis_green_function_solve(green, time_range, NULL)); - OK(sdis_green_function_solve(green, time_range, &estimator2)); + BA(sdis_green_function_solve(green, solve_args.time_range, NULL)); + OK(sdis_green_function_solve(green, solve_args.time_range, &estimator2)); check_green_function(green); check_estimator_eq(estimator, estimator2); @@ -432,15 +453,22 @@ main(int argc, char** argv) OK(sdis_estimator_ref_put(estimator)); OK(sdis_estimator_ref_put(estimator2)); - OK(sdis_solve_probe(scn, N, pos, time_range, 1.0, 0, 0, 0, &estimator)); + OK(sdis_solve_probe(scn, &solve_args, &estimator)); BA(sdis_estimator_get_paths_count(NULL, &n)); BA(sdis_estimator_get_paths_count(estimator, NULL)); OK(sdis_estimator_get_paths_count(estimator, &n)); CHK(n == 0); OK(sdis_estimator_ref_put(estimator)); - OK(sdis_solve_probe(scn, N_dump, pos, time_range, 1.0, 0, 0, - SDIS_HEAT_PATH_ALL, &estimator)); + solve_args.nrealisations = N_dump; + solve_args.register_paths = SDIS_HEAT_PATH_ALL; + + /* Check simulation error handling when paths are registered */ + fluid_param->temperature = -1; + BA(sdis_solve_probe(scn, &solve_args, &estimator)); + + fluid_param->temperature = 300; + OK(sdis_solve_probe(scn, &solve_args, &estimator)); OK(sdis_estimator_get_paths_count(estimator, &n)); CHK(n == N_dump); diff --git a/src/test_sdis_solve_probe2.c b/src/test_sdis_solve_probe2.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -162,10 +162,9 @@ main(int argc, char** argv) struct sdis_solid_shader solid_shader = DUMMY_SOLID_SHADER; struct sdis_interface_shader interface_shader = DUMMY_INTERFACE_SHADER; struct sdis_interface* interfaces[12]; + struct sdis_solve_probe_args solve_args = SDIS_SOLVE_PROBE_ARGS_DEFAULT; struct context ctx; struct interf* interface_param = NULL; - double pos[3]; - double time_range[2] = { INF, INF }; double ref; const size_t N = 10000; size_t nreals; @@ -239,20 +238,23 @@ main(int argc, char** argv) OK(sdis_interface_ref_put(T350)); /* Launch the solver */ - pos[0] = 0.5; - pos[1] = 0.5; - pos[2] = 0.5; - time_range[0] = time_range[1] = INF; - OK(sdis_solve_probe(scn, N, pos, time_range, 1.0, -1, 0, 0, &estimator)); + solve_args.nrealisations = N; + solve_args.position[0] = 0.5; + solve_args.position[1] = 0.5; + solve_args.position[2] = 0.5; + solve_args.time_range[0] = INF; + solve_args.time_range[1] = INF; + + OK(sdis_solve_probe(scn, &solve_args, &estimator)); OK(sdis_estimator_get_realisation_count(estimator, &nreals)); OK(sdis_estimator_get_failure_count(estimator, &nfails)); OK(sdis_estimator_get_temperature(estimator, &T)); OK(sdis_estimator_get_realisation_time(estimator, &time)); /* Print the estimation results */ - ref = 350 * pos[2] + (1-pos[2]) * 300; + ref = 350 * solve_args.position[2] + (1-solve_args.position[2]) * 300; printf("Temperature at (%g, %g, %g) = %g ~ %g +/- %g\n", - SPLIT3(pos), ref, T.E, T.SE); + SPLIT3(solve_args.position), ref, T.E, T.SE); printf("Time per realisation (in usec) = %g +/- %g\n", time.E, time.SE); printf("#failures = %lu/%lu\n", (unsigned long)nfails, (unsigned long)N); @@ -262,8 +264,8 @@ main(int argc, char** argv) CHK(eq_eps(T.E, ref, 3*T.SE)); /* Check green */ - OK(sdis_solve_probe_green_function(scn, N, pos, 1, -1, 0, &green)); - OK(sdis_green_function_solve(green, time_range, &estimator2)); + OK(sdis_solve_probe_green_function(scn, &solve_args, &green)); + OK(sdis_green_function_solve(green, solve_args.time_range, &estimator2)); check_green_function(green); check_estimator_eq(estimator, estimator2); diff --git a/src/test_sdis_solve_probe2_2d.c b/src/test_sdis_solve_probe2_2d.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -159,10 +159,9 @@ main(int argc, char** argv) struct sdis_solid_shader solid_shader = DUMMY_SOLID_SHADER; struct sdis_interface_shader interface_shader = DUMMY_INTERFACE_SHADER; struct sdis_interface* interfaces[4]; + struct sdis_solve_probe_args solve_args = SDIS_SOLVE_PROBE_ARGS_DEFAULT; struct context ctx; struct interf* interface_param = NULL; - double pos[2]; - double time_range[2]; double ref; const size_t N = 10000; size_t nreals; @@ -186,14 +185,14 @@ main(int argc, char** argv) /* Create the fluid/solid interface with no limit conidition */ interface_shader.convection_coef = null_interface_value; - interface_shader.front = SDIS_INTERFACE_SIDE_SHADER_NULL; - interface_shader.back = SDIS_INTERFACE_SIDE_SHADER_NULL; + interface_shader.front = SDIS_INTERFACE_SIDE_SHADER_NULL; + interface_shader.back = SDIS_INTERFACE_SIDE_SHADER_NULL; OK(sdis_interface_create (dev, solid, fluid, &interface_shader, NULL, &Tnone)); interface_shader.convection_coef = null_interface_value; - interface_shader.front = SDIS_INTERFACE_SIDE_SHADER_NULL; - interface_shader.back = SDIS_INTERFACE_SIDE_SHADER_NULL; + interface_shader.front = SDIS_INTERFACE_SIDE_SHADER_NULL; + interface_shader.back = SDIS_INTERFACE_SIDE_SHADER_NULL; interface_shader.front.temperature = interface_get_temperature; /* Create the fluid/solid interface with a fixed temperature of 300K */ @@ -238,20 +237,23 @@ main(int argc, char** argv) OK(sdis_interface_ref_put(T350)); /* Launch the solver */ - pos[0] = 0.5; - pos[1] = 0.5; - time_range[0] = time_range[1] = INF; - OK(sdis_solve_probe(scn, N, pos, time_range, 1.0, -1, 0, 0, &estimator)); + solve_args.nrealisations = N; + solve_args.position[0] = 0.5; + solve_args.position[1] = 0.5; + solve_args.time_range[0] = INF; + solve_args.time_range[1] = INF; + + OK(sdis_solve_probe(scn, &solve_args, &estimator)); + OK(sdis_estimator_get_realisation_count(estimator, &nreals)); OK(sdis_estimator_get_failure_count(estimator, &nfails)); OK(sdis_estimator_get_temperature(estimator, &T)); OK(sdis_estimator_get_realisation_time(estimator, &time)); - /* Print the estimation results */ - ref = 350 * pos[0] + (1-pos[0]) * 300; + ref = 350 * solve_args.position[0] + (1-solve_args.position[0]) * 300; printf("Temperature at (%g, %g) = %g ~ %g +/- %g\n", - SPLIT2(pos), ref, T.E, T.SE); + SPLIT2(solve_args.position), ref, T.E, T.SE); printf("Time per realisation (in usec) = %g +/- %g\n", time.E, time.SE); printf("#failures = %lu/%lu\n", (unsigned long)nfails, (unsigned long)N); @@ -261,8 +263,8 @@ main(int argc, char** argv) CHK(eq_eps(T.E, ref, T.SE*2)); /* Check green function */ - OK(sdis_solve_probe_green_function(scn, N, pos, 1.0, -1, 0, &green)); - OK(sdis_green_function_solve(green, time_range, &estimator2)); + OK(sdis_solve_probe_green_function(scn, &solve_args, &green)); + OK(sdis_green_function_solve(green, solve_args.time_range, &estimator2)); check_green_function(green); check_estimator_eq(estimator, estimator2); diff --git a/src/test_sdis_solve_probe3.c b/src/test_sdis_solve_probe3.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -184,12 +184,11 @@ main(int argc, char** argv) struct sdis_fluid_shader fluid_shader = DUMMY_FLUID_SHADER; struct sdis_solid_shader solid_shader = DUMMY_SOLID_SHADER; struct sdis_interface_shader interface_shader = DUMMY_INTERFACE_SHADER; + struct sdis_solve_probe_args solve_args = SDIS_SOLVE_PROBE_ARGS_DEFAULT; struct s3dut_mesh* msh = NULL; struct s3dut_mesh_data msh_data; struct context ctx = CONTEXT_NULL; struct interf* interface_param = NULL; - double pos[3]; - double time_range[2]; double ref; const size_t N = 10000; size_t ntris; @@ -295,20 +294,23 @@ main(int argc, char** argv) sa_release(ctx.indices); /* Launch the solver */ - pos[0] = 0.5; - pos[1] = 0.5; - pos[2] = 0.5; - time_range[0] = time_range[1] = INF; - OK(sdis_solve_probe( scn, N, pos, time_range, 1.0, -1, 0, 0, &estimator)); + solve_args.nrealisations = N; + solve_args.position[0] = 0.5; + solve_args.position[1] = 0.5; + solve_args.position[2] = 0.5; + solve_args.time_range[0] = INF; + solve_args.time_range[1] = INF; + + OK(sdis_solve_probe(scn, &solve_args, &estimator)); OK(sdis_estimator_get_realisation_count(estimator, &nreals)); OK(sdis_estimator_get_failure_count(estimator, &nfails)); OK(sdis_estimator_get_temperature(estimator, &T)); OK(sdis_estimator_get_realisation_time(estimator, &time)); /* Print the estimation results */ - ref = 350 * pos[2] + (1-pos[2]) * 300; + ref = 350 * solve_args.position[2] + (1-solve_args.position[2]) * 300; printf("Temperature at (%g, %g, %g) = %g ~ %g +/- %g\n", - SPLIT3(pos), ref, T.E, T.SE); + SPLIT3(solve_args.position), ref, T.E, T.SE); printf("Time per realisation (in usec) = %g +/- %g\n", time.E, time.SE); printf("#failures = %lu/%lu\n", (unsigned long)nfails, (unsigned long)N); @@ -318,8 +320,8 @@ main(int argc, char** argv) CHK(eq_eps(T.E, ref, 3*T.SE)); /* Check green function */ - OK(sdis_solve_probe_green_function(scn, N, pos, 1.0, -1, 0, &green)); - OK(sdis_green_function_solve(green, time_range, &estimator2)); + OK(sdis_solve_probe_green_function(scn, &solve_args, &green)); + OK(sdis_green_function_solve(green, solve_args.time_range, &estimator2)); check_green_function(green); check_estimator_eq(estimator, estimator2); diff --git a/src/test_sdis_solve_probe3_2d.c b/src/test_sdis_solve_probe3_2d.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -181,10 +181,9 @@ main(int argc, char** argv) struct sdis_fluid_shader fluid_shader = DUMMY_FLUID_SHADER; struct sdis_solid_shader solid_shader = DUMMY_SOLID_SHADER; struct sdis_interface_shader interface_shader = DUMMY_INTERFACE_SHADER; + struct sdis_solve_probe_args solve_args = SDIS_SOLVE_PROBE_ARGS_DEFAULT; struct context ctx = CONTEXT_NULL; struct interf* interface_param = NULL; - double pos[2]; - double time_range[2]; double ref; const size_t N = 10000; size_t nsegs; @@ -289,19 +288,21 @@ main(int argc, char** argv) sa_release(ctx.indices); /* Launch the solver */ - pos[0] = 0.5; - pos[1] = 0.5; - time_range[0] = time_range[1] = INF; - OK(sdis_solve_probe(scn, N, pos, time_range, 1.0, -1, 0, 0, &estimator)); + solve_args.nrealisations = N; + solve_args.position[0] = 0.5; + solve_args.position[1] = 0.5; + solve_args.time_range[0] = INF; + solve_args.time_range[1] = INF; + OK(sdis_solve_probe(scn, &solve_args, &estimator)); OK(sdis_estimator_get_realisation_count(estimator, &nreals)); OK(sdis_estimator_get_failure_count(estimator, &nfails)); OK(sdis_estimator_get_temperature(estimator, &T)); OK(sdis_estimator_get_realisation_time(estimator, &time)); /* Print the estimation results */ - ref = 350 * pos[0] + (1-pos[0]) * 300; + ref = 350 * solve_args.position[0] + (1-solve_args.position[0]) * 300; printf("Temperature at (%g, %g) = %g ~ %g +/- %g\n", - SPLIT2(pos), ref, T.E, T.SE); + SPLIT2(solve_args.position), ref, T.E, T.SE); printf("Time per realisation (in usec) = %g +/- %g\n", time.E, time.SE); printf("#failures = %lu/%lu\n", (unsigned long)nfails, (unsigned long)N); @@ -311,8 +312,8 @@ main(int argc, char** argv) CHK(eq_eps(T.E, ref, 3*T.SE)); /* Check green function */ - OK(sdis_solve_probe_green_function(scn, N, pos, 1.0, -1, 0, &green)); - OK(sdis_green_function_solve(green, time_range, &estimator2)); + OK(sdis_solve_probe_green_function(scn, &solve_args, &green)); + OK(sdis_green_function_solve(green, solve_args.time_range, &estimator2)); check_green_function(green); check_estimator_eq(estimator, estimator2); diff --git a/src/test_sdis_solve_probe_2d.c b/src/test_sdis_solve_probe_2d.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -148,10 +148,9 @@ main(int argc, char** argv) struct sdis_fluid_shader fluid_shader = DUMMY_FLUID_SHADER; struct sdis_solid_shader solid_shader = DUMMY_SOLID_SHADER; struct sdis_interface_shader interface_shader = DUMMY_INTERFACE_SHADER; + struct sdis_solve_probe_args solve_args = SDIS_SOLVE_PROBE_ARGS_DEFAULT; struct context ctx; struct fluid* fluid_param; - double pos[2]; - double time_range[2] = { INF, INF }; double ref; const size_t N = 1000; size_t nreals; @@ -199,10 +198,13 @@ main(int argc, char** argv) OK(sdis_interface_ref_put(interf)); /* Test the solver */ - pos[0] = 0.5; - pos[1] = 0.5; - time_range[0] = time_range[1] = INF; - OK(sdis_solve_probe(scn, N, pos, time_range, 1.0, 0, 0, 0, &estimator)); + solve_args.nrealisations = N; + solve_args.position[0] = 0.5; + solve_args.position[1] = 0.5; + solve_args.time_range[0] = INF; + solve_args.time_range[1] = INF; + + OK(sdis_solve_probe(scn, &solve_args, &estimator)); OK(sdis_estimator_get_realisation_count(estimator, &nreals)); OK(sdis_estimator_get_failure_count(estimator, &nfails)); OK(sdis_estimator_get_temperature(estimator, &T)); @@ -210,7 +212,7 @@ main(int argc, char** argv) ref = 300; printf("Temperature at (%g, %g) = %g ~ %g +/- %g\n", - SPLIT2(pos), ref, T.E, T.SE); + SPLIT2(solve_args.position), ref, T.E, T.SE); printf("Time per realisation (in usec) = %g +/- %g\n", time.E, time.SE); printf("#failures = %lu/%lu\n", (unsigned long)nfails, (unsigned long)N); @@ -218,8 +220,8 @@ main(int argc, char** argv) CHK(nfails < N/1000); CHK(eq_eps(T.E, ref, T.SE)); - OK(sdis_solve_probe_green_function(scn, N, pos, 1.0, 0, 0, &green)); - OK(sdis_green_function_solve(green, time_range, &estimator2)); + OK(sdis_solve_probe_green_function(scn, &solve_args, &green)); + OK(sdis_green_function_solve(green, solve_args.time_range, &estimator2)); check_green_function(green); check_estimator_eq(estimator, estimator2); @@ -230,7 +232,7 @@ main(int argc, char** argv) /* The external fluid cannot have an unknown temperature */ fluid_param->temperature = -1; - BA(sdis_solve_probe(scn, N, pos, time_range, 1.0, 0, 0, 0, &estimator)); + BA(sdis_solve_probe(scn, &solve_args, &estimator)); OK(sdis_scene_ref_put(scn)); OK(sdis_device_ref_put(dev)); diff --git a/src/test_sdis_utils.c b/src/test_sdis_utils.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -354,8 +354,8 @@ dump_heat_paths(FILE* stream, const struct sdis_estimator* estimator) OK(sdis_estimator_get_path(estimator, ipath, &path)); OK(sdis_heat_path_get_status(path, &status)); switch(status) { - case SDIS_HEAT_PATH_SUCCEED: fprintf(stream, "0.0\n"); break; - case SDIS_HEAT_PATH_FAILED: fprintf(stream, "1.0\n"); break; + case SDIS_HEAT_PATH_SUCCESS: fprintf(stream, "0.0\n"); break; + case SDIS_HEAT_PATH_FAILURE: fprintf(stream, "1.0\n"); break; default: FATAL("Unreachable code.\n"); break; } } diff --git a/src/test_sdis_utils.h b/src/test_sdis_utils.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/test_sdis_volumic_power.c b/src/test_sdis_volumic_power.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -156,6 +156,7 @@ solve(struct sdis_scene* scn, const double pos[]) struct sdis_estimator* estimator; struct sdis_estimator* estimator2; struct sdis_green_function* green; + struct sdis_solve_probe_args solve_args = SDIS_SOLVE_PROBE_ARGS_DEFAULT; struct sdis_mc T; size_t nreals; size_t nfails; @@ -168,8 +169,17 @@ solve(struct sdis_scene* scn, const double pos[]) x = pos[0] - 0.5; ref = P0 / (2*LAMBDA) * (1.0/4.0 - x*x) + T0; + OK(sdis_scene_get_dimension(scn, &dim)); + + solve_args.nrealisations = N; + solve_args.time_range[0] = INF; + solve_args.time_range[1] = INF; + solve_args.position[0] = pos[0]; + solve_args.position[1] = pos[1]; + solve_args.position[2] = dim == SDIS_SCENE_2D ? 0 : pos[2]; + time_current(&t0); - OK(sdis_solve_probe(scn, N, pos, time_range, 1.0, 0, 0, 0, &estimator)); + OK(sdis_solve_probe(scn, &solve_args, &estimator)); time_sub(&t0, time_current(&t1), &t0); time_dump(&t0, TIME_ALL, NULL, dump, sizeof(dump)); @@ -177,8 +187,6 @@ solve(struct sdis_scene* scn, const double pos[]) OK(sdis_estimator_get_failure_count(estimator, &nfails)); OK(sdis_estimator_get_temperature(estimator, &T)); - OK(sdis_scene_get_dimension(scn, &dim)); - switch(dim) { case SDIS_SCENE_2D: printf("Temperature at (%g %g) = %g ~ %g +/- %g [%g, %g]\n", @@ -198,7 +206,7 @@ solve(struct sdis_scene* scn, const double pos[]) CHK(eq_eps(T.E, ref, T.SE*3)); time_current(&t0); - OK(sdis_solve_probe_green_function(scn, N, pos, 1.0, 0, 0, &green)); + OK(sdis_solve_probe_green_function(scn, &solve_args, &green)); time_current(&t1); OK(sdis_green_function_solve(green, time_range, &estimator2)); time_current(&t2); diff --git a/src/test_sdis_volumic_power2.c b/src/test_sdis_volumic_power2.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -229,20 +229,24 @@ static void check(struct sdis_scene* scn, const struct reference refs[], const size_t nrefs) { struct sdis_estimator* estimator = NULL; + struct sdis_solve_probe_args solve_args = SDIS_SOLVE_PROBE_ARGS_DEFAULT; struct sdis_mc T = SDIS_MC_NULL; size_t nreals; size_t nfails; double pos[3] = {0,0}; - double time_range[2] = { INF, INF }; size_t i; + solve_args.time_range[0] = INF; + solve_args.time_range[1] = INF; + solve_args.nrealisations = N; + FOR_EACH(i, 0, nrefs) { double Tc; - pos[0] = refs[i].pos[0]; - pos[1] = refs[i].pos[1]; - pos[2] = refs[i].pos[2]; + solve_args.position[0] = refs[i].pos[0]; + solve_args.position[1] = refs[i].pos[1]; + solve_args.position[2] = refs[i].pos[2]; - OK(sdis_solve_probe(scn, N, pos, time_range, 1.f, -1, 0, 0, &estimator)); + OK(sdis_solve_probe(scn, &solve_args, &estimator)); OK(sdis_estimator_get_temperature(estimator, &T)); OK(sdis_estimator_get_realisation_count(estimator, &nreals)); OK(sdis_estimator_get_failure_count(estimator, &nfails)); diff --git a/src/test_sdis_volumic_power2_2d.c b/src/test_sdis_volumic_power2_2d.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -250,18 +250,22 @@ check(struct sdis_scene* scn, const struct reference refs[], const size_t nrefs) { struct sdis_estimator* estimator = NULL; struct sdis_mc T = SDIS_MC_NULL; + struct sdis_solve_probe_args solve_args = SDIS_SOLVE_PROBE_ARGS_DEFAULT; size_t nreals; size_t nfails; double pos[2] = {0,0}; - double time_range[2] = { INF, INF }; size_t i; + solve_args.nrealisations = N; + solve_args.time_range[0] = INF; + solve_args.time_range[1] = INF; + FOR_EACH(i, 0, nrefs) { double Tc; - pos[0] = refs[i].pos[0]; - pos[1] = refs[i].pos[1]; + solve_args.position[0] = refs[i].pos[0]; + solve_args.position[1] = refs[i].pos[1]; - OK(sdis_solve_probe(scn, N, pos, time_range, 1.f, -1, 0, 0, &estimator)); + OK(sdis_solve_probe(scn, &solve_args, &estimator)); OK(sdis_estimator_get_temperature(estimator, &T)); OK(sdis_estimator_get_realisation_count(estimator, &nreals)); OK(sdis_estimator_get_failure_count(estimator, &nfails)); diff --git a/src/test_sdis_volumic_power3_2d.c b/src/test_sdis_volumic_power3_2d.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -261,6 +261,7 @@ main(int argc, char** argv) struct sdis_interface* interf_solid1_fluid = NULL; struct sdis_interface* interf_solid2_fluid = NULL; struct sdis_interface* interfaces[10/*#segment*/]; + struct sdis_solve_probe_args solve_args = SDIS_SOLVE_PROBE_ARGS_DEFAULT; struct sdis_mc T = SDIS_MC_NULL; double Tref; double time_range[2] = { INF, INF }; @@ -441,7 +442,12 @@ main(int argc, char** argv) FATAL("Unreachable code.\n"); } - OK(sdis_solve_probe(scn, N, pos, time_range, 1.f, -1, 0, 0, &estimator)); + solve_args.nrealisations = N; + solve_args.position[0] = pos[0]; + solve_args.position[1] = pos[1]; + solve_args.time_range[0] = time_range[0]; + solve_args.time_range[1] = time_range[1]; + OK(sdis_solve_probe(scn, &solve_args, &estimator)); OK(sdis_estimator_get_temperature(estimator, &T)); OK(sdis_estimator_get_failure_count(estimator, &nfails)); OK(sdis_estimator_get_realisation_count(estimator, &nreals)); diff --git a/src/test_sdis_volumic_power4.c b/src/test_sdis_volumic_power4.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2020 |Meso|Star> (contact@meso-star.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -225,9 +225,9 @@ main(int argc, char** argv) struct sdis_interface* interf_solid_fluid2 = NULL; struct sdis_interface* interfaces[12/*#max primitives*/]; struct sdis_mc T = SDIS_MC_NULL; + struct sdis_solve_probe_args solve_args = SDIS_SOLVE_PROBE_ARGS_DEFAULT; size_t nreals, nfails; double pos[3]; - double time_range[2] = { INF, INF }; double Tref; double x; (void)argc, (void)argv; @@ -353,10 +353,17 @@ main(int argc, char** argv) x = pos[1]; Tref = -Power / (2*LAMBDA) * x*x + Tf + Power/(2*H) + Power/(8*LAMBDA); + solve_args.nrealisations = N; + solve_args.position[0] = pos[0]; + solve_args.position[1] = pos[1]; + solve_args.position[2] = pos[2]; + solve_args.time_range[0] = INF; + solve_args.time_range[1] = INF; + printf(">>> 2D\n"); time_current(&t0); - OK(sdis_solve_probe(scn_2d, N, pos, time_range, 1.f, -1, 0, 0, &estimator)); + OK(sdis_solve_probe(scn_2d, &solve_args, &estimator)); time_sub(&t0, time_current(&t1), &t0); time_dump(&t0, TIME_ALL, NULL, dump, sizeof(dump)); printf("Elapsed time = %s\n", dump); @@ -375,7 +382,7 @@ main(int argc, char** argv) printf("\n>>> 3D\n"); time_current(&t0); - OK(sdis_solve_probe(scn_3d, N, pos, time_range, 1.f, -1, 0, 0, &estimator)); + OK(sdis_solve_probe(scn_3d, &solve_args, &estimator)); time_sub(&t0, time_current(&t1), &t0); time_dump(&t0, TIME_ALL, NULL, dump, sizeof(dump)); printf("Elapsed time = %s\n", dump);