stardis

Perform coupled heat transfer calculations
git clone git://git.meso-star.fr/stardis.git
Log | Files | Refs | README | LICENSE

commit 230d8262d64c31a49afee89fc56014fc0dfdaa4e
parent 11aa198e4afa1f0a152b4ff21b467f45123dd72e
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Thu, 24 Sep 2020 12:00:28 +0200

Allow computations over a time range

Diffstat:
Mcmake/CMakeLists.txt | 4++--
Mdoc/stardis.1.txt.in | 83+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
Msrc/stardis-app.c | 10+++++-----
Msrc/stardis-app.h | 8+++++---
Msrc/stardis-compute.c | 14+++++++-------
Msrc/stardis-output.c | 112++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------
Msrc/stardis-parsing.c | 143++++++++++++++++++++++++++++++++++++++-----------------------------------------
Msrc/stardis-parsing.h | 4++--
8 files changed, 219 insertions(+), 159 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -36,14 +36,14 @@ set_property(CACHE STARDIS_DOC PROPERTY STRINGS # Generate files ############################################################################### set(STARDIS_ARGS_DEFAULT_AMBIENT_TEMP "300") -set(STARDIS_ARGS_DEFAULT_COMPUTE_TIME "INF") +set(STARDIS_ARGS_DEFAULT_COMPUTE_TIME "INF, INF") set(STARDIS_ARGS_DEFAULT_RENDERING_FOV "70") # degrees set(STARDIS_ARGS_DEFAULT_RENDERING_IMG_HEIGHT "480") set(STARDIS_ARGS_DEFAULT_RENDERING_IMG_WIDTH "640") set(STARDIS_ARGS_DEFAULT_RENDERING_POS "1, 1, 1") set(STARDIS_ARGS_DEFAULT_RENDERING_SPP "4") set(STARDIS_ARGS_DEFAULT_RENDERING_TGT "0, 0, 0") -set(STARDIS_ARGS_DEFAULT_RENDERING_TIME "INF") +set(STARDIS_ARGS_DEFAULT_RENDERING_TIME "INF, INF") set(STARDIS_ARGS_DEFAULT_RENDERING_UP "0, 0, 1") set(STARDIS_ARGS_DEFAULT_REFERENCE_TEMP "300") set(STARDIS_ARGS_DEFAULT_SAMPLES_COUNT "10000") diff --git a/doc/stardis.1.txt.in b/doc/stardis.1.txt.in @@ -39,9 +39,11 @@ relative to the characteristic time of the system. The provided system description should comply with the *stardis-input*(5) format. *stardis* can compute a thermal observable, like temperature or flux, at a -probe point and date or the mean value of an observable over a given surface -or volume, and time period. In addition, *stardis* gives access to the -evaluation of the propagator (a.k.a the *Green function*). +probe point and date or the mean value of an observable over a given surface, +volume, or time range. When a time range *t1, t2* is provided, the computed +value is the mean value over the time range. To compute the value at a given +time, simply provide a single value *t*. In addition, *stardis* gives access to +the evaluation of the propagator (a.k.a the *Green function*). The propagator is of great value for thermicist engineers as it gives some crucial information to analyse heat transfers in the system. It helps engineers @@ -89,43 +91,45 @@ MANDATORY OPTIONS EXCLUSIVE OPTIONS ----------------- -*-p* _x,y,z[,time]_:: - Compute the temperature at the given probe at a given time. By default - compute time is @STARDIS_ARGS_DEFAULT_COMPUTE_TIME@. The probe must be in a - medium. The probe coordinates must be in the same system as the geometry. +*-p* _x,y,z[,time-range]_:: + Compute the temperature at the given probe at a given time. By default the + compute time range is @STARDIS_ARGS_DEFAULT_COMPUTE_TIME@. The probe must + be in a medium. The probe coordinates must be in the same system as the + geometry. -*-P* _x,y,z[,time]_:: +*-P* _x,y,z[,time-range]_:: Compute the temperature at the given probe on an interface at a given time. - By default compute time is @STARDIS_ARGS_DEFAULT_COMPUTE_TIME@. The probe is - supposed to be on an interface and is moved to the closest point of the - closest interface before the computation start. The probe coordinates must - be in the same system as the geometry. + By default the compute time range is @STARDIS_ARGS_DEFAULT_COMPUTE_TIME@. The + probe is supposed to be on an interface and is moved to the closest point of + the closest interface before the computation start. The probe coordinates + must be in the same system as the geometry. -*-m* _medium_name[,time]_:: +*-m* _medium_name[,time-range]_:: Compute the mean temperature in a given medium at a given time. The medium - name must be part of the system description. By default compute time is - @STARDIS_ARGS_DEFAULT_COMPUTE_TIME@. The medium does not need to be connex. - -*-s* _file[,time]_:: - Compute the mean temperature on a given 2D region at a given time, the - region being defined as the front sides of the triangles in the provided - *STL* file. By default compute time is @STARDIS_ARGS_DEFAULT_COMPUTE_TIME@. + name must be part of the system description. By default the compute time + range is @STARDIS_ARGS_DEFAULT_COMPUTE_TIME@. The medium does not need to be + connex. + +*-s* _file[,time-range]_:: + Compute the mean temperature on a given 2D region at a given time, the region + being defined as the front sides of the triangles in the provided *STL* file. + By default the compute time range is @STARDIS_ARGS_DEFAULT_COMPUTE_TIME@. These triangles are not added to the geometry, but must be part of it. The region does not need to be connex. -*-S* _file[,time]_:: +*-S* _file[,time-range]_:: Compute the by-triangle mean temperature on a given 2D region at a given time, the region being defined as the front sides of the triangles in the provided *VTK* file. These triangles are not added to the geometry, but must - be part of it. By default compute time is + be part of it. By default the compute time range is @STARDIS_ARGS_DEFAULT_COMPUTE_TIME@. The region does not need to be connex. -*-F* _file[,time]_:: +*-F* _file[,time-range]_:: Compute the mean flux on a given 2D region at a given time, the region being defined as the front sides of the triangles in the provided *VTK* file. These triangles are not added to the geometry, but must be part of it. Flux is accounted positive when going from the front side to the back side, at a - single-triangle level. By default compute time is + single-triangle level. By default the compute time range is @STARDIS_ARGS_DEFAULT_COMPUTE_TIME@.The region does not need to be connex. *-R* [__sub-option__:...]:: @@ -153,8 +157,9 @@ EXCLUSIVE OPTIONS Number of samples per pixel. By default, use @STARDIS_ARGS_DEFAULT_RENDERING_SPP@ samples per pixel. - **t=**_time_;; - Rendering time. By default _time_ is @STARDIS_ARGS_DEFAULT_RENDERING_TIME@. + **t=**_time-range_;; + Rendering time range. By default _time-range_ is + @STARDIS_ARGS_DEFAULT_RENDERING_TIME@. **tgt=**_x_**,**_y_**,**_z_;; Position targeted by the camera. By default, it is set to @@ -205,14 +210,14 @@ options -g or -G. + This option can only be used in conjunction with one these options: -p, -P, -m, -s and cannot be used in conjunction with option -D. Any compute time -provided through one of these options is silently ignored. +range provided through one of these options is silently ignored. *-G* _file_name_:: Compute the Green function at steady state and write it to an binary file. + This option can only be used in conjunction with one these options: -p, -P, -m, -s and cannot be used in conjunction with option -D. Any compute time -provided through one of these options is silently ignored. +range provided through one of these options is silently ignored. + The resulting file can be further used through the *sgreen*(1) command to apply different temperature, flux or volumic power values. @@ -250,16 +255,26 @@ in the file *scene.vtk*. Verbosity level is set to *3*: $ stardis -M "scene 5.txt" -F edge.stl -d -V 3 > scene.vtk Compute the temperature at the probe point *0, 0.5, 0* at steady state. The -system is read from the 2 files *media.txt* and *bounds.txt* and the number of -samples is set to *1000000*: +system is read from the file *model.txt* and the number of samples is set to +*1000000*: - $ stardis -M media.txt -M bounds.txt -p 0,0.5,0 -n 1000000 + $ stardis -M model.txt -p 0,0.5,0 -n 1000000 Compute the mean temperature in the medium *med05* at *t=100* s. The system is -read from the 2 files *media.txt* and *bounds.txt* and the result is output -with extended format: +read from the file *model.txt* and the result is output with extended format: + + $ stardis -M model.txt -m med05,100 -e + +Compute the temperature at the probe point *0, 0, 0* at *t=2500*. The system is +read from the 2 files *media.txt* and *bounds.txt* and the number of samples is +set to *1000000*: + + $ stardis -M media.txt -M bounds.txt -p 0,0,0,2500 -n 1000000 + +Compute the mean temperature at the probe point *1, 2.5, 0* over the *50, 5000* +time range. The system is read from the file *model.txt*: - $ stardis -M media.txt -M bounds.txt -m med05,100 -e + $ stardis -M model.txt -p 1,2.5,0,50,5000 Render the system as described in *scene.txt* with default settings: diff --git a/src/stardis-app.c b/src/stardis-app.c @@ -27,6 +27,8 @@ #include <rsys/str.h> #include <rsys/text_reader.h> #include <rsys/logger.h> +#include <rsys/double2.h> +#include <rsys/double3.h> #include <string.h> @@ -207,10 +209,8 @@ stardis_init stardis->allocator = allocator; htable_intface_init(stardis->allocator, &htable_interfaces); darray_descriptions_init(stardis->allocator, &stardis->descriptions); - stardis->probe[0] = args->probe[0]; - stardis->probe[1] = args->probe[1]; - stardis->probe[2] = args->probe[2]; - stardis->probe[3] = args->probe[3]; + d3_set(stardis->probe, args->pos_and_time); + d2_set(stardis->time_range, args->pos_and_time + 3); stardis->dev = NULL; stardis->sdis_scn = NULL; stardis->senc3d_scn = NULL; @@ -250,7 +250,7 @@ stardis_init &stardis->geometry)); if(args->mode & MODE_IR_COMPUTE) { - ERR(parse_camera(stardis->logger, args->camera, &stardis->camera)); + ERR(parse_camera(stardis->logger, args->camera, stardis)); } else if(args->mode & MODE_MEDIUM_COMPUTE) { ERR(str_set(&stardis->solve_name, args->medium_name)); diff --git a/src/stardis-app.h b/src/stardis-app.h @@ -26,6 +26,7 @@ #include <rsys/rsys.h> #include <rsys/float3.h> +#include <rsys/double2.h> #include <rsys/double3.h> #include <rsys/dynamic_array_size_t.h> #include <rsys/dynamic_array.h> @@ -615,7 +616,7 @@ struct camera { double tgt[3]; double up[3]; double fov; - double time; + double time_range[2]; unsigned spp; unsigned img_width, img_height; int auto_look_at; @@ -630,7 +631,7 @@ init_camera(struct camera* cam) { cam->spp = STARDIS_DEFAULT_RENDERING_SPP; cam->img_width = STARDIS_DEFAULT_RENDERING_IMG_WIDTH; cam->img_height = STARDIS_DEFAULT_RENDERING_IMG_HEIGHT; - cam->time = STARDIS_DEFAULT_RENDERING_TIME; + d2(cam->time_range, STARDIS_DEFAULT_RENDERING_TIME); cam->auto_look_at = 1; } @@ -704,7 +705,8 @@ struct stardis { struct senc3d_scene* senc3d_scn; struct counts counts; - double probe[4]; /* x,y,z,t of probe when mode is PROBE_COMPUTE */ + double probe[3]; /* x,y,z of probe when mode is PROBE_COMPUTE */ + double time_range[2]; /* compute time */ struct camera camera; /* camera when mode is IR_COMPUTE */ struct str solve_name; /* medium name when mode is MEDIUM_COMPUTE, boundary file name when [FLUX_]BOUNDARY_COMPUTE diff --git a/src/stardis-compute.c b/src/stardis-compute.c @@ -404,7 +404,7 @@ compute_probe(struct stardis* stardis) ERR(dump_green_ascii(green, stardis, stdout)); } } else { - d2_splat(args.time_range, stardis->probe[3]); + d2_set(args.time_range, stardis->time_range); args.register_paths = stardis->dump_paths; ERR(sdis_solve_probe(stardis->sdis_scn, &args, &estimator)); ERR(print_single_MC_result(estimator, stardis, stdout)); @@ -466,7 +466,7 @@ compute_probe_on_interface(struct stardis* stardis) ERR(dump_green_ascii(green, stardis, stdout)); } } else { - d2_splat(args.time_range, stardis->probe[3]); + d2_set(args.time_range, stardis->time_range); args.register_paths = stardis->dump_paths; ERR(sdis_solve_probe_boundary(stardis->sdis_scn, &args, &estimator)); ERR(print_single_MC_result(estimator, stardis, stdout)); @@ -600,7 +600,7 @@ compute_camera(struct stardis* stardis) stardis->camera.up)); args.cam = cam; - d2_splat(args.time_range, stardis->camera.time); + d2_set(args.time_range, stardis->camera.time_range); args.fp_to_meter = stardis->scale_factor; args.ambient_radiative_temperature = stardis->ambient_temp; args.reference_temperature = stardis->ref_temp; @@ -681,7 +681,7 @@ compute_medium(struct stardis* stardis) ERR(dump_green_ascii(green, stardis, stdout)); } } else { - d2_splat(args.time_range, stardis->probe[3]); + d2_set(args.time_range, stardis->time_range); args.register_paths = stardis->dump_paths; ERR(sdis_solve_medium(stardis->sdis_scn, &args, &estimator)); ERR(print_single_MC_result(estimator, stardis, stdout)); @@ -787,7 +787,7 @@ compute_boundary(struct stardis* stardis) ERR(dump_green_ascii(green, stardis, stdout)); } } else { - d2_splat(args.time_range, stardis->probe[3]); + d2_set(args.time_range, stardis->time_range); args.register_paths = stardis->dump_paths; ERR(sdis_solve_boundary(stardis->sdis_scn, &args, &estimator)); ERR(print_single_MC_result(estimator, stardis, stdout)); @@ -823,7 +823,7 @@ compute_flux_boundary(struct stardis* stardis) = darray_size_t_cdata_get(&stardis->compute_surface.primitives); args.nprimitives = darray_size_t_size_get(&stardis->compute_surface.primitives); - d2_splat(args.time_range, stardis->probe[3]); + d2_set(args.time_range, stardis->time_range); args.fp_to_meter = stardis->scale_factor; args.ambient_radiative_temperature = stardis->ambient_temp; args.reference_temperature = stardis->ref_temp; @@ -873,7 +873,7 @@ compute_map(struct stardis* stardis) args.sides = darray_sides_cdata_get(&stardis->compute_surface.sides); args.nprimitives = darray_size_t_size_get(&stardis->compute_surface.primitives); - d2_splat(args.time_range, stardis->probe[3]); + d2_set(args.time_range, stardis->time_range); args.fp_to_meter = stardis->scale_factor; args.ambient_radiative_temperature = stardis->ambient_temp; args.reference_temperature = stardis->ref_temp; diff --git a/src/stardis-output.c b/src/stardis-output.c @@ -1132,40 +1132,64 @@ print_single_MC_result switch (stardis->mode & COMPUTE_MODES) { case MODE_PROBE_COMPUTE: if(stardis->mode & MODE_EXTENDED_RESULTS) { - fprintf(stream, "Temperature at [%g, %g, %g] at t=%g = %g +/- %g\n", - SPLIT4(stardis->probe), - result.E, /* Expected value */ - result.SE); /* Standard error */ + if(stardis->time_range[0] == stardis->time_range[1]) + fprintf(stream, "Temperature at [%g, %g, %g] at t=%g = %g +/- %g\n", + SPLIT3(stardis->probe), stardis->time_range[0], + result.E, /* Expected value */ + result.SE); /* Standard error */ + else + fprintf(stream, "Temperature at [%g, %g, %g] with t in [%g %g] = %g +/- %g\n", + SPLIT3(stardis->probe), SPLIT2(stardis->time_range), + result.E, /* Expected value */ + result.SE); /* Standard error */ } else fprintf(stream, "%g %g %zu %zu\n", result.E, result.SE, nfailures, stardis->samples); break; case MODE_PROBE_COMPUTE_ON_INTERFACE: if(stardis->mode & MODE_EXTENDED_RESULTS) { - fprintf(stream, "Boundary temperature at [%g, %g, %g] at t=%g = %g +/- %g\n", - SPLIT4(stardis->probe), - result.E, /* Expected value */ - result.SE); /* Standard error */ + if(stardis->time_range[0] == stardis->time_range[1]) + fprintf(stream, "Boundary temperature at [%g, %g, %g] at t=%g = %g +/- %g\n", + SPLIT3(stardis->probe), stardis->time_range[0], + result.E, /* Expected value */ + result.SE); /* Standard error */ + else + fprintf(stream, "Boundary temperature at [%g, %g, %g] with t in [%g %g] = %g +/- %g\n", + SPLIT3(stardis->probe), SPLIT2(stardis->time_range), + result.E, /* Expected value */ + result.SE); /* Standard error */ } else fprintf(stream, "%g %g %zu %zu\n", result.E, result.SE, nfailures, stardis->samples); break; case MODE_MEDIUM_COMPUTE: if(stardis->mode & MODE_EXTENDED_RESULTS) { - fprintf(stream, "Temperature in medium '%s' at t=%g = %g +/- %g\n", - str_cget(&stardis->solve_name), stardis->probe[3], - result.E, /* Expected value */ - result.SE); /* Standard error */ + if(stardis->time_range[0] == stardis->time_range[1]) + fprintf(stream, "Temperature in medium '%s' at t=%g = %g +/- %g\n", + str_cget(&stardis->solve_name), stardis->time_range[0], + result.E, /* Expected value */ + result.SE); /* Standard error */ + else + fprintf(stream, "Temperature in medium '%s' with t in [%g %g] = %g +/- %g\n", + str_cget(&stardis->solve_name), SPLIT2(stardis->time_range), + result.E, /* Expected value */ + result.SE); /* Standard error */ } else fprintf(stream, "%g %g %zu %zu\n", result.E, result.SE, nfailures, stardis->samples); break; case MODE_BOUNDARY_COMPUTE: if(stardis->mode & MODE_EXTENDED_RESULTS) { - fprintf(stream, "Temperature at boundary %s at t=%g = %g +/- %g\n", - str_cget(&stardis->solve_name), stardis->probe[3], - result.E, /* Expected value */ - result.SE); /* Standard error */ + if(stardis->time_range[0] == stardis->time_range[1]) + fprintf(stream, "Temperature at boundary %s at t=%g = %g +/- %g\n", + str_cget(&stardis->solve_name), stardis->time_range[0], + result.E, /* Expected value */ + result.SE); /* Standard error */ + else + fprintf(stream, "Temperature at boundary %s with t in [%g %g] = %g +/- %g\n", + str_cget(&stardis->solve_name), SPLIT2(stardis->time_range), + result.E, /* Expected value */ + result.SE); /* Standard error */ } else fprintf(stream, "%g %g %zu %zu\n", result.E, result.SE, nfailures, stardis->samples); @@ -1176,25 +1200,49 @@ print_single_MC_result ASSERT(type == SDIS_ESTIMATOR_FLUX); if(stardis->mode & MODE_EXTENDED_RESULTS) { - fprintf(stream, "Temperature at boundary %s at t=%g = %g +/- %g\n", - str_cget(&stardis->solve_name), stardis->probe[3], - result.E, /* Expected value */ - result.SE); /* Standard error */ + if(stardis->time_range[0] == stardis->time_range[1]) + fprintf(stream, "Temperature at boundary %s at t=%g = %g +/- %g\n", + str_cget(&stardis->solve_name), stardis->time_range[0], + result.E, /* Expected value */ + result.SE); /* Standard error */ + else + fprintf(stream, "Temperature at boundary %s with t in [%g %g] = %g +/- %g\n", + str_cget(&stardis->solve_name), SPLIT2(stardis->time_range), + result.E, /* Expected value */ + result.SE); /* Standard error */ ERR(sdis_estimator_get_convective_flux(estimator, &result)); - fprintf(stream, "Convective flux at boundary %s at t=%g = %g +/- %g\n", - str_cget(&stardis->solve_name), stardis->probe[3], - result.E, /* Expected value */ - result.SE); /* Standard error */ + if(stardis->time_range[0] == stardis->time_range[1]) + fprintf(stream, "Convective flux at boundary %s at t=%g = %g +/- %g\n", + str_cget(&stardis->solve_name), stardis->time_range[0], + result.E, /* Expected value */ + result.SE); /* Standard error */ + else + fprintf(stream, "Convective flux at boundary %s with t in [%g %g] = %g +/- %g\n", + str_cget(&stardis->solve_name), SPLIT2(stardis->time_range), + result.E, /* Expected value */ + result.SE); /* Standard error */ ERR(sdis_estimator_get_radiative_flux(estimator, &result)); - fprintf(stream, "Radiative flux at boundary %s at t=%g = %g +/- %g\n", - str_cget(&stardis->solve_name), stardis->probe[3], - result.E, /* Expected value */ - result.SE); /* Standard error */ + if(stardis->time_range[0] == stardis->time_range[1]) + fprintf(stream, "Radiative flux at boundary %s at t=%g = %g +/- %g\n", + str_cget(&stardis->solve_name), stardis->time_range[0], + result.E, /* Expected value */ + result.SE); /* Standard error */ + else + fprintf(stream, "Radiative flux at boundary %s with t in [%g %g] = %g +/- %g\n", + str_cget(&stardis->solve_name), SPLIT2(stardis->time_range), + result.E, /* Expected value */ + result.SE); /* Standard error */ ERR(sdis_estimator_get_total_flux(estimator, &result)); - fprintf(stream, "Total flux Flux at boundary %s at t=%g = %g +/- %g\n", - str_cget(&stardis->solve_name), stardis->probe[3], - result.E, /* Expected value */ - result.SE); /* Standard error */ + if(stardis->time_range[0] == stardis->time_range[1]) + fprintf(stream, "Total flux Flux at boundary %s at t=%g = %g +/- %g\n", + str_cget(&stardis->solve_name), stardis->time_range[0], + result.E, /* Expected value */ + result.SE); /* Standard error */ + else + fprintf(stream, "Total flux Flux at boundary %s with t in [%g %g] = %g +/- %g\n", + str_cget(&stardis->solve_name), SPLIT2(stardis->time_range), + result.E, /* Expected value */ + result.SE); /* Standard error */ } else { fprintf(stream, "%g %g ", result.E, result.SE); ERR(sdis_estimator_get_convective_flux(estimator, &result)); diff --git a/src/stardis-parsing.c b/src/stardis-parsing.c @@ -20,6 +20,7 @@ #include "stardis-version.h" #include <rsys/cstr.h> +#include <rsys/double2.h> #include <rsys/double3.h> #include <sdis_version.h> #include <rsys/logger.h> @@ -343,7 +344,7 @@ init_args /* Set default values */ args->samples = STARDIS_DEFAULT_SAMPLES_COUNT; args->nthreads = SDIS_NTHREADS_DEFAULT; - args->probe[3] = STARDIS_DEFAULT_COMPUTE_TIME; + d2(args->pos_and_time+3, STARDIS_DEFAULT_COMPUTE_TIME); args->ambient_temp = STARDIS_DEFAULT_AMBIENT_TEMP; args->ref_temp = STARDIS_DEFAULT_REFERENCE_TEMP; args->verbose = STARDIS_DEFAULT_VERBOSE_LEVEL; @@ -438,37 +439,37 @@ short_help name); print_version(stream); - fprintf(stream, "\nMandatory arguments\n"); + fprintf(stream, "\nMandatory options\n"); fprintf(stream, "-------------------\n"); fprintf(stream, "\n -M <FILE>\n"); fprintf(stream, " Read a text file that contains (partial) description of the model.\n"); - fprintf(stream, "\nExclusive arguments\n"); + fprintf(stream, "\nExclusive options\n"); fprintf(stream, "-------------------\n"); - fprintf(stream, "\n -F STL_FILE[,TIME]\n"); + fprintf(stream, "\n -F STL_FILE[,TIME-RANGE]\n"); fprintf(stream, " Compute the mean flux on a given 2D region at a given time.\n"); - fprintf(stream, "\n -m MEDIUM_NAME[,TIME]\n"); + fprintf(stream, "\n -m MEDIUM_NAME[,TIME-RANGE]\n"); fprintf(stream, " Compute the mean temperature in a given medium at a given time.\n"); - fprintf(stream, "\n -p X,Y,Z[,TIME]\n"); + fprintf(stream, "\n -p X,Y,Z[,TIME-RANGE]\n"); fprintf(stream, " Compute the temperature at the given probe.\n"); - fprintf(stream, "\n -P X,Y,Z[,TIME]\n"); + fprintf(stream, "\n -P X,Y,Z[,TIME-RANGE]\n"); fprintf(stream, " Compute the temperature at the given probe on an interface.\n"); fprintf(stream, "\n -R [RENDERING_OPTIONS]\n"); fprintf(stream, " Compute an infra-red image of the model.\n"); - fprintf(stream, "\n -s STL_FILE[,TIME]\n"); + fprintf(stream, "\n -s STL_FILE[,TIME-RANGE]\n"); fprintf(stream, " Compute the mean temperature on a given 2D region.\n"); - fprintf(stream, "\n -S STL_FILE[,TIME]\n"); + fprintf(stream, "\n -S STL_FILE[,TIME-RANGE]\n"); fprintf(stream, " Compute the by-triangle mean temperature on a given 2D region.\n"); - fprintf(stream, "\nOptionnal arguments\n"); + fprintf(stream, "\nOther options\n"); fprintf(stream, "-------------------\n"); fprintf(stream, "\n -a AMBIENT_TEMP\n"); @@ -511,6 +512,39 @@ short_help fprintf(stream, " Set the verbosity level.\n"); } +/* Get a time range from a coma-separated list of doubles + * The first Rank values are mandatory, followed by an optional time range + * that can be a single time */ +#define GET_OPTIONAL_TIME_RANGE(Src, Rank, Dst, Logger, OptionString, Option) \ + res = cstr_to_list_double((Src), ',', (Dst), &len, (Rank)+2); \ + if(res != RES_OK \ + || (len < (Rank)) \ + || (len == (Rank)+1 && (Dst)[(Rank)] < 0) \ + || (len == (Rank)+2 && ((Dst)[0] < 0 || (Dst)[(Rank)] > (Dst)[(Rank)+1])) \ + || len > (Rank)+2) \ + { \ + if(res == RES_OK) res = RES_BAD_ARG; \ + logger_print((Logger), LOG_ERROR, \ + "Invalid argument for option "OptionString": %s\n", \ + (Option), (Src)); \ + goto error; \ + } else { \ + if(len == (Rank)+1) (Dst)[(Rank)+1] = (Dst)[(Rank)];\ + } + + /* Get a string followed by an optional time range */ +#define GET_STR_AND_OPTIONAL_TIME_RANGE(Str, Time) \ + ptr = strchr(optarg, ','); /* First ',' */ \ + if(ptr) { /* Time range provided */ \ + GET_OPTIONAL_TIME_RANGE(ptr+1, 0, (Time), args->logger, "-%c", opt); \ + *ptr = '\0'; \ + } \ + (Str) = optarg; + +/* Get a position followed by an optional time range */ +#define GET_POS_AND_OPTIONAL_TIME_RANGE(Dst) \ + GET_OPTIONAL_TIME_RANGE(optarg, 3, (Dst), args->logger, "-%c", opt); + res_T parse_args (const int argc, @@ -648,23 +682,7 @@ parse_args goto error; } args->mode |= MODE_MEDIUM_COMPUTE; - ptr = strrchr(optarg, ','); - if(ptr) { - if(ptr != strchr(optarg, ',')) - res = RES_BAD_ARG; /* Single ',' allowed */ - else { - res = cstr_to_double(ptr + 1, args->probe + 3); - if(res == RES_OK && args->probe[3] < 0) res = RES_BAD_ARG; - } - *ptr = '\0'; - } - if(res != RES_OK) { - logger_print(args->logger, LOG_ERROR, - "Invalid argument for option -%c: %s\n", - opt, optarg); - goto error; - } - args->medium_name = optarg; + GET_STR_AND_OPTIONAL_TIME_RANGE(args->medium_name, args->pos_and_time + 3); break; } @@ -702,18 +720,7 @@ parse_args goto error; } args->mode |= MODE_PROBE_COMPUTE; - res = cstr_to_list_double(optarg, ',', args->probe, &len, 4); - if(res != RES_OK - || len < 3 - || (len == 4 && args->probe[3] < 0) - || len > 4) - { - if(res == RES_OK) res = RES_BAD_ARG; - logger_print(args->logger, LOG_ERROR, - "Invalid argument for option -%c: %s\n", - opt, optarg); - goto error; - } + GET_POS_AND_OPTIONAL_TIME_RANGE(args->pos_and_time); break; case 'P': @@ -725,18 +732,7 @@ parse_args goto error; } args->mode |= MODE_PROBE_COMPUTE_ON_INTERFACE; - res = cstr_to_list_double(optarg, ',', args->probe, &len, 4); - if(res != RES_OK - || len < 3 - || (len == 4 && args->probe[3] < 0) - || len > 4) - { - if(res == RES_OK) res = RES_BAD_ARG; - logger_print(args->logger, LOG_ERROR, - "Invalid argument for option -%c: %s\n", - opt, optarg); - goto error; - } + GET_POS_AND_OPTIONAL_TIME_RANGE(args->pos_and_time); break; case 'r': @@ -786,24 +782,7 @@ parse_args args->mode |= MODE_FLUX_BOUNDARY_COMPUTE; break; } - ptr = strrchr(optarg, ','); - if(ptr) { - if(ptr != strchr(optarg, ',')) - res = RES_BAD_ARG; /* Single ',' allowed */ - else { - res = cstr_to_double(ptr + 1, args->probe + 3); - if(res == RES_OK && args->probe[3] < 0) - res = RES_BAD_ARG; - } - *ptr = '\0'; - } - args->solve_filename = optarg; - if(res != RES_OK) { - logger_print(args->logger, LOG_ERROR, - "Invalid argument for option -%c: %s\n", - opt, optarg); - goto error; - } + GET_STR_AND_OPTIONAL_TIME_RANGE(args->solve_filename, args->pos_and_time + 3); break; } @@ -944,25 +923,36 @@ res_T parse_camera (struct logger* logger, char* cam_param, - struct camera* cam) + struct stardis* stardis) { char** line = NULL; char** opt = NULL; + struct camera* cam; res_T res = RES_OK; - ASSERT(cam_param && cam); - + ASSERT(cam_param && stardis); + cam = &stardis->camera; line = split_line(cam_param, ':'); if(line) { + struct str keep; int i = 0; + str_init(stardis->allocator, &keep); for(i = 0; *(line + i); i++) { size_t len = 0; + str_set(&keep, line[i]); opt = split_line(line[i], '='); - ASSERT(opt[0] && opt[1] && !opt[2]); + if(!opt[0] || ! opt[1] || opt[2]) { + if(res == RES_OK) res = RES_BAD_ARG; + logger_print((logger), LOG_ERROR, + "Invalid option syntax: %s\n", str_cget(&keep)); + goto error; + } + str_set(&keep, opt[0]); _strupr(opt[0]); if(strcmp(opt[0], "T") == 0) { - ERR(cstr_to_double(opt[1], &cam->time)); + GET_OPTIONAL_TIME_RANGE(opt[1], 0, cam->time_range, logger, "%s", + str_cget(&keep)); } else if(strcmp(opt[0], "FOV") == 0) { ERR(cstr_to_double(opt[1], &cam->fov)); @@ -994,6 +984,7 @@ parse_camera goto error; } } + str_release(&keep); } end: @@ -1015,6 +1006,10 @@ error: goto end; } +#undef GET_STR_AND_OPTIONAL_TIME_RANGE +#undef GET_POS_AND_OPTIONAL_TIME_RANGE +#undef GET_OPTIONAL_TIME_RANGE + static struct description* find_description_by_name (struct stardis* stardis, diff --git a/src/stardis-parsing.h b/src/stardis-parsing.h @@ -104,7 +104,7 @@ struct args { char* chunks_prefix; size_t samples; unsigned nthreads; - double probe[4]; + double pos_and_time[5]; enum stardis_mode mode; double ambient_temp, ref_temp; char* camera; @@ -179,7 +179,7 @@ extern res_T parse_camera (struct logger* logger, char* cam_param, - struct camera* cam); + struct stardis* stardis); extern LOCAL_SYM res_T process_model_line