star-line

Structure for accelerating line importance sampling
git clone git://git.meso-star.fr/star-line.git
Log | Files | Refs | README | LICENSE

commit b95348c666e7c6345f2e4c33168f7df4e5abeba8
parent d2b8e200ce1dbac663adab7bb9cbe46a90da157b
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Mon, 23 May 2022 16:14:02 +0200

[De]serialize the mixture

Add the functions sln_mixture_write and sln_mixture_create_from_stream.

Diffstat:
Msrc/sln.h | 14++++++++++++++
Msrc/sln_mixture.c | 159++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
Msrc/sln_mixture_c.h | 4++++
3 files changed, 164 insertions(+), 13 deletions(-)

diff --git a/src/sln.h b/src/sln.h @@ -48,6 +48,7 @@ /* Forwar declaration of external data structures */ struct logger; struct mem_allocator; +struct shtr; struct shtr_line; struct shtr_isotope_metadata; struct shtr_line_list; @@ -188,6 +189,14 @@ sln_mixture_create const struct sln_mixture_create_args* args, struct sln_mixture** mixture); +/* Load a mixture serialized with the "shtr_mixture_write" function */ +SLN_API res_T +sln_mixture_create_from_stream + (struct sln_device* sln, + struct shtr* shtr, + FILE* stream, + struct sln_mixture** mixture); + SLN_API res_T sln_mixture_ref_get (struct sln_mixture* mixture); @@ -201,6 +210,11 @@ sln_mixture_get_desc (const struct sln_mixture* mixture, struct sln_mixture_desc* desc); +SLN_API res_T +sln_mixture_write + (const struct sln_mixture* mixture, + FILE* stream); + /******************************************************************************* * Tree API ******************************************************************************/ diff --git a/src/sln_mixture.c b/src/sln_mixture.c @@ -22,6 +22,7 @@ #include "sln_mixture_c.h" #include <star/shtr.h> +#include <rsys/cstr.h> STATIC_ASSERT(SLN_MAX_MOLECULES_COUNT <= SHTR_MAX_MOLECULES_COUNT, Invalid_SLN_MAX_MOLECULES_COUNT); @@ -192,6 +193,33 @@ check_sln_mixture_create_args } static res_T +create_mixture(struct sln_device* sln, struct sln_mixture** out_mixture) +{ + struct sln_mixture* mixture = NULL; + res_T res = RES_OK; + ASSERT(sln && out_mixture); + + mixture = MEM_CALLOC(sln->allocator, 1, sizeof(struct sln_mixture)); + if(!mixture) { + log_err(sln, "%s: could not allocate the mixture data structure.\n", + FUNC_NAME); + res = RES_MEM_ERR; + goto error; + } + ref_init(&mixture->ref); + SLN(device_ref_get(sln)); + mixture->sln = sln; + darray_line_init(sln->allocator, &mixture->lines); + +exit: + *out_mixture = mixture; + return res; +error: + if(mixture) { SLN(mixture_ref_put(mixture)); mixture = NULL; } + goto exit; +} + +static res_T create_line_view (struct sln_device* sln, const struct sln_mixture_create_args* mixture_args, @@ -326,7 +354,6 @@ error: goto exit; } - static void release_mixture(ref_T* ref) { @@ -356,18 +383,8 @@ sln_mixture_create if(!sln || !out_mixture) { res = RES_BAD_ARG; goto error; } res = check_sln_mixture_create_args(sln, FUNC_NAME, args); if(res != RES_OK) goto error; - - mixture = MEM_CALLOC(sln->allocator, 1, sizeof(struct sln_mixture)); - if(!mixture) { - log_err(sln, "%s: could not allocate the mixture data structure.\n", - FUNC_NAME); - res = RES_MEM_ERR; - goto error; - } - ref_init(&mixture->ref); - SLN(device_ref_get(sln)); - mixture->sln = sln; - darray_line_init(sln->allocator, &mixture->lines); + res = create_mixture(sln, &mixture); + if(res != RES_OK) goto error; #define CALL(Func) { if(RES_OK != (res = Func)) goto error; } (void)0 CALL(create_line_view(sln, args, &mixture->line_view)); @@ -385,6 +402,82 @@ error: } res_T +sln_mixture_create_from_stream + (struct sln_device* sln, + struct shtr* shtr, + FILE* stream, + struct sln_mixture** out_mixture) +{ + struct sln_mixture* mixture = NULL; + size_t nlines = 0; + int version = 0; + res_T res = RES_OK; + + if(!sln || !shtr || !stream || !out_mixture) { + res = RES_BAD_ARG; + goto error; + } + + res = create_mixture(sln, &mixture); + if(res != RES_OK) goto error; + + #define READ(Var, Nb) { \ + if(fread((Var), sizeof(*(Var)), (Nb), stream) != (Nb)) { \ + if(feof(stream)) { \ + res = RES_BAD_ARG; \ + } else if(ferror(stream)) { \ + res = RES_IO_ERR; \ + } else { \ + res = RES_UNKNOWN_ERR; \ + } \ + log_err(sln, "%s: error reading mixture data -- %s.\n", \ + FUNC_NAME, res_to_cstr(res)); \ + goto error; \ + } \ + } (void)0 + READ(&version, 1); + if(version != SLN_MIXTURE_VERSION) { + log_err(sln, + "%s: unexpected mixture version %d. " + "Expecting a mixture in version %d.\n", + FUNC_NAME, version, SLN_MIXTURE_VERSION); + res = RES_BAD_ARG; + goto error; + } + READ(mixture->molecules_params, SLN_MAX_MOLECULES_COUNT); + + res = shtr_isotope_metadata_create_from_stream(shtr, stream, &mixture->metadata); + if(res != RES_OK) goto error; + res = shtr_line_view_create_from_stream(shtr, stream, &mixture->line_view); + if(res != RES_OK) goto error; + + READ(&nlines, 1); + res = darray_line_resize(&mixture->lines, nlines); + if(res != RES_OK) { + log_err(sln, "%s: error allocating mixture lines -- %s.\n", + FUNC_NAME, res_to_cstr(res)); + goto error; + } + READ(darray_line_data_get(&mixture->lines), nlines); +#ifndef NDEBUG + SHTR(line_view_get_size(mixture->line_view, &nlines)); + ASSERT(darray_line_size_get(&mixture->lines) == nlines); +#endif + + READ(&mixture->temperature, 1); + READ(&mixture->pressure, 1); + READ(&mixture->wavenumber_range, 1); + #undef READ + +exit: + if(out_mixture) *out_mixture = mixture; + return res; +error: + if(mixture) { SLN(mixture_ref_put(mixture)); mixture = NULL; } + goto exit; +} + +res_T sln_mixture_ref_get(struct sln_mixture* mixture) { if(!mixture) return RES_BAD_ARG; @@ -413,3 +506,43 @@ sln_mixture_get_desc desc->nlines = darray_line_size_get(&mixture->lines); return RES_OK; } + +res_T +sln_mixture_write(const struct sln_mixture* mixture, FILE* stream) +{ + size_t nlines = 0; + res_T res = RES_OK; + + if(!mixture || !stream) { + res = RES_BAD_ARG; + goto error; + } + + #define WRITE(Var, Nb) { \ + if(fwrite((Var), sizeof(*(Var)), (Nb), stream) != (Nb)) { \ + log_err(mixture->sln, "%s: error writing the mixture.\n", FUNC_NAME); \ + res = RES_IO_ERR; \ + goto error; \ + } \ + } (void)0 + WRITE(&SLN_MIXTURE_VERSION, 1); + WRITE(mixture->molecules_params, SLN_MAX_MOLECULES_COUNT); + + res = shtr_isotope_metadata_write(mixture->metadata, stream); + if(res != RES_OK) goto error; + res = shtr_line_view_write(mixture->line_view, stream); + if(res != RES_OK) goto error; + + nlines = darray_line_size_get(&mixture->lines); + WRITE(&nlines, 1); + WRITE(darray_line_cdata_get(&mixture->lines), nlines); + WRITE(&mixture->temperature, 1); + WRITE(&mixture->pressure, 1); + WRITE(mixture->wavenumber_range, 2); + #undef WRITE + +exit: + return res; +error: + goto exit; +} diff --git a/src/sln_mixture_c.h b/src/sln_mixture_c.h @@ -41,6 +41,10 @@ struct molecule_params { double cutoff; }; +/* Current version of the mixture. One should increment it and perform a + * version management onto serialized data when muxture structure is updated. */ +static const int SLN_MIXTURE_VERSION = 0; + struct sln_mixture { /* Map the molecule id to its parameters (i.e. concentration, cutoff, * isotopes abundance) */