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 9ccba0ca6e9ad28a2fec5b8dc4a1a5c3132cf5da
parent 94a8908662ea1b0c1faf62503db20f68cf0bb71f
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Mon, 20 Mar 2017 11:06:41 +0100

Provide optional arguments to the dump radiative path option -p

Optionally configure the length of the path segment starting from the
sun or going to the infinity.

Diffstat:
Mdoc/cli | 14+++++++++++++-
Msrc/solstice.c | 2+-
Msrc/solstice.h | 2+-
Msrc/solstice_args.c | 167+++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
Msrc/solstice_args.h.in | 12++++++++++--
Msrc/solstice_solve.c | 5+++--
Msrc/test_solstice_args.c | 58++++++++++++++++++++++++++++++++++++++++++++++++++--------
7 files changed, 181 insertions(+), 79 deletions(-)

diff --git a/doc/cli b/doc/cli @@ -6,7 +6,7 @@ solstice -h # Short help and exit -g <dump> # Switch in dump geometry -o OUTPUT # defaulting to stdout if not defined - -p # Switch in dump paths mode + -p [ <dump-radiative-path> ] # Switch in dump radiative paths mode -q # don't print a message if no INPUT is submitted -n INTEGER # Realisations count -r <rendering> # Switch in rendering mode @@ -43,6 +43,18 @@ solstice -g format=obj:split-group=1 <dump> ::= format=<dump-format>[:split=<split-mode>] +<dump-radiative-path> ::= + <dump-path-option>[:<dump-path-option> ... ] + +<dump-path-option> ::= + <sun-ray-len> | <inf-ray-len> + +<sun-ray-len> ::= + srlen=REAL + +<inf-ray-len> ::= # Length of the rays going to infinite + irlen=REAL + <dump-format> ::= obj diff --git a/src/solstice.c b/src/solstice.c @@ -598,7 +598,7 @@ solstice_init goto error; } - solstice->nrealisations = args->nrealisations; + solstice->nexperiments = args->nexperiments; solstice->output_hits = args->output_hits; solstice->dump_format = args->dump_format; solstice->dump_split_mode = args->dump_split_mode; diff --git a/src/solstice.h b/src/solstice.h @@ -97,7 +97,7 @@ struct solstice { struct darray_double sun_dirs; /* List of double3 */ struct darray_double sun_angles; - size_t nrealisations; /* # realisations */ + size_t nexperiments; /* # MC experiments */ FILE* output; /* Output stream */ int output_hits; /* Output per receiver hits */ int dump_paths; diff --git a/src/solstice_args.c b/src/solstice_args.c @@ -51,8 +51,8 @@ print_help(const char* program) printf( " -h display this help and exit.\n"); printf( -" -n REALISATIONS number of realisations. Default is %lu.\n", - SOLSTICE_ARGS_DEFAULT.nrealisations); +" -n EXPERIMENTS number of Monte Carlo experiments. Default is %lu.\n", + SOLSTICE_ARGS_DEFAULT.nexperiments); printf( " -g <dump> switch in dump geometry mode and configure it.\n"); printf( @@ -97,6 +97,37 @@ parse_fov(const char* str, double* out_fov) return RES_OK; } +static res_T +parse_multiple_options + (const char* str, + struct solstice_args* args, + res_T (*parse_option)(const char* str, struct solstice_args* args)) +{ + char buf[512]; + char* tk; + char* ctx; + res_T res = RES_OK; + ASSERT(args && str); + + if(strlen(str) >= sizeof(buf) - 1/*NULL char*/) { + fprintf(stderr, "Could not duplicate the option string `%s'.\n", str); + res = RES_MEM_ERR; + goto error; + } + strncpy(buf, str, sizeof(buf)); + + tk = strtok_r(buf, ":", &ctx); + do { + res = parse_option(tk, args); + if(res != RES_OK) goto error; + tk = strtok_r(NULL, ":", &ctx); + } while(tk); + +exit: + return res; +error: + goto exit; +} static res_T parse_sun_dir_list(const char* str, struct solstice_args* args) @@ -294,41 +325,6 @@ parse_rendering_option(const char* str, struct solstice_args* args) res = RES_BAD_ARG; goto error; } - args->rendering = 1; - -exit: - return res; -error: - goto exit; -} - -static res_T -parse_rendering_options(const char* str, struct solstice_args* args) -{ - char buf[512]; - char* tk; - char* ctx; - res_T res = RES_OK; - ASSERT(args && str); - - /* Setup default values of the rendering parameters */ - args->camera = SOLSTICE_ARGS_DEFAULT.camera; - args->img = SOLSTICE_ARGS_DEFAULT.img; - - if(strlen(str) >= sizeof(buf) - 1/*NULL char*/) { - fprintf(stderr, - "Could not duplicate the rendering options string `%s'.\n", str); - res = RES_MEM_ERR; - goto error; - } - strncpy(buf, str, sizeof(buf)); - - tk = strtok_r(buf, ":", &ctx); - do { - res = parse_rendering_option(tk, args); - if(res != RES_OK) goto error; - tk = strtok_r(NULL, ":", &ctx); - } while(tk); exit: return res; @@ -417,12 +413,6 @@ parse_dump_option(const char* str, struct solstice_args* args) } if(res != RES_OK) goto error; - if(args->dump_format == SOLSTICE_ARGS_DUMP_NONE) { - fprintf(stderr, "No dump format is defined.\n"); - res = RES_BAD_ARG; - goto error; - } - exit: return res; error: @@ -430,27 +420,52 @@ error: } static res_T -parse_dump_options(const char* str, struct solstice_args* args) +parse_dump_paths_option(const char* str, struct solstice_args* args) { - char buf[512]; - char* tk; + char buf[128]; + char* key; + char* val; char* ctx; res_T res = RES_OK; - ASSERT(args && str); - (void)str, (void)args; + ASSERT(str && args); if(strlen(str) >= sizeof(buf) - 1/*NULL char*/) { fprintf(stderr, - "Could not duplicate the dump geometry options string `%s'.\n", str); +"Could not duplicate the dump radiative paths option string `%s'.\n", str); res = RES_MEM_ERR; goto error; } + strncpy(buf, str, sizeof(buf)); - tk = strtok_r(buf, ":", &ctx); - do { - res = parse_dump_option(tk, args); - tk = strtok_r(NULL, ":", &ctx); - } while(tk); + + key = strtok_r(buf, "=", &ctx); + val = strtok_r(NULL, "", &ctx); + + if(!val) { + fprintf(stderr, + "Missing a value to the dump radiative paths option `%s'.\n", key); + res = RES_BAD_ARG; + goto error; + } + + if(!strcmp(key, "irlen")) { + res = cstr_to_double(val, &args->infinite_ray_length); + if(res != RES_OK) { + fprintf(stderr, "Invalid infinite ray length `%s'.\n", val); + goto error; + } + } else if(!strcmp(key, "srlen")) { + res = cstr_to_double(val, &args->sun_ray_length); + if(res != RES_OK) { + fprintf(stderr, "Invalid sun ray length `%s'.\n", val); + goto error; + } + } else { + fprintf(stderr, "Invalid dump radiative paths option `%s'.\n", val); + res = RES_BAD_ARG; + goto error; + } + if(res != RES_OK) goto error; exit: return res; @@ -470,33 +485,57 @@ solstice_args_init(struct solstice_args* args, const int argc, char** argv) *args = SOLSTICE_ARGS_DEFAULT; + opterr = 0; optind = 0; - while((opt = getopt(argc, argv, "D:fg:Hhn:o:pqR:r:t:")) != -1) { + while((opt = getopt(argc, argv, "D:fg:Hhn:o:p:qR:r:t:")) != -1) { switch(opt) { - case 'D': + case 'D': /* Sun directions */ res = parse_sun_dir_list(optarg, args); break; case 'f': args->force_overwriting = 1; break; case 'H': args->output_hits = 1; break; - case 'h': + case 'h': /* Print short help and exit */ print_help(argv[0]); solstice_args_release(args); args->quit = 1; goto exit; - case 'n': - res = cstr_to_ulong(optarg, &args->nrealisations); - if(res == RES_OK && !args->nrealisations) res = RES_BAD_ARG; + case 'n': /* Define the number of experiments */ + res = cstr_to_ulong(optarg, &args->nexperiments); + if(res == RES_OK && !args->nexperiments) res = RES_BAD_ARG; + 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) { + fprintf(stderr, "%s: missing a dump format -- `%s'.\n", + argv[0], optarg); + res = RES_BAD_ARG; + } break; - case 'g': res = parse_dump_options(optarg, args); break; case 'o': args->output_filename = optarg; break; - case 'p': args->dump_paths = 1; break; + case 'p': /* Switch in dump radiative paths mode and configure it */ + args->dump_paths = 1; + res = parse_multiple_options(optarg, args, parse_dump_paths_option); + break; case 'q': args->quiet = 1; break; case 'R': args->receivers_filename = optarg; break; - case 'r': res = parse_rendering_options(optarg, args); break; - case 't': + case 'r': /* Switch in rendering mode and configure it */ + args->rendering = 1; + res = parse_multiple_options(optarg, args, parse_rendering_option); + break; + case 't': /* Submit an hint on the number of threads to use */ res = cstr_to_uint(optarg, &args->nthreads); if(res == RES_OK && !args->nthreads) res = RES_BAD_ARG; break; + case '?': /* Option with optionnal arguments */ + switch(optopt) { + case 'p': args->dump_paths = 1; break; + default: + fprintf(stderr, "%s: option requires an argument -- '%c'\n", + argv[0], optopt); + res = RES_BAD_ARG; + break; + } + break; default: res = RES_BAD_ARG; break; } if(res != RES_OK) { diff --git a/src/solstice_args.h.in b/src/solstice_args.h.in @@ -44,7 +44,7 @@ struct solstice_args { const char* output_filename; const char* input_filename; /* May be NULL <=> read data from stdin */ const char* receivers_filename; - unsigned long nrealisations; /* #realisations */ + unsigned long nexperiments; /* #experiments */ unsigned nthreads; /* #threads */ /* List of sun directions */ @@ -67,11 +67,16 @@ struct solstice_args { enum solstice_args_render_mode render_mode; + /* Dump geometry mode */ enum solstice_args_dump_format dump_format; enum solstice_args_dump_split_mode dump_split_mode; + /* Dump radiative paths options. */ + double sun_ray_length; /* Length of the sun rays. */ + double infinite_ray_length; /* Length of the rays going to infinity. */ + int force_overwriting; - int dump_paths; + int dump_paths; /* Dump radiative paths */ int rendering; int output_hits; /* Output the per receiver hits */ int quiet; @@ -110,6 +115,9 @@ static const struct solstice_args SOLSTICE_ARGS_NULL = SOLSTICE_ARGS_NULL__; SOLSTICE_ARGS_DUMP_NONE, /* Dump format */ \ SOLSTICE_ARGS_DUMP_SPLIT_NONE, /* Dump split mode */ \ \ + -1, /* Sun ray length */ \ + -1, /* Infinite ray length */ \ + \ 0, /* Force overwriting */ \ 0, /* Dump radiative paths */ \ 0, /* Rendering */ \ diff --git a/src/solstice_solve.c b/src/solstice_solve.c @@ -378,8 +378,9 @@ solstice_solve(struct solstice* solstice) } } - res = ssol_solve(solstice->scene, rng, solstice->nrealisations, - solstice->dump_paths, bin_stream, &estimator); + res = ssol_solve(solstice->scene, rng, solstice->nexperiments, + solstice->dump_paths ? &SSOL_PATH_TRACKER_DEFAULT : NULL, bin_stream, + &estimator); if(res != RES_OK) { fprintf(stderr, "Error in integrating the solar flux.\n"); goto error; diff --git a/src/test_solstice_args.c b/src/test_solstice_args.c @@ -83,7 +83,7 @@ test_rendering(void) cmd = cmd_create(0, "test", "-r", "img=1280x720", NULL); CHECK(solstice_args_init(&args, cmd_size(cmd), cmd), RES_OK); CHECK(args.rendering, 1); - CHECK(args.nrealisations, SOLSTICE_ARGS_DEFAULT.nrealisations); + CHECK(args.nexperiments, SOLSTICE_ARGS_DEFAULT.nexperiments); CHECK(d3_eq(args.camera.pos, SOLSTICE_ARGS_DEFAULT.camera.pos), 1); CHECK(d3_eq(args.camera.tgt, SOLSTICE_ARGS_DEFAULT.camera.tgt), 1); CHECK(d3_eq(args.camera.up, SOLSTICE_ARGS_DEFAULT.camera.up), 1); @@ -100,7 +100,7 @@ test_rendering(void) cmd = cmd_create(0, "test", "-q", "-r", "img=640x480:fov=70:pos=1,2,3", NULL); CHECK(solstice_args_init(&args, cmd_size(cmd), cmd), RES_OK); CHECK(args.rendering, 1); - CHECK(args.nrealisations, SOLSTICE_ARGS_DEFAULT.nrealisations); + CHECK(args.nexperiments, SOLSTICE_ARGS_DEFAULT.nexperiments); CHECK(d3_eq(args.camera.pos, d3(tmp, 1, 2, 3)), 1); CHECK(d3_eq(args.camera.tgt, SOLSTICE_ARGS_DEFAULT.camera.tgt), 1); CHECK(d3_eq(args.camera.up, SOLSTICE_ARGS_DEFAULT.camera.up), 1); @@ -116,7 +116,7 @@ test_rendering(void) cmd = cmd_create(0, "test", "-r", "up=0,0,1:tgt=0,-10,0:rmode=draft", NULL); CHECK(solstice_args_init(&args, cmd_size(cmd), cmd), RES_OK); - CHECK(args.nrealisations, SOLSTICE_ARGS_DEFAULT.nrealisations); + CHECK(args.nexperiments, SOLSTICE_ARGS_DEFAULT.nexperiments); CHECK(d3_eq(args.camera.pos, SOLSTICE_ARGS_DEFAULT.camera.pos), 1); CHECK(d3_eq(args.camera.tgt, d3(tmp, 0,-10, 0)), 1); CHECK(d3_eq(args.camera.up, d3(tmp, 0, 0, 1)), 1); @@ -132,7 +132,7 @@ test_rendering(void) cmd = cmd_create(0, "test", "-r", "up=0,0,1:rmode=pt:spp=4", NULL); CHECK(solstice_args_init(&args, cmd_size(cmd), cmd), RES_OK); - CHECK(args.nrealisations, SOLSTICE_ARGS_DEFAULT.nrealisations); + CHECK(args.nexperiments, SOLSTICE_ARGS_DEFAULT.nexperiments); CHECK(d3_eq(args.camera.up, d3(tmp, 0, 0, 1)), 1); CHECK(args.img.width, SOLSTICE_ARGS_DEFAULT.img.width); CHECK(args.img.height, SOLSTICE_ARGS_DEFAULT.img.height); @@ -317,19 +317,19 @@ test_realisations_count(void) cmd = cmd_create(0, "test", "-D", "0,90", "-n", "1", NULL); CHECK(solstice_args_init(&args, cmd_size(cmd), cmd), RES_OK); - CHECK(args.nrealisations, 1); + CHECK(args.nexperiments, 1); solstice_args_release(&args); cmd_delete(cmd); cmd = cmd_create(0, "test", "-D", "0,90", NULL); CHECK(solstice_args_init(&args, cmd_size(cmd), cmd), RES_OK); - CHECK(args.nrealisations, SOLSTICE_ARGS_DEFAULT.nrealisations); + CHECK(args.nexperiments, SOLSTICE_ARGS_DEFAULT.nexperiments); solstice_args_release(&args); cmd_delete(cmd); cmd = cmd_create(0, "test", "-D", "0,90", "-n", "123", NULL); CHECK(solstice_args_init(&args, cmd_size(cmd), cmd), RES_OK); - CHECK(args.nrealisations, 123); + CHECK(args.nexperiments, 123); solstice_args_release(&args); cmd_delete(cmd); @@ -582,10 +582,52 @@ test_dump_paths(void) cmd = cmd_create(0, "test", "-D", "0,90", "-p", NULL); CHECK(solstice_args_init(&args, cmd_size(cmd), cmd), RES_OK); CHECK(args.dump_paths, 1); + CHECK(args.infinite_ray_length, SOLSTICE_ARGS_DEFAULT.infinite_ray_length); + CHECK(args.sun_ray_length, SOLSTICE_ARGS_DEFAULT.sun_ray_length); solstice_args_release(&args); cmd_delete(cmd); - cmd = cmd_create(0, "test", "-p", NULL); + cmd = cmd_create(0, "test", "-D", "0,90", "-p", "irlen=3.14:srlen=1.23", NULL); + CHECK(solstice_args_init(&args, cmd_size(cmd), cmd), RES_OK); + CHECK(args.dump_paths, 1); + CHECK(eq_eps(args.infinite_ray_length, 3.14, 1.e-6), 1); + CHECK(eq_eps(args.sun_ray_length, 1.23, 1.e-6), 1); + solstice_args_release(&args); + cmd_delete(cmd); + + cmd = cmd_create(0, "test", "-D", "0,90", "-p", "irlen=0", NULL); + CHECK(solstice_args_init(&args, cmd_size(cmd), cmd), RES_OK); + CHECK(args.dump_paths, 1); + CHECK(eq_eps(args.infinite_ray_length, 0, 1.e-6), 1); + CHECK(args.sun_ray_length, SOLSTICE_ARGS_DEFAULT.sun_ray_length); + solstice_args_release(&args); + cmd_delete(cmd); + + cmd = cmd_create(0, "test", "-D", "0,90", "-p", "srlen=-4", NULL); + CHECK(solstice_args_init(&args, cmd_size(cmd), cmd), RES_OK); + CHECK(args.dump_paths, 1); + CHECK(args.infinite_ray_length, SOLSTICE_ARGS_DEFAULT.infinite_ray_length); + CHECK(eq_eps(args.sun_ray_length, -4, 1.e-6), 1); + solstice_args_release(&args); + cmd_delete(cmd); + + cmd = cmd_create(0, "test", "-D", "0,90", "-p", "srlen=", NULL); + CHECK(solstice_args_init(&args, cmd_size(cmd), cmd), RES_BAD_ARG); + cmd_delete(cmd); + + cmd = cmd_create(0, "test", "-D", "0,90", "-p", "irlen=", NULL); + CHECK(solstice_args_init(&args, cmd_size(cmd), cmd), RES_BAD_ARG); + cmd_delete(cmd); + + cmd = cmd_create(0, "test", "-D", "0,90", "-p", "srlen=abcd", NULL); + CHECK(solstice_args_init(&args, cmd_size(cmd), cmd), RES_BAD_ARG); + cmd_delete(cmd); + + cmd = cmd_create(0, "test", "-D", "0,90", "-p", "irlen", NULL); + CHECK(solstice_args_init(&args, cmd_size(cmd), cmd), RES_BAD_ARG); + cmd_delete(cmd); + + cmd = cmd_create(0, "test", "-D", "0,90", "-p", "=abcd", NULL); CHECK(solstice_args_init(&args, cmd_size(cmd), cmd), RES_BAD_ARG); cmd_delete(cmd); }