solstice-solver

Solver library of the solstice app
git clone git://git.meso-star.com/solstice-solver.git
Log | Files | Refs | README | LICENSE

commit a6f399bea429efc48db8a6f8cec5e5979c398963
parent 3d21cacdfd8f31136192afeab00381921c62fc4b
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Sat, 24 Sep 2016 15:04:23 +0200

BugFix: management of failed realisations

They are now replayed untill success or general failure

Diffstat:
Msrc/ssol_solver.c | 59++++++++++++++++++++++++++++++++++++-----------------------
Msrc/test_ssol_postprocess.h | 23++++++++---------------
Msrc/test_ssol_solver1.c | 10+++++-----
Msrc/test_ssol_solver2.c | 2+-
Msrc/test_ssol_solver2b.c | 2+-
Msrc/test_ssol_solver3.c | 2+-
Msrc/test_ssol_solver4.c | 2+-
Msrc/test_ssol_solver5.c | 2+-
8 files changed, 54 insertions(+), 48 deletions(-)

diff --git a/src/ssol_solver.c b/src/ssol_solver.c @@ -671,30 +671,43 @@ ssol_solve res = init_realisation(scene, rng, output, &rs); if (res != RES_OK) goto error; - FOR_EACH(r, 0, realisations_count) { - reset_realisation(r, &rs); - sample_point_on_primary_mirror(&rs); - sample_input_sundir(&rs); - sample_wavelength(&rs); - - /* check if the point receives sun light */ - if (receive_sunlight(&rs)) { - /* start propagating from mirror */ - do { - if (RES_OK != setup_next_segment(&rs)) { - rs.end = TERM_ERR; - } else { - propagate(&rs); - } - } while (rs.end == TERM_NONE); - } - - /* propagation ended */ - fprintf(output, "Realisation %u success mask: 0x%0x\n", - (unsigned)r, rs.success_mask); - fprintf(output, "Realisation %u end: %s\n\n", - (unsigned)r, END_TEXT[rs.end]); + for (r = 0; r < realisations_count; ) { + fpos_t real_start; + int err_count = 0; + CHECK(fgetpos(output, &real_start), 0); + do { + reset_realisation(r, &rs); + sample_point_on_primary_mirror(&rs); + sample_input_sundir(&rs); + sample_wavelength(&rs); + + /* check if the point receives sun light */ + if (receive_sunlight(&rs)) { + /* start propagating from mirror */ + do { + if (RES_OK != setup_next_segment(&rs)) { + rs.end = TERM_ERR; + } + else { + propagate(&rs); + } + } while (rs.end == TERM_NONE); + } + /* propagation ended */ + fprintf(output, "Realisation %u success mask: 0x%0x\n", + (unsigned) r, rs.success_mask); + fprintf(output, "Realisation %u end: %s\n\n", + (unsigned) r, END_TEXT[rs.end]); + + /* must retry failed realisations */ + if (rs.end == TERM_ERR) { + CHECK(fsetpos(output, &real_start), 0); + if (++err_count > 10) goto error; + } + else r++; + } while (rs.end == TERM_ERR); } + /* TODO: overwrite trailing chars if canceled realizations wrote past the current fpos */ exit: release_realisation(&rs); diff --git a/src/test_ssol_postprocess.h b/src/test_ssol_postprocess.h @@ -20,12 +20,11 @@ #include <math.h> static INLINE res_T -pp_sum(FILE* f, const char* target, double* mean, double* std) +pp_sum(FILE* f, const char* target, const size_t count, double* mean, double* std) { double sum = 0, sum2 = 0, var; - size_t cpt = 0; char expect_tok[256]; - ASSERT(f && target && mean && std); + ASSERT(f && target && mean && std && count); snprintf(expect_tok, 256, "'%s':", target); rewind(f); while (!feof(f)) { @@ -33,24 +32,18 @@ pp_sum(FILE* f, const char* target, double* mean, double* std) if (fgets(buf, 256, f)) { char tok[256]; double w; - if(2 == sscanf(buf, "Receiver %s %*f %*f %*f %lf", tok, &w)) { + if (2 == sscanf(buf, "Receiver %s %*f %*f %*f %lf", tok, &w)) { if (strcmp(tok, expect_tok)) continue; sum += w; sum2 += w * w; } - else if (1 == sscanf(buf, "Realisation %*d %s:", tok)) { - if (strcmp(tok, "end:")) continue; - cpt++; - } } } - if (cpt) { - *mean = sum / cpt; - var = (sum2 / cpt - *mean * *mean); - *std = var > 0 ? sqrt(var / cpt) : 0; - return RES_OK; - } - return RES_UNKNOWN_ERR; + + *mean = sum / count; + var = (sum2 / count - *mean * *mean); + *std = var > 0 ? sqrt(var / count) : 0; + return RES_OK; } #endif /* TEST_SSOL_POSTPROCESS_H */ diff --git a/src/test_ssol_solver1.c b/src/test_ssol_solver1.c @@ -192,7 +192,7 @@ main(int argc, char** argv) CHECK(!tmp, 0); #define N 5000 CHECK(ssol_solve(scene, rng, N, tmp), RES_OK); - CHECK(pp_sum(tmp, "cible", &m, &std), RES_OK); + CHECK(pp_sum(tmp, "cible", N, &m, &std), RES_OK); logger_print(&logger, LOG_OUTPUT, "\nP = %g +/- %g\n", m, std); #define DNI_cos (1000 * cos(PI / 4)) CHECK(eq_eps(m, 4 * DNI_cos, 4 * DNI_cos * 1e-2), 1); @@ -209,7 +209,7 @@ main(int argc, char** argv) tmp = tmpfile(); CHECK(ssol_solve(scene, rng, N, tmp), RES_OK); - CHECK(pp_sum(tmp, "cible", &m, &std), RES_OK); + CHECK(pp_sum(tmp, "cible", N, &m, &std), RES_OK); logger_print(&logger, LOG_OUTPUT, "\nP = %g +/- %g\n", m, std); CHECK(eq_eps(m, 4 * DNI_cos, 4 * DNI_cos * 1e-4), 1); CHECK(eq_eps(std, 0, 1e-4), 1); @@ -224,7 +224,7 @@ main(int argc, char** argv) NCHECK(tmp = tmpfile(), 0); CHECK(ssol_solve(scene, rng, N, tmp), RES_OK); - CHECK(pp_sum(tmp, "cible", &m, &std), RES_OK); + CHECK(pp_sum(tmp, "cible", N, &m, &std), RES_OK); logger_print(&logger, LOG_OUTPUT, "\nP = %g +/- %g\n", m, std); CHECK(fclose(tmp), 0); CHECK(eq_eps(m, 4 * DNI_cos, 4 * DNI_cos * 1e-4), 1); @@ -243,7 +243,7 @@ main(int argc, char** argv) NCHECK(tmp = tmpfile(), 0); CHECK(ssol_solve(scene, rng, N, tmp), RES_OK); - CHECK(pp_sum(tmp, "cible", &m, &std), RES_OK); + CHECK(pp_sum(tmp, "cible", N, &m, &std), RES_OK); logger_print(&logger, LOG_OUTPUT, "\nP = %g +/- %g\n", m, std); CHECK(fclose(tmp), 0); #define K (exp(-0.1 * 2 * sqrt(2))) @@ -262,7 +262,7 @@ main(int argc, char** argv) CHECK(ssol_spectrum_setup(abs, wavelengths, ka, 2), RES_OK); NCHECK(tmp = tmpfile(), 0); CHECK(ssol_solve(scene, rng, N, tmp), RES_OK); - CHECK(pp_sum(tmp, "cible", &m, &std), RES_OK); + CHECK(pp_sum(tmp, "cible", N, &m, &std), RES_OK); logger_print(&logger, LOG_OUTPUT, "\nP = %g +/- %g\n", m, std); CHECK(fclose(tmp), 0); #define K2 (exp(-0.121 * 2 * sqrt(2))) diff --git a/src/test_ssol_solver2.c b/src/test_ssol_solver2.c @@ -179,7 +179,7 @@ main(int argc, char** argv) tmp = tmpfile(); #define N 10000 CHECK(ssol_solve(scene, rng, N, tmp), RES_OK); - CHECK(pp_sum(tmp, "cible", &m, &std), RES_OK); + CHECK(pp_sum(tmp, "cible", N, &m, &std), RES_OK); logger_print(&logger, LOG_OUTPUT, "\nP = %g +/- %g\n", m, std); #define DNI_cos (1000 * cos(PI / 4)) CHECK(eq_eps(m, 4 * DNI_cos, 4 * DNI_cos * 1e-4), 1); diff --git a/src/test_ssol_solver2b.c b/src/test_ssol_solver2b.c @@ -184,7 +184,7 @@ main(int argc, char** argv) tmp = tmpfile(); #define N 10000 CHECK(ssol_solve(scene, rng, N, tmp), RES_OK); - CHECK(pp_sum(tmp, "cible", &m, &std), RES_OK); + CHECK(pp_sum(tmp, "cible", N, &m, &std), RES_OK); logger_print(&logger, LOG_OUTPUT, "\nP = %g +/- %g\n", m, std); #define DNI_cos (1000 * cos(PI / 4)) CHECK(eq_eps(m, 2 * DNI_cos, 2 * DNI_cos * 1e-2), 1); diff --git a/src/test_ssol_solver3.c b/src/test_ssol_solver3.c @@ -140,7 +140,7 @@ main(int argc, char** argv) tmp = tmpfile(); #define N 10000 CHECK(ssol_solve(scene, rng, N, tmp), RES_OK); - CHECK(pp_sum(tmp, "cible", &m, &std), RES_OK); + CHECK(pp_sum(tmp, "cible", N, &m, &std), RES_OK); logger_print(&logger, LOG_OUTPUT, "\nP = %g +/- %g\n", m, std); #define DNI_cos (1000 * cos(PI / 4)) CHECK(eq_eps(m, 4 * DNI_cos, 4 * DNI_cos * 2e-1), 1); diff --git a/src/test_ssol_solver4.c b/src/test_ssol_solver4.c @@ -140,7 +140,7 @@ main(int argc, char** argv) tmp = tmpfile(); #define N 10000 CHECK(ssol_solve(scene, rng, N, tmp), RES_OK); - CHECK(pp_sum(tmp, "cible", &m, &std), RES_OK); + CHECK(pp_sum(tmp, "cible", N, &m, &std), RES_OK); logger_print(&logger, LOG_OUTPUT, "\nP = %g +/- %g\n", m, std); #define DNI_cos (1000 * cos(0)) CHECK(eq_eps(m, 400 * DNI_cos, 1), 1); diff --git a/src/test_ssol_solver5.c b/src/test_ssol_solver5.c @@ -140,7 +140,7 @@ main(int argc, char** argv) tmp = tmpfile(); #define N 10000 CHECK(ssol_solve(scene, rng, N, tmp), RES_OK); - CHECK(pp_sum(tmp, "cible", &m, &std), RES_OK); + CHECK(pp_sum(tmp, "cible", N, &m, &std), RES_OK); logger_print(&logger, LOG_OUTPUT, "\nP = %g +/- %g\n", m, std); #define DNI_cos (1000 * cos(0)) CHECK(eq_eps(m, 400 * DNI_cos, 20), 1);