commit 91f69384157d0ede5f6b5d331d3dc09f0d5df4a5
parent 6ab72843d44425b8dbf6e6adc7f4cb9785d8df36
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Fri, 23 Feb 2024 11:51:49 +0100
Preparing the calculation for several probes on the boundary
Add the -L option (not yet documented) which defines a file listing a
set of probes on the boundary. The file is analyzed during the argument
analysis. This choice is debatable and we could simply store the name
of the file and then, once all the arguments have been analyzed, load
the set of probes when stardis is initialized.
Boundary probes are now stored in a dynamic array, even when calculating
a single probe. In this case, the array contains only one element.
The compute_probe_on_interface partially supports this new calculation
mode, i.e. the calculation of multiple probes on the boundary. This is
only partial support: the solver is not called.
Diffstat:
7 files changed, 240 insertions(+), 51 deletions(-)
diff --git a/src/stardis-app.c b/src/stardis-app.c
@@ -260,6 +260,7 @@ stardis_init
darray_size_t_init(stardis->allocator, &stardis->compute_surface.primitives);
darray_sides_init(stardis->allocator, &stardis->compute_surface.sides);
darray_uint_init(stardis->allocator, &stardis->compute_surface.err_triangles);
+ darray_probe_boundary_init(stardis->allocator, &stardis->probe_boundary_list);
stardis->compute_surface.area = 0;
stardis->samples = args->samples;
stardis->nthreads = args->nthreads;
@@ -319,8 +320,10 @@ stardis_init
else if(args->mode & MODE_MEDIUM_COMPUTE) {
ERR(str_set(&stardis->solve_name, args->medium_name));
}
- else if(args->mode & MODE_PROBE_COMPUTE_ON_INTERFACE) {
- stardis->probe_boundary = args->probe_boundary;
+ else if((args->mode & MODE_PROBE_COMPUTE_ON_INTERFACE)
+ || (args->mode & MODE_PROBE_LIST_COMPUTE_ON_INTERFACE)) {
+ ERR(darray_probe_boundary_copy
+ (&stardis->probe_boundary_list, &args->probe_boundary_list));
}
else if(args->mode & SURFACE_COMPUTE_MODES) {
ERR(str_set(&stardis->solve_name, args->solve_filename));
@@ -572,6 +575,7 @@ stardis_release
if(stardis->dummies.stardis_solid) {
release_solid(stardis->dummies.stardis_solid, stardis->allocator);
}
+ darray_probe_boundary_release(&stardis->probe_boundary_list);
}
unsigned
diff --git a/src/stardis-app.h b/src/stardis-app.h
@@ -240,7 +240,7 @@ struct stardis {
int mpi_initialized;
int mpi_rank;
- struct stardis_probe_boundary probe_boundary;
+ struct darray_probe_boundary probe_boundary_list;
};
unsigned
diff --git a/src/stardis-args.c b/src/stardis-args.c
@@ -20,11 +20,13 @@
#include "stardis-default.h"
#include "stardis-version.h"
+#include <sdis_version.h>
+
#include <rsys/cstr.h>
#include <rsys/double2.h>
#include <rsys/double3.h>
-#include <sdis_version.h>
#include <rsys/logger.h>
+#include <rsys/text_reader.h>
#include <getopt.h>
#include <stdlib.h>
@@ -114,6 +116,7 @@ mode_option(const int m)
if(m & MODE_GREEN) { found++; res = 'g'; }
if(m & MODE_BIN_GREEN) { found++; res = 'G'; }
if(m & MODE_DUMP_HELP) { found++; res = 'h'; }
+ if(m & MODE_PROBE_LIST_COMPUTE_ON_INTERFACE) { found++; res = 'L'; }
if(m & MODE_MEDIUM_COMPUTE) { found++; res = 'm'; }
if(m & MODE_PROBE_COMPUTE) { found++; res = 'p'; }
if(m & MODE_PROBE_COMPUTE_ON_INTERFACE) { found++; res = 'P'; }
@@ -270,6 +273,91 @@ error:
goto exit;
}
+static res_T
+allocate_probe_boundary
+ (struct args* args,
+ struct stardis_probe_boundary** out_probe)
+{
+ size_t i = 0;
+ res_T res = RES_OK;
+ ASSERT(args && out_probe);
+
+ i = darray_probe_boundary_size_get(&args->probe_boundary_list);
+ res = darray_probe_boundary_resize(&args->probe_boundary_list, i+1);
+ if(res != RES_OK) {
+ logger_print(args->logger, LOG_ERROR,
+ "Error allocating the probe on the boundary -- %s.\n",
+ res_to_cstr(res));
+ goto error;
+ }
+
+ *out_probe = darray_probe_boundary_data_get(&args->probe_boundary_list) + i;
+
+exit:
+ return res;
+error:
+ darray_probe_boundary_resize(&args->probe_boundary_list, i); /* Deallocate */
+ goto exit;
+}
+
+static res_T
+parse_probe_boundary_list
+ (const char* filename,
+ struct logger* logger,
+ struct mem_allocator* allocator,
+ struct darray_probe_boundary* list)
+{
+ struct txtrdr* txtrdr = NULL;
+ res_T res = RES_OK;
+ ASSERT(filename && list);
+
+ res = txtrdr_file(allocator, filename, '#', &txtrdr);
+ if(res != RES_OK) goto error;
+
+ for(;;) {
+ struct stardis_probe_boundary probe = STARDIS_PROBE_BOUNDARY_NULL;
+ const char* line = NULL;
+
+ res = txtrdr_read_line(txtrdr);
+ if(res != RES_OK) {
+ logger_print(logger, LOG_ERROR,
+ "%s: could not read the line `%lu' -- %s.\n",
+ txtrdr_get_name(txtrdr), (unsigned long)txtrdr_get_line_num(txtrdr),
+ res_to_cstr(res));
+ goto error;
+ }
+
+ if(!(line = txtrdr_get_cline(txtrdr))) goto exit; /* No line to parse */
+
+ res = parse_probe_boundary(line, &probe);
+ if(res != RES_OK) goto error;
+
+ res = darray_probe_boundary_push_back(list, &probe);
+ if(res != RES_OK) {
+ logger_print(logger, LOG_ERROR,
+ "%s:%lu: error registering the probe on the boundary -- %s.\n",
+ txtrdr_get_name(txtrdr), (unsigned long)txtrdr_get_line_num(txtrdr),
+ res_to_cstr(res));
+ goto error;
+ }
+ }
+
+ if(!darray_probe_boundary_size_get(list)) {
+ logger_print(logger, LOG_ERROR,
+ "The file `%s' does not list any probes on the boundary.\n",
+ filename);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+exit:
+ if(txtrdr) txtrdr_ref_put(txtrdr);
+ return res;
+error:
+ darray_probe_boundary_clear(list);
+ goto exit;
+}
+
/*******************************************************************************
* Public Functions
******************************************************************************/
@@ -316,6 +404,7 @@ init_args
d2(args->pos_and_time+3,
STARDIS_DEFAULT_COMPUTE_TIME, STARDIS_DEFAULT_COMPUTE_TIME);
args->verbose = STARDIS_DEFAULT_VERBOSE_LEVEL;
+ darray_probe_boundary_init(allocator, &args->probe_boundary_list);
end:
*out_args = args;
@@ -331,6 +420,7 @@ release_args(struct args* args)
{
ASSERT(args);
darray_str_release(&args->model_files);
+ darray_probe_boundary_release(&args->probe_boundary_list);
free(args);
}
@@ -404,7 +494,7 @@ parse_args
{
int opt = 0, n_used = 0, o_used = 0;
size_t len = 0;
- const char option_list[] = "c:d:D:eF:gG:hm:M:n:o:p:P:R:s:S:t:vV:x:X:";
+ const char option_list[] = "c:d:D:eF:gG:hL:m:M:n:o:p:P:R:s:S:t:vV:x:X:";
char buf[128];
struct str keep;
char** line = NULL;
@@ -533,6 +623,19 @@ parse_args
args->mode |= MODE_DUMP_HELP;
break;
+ case 'L':
+ if(args->mode & EXCLUSIVE_MODES) {
+ logger_print(args->logger, LOG_ERROR,
+ "Options -%c and -%c are exclusive.\n",
+ (char)opt, mode_option(args->mode));
+ goto error;
+ }
+ args->mode |= MODE_PROBE_COMPUTE_ON_INTERFACE;
+ res = parse_probe_boundary_list
+ (optarg, args->logger, args->allocator, &args->probe_boundary_list);
+ if(res != RES_OK) goto error;
+ break;
+
case 'm': {
char* ptr;
if(args->mode & EXCLUSIVE_MODES) {
@@ -601,7 +704,9 @@ parse_args
GET_POS_AND_OPTIONAL_TIME_RANGE(optarg, args->pos_and_time, optarg);
break;
- case 'P':
+ case 'P': {
+ struct stardis_probe_boundary* probe = NULL;
+
if(args->mode & EXCLUSIVE_MODES) {
logger_print(args->logger, LOG_ERROR,
"Options -%c and -%c are exclusive.\n",
@@ -610,9 +715,12 @@ parse_args
goto error;
}
args->mode |= MODE_PROBE_COMPUTE_ON_INTERFACE;
- res = parse_probe_boundary(optarg, &args->probe_boundary);
+ res = allocate_probe_boundary(args, &probe);
+ if(res != RES_OK) goto error;
+ res = parse_probe_boundary(optarg, probe);
if(res != RES_OK) goto error;
break;
+ }
case 'R':
if(args->mode & EXCLUSIVE_MODES) {
diff --git a/src/stardis-args.h.in b/src/stardis-args.h.in
@@ -37,6 +37,11 @@ struct stardis_probe_boundary {
static const struct stardis_probe_boundary STARDIS_PROBE_BOUNDARY_NULL =
STARDIS_PROBE_BOUNDARY_NULL__;
+/* Define the dynamic array of probes on the boundary */
+#define DARRAY_NAME probe_boundary
+#define DARRAY_DATA struct stardis_probe_boundary
+#include <rsys/dynamic_array.h>
+
enum stardis_mode {
/* Ordered so that print_multiple_modes() prints in alphabetical order */
UNDEF_MODE = 0,
@@ -48,40 +53,62 @@ enum stardis_mode {
MODE_BIN_GREEN = BIT(5), /* -G */
MODE_GREEN = BIT(6), /* -g */
MODE_DUMP_HELP = BIT(7), /* -h */
- MODE_MEDIUM_COMPUTE = BIT(8), /* -m */
- MODE_PROBE_COMPUTE_ON_INTERFACE = BIT(9), /* -P */
- MODE_PROBE_COMPUTE = BIT(10), /* -p */
- MODE_IR_COMPUTE = BIT(11), /* -R */
- MODE_MAP_COMPUTE = BIT(12), /* -S */
- MODE_BOUNDARY_COMPUTE = BIT(13), /* -s */
- MODE_VERBOSITY = BIT(14), /* -V */
- MODE_DUMP_VERSION = BIT(15), /* -v */
-
- GREEN_COMPATIBLE_MODES
- = MODE_PROBE_COMPUTE | MODE_PROBE_COMPUTE_ON_INTERFACE | MODE_MEDIUM_COMPUTE
- | MODE_BOUNDARY_COMPUTE,
-
- SURFACE_COMPUTE_MODES
- = MODE_BOUNDARY_COMPUTE | MODE_FLUX_BOUNDARY_COMPUTE | MODE_MAP_COMPUTE,
-
- EXT_COMPATIBLE_MODES
- = GREEN_COMPATIBLE_MODES | MODE_MEDIUM_COMPUTE | MODE_FLUX_BOUNDARY_COMPUTE,
-
- REGION_COMPUTE_MODES = SURFACE_COMPUTE_MODES | MODE_MEDIUM_COMPUTE,
-
- COMPUTE_MODES = GREEN_COMPATIBLE_MODES | MODE_IR_COMPUTE | SURFACE_COMPUTE_MODES,
+ MODE_PROBE_LIST_COMPUTE_ON_INTERFACE = BIT(8), /* -L */
+ MODE_MEDIUM_COMPUTE = BIT(9), /* -m */
+ MODE_PROBE_COMPUTE_ON_INTERFACE = BIT(10), /* -P */
+ MODE_PROBE_COMPUTE = BIT(11), /* -p */
+ MODE_IR_COMPUTE = BIT(12), /* -R */
+ MODE_MAP_COMPUTE = BIT(13), /* -S */
+ MODE_BOUNDARY_COMPUTE = BIT(14), /* -s */
+ MODE_VERBOSITY = BIT(15), /* -V */
+ MODE_DUMP_VERSION = BIT(16), /* -v */
+
+ GREEN_COMPATIBLE_MODES =
+ MODE_PROBE_COMPUTE
+ | MODE_PROBE_COMPUTE_ON_INTERFACE
+ | MODE_MEDIUM_COMPUTE
+ | MODE_BOUNDARY_COMPUTE,
+
+ SURFACE_COMPUTE_MODES =
+ MODE_BOUNDARY_COMPUTE
+ | MODE_FLUX_BOUNDARY_COMPUTE
+ | MODE_MAP_COMPUTE,
+
+ EXT_COMPATIBLE_MODES =
+ GREEN_COMPATIBLE_MODES
+ | MODE_MEDIUM_COMPUTE
+ | MODE_FLUX_BOUNDARY_COMPUTE,
+
+ REGION_COMPUTE_MODES =
+ SURFACE_COMPUTE_MODES
+ | MODE_MEDIUM_COMPUTE,
+
+ COMPUTE_MODES =
+ GREEN_COMPATIBLE_MODES
+ | MODE_IR_COMPUTE
+ | SURFACE_COMPUTE_MODES
+ | MODE_PROBE_LIST_COMPUTE_ON_INTERFACE,
EXCLUSIVE_MODES = COMPUTE_MODES,
- SHORT_EXIT_MODES = MODE_DUMP_HELP | MODE_DUMP_VERSION,
-
- USE_STDOUT_MODES
- = MODE_DUMP_C_CHUNKS | MODE_DUMP_HELP | MODE_DUMP_VERSION | MODE_IR_COMPUTE
- | MODE_GREEN,
-
- RANDOM_RW_MODES
- = MODE_PROBE_COMPUTE | MODE_PROBE_COMPUTE_ON_INTERFACE | MODE_MEDIUM_COMPUTE
- | MODE_BOUNDARY_COMPUTE | MODE_FLUX_BOUNDARY_COMPUTE
+ SHORT_EXIT_MODES =
+ MODE_DUMP_HELP
+ | MODE_DUMP_VERSION,
+
+ USE_STDOUT_MODES =
+ MODE_DUMP_C_CHUNKS
+ | MODE_DUMP_HELP
+ | MODE_DUMP_VERSION
+ | MODE_IR_COMPUTE
+ | MODE_GREEN,
+
+ RANDOM_RW_MODES =
+ MODE_PROBE_COMPUTE
+ | MODE_PROBE_COMPUTE_ON_INTERFACE
+ | MODE_PROBE_LIST_COMPUTE_ON_INTERFACE
+ | MODE_MEDIUM_COMPUTE
+ | MODE_BOUNDARY_COMPUTE
+ | MODE_FLUX_BOUNDARY_COMPUTE
};
STATIC_ASSERT(GREEN_COMPATIBLE_MODES == (COMPUTE_MODES & GREEN_COMPATIBLE_MODES),
@@ -116,7 +143,7 @@ struct args {
enum dump_path_type dump_paths;
int verbose;
- struct stardis_probe_boundary probe_boundary;
+ struct darray_probe_boundary probe_boundary_list;
};
extern LOCAL_SYM res_T
diff --git a/src/stardis-compute-probe-boundary.c b/src/stardis-compute-probe-boundary.c
@@ -773,16 +773,15 @@ error:
goto exit;
}
-/*******************************************************************************
- * Local functions
- ******************************************************************************/
-res_T
-compute_probe_on_interface(struct stardis* stardis, struct time* start)
+static res_T
+compute_single_probe_on_interface
+ (struct stardis* stardis,
+ struct time* start,
+ const struct stardis_probe_boundary* probe)
{
/* Probe */
struct sdis_solve_probe_boundary_args args
= SDIS_SOLVE_PROBE_BOUNDARY_ARGS_DEFAULT;
- const struct stardis_probe_boundary* probe = NULL;
enum sdis_side probe_side = SDIS_SIDE_NULL__;
/* Miscellaneous */
@@ -792,9 +791,8 @@ compute_probe_on_interface(struct stardis* stardis, struct time* start)
res_T output_status[2] = {RES_OK, RES_OK};
res_T res = RES_OK;
- ASSERT(stardis && start && (stardis->mode & MODE_PROBE_COMPUTE_ON_INTERFACE));
-
- probe = &stardis->probe_boundary;
+ /* Check pre-conditions */
+ ASSERT(stardis && start && probe);
/* Calculate the probe position on the boundary */
ERR(move_to_boundary(stardis, probe->position, probe->time[0], &iprim, uv));
@@ -836,5 +834,52 @@ exit:
res = (res != RES_OK ? res : output_status[1]);
return res;
error:
- goto exit;
+ goto exit;
+}
+
+static res_T
+compute_multiple_probes_on_interface
+ (struct stardis* stardis,
+ struct time* start)
+{
+ res_T res = RES_OK;
+ ASSERT(stardis && start);
+ (void)stardis, (void)start; /* Avoid "unused variable" warnings */
+
+ /* TODO */
+ return res;
+}
+
+/*******************************************************************************
+ * Local functions
+ ******************************************************************************/
+res_T
+compute_probe_on_interface(struct stardis* stardis, struct time* start)
+{
+ res_T res = RES_OK;
+ ASSERT(stardis && start);
+ ASSERT((stardis->mode & MODE_PROBE_COMPUTE_ON_INTERFACE)
+ || (stardis->mode & MODE_PROBE_LIST_COMPUTE_ON_INTERFACE));
+
+ /* Multiple probes */
+ if(stardis->mode & MODE_PROBE_LIST_COMPUTE_ON_INTERFACE) {
+ ASSERT(darray_probe_boundary_size_get(&stardis->probe_boundary_list) > 1);
+
+ res = compute_multiple_probes_on_interface(stardis, start);
+ if(res != RES_OK) goto error;
+
+ /* Single probe */
+ } else if(stardis->mode & MODE_PROBE_COMPUTE_ON_INTERFACE) {
+ const struct stardis_probe_boundary* probe = NULL;
+ ASSERT(darray_probe_boundary_size_get(&stardis->probe_boundary_list) == 1);
+
+ probe = darray_probe_boundary_cdata_get(&stardis->probe_boundary_list);
+ res = compute_single_probe_on_interface(stardis, start, probe);
+ if(res != RES_OK) goto error;
+ }
+
+exit:
+ return res;
+error:
+ goto exit;
}
diff --git a/src/stardis-compute.c b/src/stardis-compute.c
@@ -1171,6 +1171,8 @@ stardis_compute
ERR(compute_probe(stardis, start));
else if(stardis->mode & MODE_PROBE_COMPUTE_ON_INTERFACE)
ERR(compute_probe_on_interface(stardis, start));
+ else if(stardis->mode & MODE_PROBE_LIST_COMPUTE_ON_INTERFACE)
+ ERR(compute_probe_on_interface(stardis, start));
else if(stardis->mode & MODE_IR_COMPUTE)
ERR(compute_camera(stardis, start));
else if(stardis->mode & MODE_MEDIUM_COMPUTE)
diff --git a/src/stardis-output.c b/src/stardis-output.c
@@ -1646,11 +1646,14 @@ print_single_MC_result
break;
case MODE_PROBE_COMPUTE_ON_INTERFACE:
if(stardis->mode & MODE_EXTENDED_RESULTS) {
+ const struct stardis_probe_boundary* probe = NULL;
+ ASSERT(darray_probe_boundary_size_get(&stardis->probe_boundary_list) == 1);
+ probe = darray_probe_boundary_cdata_get(&stardis->probe_boundary_list);
if(stardis->time_range[0] == stardis->time_range[1])
fprintf(stream,
"Boundary temperature at [%g, %g, %g] at t=%g = %g K +/- %g\n",
- SPLIT3(stardis->probe_boundary.position),
- stardis->probe_boundary.time[0],
+ SPLIT3(probe->position),
+ probe->time[0],
result.E, /* Expected value */
result.SE); /* Standard error */
else