commit e33c2d32b1676023beec4c3dd9cb1d54af463a85
parent 4bc6aef5b7a422caca699576309edfeb101c73a8
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Wed, 17 Jul 2024 11:25:24 +0200
Merge branch 'release_0.11'
Diffstat:
20 files changed, 409 insertions(+), 244 deletions(-)
diff --git a/README.md b/README.md
@@ -33,6 +33,52 @@ Edit config.mk as needed, then run:
## Release notes
+### Version 0.11
+
+#### Programmable properties
+
+- Custom sampling of conductive paths. On programmable solids, users
+ can now define the new `stardis_sampling_conductive_path` function, in
+ which they can write their own sampling process. As input, the
+ function takes a path whose spatio-temporal position lies within the
+ programmable solid. Once the path has been sampled, this position is
+ updated and can be either within the solid if the initial condition is
+ reached, or at the boundary, i.e. at a boundary condition. Stardis
+ then continues the path sampling procedure in relation to the returned
+ state.
+- Addition of the property name as the first argument of the input
+ string sent to the programmable data creation functions. Not only is
+ this useful information, it also respects the convention of program
+ arguments. In this way, the standard getopt function can be used
+ directly to analyze them.
+- Addition of symbolic constants to the public API for programmable
+ properties. The constants added are those defining an unknown
+ temperature, and constants characterizing null flux or null volumic
+ power.
+
+#### Manual pages
+
+- Document the `-n` option which defines the number of realisations. Its
+ documentation was missing from the `stardis` manual page.
+- Correction of the title of the `stardis-output` manual page. It was
+ defined as `stardis-input`.
+- Updated the layout of the `stardis-output` manual page. When converted
+ to HTML, the width of the columns changed from one list to another,
+ resulting in an unstructured layout.
+
+#### Miscellaneous
+
+- Correction of the Dirichlet boundary condition definition. No
+ reference temperature was defined on a surface oriented towards a
+ fluid and on which a Dirichlet boundary condition was imposed
+ (keywords `T_BOUNDARY_FOR_SOLID[_PROG]`). Stardis therefore notified an
+ error and rejected radiative trajectories reaching such interfaces
+ without a reference temperature. From now on, its reference
+ temperature is implicitly defined as the set temperature value.
+- Removal of a warning message when calculating a list of boundary
+ probes. It incorrectly warned that the side of the boundary on which
+ the probe was located was not defined.
+
### Version 0.10.1
Add a pkg-config file to support the use of Stardis header files such as
@@ -283,4 +329,3 @@ Copyright (C) 2018-2024 |Méso|Star> (<contact@meso-star.com>)
Stardis is free software released under the GPL v3+ license: GNU GPL
version 3 or later. You are welcome to redistribute it under certain
conditions; refer to the COPYING file for details.
-
diff --git a/config.mk b/config.mk
@@ -1,6 +1,6 @@
VERSION_MAJOR = 0
-VERSION_MINOR = 10
-VERSION_PATCH = 1
+VERSION_MINOR = 11
+VERSION_PATCH = 0
VERSION = $(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_PATCH)
PREFIX = /usr/local
@@ -74,11 +74,11 @@ S3D_VERSION = 0.10
S3D_CFLAGS = $$($(PKG_CONFIG) $(PCFLAGS) --cflags s3d)
S3D_LIBS = $$($(PKG_CONFIG) $(PCFLAGS) --libs s3d)
-SDIS_VERSION = 0.15.1
+SDIS_VERSION = 0.16
SDIS_CFLAGS = $$($(PKG_CONFIG) $(PCFLAGS) --cflags sdis)
SDIS_LIBS = $$($(PKG_CONFIG) $(PCFLAGS) --libs sdis)
-SENC3D_VERSION = 0.5
+SENC3D_VERSION = 0.7.2
SENC3D_CFLAGS = $$($(PKG_CONFIG) $(PCFLAGS) --cflags senc3d)
SENC3D_LIBS = $$($(PKG_CONFIG) $(PCFLAGS) --libs senc3d)
diff --git a/doc/stardis-output.5 b/doc/stardis-output.5
@@ -13,7 +13,7 @@
.\" You should have received a copy of the GNU General Public License
.\" along with this program. If not, see <http://www.gnu.org/licenses/>.
.Dd April 12, 2024
-.Dt STARDIS-INPUT 5
+.Dt STARDIS-OUTPUT 5
.Os
.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
.\" Name and short description
@@ -112,30 +112,26 @@ or an extended format that mixes numbers and their descriptions
.It Ta \& \& | Ta Ao Va medium-temp Ac # Option Fl m
.It Ta \& \& | Ta Ao Va mean-temp Ac # Option Fl s
.It Ta \& \& | Ta Ao Va mean-flux Ac # Option Fl F
-.El
+.It \ Ta Ta
.\" Probe temperature
-.Bl -column (******************) (::=) ()
.It Ao Va probe-temp Ac Ta ::= Ta Ao Va probe-temp-raw Ac | Ao Va probe-temp-ext Ac
.It Ao Va probe-temp-raw Ac Ta ::= Ta Ao Va estimate Ac Ao Va failures Ac
.It Ao Va probe-temp-ext Ac Ta ::= Ta Li Temperature at Ao Va position Ac Ao Va time Ac \e
.It Ta Ta Ao Va estimate-temp-ext Ac Ao Va failures-ext Ac
-.El
+.It \ Ta Ta
.\" Medium temperature
-.Bl -column (******************) (::=) ()
.It Ao Va medium-temp Ac Ta ::= Ta Ao Va medium-temp-raw Ac | Ao Va medium-temp-ext Ac
.It Ao Va medium-temp-raw Ac Ta ::= Ta Ao Va estimate Ac Ao Va failures Ac
.It Ao Va medium-temp-ext Ac Ta ::= Ta Li Temperature in medium Ao Va medium-name Ac \e
.It Ta Ta Ao Va time Ac Ao Va estimate-temp-ext Ac Ao Va failures-ext Ac
-.El
+.It \ Ta Ta
.\" Mean temperature
-.Bl -column (******************) (::=) ()
.It Ao Va mean-temp Ac Ta ::= Ta Ao Va mean-temp-raw Ac | Ao Va mean-temp-ext Ac
.It Ao Va mean-temp-raw Ac Ta ::= Ta Ao Va estimate Ac Ao Va failures Ac
.It Ao Va mean-temp-ext Ac Ta ::= Ta Li Temperature at boundary Ao Va stl-path Ac \e
.It Ta Ta Ao Va time Ac Ao Va estimate-temp-ext Ac Ao Va failures-ext Ac
-.El
+.It \ Ta Ta
.\" Mean flux
-.Bl -column (******************) (::=) ()
.It Ao Va mean-flux Ac Ta ::= Ta Ao Va mean-flux-raw Ac | Ao Va mean-flux-ext Ac
.It Ao Va mean-flux-raw Ac Ta ::= Ta Ao Va estimate Ac Ao Va estimate Ac Ao Va estimate Ac \e
.It Ta Ta Ao Va estimate Ac Ao Va estimate Ac Ao Va failures Ac
@@ -150,21 +146,18 @@ or an extended format that mixes numbers and their descriptions
.It Ta Ta Li Total flux at boundary Ao Va stl-path Ac \e
.It Ta Ta Ao Va time Ac Ao Va estimate-flux-ext Ac
.It Ta Ta Ao Va failures-ext Ac
-.El
+.It \ Ta Ta
.\" Miscellaneous
-.Bl -column (******************) (::=) ()
.It Ao Va estimate Ac Ta ::= Ta Ao Va expected-value Ac Ao Va standard-error Ac
.It Ao Va estimate-temp-ext Ac Ta ::= Ta Ao Va expected-value Ac Li K +/- Ao Va standard-error Ac
.It Ao Va estimate-flux-ext Ac Ta ::= Ta Ao Va expected-value Ac Li W +/- Ao Va standard-error Ac
.It Ao Va expected-value Ac Ta ::= Ta Vt real
.It Ao Va standard-error Ac Ta ::= Ta Vt real
-.El
-.Bl -column (******************) (::=) ()
+.It \ Ta Ta
.It Ao Va failures Ac Ta ::= Ta Ao Va error-count Ac Ao Va success-count Ac
.It Ao Va error-count Ac Ta ::= Ta Vt integer
.It Ao Va success-count Ac Ta ::= Ta Vt integer
-.El
-.Bl -column (******************) (::=) ()
+.It \ Ta Ta
.It Ao Va position Ac Ta ::= Ta [ Vt real , Vt real , Vt real ]
.It Ao Va time Ac Ta ::= Ta Li at t= Ns Vt real
.It Ta \& \& | Ta Li with t in [ Vt real , Vt real ]
@@ -510,8 +503,7 @@ List the file identifier in which each triangle first appeared:
.It Ta Ta Li LOOKUP_TABLE default
.It Ta Ta Aq Va file-rank
.It Ta Ta ... # Up to Aq Va #triangles
-.El
-.Bl -column (******************) (::=) ()
+.It \ Ta Ta
.It Ao Va #vertices Ac Ta ::= Ta Vt integer
.It Ao Va #triangles Ac Ta ::= Ta Vt integer
.It Ao Va #triangles*4 Ac Ta ::= Ta Vt integer
diff --git a/doc/stardis.1.in b/doc/stardis.1.in
@@ -12,7 +12,7 @@
.\"
.\" You should have received a copy of the GNU General Public License
.\" along with this program. If not, see <http://www.gnu.org/licenses/>.
-.Dd April 26, 2024
+.Dd June 17, 2024
.Dt STARDIS 1
.Os
.Sh NAME
@@ -271,6 +271,10 @@ The medium name must be part of the
description.
By default the compute time is @STARDIS_ARGS_DEFAULT_COMPUTE_TIME@.
The medium region does not need to be connex.
+.It Fl n Ar samples_count
+Number of Monte Carlo realisations.
+By default, the number of realisations is
+@STARDIS_ARGS_DEFAULT_SAMPLES_COUNT@.
.It Fl o Ar picard_order
Determine the iteration level used with the Picard method to deal with
non-linear radiative transfer accross the model.
diff --git a/src/stardis-app.h b/src/stardis-app.h
@@ -34,7 +34,7 @@
#include <sdis.h>
#ifdef STARDIS_ENABLE_MPI
-#include <mpi.h>
+ #include <mpi.h>
#endif
/* Forward declarations */
@@ -216,6 +216,10 @@ struct stardis {
struct compute_surface compute_surface; /* 2D compute region when mode is
[FLUX_]BOUNDARY_COMPUTE
or MAP_COMPUTE */
+
+ /* Min/Max temperatures used to linearize radiative transfer */
+ double t_range[2]; /* [K] */
+
struct str dump_model_filename;
struct str paths_filename;
struct str bin_green_filename;
@@ -230,7 +234,6 @@ struct stardis {
int radenv_def;
size_t samples;
double scale_factor;
- double t_range[2];
double initial_time; /* [s] */
int mode;
unsigned nthreads;
diff --git a/src/stardis-compute-probe-boundary.c b/src/stardis-compute-probe-boundary.c
@@ -342,10 +342,6 @@ move_to_boundary
double proj_pos[3] = {0,0,0};
size_t iprim = 0;
- /* Properties */
- const struct description* desc_list = NULL;
- const struct description* desc = NULL;
- unsigned desc_ids[SG3D_PROP_TYPES_COUNT__];
/* Miscellaneous */
size_t nvertices_close = 0;
@@ -355,19 +351,17 @@ move_to_boundary
ASSERT(stardis && pos && time >= 0 && out_iprim && uv);
ERR(find_closest_point(stardis, pos, &filter_ctx, &iprim, uv));
- SG3D(geometry_get_unique_triangle_properties
- (stardis->geometry.sg3d, (unsigned)iprim, desc_ids));
- desc_list = darray_descriptions_cdata_get(&stardis->descriptions);
+ if(filter_ctx.side != SG3D_INTFACE) {
+ /* Properties */
+ const struct description* desc_list = NULL;
+ const struct description* desc = NULL;
+ unsigned desc_ids[SG3D_PROP_TYPES_COUNT__];
- /* Undefined medium */
- if(filter_ctx.side == SG3D_INTFACE
- || desc_ids[filter_ctx.side] == SG3D_UNSPECIFIED_PROPERTY) {
- logger_print(stardis->logger, LOG_WARNING,
- "Could not determine the medium probe is in.\n");
- }
+ SG3D(geometry_get_unique_triangle_properties
+ (stardis->geometry.sg3d, (unsigned)iprim, desc_ids));
- if(filter_ctx.side != SG3D_INTFACE) {
+ desc_list = darray_descriptions_cdata_get(&stardis->descriptions);
/* Probe is outside the system */
if(desc_ids[filter_ctx.side] == SG3D_UNSPECIFIED_PROPERTY) {
diff --git a/src/stardis-fbound-prog.c b/src/stardis-fbound-prog.c
@@ -82,14 +82,16 @@ str_print_f_boundary_prog
{
res_T res = RES_OK;
ASSERT(str && b);
+ ASSERT(b->argc >= 1); /* At least one argument which is the program name */
+
ERR(str_append_printf(str,
"programmed F boundary for SOLID '%s': lib='%s', "
"(using medium %u as external medium)",
str_cget(&b->name), str_cget(&b->prog_name), b->mat_id));
- if(b->argc > 0) {
+ if(b->argc > 1) {
size_t i;
ERR(str_append_printf(str, ", provided arguments:\n"));
- for(i = 0; i < b->argc; i++) {
+ for(i = 1; i < b->argc; i++) {
ERR(str_append_printf(str, (i+1 == b->argc ? "\t%s" : "\t%s\n"), b->argv[i]));
}
}
diff --git a/src/stardis-fluid-prog.c b/src/stardis-fluid-prog.c
@@ -24,7 +24,6 @@
#include <limits.h>
-
/*******************************************************************************
* Local Functions
******************************************************************************/
@@ -59,9 +58,11 @@ fluid_prog_get_temperature
{
const struct fluid_prog* const* fluid_props = sdis_data_cget(data);
struct stardis_vertex v;
+ double temp = 0;
d3_set(v.P, vtx->P);
v.time = vtx->time;
- return (*fluid_props)->temp(&v, (*fluid_props)->prog_data);
+ temp = (*fluid_props)->temp(&v, (*fluid_props)->prog_data);
+ return STARDIS_TEMPERATURE_IS_KNOWN(temp) ? temp : SDIS_TEMPERATURE_NONE;;
}
/*******************************************************************************
@@ -188,13 +189,16 @@ str_print_fluid_prog(struct str* str, const struct fluid_prog* f)
{
res_T res = RES_OK;
ASSERT(str && f);
+ ASSERT(f->argc >= 1); /* At least one argument which is the program name */
+
ERR(str_append_printf(str,
"programmed fluid '%s': lib='%s', it is medium %u)",
str_cget(&f->name), str_cget(&f->prog_name), f->fluid_id));
- if(f->argc > 0) {
+
+ if(f->argc > 1) {
size_t i;
ERR(str_append_printf(str, ", provided arguments:\n"));
- for(i = 0; i < f->argc; i++) {
+ for(i = 1; i < f->argc; i++) {
ERR(str_append_printf(str, (i+1 == f->argc ? "\t%s" : "\t%s\n"), f->argv[i]));
}
}
diff --git a/src/stardis-fluid-prog.h b/src/stardis-fluid-prog.h
@@ -45,7 +45,6 @@ struct fluid_prog {
double (*rho)(const struct stardis_vertex*, void*);
double (*cp)(const struct stardis_vertex*, void*);
double (*temp)(const struct stardis_vertex*, void*);
- double* (*t_range)(void*, double trange[2]);
};
res_T
diff --git a/src/stardis-hbound-prog.c b/src/stardis-hbound-prog.c
@@ -85,17 +85,20 @@ str_print_h_boundary_prog
res_T res = RES_OK;
const struct h_boundary_prog* b;
ASSERT(str && desc && DESC_IS_H(desc));
+
b = desc->d.h_boundary_prog;
+ ASSERT(b->argc >= 1); /* At least one argument which is the program name */
+
ERR(str_append_printf(str,
"programmed H boundary for %s '%s': lib='%s', "
"(using medium %u as external medium)",
(desc->type == DESC_BOUND_H_FOR_SOLID_PROG ? "solid" : "fluid"),
str_cget(&b->name), str_cget(&b->prog_name),
b->mat_id));
- if(b->argc > 0) {
+ if(b->argc > 1) {
size_t i;
ERR(str_append_printf(str, ", provided arguments:\n"));
- for(i = 0; i < b->argc; i++) {
+ for(i = 1; i < b->argc; i++) {
ERR(str_append_printf(str, (i+1 == b->argc ? "\t%s" : "\t%s\n"), b->argv[i]));
}
}
diff --git a/src/stardis-hfbound-prog.c b/src/stardis-hfbound-prog.c
@@ -85,17 +85,20 @@ str_print_hf_boundary_prog
res_T res = RES_OK;
const struct hf_boundary_prog* b;
ASSERT(str && desc && DESC_IS_HF(desc));
+
b = desc->d.hf_boundary_prog;
+ ASSERT(b->argc >= 1); /* At least one argument which is the program name */
+
ERR(str_append_printf(str,
"programmed HF boundary for %s '%s': lib='%s', "
"(using medium %u as external medium)",
(desc->type == DESC_BOUND_HF_FOR_SOLID_PROG ? "solid" : "fluid"),
str_cget(&b->name), str_cget(&b->prog_name),
b->mat_id));
- if(b->argc > 0) {
+ if(b->argc > 1) {
size_t i;
ERR(str_append_printf(str, ", provided arguments:\n"));
- for(i = 0; i < b->argc; i++) {
+ for(i = 1; i < b->argc; i++) {
ERR(str_append_printf(str, (i+1 == b->argc ? "\t%s" : "\t%s\n"), b->argv[i]));
}
}
diff --git a/src/stardis-intface.c b/src/stardis-intface.c
@@ -126,13 +126,15 @@ intface_prog_get_temp
{
const struct intface* interface_props = sdis_data_cget(data);
struct stardis_interface_fragment f;
+ double temp;
d3_set(f.P, frag->P);
d3_set(f.Ng, frag->Ng);
d3_set(f.uv, frag->uv);
f.time = frag->time;
ASSERT(frag->side == SDIS_FRONT || frag->side == SDIS_BACK);
f.side = (frag->side == SDIS_FRONT) ? FRONT : BACK;
- return interface_props->get_temp(&f, interface_props->prog_data);
+ temp = interface_props->get_temp(&f, interface_props->prog_data);
+ return STARDIS_TEMPERATURE_IS_KNOWN(temp) ? temp : SDIS_TEMPERATURE_NONE;
}
static double
@@ -142,13 +144,15 @@ intface_prog_get_flux
{
const struct intface* interface_props = sdis_data_cget(data);
struct stardis_interface_fragment f;
+ double flux;
d3_set(f.P, frag->P);
d3_set(f.Ng, frag->Ng);
d3_set(f.uv, frag->uv);
f.time = frag->time;
ASSERT(frag->side == SDIS_FRONT || frag->side == SDIS_BACK);
f.side = (frag->side == SDIS_FRONT) ? FRONT : BACK;
- return interface_props->get_flux(&f, interface_props->prog_data);
+ flux = interface_props->get_flux(&f, interface_props->prog_data);
+ return flux != STARDIS_FLUX_NONE ? flux : SDIS_FLUX_NONE;
}
static double
@@ -170,39 +174,39 @@ intface_prog_get_hc
static double
intface_prog_get_emissivity
(const struct sdis_interface_fragment* frag,
- const unsigned source_id,
+ const unsigned src_id,
struct sdis_data* data)
{
const struct intface* interface_props = sdis_data_cget(data);
struct stardis_interface_fragment f;
- (void)source_id;
+ unsigned id;
d3_set(f.P, frag->P);
d3_set(f.Ng, frag->Ng);
d3_set(f.uv, frag->uv);
f.time = frag->time;
ASSERT(frag->side == SDIS_FRONT || frag->side == SDIS_BACK);
f.side = (frag->side == SDIS_FRONT) ? FRONT : BACK;
- return interface_props->get_emissivity
- (&f, source_id, interface_props->prog_data);
+ id = src_id != SDIS_INTERN_SOURCE_ID ? src_id : STARDIS_INTERN_SOURCE_ID;
+ return interface_props->get_emissivity(&f, id, interface_props->prog_data);
}
static double
intface_prog_get_alpha
(const struct sdis_interface_fragment* frag,
- const unsigned source_id,
+ const unsigned src_id,
struct sdis_data* data)
{
const struct intface* interface_props = sdis_data_cget(data);
struct stardis_interface_fragment f;
- (void)source_id;
+ unsigned id;
d3_set(f.P, frag->P);
d3_set(f.Ng, frag->Ng);
d3_set(f.uv, frag->uv);
f.time = frag->time;
ASSERT(frag->side == SDIS_FRONT || frag->side == SDIS_BACK);
f.side = (frag->side == SDIS_FRONT) ? FRONT : BACK;
- return interface_props->get_alpha
- (&f, source_id, interface_props->prog_data);
+ id = src_id != SDIS_INTERN_SOURCE_ID ? src_id : STARDIS_INTERN_SOURCE_ID;
+ return interface_props->get_alpha(&f, id, interface_props->prog_data);
}
static double
@@ -212,13 +216,15 @@ intface_prog_get_ref_temp
{
const struct intface* interface_props = sdis_data_cget(data);
struct stardis_interface_fragment f;
+ double temp;
d3_set(f.P, frag->P);
d3_set(f.Ng, frag->Ng);
d3_set(f.uv, frag->uv);
f.time = frag->time;
ASSERT(frag->side == SDIS_FRONT || frag->side == SDIS_BACK);
f.side = (frag->side == SDIS_FRONT) ? FRONT : BACK;
- return interface_props->get_ref_temp(&f, interface_props->prog_data);
+ temp = interface_props->get_ref_temp(&f, interface_props->prog_data);
+ return STARDIS_TEMPERATURE_IS_KNOWN(temp) ? temp : SDIS_TEMPERATURE_NONE;
}
static double
@@ -554,8 +560,12 @@ create_intface
fluid_side_shader->emissivity = interface_get_emissivity;
interface_props->emissivity = 1;
ASSERT(SDIS_TEMPERATURE_IS_KNOWN(intface->d.t_boundary->imposed_temperature));
- interface_props->imposed_temperature
- = intface->d.t_boundary->imposed_temperature;
+ interface_props->imposed_temperature = intface->d.t_boundary->imposed_temperature;
+ /* Temporarily set the reference temperature to the set temperature.
+ * TODO use a different reference temperature when the file format is
+ * updated to allow explicit definition by the user. */
+ fluid_side_shader->reference_temperature = interface_get_ref_temperature;
+ interface_props->ref_temperature = intface->d.t_boundary->imposed_temperature;
break;
case DESC_BOUND_T_FOR_SOLID_PROG:
if(sdis_medium_get_type(def_medium) != SDIS_SOLID) {
@@ -586,6 +596,10 @@ create_intface
interface_props->get_emissivity = emissivity_1;
interface_props->get_temp = intface->d.t_boundary_prog->temperature;
interface_props->prog_data = intface->d.t_boundary_prog->prog_data;
+ /* Temporarily set the reference temperature to the set temperature.
+ * TODO use a different reference temperature when the file format is
+ * updated to allow explicit definition by the user. */
+ fluid_side_shader->reference_temperature = intface_prog_get_temp;
break;
case DESC_BOUND_F_FOR_SOLID:
if(sdis_medium_get_type(def_medium) != SDIS_SOLID) {
diff --git a/src/stardis-parsing.c b/src/stardis-parsing.c
@@ -443,8 +443,6 @@ process_h
if(res == RES_OK) res = RES_BAD_ARG;
goto end;
}
- stardis->t_range[0] = MMIN(stardis->t_range[0], h_boundary->imposed_temperature);
- stardis->t_range[1] = MMAX(stardis->t_range[1], h_boundary->imposed_temperature);
if(type == DESC_BOUND_H_FOR_FLUID)
ERR(get_dummy_solid_id(stardis, &h_boundary->mat_id));
@@ -568,8 +566,6 @@ process_hf
if(res == RES_OK) res = RES_BAD_ARG;
goto end;
}
- stardis->t_range[0] = MMIN(stardis->t_range[0], hf_boundary->imposed_temperature);
- stardis->t_range[1] = MMAX(stardis->t_range[1], hf_boundary->imposed_temperature);
ASSERT(type == DESC_BOUND_HF_FOR_SOLID);
ERR(init_fluid(stardis->allocator, &fluid));
@@ -600,55 +596,54 @@ error:
static res_T
set_argc_argv
(struct mem_allocator* allocator,
- size_t* argc,
- char** argv[],
+ const char* prog_name, /* First argument to copy in argv[0] */
+ size_t* out_argc,
+ char** out_argv[],
const wordexp_t* pwordexp,
size_t idx)
{
+ char** argv = NULL;
+ size_t argc;
size_t i, n;
res_T res = RES_OK;
- ASSERT(argc && argv && pwordexp);
- *argv = NULL;
+ ASSERT(prog_name && out_argc && out_argv && pwordexp);
if(pwordexp->we_wordc < idx) {
res = RES_BAD_ARG;
goto error;
}
- *argc = pwordexp->we_wordc - idx;
- /* Review: why allocate an extra argument? In fact, it's necessary because
- * this function is called even if there are no arguments to analyze. In this
- * case, allocation would fail, as the size to be allocated would be zero.
- * This +1 therefore guarantees that at least one element will be allocated.
- * But this could be eliminated by checking that there are no arguments
- * (argc==0) and, if necessary, returning before any allocation.
- *
- * Nevertheless, this extra argument makes sense. It should be the first
- * argument and contain the program name. In this way, the argument list would
- * respect the C convention for declaring an argument list. And so, anyone
- * could use the getopt analysis function without having to declare a dummy
- * argument as the program's first parameter */
- *argv = MEM_CALLOC(allocator, 1 + *argc, sizeof(char *));
- if(*argv == NULL) {
- res = RES_MEM_ERR;
- goto error;
- }
- for(i = idx, n = 0; i < pwordexp->we_wordc; i++, n++) {
- (*argv)[n] = MEM_CALLOC(allocator, 1, 1 + strlen(pwordexp->we_wordv[i]));
- if((*argv)[n] == NULL) {
- res = RES_MEM_ERR;
- goto error;
- }
- strcpy((*argv)[n], pwordexp->we_wordv[i]); /* size is adequate */
+
+ /* Allocate an additional argument to store the program name as the first
+ * argument. This is not only useful information, but also respects the C
+ * convention for declaring a list of arguments. So anyone can use the
+ * standard getopt function to parse input arguments*/
+ argc = pwordexp->we_wordc - idx + 1/*program name*/;
+ argv = MEM_CALLOC(allocator, argc, sizeof(char*));
+ if(argv == NULL) { res = RES_MEM_ERR; goto error; }
+
+ #define STRDUP(Dst, Src) { \
+ (Dst) = MEM_CALLOC(allocator, 1, 1 + strlen(Src)); \
+ if((Dst) == NULL) { res = RES_MEM_ERR; goto error; } \
+ strcpy((Dst), (Src)); /* size is adequate */ \
+ } (void)0
+ STRDUP(argv[0], prog_name);
+ for(i = idx, n = 1; i < pwordexp->we_wordc; i++, n++) {
+ STRDUP(argv[n], pwordexp->we_wordv[i]);
}
+ #undef STRDUP
+
end:
+ *out_argc = argc;
+ *out_argv = argv;
return res;
error:
- if(*argv) {
- for(i = 0; i < *argc; i++)
- if((*argv)[i]) MEM_RM(allocator, (*argv)[i]);
- MEM_RM(allocator, *argv);
+ if(argv) {
+ FOR_EACH(i, 0, argc) if(argv[i]) MEM_RM(allocator, argv[i]);
+ MEM_RM(allocator, argv);
}
+ argc = 0;
+ argv = NULL;
goto end;
}
@@ -798,8 +793,8 @@ process_program
}
/* store the end of line as args for custom init */
- ERR(set_argc_argv(stardis->allocator, &program->argc, &program->argv,
- pwordexp, idx));
+ ERR(set_argc_argv(stardis->allocator, str_cget(&program->name),
+ &program->argc, &program->argv, pwordexp, idx));
if(program->create) {
/* create and init custom data */
struct stardis_program_context ctx;
@@ -813,7 +808,7 @@ process_program
FATAL("error:" STR(__FILE__) ":" STR(__LINE__)": Invalid type.\n");
}
CREATE_DESC_DATA_BASE(program, LIST_ARG2(program->argc, program->argv));
- } else if(program->argc != 0) {
+ } else if(program->argc != 1) {
logger_print(stardis->logger, LOG_ERROR,
"Library '%s' has no custom data management functions but has arguments:\n",
lib_name);
@@ -893,8 +888,8 @@ process_h_prog
ERR(read_sides_and_files(stardis, 1, (unsigned)sz, pwordexp, &idx));
/* store the end of line as args for custom init */
- ERR(set_argc_argv(stardis->allocator, &h_boundary_prog->argc,
- &h_boundary_prog->argv, pwordexp, idx));
+ ERR(set_argc_argv(stardis->allocator, str_cget(&h_boundary_prog->name),
+ &h_boundary_prog->argc, &h_boundary_prog->argv, pwordexp, idx));
/* get the user-defined functions from the library */
ERR(get_prog_common(lib_name, stardis, &h_boundary_prog->program,
&h_boundary_prog->create, &h_boundary_prog->release));
@@ -914,8 +909,10 @@ process_h_prog
CREATE_DESC_DATA(h_boundary_prog);
h_boundary_prog->t_range(h_boundary_prog->prog_data, h_bound_t_range);
- stardis->t_range[0] = MMIN(stardis->t_range[0], h_bound_t_range[0]);
- stardis->t_range[1] = MMAX(stardis->t_range[1], h_bound_t_range[1]);
+ if(STARDIS_TEMPERATURE_IS_KNOWN(h_bound_t_range[0]))
+ stardis->t_range[0] = MMIN(stardis->t_range[0], h_bound_t_range[0]);
+ if(STARDIS_TEMPERATURE_IS_KNOWN(h_bound_t_range[1]))
+ stardis->t_range[1] = MMAX(stardis->t_range[1], h_bound_t_range[1]);
/* create the media behind the interface */
if(type == DESC_BOUND_H_FOR_FLUID_PROG) {
@@ -992,8 +989,8 @@ process_hf_prog
ERR(read_sides_and_files(stardis, 1, (unsigned)sz, pwordexp, &idx));
/* store the end of line as args for custom init */
- ERR(set_argc_argv(stardis->allocator, &hf_boundary_prog->argc,
- &hf_boundary_prog->argv, pwordexp, idx));
+ ERR(set_argc_argv(stardis->allocator, str_cget(&hf_boundary_prog->name),
+ &hf_boundary_prog->argc, &hf_boundary_prog->argv, pwordexp, idx));
/* get the user-defined functions from the library */
ERR(get_prog_common(lib_name, stardis, &hf_boundary_prog->program,
&hf_boundary_prog->create, &hf_boundary_prog->release));
@@ -1010,8 +1007,10 @@ process_hf_prog
CREATE_DESC_DATA(hf_boundary_prog);
hf_boundary_prog->t_range(hf_boundary_prog->prog_data, hf_bound_t_range);
- stardis->t_range[0] = MMIN(stardis->t_range[0], hf_bound_t_range[0]);
- stardis->t_range[1] = MMAX(stardis->t_range[1], hf_bound_t_range[1]);
+ if(STARDIS_TEMPERATURE_IS_KNOWN(hf_bound_t_range[0]))
+ stardis->t_range[0] = MMIN(stardis->t_range[0], hf_bound_t_range[0]);
+ if(STARDIS_TEMPERATURE_IS_KNOWN(hf_bound_t_range[1]))
+ stardis->t_range[1] = MMAX(stardis->t_range[1], hf_bound_t_range[1]);
/* create the media behind the interface */
ERR(init_fluid_prog(stardis->allocator, &fluid_prog));
@@ -1079,6 +1078,10 @@ process_t
if(res == RES_OK) res = RES_BAD_ARG;
goto end;
}
+
+ /* Temporarily use the set temperature as a reference temperature.
+ * TODO use a different reference temperature when the file format is updated
+ * to allow explicit definition by the user. */
stardis->t_range[0] = MMIN(stardis->t_range[0], t_boundary->imposed_temperature);
stardis->t_range[1] = MMAX(stardis->t_range[1], t_boundary->imposed_temperature);
@@ -1138,8 +1141,8 @@ process_t_prog
ERR(read_sides_and_files(stardis, 1, (unsigned)sz, pwordexp, &idx));
/* store the end of line as args for custom init */
- ERR(set_argc_argv(stardis->allocator, &t_boundary_prog->argc,
- &t_boundary_prog->argv, pwordexp, idx));
+ ERR(set_argc_argv(stardis->allocator, str_cget(&t_boundary_prog->name),
+ &t_boundary_prog->argc, &t_boundary_prog->argv, pwordexp, idx));
/* get the user-defined functions from the library */
ERR(get_prog_common(lib_name, stardis, &t_boundary_prog->program,
&t_boundary_prog->create, &t_boundary_prog->release));
@@ -1150,8 +1153,10 @@ process_t_prog
CREATE_DESC_DATA(t_boundary_prog);
t_boundary_prog->t_range(t_boundary_prog->prog_data, t_bound_t_range);
- stardis->t_range[0] = MMIN(stardis->t_range[0], t_bound_t_range[0]);
- stardis->t_range[1] = MMAX(stardis->t_range[1], t_bound_t_range[1]);
+ if(STARDIS_TEMPERATURE_IS_KNOWN(t_bound_t_range[0]))
+ stardis->t_range[0] = MMIN(stardis->t_range[0], t_bound_t_range[0]);
+ if(STARDIS_TEMPERATURE_IS_KNOWN(t_bound_t_range[1]))
+ stardis->t_range[1] = MMAX(stardis->t_range[1], t_bound_t_range[1]);
end:
return res;
@@ -1268,8 +1273,8 @@ process_flx_prog
ERR(read_sides_and_files(stardis, 1, (unsigned)sz, pwordexp, &idx));
/* store the end of line as args for custom init */
- ERR(set_argc_argv(stardis->allocator, &f_boundary_prog->argc,
- &f_boundary_prog->argv, pwordexp, idx));
+ ERR(set_argc_argv(stardis->allocator, str_cget(&f_boundary_prog->name),
+ &f_boundary_prog->argc, &f_boundary_prog->argv, pwordexp, idx));
/* get the user-defined functions from the library */
ERR(get_prog_common(lib_name, stardis, &f_boundary_prog->program,
&f_boundary_prog->create, &f_boundary_prog->release));
@@ -1414,8 +1419,8 @@ process_sfc_prog
ERR(read_sides_and_files(stardis, 1, (unsigned)sz, pwordexp, &idx));
/* store the end of line as args for custom init */
- ERR(set_argc_argv(stardis->allocator, &sf_connect_prog->argc,
- &sf_connect_prog->argv, pwordexp, idx));
+ ERR(set_argc_argv(stardis->allocator, str_cget(&sf_connect_prog->name),
+ &sf_connect_prog->argc, &sf_connect_prog->argv, pwordexp, idx));
/* get the user-defined functions from the library */
ERR(get_prog_common(lib_name, stardis, &sf_connect_prog->program,
&sf_connect_prog->create, &sf_connect_prog->release));
@@ -1430,8 +1435,10 @@ process_sfc_prog
CREATE_DESC_DATA(sf_connect_prog);
sf_connect_prog->t_range(sf_connect_prog->prog_data, sf_t_range);
- stardis->t_range[0] = MMIN(stardis->t_range[0], sf_t_range[0]);
- stardis->t_range[1] = MMAX(stardis->t_range[1], sf_t_range[1]);
+ if(STARDIS_TEMPERATURE_IS_KNOWN(sf_t_range[0]))
+ stardis->t_range[0] = MMIN(stardis->t_range[0], sf_t_range[0]);
+ if(STARDIS_TEMPERATURE_IS_KNOWN(sf_t_range[1]))
+ stardis->t_range[1] = MMAX(stardis->t_range[1], sf_t_range[1]);
end:
return res;
@@ -1544,8 +1551,8 @@ process_ssc_prog
ERR(read_sides_and_files(stardis, 1, (unsigned)sz, pwordexp, &idx));
/* store the end of line as args for custom init */
- ERR(set_argc_argv(stardis->allocator, &ss_connect_prog->argc,
- &ss_connect_prog->argv, pwordexp, idx));
+ ERR(set_argc_argv(stardis->allocator, str_cget(&ss_connect_prog->name),
+ &ss_connect_prog->argc, &ss_connect_prog->argv, pwordexp, idx));
/* get the user-defined functions from the library */
ERR(get_prog_common(lib_name, stardis, &ss_connect_prog->program,
&ss_connect_prog->create, &ss_connect_prog->release));
@@ -1706,8 +1713,6 @@ process_solid
if(res == RES_OK) res = RES_BAD_ARG;
goto end;
}
- stardis->t_range[0] = MMIN(stardis->t_range[0], solid->tinit);
- stardis->t_range[1] = MMAX(stardis->t_range[1], solid->tinit);
ERR(read_imposed_temperature(stardis, &solid->imposed_temperature,
pwordexp, &idx));
if(SDIS_TEMPERATURE_IS_KNOWN(solid->imposed_temperature)
@@ -1720,10 +1725,7 @@ process_solid
res = RES_BAD_ARG;
goto end;
}
- if(SDIS_TEMPERATURE_IS_KNOWN(solid->imposed_temperature))
- stardis->t_range[0] = MMIN(stardis->t_range[0], solid->imposed_temperature);
- stardis->t_range[1] = MMAX(stardis->t_range[1], solid->imposed_temperature);
CHK_ARG(idx, "volumic power");
res = cstr_to_double(arg, &solid->vpower);
if(res != RES_OK) {
@@ -1760,7 +1762,6 @@ process_solid_prog
char* arg = NULL;
struct description* desc;
const char *lib_name, *desc_name;
- double solid_t_range[2] = {DBL_MAX, -DBL_MAX};
size_t sz;
struct solid_prog* solid_prog;
struct stardis_description_create_context ctx;
@@ -1798,8 +1799,8 @@ process_solid_prog
ERR(read_sides_and_files(stardis, 0, (unsigned)sz, pwordexp, &idx));
/* store the end of line as args for custom init */
- ERR(set_argc_argv(stardis->allocator, &solid_prog->argc, &solid_prog->argv,
- pwordexp, idx));
+ ERR(set_argc_argv(stardis->allocator, str_cget(&solid_prog->name),
+ &solid_prog->argc, &solid_prog->argv, pwordexp, idx));
/* get the user-defined functions from the library */
ERR(get_prog_common(lib_name, stardis, &solid_prog->program,
&solid_prog->create, &solid_prog->release));
@@ -1809,15 +1810,14 @@ process_solid_prog
GET_LIB_SYMBOL(solid_prog, delta, stardis_delta_solid);
GET_LIB_SYMBOL(solid_prog, temp, stardis_medium_temperature);
GET_LIB_SYMBOL(solid_prog, vpower, stardis_volumic_power);
- GET_LIB_SYMBOL(solid_prog, t_range, stardis_t_range);
+
+ GET_LIB_SYMBOL_BASE(&solid_prog->sample_path, solid_prog->program->lib_handle,
+ stardis_sample_conductive_path, 1);
+
/* create and init custom data */
ctx.name = desc_name;
CREATE_DESC_DATA(solid_prog);
- solid_prog->t_range(solid_prog->prog_data, solid_t_range);
- stardis->t_range[0] = MMIN(stardis->t_range[0], solid_t_range[0]);
- stardis->t_range[1] = MMAX(stardis->t_range[1], solid_t_range[1]);
-
ERR(create_solver_solid_prog(stardis, solid_prog));
end:
@@ -1889,8 +1889,6 @@ process_fluid
if(res == RES_OK) res = RES_BAD_ARG;
goto end;
}
- stardis->t_range[0] = MMIN(stardis->t_range[0], fluid->tinit);
- stardis->t_range[1] = MMAX(stardis->t_range[1], fluid->tinit);
ERR(read_imposed_temperature(stardis, &fluid->imposed_temperature,
pwordexp, &idx));
if(SDIS_TEMPERATURE_IS_KNOWN(fluid->imposed_temperature)
@@ -1902,9 +1900,6 @@ process_fluid
res = RES_BAD_ARG;
goto end;
}
- if(SDIS_TEMPERATURE_IS_KNOWN(fluid->imposed_temperature))
- stardis->t_range[0] = MMIN(stardis->t_range[0], fluid->imposed_temperature);
- stardis->t_range[1] = MMAX(stardis->t_range[1], fluid->imposed_temperature);
ERR(create_solver_fluid(stardis, fluid));
@@ -1925,7 +1920,6 @@ process_fluid_prog
char* arg = NULL;
struct description* desc;
const char *lib_name, *desc_name;
- double fluid_t_range[2] = {DBL_MAX, -DBL_MAX};
size_t sz;
struct fluid_prog* fluid_prog;
struct stardis_description_create_context ctx;
@@ -1963,23 +1957,18 @@ process_fluid_prog
ERR(read_sides_and_files(stardis, 0, (unsigned)sz, pwordexp, &idx));
/* store the end of line as args for custom init */
- ERR(set_argc_argv(stardis->allocator, &fluid_prog->argc, &fluid_prog->argv,
- pwordexp, idx));
+ ERR(set_argc_argv(stardis->allocator, str_cget(&fluid_prog->name),
+ &fluid_prog->argc, &fluid_prog->argv, pwordexp, idx));
/* get the user-defined functions from the library */
ERR(get_prog_common(lib_name, stardis, &fluid_prog->program,
&fluid_prog->create, &fluid_prog->release));
GET_LIB_SYMBOL(fluid_prog, rho, stardis_volumic_mass);
GET_LIB_SYMBOL(fluid_prog, cp, stardis_calorific_capacity);
GET_LIB_SYMBOL(fluid_prog, temp, stardis_medium_temperature);
- GET_LIB_SYMBOL(fluid_prog, t_range, stardis_t_range);
/* create and init custom data */
ctx.name = desc_name;
CREATE_DESC_DATA(fluid_prog);
- fluid_prog->t_range(fluid_prog->prog_data, fluid_t_range);
- stardis->t_range[0] = MMIN(stardis->t_range[0], fluid_t_range[0]);
- stardis->t_range[1] = MMAX(stardis->t_range[1], fluid_t_range[1]);
-
ERR(create_solver_fluid_prog(stardis, fluid_prog));
end:
@@ -2105,7 +2094,7 @@ process_radiative_prog(struct stardis* stardis, wordexp_t* pwordexp)
lib_name = arg;
if(idx < pwordexp->we_wordc
- && strcasecmp(pwordexp->we_wordv[idx], "PROG_PARAMS")) {
+ && strcasecmp(pwordexp->we_wordv[idx++], "PROG_PARAMS")) {
logger_print(stardis->logger, LOG_ERROR,
"Expecting PROG_PARAMS keyword while parsing `%s'.\n",
pwordexp->we_wordv[idx]);
@@ -2113,8 +2102,8 @@ process_radiative_prog(struct stardis* stardis, wordexp_t* pwordexp)
goto error;
}
- ERR(set_argc_argv
- (stardis->allocator, &radenv->argc, &radenv->argv, pwordexp, idx));
+ ERR(set_argc_argv(stardis->allocator, str_cget(&radenv->prog_name),
+ &radenv->argc, &radenv->argv, pwordexp, idx));
ERR(get_prog_common
(lib_name, stardis, &radenv->program, &radenv->create, &radenv->release));
GET_LIB_SYMBOL(radenv, temperature,
@@ -2135,8 +2124,10 @@ process_radiative_prog(struct stardis* stardis, wordexp_t* pwordexp)
}
radenv->t_range(radenv->data, radenv_t_range);
- stardis->t_range[0] = MMIN(stardis->t_range[0], radenv_t_range[0]);
- stardis->t_range[1] = MMAX(stardis->t_range[1], radenv_t_range[1]);
+ if(STARDIS_TEMPERATURE_IS_KNOWN(radenv_t_range[0]))
+ stardis->t_range[0] = MMIN(stardis->t_range[0], radenv_t_range[0]);
+ if(STARDIS_TEMPERATURE_IS_KNOWN(radenv_t_range[1]))
+ stardis->t_range[1] = MMAX(stardis->t_range[1], radenv_t_range[1]);
exit:
return res;
@@ -2258,7 +2249,7 @@ process_spherical_source_prog(struct stardis* stardis, wordexp_t* pwordexp)
lib_name = arg;
if(idx < pwordexp->we_wordc
- && strcasecmp(pwordexp->we_wordv[idx], "PROG_PARAMS")) {
+ && strcasecmp(pwordexp->we_wordv[idx++], "PROG_PARAMS")) {
logger_print(stardis->logger, LOG_ERROR,
"Expecting PROG_PARAMS keyword while parsing `%s'.\n",
pwordexp->we_wordv[idx]);
@@ -2266,7 +2257,8 @@ process_spherical_source_prog(struct stardis* stardis, wordexp_t* pwordexp)
goto error;
}
- ERR(set_argc_argv(stardis->allocator, &src->argc, &src->argv, pwordexp, idx));
+ ERR(set_argc_argv(stardis->allocator, str_cget(&src->prog_name), &src->argc,
+ &src->argv, pwordexp, idx));
ERR(get_prog_common(lib_name, stardis, &src->program, &src->create, &src->release));
GET_LIB_SYMBOL(src, position, stardis_spherical_source_position);
GET_LIB_SYMBOL(src, power, stardis_spherical_source_power);
@@ -2553,7 +2545,7 @@ exp_error:
stardis->t_range[1] = MMAX(stardis->t_range[1], trad_ref);
}
logger_print(stardis->logger, LOG_OUTPUT,
- "System T range is [%g %g]\n", SPLIT2(stardis->t_range));
+ "System Tref range is [%g %g]\n", SPLIT2(stardis->t_range));
logger_print(stardis->logger, LOG_OUTPUT,
"Picard order is %u\n", stardis->picard_order);
diff --git a/src/stardis-prog-properties.h.in b/src/stardis-prog-properties.h.in
@@ -1,4 +1,4 @@
-/* Copyright (C) 2018-2022 |Meso|Star> (contact@meso-star.com)
+/* Copyright (C) 2018-2024 |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 Lesser General Public
@@ -10,8 +10,9 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program. If not, see
+ * <http://www.gnu.org/licenses/>. */
#ifndef STARDIS_PROG_H__
#define STARDIS_PROG_H__
@@ -32,12 +33,27 @@
#define STARDIS_API extern
#endif
-/*****************************************************************************/
-/* API types. */
-/* The various functions defining programmed descriptions receive arguments */
-/* of the following types when called from the stardis simulation. */
-/*****************************************************************************/
+/* Constants defining that no power density/imposed flux is defined */
+#define STARDIS_VOLUMIC_POWER_NONE DBL_MAX
+#define STARDIS_FLUX_NONE DBL_MAX
+/* Syntactic sugar used to define whether a temperature is known or not */
+#define STARDIS_TEMPERATURE_NONE (-(DBL_MAX+DBL_MAX)*0) /* NAN */
+#define STARDIS_TEMPERATURE_IS_KNOWN(Temp) (Temp==Temp)
+#define STARDIS_TEMPERATURE_IS_UNKNOWN(Temp) (Temp!=Temp)
+
+/* Indentifier of the internal source of radiation */
+#define STARDIS_INTERN_SOURCE_ID UINT_MAX
+
+/* Forward declaration of external data types */
+struct sdis_scene;
+struct ssp_rng;
+
+/*******************************************************************************
+ * API types.
+ * The various functions defining programmed descriptions receive arguments
+ * of the following types when called from the stardis simulation.
+ ******************************************************************************/
struct stardis_vertex {
double P[3]; /* World space position */
double time; /* "Time" of the vertex */
@@ -79,15 +95,51 @@ struct stardis_description_create_context {
const char* name; /* Description name */
};
+struct stardis_triangle {
+ double vtx0[3];
+ double vtx1[3];
+ double vtx2[3];
+};
+#define STARDIS_TRIANGLE_NULL__ {{0,0,0}, {0,0,0}, {0,0,0}}
+static const struct stardis_triangle STARDIS_TRIANGLE_NULL =
+ STARDIS_TRIANGLE_NULL__;
+
+/* Helper macro that check if the triangle is NULL */
+#define STARDIS_TRIANGLE_NONE(T) \
+ ( (T)->vtx0[0] == 0 && (T)->vtx0[1] == 0 && (T)->vtx0[2] == 0 \
+ && (T)->vtx1[0] == 0 && (T)->vtx1[1] == 0 && (T)->vtx1[2] == 0 \
+ && (T)->vtx2[0] == 0 && (T)->vtx2[1] == 0 && (T)->vtx2[2] == 0)
+
+/* A sampled path */
+struct stardis_path {
+ struct stardis_vertex vtx; /* Current position and time */
+
+ /* Triangle intersected by the path. When defined, the path is on a border */
+ struct stardis_triangle tri;
+
+ double weight; /* Monte Carlo weight update along the path */
+
+ /* Define whether the path has reached a boundary conduction in time/space */
+ int at_limit;
+};
+#define STARDIS_PATH_NULL__ { \
+ STARDIS_VERTEX_NULL__, \
+ STARDIS_TRIANGLE_NULL__, \
+ 0, /* MC weight */ \
+ 0 /* At limit */ \
+}
+static const struct stardis_path STARDIS_PATH_NULL =
+ STARDIS_PATH_NULL__;
+
#ifdef __cplusplus
extern "C" {
#endif
-/******************************************************************************/
-/* Optional functions for any programmed library. */
-/* Either all 3 or none of the 3 following functions must be defined. */
-/* If a libray doesn't need its own data, just let these functions undefined. */
-/******************************************************************************/
+/*******************************************************************************
+ * Optional functions for any programmed library.
+ * Either all 3 or none of the 3 following functions must be defined.
+ * If a libray doesn't need its own data, just let these functions undefined.
+ ******************************************************************************/
/* Create the data attached to a given libray.
* A NULL result is interpreted as an error and ends the program.
@@ -121,9 +173,9 @@ STARDIS_API void
stardis_release_library_data
(void* lib_data);
-/******************************************************************************/
-/* Mandatory functions for any programmed description regardless of its type. */
-/******************************************************************************/
+/*******************************************************************************
+ * Mandatory functions for any programmed description regardless of its type.
+ ******************************************************************************/
/* Create the data attached to a given description.
* A NULL result is interpreted as an error and ends the program.
@@ -168,15 +220,9 @@ STARDIS_API const char*
get_license_text
(void* data);
-/*****************************************************************************/
-/* Additional mandatory function declarations (sorted by description type). */
-/* Some functions appear multiple times as they are part of more than one */
-/* description requirement. */
-/*****************************************************************************/
-
-/*********************************************************/
-/* Additional mandatory functions for a programmed solid */
-/*********************************************************/
+/*******************************************************************************
+ * Mandatory functions for a solid
+ ******************************************************************************/
/* Returns the calorific capacity at a given vertex.
* This functions is called at every vertex of every path of the computation
@@ -233,18 +279,22 @@ stardis_medium_temperature
(const struct stardis_vertex* vtx,
void* data);
-/* Computes the expected temperature range for this solid.
- * This functions is called once when initializing the computation.
- * data is the pointer returned by stardis_create_data for this solid.
- * Returns its modified range argument. */
-STARDIS_API double*
-stardis_t_range
- (void* data,
- double range[2]);
+/*******************************************************************************
+ * Optional function for a solid
+ ******************************************************************************/
-/*********************************************************/
-/* Additional mandatory functions for a programmed fluid */
-/*********************************************************/
+/* Function used to sample a conductive path. When defined, it is no
+ * longer Stardis that samples the path, but the user via this function */
+STARDIS_API int /* Error code */
+stardis_sample_conductive_path
+ (struct sdis_scene* scn,
+ struct ssp_rng* rng,
+ struct stardis_path* path,
+ void* data);
+
+/*******************************************************************************
+ * Mandatory functions for a fluid
+ ******************************************************************************/
/* Returns the calorific capacity at a given vertex.
* This functions is called at every vertex of every path of the computation
@@ -274,18 +324,9 @@ stardis_medium_temperature
(const struct stardis_vertex* vtx,
void* data);
-/* Computes the expected temperature range for this fluid.
- * This functions is called once when initializing the computation.
- * data is the pointer returned by stardis_create_data for this fluid.
- * Returns its modified range argument. */
-STARDIS_API double*
-stardis_t_range
- (void* data,
- double range[2]);
-
-/**************************************************************************/
-/* Additional mandatory functions for a programmed H boundary for a fluid */
-/**************************************************************************/
+/*******************************************************************************
+ * Mandatory functions for a H boundary for a fluid
+ ******************************************************************************/
/* Returns the boundary temperature at a given fragment.
* This functions is called every time a path of the computation reaches
@@ -352,9 +393,9 @@ stardis_t_range
(void* data,
double range[2]);
-/**************************************************************************/
-/* Additional mandatory functions for a programmed H boundary for a solid */
-/**************************************************************************/
+/*******************************************************************************
+ * Mandatory functions for a H boundary for a solid
+ ******************************************************************************/
/* Returns the emissivity at a given fragment.
* This functions is called every time a path of the computation reaches
@@ -423,9 +464,9 @@ stardis_t_range
(void* data,
double range[2]);
-/**************************************************************/
-/* Additional mandatory functions for a programmed T boundary */
-/**************************************************************/
+/*******************************************************************************
+ * Mandatory functions for a T boundary
+ ******************************************************************************/
/* Returns the boundary temperature at a given fragment.
* This functions is called every time a path of the computation reaches
@@ -445,9 +486,9 @@ stardis_t_range
(void* data,
double range[2]);
-/****************************************************************/
-/* Additional mandatory functions for a programmed F+H boundary */
-/****************************************************************/
+/*******************************************************************************
+ * Mandatory functions for a F+H boundary
+ ******************************************************************************/
/* Returns the emissivity at a given fragment.
* This functions is called every time a path of the computation reaches
@@ -525,9 +566,9 @@ stardis_t_range
(void* data,
double range[2]);
-/**************************************************************/
-/* Additional mandatory functions for a programmed F boundary */
-/**************************************************************/
+/*******************************************************************************
+ * Mandatory functions for a F boundary
+ ******************************************************************************/
/* Returns the flux at the boundary at a given fragment.
* This functions is called every time a path of the computation reaches
@@ -538,9 +579,9 @@ stardis_boundary_flux
(const struct stardis_interface_fragment* frag,
void* data);
-/**************************************************************************/
-/* Additional mandatory functions for a programmed Solid-Solid connection */
-/**************************************************************************/
+/*******************************************************************************
+ * Mandatory functions for a solid-solid connection
+ ******************************************************************************/
/* Returns the thermal contact resistance at a given fragment.
* This functions is called every time a path of the computation reaches
@@ -551,9 +592,9 @@ stardis_thermal_contact_resistance
(const struct stardis_interface_fragment* frag,
void* data);
-/**************************************************************************/
-/* Additional mandatory functions for a programmed Solid-Fluid connection */
-/**************************************************************************/
+/*******************************************************************************
+ * Mandatory functions for a solid-fluid connection
+ ******************************************************************************/
/* Returns the emissivity at a given fragment.
* This functions is called every time a path of the computation reaches
@@ -611,10 +652,10 @@ stardis_t_range
(void* data,
double range[2]);
-/******************************************************************************/
-/* Additional mandatory functions for a programmed spherical source */
-/* These functions are used to calculate the external flux at the boundaries. */
-/******************************************************************************/
+/*******************************************************************************
+ * Mandatory functions for a spherical source.
+ * These functions are used to calculate the external flux at the boundaries
+ ******************************************************************************/
/* Retrieve the position of the spherical source center.
* This function is used to calculate the external flux at the boundaries.
@@ -642,9 +683,9 @@ stardis_spherical_source_diffuse_radiance
const double dir[3],
void* data);
-/******************************************************************************/
-/* Additional mandatory functions for a programmed radiative environment */
-/******************************************************************************/
+/*******************************************************************************
+ * Mandatory functions for a radiative environment
+ ******************************************************************************/
/* Retrieve the temperature of radiative paths that reach infinity */
STARDIS_API double
diff --git a/src/stardis-program.c b/src/stardis-program.c
@@ -72,11 +72,13 @@ str_print_program
const struct program* p)
{
res_T res = RES_OK;
+ ASSERT(p->argc >= 1); /* At least one argument which is the program name */
+
ERR(str_append_printf(str, "Library %s", str_cget(&p->name)));
- if(p->argc > 0) {
+ if(p->argc > 1) {
size_t i;
ERR(str_append_printf(str, ", provided arguments:\n"));
- for(i = 0; i < p->argc; i++) {
+ for(i = 1; i < p->argc; i++) {
ERR(str_append_printf(str, (i+1 == p->argc ? "\t%s" : "\t%s\n"), p->argv[i]));
}
}
diff --git a/src/stardis-sfconnect-prog.c b/src/stardis-sfconnect-prog.c
@@ -81,13 +81,15 @@ str_print_sf_connect_prog
{
res_T res = RES_OK;
ASSERT(str && c);
+ ASSERT(c->argc >= 1); /* At least one argument which is the program name */
+
ERR(str_append_printf(str,
"programmed Solid-Fluid connection '%s': lib='%s'",
str_cget(&c->name), str_cget(&c->prog_name)));
- if(c->argc > 0) {
+ if(c->argc > 1) {
size_t i;
ERR(str_append_printf(str, ", provided arguments:\n"));
- for(i = 0; i < c->argc; i++) {
+ for(i = 1; i < c->argc; i++) {
ERR(str_append_printf(str, (i+1 == c->argc ? "\t%s" : "\t%s\n"), c->argv[i]));
}
}
diff --git a/src/stardis-solid-prog.c b/src/stardis-solid-prog.c
@@ -82,9 +82,11 @@ solid_prog_get_volumic_power
{
const struct solid_prog* const* solid_props = sdis_data_cget(data);
struct stardis_vertex v;
+ double power;
d3_set(v.P, vtx->P);
v.time = vtx->time;
- return (*solid_props)->vpower(&v, (*solid_props)->prog_data);
+ power = (*solid_props)->vpower(&v, (*solid_props)->prog_data);
+ return power != STARDIS_VOLUMIC_POWER_NONE ? power : SDIS_VOLUMIC_POWER_NONE;
}
static double
@@ -94,9 +96,56 @@ solid_prog_get_temperature
{
const struct solid_prog* const* solid_props = sdis_data_cget(data);
struct stardis_vertex v;
+ double temp;
d3_set(v.P, vtx->P);
v.time = vtx->time;
- return (*solid_props)->temp(&v, (*solid_props)->prog_data);
+ temp = (*solid_props)->temp(&v, (*solid_props)->prog_data);
+ return STARDIS_TEMPERATURE_IS_KNOWN(temp) ? temp : SDIS_TEMPERATURE_NONE;
+}
+
+static res_T
+solid_prog_sample_path
+ (struct sdis_scene* scn,
+ struct ssp_rng* rng,
+ struct sdis_path* path,
+ struct sdis_data* data)
+{
+ const struct solid_prog* const* solid_props = sdis_data_cget(data);
+ struct stardis_path p = STARDIS_PATH_NULL;
+ int err = 0;
+ res_T res = RES_OK;
+
+ d3_set(p.vtx.P, path->vtx.P);
+ p.vtx.time = path->vtx.time;
+
+ err = (*solid_props)->sample_path(scn, rng, &p, (*solid_props)->prog_data);
+ if(err) { res = RES_UNKNOWN_ERR; goto error; }
+
+ d3_set(path->vtx.P, p.vtx.P);
+ path->vtx.time = p.vtx.time;
+ path->weight = p.weight;
+ path->at_limit = p.at_limit;
+
+ if(!STARDIS_TRIANGLE_NONE(&p.tri)) {
+ struct sdis_primkey key = SDIS_PRIMKEY_NULL;
+
+ sdis_primkey_setup(&key, p.tri.vtx0, p.tri.vtx1, p.tri.vtx2);
+ res = sdis_scene_get_s3d_primitive(scn, &key, &path->prim_3d);
+
+ /* In fact, we'd like to log an error notifying us that the returned
+ * triangle doesn't exist in Stardis. But there's no easy way to retrieve
+ * the logger since the program has no reference to Stardis. This lack stems
+ * from design choices where internal data structures are not managed by
+ * reference and don't take a reference on the Stardis structure. In any
+ * case, until stardis' internal data structures have been thoroughly
+ * redesigned, we're only returning an error */
+ if(res != RES_OK) goto error;
+ }
+
+exit:
+ return res;
+error:
+ goto exit;
}
/*******************************************************************************
@@ -117,10 +166,13 @@ create_solver_solid_prog
solid_shader.calorific_capacity = solid_prog_get_calorific_capacity;
solid_shader.thermal_conductivity = solid_prog_get_thermal_conductivity;
solid_shader.volumic_mass = solid_prog_get_volumic_mass;
- solid_shader.delta= solid_prog_get_delta;
+ solid_shader.delta = solid_prog_get_delta;
solid_shader.volumic_power = solid_prog_get_volumic_power;
solid_shader.temperature = solid_prog_get_temperature;
solid_shader.t0 = stardis->initial_time;
+ if(solid_props->sample_path) {
+ solid_shader.sample_path = solid_prog_sample_path;
+ }
ERR(sdis_data_create(stardis->dev, sizeof(struct solid_prog*),
ALIGNOF(struct solid_prog*), NULL, &data));
@@ -189,13 +241,15 @@ str_print_solid_prog(struct str* str, const struct solid_prog* f)
{
res_T res = RES_OK;
ASSERT(str && f);
+ ASSERT(f->argc >= 1); /* At least one argument which is the program name */
+
ERR(str_append_printf(str,
"programmed solid '%s': lib='%s', it is medium %u)",
str_cget(&f->name), str_cget(&f->prog_name), f->solid_id));
- if(f->argc > 0) {
+ if(f->argc > 1) {
size_t i;
ERR(str_append_printf(str, ", provided arguments:\n"));
- for(i = 0; i < f->argc; i++) {
+ for(i = 1; i < f->argc; i++) {
ERR(str_append_printf(str, (i+1 == f->argc ? "\t%s" : "\t%s\n"), f->argv[i]));
}
}
diff --git a/src/stardis-solid-prog.h b/src/stardis-solid-prog.h
@@ -48,7 +48,14 @@ struct solid_prog {
double (*delta)(const struct stardis_vertex*, void*);
double (*temp)(const struct stardis_vertex*, void*);
double (*vpower)(const struct stardis_vertex*, void*);
- double* (*t_range)(void*, double trange[2]);
+
+ /* User-defined function for sampling a conductive path */
+ int
+ (*sample_path)
+ (struct sdis_scene*,
+ struct ssp_rng*,
+ struct stardis_path*,
+ void*);
};
res_T
diff --git a/src/stardis-ssconnect-prog.c b/src/stardis-ssconnect-prog.c
@@ -82,13 +82,15 @@ str_print_ss_connect_prog
{
res_T res = RES_OK;
ASSERT(str && c);
+ ASSERT(c->argc >= 1); /* At least one argument which is the program name */
+
ERR(str_append_printf(str,
"programmed Solid-Solid connection '%s': lib='%s'",
str_cget(&c->name), str_cget(&c->prog_name)));
- if(c->argc > 0) {
+ if(c->argc > 1) {
size_t i;
ERR(str_append_printf(str, ", provided arguments:\n"));
- for(i = 0; i < c->argc; i++) {
+ for(i = 1; i < c->argc; i++) {
ERR(str_append_printf(str, (i+1 == c->argc ? "\t%s" : "\t%s\n"), c->argv[i]));
}
}
diff --git a/src/stardis-tbound-prog.c b/src/stardis-tbound-prog.c
@@ -81,14 +81,16 @@ str_print_t_boundary_prog
{
res_T res = RES_OK;
ASSERT(str && b);
+ ASSERT(b->argc >= 1); /* At least one argument which is the program name */
+
ERR(str_append_printf(str,
"programmed T boundary for solid '%s': lib='%s', "
"(using medium %u as external medium)",
str_cget(&b->name), str_cget(&b->prog_name), b->mat_id));
- if(b->argc > 0) {
+ if(b->argc > 1) {
size_t i;
ERR(str_append_printf(str, ", provided arguments:\n"));
- for(i = 0; i < b->argc; i++) {
+ for(i = 1; i < b->argc; i++) {
ERR(str_append_printf(str, (i+1 == b->argc ? "\t%s" : "\t%s\n"), b->argv[i]));
}
}