commit 7dc1cc64316d6ab09aefa033cce75bff99729a20
parent b841193d6d50c2689c95468fbdd1a2867280db0c
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Fri, 28 Feb 2025 10:43:24 +0100
Add the -l option to compute list of flux density probes
It differs from the -L option, that computes list of temperature probes,
in the way it is parallelized: every probe point is computed in parallel
using all the available resources.
This could eventually be changed when the solver has a dedicated API
function.
Diffstat:
7 files changed, 172 insertions(+), 53 deletions(-)
diff --git a/doc/stardis.1.in b/doc/stardis.1.in
@@ -31,6 +31,7 @@
.Op Fl G Pa green_bin Ns Op , Ns Pa green_ascii
.Op Fl I Ar initial_time
.Op Fl L Pa interface_probes
+.Op Fl l Pa interface_probes
.Op Fl m Ar medium_name Ns Op , Ns Ar time Ns Op , Ns Ar time
.Op Fl n Ar samples_count
.Op Fl o Ar picard_order
@@ -269,6 +270,22 @@ and not the calculation of each individual probe.
Its use is therefore more advantageous in terms of load distribution
when the number of probes to be evaluated is large, compared with the
cost of calculating a single probe point.
+.It Fl l Pa interface_probes
+Defines a set of interface probes for which
+.Nm
+calculates the flux density.
+The argument file lists the interface probe points.
+Each line of this file describes a probe point using the same grammar as
+that used to describe a single interface probe
+.Pq see Fl f No option .
+In addition to this syntax, characters behind the hash mark
+.Pq Ql #
+are considered comments and are therefore ignored, as are empty lines,
+i.e. lines with no characters at all or composed solely of spaces and
+tabs.
+.Pp
+This option allows the calculation of the probe list while reading and
+constructing the system only once.
.It Fl M Pa system
Read a text file containing a possibly partial description of the system.
Can include programs, media enclosures and boundary conditions.
diff --git a/src/stardis-app.c b/src/stardis-app.c
@@ -329,7 +329,8 @@ stardis_init
}
else if((args->mode & MODE_COMPUTE_PROBE_TEMP_ON_SURF)
|| (args->mode & MODE_COMPUTE_PROBE_FLUX_DNSTY_ON_SURF)
- || (args->mode & MODE_COMPUTE_LIST_PROBE_TEMP_ON_SURF)) {
+ || (args->mode & MODE_COMPUTE_LIST_PROBE_TEMP_ON_SURF)
+ || (args->mode & MODE_COMPUTE_LIST_PROBE_FLUX_DNSTY_ON_SURF)) {
ERR(darray_probe_boundary_copy
(&stardis->probe_boundary_list, &args->probe_boundary_list));
}
diff --git a/src/stardis-args.c b/src/stardis-args.c
@@ -118,6 +118,7 @@ mode_option(const int m)
if(m & MODE_GREEN_BIN) { found++; res = 'G'; }
if(m & MODE_DUMP_HELP) { found++; res = 'h'; }
if(m & MODE_COMPUTE_LIST_PROBE_TEMP_ON_SURF) { found++; res = 'L'; }
+ if(m & MODE_COMPUTE_LIST_PROBE_FLUX_DNSTY_ON_SURF) { found++; res = 'l'; }
if(m & MODE_COMPUTE_TEMP_MEAN_IN_MEDIUM) { found++; res = 'm'; }
if(m & MODE_COMPUTE_PROBE_TEMP_ON_VOL) { found++; res = 'p'; }
if(m & MODE_COMPUTE_PROBE_TEMP_ON_SURF) { found++; res = 'P'; }
@@ -268,7 +269,10 @@ error:
}
static res_T
-parse_probe_boundary(const char* str, struct stardis_probe_boundary* probe)
+parse_probe_boundary
+ (const char* str,
+ int with_sides,
+ struct stardis_probe_boundary* probe)
{
char buf[128];
char* pos_and_time = NULL;
@@ -286,12 +290,12 @@ parse_probe_boundary(const char* str, struct stardis_probe_boundary* probe)
strncpy(buf, str, sizeof(buf));
pos_and_time = strtok_r(buf, ":", &ctx);
- side = strtok_r(NULL, "", &ctx);
+ if(with_sides) side = strtok_r(NULL, "", &ctx);
res = parse_position_and_time(pos_and_time, probe->position, probe->time);
if(res != RES_OK) goto error;
- if(side) {
+ if(with_sides && side) {
res = parse_side_indicator(side, probe->side);
if(res != RES_OK) goto error;
}
@@ -334,6 +338,7 @@ parse_probe_boundary_list
(const char* filename,
struct logger* logger,
struct mem_allocator* allocator,
+ int with_sides,
struct darray_probe_boundary* list)
{
struct txtrdr* txtrdr = NULL;
@@ -358,7 +363,7 @@ parse_probe_boundary_list
if(!(line = txtrdr_get_cline(txtrdr))) goto exit; /* No line to parse */
- res = parse_probe_boundary(line, &probe);
+ res = parse_probe_boundary(line, with_sides, &probe);
if(res != RES_OK) goto error;
res = darray_probe_boundary_push_back(list, &probe);
@@ -461,7 +466,7 @@ usage(FILE* stream)
PRINT("stardis [-eghiv] [-a diff_algo] [-D path_type,files_name_prefix]\n");
PRINT(" [-d file_base_name] [-F surface[,time[,time]]]\n");
PRINT(" [-f x,y,z[,time[,time]]] [-G green_bin[,green_ascii]]\n");
- PRINT(" [-g] [-I initial_time] [-L interface_probes]\n");
+ PRINT(" [-g] [-I initial_time] [-L interface_probes] [-l interface_probes]\n");
PRINT(" [-m medium_name[,time[,time]]] [-n samples_count]\n");
PRINT(" [-o picard_order] [-P x,y,z[,time[,time]][:side_indicator]]\n");
PRINT(" [-p x,y,z[,time[,time]]] [-R rendering_opt[:rendering_opt ...]]\n");
@@ -526,7 +531,7 @@ parse_args
{
int opt = 0, n_used = 0, o_used = 0;
size_t len = 0;
- const char option_list[] = "a:c:d:D:ef:F:gG:hiI:L:m:M:n:o:p:P:R:s:S:t:vV:x:X:";
+ const char option_list[] = "a:c:d:D:ef:F:gG:hiI:L:l:m:M:n:o:p:P:R:s:S:t:vV:x:X:";
char buf[128];
struct str keep;
char** line = NULL;
@@ -624,7 +629,7 @@ parse_args
args->mode |= MODE_COMPUTE_PROBE_FLUX_DNSTY_ON_SURF;
res = allocate_probe_boundary(args, &probe);
if(res != RES_OK) goto error;
- res = parse_position_and_time(optarg, probe->position, probe->time);
+ res = parse_probe_boundary(optarg, 0, probe);
if(res != RES_OK) goto error;
break;
}
@@ -697,7 +702,20 @@ parse_args
}
args->mode |= MODE_COMPUTE_LIST_PROBE_TEMP_ON_SURF;
res = parse_probe_boundary_list
- (optarg, args->logger, args->allocator, &args->probe_boundary_list);
+ (optarg, args->logger, args->allocator, 1, &args->probe_boundary_list);
+ if(res != RES_OK) goto error;
+ 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_COMPUTE_LIST_PROBE_FLUX_DNSTY_ON_SURF;
+ res = parse_probe_boundary_list
+ (optarg, args->logger, args->allocator, 0, &args->probe_boundary_list);
if(res != RES_OK) goto error;
break;
@@ -782,7 +800,7 @@ parse_args
args->mode |= MODE_COMPUTE_PROBE_TEMP_ON_SURF;
res = allocate_probe_boundary(args, &probe);
if(res != RES_OK) goto error;
- res = parse_probe_boundary(optarg, probe);
+ res = parse_probe_boundary(optarg, 1, probe);
if(res != RES_OK) goto error;
break;
}
diff --git a/src/stardis-args.h.in b/src/stardis-args.h.in
@@ -55,14 +55,15 @@ enum stardis_mode {
MODE_GREEN_ASCII = BIT(7), /* -g */
MODE_DUMP_HELP = BIT(8), /* -h */
MODE_COMPUTE_LIST_PROBE_TEMP_ON_SURF = BIT(9), /* -L */
- MODE_COMPUTE_TEMP_MEAN_IN_MEDIUM = BIT(10), /* -m */
- MODE_COMPUTE_PROBE_TEMP_ON_SURF = BIT(11), /* -P */
- MODE_COMPUTE_PROBE_TEMP_ON_VOL = BIT(12), /* -p */
- MODE_COMPUTE_IMAGE_IR = BIT(13), /* -R */
- MODE_COMPUTE_TEMP_MAP_ON_SURF = BIT(14), /* -S */
- MODE_COMPUTE_TEMP_MEAN_ON_SURF = BIT(15), /* -s */
- MODE_VERBOSITY = BIT(16), /* -V */
- MODE_DUMP_VERSION = BIT(17), /* -v */
+ MODE_COMPUTE_LIST_PROBE_FLUX_DNSTY_ON_SURF = BIT(10), /* -l */
+ MODE_COMPUTE_TEMP_MEAN_IN_MEDIUM = BIT(11), /* -m */
+ MODE_COMPUTE_PROBE_TEMP_ON_SURF = BIT(12), /* -P */
+ MODE_COMPUTE_PROBE_TEMP_ON_VOL = BIT(13), /* -p */
+ MODE_COMPUTE_IMAGE_IR = BIT(14), /* -R */
+ MODE_COMPUTE_TEMP_MAP_ON_SURF = BIT(15), /* -S */
+ MODE_COMPUTE_TEMP_MEAN_ON_SURF = BIT(16), /* -s */
+ MODE_VERBOSITY = BIT(17), /* -V */
+ MODE_DUMP_VERSION = BIT(18), /* -v */
GREEN_COMPATIBLE_MODES =
MODE_COMPUTE_PROBE_TEMP_ON_VOL
@@ -90,7 +91,8 @@ enum stardis_mode {
| MODE_COMPUTE_IMAGE_IR
| SURFACE_COMPUTE_MODES
| MODE_COMPUTE_LIST_PROBE_TEMP_ON_SURF
- | MODE_COMPUTE_PROBE_FLUX_DNSTY_ON_SURF,
+ | MODE_COMPUTE_PROBE_FLUX_DNSTY_ON_SURF
+ | MODE_COMPUTE_LIST_PROBE_FLUX_DNSTY_ON_SURF,
EXCLUSIVE_MODES = COMPUTE_MODES,
@@ -109,6 +111,7 @@ enum stardis_mode {
MODE_COMPUTE_PROBE_TEMP_ON_VOL
| MODE_COMPUTE_PROBE_TEMP_ON_SURF
| MODE_COMPUTE_LIST_PROBE_TEMP_ON_SURF
+ | MODE_COMPUTE_LIST_PROBE_FLUX_DNSTY_ON_SURF
| MODE_COMPUTE_TEMP_MEAN_IN_MEDIUM
| MODE_COMPUTE_TEMP_MEAN_ON_SURF
| MODE_COMPUTE_FLUX_THROUGH_SURF
diff --git a/src/stardis-compute-probe-boundary.c b/src/stardis-compute-probe-boundary.c
@@ -736,6 +736,84 @@ error:
}
static res_T
+setup_solve_probe_boundary_flux_args
+ (struct stardis* stardis,
+ const struct stardis_probe_boundary* probe,
+ struct sdis_solve_probe_boundary_flux_args* args)
+{
+ double uv[2] = {0, 0};
+ size_t iprim = SIZE_MAX;
+ unsigned desc_ids[SG3D_PROP_TYPES_COUNT__];
+ res_T res = RES_OK;
+ ASSERT(stardis && probe && args);
+
+ /* Calculate the probe position on the boundary */
+ ERR(move_to_boundary(stardis, probe->position, probe->time[0], 0, &iprim, uv));
+
+ ERR(sg3d_geometry_get_unique_triangle_properties(stardis->geometry.sg3d,
+ (unsigned)iprim, desc_ids));
+
+ d3_set(stardis->probe, probe->position);
+ /* Setup of solve input parameters */
+
+ args->nrealisations = stardis->samples;
+ args->iprim = iprim;
+ d2_set(args->uv, uv);
+ args->picard_order = stardis->picard_order;
+ d2_set(args->time_range, stardis->time_range);
+ args->diff_algo = stardis->diff_algo;
+
+exit:
+ return res;
+error:
+ goto exit;
+}
+
+static res_T
+solve_flux_list
+ (struct stardis* stardis,
+ struct time* start,
+ const struct stardis_probe_boundary* probes,
+ size_t nprobes)
+{
+ struct time t0, t1;
+ struct sdis_mc time = SDIS_MC_NULL; /* Time per realisation */
+ struct sdis_estimator_buffer* buffer = NULL;
+ size_t i = 0;
+ struct sdis_estimator* estimator = NULL;
+ FILE* stream_r = NULL;
+ struct sdis_solve_probe_boundary_flux_args args;
+ res_T res = RES_OK;
+ ASSERT(stardis && start);
+
+ /* Input random state? */
+ READ_RANDOM_STATE(&stardis->rndgen_state_in_filename);
+
+ time_current(&t0);
+ for(i = 0; i < nprobes; i++) {
+ args = SDIS_SOLVE_PROBE_BOUNDARY_FLUX_ARGS_DEFAULT;
+ ERR(setup_solve_probe_boundary_flux_args(stardis, &probes[i], &args));
+ /* Run the calculation */
+ ERR(sdis_solve_probe_boundary_flux(stardis->sdis_scn, &args, &estimator));
+ /* Print the estimated temperature */
+ ERR(print_single_MC_result(estimator, stardis, stdout));
+ ERR(sdis_estimator_ref_put(estimator));
+ }
+ time_current(&t1);
+
+ /* Output random state? */
+ WRITE_RANDOM_STATE(&stardis->rndgen_state_out_filename);
+
+ ERR(print_computation_time(&time, stardis, start, &t0, &t1, NULL));
+
+exit:
+ if(buffer) SDIS(estimator_buffer_ref_put(buffer));
+ return res;
+error:
+ goto exit;
+}
+
+static res_T
solve_green
(struct stardis* stardis,
struct time* start,
@@ -828,40 +906,6 @@ error:
}
static res_T
-setup_solve_probe_boundary_flux_args
- (struct stardis* stardis,
- const struct stardis_probe_boundary* probe,
- struct sdis_solve_probe_boundary_flux_args* args)
-{
- double uv[2] = {0, 0};
- size_t iprim = SIZE_MAX;
- unsigned desc_ids[SG3D_PROP_TYPES_COUNT__];
- res_T res = RES_OK;
- ASSERT(stardis && probe && args);
-
- /* Calculate the probe position on the boundary */
- ERR(move_to_boundary(stardis, probe->position, probe->time[0], 0, &iprim, uv));
-
- ERR(sg3d_geometry_get_unique_triangle_properties(stardis->geometry.sg3d,
- (unsigned)iprim, desc_ids));
-
- d3_set(stardis->probe, probe->position);
- /* Setup of solve input parameters */
-
- args->nrealisations = stardis->samples;
- args->iprim = iprim;
- d2_set(args->uv, uv);
- args->picard_order = stardis->picard_order;
- d2_set(args->time_range, stardis->time_range);
- args->diff_algo = stardis->diff_algo;
-
-exit:
- return res;
-error:
- goto exit;
-}
-
-static res_T
compute_single_flux_probe_on_interface
(struct stardis* stardis,
struct time* start,
@@ -1036,6 +1080,31 @@ error:
goto exit;
}
+static res_T
+compute_multiple_flux_probes_on_interface
+ (struct stardis* stardis,
+ struct time* start)
+{
+ /* Probes */
+ const struct stardis_probe_boundary* probes = NULL;
+ size_t nprobes = 0;
+ res_T res = RES_OK;
+ ASSERT(stardis && start);
+
+ /* Fetch the list of probes arguments */
+ probes = darray_probe_boundary_cdata_get(&stardis->probe_boundary_list);
+ nprobes = darray_probe_boundary_size_get(&stardis->probe_boundary_list);
+ ASSERT(nprobes > 1);
+
+ /* Run calculations */
+ ERR(solve_flux_list(stardis, start, probes, nprobes));
+
+exit:
+ return res;
+error:
+ goto exit;
+}
+
/*******************************************************************************
* Local functions
******************************************************************************/
@@ -1046,6 +1115,7 @@ compute_probe_on_interface(struct stardis* stardis, struct time* start)
ASSERT(stardis && start);
ASSERT((stardis->mode & MODE_COMPUTE_PROBE_TEMP_ON_SURF)
|| (stardis->mode & MODE_COMPUTE_LIST_PROBE_TEMP_ON_SURF)
+ || (stardis->mode & MODE_COMPUTE_LIST_PROBE_FLUX_DNSTY_ON_SURF)
|| (stardis->mode & MODE_COMPUTE_PROBE_FLUX_DNSTY_ON_SURF));
/* Multiple probes */
@@ -1055,6 +1125,12 @@ compute_probe_on_interface(struct stardis* stardis, struct time* start)
res = compute_multiple_probes_on_interface(stardis, start);
if(res != RES_OK) goto error;
+ } else if(stardis->mode & MODE_COMPUTE_LIST_PROBE_FLUX_DNSTY_ON_SURF) {
+ ASSERT(darray_probe_boundary_size_get(&stardis->probe_boundary_list) > 1);
+
+ res = compute_multiple_flux_probes_on_interface(stardis, start);
+ if(res != RES_OK) goto error;
+
/* Single probe */
} else if(stardis->mode & MODE_COMPUTE_PROBE_TEMP_ON_SURF) {
const struct stardis_probe_boundary* probe = NULL;
diff --git a/src/stardis-compute.c b/src/stardis-compute.c
@@ -1145,6 +1145,9 @@ stardis_compute
case MODE_COMPUTE_LIST_PROBE_TEMP_ON_SURF:
ERR(compute_probe_on_interface(stardis, start));
break;
+ case MODE_COMPUTE_LIST_PROBE_FLUX_DNSTY_ON_SURF:
+ ERR(compute_probe_on_interface(stardis, start));
+ break;
case MODE_COMPUTE_PROBE_FLUX_DNSTY_ON_SURF:
ERR(compute_probe_on_interface(stardis, start));
break;
diff --git a/src/stardis-output.c b/src/stardis-output.c
@@ -1692,6 +1692,7 @@ print_single_MC_result
break;
case MODE_COMPUTE_PROBE_FLUX_DNSTY_ON_SURF:
+ case MODE_COMPUTE_LIST_PROBE_FLUX_DNSTY_ON_SURF:
{
enum sdis_estimator_type type;
ERR(sdis_estimator_get_type(estimator, &type));