commit e071677ae4fa254c9a238b5a7aa4105c294c3ecb parent 213a6da1be117cdbda807b565620d17ad0d81d9d Author: Vincent Forest <vincent.forest@meso-star.com> Date: Mon, 24 Apr 2023 15:00:53 +0200 Merge branch 'release_0.14' Diffstat:
96 files changed, 1527 insertions(+), 327 deletions(-)
diff --git a/README.md b/README.md @@ -29,7 +29,7 @@ The hypothesis these algorithms are based upon are the following: converge the result closer to the solution of a rigorous spectrally-integrated radiative transfer (a difference of temperatures to the power 4 when integrated over the whole spectrum). The higher the recursion - order, to better will be the convergence of the algorithm. + order, the better will be the convergence of the algorithm. In Stardis-Solver the system to simulate is represented by a *scene* whose geometry defines the contour of the object only: in contrast to legacy thermal @@ -117,6 +117,28 @@ variable the install directories of its dependencies. ## Release notes +### Version 0.14 + +- The net flux imposed can be combined with other boundary/connection + conditions, i.e. a net flux can be set in addition to convective + exchange and radiative transfer. +- Added support for plain text log messages. Until now, log messages were + intended to be read by a VT100-like terminal and could therefore contain + escape sequences that required post-processing to store them in plain text + log files. +- Added support for user-defined signature on the green function. It allows to + check that, when reloaded, a green function is the one expected by the user + according to its own constraints that the green function cannot check itself + such as, for example, that the same deltas are used in conductive random + walks. +- Changes the value of the constant `SDIS_VOLUMIC_POWER_NONE`. Its previous + value of zero caused problems during the evaluation of the propagator: a + media with a power density of zero was not registered in the list of media + with a volumic power. A volumic power that was not zero was therefore not + taken into account during the re-evaluation of the propagator. The constant + is now set to `DBL_MAX`, which means that the medium has no power density, + while a value of 0 is now treated as any valid power density term. + ### Version 0.13.1 Fixed compilation errors and compilation warnings displayed on some versions of @@ -138,17 +160,16 @@ the counterpart of an increase in calculation time. #### Distributed memory parallelism Uses message passing interface to distribute computation across multiple -computers. Stardis-Solver now, uses a mixed parallelism: on one computer (i.e. a -node), it uses a shared memory parallelism and relies on the message passing +computers. Stardis-Solver now, uses a mixed parallelism: on one computer (i.e. +a node), it uses a shared memory parallelism and relies on the message passing interface to parallelize calculations between several nodes. #### Type and state of the random number generator -Adds the member input variable `rng_type` to the solve functions. It -defines the type of random number generator to use when no generator is -defined. Note that the `sdis_solve_camera` function does not have a random -number generator as an input variable and has therefore been updated to support -it. +Adds the member input variable `rng_type` to the solve functions. It defines +the type of random number generator to use when no generator is defined. Note +that the `sdis_solve_camera` function does not have a random number generator +as an input variable and has therefore been updated to support it. #### Reading the source code @@ -417,7 +438,7 @@ First version and implementation of the Stardis-Solver API. ## License -Copyright (C) 2016-2022 |Méso|Star> (<contact@meso-star.com>). Stardis-Solver +Copyright (C) 2016-2023 |Méso|Star> (<contact@meso-star.com>). Stardis-Solver 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-2022 |Meso|Star> (contact@meso-star.com) +# Copyright (C) 2016-2023 |Méso|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 @@ -37,7 +37,7 @@ find_package(Star3D 0.8 REQUIRED) find_package(StarSP 0.13 REQUIRED) find_package(StarEnc2D 0.5 REQUIRED) find_package(StarEnc3D 0.5 REQUIRED) -find_package(RSys 0.12 REQUIRED) +find_package(RSys 0.13 REQUIRED) find_package(OpenMP 2.0 REQUIRED) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${RCMAKE_SOURCE_DIR}) @@ -65,8 +65,8 @@ rcmake_append_runtime_dirs(_runtime_dirs # Configure and define targets ############################################################################### set(VERSION_MAJOR 0) -set(VERSION_MINOR 13) -set(VERSION_PATCH 1) +set(VERSION_MINOR 14) +set(VERSION_PATCH 0) set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}) set(SDIS_FILES_SRC @@ -212,6 +212,8 @@ if(NOT NO_TEST) new_test(test_sdis_data) new_test(test_sdis_device) new_test(test_sdis_flux) + new_test(test_sdis_flux2) + new_test(test_sdis_flux_with_h) new_test(test_sdis_interface) new_test(test_sdis_medium) new_test(test_sdis_picard) diff --git a/src/sdis.c b/src/sdis.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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 @@ -99,7 +99,12 @@ static void rewind_progress_printing(struct sdis_device* dev) { size_t i; - if(!dev->use_mpi || dev->mpi_nprocs == 1) return; + + if(!dev->use_mpi + || dev->no_escape_sequence + || dev->mpi_nprocs == 1) + return; + FOR_EACH(i, 0, dev->mpi_nprocs-1) { log_info(dev, "\033[1A\r"); /* Move up */ } @@ -187,6 +192,9 @@ gather_green_functions_from_non_master_process (struct sdis_scene* scn, struct sdis_green_function* greens[]) { + struct sdis_green_function_create_from_stream_args green_args = + SDIS_GREEN_FUNCTION_CREATE_FROM_STREAM_ARGS_DEFAULT; + void* data = NULL; /* Pointer to gathered serialized green function data */ FILE* stream = NULL; /* Temp file that stores the serialized green function */ int iproc; @@ -249,7 +257,9 @@ gather_green_functions_from_non_master_process * iterate over the indices of non master processes in [1, #procs], * the index the green function to deserialized is iproc - 1 */ rewind(stream); - res = sdis_green_function_create_from_stream(scn, stream, &greens[iproc-1]); + green_args.scene = scn; + green_args.stream = stream; + res = sdis_green_function_create_from_stream(&green_args, &greens[iproc-1]); if(res != RES_OK) { log_err(scn->dev, "Error deserializing the green function sent by the process %d -- %s.\n", @@ -359,6 +369,7 @@ release_per_thread_rng(struct sdis_device* dev, struct ssp_rng* rngs[]) res_T create_per_thread_green_function (struct sdis_scene* scn, + const hash256_T signature, struct sdis_green_function** out_greens[]) { struct sdis_green_function** greens = NULL; @@ -375,7 +386,7 @@ create_per_thread_green_function } FOR_EACH(i, 0, scn->dev->nthreads) { - res = green_function_create(scn, &greens[i]); + res = green_function_create(scn, signature, &greens[i]); if(res != RES_OK) goto error; } @@ -816,17 +827,19 @@ print_progress { ASSERT(dev && label); #ifndef SDIS_ENABLE_MPI - log_info(dev, "%s%3d%%\r", label, progress[0]); + log_info(dev, "%s%3d%%%c", label, progress[0], + dev->no_escape_sequence ? '\n' : '\r'); #else if(!dev->use_mpi) { - log_info(dev, "%s%3d%%\r", label, progress[0]); + log_info(dev, "%s%3d%%%c", label, progress[0], + dev->no_escape_sequence ? '\n' : '\r'); } else { int i; if(dev->mpi_rank != 0) return; mpi_fetch_progress(dev, progress); FOR_EACH(i, 0, dev->mpi_nprocs) { - log_info(dev, "Process %d -- %s%3d%%%c", - i, label, progress[i], i == dev->mpi_nprocs - 1 ? '\r' : '\n'); + log_info(dev, "Process %d -- %s%3d%%%c", i, label, progress[i], + i == dev->mpi_nprocs - 1 && !dev->no_escape_sequence ? '\r' : '\n'); } } #endif @@ -857,6 +870,35 @@ print_progress_update } void +print_progress_completion + (struct sdis_device* dev, + int32_t progress[], + const char* label) +{ + ASSERT(dev); + (void)dev, (void)progress, (void)label; + + /* Only print at 100% completion when MPI is enabled, because when last + * printed non-master processes might still be running. When MPI is disabled, + * 100% completion is printed during calculation */ +#ifdef SDIS_ENABLE_MPI + if(dev->use_mpi && dev->mpi_rank == 0 && dev->mpi_nprocs > 1) { + mpi_fetch_progress(dev, progress); + rewind_progress_printing(dev); + print_progress(dev, progress, label); + + /* When escape sequences are allowed, the last newline character of the + * progress message is replaced with a carriage return. After the + * calculation is complete, we therefore print an additional newline + * character after this carriage return. */ + if(!dev->no_escape_sequence) { + log_info(dev, "\n"); + } + } +#endif +} + +void process_barrier(struct sdis_device* dev) { #ifndef SDIS_ENABLE_MPI diff --git a/src/sdis.h b/src/sdis.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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 @@ -18,6 +18,7 @@ #include <star/ssp.h> +#include <rsys/hash.h> #include <rsys/rsys.h> #include <float.h> @@ -43,7 +44,7 @@ * as CPU cores */ #define SDIS_NTHREADS_DEFAULT (~0u) -#define SDIS_VOLUMIC_POWER_NONE 0 /* <=> No volumic power */ +#define SDIS_VOLUMIC_POWER_NONE DBL_MAX /* <=> No volumic power */ #define SDIS_FLUX_NONE DBL_MAX /* <=> No flux */ #define SDIS_PRIMITIVE_NONE SIZE_MAX /* Invalid primitive */ @@ -137,6 +138,7 @@ struct sdis_device_create_args { struct mem_allocator* allocator; /* NULL <=> default allocator */ unsigned nthreads_hint; /* Hint on the number of threads to use */ int verbosity; /* Verbosity level */ + int no_escape_sequence; /* Rm escape sequences from log messages */ /* Use the Message Passing Interface to distribute work between processes. * This option is taken into account only if Stardis-Solver is compiled with @@ -144,7 +146,7 @@ struct sdis_device_create_args { int use_mpi; }; #define SDIS_DEVICE_CREATE_ARGS_DEFAULT__ { \ - NULL, NULL, SDIS_NTHREADS_DEFAULT, 1, 0 \ + NULL, NULL, SDIS_NTHREADS_DEFAULT, 1, 0, 0 \ } static const struct sdis_device_create_args SDIS_DEVICE_CREATE_ARGS_DEFAULT = SDIS_DEVICE_CREATE_ARGS_DEFAULT__; @@ -279,7 +281,7 @@ enum sdis_heat_path_flag { SDIS_HEAT_PATH_NONE = 0 }; -/* Vertex of heat path v*/ +/* Vertex of heat path */ struct sdis_heat_vertex { double P[3]; double time; @@ -393,7 +395,7 @@ struct sdis_ambient_radiative_temperature { }; #define SDIS_AMBIENT_RADIATIVE_TEMPERATURE_NULL__ {-1, -1} static const struct sdis_ambient_radiative_temperature -SDIS_AMBIENT_RADIATIVE_TEMPERATURE_NULL = +SDIS_AMBIENT_RADIATIVE_TEMPERATURE_NULL = SDIS_AMBIENT_RADIATIVE_TEMPERATURE_NULL__; struct sdis_scene_create_args { @@ -407,7 +409,7 @@ struct sdis_scene_create_args { size_t nprimitives; /* #primitives, i.e. #segments or #triangles */ size_t nvertices; /* #vertices */ - double fp_to_meter; /* Scale factor used to convert 1.0 in 1 meter */ + double fp_to_meter; /* Scale factor used to convert a float in meter */ struct sdis_ambient_radiative_temperature trad; /* Ambient radiative temp */ /* Min/max temperature used to linearise the radiative temperature */ @@ -444,6 +446,12 @@ struct sdis_solve_probe_args { int register_paths; /* Combination of enum sdis_heat_path_flag */ struct ssp_rng* rng_state; /* Initial RNG state. May be NULL */ enum ssp_rng_type rng_type; /* RNG type to use if `rng_state' is NULL */ + + /* Signature of the estimated green function. The signature is ignored in an + * ordinary probe estimation. The signature of the green function can be + * queried to verify that it is the expected one with respect to the caller's + * constraints that the green function cannot otherwise ensure */ + hash256_T signature; }; #define SDIS_SOLVE_PROBE_ARGS_DEFAULT__ { \ 10000, /* #realisations */ \ @@ -452,7 +460,8 @@ struct sdis_solve_probe_args { 1, /* Picard order */ \ SDIS_HEAT_PATH_NONE, /* Register paths mask */ \ NULL, /* RNG state */ \ - SSP_RNG_THREEFRY /* RNG type */ \ + SSP_RNG_THREEFRY, /* RNG type */ \ + {0} /* Signature */ \ } static const struct sdis_solve_probe_args SDIS_SOLVE_PROBE_ARGS_DEFAULT = SDIS_SOLVE_PROBE_ARGS_DEFAULT__; @@ -473,6 +482,12 @@ struct sdis_solve_probe_boundary_args { int register_paths; /* Combination of enum sdis_heat_path_flag */ struct ssp_rng* rng_state; /* Initial RNG state. May be NULL */ enum ssp_rng_type rng_type; /* RNG type to use if `rng_state' is NULL */ + + /* Signature of the estimated green function. The signature is ignored in an + * ordinary probe estimation. The signature of the green function can be + * queried to verify that it is the expected one with respect to the caller's + * constraints that the green function cannot otherwise ensure */ + hash256_T signature; }; #define SDIS_SOLVE_PROBE_BOUNDARY_ARGS_DEFAULT__ { \ 10000, /* #realisations */ \ @@ -483,7 +498,8 @@ struct sdis_solve_probe_boundary_args { SDIS_SIDE_NULL__, \ SDIS_HEAT_PATH_NONE, \ NULL, /* RNG state */ \ - SSP_RNG_THREEFRY /* RNG type */ \ + SSP_RNG_THREEFRY, /* RNG type */ \ + {0} /* Signature */ \ } static const struct sdis_solve_probe_boundary_args SDIS_SOLVE_PROBE_BOUNDARY_ARGS_DEFAULT = @@ -504,6 +520,12 @@ struct sdis_solve_boundary_args { int register_paths; /* Combination of enum sdis_heat_path_flag */ struct ssp_rng* rng_state; /* Initial RNG state. May be NULL */ enum ssp_rng_type rng_type; /* RNG type to use if `rng_state' is NULL */ + + /* Signature of the estimated green function. The signature is ignored in an + * ordinary probe estimation. The signature of the green function can be + * queried to verify that it is the expected one with respect to the caller's + * constraints that the green function cannot otherwise ensure */ + hash256_T signature; }; #define SDIS_SOLVE_BOUNDARY_ARGS_DEFAULT__ { \ 10000, /* #realisations */ \ @@ -514,7 +536,8 @@ struct sdis_solve_boundary_args { 1, /* Picard order */ \ SDIS_HEAT_PATH_NONE, \ NULL, /* RNG state */ \ - SSP_RNG_THREEFRY /* RNG type */ \ + SSP_RNG_THREEFRY, /* RNG type */ \ + {0} /* Signature */ \ } static const struct sdis_solve_boundary_args SDIS_SOLVE_BOUNDARY_ARGS_DEFAULT = SDIS_SOLVE_BOUNDARY_ARGS_DEFAULT__; @@ -532,6 +555,12 @@ struct sdis_solve_medium_args { int register_paths; /* Combination of enum sdis_heat_path_flag */ struct ssp_rng* rng_state; /* Initial RNG state. May be NULL */ enum ssp_rng_type rng_type; /* RNG type to use if `rng_state' is NULL */ + + /* Signature of the estimated green function. The signature is ignored in an + * ordinary probe estimation. The signature of the green function can be + * queried to verify that it is the expected one with respect to the caller's + * constraints that the green function cannot otherwise ensure */ + hash256_T signature; }; #define SDIS_SOLVE_MEDIUM_ARGS_DEFAULT__ { \ 10000, /* #realisations */ \ @@ -540,7 +569,8 @@ struct sdis_solve_medium_args { 1, /* Picard order */ \ SDIS_HEAT_PATH_NONE, \ NULL, /* RNG state */ \ - SSP_RNG_THREEFRY /* RNG type */ \ + SSP_RNG_THREEFRY, /* RNG type */ \ + {0} /* Signature */ \ } static const struct sdis_solve_medium_args SDIS_SOLVE_MEDIUM_ARGS_DEFAULT = SDIS_SOLVE_MEDIUM_ARGS_DEFAULT__; @@ -548,7 +578,7 @@ static const struct sdis_solve_medium_args 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 uv[2]; /* Parametric coordinates of the probe onto the primitive */ double time_range[2]; /* Observation time */ /* Set the Picard recursion order to estimate the radiative temperature. An @@ -645,6 +675,23 @@ struct sdis_compute_power_args { static const struct sdis_compute_power_args SDIS_COMPUTE_POWER_ARGS_DEFAULT = SDIS_COMPUTE_POWER_ARGS_DEFAULT__; +struct sdis_green_function_create_from_stream_args { + struct sdis_scene* scene; /* Scene from which the green was evaluated */ + FILE* stream; /* Stream from which the green function is deserialized */ + + /* This signature is compared to the one serialized with the green function. + * An error is returned if they differ */ + hash256_T signature; +}; +#define SDIS_GREEN_FUNCTION_CREATE_FROM_STREAM_ARGS_DEFAULT__ { \ + NULL, /* Scene */ \ + NULL, /* Stream */ \ + {0} /* Signature */ \ +} +static const struct sdis_green_function_create_from_stream_args +SDIS_GREEN_FUNCTION_CREATE_FROM_STREAM_ARGS_DEFAULT = + SDIS_GREEN_FUNCTION_CREATE_FROM_STREAM_ARGS_DEFAULT__; + BEGIN_DECLS /******************************************************************************* @@ -1081,22 +1128,22 @@ sdis_estimator_get_realisation_time SDIS_API res_T sdis_estimator_get_convective_flux (const struct sdis_estimator* estimator, - struct sdis_mc* flux); + struct sdis_mc* flux); /* In W/m² */ SDIS_API res_T sdis_estimator_get_radiative_flux (const struct sdis_estimator* estimator, - struct sdis_mc* flux); + struct sdis_mc* flux); /* In W/m² */ SDIS_API res_T sdis_estimator_get_imposed_flux (const struct sdis_estimator* estimator, - struct sdis_mc* flux); + struct sdis_mc* flux); /* In W/m² */ SDIS_API res_T sdis_estimator_get_total_flux (const struct sdis_estimator* estimator, - struct sdis_mc* flux); + struct sdis_mc* flux); /* In W/m² */ SDIS_API res_T sdis_estimator_get_power @@ -1151,8 +1198,7 @@ sdis_green_function_write SDIS_API res_T sdis_green_function_create_from_stream - (struct sdis_scene* scn, /* Scene from which the green was evaluated */ - FILE* stream, /* Stream into which the green was serialized */ + (struct sdis_green_function_create_from_stream_args* args, struct sdis_green_function** green); /* Retrieve the scene used to compute the green function */ @@ -1175,6 +1221,11 @@ sdis_green_function_get_invalid_paths_count (const struct sdis_green_function* green, size_t* nfails); +SDIS_API res_T +sdis_green_function_get_signature + (const struct sdis_green_function* green, + hash256_T signature); + /* Iterate over all valid green function paths */ SDIS_API res_T sdis_green_function_for_each_path @@ -1291,12 +1342,18 @@ sdis_solve_boundary const struct sdis_solve_boundary_args* args, struct sdis_estimator** estimator); +/* Calculate the flux density in W/m² _entering_ the solid through the given + * boundary position, i.e. the flux density is positive or negative if the + * solid gains or loses energy, respectively. */ SDIS_API res_T sdis_solve_probe_boundary_flux (struct sdis_scene* scn, const struct sdis_solve_probe_boundary_flux_args* args, struct sdis_estimator** estimator); +/* Calculate the average flux density in W/m² _entering_ the solid through the + * given boundary surfaces, i.e. the flux density is positive or negative if + * the solid gains or loses energy, respectively. */ SDIS_API res_T sdis_solve_boundary_flux (struct sdis_scene* scn, @@ -1315,9 +1372,7 @@ sdis_solve_medium const struct sdis_solve_medium_args* args, struct sdis_estimator** estimator); -/* P = SUM(volumic_power(x)) / Nrealisations * Volume - * power (in Watt) = time_range[0] == time_range[1] - * ? P : P / (time_range[1] - time_range[0]) */ +/* power (in Watt) = SUM(volumic_power(x)) / Nrealisations * Volume */ SDIS_API res_T sdis_compute_power (struct sdis_scene* scn, diff --git a/src/sdis_Xd_begin.h b/src/sdis_Xd_begin.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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_Xd_end.h b/src/sdis_Xd_end.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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_c.h b/src/sdis_c.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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 @@ #define SDIS_C_H #include <star/ssp.h> +#include <rsys/hash.h> #include <rsys/rsys.h> /* Id of the messages sent between processes */ @@ -61,6 +62,7 @@ release_per_thread_rng extern LOCAL_SYM res_T create_per_thread_green_function (struct sdis_scene* scene, + const hash256_T signature, struct sdis_green_function** greens[]); extern LOCAL_SYM void @@ -149,6 +151,13 @@ print_progress_update int32_t progress[], const char* label); /* Text preceding the progress status */ +/* Print progress completion, i.e. rewind the printing and print 100% */ +extern LOCAL_SYM void +print_progress_completion + (struct sdis_device* dev, + int32_t progress[], + const char* label); /* Text preceding the progress status */ + /* Waiting for all processes. Without MPI this function does nothing. With MPI * it waits for MPI process synchronisation */ extern LOCAL_SYM void diff --git a/src/sdis_camera.c b/src/sdis_camera.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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_device.c b/src/sdis_device.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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 @@ -326,6 +326,7 @@ sdis_device_create } nthreads_max = (unsigned)MMAX(omp_get_max_threads(), omp_get_num_procs()); dev->allocator = allocator; + dev->no_escape_sequence = args->no_escape_sequence; dev->verbose = args->verbosity; dev->nthreads = MMIN(args->nthreads_hint, nthreads_max); ref_init(&dev->ref); diff --git a/src/sdis_device_c.h b/src/sdis_device_c.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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 @@ -46,6 +46,7 @@ struct sdis_device { struct logger logger__; /* Default logger */ struct mem_allocator* allocator; unsigned nthreads; + int no_escape_sequence; int verbose; #ifdef SDIS_ENABLE_MPI diff --git a/src/sdis_estimator.c b/src/sdis_estimator.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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 @@ -163,12 +163,6 @@ sdis_estimator_get_power return RES_BAD_ARG; SETUP_MC(power, &estimator->power.power); power->E *= estimator->power.spread; - - if(estimator->power.time_range[0] - != estimator->power.time_range[1]) { - power->E /= /* From Joule to Watt */ - (estimator->power.time_range[1]-estimator->power.time_range[0]); - } return RES_OK; } diff --git a/src/sdis_estimator_buffer.c b/src/sdis_estimator_buffer.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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_estimator_buffer_c.h b/src/sdis_estimator_buffer_c.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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_estimator_c.h b/src/sdis_estimator_c.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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 @@ -88,7 +88,7 @@ estimator_setup_realisations_count const size_t nrealisations, const size_t nsuccesses) { - ASSERT(estimator && nrealisations && nsuccesses && nsuccesses<=nrealisations); + ASSERT(estimator && nrealisations && nsuccesses<=nrealisations); estimator->nrealisations = nsuccesses; estimator->nfailures = nrealisations - nsuccesses; } @@ -99,7 +99,7 @@ estimator_setup_temperature const double sum, const double sum2) { - ASSERT(estim && estim->nrealisations); + ASSERT(estim); estim->temperature.sum = sum; estim->temperature.sum2 = sum2; estim->temperature.count = estim->nrealisations; @@ -113,7 +113,7 @@ estimator_setup_power const double spread, const double time_range[2]) { - ASSERT(estim && estim->nrealisations && time_range); + ASSERT(estim && time_range); estim->power.power.sum = sum; estim->power.power.sum2 = sum2; estim->power.power.count = estim->nrealisations; @@ -128,7 +128,7 @@ estimator_setup_realisation_time const double sum, const double sum2) { - ASSERT(estim && estim->nrealisations); + ASSERT(estim); estim->realisation_time.sum = sum; estim->realisation_time.sum2 = sum2; estim->realisation_time.count = estim->nrealisations; @@ -141,7 +141,7 @@ estimator_setup_flux const double sum, const double sum2) { - ASSERT(estim && (unsigned)name < FLUX_NAMES_COUNT__ && estim->nrealisations); + ASSERT(estim && (unsigned)name < FLUX_NAMES_COUNT__); estim->fluxes[name].sum = sum; estim->fluxes[name].sum2 = sum2; estim->fluxes[name].count = estim->nrealisations; diff --git a/src/sdis_green.c b/src/sdis_green.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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 @@ -300,6 +300,7 @@ struct sdis_green_function { size_t npaths_valid; size_t npaths_invalid; + hash256_T signature; struct accum realisation_time; /* Time per realisation */ @@ -313,6 +314,15 @@ struct sdis_green_function { /******************************************************************************* * Helper functions ******************************************************************************/ +static INLINE res_T +check_sdis_green_function_create_from_stream_args + (const struct sdis_green_function_create_from_stream_args* args) +{ + if(!args || !args->scene || !args->stream) + return RES_BAD_ARG; + return RES_OK; +} + static res_T ensure_medium_registration (struct sdis_green_function* green, @@ -892,7 +902,9 @@ sdis_green_function_write(struct sdis_green_function* green, FILE* stream) res = scene_compute_hash(green->scn, hash); if(res != RES_OK) goto error; + WRITE(hash, sizeof(hash256_T)); + WRITE(green->signature, sizeof(hash256_T)); res = write_media(green, stream); if(res != RES_OK) goto error; @@ -925,8 +937,7 @@ error: res_T sdis_green_function_create_from_stream - (struct sdis_scene* scn, - FILE* stream, + (struct sdis_green_function_create_from_stream_args* args, struct sdis_green_function** out_green) { hash256_T hash0, hash1; @@ -935,19 +946,18 @@ sdis_green_function_create_from_stream int version = 0; res_T res = RES_OK; - if(!scn || !stream || !out_green) { - res = RES_BAD_ARG; - goto error; - } + if(!out_green) { res = RES_BAD_ARG; goto error; } + res = check_sdis_green_function_create_from_stream_args(args); + if(res != RES_OK) goto error; - res = green_function_create(scn, &green); + res = green_function_create(args->scene, args->signature, &green); if(res != RES_OK) goto error; #define READ(Var, Nb) { \ - if(fread((Var), sizeof(*(Var)), (Nb), stream) != (Nb)) { \ - if(feof(stream)) { \ + if(fread((Var), sizeof(*(Var)), (Nb), args->stream) != (Nb)) { \ + if(feof(args->stream)) { \ res = RES_BAD_ARG; \ - } else if(ferror(stream)) { \ + } else if(ferror(args->stream)) { \ res = RES_IO_ERR; \ } else { \ res = RES_UNKNOWN_ERR; \ @@ -978,11 +988,20 @@ sdis_green_function_create_from_stream goto error; } - res = read_media(green, stream); + READ(hash1, sizeof(hash256_T)); + if(!hash256_eq(hash1, green->signature)) { + log_err(green->scn->dev, + "%s: the input signature does not match the saved signature\n", + FUNC_NAME); + res = RES_BAD_ARG; + goto error; + } + + res = read_media(green, args->stream); if(res != RES_OK) goto error; - res = read_interfaces(green, stream); + res = read_interfaces(green, args->stream); if(res != RES_OK) goto error; - res = read_paths_list(green, stream); + res = read_paths_list(green, args->stream); if(res != RES_OK) goto error; READ(&green->npaths_valid, 1); @@ -994,7 +1013,7 @@ sdis_green_function_create_from_stream /* Create a temporary RNG used to deserialise the RNG state */ res = ssp_rng_create(green->scn->dev->allocator, green->rng_type, &rng); if(res != RES_OK) goto error; - res = ssp_rng_read(rng, stream); + res = ssp_rng_read(rng, args->stream); if(res != RES_OK) goto error; res = ssp_rng_write(rng, green->rng_state); if(res != RES_OK) goto error; @@ -1043,6 +1062,15 @@ sdis_green_function_get_invalid_paths_count } res_T +sdis_green_function_get_signature + (const struct sdis_green_function* green, hash256_T signature) +{ + if(!green || !signature) return RES_BAD_ARG; + memcpy(signature, green->signature, sizeof(hash256_T)); + return RES_OK; +} + +res_T sdis_green_function_for_each_path (struct sdis_green_function* green, sdis_process_green_path_T func, @@ -1329,7 +1357,9 @@ error: ******************************************************************************/ res_T green_function_create - (struct sdis_scene* scn, struct sdis_green_function** out_green) + (struct sdis_scene* scn, + const hash256_T signature, + struct sdis_green_function** out_green) { struct sdis_green_function* green = NULL; res_T res = RES_OK; @@ -1348,7 +1378,11 @@ green_function_create darray_green_path_init(scn->dev->allocator, &green->paths); green->npaths_valid = SIZE_MAX; green->npaths_invalid = SIZE_MAX; + memcpy(green->signature, signature, sizeof(hash256_T)); + /* TODO replace the tmpfile. tmpfile can only be called a limited number of + * times while one could create a huge amount of green functions at the same + * time (e.g. for image rendering) */ green->rng_state = tmpfile(); if(!green->rng_state) { res = RES_IO_ERR; diff --git a/src/sdis_green.h b/src/sdis_green.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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,12 +16,13 @@ #ifndef SDIS_GREEN_H #define SDIS_GREEN_H +#include <rsys/hash.h> #include <rsys/rsys.h> /* Current version the green function data structure. One should increment it * and perform a version management onto serialized data when the gren function * data structure is updated. */ -static const int SDIS_GREEN_FUNCTION_VERSION = 1; +static const int SDIS_GREEN_FUNCTION_VERSION = 2; /* Forward declaration */ struct accum; @@ -40,6 +41,7 @@ static const struct green_path_handle GREEN_PATH_HANDLE_NULL = extern LOCAL_SYM res_T green_function_create (struct sdis_scene* scn, + const hash256_T signature, struct sdis_green_function** green); /* Merge `src' into `dst' an clear `src' */ diff --git a/src/sdis_heat_path.c b/src/sdis_heat_path.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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.c b/src/sdis_heat_path_boundary.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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 @@ -39,7 +39,6 @@ XD(boundary_path) struct sdis_interface* interf = NULL; struct sdis_medium* mdm_front = NULL; struct sdis_medium* mdm_back = NULL; - struct sdis_medium* mdm = NULL; double tmp; res_T res = RES_OK; ASSERT(scn && ctx && rwalk && rng && T); @@ -70,20 +69,6 @@ XD(boundary_path) goto exit; } - /* Check if the boundary flux is known. Note that currently, only solid media - * can have a flux as limit condition */ - mdm = interface_get_medium(interf, frag.side); - if(sdis_medium_get_type(mdm) == SDIS_SOLID) { - const double phi = interface_side_get_flux(interf, &frag); - if(phi != SDIS_FLUX_NONE) { - res = XD(solid_boundary_with_flux_path) - (scn, ctx, &frag, phi, rwalk, rng, T); - if(res != RES_OK) goto error; - - goto exit; - } - } - mdm_front = interface_get_medium(interf, SDIS_FRONT); mdm_back = interface_get_medium(interf, SDIS_BACK); diff --git a/src/sdis_heat_path_boundary_Xd_c.h b/src/sdis_heat_path_boundary_Xd_c.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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 @@ -872,4 +872,48 @@ error: goto exit; } +res_T +XD(handle_net_flux) + (const struct sdis_scene* scn, + const struct handle_net_flux_args* args, + struct XD(temperature)* T) +{ + double flux_term; + double phi; + res_T res = RES_OK; + CHK(scn && T); + CHK(args->interf && args->frag); + CHK(args->h_cond >= 0); + CHK(args->h_conv >= 0); + CHK(args->h_radi >= 0); + CHK(args->h_cond + args->h_conv + args->h_radi > 0); + + phi = interface_side_get_flux(args->interf, args->frag); + if(phi == SDIS_FLUX_NONE) goto exit; /* No flux. Do nothing */ + + if(args->picard_order > 1 && phi != 0) { + log_err(scn->dev, + "%s: invalid flux '%g' W/m^2. Could not manage a flux != 0 when the " + "picard order is not equal to 1; Picard order is currently set to %lu.\n", + FUNC_NAME, phi, (unsigned long)args->picard_order); + res = RES_BAD_ARG; + goto error; + } + + flux_term = 1.0 / (args->h_cond + args->h_conv + args->h_radi); + T->value += phi * flux_term; + + /* Register the net flux term */ + if(args->green_path) { + res = green_path_add_flux_term + (args->green_path, args->interf, args->frag, flux_term); + if(res != RES_OK) goto error; + } + +exit: + return res; +error: + goto exit; +} + #include "sdis_Xd_end.h" diff --git a/src/sdis_heat_path_boundary_Xd_fixed_flux.h b/src/sdis_heat_path_boundary_Xd_fixed_flux.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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_solid_fluid_picard1.h b/src/sdis_heat_path_boundary_Xd_solid_fluid_picard1.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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 @@ -51,7 +51,7 @@ XD(check_Tref) } if(Tref > scn->tmax) { log_err(scn->dev, - "%s: invalid maximum temperature `%gK'. The reference temperature `%gK'" + "%s: invalid maximum temperature `%gK'. The reference temperature `%gK' " "at the position `"STR_VECX"' is greater than this temperature.\n", func_name, scn->tmax, Tref, SPLITX(pos)); return RES_BAD_OP_IRRECOVERABLE; @@ -119,6 +119,9 @@ XD(solid_fluid_boundary_picard1_path) struct ssp_rng* rng, struct XD(temperature)* T) { + /* Input argument used to handle the net flux */ + struct handle_net_flux_args handle_net_flux_args = HANDLE_NET_FLUX_ARGS_NULL; + /* Input/output arguments of the function used to sample a reinjection */ struct XD(sample_reinjection_step_args) samp_reinject_step_args = XD(SAMPLE_REINJECTION_STEP_ARGS_NULL); @@ -150,6 +153,7 @@ XD(solid_fluid_boundary_picard1_path) double lambda; /* Solid conductivity */ double delta_boundary; /* Orthogonal reinjection dst at the boundary */ double delta; /* Orthogonal fitted reinjection dst at the boundary */ + double delta_m; /* delta in meter */ double r; struct sdis_heat_vertex hvtx = SDIS_HEAT_VERTEX_NULL; @@ -209,10 +213,11 @@ XD(solid_fluid_boundary_picard1_path) /* Define the orthogonal dst from the reinjection pos to the interface */ delta = reinject_step.distance / sqrt(DIM); + delta_m = delta * scn->fp_to_meter; /* Compute the convective, conductive and the upper bound radiative coef */ h_conv = interface_get_convection_coef(interf, frag); - h_cond = lambda / (delta * scn->fp_to_meter); + h_cond = lambda / delta_m; h_radi_hat = 4.0 * BOLTZMANN_CONSTANT * ctx->That3 * epsilon; /* Compute a global upper bound coefficient */ @@ -222,6 +227,17 @@ XD(solid_fluid_boundary_picard1_path) p_conv = h_conv / h_hat; p_cond = h_cond / h_hat; + /* Handle the net flux if any */ + handle_net_flux_args.interf = interf; + handle_net_flux_args.frag = frag; + handle_net_flux_args.green_path = ctx->green_path; + handle_net_flux_args.picard_order = get_picard_order(ctx); + handle_net_flux_args.h_cond = h_cond; + handle_net_flux_args.h_conv = h_conv; + handle_net_flux_args.h_radi = h_radi_hat; + res = XD(handle_net_flux)(scn, &handle_net_flux_args, T); + if(res != RES_OK) goto error; + /* Fetch the last registered heat path vertex */ if(ctx->heat_path) hvtx = *heat_path_get_last_vertex(ctx->heat_path); diff --git a/src/sdis_heat_path_boundary_Xd_solid_fluid_picardN.h b/src/sdis_heat_path_boundary_Xd_solid_fluid_picardN.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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 @@ -26,6 +26,41 @@ #include "sdis_Xd_begin.h" /******************************************************************************* + * Non generic helper functions + ******************************************************************************/ +#ifndef SDIS_HEAT_PATH_BOUNDARY_XD_SOLID_FLUID_PICARD_N_H +#define SDIS_HEAT_PATH_BOUNDARY_XD_SOLID_FLUID_PICARD_N_H + +static INLINE res_T +check_net_flux + (struct sdis_scene* scn, + const struct sdis_interface* interf, + const struct sdis_interface_fragment* frag, + const size_t picard_order) +{ + double phi; + res_T res = RES_OK; + ASSERT(scn && interf && frag && picard_order > 1); + + phi = interface_side_get_flux(interf, frag); + if(phi != SDIS_FLUX_NONE && phi != 0) { + log_err(scn->dev, + "%s: invalid flux '%g' W/m^2. Could not manage a flux != 0 when the " + "picard order is not equal to 1; Picard order is currently set to %lu.\n", + FUNC_NAME, phi, (unsigned long)picard_order); + res = RES_BAD_ARG; + goto error; + } + +exit: + return res; +error: + goto exit; +} + +#endif /* SDIS_HEAT_PATH_BOUNDARY_XD_SOLID_FLUID_PICARD_N_H */ + +/******************************************************************************* * Generic helper functions ******************************************************************************/ static INLINE res_T @@ -139,6 +174,7 @@ XD(solid_fluid_boundary_picardN_path) ASSERT(scn && rwalk && rng && T && ctx); ASSERT(XD(check_rwalk_fragment_consistency)(rwalk, frag)); + /* Fetch the Min/max temperature */ Tmin = ctx->Tmin; Tmin2 = ctx->Tmin2; @@ -159,6 +195,11 @@ XD(solid_fluid_boundary_picardN_path) ASSERT(fluid->type == SDIS_FLUID); } + /* Check that no net flux is set for this interface since the provided + * picardN algorithm does not handle it */ + res = check_net_flux(scn, interf, frag, get_picard_order(ctx)); + if(res != RES_OK) goto error; + /* Setup a fragment for the fluid side */ frag_fluid = *frag; frag_fluid.side = fluid_side; diff --git a/src/sdis_heat_path_boundary_Xd_solid_solid.h b/src/sdis_heat_path_boundary_Xd_solid_solid.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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_c.h b/src/sdis_heat_path_boundary_c.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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 @@ -68,7 +68,7 @@ SAMPLE_REINJECTION_STEP_ARGS_NULL_3d = SAMPLE_REINJECTION_STEP_ARGS_NULL___3d; #define REINJECTION_STEP_NULL___2d {S2D_HIT_NULL__, {0,0}, 0} #define REINJECTION_STEP_NULL___3d {S3D_HIT_NULL__, {0,0,0}, 0} -static const struct reinjection_step_2d +static const struct reinjection_step_2d REINJECTION_STEP_NULL_2d = REINJECTION_STEP_NULL___2d; static const struct reinjection_step_3d REINJECTION_STEP_NULL_3d = REINJECTION_STEP_NULL___3d; @@ -140,6 +140,35 @@ solid_reinjection_3d struct solid_reinjection_args_3d* args); /******************************************************************************* + * Handle net flux + ******************************************************************************/ +struct handle_net_flux_args { + struct sdis_interface* interf; + const struct sdis_interface_fragment* frag; + struct green_path_handle* green_path; + + size_t picard_order; + double h_cond; /* Convective coefficient, i.e. lambda/delta */ + double h_conv; /* Condutive coefficient */ + double h_radi; /* Radiative coefficient */ +}; +#define HANDLE_NET_FLUX_ARGS_NULL__ {NULL,NULL,NULL,0,0,0,0} +static const struct handle_net_flux_args HANDLE_NET_FLUX_ARGS_NULL = + HANDLE_NET_FLUX_ARGS_NULL__; + +extern LOCAL_SYM res_T +handle_net_flux_2d + (const struct sdis_scene* scn, + const struct handle_net_flux_args* args, + struct temperature_2d* T); + +extern LOCAL_SYM res_T +handle_net_flux_3d + (const struct sdis_scene* scn, + const struct handle_net_flux_args* args, + struct temperature_3d* T); + +/******************************************************************************* * Boundary sub-paths ******************************************************************************/ extern LOCAL_SYM res_T 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-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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 @@ -335,7 +335,7 @@ XD(handle_volumic_power) double h; double h_in_meter; double cos_U_N; - float N[DIM]; + float N[DIM] = {0}; if(args->delta == args->hit0->distance) { fX(normalize)(N, args->hit0->normal); @@ -421,7 +421,7 @@ XD(conductive_path) * that those that are supposed to be constant by the conductive random walk * remain the same. Note that we take care of the same constraints on the * solid reinjection since once reinjected, the position of the random walk - * is that at the beginning of the conductive random walkh. Thus, after a + * is that at the beginning of the conductive random walk. Thus, after a * reinjection, the next line retrieves the properties of the reinjection * position. By comparing them to the properties along the random walk, we * thus verify that the properties are constant throughout the random walk 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-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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_radiative_Xd.h b/src/sdis_heat_path_radiative_Xd.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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_interface.c b/src/sdis_interface.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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 @@ -73,6 +73,7 @@ check_interface_shader FOR_EACH(i, 0, 2) { switch(type[i]) { + case SDIS_FLUID: /* No constraint */ break; case SDIS_SOLID: if(shaders[i]->emissivity || shaders[i]->specular_fraction @@ -84,14 +85,6 @@ check_interface_shader caller_name); } break; - case SDIS_FLUID: - if(shaders[i]->flux) { - log_warn(dev, - "%s: the interface side toward a fluid can't have a flux property. " - "The shader's pointer function for this attribute should be NULL.\n", - caller_name); - } - break; default: FATAL("Unreachable code.\n"); break; } } diff --git a/src/sdis_interface_c.h b/src/sdis_interface_c.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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 @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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 @@ -41,22 +41,35 @@ log_msg static void print_info(const char* msg, void* ctx) { - (void)ctx; - fprintf(stderr, MSG_INFO_PREFIX"%s", msg); + struct sdis_device* dev = ctx; + + if(dev->no_escape_sequence) { + fprintf(stderr, MSG_INFO_PREFIX_PLAIN_TEXT"%s", msg); + } else { + 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); + struct sdis_device* dev = ctx; + if(dev->no_escape_sequence) { + fprintf(stderr, MSG_ERROR_PREFIX_PLAIN_TEXT"%s", msg); + } else { + 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); + struct sdis_device* dev = ctx; + if(dev->no_escape_sequence) { + fprintf(stderr, MSG_WARNING_PREFIX_PLAIN_TEXT"%s", msg); + } else { + fprintf(stderr, MSG_WARNING_PREFIX"%s", msg); + } } /******************************************************************************* @@ -73,9 +86,9 @@ setup_log_default(struct sdis_device* dev) 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); + logger_set_stream(&dev->logger__, LOG_OUTPUT, print_info, dev); + logger_set_stream(&dev->logger__, LOG_ERROR, print_err, dev); + logger_set_stream(&dev->logger__, LOG_WARNING, print_warn, dev); dev->logger = &dev->logger__; exit: diff --git a/src/sdis_log.h b/src/sdis_log.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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 @@ -18,16 +18,15 @@ #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 +/* By default assume messages are printed in 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): " + +/* Plain text message prefixes */ +#define MSG_INFO_PREFIX_PLAIN_TEXT "stardis-solver (info): " +#define MSG_ERROR_PREFIX_PLAIN_TEXT "stardis-solver (error): " +#define MSG_WARNING_PREFIX_PLAIN_TEXT "stardis-solver (warning): " extern LOCAL_SYM res_T setup_log_default diff --git a/src/sdis_medium.c b/src/sdis_medium.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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_medium_c.h b/src/sdis_medium_c.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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 @@ -176,7 +176,7 @@ fluid_get_properties /******************************************************************************* * Solid local functions ******************************************************************************/ -DEFINE_MDM_CHK_PROP_FUNC(solid, calorific_capacity,0, INF, 0, 1) +DEFINE_MDM_CHK_PROP_FUNC(solid, calorific_capacity, 0, INF, 0, 1) DEFINE_MDM_CHK_PROP_FUNC(solid, thermal_conductivity, 0, INF, 0, 1) DEFINE_MDM_CHK_PROP_FUNC(solid, volumic_mass, 0, INF, 0, 1) DEFINE_MDM_CHK_PROP_FUNC(solid, delta, 0, INF, 0, 1) diff --git a/src/sdis_misc.c b/src/sdis_misc.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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_Xd.h b/src/sdis_misc_Xd.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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_mpi.c b/src/sdis_mpi.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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_mpi.h b/src/sdis_mpi.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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_scene.c b/src/sdis_scene.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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 @@ -13,10 +13,6 @@ * 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 200809L /* mmap support */ -#define _DEFAULT_SOURCE 1 /* MAP_POPULATE support */ -#define _BSD_SOURCE 1 /* MAP_POPULATE for glibc < 2.19 */ - #include "sdis_scene_Xd.h" /* Generate the Generic functions of the scene */ @@ -31,9 +27,6 @@ #include <float.h> #include <limits.h> -#ifdef COMPILER_GCC -#include <sys/mman.h> -#endif /******************************************************************************* * Helper function @@ -453,32 +446,24 @@ scene_get_medium_in_closed_boundaries res_T scene_compute_hash(const struct sdis_scene* scn, hash256_T hash) { - void* data = NULL; - FILE* stream = NULL; + struct sha256_ctx sha256_ctx; size_t iprim, nprims; - size_t len; res_T res = RES_OK; ASSERT(scn && hash); - stream = tmpfile(); - if(!stream) { - res = RES_IO_ERR; - goto error; - } + sha256_ctx_init(&sha256_ctx); - #define WRITE(Var, Nb) \ - if(fwrite((Var), sizeof(*(Var)), Nb, stream) != (Nb)) { \ - res = RES_IO_ERR; \ - goto error; \ - } (void)0 if(scene_is_2d(scn)) { S2D(scene_view_primitives_count(scn->s2d_view, &nprims)); } else { S3D(scene_view_primitives_count(scn->s3d_view, &nprims)); } - WRITE(&scn->trad.reference, 1); - WRITE(&scn->tmax, 1); - WRITE(&scn->fp_to_meter, 1); + #define SHA256_UPD(Var, Nb) \ + sha256_ctx_update(&sha256_ctx, (const char*)(Var), sizeof(*Var)*(Nb)) + + SHA256_UPD(&scn->trad.reference, 1); + SHA256_UPD(&scn->tmax, 1); + SHA256_UPD(&scn->fp_to_meter, 1); FOR_EACH(iprim, 0, nprims) { struct sdis_interface* interf = NULL; size_t ivert; @@ -489,7 +474,7 @@ scene_compute_hash(const struct sdis_scene* scn, hash256_T hash) FOR_EACH(ivert, 0, 2) { struct s2d_attrib attr; S2D(segment_get_vertex_attrib(&prim, ivert, S2D_POSITION, &attr)); - WRITE(attr.value, 2); + SHA256_UPD(attr.value, 2); } } else { struct s3d_primitive prim; @@ -497,50 +482,20 @@ scene_compute_hash(const struct sdis_scene* scn, hash256_T hash) FOR_EACH(ivert, 0, 3) { struct s3d_attrib attr; S3D(triangle_get_vertex_attrib(&prim, ivert, S3D_POSITION, &attr)); - WRITE(attr.value, 3); + SHA256_UPD(attr.value, 3); } } interf = scene_get_interface(scn, (unsigned)iprim); - WRITE(&interf->medium_front->type, 1); - WRITE(&interf->medium_front->id, 1); - WRITE(&interf->medium_back->type, 1); - WRITE(&interf->medium_back->id, 1); - } - #undef WRITE - - len = (size_t)ftell(stream); - rewind(stream); -#ifdef COMPILER_GCC - data = mmap(NULL, len, PROT_READ, MAP_PRIVATE|MAP_POPULATE, fileno(stream), 0); - if(data == MAP_FAILED) { - res = RES_IO_ERR; - goto error; - } -#else - data = MEM_ALLOC_ALIGNED(scn->dev->allocator, len, 16); - if(!data) { - res = RES_MEM_ERR; - goto error; - } - if(fread(data, len, 1, stream) != 1) { - res = RES_IO_ERR; - goto error; + SHA256_UPD(&interf->medium_front->type, 1); + SHA256_UPD(&interf->medium_front->id, 1); + SHA256_UPD(&interf->medium_back->type, 1); + SHA256_UPD(&interf->medium_back->id, 1); } -#endif - - hash_sha256(data, len, hash); + #undef SHA256_UPD + sha256_ctx_finalize(&sha256_ctx, hash); -exit: -#ifdef COMPILER_GCC - if(data) munmap(data, len); -#else - if(data) MEM_RM(scn->dev->allocator, data); -#endif - if(stream) fclose(stream); return res; -error: - goto exit; } res_T diff --git a/src/sdis_scene_Xd.h b/src/sdis_scene_Xd.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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 @@ -1065,7 +1065,8 @@ XD(scene_get_medium) struct sXd(primitive) prim; size_t iprim2; const float range[2] = {FLT_MIN, FLT_MAX}; - float N[DIM], dir[DIM], cos_N_dir; + float N[DIM] = {0}; + float dir[DIM], cos_N_dir; size_t istep = 0; /* 1 primitive over 2, take a primitive from the end of the primitive list. @@ -1188,7 +1189,7 @@ XD(scene_get_medium_in_closed_boundaries) fX_set_dX(P, pos); FOR_EACH(idir, 0, 2*DIM) { struct sXd(hit) hit; - float N[DIM]; + float N[DIM] = {0}; const float range[2] = {FLT_MIN, FLT_MAX}; float cos_N_dir; diff --git a/src/sdis_scene_c.h b/src/sdis_scene_c.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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_solve.c b/src/sdis_solve.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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_solve_boundary_Xd.h b/src/sdis_solve_boundary_Xd.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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 @@ -195,6 +195,7 @@ XD(solve_boundary) int64_t irealisation = 0; size_t i; int32_t* progress = NULL; /* Per process progress bar */ + int pcent_progress = 1; /* Percentage requiring progress update */ int register_paths = SDIS_HEAT_PATH_NONE; int is_master_process = 1; ATOMIC nsolved_realisations = 0; @@ -237,6 +238,11 @@ XD(solve_boundary) is_master_process = !scn->dev->use_mpi || scn->dev->mpi_rank == 0; #endif + /* Update the progress bar every percent if escape sequences are allowed in + * log messages or only every 10 percent when only plain text is allowed. + * This reduces the number of lines of plain text printed */ + pcent_progress = scn->dev->no_escape_sequence ? 10 : 1; + /* Create the Star-XD shape of the boundary */ #if SDIS_XD_DIMENSION == 2 res = s2d_shape_create_line_segments(scn->dev->sXd(dev), &shape); @@ -292,7 +298,8 @@ XD(solve_boundary) /* Create the per thread green function */ if(out_green) { - res = create_per_thread_green_function(scn, &per_thread_green); + res = create_per_thread_green_function + (scn, args->signature, &per_thread_green); if(res != RES_OK) goto error; } @@ -443,7 +450,7 @@ XD(solve_boundary) n = (size_t)ATOMIC_INCR(&nsolved_realisations); pcent = (int)((double)n * 100.0 / (double)nrealisations + 0.5/*round*/); #pragma omp critical - if(pcent > progress[0]) { + if(pcent/pcent_progress > progress[0]/pcent_progress) { progress[0] = pcent; print_progress_update(scn->dev, progress, PROGRESS_MSG); } @@ -459,8 +466,7 @@ XD(solve_boundary) res = gather_res_T(scn->dev, (res_T)res); if(res != RES_OK) goto error; - print_progress_update(scn->dev, progress, PROGRESS_MSG); - log_info(scn->dev, "\n"); + print_progress_completion(scn->dev, progress, PROGRESS_MSG); #undef PROGRESS_MSG /* Report computation time */ @@ -587,6 +593,7 @@ XD(solve_boundary_flux) int64_t irealisation; size_t i; int32_t* progress = NULL; /* Per process progress bar */ + int pcent_progress = 1; /* Percentage requiring progress update */ int is_master_process = 1; ATOMIC nsolved_realisations = 0; ATOMIC res = RES_OK; @@ -642,6 +649,11 @@ XD(solve_boundary_flux) is_master_process = !scn->dev->use_mpi || scn->dev->mpi_rank == 0; #endif + /* Update the progress bar every percent if escape sequences are allowed in + * log messages or only every 10 percent when only plain text is allowed. + * This reduces the number of lines of plain text printed */ + pcent_progress = scn->dev->no_escape_sequence ? 10 : 1; + /* Create the per thread RNGs */ res = create_per_thread_rng (scn->dev, args->rng_state, args->rng_type, &rng_proxy, &per_thread_rng); @@ -805,9 +817,12 @@ XD(solve_boundary_flux) continue; } else if(res_simul == RES_OK) { /* Update accumulators */ const double usec = (double)time_val(&t0, TIME_NSEC) * 0.001; - const double w_conv = hc * (result.Tboundary - result.Tfluid); + /* Convective flux from fluid to solid */ + const double w_conv = hc * (result.Tfluid - result.Tboundary); + /* Radiative flux from ambient to solid */ const double w_rad = (result.Tradiative < 0) ? - 0 : hr * (result.Tboundary - result.Tradiative); + 0 : hr * (result.Tradiative - result.Tboundary); + /* Imposed flux that goes _into_ the solid */ const double w_imp = (imposed_flux != SDIS_FLUX_NONE) ? imposed_flux : 0; const double w_total = w_conv + w_rad + w_imp; /* Temperature */ @@ -840,7 +855,7 @@ XD(solve_boundary_flux) n = (size_t)ATOMIC_INCR(&nsolved_realisations); pcent = (int)((double)n * 100.0 / (double)nrealisations + 0.5/*round*/); #pragma omp critical - if(pcent > progress[0]) { + if(pcent/pcent_progress > progress[0]/pcent_progress) { progress[0] = pcent; print_progress_update(scn->dev, progress, PROGRESS_MSG); } @@ -851,8 +866,7 @@ XD(solve_boundary_flux) res = gather_res_T(scn->dev, (res_T)res); if(res != RES_OK) goto error; - print_progress_update(scn->dev, progress, PROGRESS_MSG); - log_info(scn->dev, "\n"); + print_progress_completion(scn->dev, progress, PROGRESS_MSG); #undef PROGRESS_MSG /* Report computation time */ diff --git a/src/sdis_solve_camera.c b/src/sdis_solve_camera.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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 @@ -268,15 +268,21 @@ write_tile { res_T res = RES_OK; size_t tile_org[2]; + size_t buf_sz[2]; + size_t tile_sz[2]; uint16_t x, y; ASSERT(buf && spp && tile); + SDIS(estimator_buffer_get_definition(buf, buf_sz)); + tile_org[0] = (size_t)(tile->data.x * TILE_SIZE); tile_org[1] = (size_t)(tile->data.y * TILE_SIZE); + tile_sz[0] = MMIN(TILE_SIZE, buf_sz[0] - tile_org[0]); + tile_sz[1] = MMIN(TILE_SIZE, buf_sz[1] - tile_org[1]); - FOR_EACH(y, 0, TILE_SIZE) { + FOR_EACH(y, 0, tile_sz[1]) { const size_t pix_y = tile_org[1] + y; - FOR_EACH(x, 0, TILE_SIZE) { + FOR_EACH(x, 0, tile_sz[0]) { const size_t pix_x = tile_org[0] + x; struct sdis_estimator* estimator = NULL; struct pixel* pixel = NULL; @@ -504,6 +510,7 @@ sdis_solve_camera int64_t mcode_1st; /* morton code of the 1st tile computed by the process */ int64_t mcode_incr; /* Increment toward the next morton code */ int32_t* progress = NULL; /* Per process progress bar */ + int pcent_progress = 1; /* Percentage requiring progress update */ int register_paths = SDIS_HEAT_PATH_NONE; int is_master_process = 1; ATOMIC nsolved_tiles = 0; @@ -568,6 +575,11 @@ sdis_solve_camera ntiles_proc = ntiles; } + /* Update the progress bar every percent if escape sequences are allowed in + * log messages or only every 10 percent when only plain text is allowed. + * This reduces the number of lines of plain text printed */ + pcent_progress = scn->dev->no_escape_sequence ? 10 : 1; + /* Compute the normalized pixel size */ pix_sz[0] = 1.0 / (double)args->image_definition[0]; pix_sz[1] = 1.0 / (double)args->image_definition[1]; @@ -648,7 +660,7 @@ sdis_solve_camera n = (size_t)ATOMIC_INCR(&nsolved_tiles); pcent = (int)((double)n*100.0 / (double)ntiles_proc + 0.5/*round*/); #pragma omp critical - if(pcent > progress[0]) { + if(pcent/pcent_progress > progress[0]/pcent_progress) { progress[0] = pcent; print_progress_update(scn->dev, progress, PROGRESS_MSG); } @@ -660,8 +672,7 @@ sdis_solve_camera res = gather_res_T(scn->dev, (res_T)res); if(res != RES_OK) goto error; - print_progress_update(scn->dev, progress, PROGRESS_MSG); - log_info(scn->dev, "\n"); + print_progress_completion(scn->dev, progress, PROGRESS_MSG); #undef PROGRESS_MSG /* Report computation time */ @@ -700,5 +711,3 @@ error: if(buf) { SDIS(estimator_buffer_ref_put(buf)); buf = NULL; } goto exit; } - - diff --git a/src/sdis_solve_medium_Xd.h b/src/sdis_solve_medium_Xd.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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 @@ -298,6 +298,7 @@ XD(solve_medium) size_t nrealisations = 0; int64_t irealisation; int32_t* progress = NULL; /* Per process progress bar */ + int pcent_progress = 1; /* Percentage requiring progress update */ int is_master_process = 1; int cumul_is_init = 0; int register_paths = SDIS_HEAT_PATH_NONE; @@ -327,6 +328,11 @@ XD(solve_medium) nthreads = scn->dev->nthreads; allocator = scn->dev->allocator; + /* Update the progress bar every percent if escape sequences are allowed in + * log messages or only every 10 percent when only plain text is allowed. + * This reduces the number of lines of plain text printed */ + pcent_progress = scn->dev->no_escape_sequence ? 10 : 1; + /* Create the per thread RNGs */ res = create_per_thread_rng (scn->dev, args->rng_state, args->rng_type, &rng_proxy, &per_thread_rng); @@ -349,7 +355,8 @@ XD(solve_medium) if(res != RES_OK) goto error; if(out_green) { - res = create_per_thread_green_function(scn, &per_thread_green); + res = create_per_thread_green_function + (scn, args->signature, &per_thread_green); if(res != RES_OK) goto error; } @@ -470,7 +477,7 @@ XD(solve_medium) n = (size_t)ATOMIC_INCR(&nsolved_realisations); pcent = (int)((double)n * 100.0 / (double)nrealisations + 0.5/*round*/); #pragma omp critical - if(pcent > progress[0]) { + if(pcent/pcent_progress > progress[0]/pcent_progress) { progress[0] = pcent; print_progress_update(scn->dev, progress, PROGRESS_MSG); } @@ -486,8 +493,7 @@ XD(solve_medium) res = gather_res_T(scn->dev, (res_T)res); if(res != RES_OK) goto error; - print_progress_update(scn->dev, progress, PROGRESS_MSG); - log_info(scn->dev, "\n"); + print_progress_completion(scn->dev, progress, PROGRESS_MSG); #undef PROGRESS_MSG /* Report computation time */ diff --git a/src/sdis_solve_probe_Xd.h b/src/sdis_solve_probe_Xd.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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 @@ -102,6 +102,7 @@ XD(solve_probe) size_t nrealisations = 0; int64_t irealisation = 0; int32_t* progress = NULL; /* Per process progress bar */ + int pcent_progress = 1; /* Percentage requiring progress update */ int register_paths = SDIS_HEAT_PATH_NONE; int is_master_process = 1; ATOMIC nsolved_realisations = 0; @@ -130,6 +131,11 @@ XD(solve_probe) nthreads = scn->dev->nthreads; allocator = scn->dev->allocator; + /* Update the progress bar every percent if escape sequences are allowed in + * log messages or only every 10 percent when only plain text is allowed. + * This reduces the number of lines of plain text printed */ + pcent_progress = scn->dev->no_escape_sequence ? 10 : 1; + /* Create the per thread RNGs */ res = create_per_thread_rng (scn->dev, args->rng_state, args->rng_type, &rng_proxy, &per_thread_rng); @@ -151,7 +157,8 @@ XD(solve_probe) /* Create the per thread green function */ if(out_green) { - res = create_per_thread_green_function(scn, &per_thread_green); + res = create_per_thread_green_function + (scn, args->signature, &per_thread_green); if(res != RES_OK) goto error; } @@ -265,7 +272,7 @@ XD(solve_probe) pcent = (int)((double)n * 100.0 / (double)nrealisations + 0.5/*round*/); #pragma omp critical - if(pcent > progress[0]) { + if(pcent/pcent_progress > progress[0]/pcent_progress) { progress[0] = pcent; print_progress_update(scn->dev, progress, PROGRESS_MSG); } @@ -283,8 +290,7 @@ XD(solve_probe) res = gather_res_T(scn->dev, (res_T)res); if(res != RES_OK) goto error; - print_progress_update(scn->dev, progress, PROGRESS_MSG); - log_info(scn->dev, "\n"); + print_progress_completion(scn->dev, progress, PROGRESS_MSG); #undef PROGRESS_MSG /* Report computation time */ 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-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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 @@ -142,6 +142,7 @@ XD(solve_probe_boundary) size_t nrealisations = 0; int64_t irealisation = 0; int32_t* progress = NULL; /* Per process progress bar */ + int pcent_progress = 1; /* Percentage requiring progress update */ int register_paths = SDIS_HEAT_PATH_NONE; int is_master_process = 1; ATOMIC nsolved_realisations = 0; @@ -174,6 +175,11 @@ XD(solve_probe_boundary) nthreads = scn->dev->nthreads; allocator = scn->dev->allocator; + /* Update the progress bar every percent if escape sequences are allowed in + * log messages or only every 10 percent when only plain text is allowed. + * This reduces the number of lines of plain text printed */ + pcent_progress = scn->dev->no_escape_sequence ? 10 : 1; + /* Create the per thread RNGs */ res = create_per_thread_rng (scn->dev, args->rng_state, args->rng_type, &rng_proxy, &per_thread_rng); @@ -191,7 +197,8 @@ XD(solve_probe_boundary) /* Create the per thread green function */ if(out_green) { - res = create_per_thread_green_function(scn, &per_thread_green); + res = create_per_thread_green_function + (scn, args->signature, &per_thread_green); if(res != RES_OK) goto error; } @@ -307,7 +314,7 @@ XD(solve_probe_boundary) n = (size_t)ATOMIC_INCR(&nsolved_realisations); pcent = (int)((double)n * 100.0 / (double)nrealisations + 0.5/*round*/); #pragma omp critical - if(pcent > progress[0]) { + if(pcent/pcent_progress > progress[0]/pcent_progress) { progress[0] = pcent; print_progress_update(scn->dev, progress, PROGRESS_MSG); } @@ -324,8 +331,7 @@ XD(solve_probe_boundary) res = gather_res_T(scn->dev, (res_T)res); if(res != RES_OK) goto error; - print_progress_update(scn->dev, progress, PROGRESS_MSG); - log_info(scn->dev, "\n"); + print_progress_completion(scn->dev, progress, PROGRESS_MSG); #undef PROGRESS_MSG /* Report computation time */ @@ -446,6 +452,7 @@ XD(solve_probe_boundary_flux) size_t nrealisations = 0; int64_t irealisation = 0; int32_t* progress = NULL; /* Per process progress bar */ + int pcent_progress = 1; /* Percentage requiring progress update */ int is_master_process = 1; ATOMIC nsolved_realisations = 0; ATOMIC res = RES_OK; @@ -481,6 +488,11 @@ XD(solve_probe_boundary_flux) is_master_process = !scn->dev->use_mpi || scn->dev->mpi_rank == 0; #endif + /* Update the progress bar every percent if escape sequences are allowed in + * log messages or only every 10 percent when only plain text is allowed. + * This reduces the number of lines of plain text printed */ + pcent_progress = scn->dev->no_escape_sequence ? 10 : 1; + /* Create the per thread RNGs */ res = create_per_thread_rng (scn->dev, args->rng_state, args->rng_type, &rng_proxy, &per_thread_rng); @@ -599,10 +611,14 @@ XD(solve_probe_boundary_flux) continue; } else if(res_simul == RES_OK) { /* Update accumulators */ const double usec = (double)time_val(&t0, TIME_NSEC) * 0.001; - const double w_conv = hc * (result.Tboundary - result.Tfluid); + /* Convective flux from fluid to solid */ + const double w_conv = hc * (result.Tfluid - result.Tboundary); + /* Radiative flux from ambient to solid */ const double w_rad = (result.Tradiative < 0) ? - 0 : hr * (result.Tboundary - result.Tradiative); + 0 : hr * (result.Tradiative - result.Tboundary); + /* Imposed flux that goes _into_ the solid */ const double w_imp = (imposed_flux != SDIS_FLUX_NONE) ? imposed_flux : 0; + /* Total flux */ const double w_total = w_conv + w_rad + w_imp; /* Temperature */ acc_temp->sum += result.Tboundary; @@ -634,7 +650,7 @@ XD(solve_probe_boundary_flux) n = (size_t)ATOMIC_INCR(&nsolved_realisations); pcent = (int)((double)n * 100.0 / (double)nrealisations + 0.5/*round*/); #pragma omp critical - if(pcent > progress[0]) { + if(pcent/pcent_progress > progress[0]/pcent_progress) { progress[0] = pcent; print_progress_update(scn->dev, progress, PROGRESS_MSG); } @@ -645,8 +661,7 @@ XD(solve_probe_boundary_flux) res = gather_res_T(scn->dev, (res_T)res); if(res != RES_OK) goto error; - print_progress_update(scn->dev, progress, PROGRESS_MSG); - log_info(scn->dev, "\n"); + print_progress_completion(scn->dev, progress, PROGRESS_MSG); #undef PROGRESS_MSG /* Report computation time */ diff --git a/src/sdis_tile.c b/src/sdis_tile.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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_tile.h b/src/sdis_tile.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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.c b/src/test_sdis.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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_accum_buffer.c b/src/test_sdis_accum_buffer.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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_compute_power.c b/src/test_sdis_compute_power.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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 @@ -267,7 +267,7 @@ main(int argc, char** argv) /* Check results for solid 0 */ ref = 4.0/3.0 * PI * POWER0; - printf("Mean power of the solid0 = %g ~ %g +/- %g\n", + printf("Mean power of the solid0 = %g W ~ %g W +/- %g\n", ref, mpow.E, mpow.SE); check_intersection(ref, 1.e-3*ref, mpow.E, 3*mpow.SE); OK(sdis_estimator_ref_put(estimator)); @@ -280,7 +280,7 @@ main(int argc, char** argv) /* Check results for solid 1 */ OK(sdis_estimator_get_power(estimator, &mpow)); ref = PI * 10 * POWER1; - printf("Mean power of the solid1 = %g ~ %g +/- %g\n", + printf("Mean power of the solid1 = %g W ~ %g W +/- %g\n", ref, mpow.E, mpow.SE); check_intersection(ref, 1.e-3*ref, mpow.E, 3*mpow.SE); OK(sdis_estimator_ref_put(estimator)); @@ -293,8 +293,8 @@ main(int argc, char** argv) if(is_master_process) { /* Check for a not null time range */ OK(sdis_estimator_get_power(estimator, &mpow)); - ref = PI * 10 * POWER1 / 10; - printf("Mean power of the solid1 in [0, 10] s = %g ~ %g +/- %g\n", + ref = PI * 10 * POWER1; + printf("Mean power of the solid1 in [0, 10] s = %g W ~ %g W +/- %g\n", ref, mpow.E, mpow.SE); check_intersection(ref, 1.e-3*ref, mpow.E, 3*mpow.SE); OK(sdis_estimator_ref_put(estimator)); @@ -317,7 +317,7 @@ main(int argc, char** argv) if(is_master_process) { OK(sdis_estimator_get_power(estimator, &mpow)); ref = 4.0/3.0*PI*POWER0 + PI*10*POWER1; - printf("Mean power of the sphere+cylinder = %g ~ %g +/- %g\n", + printf("Mean power of the sphere+cylinder = %g W ~ %g W +/- %g\n", ref, mpow.E, mpow.SE); check_intersection(ref, 1e-2*ref, mpow.E, 3*mpow.SE); OK(sdis_estimator_ref_put(estimator)); diff --git a/src/test_sdis_conducto_radiative.c b/src/test_sdis_conducto_radiative.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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_2d.c b/src/test_sdis_conducto_radiative_2d.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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_contact_resistance.c b/src/test_sdis_contact_resistance.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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_contact_resistance.h b/src/test_sdis_contact_resistance.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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_contact_resistance_2.c b/src/test_sdis_contact_resistance_2.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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_convection.c b/src/test_sdis_convection.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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_convection_non_uniform.c b/src/test_sdis_convection_non_uniform.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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_data.c b/src/test_sdis_data.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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_flux2.c b/src/test_sdis_flux2.c @@ -0,0 +1,542 @@ +/* Copyright (C) 2016-2023 |Méso|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/>. */ + +#include "sdis.h" +#include "test_sdis_utils.h" + +#define UNKNOWN_TEMPERATURE -1 + +/* This test consists in solving the temperature profile in a solid slab + * surrounded by two different convective and radiative temperatures. The + * conductivity of the solid material is known, as well as its thickness. A net + * flux is fixed on the left side of the slab. + * + * + * Y ////(0.1,1,1) 280K + * | +----------+-------+ (1.1,1,1) + * o--- X /##########/'E=1 /| + * / +----------+-------+ | + * Z /_ |##########|*' _\ | | + * ---> \ \ E=1|##########|*'/ / |280K + * 320K-> \__/ |##########|*'\__/ | | + * ---> 330K |##########|*'290K | | + * --\|##########|*+.... |.+ + * 10000W.m^-2 --/|##########|/ |/ + * (-1,-1,-1) +----------+-------+ + * (0,-1,-1)/////// 280K + * + */ + +enum interface_type { + ADIABATIC, + FIXED_TEMPERATURE, + SOLID_FLUID_WITH_FLUX, + SOLID_FLUID, + INTERFACES_COUNT__ +}; + +struct probe { + double x; + double time; + double ref; /* Analytically computed temperature */ +}; + +/******************************************************************************* + * Geometry + ******************************************************************************/ +struct geometry { + const double* positions; + const size_t* indices; + struct sdis_interface** interfaces; +}; + +static const double vertices_3d[12/*#vertices*/*3/*#coords per vertex*/] = { + 0.0,-1.0,-1.0, + 0.1,-1.0,-1.0, + 0.0, 1.0,-1.0, + 0.1, 1.0,-1.0, + 0.0,-1.0, 1.0, + 0.1,-1.0, 1.0, + 0.0, 1.0, 1.0, + 0.1, 1.0, 1.0, + 1.1,-1.0,-1.0, + 1.1, 1.0,-1.0, + 1.1,-1.0, 1.0, + 1.1, 1.0, 1.0 +}; +static const size_t nvertices_3d = sizeof(vertices_3d) / (sizeof(double)*3); + +static const size_t indices_3d[22/*#triangles*/*3/*#indices per triangle*/] = { + 0, 2, 1, 1, 2, 3, /* Solid -Z */ + 0, 4, 2, 2, 4, 6, /* Solid -X */ + 4, 5, 6, 6, 5, 7, /* Solid +Z */ + 3, 7, 1, 1, 7, 5, /* Solid +X */ + 2, 6, 3, 3, 6, 7, /* Solid +Y */ + 0, 1, 4, 4, 1, 5, /* Solid -Y */ + + 1, 3, 8, 8, 3, 9, /* Right fluid -Z */ + 5, 10, 7, 7, 10, 11, /* Right fluid +Z */ + 9, 11, 8, 8, 11, 10, /* Right fluid +X */ + 3, 7, 9, 9, 7, 11, /* Right fluid +Y */ + 1, 8, 5, 5, 8, 10 /* Right fluid -Y */ +}; +static const size_t nprimitives_3d = sizeof(indices_3d) / (sizeof(size_t)*3); + +static void +get_indices_3d(const size_t itri, size_t ids[3], void* ctx) +{ + struct geometry* geom = ctx; + CHK(ctx != NULL); + ids[0] = geom->indices[itri*3+0]; + ids[1] = geom->indices[itri*3+1]; + ids[2] = geom->indices[itri*3+2]; +} + +static void +get_position_3d(const size_t ivert, double pos[3], void* ctx) +{ + struct geometry* geom = ctx; + CHK(ctx != NULL); + pos[0] = geom->positions[ivert*3+0]; + pos[1] = geom->positions[ivert*3+1]; + pos[2] = geom->positions[ivert*3+2]; +} + +static void +get_interface(const size_t iprim, struct sdis_interface** bound, void* ctx) +{ + struct geometry* geom = ctx; + CHK(ctx != NULL); + *bound = geom->interfaces[iprim]; +} + +/******************************************************************************* + * Solid media + ******************************************************************************/ +struct solid { + double lambda; + double rho; + double cp; + double volumic_power; +}; + +static double +solid_get_calorific_capacity + (const struct sdis_rwalk_vertex* vtx, struct sdis_data* data) +{ + const struct solid* solid = sdis_data_cget(data); + CHK(vtx && solid); + return solid->cp; +} + +static double +solid_get_thermal_conductivity + (const struct sdis_rwalk_vertex* vtx, struct sdis_data* data) +{ + const struct solid* solid = sdis_data_cget(data); + CHK(vtx && solid); + return solid->lambda; +} + +static double +solid_get_volumic_mass + (const struct sdis_rwalk_vertex* vtx, struct sdis_data* data) +{ + const struct solid* solid = sdis_data_cget(data); + CHK(vtx && solid); + return solid->rho; +} + +static double +solid_get_delta + (const struct sdis_rwalk_vertex* vtx, struct sdis_data* data) +{ + CHK(vtx && data); + return 0.005; +} + +static double +solid_get_temperature + (const struct sdis_rwalk_vertex* vtx, struct sdis_data* data) +{ + const struct solid* solid = sdis_data_cget(data); + CHK(vtx && solid); + + if(vtx->time > 0) { + return UNKNOWN_TEMPERATURE; + } else { + /* The initial temperature is a linear profile between T1 and T2, where T1 + * and T2 are the temperature on the left and right slab boundary, + * respectively. */ + const double T1 = 306.334; + const double T2 = 294.941; + const double u = CLAMP(vtx->P[0] / 0.1, 0.0, 1.0); + return u*(T2 - T1) + T1; + } +} + +static void +create_solid + (struct sdis_device* dev, + const struct solid* solid_props, + struct sdis_medium** solid) +{ + struct sdis_data* data = NULL; + struct sdis_solid_shader shader = SDIS_SOLID_SHADER_NULL; + CHK(dev && solid_props && solid); + + OK(sdis_data_create + (dev, sizeof(struct solid), ALIGNOF(struct solid), NULL, &data)); + memcpy(sdis_data_get(data), solid_props, sizeof(struct solid)); + shader.calorific_capacity = solid_get_calorific_capacity; + shader.thermal_conductivity = solid_get_thermal_conductivity; + shader.volumic_mass = solid_get_volumic_mass; + shader.delta = solid_get_delta; + shader.temperature = solid_get_temperature; + OK(sdis_solid_create(dev, &shader, data, solid)); + OK(sdis_data_ref_put(data)); +} + +/******************************************************************************* + * Fluid media + ******************************************************************************/ +struct fluid { + double temperature; +}; + +static double +fluid_get_temperature + (const struct sdis_rwalk_vertex* vtx, struct sdis_data* data) +{ + const struct fluid* fluid = sdis_data_cget(data); + CHK(vtx && fluid); + return fluid->temperature; +} + +static void +create_fluid + (struct sdis_device* dev, + const struct fluid* fluid_props, + struct sdis_medium** fluid) +{ + struct sdis_data* data = NULL; + struct sdis_fluid_shader shader = DUMMY_FLUID_SHADER; + CHK(dev && fluid_props && fluid); + + OK(sdis_data_create + (dev, sizeof(struct fluid), ALIGNOF(struct fluid), NULL, &data)); + memcpy(sdis_data_get(data), fluid_props, sizeof(struct fluid)); + shader.temperature = fluid_get_temperature; + OK(sdis_fluid_create(dev, &shader, data, fluid)); + OK(sdis_data_ref_put(data)); +} + +/******************************************************************************* + * Interface + ******************************************************************************/ +struct interf { + double h; + double emissivity; + double phi; + double temperature; + double Tref; +}; + +static double +interface_get_temperature + (const struct sdis_interface_fragment* frag, struct sdis_data* data) +{ + const struct interf* interf = sdis_data_cget(data); + CHK(frag && data); + return interf->temperature; +} + +static double +interface_get_reference_temperature + (const struct sdis_interface_fragment* frag, struct sdis_data* data) +{ + const struct interf* interf = sdis_data_cget(data); + CHK(frag && interf); + return interf->Tref; +} + +static double +interface_get_convection_coef + (const struct sdis_interface_fragment* frag, struct sdis_data* data) +{ + const struct interf* interf = sdis_data_cget(data); + CHK(frag && interf); + return interf->h; +} + +static double +interface_get_emissivity + (const struct sdis_interface_fragment* frag, struct sdis_data* data) +{ + const struct interf* interf = sdis_data_cget(data); + CHK(frag && interf); + return interf->emissivity; +} + +static double +interface_get_specular_fraction + (const struct sdis_interface_fragment* frag, struct sdis_data* data) +{ + CHK(frag && data); + return 0; /* Unused */ +} + +static double +interface_get_flux + (const struct sdis_interface_fragment* frag, struct sdis_data* data) +{ + const struct interf* interf = sdis_data_cget(data); + CHK(frag && interf); + return interf->phi; +} + +static void +create_interface + (struct sdis_device* dev, + struct sdis_medium* front, + struct sdis_medium* back, + const struct interf* interf, + struct sdis_interface** out_interf) +{ + struct sdis_interface_shader shader = SDIS_INTERFACE_SHADER_NULL; + struct sdis_data* data = NULL; + + CHK(interf != NULL); + + shader.front.temperature = interface_get_temperature; + shader.back.temperature = interface_get_temperature; + shader.front.flux = interface_get_flux; + shader.back.flux = interface_get_flux; + + if(sdis_medium_get_type(front) != sdis_medium_get_type(back)) { + shader.convection_coef = interface_get_convection_coef; + } + if(sdis_medium_get_type(front) == SDIS_FLUID) { + shader.front.emissivity = interface_get_emissivity; + shader.front.specular_fraction = interface_get_specular_fraction; + shader.front.reference_temperature = interface_get_reference_temperature; + } + if(sdis_medium_get_type(back) == SDIS_FLUID) { + shader.back.emissivity = interface_get_emissivity; + shader.back.specular_fraction = interface_get_specular_fraction; + shader.back.reference_temperature = interface_get_reference_temperature; + } + shader.convection_coef_upper_bound = MMAX(0, interf->h); + + OK(sdis_data_create + (dev, sizeof(struct interf), ALIGNOF(struct interf), NULL, &data)); + memcpy(sdis_data_get(data), interf, sizeof(*interf)); + + OK(sdis_interface_create(dev, front, back, &shader, data, out_interf)); + OK(sdis_data_ref_put(data)); +} + +/******************************************************************************* + * Create scene + ******************************************************************************/ +static void +create_scene_3d + (struct sdis_device* dev, + struct sdis_interface* interfaces[INTERFACES_COUNT__], + struct sdis_scene** scn) +{ + struct geometry geom; + struct sdis_interface* prim_interfaces[32]; + struct sdis_scene_create_args scn_args = SDIS_SCENE_CREATE_ARGS_DEFAULT; + + CHK(dev && interfaces && scn); + + /* Setup the per primitive interface of the solid medium */ + prim_interfaces[0] = prim_interfaces[1] = interfaces[ADIABATIC]; + prim_interfaces[2] = prim_interfaces[3] = interfaces[SOLID_FLUID_WITH_FLUX]; + prim_interfaces[4] = prim_interfaces[5] = interfaces[ADIABATIC]; + prim_interfaces[6] = prim_interfaces[7] = interfaces[SOLID_FLUID]; + prim_interfaces[8] = prim_interfaces[9] = interfaces[ADIABATIC]; + prim_interfaces[10] = prim_interfaces[11] = interfaces[ADIABATIC]; + + /* Setup the per primitive interface for the right fluid */ + prim_interfaces[12] = prim_interfaces[13] = interfaces[FIXED_TEMPERATURE]; + prim_interfaces[14] = prim_interfaces[15] = interfaces[FIXED_TEMPERATURE]; + prim_interfaces[16] = prim_interfaces[17] = interfaces[FIXED_TEMPERATURE]; + prim_interfaces[18] = prim_interfaces[19] = interfaces[FIXED_TEMPERATURE]; + prim_interfaces[20] = prim_interfaces[21] = interfaces[FIXED_TEMPERATURE]; + + /* Create the scene */ + geom.positions = vertices_3d; + geom.indices = indices_3d; + geom.interfaces = prim_interfaces; + scn_args.get_indices = get_indices_3d; + scn_args.get_interface = get_interface; + scn_args.get_position = get_position_3d; + scn_args.nprimitives = nprimitives_3d; + scn_args.nvertices = nvertices_3d; + scn_args.t_range[0] = 300; + scn_args.t_range[1] = 300; + scn_args.context = &geom; + scn_args.trad.temperature = 320; + scn_args.trad.reference = 300; + OK(sdis_scene_create(dev, &scn_args, scn)); +} + +/******************************************************************************* + * Helper functions + ******************************************************************************/ +static void +check(struct sdis_scene* scn, const struct probe* probe) +{ + struct sdis_solve_probe_args args = SDIS_SOLVE_PROBE_ARGS_DEFAULT; + struct sdis_estimator* estimator = NULL; + struct sdis_mc T = SDIS_MC_NULL; + + CHK(scn && probe); + + args.nrealisations = 10000; + args.picard_order = 1; + args.position[0] = probe->x; + args.position[1] = 0; + args.position[2] = 0; + args.time_range[0] = probe->time; + args.time_range[1] = probe->time; + + OK(sdis_solve_probe(scn, &args, &estimator)); + OK(sdis_estimator_get_temperature(estimator, &T)); + OK(sdis_estimator_ref_put(estimator)); + + printf("Temperature at x=%g, t=%g: %g ~ %g +/- %g\n", + probe->x, probe->time, probe->ref, T.E, T.SE); + + CHK(eq_eps(probe->ref, T.E, T.SE*3)); +} + +/******************************************************************************* + * Test + ******************************************************************************/ +int +main(int argc, char** argv) +{ + struct sdis_device* dev = NULL; + struct sdis_scene* scn_3d = NULL; + struct sdis_medium* solid = NULL; + struct sdis_medium* dummy = NULL; + struct sdis_medium* fluid1 = NULL; + struct sdis_medium* fluid2 = NULL; + struct sdis_interface* interfaces[INTERFACES_COUNT__]; + + struct solid solid_props; + struct fluid fluid_props; + struct interf interf_props; + + const struct probe probes[] = { + {0.01, 1000.0, 481.72005748728628}, + {0.05, 1000.0, 335.19469995601020}, + {0.09, 1000.0, 299.94436943411478}, + {0.01, 2000.0, 563.21759568607558}, + {0.05, 2000.0, 392.79827670626440}, + {0.09, 2000.0, 324.89742556243448}, + {0.01, 3000.0, 620.25242712533577}, + {0.05, 3000.0, 444.73414407361213}, + {0.09, 3000.0, 359.44045704073852}, + {0.01, 4000.0, 665.65935222224493}, + {0.05, 4000.0, 490.32470982110840}, + {0.09, 4000.0, 393.89924931902408}, + {0.01, 10000.0, 830.44439052891505}, + {0.05, 10000.0, 664.82771620162805}, + {0.09, 10000.0, 533.92442748613928} + }; + const size_t nprobes = sizeof(probes)/sizeof(*probes); + size_t iprobe; + + (void)argc, (void)argv; + + OK(sdis_device_create(&SDIS_DEVICE_CREATE_ARGS_DEFAULT, &dev)); + + /* Solid medium */ + solid_props.lambda = 1.15; + solid_props.rho = 1700; + solid_props.cp = 800; + create_solid(dev, &solid_props, &solid); + + /* Dummy solid medium */ + solid_props.lambda = 0; + solid_props.rho = 1700; + solid_props.cp = 800; + create_solid(dev, &solid_props, &dummy); + + /* Fluid media */ + fluid_props.temperature = 330; + create_fluid(dev, &fluid_props, &fluid1); + fluid_props.temperature = 290; + create_fluid(dev, &fluid_props, &fluid2); + + /* Adiabatic interfaces */ + interf_props.h = 0; + interf_props.emissivity = 0; + interf_props.phi = SDIS_FLUX_NONE; + interf_props.temperature = UNKNOWN_TEMPERATURE; + interf_props.Tref = UNKNOWN_TEMPERATURE; + create_interface(dev, solid, dummy, &interf_props, &interfaces[ADIABATIC]); + + /* Interfaces with a fixed temperature */ + interf_props.h = 1; + interf_props.emissivity = 1; + interf_props.phi = SDIS_FLUX_NONE; + interf_props.temperature = 280; + interf_props.Tref = 300; + create_interface + (dev, fluid2, dummy, &interf_props, &interfaces[FIXED_TEMPERATURE]); + + /* Interfaces with a fixed flux */ + interf_props.h = 2; + interf_props.emissivity = 1; + interf_props.phi = 10000; + interf_props.temperature = UNKNOWN_TEMPERATURE; + interf_props.Tref = 300; + create_interface + (dev, solid, fluid1, &interf_props, &interfaces[SOLID_FLUID_WITH_FLUX]); + + interf_props.h = 8; + interf_props.emissivity = 1; + interf_props.phi = SDIS_FLUX_NONE; + interf_props.temperature = UNKNOWN_TEMPERATURE; + interf_props.Tref = 300; + create_interface + (dev, solid, fluid2, &interf_props, &interfaces[SOLID_FLUID]); + + create_scene_3d(dev, interfaces, &scn_3d); + + FOR_EACH(iprobe, 0, nprobes) { + check(scn_3d, &probes[iprobe]); + } + + /* Release memory */ + OK(sdis_scene_ref_put(scn_3d)); + OK(sdis_medium_ref_put(solid)); + OK(sdis_medium_ref_put(dummy)); + OK(sdis_medium_ref_put(fluid1)); + OK(sdis_medium_ref_put(fluid2)); + OK(sdis_interface_ref_put(interfaces[ADIABATIC])); + OK(sdis_interface_ref_put(interfaces[FIXED_TEMPERATURE])); + OK(sdis_interface_ref_put(interfaces[SOLID_FLUID_WITH_FLUX])); + OK(sdis_interface_ref_put(interfaces[SOLID_FLUID])); + OK(sdis_device_ref_put(dev)); + + CHK(mem_allocated_size() == 0); + return 0; +} diff --git a/src/test_sdis_flux_with_h.c b/src/test_sdis_flux_with_h.c @@ -0,0 +1,299 @@ +/* Copyright (C) 2016-2023 |Méso|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/>. */ + +#include "sdis.h" +#include "test_sdis_utils.h" + +/* + * The configuration is a rectangle whose the conductivity is lambda and its + * temperature is unknown. Its top and bottom boundaries rectangle are + * adiabatics while its left and right ones have a fixed fluxes of phi1 and + * phi2 respectively. The left boundary has also a convective exchange with the + * surrounding fluid whose temperature is Text. At stationnary, the + * temperature at a given position into the solid rectangle is: + * + * T(x) = phi2/lambda*x + (Text + (phi1 + phi2)/h) + * + * with h the convective coefficient on the left boundary + * + * + * Text ///// (0.2,0.5) + * +---------+ + * | | + * h _\ |--> <--| + * / / phi1-> <-phi2 + * \__/ |--> <--| + * | | + * +---------+ + * (0,0) /////// + */ + +#define LAMBDA 25.0 +#define RHO 7500.0 +#define CP 500.0 +#define DELTA 0.01 +#define Text 373.15 +#define PHI1 1000.0 +#define PHI2 5000.0 +#define H 10 + +#define N 10000 /* #realisations */ + +/******************************************************************************* + * Geometry + ******************************************************************************/ +static void +get_position(const size_t ivert, double pos[2], void* ctx) +{ + square_get_position(ivert, pos, ctx); + pos[0] *= 0.2; + pos[1] *= 0.5; +} + +/******************************************************************************* + * Media + ******************************************************************************/ +static double +solid_get_calorific_capacity + (const struct sdis_rwalk_vertex* vtx, + struct sdis_data* data) +{ + (void)data, (void)vtx; + return CP; +} + +static double +solid_get_thermal_conductivity + (const struct sdis_rwalk_vertex* vtx, + struct sdis_data* data) +{ + (void)data, (void)vtx; + return LAMBDA; +} + +static double +solid_get_volumic_mass + (const struct sdis_rwalk_vertex* vtx, + struct sdis_data* data) +{ + (void)data, (void)vtx; + return RHO; +} + +static double +solid_get_delta + (const struct sdis_rwalk_vertex* vtx, + struct sdis_data* data) +{ + (void)data, (void)vtx; + return DELTA; +} + +static double +solid_get_temperature + (const struct sdis_rwalk_vertex* vtx, + struct sdis_data* data) +{ + (void)data, (void)vtx; + return -1; +} + +static double +fluid_get_temperature + (const struct sdis_rwalk_vertex* vtx, + struct sdis_data* data) +{ + (void)data, (void)vtx; + return Text; +} + +static struct sdis_medium* +create_solid(struct sdis_device* dev) +{ + struct sdis_solid_shader shader = SDIS_SOLID_SHADER_NULL; + struct sdis_medium* solid = NULL; + + /* Create the solid_medium */ + shader.calorific_capacity = solid_get_calorific_capacity; + shader.thermal_conductivity = solid_get_thermal_conductivity; + shader.volumic_mass = solid_get_volumic_mass; + shader.delta = solid_get_delta; + shader.temperature = solid_get_temperature; + OK(sdis_solid_create(dev, &shader, NULL, &solid)); + return solid; +} + +static struct sdis_medium* +create_fluid(struct sdis_device* dev) +{ + struct sdis_fluid_shader shader = DUMMY_FLUID_SHADER; + struct sdis_medium* fluid = NULL; + + /* Create the solid_medium */ + shader.temperature = fluid_get_temperature; + OK(sdis_fluid_create(dev, &shader, NULL, &fluid)); + return fluid; +} + +/******************************************************************************* + * Interfaces + ******************************************************************************/ +struct interf { + double h; + double phi; +}; + +static double +interface_get_convection_coef + (const struct sdis_interface_fragment* frag, + struct sdis_data* data) +{ + const struct interf* interf = sdis_data_cget(data); + (void)frag; + return interf->h; +} + +static double +interface_get_flux + (const struct sdis_interface_fragment* frag, + struct sdis_data* data) +{ + const struct interf* interf = sdis_data_cget(data); + (void)frag; + return interf->phi; +} + +static struct sdis_interface* +interface_create + (struct sdis_device* sdis, + struct sdis_medium* front, + struct sdis_medium* back, + const double h, + const double phi) +{ + struct sdis_interface* interf = NULL; + struct sdis_interface_shader shader = SDIS_INTERFACE_SHADER_NULL; + struct sdis_data* data = NULL; + struct interf* props = NULL; + + shader.front.flux = interface_get_flux; + shader.convection_coef = interface_get_convection_coef; + shader.convection_coef_upper_bound = h; + + OK(sdis_data_create(sdis, sizeof(struct interf), 16, NULL, &data)); + props = sdis_data_get(data); + props->h = h; + props->phi = phi; + OK(sdis_interface_create(sdis, front, back, &shader, data, &interf)); + OK(sdis_data_ref_put(data)); + return interf; +} + +/******************************************************************************* + * Test + ******************************************************************************/ +int +main(int argc, char** argv) +{ + struct sdis_device* dev = NULL; + struct sdis_estimator* estimator = NULL; + struct sdis_interface* interf_left = NULL; + struct sdis_interface* interf_right = NULL; + struct sdis_interface* interf_adiab = NULL; + struct sdis_interface* interfaces[4]; + struct sdis_medium* solid = NULL; + struct sdis_medium* fluid = NULL; + struct sdis_scene* scn = NULL; + struct sdis_mc mc = SDIS_MC_NULL; + struct sdis_scene_create_args scn_args = SDIS_SCENE_CREATE_ARGS_DEFAULT; + struct sdis_solve_probe_args probe_args = SDIS_SOLVE_PROBE_ARGS_DEFAULT; + struct sdis_solve_boundary_flux_args flux_args = + SDIS_SOLVE_BOUNDARY_FLUX_ARGS_DEFAULT; + struct sdis_solve_probe_boundary_flux_args probe_flux_args = + SDIS_SOLVE_PROBE_BOUNDARY_FLUX_ARGS_DEFAULT; + double Tref = 0; + size_t prim = 0; + (void)argc, (void)argv; + + OK(sdis_device_create(&SDIS_DEVICE_CREATE_ARGS_DEFAULT, &dev)); + + solid = create_solid(dev); + fluid = create_fluid(dev); + + interf_left = interface_create(dev, solid, fluid, H, PHI1); + interf_right = interface_create(dev, solid, fluid, 0, PHI2); + interf_adiab = interface_create(dev, solid, fluid, 0, SDIS_FLUX_NONE); + interfaces[0] = interf_adiab; /* Bottom */ + interfaces[1] = interf_left; + interfaces[2] = interf_adiab; /* Top */ + interfaces[3] = interf_right; + + scn_args.get_indices = square_get_indices; + scn_args.get_interface = square_get_interface; + scn_args.get_position = get_position; + scn_args.nprimitives = square_nsegments; + scn_args.nvertices = square_nvertices; + scn_args.context = interfaces; + OK(sdis_scene_2d_create(dev, &scn_args, &scn)); + + prim = 1; /* Left */ + flux_args.nrealisations = N; + flux_args.nprimitives = 1; + flux_args.primitives = &prim; + OK(sdis_solve_boundary_flux(scn, &flux_args, &estimator)); + OK(sdis_estimator_get_convective_flux(estimator, &mc)); + printf("Convective flux (left side) ~ %g W/m² +/- %g\n", mc.E, mc.SE); + OK(sdis_estimator_get_imposed_flux(estimator, &mc)); + printf("Imposed flux (left side) ~ %g W/m² +/- %g\n", mc.E, mc.SE); + OK(sdis_estimator_get_total_flux(estimator, &mc)); + printf("Total flux (left side) ~ %g W/m² +/- %g\n", mc.E, mc.SE); + CHK(eq_eps(-PHI2, mc.E, 3*mc.SE)); + OK(sdis_estimator_ref_put(estimator)); + + probe_flux_args.nrealisations = N; + probe_flux_args.iprim = 1; /* Left */ + probe_flux_args.uv[0] = 0.5; + OK(sdis_solve_probe_boundary_flux(scn, &probe_flux_args, &estimator)); + OK(sdis_estimator_get_convective_flux(estimator, &mc)); + printf("Convective flux (probe on left side) ~ %g W/m² +/- %g\n", mc.E, mc.SE); + OK(sdis_estimator_get_imposed_flux(estimator, &mc)); + printf("Imposed flux (probe on left side) ~ %g W/m² +/- %g\n", mc.E, mc.SE); + OK(sdis_estimator_get_total_flux(estimator, &mc)); + printf("Total flux (probe on left side) ~ %g W/m² +/- %g\n", mc.E, mc.SE); + CHK(eq_eps(-PHI2, mc.E, 3*mc.SE)); + OK(sdis_estimator_ref_put(estimator)); + + probe_args.nrealisations = N; + probe_args.position[0] = 0.2; + probe_args.position[1] = 0.25; + OK(sdis_solve_probe(scn, &probe_args, &estimator)); + OK(sdis_estimator_get_temperature(estimator, &mc)); + OK(sdis_estimator_ref_put(estimator)); + + Tref = PHI2/LAMBDA*probe_args.position[0] + (Text + (PHI1 + PHI2)/H); + printf("Temperature at %g = %g ~ %g +/- %g\n", + probe_args.position[0], Tref, mc.E, mc.SE); + CHK(eq_eps(mc.E, Tref, 3*mc.SE)); + + OK(sdis_device_ref_put(dev)); + OK(sdis_interface_ref_put(interf_left)); + OK(sdis_interface_ref_put(interf_right)); + OK(sdis_interface_ref_put(interf_adiab)); + OK(sdis_medium_ref_put(solid)); + OK(sdis_medium_ref_put(fluid)); + OK(sdis_scene_ref_put(scn)); + CHK(mem_allocated_size() == 0); + return 0; +} diff --git a/src/test_sdis_interface.c b/src/test_sdis_interface.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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_picard.c b/src/test_sdis_picard.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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_solid_random_walk_robustness.c b/src/test_sdis_solid_random_walk_robustness.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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_solve_boundary.c b/src/test_sdis_solve_boundary.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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_solve_boundary_flux.c b/src/test_sdis_solve_boundary_flux.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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 @@ -32,8 +32,8 @@ * with Hrad = 4 * BOLTZMANN_CONSTANT * Tref^3 * epsilon * T(-X) = Tb * - * CF = H * (T - Tf) - * RF = Hrad * (T - Trad) + * CF = H * (Tf - T) + * RF = Hrad * (Trad - T) * TF = CF + RF * * with Tf the temperature of the surrounding fluid, lambda the conductivity of @@ -373,8 +373,8 @@ main(int argc, char** argv) OK(sdis_interface_ref_put(interf_H)); analyticT = (H*Tf + Hrad*Trad + LAMBDA * Tb) / (H + Hrad + LAMBDA); - analyticCF = H * (analyticT - Tf); - analyticRF = Hrad * (analyticT - Trad); + analyticCF = H * (Tf - analyticT); + analyticRF = Hrad * (Trad - analyticT); analyticTF = analyticCF + analyticRF; #define SOLVE sdis_solve_probe_boundary_flux diff --git a/src/test_sdis_solve_camera.c b/src/test_sdis_solve_camera.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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 @@ -29,9 +29,9 @@ #include <string.h> #define UNKOWN_TEMPERATURE -1 -#define IMG_WIDTH 640 -#define IMG_HEIGHT 480 -#define SPP 4 /* #Samples per pixel, i.e. #realisations per pixel */ +#define IMG_WIDTH 157 +#define IMG_HEIGHT 53 +#define SPP 30 /* #Samples per pixel, i.e. #realisations per pixel */ /* * The scene is composed of a solid cube whose temperature is unknown. The @@ -741,7 +741,7 @@ main(int argc, char** argv) OK(sdis_solve_camera(scn, &solve_args, &buf2)); if(is_master_process) { OK(sdis_estimator_buffer_get_temperature(buf2, &T2)); - CHK(T.E != T2.E); + CHK(T.E != T2.E || (T2.SE == 0 && T.SE ==0)); CHK(T2.E + 3*T2.SE >= T.E - 3*T.SE && T2.E - 3*T2.SE <= T.E + 3*T.SE); OK(sdis_estimator_buffer_ref_put(buf2)); @@ -756,7 +756,7 @@ main(int argc, char** argv) OK(ssp_rng_ref_put(rng)); if(is_master_process) { OK(sdis_estimator_buffer_get_temperature(buf2, &T2)); - CHK(T.E != T2.E); + CHK(T.E != T2.E || (T2.SE == 0 && T.SE == 0)); CHK(T2.E + 3*T2.SE >= T.E - 3*T.SE && T2.E - 3*T2.SE <= T.E + 3*T.SE); OK(sdis_estimator_buffer_ref_put(buf2)); diff --git a/src/test_sdis_solve_medium.c b/src/test_sdis_solve_medium.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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 @@ -228,7 +228,7 @@ main(int argc, char** argv) struct sdis_solve_medium_args solve_args = SDIS_SOLVE_MEDIUM_ARGS_DEFAULT; struct ssp_rng* rng = NULL; struct context ctx; - double ref; + double ref = 0; double v, v0, v1; size_t nreals; size_t nfails; 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-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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_solve_probe.c b/src/test_sdis_solve_probe.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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,8 @@ #include <star/ssp.h> #include <rsys/math.h> +#include <string.h> + /* * The scene is composed of a solid cube with unknown temperature. The * surrounding fluid has a fixed constant temperature. @@ -280,6 +282,8 @@ main(int argc, char** argv) struct sdis_green_function* green = NULL; const struct sdis_heat_path* path = NULL; struct sdis_device_create_args dev_args = SDIS_DEVICE_CREATE_ARGS_DEFAULT; + struct sdis_green_function_create_from_stream_args green_args = + SDIS_GREEN_FUNCTION_CREATE_FROM_STREAM_ARGS_DEFAULT; struct sdis_scene_create_args scn_args = SDIS_SCENE_CREATE_ARGS_DEFAULT; struct sdis_fluid_shader fluid_shader = DUMMY_FLUID_SHADER; struct sdis_solid_shader solid_shader = DUMMY_SOLID_SHADER; @@ -498,7 +502,7 @@ main(int argc, char** argv) OK(sdis_green_function_solve(green, &estimator2)); check_green_function(green); check_estimator_eq(estimator, estimator2); - + stream = tmpfile(); CHK(stream); BA(sdis_green_function_write(NULL, stream)); @@ -512,22 +516,46 @@ main(int argc, char** argv) OK(sdis_green_function_ref_put(green)); rewind(stream); - BA(sdis_green_function_create_from_stream(NULL, stream, &green)); - BA(sdis_green_function_create_from_stream(scn, NULL, &green)); - BA(sdis_green_function_create_from_stream(scn, stream, NULL)); - OK(sdis_green_function_create_from_stream(scn, stream, &green)); + green_args.scene = NULL; + green_args.stream = stream; + BA(sdis_green_function_create_from_stream(&green_args, &green)); + green_args.scene = scn; + green_args.stream = NULL; + BA(sdis_green_function_create_from_stream(&green_args, &green)); + green_args.scene = scn; + green_args.stream = stream; + BA(sdis_green_function_create_from_stream(&green_args, NULL)); + OK(sdis_green_function_create_from_stream(&green_args, &green)); CHK(!fclose(stream)); OK(sdis_green_function_solve(green, &estimator3)); - check_green_function(green); check_estimator_eq_strict(estimator2, estimator3); + OK(sdis_green_function_ref_put(green)); + OK(sdis_estimator_ref_put(estimator3)); + CHK(stream = tmpfile()); + hash_sha256("Hello, world!", strlen("Hello, world!"), solve_args.signature); + OK(sdis_solve_probe_green_function(scn, &solve_args, &green)); + OK(sdis_green_function_write(green, stream)); OK(sdis_green_function_ref_put(green)); + green_args.scene = scn; + green_args.stream = stream; + rewind(stream); + BA(sdis_green_function_create_from_stream(&green_args, &green)); + memcpy(green_args.signature, solve_args.signature, sizeof(hash256_T)); + rewind(stream); + OK(sdis_green_function_create_from_stream(&green_args, &green)); + CHK(!fclose(stream)); + + OK(sdis_green_function_solve(green, &estimator3)); + check_estimator_eq_strict(estimator2, estimator3); + OK(sdis_green_function_ref_put(green)); + OK(sdis_estimator_ref_put(estimator3)); + OK(sdis_estimator_ref_put(estimator)); OK(sdis_estimator_ref_put(estimator2)); - OK(sdis_estimator_ref_put(estimator3)); OK(sdis_solve_probe(scn, &solve_args, &estimator)); BA(sdis_estimator_get_paths_count(NULL, &n)); diff --git a/src/test_sdis_solve_probe2.c b/src/test_sdis_solve_probe2.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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_solve_probe2_2d.c b/src/test_sdis_solve_probe2_2d.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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_solve_probe3.c b/src/test_sdis_solve_probe3.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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_solve_probe3_2d.c b/src/test_sdis_solve_probe3_2d.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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_solve_probe_2d.c b/src/test_sdis_solve_probe_2d.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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_unstationary_atm.c b/src/test_sdis_unstationary_atm.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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_utils.c b/src/test_sdis_utils.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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 @@ -455,6 +455,8 @@ check_green_serialization (struct sdis_green_function* green, struct sdis_scene* scn) { + struct sdis_green_function_create_from_stream_args args = + SDIS_GREEN_FUNCTION_CREATE_FROM_STREAM_ARGS_DEFAULT; FILE* stream = NULL; struct sdis_estimator *e1 = NULL; struct sdis_estimator *e2 = NULL; @@ -467,7 +469,9 @@ check_green_serialization OK(sdis_green_function_write(green, stream)); rewind(stream); - OK(sdis_green_function_create_from_stream(scn, stream, &green2)); + args.scene = scn; + args.stream = stream; + OK(sdis_green_function_create_from_stream(&args, &green2)); CHK(!fclose(stream)); check_green_function(green2); diff --git a/src/test_sdis_utils.h b/src/test_sdis_utils.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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 @@ -285,6 +285,7 @@ dump_mesh (unsigned long)(ids[i*3+1] + 1), (unsigned long)(ids[i*3+2] + 1)); } + fflush(stream); } static INLINE void @@ -306,6 +307,7 @@ dump_segments (unsigned long)(ids[i*2+0] + 1), (unsigned long)(ids[i*2+1] + 1)); } + fflush(stream); } static INLINE void diff --git a/src/test_sdis_volumic_power.c b/src/test_sdis_volumic_power.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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 @@ -51,7 +51,7 @@ #define T0 320 #define LAMBDA 0.1 #define P0 10 -#define DELTA 1.0/50.0 +#define DELTA 1.0/55.0 /******************************************************************************* * Media @@ -373,6 +373,41 @@ solve } } +static void +check_null_power_term_with_green(struct sdis_scene* scn, struct solid* solid) +{ + struct sdis_solve_probe_args solve_args = SDIS_SOLVE_PROBE_ARGS_DEFAULT; + struct sdis_mc T = SDIS_MC_NULL; + struct sdis_estimator* estimator = NULL; + struct sdis_green_function* green = NULL; + double x = 0; + double ref = 0; + ASSERT(scn && solid); + + solve_args.position[0] = 0.5; + solve_args.position[1] = 0.5; + solve_args.position[2] = 0; + solve_args.nrealisations = N; + solve_args.time_range[0] = + solve_args.time_range[1] = INF; + + solid->vpower = 0; + OK(sdis_solve_probe_green_function(scn, &solve_args, &green)); + + solid->vpower = P0; + OK(sdis_green_function_solve(green, &estimator)); + OK(sdis_estimator_get_temperature(estimator, &T)); + + x = solve_args.position[0] - 0.5; + ref = solid->vpower / (2*LAMBDA) * (1.0/4.0 - x *x) + T0; + printf("Green steady temperature at (%g, %g, %g) with Power=%g = %g ~ %g +/- %g\n", + SPLIT3(solve_args.position), solid->vpower, ref, T.E, T.SE); + CHK(eq_eps(ref, T.E, 3*T.SE)); + + OK(sdis_estimator_ref_put(estimator)); + OK(sdis_green_function_ref_put(green)); +} + /******************************************************************************* * Test ******************************************************************************/ @@ -485,12 +520,15 @@ main(int argc, char** argv) OK(sdis_interface_ref_put(interf_T0)); /* Solve */ - OK(ssp_rng_create(NULL, SSP_RNG_KISS, &rng)); + OK(ssp_rng_create(NULL, SSP_RNG_MT19937_64, &rng)); printf(">> Box scene\n"); solve(box_scn, rng, solid_props); printf(">> Square scene\n"); solve(square_scn, rng, solid_props); + /* Check green registration with a null power term */ + check_null_power_term_with_green(box_scn, solid_props); + OK(sdis_scene_ref_put(box_scn)); OK(sdis_scene_ref_put(square_scn)); OK(sdis_device_ref_put(dev)); diff --git a/src/test_sdis_volumic_power2.c b/src/test_sdis_volumic_power2.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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_power2_2d.c b/src/test_sdis_volumic_power2_2d.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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_power3_2d.c b/src/test_sdis_volumic_power3_2d.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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_power4.c b/src/test_sdis_volumic_power4.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2022 |Meso|Star> (contact@meso-star.com) +/* Copyright (C) 2016-2023 |Méso|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