solstice-pp

Post-processing utilities for the solstice app
git clone git://git.meso-star.com/solstice-pp.git
Log | Files | Refs | README | LICENSE

commit 691e5bd1efaa745b35b5c5fcd9836faf54dd3e14
parent c2d8c758327f17b3599819bf442ac61a8b9a8eac
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Fri, 26 Jun 2026 14:52:44 +0200

Keep with solstice output changes and fix stdin

Solstice now simulates 2 kinds of sun directions: the original one +
direction defined through location+date.
This addition creates a new kind of output that needed to be addressed
by the post-processes.
Also, testing showed crashes when solpp or solppraw where used in a pipe
expression (due to an attempt to move the file ptr accross stdin).
This bug is fixed by this commit.

Diffstat:
Msrc/solmaps.c | 40++++++++++++++++++++++++++++------------
Msrc/solpaths.c | 25+++++++++++++++++--------
Msrc/solpp.c | 53+++++++++++++++++++++++++++++++++--------------------
Msrc/solpp.h | 84++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------
Msrc/solppraw.c | 47++++++++++++++++++++++++++++++++---------------
5 files changed, 161 insertions(+), 88 deletions(-)

diff --git a/src/solmaps.c b/src/solmaps.c @@ -15,6 +15,8 @@ #include "solpp.h" +#include <string.h> + int main(int argc, char** argv) { @@ -22,41 +24,55 @@ main(int argc, char** argv) buf_char_T buf = BUF_NULL; FILE* input = stdin; char* line = NULL; - double azim = -1; - double elev = -1; + double azim, elev, lat, lon; + int case_dir = 0; + char time[64]; + buf_char_T dont_read = BUF_NULL; if(argc > 1 && !(input = fopen(argv[1], "r"))) { fprintf(stderr, "Could not open the file `%s'.\n", argv[1]); return 1; } - line = read_line(&buf, input); + line = read_line(&buf, input, &dont_read); + while(line) { if(!strncmp(line, "#--- Sun direction:", 19)) { + case_dir = 1; /* Get the solar direction */ - CHK(sscanf(line+19, "%lf %lf (%*f %*f %*f)", &azim, &elev)==2); - line = read_line(&buf, input); + CHK(sscanf(line+19, "%lf %lf (%*f %*f %*f)", &azim, &elev) == 2); + line = read_line(&buf, input, &dont_read); + } else if(!strncmp(line, "#--- Sun location and time:", 27)) { + /* Get the location and time */ + case_dir = 0; + memset(time, 0, sizeof(time)); + CHK(strlen(line+27) < sizeof(time)); + CHK(sscanf(line+27, "%lf %lf %s (%*f %*f %*f)", &lat, &lon, time) == 3); + line = read_line(&buf, input, &dont_read); } else if(!strncmp(line, "# vtk", 5)) { char* header = NULL; char* rcv_name = NULL; FILE* output; - CHK(azim >= 0 && elev >= 0); - CHK(header = strdup(line)); /* Duplicate the current line */ - CHK(line = read_line(&buf, input)); + CHK(line = read_line(&buf, input, &dont_read)); CHK(rcv_name = strdup(line)); /* Duplicate the line of the receiver name */ /* Create the name of the destination file */ - CHK(snprintf(s, sizeof(s), "%g-%g-%s.vtk", azim, elev, rcv_name) - < (long)sizeof(s)); + if(case_dir) { + CHK(snprintf(s, sizeof(s), "%g-%g-%s.vtk", azim, elev, rcv_name) + < (long)sizeof(s)); + } else { + CHK(snprintf(s, sizeof(s), "%g-%g-%s-%s.vtk", lat, lon, time, rcv_name) + < (long)sizeof(s)); + } printf("Writing `%s'\n", s); CHK(output = fopen(s, "w")); /* Write the map data into `output' */ fprintf(output, "%s\n", header); fprintf(output, "%s\n", rcv_name); - while((line = read_line(&buf, input)) && line[0] != '#') { + while((line = read_line(&buf, input, &dont_read)) && line[0] != '#') { fprintf(output, "%s\n", line); } @@ -65,7 +81,7 @@ main(int argc, char** argv) free(header); free(rcv_name); } else { - line = read_line(&buf, input); + line = read_line(&buf, input, &dont_read); } } diff --git a/src/solpaths.c b/src/solpaths.c @@ -23,23 +23,32 @@ main(int argc, char** argv) FILE* input = stdin; FILE* output = NULL; char* line = NULL; - double azim = 0; - double elev = 0; + double azim, elev, lat, lon; + char time[64]; if(argc > 1 && !(input = fopen(argv[1], "r"))) { fprintf(stderr, "Could not open the file `%s'.\n", argv[1]); return 1; } - while((line = read_line(&buf, input))) { - if(strncmp(line, "#--- Sun direction:", 19)) { - CHK(output != NULL); - fprintf(output, "%s\n", line); - } else { + while((line = read_line(&buf, input, NULL))) { + if(!strncmp(line, "#--- Sun direction:", 19)) { CHK(sscanf(line+19, "%lf %lf (%*f %*f %*f)", &azim, &elev) == 2); - CHK(snprintf(s, sizeof(s), "%g-%g-paths.vtk", azim, elev) < (long)sizeof(s)); + CHK(snprintf(s, sizeof(s), "%g-%g-paths.vtk", azim, elev) + < (long)sizeof(s)); if(output) fclose(output); printf("Writing `%s'\n", s); CHK(output = fopen(s, "w")); + } else if(!strncmp(line, "#--- Sun location and time:", 27)) { + memset(time, 0, sizeof(time)); + CHK(sscanf(line+27, "%lf %lf %s (%*f %*f %*f)", &lat, &lon, time) == 3); + CHK(snprintf(s, sizeof(s), "%g-%g-%s-paths.vtk", lat, lon, time) + < (long)sizeof(s)); + if(output) fclose(output); + printf("Writing `%s'\n", s); + CHK(output = fopen(s, "w")); + } else { + CHK(output != NULL); + fprintf(output, "%s\n", line); } } BUF_RELEASE(buf); diff --git a/src/solpp.c b/src/solpp.c @@ -196,7 +196,8 @@ main(int argc, char** argv) { buf_char_T buf = BUF_NULL; char* line = NULL; - + buf_char_T dont_read_i = BUF_NULL; + buf_char_T dont_read_g = BUF_NULL; FILE* input; FILE* geom; FILE* output; @@ -209,8 +210,7 @@ main(int argc, char** argv) CHK(geom = fopen(argv[1], "r")); CHK(input = fopen(argv[2], "r")); - CHK(read_line(&buf, geom)); /* Skip the sun direction of the geometry */ - while((line = read_line(&buf, input))) { + while((line = read_line(&buf, input, &dont_read_i))) { struct simul simul; const struct rcv* rcv = NULL; @@ -227,13 +227,23 @@ main(int argc, char** argv) simul_init(&simul); - CHK(!strncmp(line, "#--- Sun direction:", 19)); - CHK(sscanf(line+19, "%lf %lf (%*f %*f %*f)", &simul.azimuth, &simul.elevation)==2); - CHK(snprintf(prefix, sizeof(prefix), "%g-%g-", - simul.azimuth, simul.elevation) < (long)sizeof(prefix)); - read_simulation(&simul, input); + if(!strncmp(line, "#--- Sun direction:", 19)) { + CHK(sscanf(line+19, "%lf %lf (%*f %*f %*f)", + &simul.azimuth, &simul.elevation)==2); + CHK(snprintf(prefix, sizeof(prefix), "%g-%g-", + simul.azimuth, simul.elevation) + < (long)sizeof(prefix)); + } else if(!strncmp(line, "#--- Sun location and time:", 27)) { + memset(simul.time, 0, sizeof(simul.time)); + CHK(sscanf(line+27, "%lf %lf %s (%*f %*f %*f)", + &simul.latitude, &simul.longitude, simul.time) == 3); + CHK(snprintf(prefix, sizeof(prefix), "%g-%g-%s-", + simul.latitude, simul.longitude, simul.time) + < (long)sizeof(prefix)); + } + read_simulation(&simul, input, &dont_read_i); - while((line = read_line(&buf, geom)) && strncmp(line, "#--- Sun", 8)) { + while((line = read_line(&buf, geom, &dont_read_g)) && strncmp(line, "#--- Sun", 8)) { if(!strncmp(line, "g ", 2)) { if(prim) { BUF_PUSH(msh_prim.ncells, ntris_grp); @@ -301,28 +311,32 @@ main(int argc, char** argv) if(prim) { BUF_PUSH(msh_prim.ncells, ntris_grp); } if(rcv) { BUF_PUSH(msh_rcv.ncells, ntris_grp); } - CHK(snprintf(filename, sizeof(filename), - "%sprimaries.vtk", prefix) < (long)sizeof(prefix)); + CHK(snprintf(filename, sizeof(filename), "%sprimaries.vtk", prefix) + < (long)sizeof(filename)); printf("Writing `%s'\n", filename); CHK(output = fopen(filename, "w")); mesh_write_vtk(output, &msh_prim); mesh_write_prim_data_vtk(output, &msh_prim, &simul); fclose(output); - CHK(snprintf(filename, sizeof(filename), - "%sreceivers.vtk", prefix) < (long)sizeof(prefix)); + CHK(snprintf(filename, sizeof(filename), "%sreceivers.vtk", prefix) + < (long)sizeof(filename)); printf("Writing `%s'\n", filename); CHK(output = fopen(filename, "w")); mesh_write_vtk(output, &msh_rcv); mesh_write_rcv_data_vtk(output, &msh_rcv, &simul); fclose(output); - CHK(snprintf(filename, sizeof(filename), - "%smiscellaneous.obj", prefix) < (long)sizeof(prefix)); - printf("Writing `%s'\n", filename); - CHK(output = fopen(filename, "w")); - mesh_write_obj(output, &msh_misc); - fclose(output); + CHK(snprintf(filename, sizeof(filename), "%smiscellaneous.obj", prefix) + < (long)sizeof(filename)); + if(BUF_SZ(msh_misc.coords) == 0) { + printf("No miscellanous geometry to write `%s'\n", filename); + } else { + printf("Writing `%s'\n", filename); + CHK(output = fopen(filename, "w")); + mesh_write_obj(output, &msh_misc); + fclose(output); + } mesh_release(&msh_prim); mesh_release(&msh_rcv); @@ -335,4 +349,3 @@ main(int argc, char** argv) BUF_RELEASE(buf); return 0; } - diff --git a/src/solpp.h b/src/solpp.h @@ -59,6 +59,13 @@ struct mc { double E/* Expected value */, SE/* Standard Error */; }; #define BUF_SZ(B) (B).sz #define BUF_MEM(B) (B).mem #define BUF_AT(B, I) (B).mem[I] +#define BUF_MOVE(D, S) (D).mem=(S).mem,(S).mem=NULL, \ + (D).ca=(S).ca,(S).ca=0, \ + (D).sz=(S).sz,(S).sz=0 +#define BUF_SAVE(B, Data, Sz) (B).mem=realloc((B).mem, (Sz)), \ + memcpy((B).mem,(Data),sizeof(*(B).mem)*(Sz)), \ + (B).sz=(B).ca=(Sz), \ + (Data)=NULL /******************************************************************************* * Helper function @@ -66,10 +73,15 @@ struct mc { double E/* Expected value */, SE/* Standard Error */; }; typedef BUF(char) buf_char_T; static inline char* -read_line(buf_char_T* b, FILE* stream) +read_line(buf_char_T* b, FILE* stream, buf_char_T* dont_read) { char* c; + if(dont_read && BUF_MEM(*dont_read) != NULL) { + BUF_MOVE(*b, *dont_read); + return BUF_MEM(*b); + } + if(!BUF_SZ(*b)) { BUF_RESIZE(*b, 32); } if(!fgets(BUF_MEM(*b), (int)BUF_SZ(*b), stream)) return NULL; @@ -83,7 +95,6 @@ read_line(buf_char_T* b, FILE* stream) /* Remove the carriage return */ if((c = strrchr(BUF_MEM(*b), '\n'))) *c = '\0'; - return BUF_MEM(*b); } @@ -162,6 +173,9 @@ struct simul { double azimuth; double elevation; + double latitude; + double longitude; + char time[64]; size_t nsamps; }; @@ -233,7 +247,11 @@ find_rcvXprim(struct simul* s, const size_t rcv_id, const size_t prim_id) * Read simulation data from a solstice-output ******************************************************************************/ static inline void -read_receiver_map_side_data(struct rcv* rcv, const size_t n, FILE* input) +read_receiver_map_side_data + (struct rcv* rcv, + const size_t n, + FILE* input, + buf_char_T* dont_read) { buf_char_T buf = BUF_NULL; char* line = NULL; @@ -242,22 +260,23 @@ read_receiver_map_side_data(struct rcv* rcv, const size_t n, FILE* input) enum flux_density flux; const char* str; - CHK(line = read_line(&buf, input)); + CHK(line = read_line(&buf, input, dont_read)); + str = line + 8; if(!strncmp(str, "Front_faces", 11)) { side = FRONT; str += 12; } else if(!strncmp(str, "Back_faces", 10)) { side = BACK; str += 11; } - else { fprintf(stderr, "Unexpected side name\n"); abort(); } + else { fprintf(stderr, "Unexpected side name: '%s'\n", str); abort(); } if(!strncmp(str, "Incoming_flux", 13)) { flux = INCOMING; } else if(!strncmp(str, "Absorbed_flux", 13)) { flux = ABSORBED; } - else { fprintf(stderr, "Unexpected flux name\n"); abort(); } + else { fprintf(stderr, "Unexpected flux name: '%s'\n", str); abort(); } - CHK(read_line(&buf, input)); /* Discard "LOOKUP_TABLE default" line */ + CHK(read_line(&buf, input, dont_read)); /* Discard "LOOKUP_TABLE default" line */ BUF_RESIZE(rcv->map[flux][side], n); FOR_EACH(i, 0, n) { struct mc* mc = &BUF_AT(rcv->map[flux][side], i); - CHK(line = read_line(&buf, input)); + CHK(line = read_line(&buf, input, dont_read)); CHK(sscanf(line, "%lf %lf", &mc->E, &mc->SE) == 2); } @@ -265,44 +284,43 @@ read_receiver_map_side_data(struct rcv* rcv, const size_t n, FILE* input) } static inline void -read_receiver_map(struct simul* simul, FILE* input) +read_receiver_map(struct simul* simul, FILE* input, buf_char_T* dont_read) { struct rcv* rcv; buf_char_T buf = BUF_NULL; char* line = NULL; size_t i, n; - long fp; - CHK(line = read_line(&buf, input)); + CHK(line = read_line(&buf, input, dont_read)); + CHK(rcv = find_receiver(simul, line)); /* Skip header */ - CHK(read_line(&buf, input)); - CHK(read_line(&buf, input)); + CHK(read_line(&buf, input, dont_read)); + CHK(read_line(&buf, input, dont_read)); /* Skip vertices */ - CHK(line = read_line(&buf, input)); + CHK(line = read_line(&buf, input, dont_read)); CHK(sscanf(line, "POINTS %zu float", &n) == 1); - FOR_EACH(i, 0, n) { CHK(read_line(&buf, input)); } + FOR_EACH(i, 0, n) { CHK(read_line(&buf, input, dont_read)); } /* Skip polygons */ - CHK(line = read_line(&buf, input)); + CHK(line = read_line(&buf, input, dont_read)); CHK(sscanf(line, "POLYGONS %zu %*u", &n) == 1); - FOR_EACH(i, 0, n) { CHK(read_line(&buf, input)); } + FOR_EACH(i, 0, n) { CHK(read_line(&buf, input, dont_read)); } /* Read the map data of one side */ - CHK(line = read_line(&buf, input)); + CHK(line = read_line(&buf, input, dont_read)); CHK(sscanf(line, "CELL_DATA %zu", &n) == 1); /* Read map data */ do { - read_receiver_map_side_data(rcv, n, input); - fp = ftell(input); - line = read_line(&buf, input); - fseek(input, fp, SEEK_SET); + read_receiver_map_side_data(rcv, n, input, dont_read); + line = read_line(&buf, input, dont_read); + BUF_SAVE(*dont_read, line, 1+strlen(line)); } while(line && !strncmp(line, "SCALARS", 7)); BUF_RELEASE(buf); } static inline void -read_simulation(struct simul* simul, FILE* input) +read_simulation(struct simul* simul, FILE* input, buf_char_T* dont_read) { buf_char_T buf = BUF_NULL; char* line = NULL; @@ -311,12 +329,12 @@ read_simulation(struct simul* simul, FILE* input) size_t i; /* Counters */ - CHK(line = read_line(&buf, input)); + CHK(line = read_line(&buf, input, dont_read)); CHK(sscanf(line, "%*u %zu %zu %zu %*u", &nrcvs, &nprims, &simul->nsamps)==3); /* Global results */ #define READ(Name) { \ - CHK(line = read_line(&buf, input)); \ + CHK(line = read_line(&buf, input, dont_read)); \ CHK(sscanf(line, "%lf %lf", &simul->Name.E, &simul->Name.SE) == 2); \ } (void)0 READ(potential_flux); @@ -334,7 +352,7 @@ read_simulation(struct simul* simul, FILE* input) struct rcv* rcv = &BUF_AT(simul->rcvs, i); rcv_init(rcv); - CHK(line = read_line(&buf, input)); + CHK(line = read_line(&buf, input, dont_read)); CHK(tk = strtok(line, " \t")); CHK(rcv->name = strdup(tk)); @@ -381,7 +399,7 @@ read_simulation(struct simul* simul, FILE* input) struct prim* prim = &BUF_AT(simul->prims, i); prim_init(prim); - CHK(line = read_line(&buf, input)); + CHK(line = read_line(&buf, input, dont_read)); CHK(tk = strtok(line, " \t")); CHK(prim->name = strdup(tk)); @@ -398,7 +416,7 @@ read_simulation(struct simul* simul, FILE* input) struct rcvXprim* rcvXprim = &BUF_AT(simul->rcvXprims, i); rcvXprim_init(rcvXprim); - CHK(line = read_line(&buf, input)); + CHK(line = read_line(&buf, input, dont_read)); #define GET(Side, Name) &rcvXprim->Name[Side].E, &rcvXprim->Name[Side].SE CHK(sscanf (line, @@ -433,13 +451,13 @@ read_simulation(struct simul* simul, FILE* input) /* Read receiver maps */ for(;;) { - const long fp = ftell(input); - line = read_line(&buf, input); + line = read_line(&buf, input, dont_read); - if(line && !strncmp(line, "# vtk", 5)) { - read_receiver_map(simul, input); + if(!line) break; + if(!strncmp(line, "# vtk", 5)) { + read_receiver_map(simul, input, dont_read); } else { - fseek(input, fp, SEEK_SET); + BUF_SAVE(*dont_read, line, 1+strlen(line)); break; } } diff --git a/src/solppraw.c b/src/solppraw.c @@ -130,36 +130,53 @@ main(int argc, char** argv) buf_char_T buf = BUF_NULL; FILE* input = stdin; char* line = NULL; + buf_char_T dont_read = BUF_NULL; if(argc > 1 && !(input = fopen(argv[1], "r"))) { fprintf(stderr, "Could not open the file `%s'.\n", argv[1]); return 1; } - while((line = read_line(&buf, input))) { + while((line = read_line(&buf, input, &dont_read))) { struct simul simul; FILE* output = NULL; - if(strncmp(line, "#--- Sun direction:", 19)) continue; + if(!strncmp(line, "#--- Sun direction:", 19)) { + simul_init(&simul); - simul_init(&simul); + CHK(sscanf(line+19, "%lf %lf (%*f %*f %*f)", + &simul.azimuth, &simul.elevation)==2); + CHK(snprintf(s, sizeof(s), "%g-%g-raw-results.txt", + simul.azimuth, simul.elevation) < (long)sizeof(s)); + read_simulation(&simul, input, &dont_read); - CHK(!strncmp(line, "#--- Sun direction:", 19)); - CHK(sscanf(line+19, "%lf %lf (%*f %*f %*f)", - &simul.azimuth, &simul.elevation)==2); - CHK(snprintf(s, sizeof(s), "%g-%g-raw-results.txt", - simul.azimuth, simul.elevation) < (long)sizeof(s)); - read_simulation(&simul, input); + printf("Writing `%s'\n", s); + CHK(output = fopen(s, "w")); + print_simulation(output, &simul); + fclose(output); - printf("Writing `%s'\n", s); - CHK(output = fopen(s, "w")); - print_simulation(output, &simul); - fclose(output); + simul_release(&simul); + } else if(!strncmp(line, "#--- Sun location and time:", 27)) { - simul_release(&simul); + simul_init(&simul); + + memset(simul.time, 0, sizeof(simul.time)); + CHK(sscanf(line+27, "%lf %lf %s (%*f %*f %*f)", + &simul.latitude, &simul.longitude, simul.time) == 3); + CHK(snprintf(s, sizeof(s), "%g-%g-%s-", + simul.latitude, simul.longitude, simul.time) + < (long)sizeof(s)); + read_simulation(&simul, input, &dont_read); + + printf("Writing `%s'\n", s); + CHK(output = fopen(s, "w")); + print_simulation(output, &simul); + fclose(output); + + simul_release(&simul); + } } BUF_RELEASE(buf); if(input && input != stdin) fclose(input); return 0; } -