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 aff12ec445b19c0effbcaed0e5b462b72d691602
parent d1b2c2a80248409f0fc12b05981191e857bab4ad
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Wed, 26 Jul 2017 15:13:30 +0200

Write the primary and receiver data to the output VTKs of solvtk

Diffstat:
Msrc/Makefile | 14++++----------
Msrc/solpp.h | 137+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
Msrc/solvtk.c | 191++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------
3 files changed, 284 insertions(+), 58 deletions(-)

diff --git a/src/Makefile b/src/Makefile @@ -19,7 +19,7 @@ NPATHS=1000 SUN_DIRS=270,45 RCV_FILE=themis-rcv.yaml -CFLAGS = -O2 -std=c99 -pedantic -Wall +CFLAGS = -g -std=c99 -pedantic -Wall SCRIPT = themis.c solsplit.c solpp.c solvtk.c PROG = $(SCRIPT:%.c=%) PATH := $(PATH):$(STAR_ENGINE)/bin:. @@ -31,17 +31,11 @@ all: $(PROG) input: $(PROG) @./themis -.PHONY: output -output: receiver - @themis | solstice -q -n$(NEXPERIMENTS) -D$(SUN_DIRS) -R $(RCV_FILE) - -.PHONY: obj -obj: $(PROG) - themis | solstice -D$(SUN_DIRS) -qg format=obj:split=geometry | solsplit - .PHONY: run run: $(PROG) receiver - themis | solstice -q -n$(NEXPERIMENTS) -D$(SUN_DIRS) -R $(RCV_FILE) | solpp + themis | solstice -D$(SUN_DIRS) -q -n$(NEXPERIMENTS) -R $(RCV_FILE) -fo simul + themis | solstice -D$(SUN_DIRS) -qg format=obj:split=none -fo geom + solvtk geom simul .PHONY: clean clean: diff --git a/src/solpp.h b/src/solpp.h @@ -30,6 +30,10 @@ struct mc { double SE; /* Standard Error */ }; +#define DARRAY_NAME mc +#define DARRAY_DATA struct mc +#include <rsys/dynamic_array.h> + static INLINE char* read_line(char** b, FILE* stream) { @@ -54,6 +58,7 @@ struct rcv { struct mc reflectivity_loss[2]; struct mc absorptivity_loss[2]; struct mc efficiency[2]; + struct darray_mc map[2]; struct str name; size_t id; double area; @@ -64,12 +69,16 @@ rcv_init(struct mem_allocator* allocator, struct rcv* rcv) { memset(rcv, 0, sizeof(struct rcv)); str_init(allocator, &rcv->name); + darray_mc_init(allocator, &rcv->map[0]); + darray_mc_init(allocator, &rcv->map[1]); } static INLINE void rcv_release(struct rcv* rcv) { str_release(&rcv->name); + darray_mc_release(&rcv->map[0]); + darray_mc_release(&rcv->map[1]); } static INLINE res_T @@ -83,6 +92,7 @@ rcv_copy(struct rcv* dst, const struct rcv* src) dst->reflectivity_loss[i] = src->reflectivity_loss[i]; dst->absorptivity_loss[i] = src->absorptivity_loss[i]; dst->efficiency[i] = src->efficiency[i]; + CHECK(darray_mc_copy(&dst->map[i], &src->map[i]), RES_OK); } dst->area = src->area; CHECK(str_copy(&dst->name, &src->name), RES_OK); @@ -100,6 +110,7 @@ rcv_copy_and_release(struct rcv* dst, struct rcv* src) dst->reflectivity_loss[i] = src->reflectivity_loss[i]; dst->absorptivity_loss[i] = src->absorptivity_loss[i]; dst->efficiency[i] = src->efficiency[i]; + CHECK(darray_mc_copy_and_release(&dst->map[i], &src->map[i]), RES_OK); } dst->area = src->area; CHECK(str_copy_and_release(&dst->name, &src->name), RES_OK); @@ -257,6 +268,79 @@ simul_copy_and_release(struct simul* dst, struct simul* src) #define DARRAY_FUNCTOR_COPY_AND_RELEASE simul_copy_and_release #include <rsys/dynamic_array.h> +static void +read_receiver_map_side_data(struct rcv* rcv, const size_t n, FILE* input) +{ + char* buf = NULL; + char* line = NULL; + size_t i; + enum side side; + + NCHECK(line = read_line(&buf, input), NULL); + if(!strncmp(line+8, "Front_faces", 5)) side = FRONT; + else if(!strncmp(line+8, "Back_faces",4)) side = BACK; + else FATAL("Unexpected side name\n"); + + NCHECK(read_line(&buf, input), NULL); /* LUT */ + + CHECK(darray_mc_resize(&rcv->map[side], n), RES_OK); + FOR_EACH(i, 0, n) { + struct mc* mc = darray_mc_data_get(&rcv->map[side])+i; + NCHECK(line = read_line(&buf, input), NULL); + CHECK(sscanf(line, "%lf %lf", &mc->E, &mc->SE), 2); + } + + sa_release(buf); +} + +static void +read_receiver_map(struct simul* simul, FILE* input) +{ + struct rcv* rcv; + char* buf = NULL; + char* line = NULL; + size_t i, n; + long fp; + + NCHECK(line = read_line(&buf, input), NULL); + FOR_EACH(i, 0, darray_rcv_size_get(&simul->rcvs)) { + rcv = darray_rcv_data_get(&simul->rcvs)+i; + if(!strcmp(str_cget(&rcv->name), line)) break; + rcv = NULL; + } + NCHECK(rcv, NULL); + + /* Skip header */ + NCHECK(read_line(&buf, input), NULL); + NCHECK(read_line(&buf, input), NULL); + + /* Skip vertices */ + NCHECK(line = read_line(&buf, input), NULL); + CHECK(sscanf(line, "POINTS %zu float", &n), 1); + FOR_EACH(i, 0, n) NCHECK(read_line(&buf, input), NULL); + + /* Skip polygons */ + NCHECK(line = read_line(&buf, input), NULL); + CHECK(sscanf(line, "POLYGONS %zu %*u", &n), 1); + FOR_EACH(i, 0, n) NCHECK(read_line(&buf, input), NULL); + + /* Read the map data of one side */ + NCHECK(line = read_line(&buf, input), NULL); + CHECK(sscanf(line, "CELL_DATA %zu", &n), 1); + + read_receiver_map_side_data(rcv, n, input); + fp = ftell(input); + + /* Read the optionnal map data of the other side */ + line = read_line(&buf, input); + fseek(input, fp, SEEK_SET); + if(line && !strncmp(line, "SCALAR", 6)) { + read_receiver_map_side_data(rcv, n, input); + } + + sa_release(buf); +} + static INLINE void read_simulation(struct simul* simul, FILE* input) { @@ -353,6 +437,20 @@ read_simulation(struct simul* simul, FILE* input) GET(BACK, absorptivity_loss)), 18); #undef GET } + + /* Read receiver maps */ + for(;;) { + const long fp = ftell(input); + line = read_line(&buf, input); + + if(line && !strncmp(line, "# vtk", 5)) { + read_receiver_map(simul, input); + } else { + fseek(input, fp, SEEK_SET); + break; + } + } + sa_release(buf); } @@ -360,24 +458,59 @@ static INLINE const struct prim* find_primary(const struct simul* simul, const char* name) { size_t i; - for(i=0; i<darray_prim_size_get(&simul->prims); ++i) { + FOR_EACH(i, 0, darray_prim_size_get(&simul->prims)) { const struct prim* prim = darray_prim_cdata_get(&simul->prims)+i; if(!strcmp(str_cget(&prim->name), name)) return prim; } return NULL; } +static INLINE const struct prim* +find_primary_by_id(const struct simul* simul, const size_t id) +{ + size_t i; + FOR_EACH(i, 0, darray_prim_size_get(&simul->prims)) { + const struct prim* prim = darray_prim_cdata_get(&simul->prims)+i; + if(prim->id == id) return prim; + } + return NULL; +} + static INLINE const struct rcv* find_receiver(const struct simul* simul, const char* name) { size_t i; - for(i=0; i<darray_rcv_size_get(&simul->rcvs); ++i) { + FOR_EACH(i, 0, darray_rcv_size_get(&simul->rcvs)) { const struct rcv* rcv = darray_rcv_cdata_get(&simul->rcvs)+i; if(!strcmp(str_cget(&rcv->name), name)) return rcv; } return NULL; } +static INLINE const struct rcv* +find_receiver_by_id(const struct simul* simul, const size_t id) +{ + size_t i; + FOR_EACH(i, 0, darray_rcv_size_get(&simul->rcvs)) { + const struct rcv* rcv = darray_rcv_cdata_get(&simul->rcvs)+i; + if(rcv->id == id) return rcv; + } + return NULL; +} + +static INLINE const struct rcvXprim* +find_rcvXprim + (const struct simul* simul, const size_t rcv_id, const size_t prim_id) +{ + size_t i; + FOR_EACH(i, 0, darray_rcvXprim_size_get(&simul->rcvXprims)) { + const struct rcvXprim* rcvXprim; + rcvXprim = darray_rcvXprim_cdata_get(&simul->rcvXprims)+i; + if(rcvXprim->rcv_id == rcv_id && rcvXprim->prim_id == prim_id) + return rcvXprim; + } + return NULL; +} #endif /* SOLPP_H */ diff --git a/src/solvtk.c b/src/solvtk.c @@ -80,6 +80,119 @@ mesh_write_obj(FILE* output, struct mesh* msh) } } +static void +mesh_write_prim_data_vtk + (FILE* output, const struct mesh* msh, const struct simul* simul) +{ + const struct prim* prim; + const struct rcvXprim* rcvXprim; + size_t ircv; + size_t iprim; + size_t icell; + size_t n; + + n = sa_size(msh->ids) / 3; + fprintf(output, "CELL_DATA %zu\n", n); + + fprintf(output, "FIELD PrimaryData %zu\n", + 2 + darray_rcv_size_get(&simul->rcvs)*8); + fprintf(output, "cos_factor 2 %zu float\n", n); + FOR_EACH(iprim, 0, sa_size(msh->entities)) { + NCHECK(prim = find_primary_by_id(simul, msh->entities[iprim]), NULL); + FOR_EACH(icell, 0, msh->ncells[iprim]) { + fprintf(output, "%g %g\n", prim->cos_factor.E, prim->cos_factor.SE); + } + } + + fprintf(output, "shadow_loss 2 %zu float\n", n); + FOR_EACH(iprim, 0, sa_size(msh->entities)) { + NCHECK(prim = find_primary_by_id(simul, msh->entities[iprim]), NULL); + FOR_EACH(icell, 0, msh->ncells[iprim]) { + fprintf(output, "%g %g\n", prim->shadow_loss.E, prim->shadow_loss.SE); + } + } + + #define WRITE(Side, Name) { \ + fprintf(output, "%s_"STR(Side)"_"STR(Name)" 2 %zu float\n", \ + str_cget(&rcv->name), n); \ + FOR_EACH(iprim, 0, sa_size(msh->entities)) { \ + rcvXprim = find_rcvXprim(simul, rcv->id, msh->entities[iprim]); \ + NCHECK(rcvXprim, NULL); \ + FOR_EACH(icell, 0, msh->ncells[iprim]) { \ + fprintf(output, "%g %g\n", \ + rcvXprim->Name[Side].E, \ + rcvXprim->Name[Side].SE); \ + } \ + } \ + } (void)0 + FOR_EACH(ircv, 0, darray_rcv_size_get(&simul->rcvs)) { + const struct rcv* rcv = darray_rcv_cdata_get(&simul->rcvs)+ircv; + WRITE(FRONT, absorbed_irradiance); + WRITE(FRONT, irradiance); + WRITE(FRONT, reflectivity_loss); + WRITE(FRONT, absorptivity_loss); + WRITE(BACK, absorbed_irradiance); + WRITE(BACK, irradiance); + WRITE(BACK, reflectivity_loss); + WRITE(BACK, absorptivity_loss); + } + #undef WRITE +} + +static void +mesh_write_rcv_data_vtk + (FILE* output, const struct mesh* msh, const struct simul* simul) +{ + const struct rcv* rcv; + size_t ircv; + size_t icell; + size_t n; + + n = sa_size(msh->ids)/3; + fprintf(output, "CELL_DATA %zu\n", n); + + fprintf(output, "FIELD PrimaryData 12\n"); + + #define WRITE(Side, Name) { \ + fprintf(output, STR(Side)"_"STR(Name)" 2 %zu float\n", n); \ + FOR_EACH(ircv, 0, sa_size(msh->entities)) { \ + NCHECK(rcv = find_receiver_by_id(simul, msh->entities[ircv]), NULL); \ + FOR_EACH(icell, 0, msh->ncells[ircv]) { \ + fprintf(output, "%g %g\n", rcv->Name[Side].E, rcv->Name[Side].SE); \ + } \ + } \ + } (void)0 + WRITE(FRONT, absorbed_irradiance); + WRITE(FRONT, irradiance); + WRITE(FRONT, reflectivity_loss); + WRITE(FRONT, absorptivity_loss); + WRITE(FRONT, efficiency); + WRITE(BACK, absorbed_irradiance); + WRITE(BACK, irradiance); + WRITE(BACK, reflectivity_loss); + WRITE(BACK, absorptivity_loss); + WRITE(BACK, efficiency); + #undef WRITE + + #define WRITE_MAP(Side) { \ + fprintf(output, STR(Side)"_map 2 %zu float\n", n); \ + FOR_EACH(ircv, 0, sa_size(msh->entities)) { \ + NCHECK(rcv = find_receiver_by_id(simul, msh->entities[ircv]), NULL); \ + if(!darray_mc_size_get(&rcv->map[Side])) { \ + FOR_EACH(icell, 0, msh->ncells[ircv]) fprintf(output, "-1 -1\n"); \ + } else { \ + FOR_EACH(icell, 0, msh->ncells[ircv]) { \ + const struct mc* mc = darray_mc_cdata_get(&rcv->map[Side])+icell; \ + fprintf(output, "%g %g\n", mc->E, mc->SE); \ + } \ + } \ + } \ + } (void)0 + WRITE_MAP(FRONT); + WRITE_MAP(BACK); + #undef WRITE_MAP +} + int main(int argc, char** argv) { @@ -99,7 +212,8 @@ main(int argc, char** argv) char* line = NULL; char* buf = NULL; char* str = NULL; - size_t ntris = 0, nverts = 0; + size_t ntris_grp = 0, nverts_grp = 0; + size_t nverts_obj = 0, offset_obj = 0; float azim, elev; int err = 0; @@ -126,12 +240,23 @@ main(int argc, char** argv) CHECK(sscanf(line+19, "%f %f (%*f %*f %*f)", &azim, &elev), 2); } else if(!strncmp(line, "g ", 2)) { CHECK(str_set(&name, line+2), RES_OK); + if(prim) { + sa_push(msh_prim.ncells, ntris_grp); + msh_prim.voffset += nverts_grp; + } + if(rcv) { + sa_push(msh_rcv.ncells, ntris_grp); + msh_rcv.voffset += nverts_grp; + } + if(!prim && !rcv) msh_misc.voffset += nverts_grp; prim = find_primary(&simul, line+2); rcv = find_receiver(&simul, line+2); if(prim) sa_push(msh_prim.entities, prim->id); if(rcv) sa_push(msh_rcv.entities, rcv->id); - ntris = 0; - nverts = 0; + ntris_grp = 0; + nverts_grp = 0; + offset_obj = nverts_obj; + } else if(!strncmp(line, "v ", 2)) { double pos[3]; CHECK(sscanf(line+2, "%lf %lf %lf", pos+0, pos+1, pos+2), 3); @@ -150,75 +275,49 @@ main(int argc, char** argv) sa_push(msh_misc.coords, pos[1]); sa_push(msh_misc.coords, pos[2]); } - ++nverts; + ++nverts_grp; + ++nverts_obj; } else if(!strncmp(line, "f ", 2)) { size_t tri[3]; CHECK(sscanf(line+2, "%zu %zu %zu", tri+0, tri+1, tri+2), 3); if(prim) { - sa_push(msh_prim.ids, tri[0] - 1 + msh_prim.voffset); - sa_push(msh_prim.ids, tri[1] - 1 + msh_prim.voffset); - sa_push(msh_prim.ids, tri[2] - 1 + msh_prim.voffset); + sa_push(msh_prim.ids, tri[0] - 1 + msh_prim.voffset - offset_obj); + sa_push(msh_prim.ids, tri[1] - 1 + msh_prim.voffset - offset_obj); + sa_push(msh_prim.ids, tri[2] - 1 + msh_prim.voffset - offset_obj); } if(rcv) { - sa_push(msh_rcv.ids, tri[0] - 1 + msh_rcv.voffset); - sa_push(msh_rcv.ids, tri[1] - 1 + msh_rcv.voffset); - sa_push(msh_rcv.ids, tri[2] - 1 + msh_rcv.voffset); + sa_push(msh_rcv.ids, tri[0] - 1 + msh_rcv.voffset - offset_obj); + sa_push(msh_rcv.ids, tri[1] - 1 + msh_rcv.voffset - offset_obj); + sa_push(msh_rcv.ids, tri[2] - 1 + msh_rcv.voffset - offset_obj); } if(!prim && !rcv) { - sa_push(msh_misc.ids, tri[0] - 1 + msh_misc.voffset); - sa_push(msh_misc.ids, tri[1] - 1 + msh_misc.voffset); - sa_push(msh_misc.ids, tri[2] - 1 + msh_misc.voffset); + sa_push(msh_misc.ids, tri[0] - 1 + msh_misc.voffset - offset_obj); + sa_push(msh_misc.ids, tri[1] - 1 + msh_misc.voffset - offset_obj); + sa_push(msh_misc.ids, tri[2] - 1 + msh_misc.voffset - offset_obj); } - ++ntris; + ++ntris_grp; } else if(!strcmp(line, "---")) { - if(prim) { - sa_push(msh_prim.ncells, ntris); - msh_prim.voffset += nverts; - } - if(rcv) { - sa_push(msh_rcv.ncells, ntris); - msh_rcv.voffset += nverts; - } - if(!prim && !rcv) { - msh_misc.voffset += nverts; - } - prim = NULL; - rcv = NULL; + nverts_obj = 0; } } + if(prim) sa_push(msh_prim.ncells, ntris_grp); + if(rcv) sa_push(msh_rcv.ncells, ntris_grp); fclose(input); NCHECK(output = fopen("primaries.vtk", "w"), NULL); mesh_write_vtk(output, &msh_prim); + mesh_write_prim_data_vtk(output, &msh_prim, &simul); fclose(output); NCHECK(output = fopen("receivers.vtk", "w"), NULL); mesh_write_vtk(output, &msh_rcv); + mesh_write_rcv_data_vtk(output, &msh_rcv, &simul); fclose(output); NCHECK(output = fopen("miscellaneous.obj", "w"), NULL); mesh_write_obj(output, &msh_misc); fclose(output); -#if 0 - fprintf(output, "CELL_DATA %zu\n", n); - fprintf(output, "FIELD PrimaryData 2\n"); - fprintf(output, "cos_factor 2 %zu float\n", n); - FOR_EACH(i, 0, sa_size(prim_ids)) { - FOR_EACH(j, 0, ncells[i]) { - fprintf(output, "%g %g\n", - prims[prim_ids[i]].cos_factor.E, - prims[prim_ids[i]].cos_factor.SE); - }} - fprintf(output, "shadow_loss 2 %zu float\n", n); - FOR_EACH(i, 0, sa_size(prim_ids)) { - FOR_EACH(j, 0, ncells[i]) { - fprintf(output, "%g %g\n", - prims[prim_ids[i]].shadow_loss.E, - prims[prim_ids[i]].shadow_loss.SE); - }} -#endif - exit: mesh_release(&msh_prim); mesh_release(&msh_rcv);