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 536142e34610080ae1db7d8dcc833fb55cfb5367
parent cfc3a8fcd4c0ccb18b3ea3e115e3db6874f5517d
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Fri, 21 Aug 2026 16:56:26 +0200

Add an arg to set the sun direction algorithm

Either meeus or psa (default) at this stage.

Diffstat:
MMakefile | 1+
MMakefile.core | 1+
Mconfig.mk | 1+
Mdoc/solstice.1.in | 28+++++++++++++++++++++++++---
Msrc/solstice.c | 10++++++++++
Msrc/solstice.h | 6++++++
Msrc/solstice_args.c | 47++++++++++++++++++++++++++++++++++++++++++-----
Msrc/solstice_args.h.in | 9++++++++-
Msrc/solstice_sun.c | 2+-
9 files changed, 95 insertions(+), 10 deletions(-)

diff --git a/Makefile b/Makefile @@ -97,6 +97,7 @@ doc/solstice.1: doc/solstice.1.in -e 's/@SOLSTICE_ARGS_DEFAULT_IMG_WIDTH@/$(SOLSTICE_ARGS_DEFAULT_IMG_WIDTH)/' \ -e 's/@SOLSTICE_ARGS_DEFAULT_IMG_HEIGHT@/$(SOLSTICE_ARGS_DEFAULT_IMG_HEIGHT)/' \ -e 's/@SOLSTICE_ARGS_DEFAULT_IMG_SPP@/$(SOLSTICE_ARGS_DEFAULT_IMG_SPP)/' \ + -e 's/@SOLSTICE_ARGS_DEFAULT_SUN_DIRECTION_ALGORITHM@/$(SOLSTICE_ARGS_DEFAULT_SUN_DIRECTION_ALGORITHM)/' \ $@.in > $@ ################################################################################ diff --git a/Makefile.core b/Makefile.core @@ -81,6 +81,7 @@ src/solstice_args.h: src/.config_core src/solstice_args.h.in -e 's/@SOLSTICE_ARGS_DEFAULT_IMG_WIDTH@/$(SOLSTICE_ARGS_DEFAULT_IMG_WIDTH)/' \ -e 's/@SOLSTICE_ARGS_DEFAULT_IMG_HEIGHT@/$(SOLSTICE_ARGS_DEFAULT_IMG_HEIGHT)/' \ -e 's/@SOLSTICE_ARGS_DEFAULT_IMG_SPP@/$(SOLSTICE_ARGS_DEFAULT_IMG_SPP)/' \ + -e 's/@SOLSTICE_ARGS_DEFAULT_SUN_DIRECTION_ALGORITHM@/SOLSTICE_ARGS_SUN_DIRECTION_ALGORITHM_$(SOLSTICE_ARGS_DEFAULT_SUN_DIRECTION_ALGORITHM)/' \ $@.in > $@ src/solstice_version.h: src/.config_core src/solstice_version.h.in diff --git a/config.mk b/config.mk @@ -24,6 +24,7 @@ SOLSTICE_ARGS_DEFAULT_CAMERA_FOV = 70 SOLSTICE_ARGS_DEFAULT_IMG_WIDTH = 800 SOLSTICE_ARGS_DEFAULT_IMG_HEIGHT = 600 SOLSTICE_ARGS_DEFAULT_IMG_SPP = 1 +SOLSTICE_ARGS_DEFAULT_SUN_DIRECTION_ALGORITHM = psa ################################################################################ # Tools diff --git a/doc/solstice.1.in b/doc/solstice.1.in @@ -108,6 +108,23 @@ All coordinates in follow the right-handed convention. .Sh OPTIONS .Bl -tag -width Ds +.It Fl A Ar algorithm Ns +The algorithm used to compute sun directions. +Only meaningful if a direction needs to be computed from a location. +Available algorithms are: +.Bl -tag -width Ds +.It Ar psa +The algorithm published by Manuel Blanco et al. in Solar Energy +.Pq see Sy Blanco et al. in the SEE ALSO section . +.It Ar meeus +The algorithm published by J. Meeus in Astronomical Algorithms +.Pq see Sy Meeus in the SEE ALSO section . +.El +.Pp +By default +.Ar algorithm +is set to +.Sy @SOLSTICE_ARGS_DEFAULT_SUN_DIRECTION_ALGORITHM@ . .It Fl D Ar azimuth,elevation Ns A sun direction, defined by two angles in degrees. The first one is the azimuthal angle in [0,\ 360[, and the second one @@ -330,8 +347,7 @@ date -u +"%Y-%m-%dT%H:%M:%S" Each provided .Ar time is used in conjunction with the last provided location to compute a -sun direction using the PSA algorithm -.Pq see Sy Blanco et al. in the SEE ALSO section +sun direction using the selected algorithm and triggers a new computation whose results are concatenated to the .Ar output . @@ -368,9 +384,10 @@ The solar facility is described in and the receivers on which the integrations must be performed are declared in .Pa rcvs.yaml . +The sun direction is computed using the psa algorithm. The results are written to standard output: .Bd -literal -offset indent -solstice -L43.605,1.445 -T"2022-05-01T12:00:00" -R rcvs.yaml input.yaml +solstice -L43.605,1.445 -A psa -T"2022-05-01T12:00:00" -R rcvs.yaml input.yaml .Ed .Pp Generate a mesh for each geometry described in @@ -453,6 +470,11 @@ solstice -D180,45 -r up=0,0,1:rmode=pt:spp=64 solplant.yaml | sed '1d' | feh - .%D 2001 .%P 431-441 .Re +.Rs +.%A Jean Meeus +.%B Astronomical Algorithms +.%D 1991 +.Re .Sh HISTORY .Nm was initially developed with funding from the diff --git a/src/solstice.c b/src/solstice.c @@ -619,6 +619,16 @@ solstice_init res = setup_sun_dirs(solstice, args); if(res != RES_OK) goto error; + switch(args->sun_algorithm) { + case SOLSTICE_SUN_DIRECTION_ALGORITHM_MEEUS: + solstice->sun_algorithm = SSOL_SUN_DIRECTION_ALGORITHM_MEEUS; + break; + case SOLSTICE_SUN_DIRECTION_ALGORITHM_PSA: + solstice->sun_algorithm = SSOL_SUN_DIRECTION_ALGORITHM_PSA; + break; + default: FATAL("Invalid sun algorithm.\n"); break; + } + if(args->rng_state_input_filename) { solstice->rng_state_input = fopen(args->rng_state_input_filename, "r"); if(!solstice->rng_state_input) { diff --git a/src/solstice.h b/src/solstice.h @@ -165,6 +165,11 @@ enum solstice_sun_dir_type { SOLSTICE_SUN_DIR_LOCATION_TIME }; + +enum solstice_sun_direction_algorithm { + SOLSTICE_SUN_DIRECTION_ALGORITHM_MEEUS, + SOLSTICE_SUN_DIRECTION_ALGORITHM_PSA +}; struct solstice_location_time { struct tm time; double latitude, longitude; @@ -223,6 +228,7 @@ struct solstice { /* Sun directions, either a spherical dir or by location+time */ struct darray_sun_dir sun_dirs; + enum ssol_sun_direction_algorithm sun_algorithm; size_t nexperiments; /* # MC experiments */ FILE* output; /* Output stream */ diff --git a/src/solstice_args.c b/src/solstice_args.c @@ -33,6 +33,14 @@ /******************************************************************************* * Helper functions ******************************************************************************/ +static const char* ALGO_NAMES[] = { "meeus", "psa" }; + +static const char* +algo_to_str(enum solstice_args_sun_direction_algorithm algo) { + ASSERT((unsigned)algo < (sizeof(ALGO_NAMES)/sizeof(*ALGO_NAMES))); + return ALGO_NAMES[algo]; +} + static void print_help(const char* program) { @@ -43,6 +51,9 @@ print_help(const char* program) "man page for more informations.\n\n", program); printf( +" -A <algo> set the algorithm to compute sun directions. Default is %s.\n", + algo_to_str(SOLSTICE_ARGS_DEFAULT.sun_algorithm)); + printf( " -D <dir> request a computation for a sun direction.\n"); printf( " -f overwrite the output files if they already exist, i.e. the\n" @@ -192,15 +203,38 @@ error: } static res_T +parse_sun_algorithm(const char* str, struct solstice_args* args) +{ + res_T res = RES_OK; + ASSERT(str && args); + + if(0 == strcmp(str, "meeus")) { + args->sun_algorithm = SOLSTICE_ARGS_SUN_DIRECTION_ALGORITHM_meeus; + } + else if(0 == strcmp(str, "psa")) { + args->sun_algorithm = SOLSTICE_ARGS_SUN_DIRECTION_ALGORITHM_psa; + } + else { + res = RES_BAD_ARG; + fprintf(stderr, "Invalid sun algorithm `%s'.\n", str); + goto error; + } + +exit: + return res; +error: + goto exit; +} + +static res_T parse_location (const char* str, - double current_loc[2], - struct solstice_args* args) + double current_loc[2]) { size_t len; double tmp[2]; res_T res = RES_OK; - ASSERT(str && current_loc && args); + ASSERT(str && current_loc); res = cstr_to_list_double(str, ',', tmp, &len, 2); if(res != RES_OK || len != 2) { @@ -627,8 +661,11 @@ solstice_args_init(struct solstice_args* args, const int argc, char** argv) } optind = 0; - while((opt = getopt(argc, argv, "D:fG:g:hI:n:L:o:p:qR:r:T:t:v")) != -1) { + while((opt = getopt(argc, argv, "A:D:fG:g:hI:n:L:o:p:qR:r:T:t:v")) != -1) { switch(opt) { + case 'A': /* 1 sun direction */ + res = parse_sun_algorithm(optarg, args); + break; case 'D': /* 1 sun direction */ res = parse_sun_spherical(optarg, args); break; @@ -661,7 +698,7 @@ solstice_args_init(struct solstice_args* args, const int argc, char** argv) break; case 'L': /* Plant location */ L_defined = 1; - res = parse_location(optarg, current_loc, args); + res = parse_location(optarg, current_loc); break; case 'n': /* Define the number of MC samples */ res = cstr_to_ulong(optarg, &args->nexperiments); diff --git a/src/solstice_args.h.in b/src/solstice_args.h.in @@ -35,6 +35,11 @@ enum solstice_args_sun_dir_type { SOLSTICE_ARGS_LOCATION_TIME }; +enum solstice_args_sun_direction_algorithm { + SOLSTICE_ARGS_SUN_DIRECTION_ALGORITHM_meeus, + SOLSTICE_ARGS_SUN_DIRECTION_ALGORITHM_psa +}; + struct solstice_args_spherical { double azimuth; double elevation; @@ -74,6 +79,7 @@ struct solstice_args { double dni; unsigned long nexperiments; /* #experiments */ unsigned nthreads; /* #threads */ + enum solstice_args_sun_direction_algorithm sun_algorithm; /* List of sun directions */ struct solstice_args_sun_dir* sun_dirs; @@ -122,9 +128,10 @@ static const struct solstice_args SOLSTICE_ARGS_NULL = SOLSTICE_ARGS_NULL__; NULL, /* output_filename */ \ NULL, /* input_filename */ \ NULL, /* receivers_filename */ \ - -1, \ + -1, \ @SOLSTICE_ARGS_DEFAULT_NREALISATIONS@, \ SSOL_NTHREADS_DEFAULT, \ + @SOLSTICE_ARGS_DEFAULT_SUN_DIRECTION_ALGORITHM@, \ \ NULL, /* sun_dirs */ \ 0, /* # nsun_dirs */ \ diff --git a/src/solstice_sun.c b/src/solstice_sun.c @@ -245,7 +245,7 @@ solstice_create_sun(struct solstice* solstice) } if(res != RES_OK) goto error; - res = ssol_sun_set_algorithm(sun, SSOL_SUN_DIRECTION_ALGORITHM_PSA); + res = ssol_sun_set_algorithm(sun, solstice->sun_algorithm); if(res != RES_OK) { fprintf(stderr, "Could not setup the sun direction algorithm.\n"); goto error;