stardis-solver

Solve coupled heat transfers
git clone git://git.meso-star.fr/stardis-solver.git
Log | Files | Refs | README | LICENSE

commit 10236cfaf42e46b3ec31ef93b7ee724d8753d01d
parent 4d91adfc1e42055ba3eea689c0cca3b1e5715578
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Fri, 28 Aug 2020 09:49:40 +0200

Add the sdis_green_function_create_from_stream function

Diffstat:
Msrc/sdis.h | 6++++++
Msrc/sdis_device_c.h | 2+-
Msrc/sdis_green.c | 261++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
Msrc/sdis_interface.c | 1+
Msrc/sdis_medium.c | 1+
5 files changed, 262 insertions(+), 9 deletions(-)

diff --git a/src/sdis.h b/src/sdis.h @@ -996,6 +996,12 @@ sdis_green_function_write (struct sdis_green_function* green, FILE* stream); +SDIS_API res_T +sdis_green_function_create_from_stream + (struct sdis_scene* scn, /* Scene from which the green was evaluated */ + FILE* stream, /* Stream into which the green was serialized */ + struct sdis_green_function** green); + /* Retrieve the number of valid paths used to estimate the green function. It * is actually equal to the number of successful realisations. */ SDIS_API res_T diff --git a/src/sdis_device_c.h b/src/sdis_device_c.h @@ -27,7 +27,7 @@ struct ssp_rng; struct ssp_rng_proxy; -struct name { FITEM; }; +struct name { FITEM; void* mem; }; #define FITEM_TYPE name #include <rsys/free_list.h> diff --git a/src/sdis_green.c b/src/sdis_green.c @@ -16,10 +16,11 @@ #include "sdis_device_c.h" #include "sdis_estimator_c.h" #include "sdis_green.h" +#include "sdis_interface_c.h" #include "sdis_log.h" #include "sdis_medium_c.h" #include "sdis_misc.h" -#include "sdis_interface_c.h" +#include "sdis_scene_c.h" #include <star/ssp.h> @@ -164,7 +165,7 @@ green_path_copy_and_release(struct green_path* dst, struct green_path* src) return RES_OK; } -static INLINE res_T +static res_T green_path_write(const struct green_path* path, FILE* stream) { size_t sz = 0; @@ -192,7 +193,7 @@ green_path_write(const struct green_path* path, FILE* stream) WRITE(&path->limit, 1); WRITE(&path->limit_type, 1); - /* Write miscellaneous data */ + /* Write miscellaneous data */ WRITE(&path->ilast_medium, 1); WRITE(&path->ilast_interf, 1); @@ -204,6 +205,54 @@ error: goto exit; } +static res_T +green_path_read(struct green_path* path, FILE* stream) +{ + size_t sz = 0; + res_T res = RES_OK; + ASSERT(path && stream); + + #define READ(Var, N) { \ + if(fread((Var), sizeof(*(Var)), (N), stream) != (N)) { \ + if(feof(stream)) { \ + res = RES_BAD_ARG; \ + } else if(ferror(stream)) { \ + res = RES_IO_ERR; \ + } else { \ + res = RES_UNKNOWN_ERR; \ + } \ + goto error; \ + } \ + } (void)0 + + /* Read the list of flux terms */ + READ(&sz, 1); + res = darray_flux_term_resize(&path->flux_terms, sz); + if(res != RES_OK) goto error; + READ(darray_flux_term_data_get(&path->flux_terms), sz); + + /* Read the list of power tems */ + READ(&sz, 1); + res = darray_power_term_resize(&path->power_terms, sz); + if(res != RES_OK) goto error; + READ(darray_power_term_data_get(&path->power_terms), sz); + + /* Read the limit point */ + READ(&path->limit, 1); + READ(&path->limit_type, 1); + + /* Read the miscellaneous data */ + READ(&path->ilast_medium, 1); + READ(&path->ilast_interf, 1); + + #undef READ + +exit: + return res; +error: + goto exit; +} + /* Generate the dynamic array of green paths */ #define DARRAY_NAME green_path #define DARRAY_DATA struct green_path @@ -431,9 +480,9 @@ write_media(struct sdis_green_function* green, FILE* stream) htable_medium_begin(&green->media, &it); htable_medium_end(&green->media, &it_end); while(!htable_medium_iterator_eq(&it, &it_end)) { - const unsigned id = *htable_medium_iterator_key_get(&it); + const struct sdis_medium* mdm = *htable_medium_iterator_data_get(&it); htable_medium_iterator_next(&it); - WRITE(&id); + WRITE(&mdm->id); } #undef WRITE @@ -445,6 +494,53 @@ error: } static res_T +read_media(struct sdis_green_function* green, FILE* stream) +{ + size_t nmedia = 0; + size_t imedium = 0; + res_T res = RES_OK; + ASSERT(green && stream); + + #define READ(Var) { \ + if(fread((Var), sizeof(*(Var)), 1, stream) != 1) { \ + if(feof(stream)) { \ + res = RES_BAD_ARG; \ + } else if(ferror(stream)) { \ + res = RES_IO_ERR; \ + } else { \ + res = RES_UNKNOWN_ERR; \ + } \ + goto error; \ + } \ + } (void)0 + + READ(&nmedia); + FOR_EACH(imedium, 0, nmedia) { + struct name* name = NULL; + struct fid id; + READ(&id); + + name = flist_name_get(&green->dev->media_names, id); + if(!name) { + log_err(green->dev, "%s: a Stardis medium is missing.\n", + FUNC_NAME); + res = RES_BAD_ARG; + goto error; + } + + res = ensure_medium_registration(green, name->mem); + if(res != RES_OK) goto error; + } + + #undef READ + +exit: + return res; +error: + goto exit; +} + +static res_T write_interfaces(struct sdis_green_function* green, FILE* stream) { struct htable_interf_iterator it, it_end; @@ -464,9 +560,9 @@ write_interfaces(struct sdis_green_function* green, FILE* stream) htable_interf_begin(&green->interfaces, &it); htable_interf_end(&green->interfaces, &it_end); while(!htable_interf_iterator_eq(&it, &it_end)) { - const unsigned id = *htable_interf_iterator_key_get(&it); + const struct sdis_interface* interf = *htable_interf_iterator_data_get(&it); htable_interf_iterator_next(&it); - WRITE(&id); + WRITE(&interf->id); } #undef WRITE @@ -477,6 +573,53 @@ error: } static res_T +read_interfaces(struct sdis_green_function* green, FILE* stream) +{ + size_t ninterfs = 0; + size_t iinterf = 0; + res_T res = RES_OK; + ASSERT(green && stream); + + #define READ(Var) { \ + if(fread((Var), sizeof(*(Var)), 1, stream) != 1) { \ + if(feof(stream)) { \ + res = RES_BAD_ARG; \ + } else if(ferror(stream)) { \ + res = RES_IO_ERR; \ + } else { \ + res = RES_UNKNOWN_ERR; \ + } \ + goto error; \ + } \ + } (void)0 + + READ(&ninterfs); + FOR_EACH(iinterf, 0, ninterfs) { + struct name* name = NULL; + struct fid id; + READ(&id); + + name = flist_name_get(&green->dev->interfaces_names, id); + if(!name) { + log_err(green->dev, "%s: a Stardis interface is missing.\n", + FUNC_NAME); + res = RES_BAD_ARG; + goto error; + } + + res = ensure_interface_registration(green, name->mem); + if(res != RES_OK) goto error; + } + + #undef READ + +exit: + return res; +error: + goto exit; +} + +static res_T write_paths_list(struct sdis_green_function* green, FILE* stream) { size_t npaths = 0; @@ -507,6 +650,45 @@ error: goto exit; } +static res_T +read_paths_list(struct sdis_green_function* green, FILE* stream) +{ + size_t npaths = 0; + size_t ipath = 0; + res_T res = RES_OK; + + #define READ(Var) { \ + if(fread((Var), sizeof(*(Var)), 1, stream) != 1) { \ + if(feof(stream)) { \ + res = RES_BAD_ARG; \ + } else if(ferror(stream)) { \ + res = RES_IO_ERR; \ + } else { \ + res = RES_UNKNOWN_ERR; \ + } \ + goto error; \ + } \ + } (void)0 + + READ(&npaths); + res = darray_green_path_resize(&green->paths, npaths); + if(res != RES_OK) goto error; + + FOR_EACH(ipath, 0, npaths) { + struct green_path* path = NULL; + path = darray_green_path_data_get(&green->paths) + ipath; + + res = green_path_read(path, stream); + if(res != RES_OK) goto error; + } + #undef READ + +exit: + return res; +error: + goto exit; +} + static void green_function_clear(struct sdis_green_function* green) { @@ -650,7 +832,7 @@ sdis_green_function_write(struct sdis_green_function* green, FILE* stream) struct ssp_rng* rng = NULL; res_T res = RES_OK; - if(!green && !stream) { + if(!green || !stream) { res = RES_BAD_ARG; goto error; } @@ -691,6 +873,69 @@ error: } res_T +sdis_green_function_create_from_stream + (struct sdis_scene* scn, + FILE* stream, + struct sdis_green_function** out_green) +{ + struct sdis_green_function* green = NULL; + struct ssp_rng* rng = NULL; + res_T res = RES_OK; + + if(!scn || !stream || !out_green) { + res = RES_BAD_ARG; + goto error; + } + + res = green_function_create(scn->dev, &green); + if(res != RES_OK) goto error; + + res = read_media(green, stream); + if(res != RES_OK) goto error; + res = read_interfaces(green, stream); + if(res != RES_OK) goto error; + res = read_paths_list(green, stream); + if(res != RES_OK) goto error; + + #define READ(Var) { \ + if(fread((Var), sizeof(*(Var)), 1, stream) != 1) { \ + if(feof(stream)) { \ + res = RES_BAD_ARG; \ + } else if(ferror(stream)) { \ + res = RES_IO_ERR; \ + } else { \ + res = RES_UNKNOWN_ERR; \ + } \ + goto error; \ + } \ + } (void)0 + READ(&green->npaths_valid); + READ(&green->npaths_invalid); + READ(&green->realisation_time); + READ(&green->rng_type); + #undef READ + + /* Create a temporary RNG used to deserialise the RNG state */ + res = ssp_rng_create(green->dev->allocator, &green->rng_type, &rng); + if(res != RES_OK) goto error; + res = ssp_rng_read(rng, stream); + if(res != RES_OK) goto error; + res = ssp_rng_write(rng, green->rng_state); + if(res != RES_OK) goto error; + +exit: + if(rng) SSP(rng_ref_put(rng)); + if(out_green) *out_green = green; + return res; +error: + if(green) { + SDIS(green_function_ref_put(green)); + green = NULL; + } + goto exit; +} + +res_T sdis_green_function_get_paths_count (const struct sdis_green_function* green, size_t* npaths) { diff --git a/src/sdis_interface.c b/src/sdis_interface.c @@ -153,6 +153,7 @@ sdis_interface_create interf->dev = dev; interf->shader = *shader; interf->id = flist_name_add(&dev->interfaces_names); + flist_name_get(&dev->interfaces_names, interf->id)->mem = interf; if(data) { SDIS(data_ref_get(data)); diff --git a/src/sdis_medium.c b/src/sdis_medium.c @@ -68,6 +68,7 @@ medium_create medium->dev = dev; medium->type = type; medium->id = flist_name_add(&dev->media_names); + flist_name_get(&dev->media_names, medium->id)->mem = medium; exit: if(out_medium) *out_medium = medium;