solstice

Compute collected power and efficiencies of a solar plant
git clone git://git.meso-star.com/solstice.git
Log | Files | Refs | README | LICENSE

commit c9e01d87d5858304078597ec930fec2b00290f24
parent 232b6eab5e2ae9305d8deff5236c41f7b156f284
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Tue,  4 Jun 2019 11:41:14 +0200

Add the -G option used to configure the RNG

Define the input file from which the initial RNG state is loaded and define
the output file where the RNG state at the end of the simulation is
saved.

Diffstat:
Mcmake/CMakeLists.txt | 2+-
Msrc/solstice.c | 17+++++++++++++++++
Msrc/solstice.h | 4++++
Msrc/solstice_args.c | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
Msrc/solstice_args.h.in | 9++++++++-
Msrc/solstice_solve.c | 19+++++++++++++++++++
Msrc/test_solstice_args.c | 56++++++++++++++++++++++++++++++++++++++++++++++++++++++++
7 files changed, 164 insertions(+), 4 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -45,7 +45,7 @@ find_package(LibYAML REQUIRED) find_package(RCMake 0.2.3 REQUIRED) find_package(RSys 0.6 REQUIRED) find_package(SolAnim 0.2 REQUIRED) -find_package(SolSolver 0.7 REQUIRED) +find_package(SolSolver 0.8 REQUIRED) find_package(Star3DUT 0.2 REQUIRED) find_package(StarSP 0.8 REQUIRED) find_package(StarSTL 0.3.1 REQUIRED) diff --git a/src/solstice.c b/src/solstice.c @@ -645,6 +645,21 @@ solstice_init if(res != RES_OK) goto error; } + if(args->rng_state_input_filename) { + solstice->rng_state_input = fopen(args->rng_state_input_filename, "r"); + if(!solstice->rng_state_input) { + fprintf(stderr, "Could not open the input RNG state file.\n"); + res = RES_IO_ERR; + goto error; + } + } + + if(args->rng_state_output_filename) { + res = open_output_stream(args->rng_state_output_filename, + args->force_overwriting, &solstice->rng_state_output); + if(res != RES_OK) goto error; + } + res = load_data(solstice, args); if(res != RES_OK) goto error; @@ -715,6 +730,8 @@ solstice_release(struct solstice* solstice) if(solstice->framebuffer) SSOL(image_ref_put(solstice->framebuffer)); if(solstice->output && solstice->output != stdout) fclose(solstice->output); if(solstice->mtl_virtual) SSOL(material_ref_put(solstice->mtl_virtual)); + if(solstice->rng_state_input) fclose(solstice->rng_state_input); + if(solstice->rng_state_output) fclose(solstice->rng_state_output); htable_material_release(&solstice->materials); htable_object_release(&solstice->objects); htable_anchor_release(&solstice->anchors); diff --git a/src/solstice.h b/src/solstice.h @@ -193,6 +193,10 @@ struct solstice { FILE* output; /* Output stream */ int dump_paths; + /* Stream used to load/store RNG state */ + FILE* rng_state_input; + FILE* rng_state_output; + struct logger logger; struct mem_allocator* allocator; }; diff --git a/src/solstice_args.c b/src/solstice_args.c @@ -48,6 +48,8 @@ print_help(const char* program) printf( " -f overwrite the OUTPUT file if it already exists.\n"); printf( +" -G <rng> configure the random number generator.\n"); + printf( " -g <dump> switch in dump geometry mode and configure it.\n"); printf( " -h display this help and exit.\n"); @@ -264,7 +266,7 @@ parse_rendering_option(const char* str, struct solstice_args* args) char* val; char* ctx; size_t len; - res_T res; + res_T res = RES_OK; ASSERT(str && args); if(strlen(str) >= sizeof(buf) - 1/*NULL char*/) { @@ -482,6 +484,56 @@ error: goto exit; } +static res_T +parse_rng_option(const char* str, struct solstice_args* args) +{ + char buf[128]; + char* key; + char* val; + char* ctx; + size_t len; + res_T res = RES_OK; + ASSERT(str && args); + + if(strlen(str) >= sizeof(buf)-1/*NULL char*/) { + fprintf(stderr, + "Could not duplicate the RNG option string `%s'\n", str); + res = RES_MEM_ERR; + goto error; + } + strncpy(buf, str, sizeof(buf)); + + key = strtok_r(buf, "=", &ctx); + val = strtok_r(NULL, "", &ctx); + + if(!val) { + fprintf(stderr, "Missing a value to the RNG option `%s'.\n", key); + res = RES_BAD_ARG; + goto error; + } + + if(!strcmp(key, "istate")) { /* Input state */ + len = strlen(val); + args->rng_state_input_filename = mem_calloc(len+1, sizeof(char)); + if(!args->rng_state_input_filename) { res = RES_MEM_ERR; goto error; } + strcpy(args->rng_state_input_filename, val); + } else if(!strcmp(key, "ostate")) { /* Output state */ + len = strlen(val); + args->rng_state_output_filename = mem_calloc(len+1, sizeof(char)); + if(!args->rng_state_output_filename) { res = RES_MEM_ERR; goto error; } + strcpy(args->rng_state_output_filename, val); + } else { + fprintf(stderr, "Invalid RNG option `%s'.\n", key); + res = RES_BAD_ARG; + goto error; + } + +exit: + return res; +error: + goto exit; +} + /******************************************************************************* * Local function ******************************************************************************/ @@ -507,7 +559,7 @@ solstice_args_init(struct solstice_args* args, const int argc, char** argv) } optind = 0; - while((opt = getopt(argc, argv, "D:fg:hn:o:p:qR:r:t:v")) != -1) { + while((opt = getopt(argc, argv, "D:fG:g:hn:o:p:qR:r:t:v")) != -1) { switch(opt) { case 'D': /* Sun directions */ res = parse_sun_dir_list(optarg, args); @@ -522,6 +574,9 @@ solstice_args_init(struct solstice_args* args, const int argc, char** argv) res = cstr_to_ulong(optarg, &args->nexperiments); if(res == RES_OK && !args->nexperiments) res = RES_BAD_ARG; break; + case 'G': /* Setup the random number generator */ + res = parse_multiple_options(optarg, args, parse_rng_option); + break; case 'g': /* Switch in dump geometry mode and configure it */ res = parse_multiple_options(optarg, args, parse_dump_option); if(res == RES_OK && args->dump_format == SOLSTICE_ARGS_DUMP_NONE) { @@ -600,6 +655,8 @@ solstice_args_release(struct solstice_args* args) { ASSERT(args); sa_release(args->sun_dirs); + if(args->rng_state_input_filename) mem_rm(args->rng_state_input_filename); + if(args->rng_state_output_filename) mem_rm(args->rng_state_output_filename); *args = SOLSTICE_ARGS_NULL; } diff --git a/src/solstice_args.h.in b/src/solstice_args.h.in @@ -1,4 +1,4 @@ -/* Copyright (C) CNRS 2016-2017 +/* Copyright (C) CNRS 2016-2018 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -75,6 +75,10 @@ struct solstice_args { double sun_ray_length; /* Length of the sun rays. */ double infinite_ray_length; /* Length of the rays going to infinity. */ + /* RNG options */ + char* rng_state_input_filename; + char* rng_state_output_filename; + int force_overwriting; int dump_paths; /* Dump radiative paths */ int rendering; @@ -118,6 +122,9 @@ static const struct solstice_args SOLSTICE_ARGS_NULL = SOLSTICE_ARGS_NULL__; -1, /* Sun ray length */ \ -1, /* Infinite ray length */ \ \ + NULL, /* RNG state input filename */ \ + NULL, /* RNG state output filename */ \ + \ 0, /* Force overwriting */ \ 0, /* Dump radiative paths */ \ 0, /* Rendering */ \ diff --git a/src/solstice_solve.c b/src/solstice_solve.c @@ -548,6 +548,15 @@ solstice_solve(struct solstice* solstice) goto error; } + if(solstice->rng_state_input) { + rewind(solstice->rng_state_input); + res = ssp_rng_read(rng, solstice->rng_state_input); + if(res != RES_OK) { + fprintf(stderr, "Could not read the input RNG state.\n"); + goto error; + } + } + max_failure = solstice->dump_paths ? solstice->nexperiments : (size_t)((double)solstice->nexperiments * MAX_PERCENT_FAILURES); @@ -566,6 +575,16 @@ solstice_solve(struct solstice* solstice) write_per_receiver_mc_primitive(solstice, estimator); } + if(solstice->rng_state_output) { + const struct ssp_rng* rng_state = NULL; + SSOL(estimator_get_rng_state(estimator, &rng_state)); + res = ssp_rng_write(rng_state, solstice->rng_state_output); + if(res != RES_OK) { + fprintf(stderr, "Could not write the RNG state.\n"); + goto error; + } + } + exit: if(estimator) SSOL(estimator_ref_put(estimator)); if(rng) SSP(rng_ref_put(rng)); diff --git a/src/test_solstice_args.c b/src/test_solstice_args.c @@ -670,6 +670,61 @@ test_dump_paths(void) cmd_delete(cmd); } +static void +test_rng(void) +{ + struct solstice_args args = SOLSTICE_ARGS_NULL; + char** cmd = NULL; + + cmd = cmd_create(0, "test", "-D", "0,90", NULL); + CHK(solstice_args_init(&args, cmd_size(cmd), cmd) == RES_OK); + CHK(args.rng_state_input_filename == NULL); + CHK(args.rng_state_output_filename == NULL); + solstice_args_release(&args); + cmd_delete(cmd); + + cmd = cmd_create(0, "test", "-D", "0,90", "-G", "ostate=/tmp/rng_output.txt", NULL); + CHK(solstice_args_init(&args, cmd_size(cmd), cmd) == RES_OK); + CHK(args.rng_state_input_filename == NULL); + CHK(!strcmp(args.rng_state_output_filename, "/tmp/rng_output.txt")); + solstice_args_release(&args); + cmd_delete(cmd); + + cmd = cmd_create(0, "test", "-D", "0,90", "-G", "istate=/tmp/rng_input.txt", NULL); + CHK(solstice_args_init(&args, cmd_size(cmd), cmd) == RES_OK); + CHK(!strcmp(args.rng_state_input_filename, "/tmp/rng_input.txt")); + CHK(args.rng_state_output_filename == NULL); + solstice_args_release(&args); + cmd_delete(cmd); + + cmd = cmd_create(0, "test", "-D", "0,90", "-G", "istate=in.txt:ostate=out.txt", NULL); + CHK(solstice_args_init(&args, cmd_size(cmd), cmd) == RES_OK); + CHK(!strcmp(args.rng_state_input_filename, "in.txt")); + CHK(!strcmp(args.rng_state_output_filename, "out.txt")); + solstice_args_release(&args); + cmd_delete(cmd); + + cmd = cmd_create(0, "test", "-D", "0,90", "-G", "istate=", NULL); + CHK(solstice_args_init(&args, cmd_size(cmd), cmd) == RES_BAD_ARG); + cmd_delete(cmd); + + cmd = cmd_create(0, "test", "-D", "0,90", "-G", "ostate=", NULL); + CHK(solstice_args_init(&args, cmd_size(cmd), cmd) == RES_BAD_ARG); + cmd_delete(cmd); + + cmd = cmd_create(0, "test", "-D", "0,90", "-G", "istate=in.txt:ostate=", NULL); + CHK(solstice_args_init(&args, cmd_size(cmd), cmd) == RES_BAD_ARG); + cmd_delete(cmd); + + cmd = cmd_create(0, "test", "-D", "0,90", "-G", "istate=:ostate=out", NULL); + CHK(solstice_args_init(&args, cmd_size(cmd), cmd) == RES_BAD_ARG); + cmd_delete(cmd); + + cmd = cmd_create(0, "test", "-D", "0,90", "-G", NULL); + CHK(solstice_args_init(&args, cmd_size(cmd), cmd) == RES_BAD_ARG); + cmd_delete(cmd); +} + int main(int argc, char** argv) { @@ -685,6 +740,7 @@ main(int argc, char** argv) test_input(); test_dump(); test_dump_paths(); + test_rng(); CHK(mem_allocated_size() == 0); return 0; }