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 ba8d0d9f5e679e0087edef1a67cfcf30580bb636
parent c1c5232efbc192f0b5406435d3b33526af29b18c
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Wed, 20 May 2026 09:04:53 +0200

Merge branch 'release_0.10'

Diffstat:
M.gitignore | 42+++++++++++++++++++++++++++++++++++-------
AMakefile | 150+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
AMakefile.core | 229+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
AMakefile.prs | 214+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
AMakefile.rcv | 167+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
MREADME.md | 117+++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------
Dcmake/CMakeLists.txt | 201-------------------------------------------------------------------------------
Dcmake/LibYAMLConfig.cmake | 63---------------------------------------------------------------
Dcmake/doc/CMakeLists.txt | 151------------------------------------------------------------------------------
Dcmake/parser/CMakeLists.txt | 121-------------------------------------------------------------------------------
Dcmake/receivers/CMakeLists.txt | 73-------------------------------------------------------------------------
Aconfig.mk | 104+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adoc/solstice-input.5 | 1328+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ddoc/solstice-input.5.txt | 1179-------------------------------------------------------------------------------
Ddoc/solstice-man.css | 96-------------------------------------------------------------------------------
Adoc/solstice-output.5 | 666+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ddoc/solstice-output.5.txt | 541-------------------------------------------------------------------------------
Adoc/solstice-receiver.5 | 165+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ddoc/solstice-receiver.5.txt | 122-------------------------------------------------------------------------------
Adoc/solstice.1.in | 412+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ddoc/solstice.1.txt.in | 272-------------------------------------------------------------------------------
Ascore.pc.in | 19+++++++++++++++++++
Asprs.pc.in | 14++++++++++++++
Msrc/parser/solparser.h | 93+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Msrc/receivers/srcvl.h | 23++++++++++++++++-------
Asrc/score.h | 60++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/solstice.h | 14+++++++++++---
Msrc/solstice_args.c | 2+-
Msrc/solstice_args.h.in | 14+++-----------
Asrcv.pc.in | 14++++++++++++++
30 files changed, 3740 insertions(+), 2926 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -1,12 +1,40 @@ -.gitignore -CMakeCache.txt -CMakeFiles -Makefile -tmp [Bb]uild* *.sw[po] -*.[ao] +*.[aodt] *.orig +*.so *~ tags - +src/solstice_args.h +src/solstice_version.h +src/.config +src/.config_core +src/.config_prs +src/.config_rcv +src/.config_score_test +src/.config_sprs_test +src/.config_srcv_test +solstice.pc +doc/solstice.1 +src/score-local.pc +src/score.pc +src/sprs-local.pc +src/sprs.pc +src/srcv-local.pc +src/srcv.pc +solstice +test_solparser +test_solparser2 +test_solparser3 +test_solparser4 +test_solparser5 +test_solparser6 +test_solparser7 +test_solparser8 +test_solparser_mirror +test_solparser_normal_map +test_solparser_spectrum +test_solstice_args +test_solstice_simulation +test_srcvl +test_srcvl2 diff --git a/Makefile b/Makefile @@ -0,0 +1,150 @@ +# Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +.POSIX: +.SUFFIXES: # Clean up default inference rules + +include config.mk + +default: executable +all: executable man test + +LIBSCORE = src/libscore.a +LIBSRCV = src/libsrcv.a +LIBSPRS = src/libsprs.a + +################################################################################ +# Program building +################################################################################ +CMD_SRC =\ +src/main.c +CMD_OBJ = $(CMD_SRC:.c=.o) +CMD_DEP = $(CMD_SRC:.c=.d) + +# Headers to configure +HDR=\ + src/solstice_args.h\ + src/solstice_version.h + +CFLAGS_CMD = $(CFLAGS_EXE) $(INCS) +LDFLAGS_CMD = $(LDFLAGS_EXE) -Lsrc -lscore -lsprs -lsrcv $(LIBS) + +$(CMD_DEP) $(CMD_OBJ): src/.config + +executable: libscore libsrcv libsprs $(CMD_DEP) + @$(MAKE) -fMakefile $$(for i in $(CMD_DEP); do echo -f $${i}; done) solstice + +solstice: $(CMD_OBJ) ${LIBSCORE} ${LIBSRCV} ${LIBSPRS} + $(CC) $(CFLAGS_CMD) -o $@ $(CMD_OBJ) $(LDFLAGS_CMD) + +$(CMD_DEP): $(HDR) + @$(CC) $(CFLAGS_CMD) -MM -MT "$(@:.d=.o) $@" $(@:.d=.c) -MF $@ + +$(CMD_OBJ): $(HDR) + $(CC) $(CFLAGS_CMD) -c $(@:.o=.c) -o $@ + +libscore: libsrcv libsprs $(HDR) + $(MAKE) -fMakefile.core library + +libsrcv: + $(MAKE) -fMakefile.rcv library + +libsprs: + $(MAKE) -fMakefile.prs library + +src/solstice_args.h: + $(MAKE) -fMakefile.core $@ + +src/solstice_version.h: + $(MAKE) -fMakefile.core $@ + +src/.config: config.mk + $(PKG_CONFIG) --atleast-version $(RSYS_VERSION) rsys + @echo "config done" > $@ + +################################################################################ +# Tests +################################################################################ +test: executable + $(MAKE) -fMakefile.prs test + $(MAKE) -fMakefile.rcv test + $(MAKE) -fMakefile.core test + +################################################################################ +# Man pages +################################################################################ +man: doc/solstice.1 + +doc/solstice.1: doc/solstice.1.in + sed -e 's/@SOLSTICE_ARGS_DEFAULT_NREALISATIONS@/$(SOLSTICE_ARGS_DEFAULT_NREALISATIONS)/' \ + -e 's/@SOLSTICE_ARGS_DEFAULT_CAMERA_POS@/$(SOLSTICE_ARGS_DEFAULT_CAMERA_POS)/' \ + -e 's/@SOLSTICE_ARGS_DEFAULT_CAMERA_TGT@/$(SOLSTICE_ARGS_DEFAULT_CAMERA_TGT)/' \ + -e 's/@SOLSTICE_ARGS_DEFAULT_CAMERA_UP@/$(SOLSTICE_ARGS_DEFAULT_CAMERA_UP)/' \ + -e 's/@SOLSTICE_ARGS_DEFAULT_CAMERA_FOV@/$(SOLSTICE_ARGS_DEFAULT_CAMERA_FOV)/' \ + -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)/' \ + $@.in > $@ + +################################################################################ +# Installation +################################################################################ +install: executable man + install() { mode="$$1"; prefix="$$2"; shift 2; \ + mkdir -p "$${prefix}"; \ + cp "$$@" "$${prefix}"; \ + chmod "$${mode}" "$${prefix}/$${@##*/}"; \ + }; \ + install 755 "$(DESTDIR)$(PREFIX)/bin" solstice; \ + install 644 "$(DESTDIR)$(PREFIX)/share/doc/solstice" COPYING; \ + install 644 "$(DESTDIR)$(PREFIX)/share/doc/solstice" README.md; \ + install 644 "$(DESTDIR)$(PREFIX)/share/man/man1" doc/solstice.1; \ + install 644 "$(DESTDIR)$(PREFIX)/share/man/man5" doc/solstice-input.5; \ + install 644 "$(DESTDIR)$(PREFIX)/share/man/man5" doc/solstice-output.5; \ + install 644 "$(DESTDIR)$(PREFIX)/share/man/man5" doc/solstice-receiver.5 + $(MAKE) -fMakefile.core install + $(MAKE) -fMakefile.rcv install + $(MAKE) -fMakefile.prs install + +uninstall: + rm -f "$(DESTDIR)$(PREFIX)/bin/solstice" + rm -f "$(DESTDIR)$(PREFIX)/share/doc/solstice/COPYING" + rm -f "$(DESTDIR)$(PREFIX)/share/doc/solstice/README.md" + rm -f "$(DESTDIR)$(PREFIX)/share/man/man1/solstice.1" + rm -f "$(DESTDIR)$(PREFIX)/share/man/man5/solstice-receiver.5" + rm -f "$(DESTDIR)$(PREFIX)/share/man/man5/solstice-input.5" + rm -f "$(DESTDIR)$(PREFIX)/share/man/man5/solstice-output.5" + $(MAKE) -fMakefile.core uninstall + $(MAKE) -fMakefile.rcv uninstall + $(MAKE) -fMakefile.prs uninstall + +################################################################################ +# Miscellaneous targets +################################################################################ +clean: + rm -f $(HDR) $(CMD_OBJ) $(CMD_DEP) + rm -f solstice doc/solstice.1 + $(MAKE) -fMakefile.core clean + $(MAKE) -fMakefile.rcv clean + $(MAKE) -fMakefile.prs clean + +lint: man + mandoc -Tlint -Wall doc/solstice.1 || [ $$? -le 1 ] + mandoc -Tlint -Wall doc/solstice-receiver.5 || [ $$? -le 1 ] + mandoc -Tlint -Wall doc/solstice-input.5 || [ $$? -le 1 ] + mandoc -Tlint -Wall doc/solstice-output.5 || [ $$? -le 1 ] + $(MAKE) -fMakefile.core lint + $(MAKE) -fMakefile.rcv lint + $(MAKE) -fMakefile.prs lint diff --git a/Makefile.core b/Makefile.core @@ -0,0 +1,229 @@ +# Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +.POSIX: +.SUFFIXES: # Clean up default inference rules + +include config.mk + +LIBNAME = src/libscore.a + +default: library +all: library tests + +################################################################################ +# Build the library +################################################################################ +SRC =\ +src/solstice_args.c\ +src/solstice_atmosphere.c\ +src/solstice.c\ +src/solstice_draw.c\ +src/solstice_dump.c\ +src/solstice_entity.c\ +src/solstice_material.c\ +src/solstice_node.c\ +src/solstice_object.c\ +src/solstice_solve.c\ +src/solstice_spectrum.c\ +src/solstice_sun.c\ +src/solstice_sun_spectrum.c +OBJ = $(SRC:.c=.o) +DEP = $(SRC:.c=.d) + +# Headers to configure +HDR=\ + src/solstice_args.h\ + src/solstice_version.h + +CFLAGS_LIB = $(CFLAGS_SO) $(INCS) -DSCORE_SHARED_BUILD +LDFLAGS_LIB = $(LDFLAGS_SO) -Lsrc -lsprs -lsrcv $(LIBS) + +$(DEP) $(OBJ): src/.config_core + +library: $(DEP) + @$(MAKE) -fMakefile.core $$(for i in $(DEP); do echo -f $${i}; done) \ + $(LIBNAME) + +$(LIBNAME): src/libscore.o + $(AR) -rc $@ $? + $(RANLIB) $@ + +src/libscore.o: $(OBJ) $(DEP) + $(LD) -r $(OBJ) -o $@ + $(OBJCOPY) $(OCPFLAGS) $@ + +$(DEP): $(HDR) + @$(CC) $(CFLAGS_LIB) -MM -MT "$(@:.d=.o) $@" $(@:.d=.c) -MF $@ + +$(OBJ): $(HDR) + $(CC) $(CFLAGS_LIB) -c $(@:.o=.c) -o $@ + +src/solstice_args.h: src/.config src/solstice_args.h.in + sed -e 's/@SOLSTICE_ARGS_DEFAULT_NREALISATIONS@/$(SOLSTICE_ARGS_DEFAULT_NREALISATIONS)/' \ + -e 's/@SOLSTICE_ARGS_DEFAULT_CAMERA_POS@/$(SOLSTICE_ARGS_DEFAULT_CAMERA_POS)/' \ + -e 's/@SOLSTICE_ARGS_DEFAULT_CAMERA_TGT@/$(SOLSTICE_ARGS_DEFAULT_CAMERA_TGT)/' \ + -e 's/@SOLSTICE_ARGS_DEFAULT_CAMERA_UP@/$(SOLSTICE_ARGS_DEFAULT_CAMERA_UP)/' \ + -e 's/@SOLSTICE_ARGS_DEFAULT_CAMERA_FOV@/$(SOLSTICE_ARGS_DEFAULT_CAMERA_FOV)/' \ + -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)/' \ + $@.in > $@ + +src/solstice_version.h: src/.config src/solstice_version.h.in + sed -e 's/@VERSION_MAJOR@/$(VERSION_MAJOR)/' \ + -e 's/@VERSION_MINOR@/$(VERSION_MINOR)/' \ + -e 's/@VERSION_PATCH@/$(VERSION_PATCH)/' \ + $@.in > $@ + +################################################################################ +# Installation +################################################################################ +src/.config_core: config.mk + $(PKG_CONFIG) --atleast-version $(RSYS_VERSION) rsys + $(PKG_CONFIG) --atleast-version $(S3DUT_VERSION) s3dut + $(PKG_CONFIG) --atleast-version $(SSP_VERSION) star-sp + $(PKG_CONFIG) --atleast-version $(SSTL_VERSION) sstl + $(PKG_CONFIG) --atleast-version $(YAML_VERSION) yaml-0.1 + $(PKG_CONFIG) --atleast-version $(SSOL_VERSION) ssol + $(PKG_CONFIG) --atleast-version $(SANIM_VERSION) sanim + @echo "config done" > $@ + +install: + +uninstall: + +clean: clean_test + rm -f $(DEP) $(OBJ) $(LIBNAME) + rm -f src/.config_core src/libscore.o + +lint: + +################################################################################ +# Tests +################################################################################ +TEST_SRC =\ + src/test_solstice_args.c\ + src/test_solstice_simulation.c +TEST_OBJ =\ + $(TEST_SRC:.c=.o) +TEST_DEP =\ + $(TEST_SRC:.c=.d) +TEST_TGT =\ + $(TEST_SRC:.c=.t) + +src/score-local.pc: score.pc.in src/.config_score_test + sed -e '1d'\ + -e 's#^includedir=.*#includedir=./src#'\ + -e 's#^libdir=.*#libdir=./#'\ + -e 's#@RSYS_VERSION@#$(RSYS_VERSION)#g'\ + -e 's#@S3DUT_VERSION@#$(S3DUT_VERSION)#g'\ + -e 's#@SSP_VERSION@#$(SSP_VERSION)#g'\ + -e 's#@SSTL_VERSION@#$(SSTL_VERSION)#g'\ + -e 's#@YAML_VERSION@#$(YAML_VERSION)#g'\ + -e 's#@SSOL_VERSION@#$(SSOL_VERSION)#g'\ + -e 's#@SANIM_VERSION@#$(SANIM_VERSION)#g'\ + score.pc.in > $@ + +# Regular cflags +PKG_CONFIG_LOCAL = PKG_CONFIG_PATH="./src:$${PKG_CONFIG_PATH}" $(PKG_CONFIG) +INCS_TEST = $$($(PKG_CONFIG_LOCAL) $(PCFLAGS) --cflags rsys score-local sprs-local srcv-local) +LIBS_TEST = $$($(PKG_CONFIG_LOCAL) $(PCFLAGS) --libs rsys score-local sprs-local srcv-local)\ + -lm + +tests: library src/score-local.pc $(TEST_DEP) $(TEST_TGT) + @$(MAKE) -fMakefile.core \ + $$(for i in $(TEST_DEP); do echo -f"$${i}"; done) \ + $$(for i in $(TEST_TGT); do echo -f"$${i}"; done) \ + test_list + +$(TEST_TGT): + @{ \ + exe="$$(basename "$@" ".t")"; \ + printf '%s: %s\n' "$${exe}" $(@:.t=.o); \ + printf 'test_list: %s\n' "$${exe}"; \ + } > $@ + +src/.config_score_test: config.mk + $(PKG_CONFIG) --atleast-version $(RSYS_VERSION) rsys + $(PKG_CONFIG) --atleast-version $(S3DUT_VERSION) s3dut + $(PKG_CONFIG) --atleast-version $(SSP_VERSION) star-sp + $(PKG_CONFIG) --atleast-version $(SSTL_VERSION) sstl + $(PKG_CONFIG) --atleast-version $(YAML_VERSION) yaml-0.1 + $(PKG_CONFIG) --atleast-version $(SSOL_VERSION) ssol + $(PKG_CONFIG) --atleast-version $(SANIM_VERSION) sanim + @echo "config done" > $@ + +clean_test: + rm -f $(TEST_DEP) $(TEST_OBJ) $(TEST_TGT) + for i in $(TEST_SRC); do rm -f "$$(basename "$${i}" ".c")"; done + rm -f src/.config_score_test src/score-local.pc + +test: tests + @err=0; \ + check() { name="$$1"; prog="$$2"; shift 2; \ + printf '%s' "$${name}"; \ + if PATH=./:"$${PATH}" "$${prog}" $$@ > /dev/null 2>&1; then \ + printf '\n'; \ + else \ + printf ': error %s\n' "$$?"; \ + err=$$((err+1)); \ + fi; \ + }; \ + \ + for i in $(TEST_SRC); do \ + test="$$(basename "$${i}" ".c")"; \ + if [ "$${test}" != "test_solstice_simulation" ]; then \ + check "$${test}" "$${test}"; \ + else \ + check test_solstice_simulation_beam_down \ + test_solstice_simulation ./solstice yaml/ beam_down; \ + check test_solstice_simulation_test02 \ + test_solstice_simulation ./solstice yaml/ test02; \ + check test_solstice_simulation_test03 \ + test_solstice_simulation ./solstice yaml/ test03; \ + check test_solstice_simulation_test04 \ + test_solstice_simulation ./solstice yaml/ test04; \ + check test_solstice_simulation_test05 \ + test_solstice_simulation ./solstice yaml/ test05; \ + check test_solstice_simulation_test06 \ + test_solstice_simulation ./solstice yaml/ test06; \ + check test_solstice_simulation_test07 \ + test_solstice_simulation ./solstice yaml/ test07; \ + #check test_solstice_simulation_test08 \ + # test_solstice_simulation ./solstice yaml/ test08; \ + #check test_solstice_simulation_test09 \ + # test_solstice_simulation ./solstice yaml/ test09; \ + fi \ + done; \ + \ + [ "$${err}" -eq 0 ] + +################################################################################ +# Regular tests +################################################################################ +CFLAGS_TEST = $(CFLAGS_EXE) $(INCS_TEST) +LDFLAGS_TEST = $(LDFLAGS_EXE) $(LIBS_TEST) + +$(TEST_DEP) : src/.config_score_test src/score-local.pc + @$(CC) $(CFLAGS_TEST) -MM -MT "$(@:.d=.o) $@" $(@:.d=.c) -MF $@ + +$(TEST_OBJ) : src/.config_score_test src/score-local.pc + $(CC) $(CFLAGS_TEST) -c $(@:.o=.c) -o $@ + +test_solstice_args\ +test_solstice_simulation\ +: src/.config_score_test src/score-local.pc $(LIBNAME) + $(CC) $(CFLAGS_TEST) -o $@ src/$@.o $(LDFLAGS_TEST) diff --git a/Makefile.prs b/Makefile.prs @@ -0,0 +1,214 @@ +# Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +.POSIX: +.SUFFIXES: # Clean up default inference rules + +include config.mk + +LIBNAME = src/libsprs.a + +default: library +all: library tests + +################################################################################ +# Build the library +################################################################################ +SRC =\ + src/parser/solparser_atmosphere.c\ + src/parser/solparser.c\ + src/parser/solparser_entity.c\ + src/parser/solparser_geometry.c\ + src/parser/solparser_image.c\ + src/parser/solparser_material.c\ + src/parser/solparser_medium.c\ + src/parser/solparser_mtl_data.c\ + src/parser/solparser_pivot.c\ + src/parser/solparser_spectrum.c\ + src/parser/solparser_sun.c +OBJ = $(SRC:.c=.o) +DEP = $(SRC:.c=.d) + +# Headers to configure +HDR= + +CFLAGS_LIB = $(CFLAGS_SO) $(INCS) -DSPRSR_SHARED_BUILD +LDFLAGS_LIB = $(LDFLAGS_SO) $(LIBS) + +$($(DEP) $(OBJ): src/.config_prs + +library: $(DEP) + @$(MAKE) -fMakefile.prs $$(for i in $(DEP); do echo -f $${i}; done) \ + $(LIBNAME) + +$(LIBNAME): src/libsprs.o + $(AR) -rc $@ $? + $(RANLIB) $@ + +src/libsprs.o: $(OBJ) $(DEP) + $(LD) -r $(OBJ) -o $@ + $(OBJCOPY) $(OCPFLAGS) $@ + +$(DEP): $(HDR) + @$(CC) $(CFLAGS_LIB) -MM -MT "$(@:.d=.o) $@" $(@:.d=.c) -MF $@ + +$(OBJ): $(HDR) + $(CC) $(CFLAGS_LIB) -c $(@:.o=.c) -o $@ + +################################################################################ +# Installation +################################################################################ +src/.config_prs: config.mk + $(PKG_CONFIG) --atleast-version $(RSYS_VERSION) rsys + $(PKG_CONFIG) --exists yaml-0.1 + @echo "config done" > $@ + +install: library + +uninstall: + +clean: clean_test + rm -f $(DEP) $(OBJ) $(LIBNAME) + rm -f src/.config_prs src/libsprs.o + +lint: + +################################################################################ +# Tests +################################################################################ +TEST_SRC =\ +src/parser/test_solparser.c\ +src/parser/test_solparser2.c\ +src/parser/test_solparser3.c\ +src/parser/test_solparser4.c\ +src/parser/test_solparser5.c\ +src/parser/test_solparser6.c\ +src/parser/test_solparser7.c\ +src/parser/test_solparser8.c\ +src/parser/test_solparser_mirror.c\ +src/parser/test_solparser_normal_map.c\ +src/parser/test_solparser_spectrum.c +TEST_OBJ =\ + $(TEST_SRC:.c=.o) +TEST_DEP =\ + $(TEST_SRC:.c=.d) +TEST_TGT =\ + $(TEST_SRC:.c=.t) + +src/sprs-local.pc: sprs.pc.in config.mk + sed -e '1d'\ + -e 's#^includedir=.*#includedir=./src#'\ + -e 's#^libdir=.*#libdir=./src#'\ + -e 's#@RSYS_VERSION@#$(RSYS_VERSION)#g'\ + -e 's#@S3DUT_VERSION@#$(S3DUT_VERSION)#g'\ + -e 's#@SSP_VERSION@#$(SSP_VERSION)#g'\ + -e 's#@SSTL_VERSION@#$(SSTL_VERSION)#g'\ + -e 's#@YAML_VERSION@#$(YAML_VERSION)#g'\ + -e 's#@SSOL_VERSION@#$(SSOL_VERSION)#g'\ + -e 's#@SANIM_VERSION@#$(SANIM_VERSION)#g'\ + sprs.pc.in > $@ + +# Regular cflags +PKG_CONFIG_LOCAL = PKG_CONFIG_PATH="./src:$${PKG_CONFIG_PATH}" $(PKG_CONFIG) +INCS_TEST = $$($(PKG_CONFIG_LOCAL) $(PCFLAGS) --cflags rsys sprs-local) +LIBS_TEST = $$($(PKG_CONFIG_LOCAL) $(PCFLAGS) --libs rsys sprs-local)\ + -lm + +tests: library src/sprs-local.pc $(TEST_DEP) $(TEST_TGT) + @$(MAKE) -fMakefile.prs \ + $$(for i in $(TEST_DEP); do echo -f"$${i}"; done) \ + $$(for i in $(TEST_TGT); do echo -f"$${i}"; done) \ + test_list + +$(TEST_TGT): + @{ \ + exe="$$(basename "$@" ".t")"; \ + printf '%s: %s\n' "$${exe}" $(@:.t=.o); \ + printf 'test_list: %s\n' "$${exe}"; \ + } > $@ + +src/.config_sprs_test: config.mk + @echo "config done" > $@ + +clean_test: + rm -f $(TEST_DEP) $(TEST_OBJ) $(TEST_TGT) + for i in $(TEST_SRC); do rm -f "$$(basename "$${i}" ".c")"; done + rm -f src/.config_sprs_test src/sprs-local.pc + +test: tests + @err=0; \ + check() { name="$$1"; prog="$$2"; shift 2; \ + printf '%s' "$${name}"; \ + if PATH=./:"$${PATH}" "$${prog}" $$@ > /dev/null 2>&1; then \ + printf '\n'; \ + else \ + printf ': error %s\n' "$$?"; \ + err=$$((err+1)); \ + fi; \ + }; \ + \ + for i in $(TEST_SRC); do \ + test="$$(basename "$${i}" ".c")"; \ + if [ "$${test}" != "test_solparser" ]; then \ + check "$${test}" "$${test}"; \ + else \ + check test_solstice_solparser_ok_0 \ + test_solparser src/parser/yaml/test_ok_0.yaml; \ + check test_solstice_solparser_ok_1 \ + test_solparser src/parser/yaml/test_ok_1.yaml; \ + check test_solstice_solparser_ok_2 \ + test_solparser src/parser/yaml/test_ok_2.yaml; \ + check test_solstice_solparser_ok_3 \ + test_solparser src/parser/yaml/test_ok_3.yaml; \ + check test_solstice_solparser_ok_4 \ + test_solparser src/parser/yaml/test_ok_4.yaml; \ + check test_solstice_solparser_ok_5 \ + test_solparser src/parser/yaml/test_ok_5.yaml; \ + check test_solstice_solparser_ok_6 \ + test_solparser src/parser/yaml/test_ok_6.yaml; \ + check test_solstice_solparser_ok_7 \ + test_solparser src/parser/yaml/test_ok_7.yaml; \ + check test_solstice_solparser_ko_0 \ + test_solparser -e src/parser/yaml/test_ko_0.yaml; \ + fi \ + done; \ + \ + [ "$${err}" -eq 0 ] + +################################################################################ +# Regular tests +################################################################################ +CFLAGS_TEST = $(CFLAGS_EXE) $(INCS_TEST) +LDFLAGS_TEST = $(LDFLAGS_EXE) $(LIBS_TEST) + +$(TEST_DEP) : src/.config_sprs_test src/sprs-local.pc + @$(CC) $(CFLAGS_TEST) -MM -MT "$(@:.d=.o) $@" $(@:.d=.c) -MF $@ + +$(TEST_OBJ) : src/.config_sprs_test src/sprs-local.pc + $(CC) $(CFLAGS_TEST) -c $(@:.o=.c) -o $@ + +test_solparser\ +test_solparser2\ +test_solparser3\ +test_solparser4\ +test_solparser5\ +test_solparser6\ +test_solparser7\ +test_solparser8\ +test_solparser_mirror\ +test_solparser_normal_map\ +test_solparser_spectrum\ +: src/.config_sprs_test src/sprs-local.pc $(LIBNAME) + $(CC) $(CFLAGS_TEST) -o $@ src/parser/$@.o $(LDFLAGS_TEST) diff --git a/Makefile.rcv b/Makefile.rcv @@ -0,0 +1,167 @@ +# Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +.POSIX: +.SUFFIXES: # Clean up default inference rules + +include config.mk + +LIBNAME = src/libsrcv.a + +default: library +all: library tests + +################################################################################ +# Build the library +################################################################################ +SRC =\ +src/receivers/srcvl.c +OBJ = $(SRC:.c=.o) +DEP = $(SRC:.c=.d) + +# Headers to configure +HDR= + +CFLAGS_LIB = $(CFLAGS_SO) $(INCS) -DSRCVL_SHARED_BUILD +LDFLAGS_LIB = $(LDFLAGS_SO) $(LIBS) + +$(DEP) $(OBJ): src/.config_rcv + +library: $(DEP) + @$(MAKE) -fMakefile.rcv $$(for i in $(DEP); do echo -f $${i}; done) \ + $(LIBNAME) + +$(LIBNAME): src/libsrcv.o + $(AR) -rc $@ $? + $(RANLIB) $@ + +src/libsrcv.o: $(OBJ) $(DEP) + $(LD) -r $(OBJ) -o $@ + $(OBJCOPY) $(OCPFLAGS) $@ + +$(DEP): $(HDR) + @$(CC) $(CFLAGS_LIB) -MM -MT "$(@:.d=.o) $@" $(@:.d=.c) -MF $@ + +$(OBJ): $(HDR) + $(CC) $(CFLAGS_LIB) -c $(@:.o=.c) -o $@ + +################################################################################ +# Installation +################################################################################ +src/.config_rcv: config.mk + $(PKG_CONFIG) --atleast-version $(RSYS_VERSION) rsys + $(PKG_CONFIG) --atleast-version $(YAML_VERSION) yaml-0.1 + @echo "config done" > $@ + +install: + +uninstall: + +clean: clean_test + rm -f $(DEP) $(OBJ) $(LIBNAME) + rm -f src/.config_rcv src/libsrcv.o + +lint: + +################################################################################ +# Tests +################################################################################ +TEST_SRC =\ + src/receivers/test_srcvl.c\ + src/receivers/test_srcvl2.c +TEST_OBJ =\ + $(TEST_SRC:.c=.o) +TEST_DEP =\ + $(TEST_SRC:.c=.d) +TEST_TGT =\ + $(TEST_SRC:.c=.t) + +src/srcv-local.pc: srcv.pc.in src/.config_srcv_test + sed -e '1d'\ + -e 's#^includedir=.*#includedir=./src#'\ + -e 's#^libdir=.*#libdir=./src#'\ + -e 's#@RSYS_VERSION@#$(RSYS_VERSION)#g'\ + -e 's#@YAML_VERSION@#$(YAML_VERSION)#g'\ + srcv.pc.in > $@ + +# Regular cflags +PKG_CONFIG_LOCAL = PKG_CONFIG_PATH="./src:$${PKG_CONFIG_PATH}" $(PKG_CONFIG) +INCS_TEST = $$($(PKG_CONFIG_LOCAL) $(PCFLAGS) --cflags rsys srcv-local) +LIBS_TEST = $$($(PKG_CONFIG_LOCAL) $(PCFLAGS) --libs rsys srcv-local)\ + -lm + +tests: library src/srcv-local.pc $(TEST_DEP) $(TEST_TGT) + @$(MAKE) -fMakefile.rcv \ + $$(for i in $(TEST_DEP); do echo -f"$${i}"; done) \ + $$(for i in $(TEST_TGT); do echo -f"$${i}"; done) \ + test_list + +$(TEST_TGT): + @{ \ + exe="$$(basename "$@" ".t")"; \ + printf '%s: %s\n' "$${exe}" $(@:.t=.o); \ + printf 'test_list: %s\n' "$${exe}"; \ + } > $@ + +src/.config_srcv_test: config.mk + @echo "config done" > $@ + +clean_test: + rm -f $(TEST_DEP) $(TEST_OBJ) $(TEST_TGT) + for i in $(TEST_SRC); do rm -f "$$(basename "$${i}" ".c")"; done + rm -f src/.config_srcv_test src/srcv-local.pc + +test: tests + @err=0; \ + check() { name="$$1"; prog="$$2"; shift 2; \ + printf '%s' "$${name}"; \ + if PATH=./:"$${PATH}" "$${prog}" $$@ > /dev/null 2>&1; then \ + printf '\n'; \ + else \ + printf ': error %s\n' "$$?"; \ + err=$$((err+1)); \ + fi; \ + }; \ + \ + for i in $(TEST_SRC); do \ + test="$$(basename "$${i}" ".c")"; \ + if [ "$${test}" != "test_srcvl" ]; then \ + check "$${test}" "$${test}"; \ + else \ + check test_srcvl_ok \ + test_srcvl src/receivers/yaml/test_ok.yaml; \ + check test_srcvl_ko \ + test_srcvl -e src/receivers/yaml/test_ko.yaml; \ + fi \ + done; \ + \ + [ "$${err}" -eq 0 ] + +################################################################################ +# Regular tests +################################################################################ +CFLAGS_TEST = $(CFLAGS_EXE) $(INCS_TEST) +LDFLAGS_TEST = $(LDFLAGS_EXE) $(LIBS_TEST) + +$(TEST_DEP) : src/.config_srcv_test src/srcv-local.pc + @$(CC) $(CFLAGS_TEST) -MM -MT "$(@:.d=.o) $@" $(@:.d=.c) -MF $@ + +$(TEST_OBJ) : src/.config_srcv_test src/srcv-local.pc + $(CC) $(CFLAGS_TEST) -c $(@:.o=.c) -o $@ + +test_srcvl\ +test_srcvl2\ +: src/.config_srcv_test src/srcv-local.pc $(LIBNAME) + $(CC) $(CFLAGS_TEST) -o $@ src/receivers/$@.o $(LDFLAGS_TEST) diff --git a/README.md b/README.md @@ -3,21 +3,21 @@ The purpose of this program is to compute the total power collected by a concentrated solar plant, and to evaluate various efficiencies for each primary reflector: it computes losses due to cosine effect, to shadowing and -masking, to orientation and surface irregularities, to reflectivity and to +masking, to orientation and surface irregularities, to reflectivity, and to atmospheric transmission. The efficiency for each one of these effects is subsequently computed for each reflector, which provides insightful information when looking for the optimal design of a concentrated solar plant. Note that -Solstice relies on Monte-Carlo method, which means that every result is +Solstice relies on Monte Carlo method, which means that every result is provided with its numerical accuracy. -In addition of the aforementioned computations, Solstice can render an image of +In addition to the computations listed above, Solstice can render an image of the solar plant, either with a simple ray-caster or with a path-tracing algorithm that correctly handles the materials of the scene. Solstice is designed to handle complex solar plants: any number of reflectors can be specified (planes, conics, cylindro-parabolic, etc.) and positioned in 3D space, with a possibility for 1-axis and 2-axis auto-orientation with -respect to the sun direction. CAO geometries can be added to the solar plant +respect to the sun direction. CAD geometries can be added to the solar plant thanks to the support of the STereo Lithography file format. Multiple materials can be used, as long as the relevant physical properties are provided (matte, mirror, dielectric, etc.). Spectral effects are also taken into account: it is @@ -25,19 +25,24 @@ possible to define the spectral distribution of any physical property, including the input solar spectrum and the absorption of the atmosphere, at any spectral resolution. -Solstice has been developed in the scope of the Solstice project, in -collaboration with the -[Laboratory of Excellence Solstice](http://www.labex-solstice.fr) and the -[PROMES](http://www.promes.cnrs.fr/index.php?page=home-en) laboratory of the -National Center for Scientific Research ([CNRS](http://www.cnrs.fr/index.php)). -Refer to the Solstice man pages for more informations on the provided -functionalities. +Solstice was developed as part of the Solstice project, in collaboration with +the [Laboratory of Excellence Solstice](http://www.labex-solstice.fr) and the +[PROMES](http://www.promes.cnrs.fr/) laboratory of the National Center for +Scientific Research ([CNRS](http://www.cnrs.fr)). Starting in 2026, a new +development effort funded by [Ademe](https://www.ademe.fr/) is ongoing. + +Refer to the solstice(1) man pages for more information on the available +features. ## How to build -This program relies on the [CMake](http://www.cmake.org) and the -[RCMake](https://gitlab.com/vaplv/rcmake/) packages to build. -It also depends on the +This program, as part of the Solstice app, can be built on any POSIX system. + +Note that you will most likely want to build the entire Solstice app rather than +this program alone. If so, a good starting point is the +[start-build](https://gitlab.com/meso-star/star-build) build system. + +This program depends on the [LibYAML](http://pyyaml.org/wiki/LibYAML), [RSys](https://gitlab.com/vaplv/rsys/), [Solstice-Anim](https://gitlab.com/meso-star/solstice-anim/), @@ -45,26 +50,66 @@ It also depends on the [Star-3DUT](https://gitlab.com/meso-star/star-3dut/), [Star-SP](https://gitlab.com/meso-star/star-sp/) and [Star-STL](https://gitlab.com/meso-star/star-stm/) libraries. -The documentation is written in -[AsciiDoc](http://www.methods.co.nz/asciidoc/) text format and relies on its -tool suite to generate HTML and/or ROFF man pages. If the AsciiDoc tools cannot -be found, the documentation will not be built. - -First ensure that CMake is installed on your system. Then install the RCMake -package as well as the aforementioned prerequisites. Finally generate the -project from the `cmake/CMakeLists.txt` file by appending to the -`CMAKE_PREFIX_PATH` variable the install directories of its dependencies. The -resulting project can be edited, built, tested and installed as any CMake -project. Refer to the [CMake](https://cmake.org/documentation) for further -informations on CMake. + +First ensure that the make utility and a compiler that implements the OpenMP 1.2 +specification are installed on your system. Then install the above +prerequisites. Finally, edit the config.mk file to meet your needs and build +the project by running: + + make clean install ## Release notes +### Version 0.10 + +#### Raise the minimum required versions of companion libs + +solstice-anim minimum version is now 0.3, while solstice-solver minimum version +is now 0.10. + +#### Replace CMake with a POSIX Makefile + +The build procedure is now written in POSIX make and can be configured via +the config.mk file. A pkg-config file is also provided to link the +library as an external dependency. + +Compared to the CMake alternative, this Makefile adds support for static +libraries and an uninstall target. It also enables compiler and linker +flags for various hardening features, improving the security and +robustness of generated binaries. More broadly, the motivation for this +rewrite is to rely on a well-established standard with a simple feature +set, available on all UNIX systems - reducing portability concerns and +maintenance burden while remaining significantly lighter. + +#### Proof-reading and editing manual pages + +Write the man pages directly in mdoc's roff macros, instead of using the +asciidoc markup language as a source for man pages. +Unlike writing manuals with man's roff macros, and even more so with +asciidoc, mdoc macros take care of layout, font handling and all the other +typesetting details which, by construction, guarantee the consistency of +all manuals without leaving the responsibility to the individual author. +This also facilitates translation into other formats and documentation +tools. These are the main reasons for writing manual pages with mdoc +macros. +A complete re-reading of the manual pages was carried out during the +translation into mdoc, with several corrections and rewrites to make the +manual clearer. + +#### Raise the minimum required version of dependencies + +Minimum required versions: +- Rsys = 0.15 +- Star-3DUT = 0.4 +- Star-SP = 0.15 +- Star-STL = 0.7 +- libYAML = 0.2 + ### Version 0.9.1 -- Sets the CMake minimum version to 3.1: since CMake 3.20, version 2.8 has - become obsolete. -- Sets the required version of Star-SampPling to 0.12. This version fixes +- Raise the minimum required CMake version to 3.1, as version 2.8 has been + deprecated since CMake 3.20. +- Raise the minimum required Star-SampPling to 0.12. This version fixes compilation errors with gcc 11 but introduces API breaks. ### Version 0.9 @@ -93,10 +138,10 @@ attribute of the receiver file format controls which flux densities to output for each triangle of a receiver. Its value can be: - `NONE`: no per-triangle flux density is computed, i.e. no receiver map is - output for the receiver. It was the comportment of the previous version of + output for the receiver. It was the behaviour of the previous version of Solstice when the `per_primitive` flag was undefined or was set to 0. - `INCOMING`: output the estimate of the per-triangle incoming flux density. - It was the comportment of the previous version of Solstice when the + It was the behaviour of the previous version of Solstice when the `per_primitive` flag was set to 1. - `ABSORBED`: output the estimate of the per-triangle absorbed flux density. - `INCOMING_AND_ABSORBED`: output both the estimates of incoming and absorbed @@ -133,7 +178,7 @@ for each triangle of a receiver. Its value can be: losses. - Rename the pillbox `aperture` parameter in `theta_max`. - Fix the distribution of the pillbox sun: the pdf was wrong and its angular - parameter was internally used as an angular diameter while it is a angular + parameter was internally used as an angular diameter while it is an angular radius. - Fix the solver for non parallel sun: the angle between the principal sun direction and the sampled direction was not correctly taken into account @@ -164,7 +209,7 @@ radiative random walks bounce on many surfaces. ### Version 0.3 -- Fix several issues in the output results. Refer to the Solsice-Solver 0.3 +- Fix several issues in the output results. Refer to the Solstice-Solver 0.3 release notes for more informations. - Add the `--version` option. - Update the man pages to fix some issues and improve the output documentation. @@ -174,14 +219,14 @@ radiative random walks bounce on many surfaces. - Update the solstice-input file format. The anchor and entity name cannot contain spaces or tabulations anymore. - Fix the reported sun directions in the solstice-output. For each submitted - sun direction, solstice correctly output its Cartesian coordinates but always + sun direction, solstice correctly outputs its Cartesian coordinates but always wrote the azimuthal and elevation angles of the first direction. - Update the solstice-output map page: add the missing `<efficiency>` grammar rule and fix the definition of the `<map-side-data>` grammar rule. ### Version 0.2.2 -- Fix how the AsciiDoc tool suite is looking for on Windows; it was never found +- Fix how the AsciiDoc tool suite is searched for on Windows; it was never found and consequently the documentation was not generated. ### Version 0.2.1 @@ -207,7 +252,7 @@ radiative random walks bounce on many surfaces. ## License -Copyright (C) 2018, 2019, 2021 |Meso|Star> (<contact@meso-star.com>). +Copyright (C) 2018-2026 |Meso|Star> (<contact@meso-star.com>). Copyright (C) 2016-2018 CNRS. Solstice is free software released under the GPL v3+ license: GNU GPL version 3 diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -1,201 +0,0 @@ -# Copyright (C) 2018, 2019, 2021 |Meso|Star> (contact@meso-star.com) -# Copyright (C) 2016-2018 CNRS -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. - -cmake_minimum_required(VERSION 3.1) -project(solstice C) -enable_testing() - -option(NO_TEST "Do not build tests" OFF) - -if(CMAKE_HOST_UNIX) - set(SOLSTICE_DOC "TROFF" CACHE STRING - "Type of documentation to generate and install.") -else() - set(SOLSTICE_DOC "HTML" CACHE STRING - "Type of documentation to generate and install.") -endif() - -set_property(CACHE SOLSTICE_DOC PROPERTY STRINGS - "HTML" - "TROFF" - "TROFF & HTML" - "NONE") - -set(SOLSTICE_SOURCE_DIR ${PROJECT_SOURCE_DIR}/../src/) - -################################################################################ -# Check dependencies -################################################################################ -get_filename_component(_current_source_dir ${CMAKE_CURRENT_LIST_FILE} PATH) -set(LibYAML_DIR ${_current_source_dir}/) - -find_package(LibYAML REQUIRED) -find_package(RCMake 0.4 REQUIRED) -find_package(RSys 0.10 REQUIRED) -find_package(SolAnim 0.2.3 REQUIRED) -find_package(SolSolver 0.9 REQUIRED) -find_package(Star3DUT 0.3.1 REQUIRED) -find_package(StarSP 0.12 REQUIRED) -find_package(StarSTL 0.3.3 REQUIRED) - -if(MSVC) - find_package(MuslGetopt REQUIRED) - include_directories(${MuslGetopt_INCLUDE_DIR}) -endif() - -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${RCMAKE_SOURCE_DIR}) -include(rcmake) -include(rcmake_runtime) - -include_directories( - ${RSys_INCLUDE_DIR} - ${MuslGetopt_INCLUDE_DIR} - ${SolAnim_INCLUDE_DIR} - ${SolSolver_INCLUDE_DIR} - ${StarSP_INCLUDE_DIR} - ${StarSTL_INCLUDE_DIR} - ${Star3DUT_INCLUDE_DIR} - ${CMAKE_CURRENT_BINARY_DIR}) - -################################################################################ -# Build subprojects -################################################################################ -if(NOT SOLSTICE_DOC STREQUAL "NONE") - add_subdirectory(doc) -endif() -add_subdirectory(parser) -add_subdirectory(receivers) - -################################################################################ -# Generate files -################################################################################ -set(SOLSTICE_ARGS_DEFAULT_NREALISATIONS "10000") -set(SOLSTICE_ARGS_DEFAULT_CAMERA_POS "0,0,0") -set(SOLSTICE_ARGS_DEFAULT_CAMERA_TGT "0,0,-1") -set(SOLSTICE_ARGS_DEFAULT_CAMERA_UP "0,1,0") -set(SOLSTICE_ARGS_DEFAULT_CAMERA_FOV "70") # In degrees -set(SOLSTICE_ARGS_DEFAULT_IMG_WIDTH "800") -set(SOLSTICE_ARGS_DEFAULT_IMG_HEIGHT "600") -set(SOLSTICE_ARGS_DEFAULT_IMG_SPP "1") - -configure_file(${SOLSTICE_SOURCE_DIR}/solstice_args.h.in - ${CMAKE_CURRENT_BINARY_DIR}/solstice_args.h @ONLY) -configure_file(${SOLSTICE_SOURCE_DIR}/../doc/solstice.1.txt.in - ${CMAKE_CURRENT_BINARY_DIR}/doc/solstice.1.txt @ONLY) - -set(VERSION_MAJOR 0) -set(VERSION_MINOR 9) -set(VERSION_PATCH 1) -set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}) - -configure_file(${SOLSTICE_SOURCE_DIR}/solstice_version.h.in - ${CMAKE_CURRENT_BINARY_DIR}/solstice_version.h @ONLY) - -################################################################################ -# Configure and define targets -################################################################################ -set(SOLSTICE_FILES_SRC - solstice.c - solstice_args.c - solstice_atmosphere.c - solstice_draw.c - solstice_dump.c - solstice_entity.c - solstice_material.c - solstice_node.c - solstice_object.c - solstice_solve.c - solstice_spectrum.c - solstice_sun.c - solstice_sun_spectrum.c) -set(SOLSTICE_FILES_INC - solstice.h - solstice_args.h.in - solstice_c.h - solstice_sun_spectrum.h - solstice_version.h.in) -set(SOLSTICE_FILES_DOC COPYING README.md) - -# Prepend each file in the `SOLSTICE_FILES_<SRC|INC>' list by `SOLSTICE_SOURCE_DIR' -rcmake_prepend_path(SOLSTICE_FILES_SRC ${SOLSTICE_SOURCE_DIR}) -rcmake_prepend_path(SOLSTICE_FILES_INC ${SOLSTICE_SOURCE_DIR}) -rcmake_prepend_path(SOLSTICE_FILES_DOC ${PROJECT_SOURCE_DIR}/../) - -if(CMAKE_COMPILER_IS_GNUCC) - set(MATH_LIB m) -endif() - -if(MSVC) - set(GETOPT_LIB MuslGetopt) -endif() - -add_library(sollib STATIC ${SOLSTICE_FILES_SRC} ${SOLSTICE_FILES_INC}) -add_executable(solstice ${SOLSTICE_SOURCE_DIR}/main.c) -target_link_libraries(solstice ${MATH_LIB} ${GETOPT_LIB} - LibYAML RSys sollib solparser SolAnim SolSolver srcvl Star3DUT StarSP StarSTL) -set_target_properties(solstice PROPERTIES - VERSION ${VERSION} - SOVERSION ${VERSION_MAJOR}) -rcmake_copy_runtime_libraries(solstice) - -################################################################################ -# Tests -################################################################################ -if(NOT NO_TEST) - function(build_test _name) - add_executable(${_name} - ${SOLSTICE_SOURCE_DIR}/${_name}.c - ${SOLSTICE_SOURCE_DIR}/test_solstice_utils.h) - target_link_libraries(${_name} ${MATH_LIB} ${GETOPT_LIB} RSys sollib) - endfunction() - - function(new_test _name) - build_test(${_name}) - add_test(${_name} ${_name}) - endfunction() - - new_test(test_solstice_args) - - build_test(test_solstice_simulation) - function(add_test_simulation _name) - add_test(NAME test_solstice_simulation_${_name} - COMMAND test_solstice_simulation - $<TARGET_FILE:solstice> - ${SOLSTICE_SOURCE_DIR}/../yaml/ - ${_name}) - endfunction() - - add_test_simulation(beam_down) - add_test_simulation(test01) - add_test_simulation(test02) - add_test_simulation(test03) - add_test_simulation(test04) - add_test_simulation(test05) - add_test_simulation(test06) - add_test_simulation(test07) - add_test_simulation(test08) - -endif() - -################################################################################ -# Define output & install directories -################################################################################ -install(TARGETS solstice - ARCHIVE DESTINATION bin - LIBRARY DESTINATION lib - RUNTIME DESTINATION bin) -install(FILES ${SOLSTICE_FILES_DOC} DESTINATION share/doc/solstice) -rcmake_install_runtime_libraries(solstice) diff --git a/cmake/LibYAMLConfig.cmake b/cmake/LibYAMLConfig.cmake @@ -1,63 +0,0 @@ -# Copyright (C) 2018, 2019, 2021 |Meso|Star> (contact@meso-star.com) -# Copyright (C) 2016-2018 CNRS -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. - -cmake_minimum_required(VERSION 3.1) - -# Try to find the LibYAML devel. Once done this will define: -# - LibYAML_FOUND: system has LibYAML -# - LibYAML_INCLUDE_DIR: the include directory -# - LibYAML: Link this to use LibYAML - -find_path(LibYAML_INCLUDE_DIR yaml.h) -unset(LibYAML_LIBRARY CACHE) -unset(LibYAML_LIBRARY_DEBUG CACHE) -unset(LibYAML_LIBRARY_RELWITHDEBINFO CACHE) -unset(LibYAML_LIBRARY_MINSIZEREL CACHE) -find_library(LibYAML_LIBRARY yaml DOC - "Path to the LibYAML library used during release builds." - PATH_SUFFIXES bin) -find_library(LibYAML_LIBRARY_DEBUG yaml-dbg DOC - "Path to the LibYAML library used during debug builds." - PATH_SUFFIXES bin) -if(NOT LibYAML_LIBRARY_DEBUG) - set(LibYAML_LIBRARY_DEBUG ${LibYAML_LIBRARY}) -endif() - -# Create the imported library target -if(CMAKE_HOST_WIN32) - set(_property IMPORTED_IMPLIB) -else(CMAKE_HOST_WIN32) - set(_property IMPORTED_LOCATION) -endif(CMAKE_HOST_WIN32) -add_library(LibYAML SHARED IMPORTED) -set_target_properties(LibYAML PROPERTIES - ${_property} ${LibYAML_LIBRARY_DEBUG} - ${_property}_DEBUG ${LibYAML_LIBRARY_DEBUG} - ${_property}_RELEASE ${LibYAML_LIBRARY}) - -# Check the package -include(FindPackageHandleStandardArgs) -if(CMAKE_HOST_WIN32) - FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibYAML DEFAULT_MSG - LibYAML_INCLUDE_DIR - LibYAML_LIBRARY_DEBUG - LibYAML_LIBRARY) -else() - FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibYAML DEFAULT_MSG - LibYAML_INCLUDE_DIR - LibYAML_LIBRARY) -endif() - diff --git a/cmake/doc/CMakeLists.txt b/cmake/doc/CMakeLists.txt @@ -1,151 +0,0 @@ -# Copyright (C) 2018, 2019, 2021 |Meso|Star> (contact@meso-star.com) -# Copyright (C) 2016-2018 CNRS -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. - -cmake_minimum_required(VERSION 3.1) - -string(REGEX MATCH ".*HTML.*" _html ${SOLSTICE_DOC}) -string(REGEX MATCH ".*ROFF.*" _roff ${SOLSTICE_DOC}) - -set(SOLSTICE_DOC_DIR ${PROJECT_SOURCE_DIR}/../doc) - -################################################################################ -# Look for asciidoc and a2x programs -################################################################################ -if(_html) - find_program(ASCIIDOC NAMES asciidoc asciidoc.py) - if(NOT ASCIIDOC) - unset(_html) - message(WARNING - "The `asciidoc' program is missing. " - "The solstice HTML documentation cannot be generated.") - endif() -endif() - -if(_roff) - find_program(A2X NAMES a2x a2x.py) - if(NOT A2X) - unset(_roff) - message(WARNING - "The `a2x' program is missing. " - "The solstice man pages cannot be generated.") - endif() -endif() - -################################################################################ -# Copy doc files -################################################################################ -set(MAN_NAMES - solstice-input.5 - solstice-output.5 - solstice-receiver.5) - -if(_roff OR _html) - set(MAN_FILES) - foreach(_name IN LISTS MAN_NAMES) - set(_src ${SOLSTICE_DOC_DIR}/${_name}.txt) - set(_dst ${CMAKE_CURRENT_BINARY_DIR}/${_name}.txt) - add_custom_command( - OUTPUT ${_dst} - COMMAND ${CMAKE_COMMAND} -E copy ${_src} ${_dst} - DEPENDS ${_src} - COMMENT "Copy the asciidoc ${_src}" - VERBATIM) - list(APPEND MAN_FILES ${_dst}) - endforeach() - add_custom_target(man-copy ALL DEPENDS ${MAN_FILES}) -endif() - -list(APPEND MAN_NAMES solstice.1) - -################################################################################ -# ROFF man pages -################################################################################ -if(_roff) - set(A2X_OPTS -dmanpage -fmanpage) - set(MAN_FILES) - set(MAN5_FILES) - set(MAN1_FILES) - foreach(_name IN LISTS MAN_NAMES) - set(_man ${CMAKE_CURRENT_BINARY_DIR}/${_name}) - set(_txt ${CMAKE_CURRENT_BINARY_DIR}/${_name}.txt) - - add_custom_command( - OUTPUT ${_man} - COMMAND ${A2X} ${A2X_OPTS} ${_txt} - DEPENDS man-copy ${_txt} - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMENT "Build ROFF man page ${_man}" - VERBATIM) - list(APPEND MAN_FILES ${_man}) - - string(REGEX MATCH "^.*.5$" _man5 ${_man}) - string(REGEX MATCH "^.*.1$" _man1 ${_man}) - if(_man1) - list(APPEND MAN1_FILES ${_man1}) - elseif(_man5) - list(APPEND MAN5_FILES ${_man5}) - else() - message(FATAL_ERROR "Unexpected man type") - endif() - endforeach() - add_custom_target(man-roff ALL DEPENDS ${MAN_FILES}) - - install(FILES ${MAN1_FILES} DESTINATION share/man/man1) - install(FILES ${MAN5_FILES} DESTINATION share/man/man5) -endif() - -################################################################################ -# HTML documentation -################################################################################ -if(_html) - set(ASCIIDOC_OPTS - -bxhtml11 - -dmanpage - --attribute themedir=${SOLSTICE_DOC_DIR} - --theme=solstice-man) - - set(MAN_FILES) - set(MAN5_FILES) - set(MAN1_FILES) - foreach(_name IN LISTS MAN_NAMES) - set(_man ${CMAKE_CURRENT_BINARY_DIR}/${_name}.html) - set(_txt ${CMAKE_CURRENT_BINARY_DIR}/${_name}.txt) - - add_custom_command( - OUTPUT ${_man} - COMMAND ${ASCIIDOC} ${ASCIIDOC_OPTS} ${_txt} - DEPENDS man-copy ${_txt} ${SOLSTICE_DOC_DIR}/solstice-man.css - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMENT "Build HTML man page ${_man}" - VERBATIM) - list(APPEND MAN_FILES ${_man}) - - string(REGEX MATCH "^.*.5.html$" _man5 ${_man}) - string(REGEX MATCH "^.*.1.html$" _man1 ${_man}) - if(_man1) - list(APPEND MAN1_FILES ${_man1}) - elseif(_man5) - list(APPEND MAN5_FILES ${_man5}) - else() - message(FATAL_ERROR "Unexpected man type") - endif() - endforeach() - add_custom_target(man-html ALL DEPENDS ${MAN_FILES}) - - install(FILES ${MAN1_FILES} DESTINATION share/doc/solstice/html) - install(FILES ${MAN5_FILES} DESTINATION share/doc/solstice/html) -endif() - diff --git a/cmake/parser/CMakeLists.txt b/cmake/parser/CMakeLists.txt @@ -1,121 +0,0 @@ -# Copyright (C) 2018, 2019, 2021 |Meso|Star> (contact@meso-star.com) -# Copyright (C) 2016-2018 CNRS -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. - -cmake_minimum_required(VERSION 3.1) -project(solstice-parser C) - -set(SOLPARSER_SOURCE_DIR ${PROJECT_SOURCE_DIR}/../../src/parser) - -################################################################################ -# Define include directories -################################################################################ -include_directories( - ${LibYAML_INCLUDE_DIR} - ${RSys_INCLUDE_DIR} - ${SOLPARSER_SOURCE_DIR}/../) - -################################################################################ -# Configure and define targets -################################################################################ -set(SOLPARSER_FILES_SRC - solparser.c - solparser_atmosphere.c - solparser_entity.c - solparser_image.c - solparser_geometry.c - solparser_material.c - solparser_medium.c - solparser_mtl_data.c - solparser_pivot.c - solparser_sun.c - solparser_spectrum.c) -set(SOLPARSER_FILES_INC - solparser.h - solparser_c.h - solparser_atmosphere.h - solparser_entity.h - solparser_geometry.h - solparser_image.h - solparser_material.h - solparser_medium.h - solparser_mtl_data.h - solparser_pivot.h - solparser_shape.h - solparser_sun.h - solparser_spectrum.h) - -# Prepend each file in the `SOLPARSER_FILES_<SRC|INC>' list by `SOLPARSER_SOURCE_DIR' -rcmake_prepend_path(SOLPARSER_FILES_SRC ${SOLPARSER_SOURCE_DIR}) -rcmake_prepend_path(SOLPARSER_FILES_INC ${SOLPARSER_SOURCE_DIR}) -rcmake_prepend_path(SOLPARSER_FILES_DOC ${PROJECT_SOURCE_DIR}/../) - -if(CMAKE_COMPILER_IS_GNUCC) - set(MATH_LIB m) -endif() - -add_library(solparser STATIC ${SOLPARSER_FILES_SRC} ${SOLPARSER_FILES_INC}) -target_link_libraries(solparser LibYAML ${MATH_LIB}) - -################################################################################ -# Tests -################################################################################ -if(NOT NO_TEST) - function(build_test _name) - add_executable(${_name} - ${SOLPARSER_SOURCE_DIR}/${_name}.c - ${SOLPARSER_SOURCE_DIR}/../test_solstice_utils.h) - target_link_libraries(${_name} LibYAML ${MATH_LIB} RSys solparser) - endfunction() - - function(new_test _name) - build_test(${_name}) - add_test(${_name} ${_name}) - endfunction() - - build_test(test_solparser) - add_test(test_solparser_ok_0 test_solparser - ${SOLPARSER_SOURCE_DIR}/yaml/test_ok_0.yaml) - add_test(test_solparser_ok_1 test_solparser - ${SOLPARSER_SOURCE_DIR}/yaml/test_ok_1.yaml) - add_test(test_solparser_ok_2 test_solparser - ${SOLPARSER_SOURCE_DIR}/yaml/test_ok_2.yaml) - add_test(test_solparser_ok_3 test_solparser - ${SOLPARSER_SOURCE_DIR}/yaml/test_ok_3.yaml) - add_test(test_solparser_ok_4 test_solparser - ${SOLPARSER_SOURCE_DIR}/yaml/test_ok_4.yaml) - add_test(test_solparser_ok_5 test_solparser - ${SOLPARSER_SOURCE_DIR}/yaml/test_ok_5.yaml) - add_test(test_solparser_ok_6 test_solparser - ${SOLPARSER_SOURCE_DIR}/yaml/test_ok_6.yaml) - add_test(test_solparser_ok_7 test_solparser - ${SOLPARSER_SOURCE_DIR}/yaml/test_ok_7.yaml) - add_test(test_solparser_ko test_solparser -e - ${SOLPARSER_SOURCE_DIR}/yaml/test_ko_0.yaml) - - new_test(test_solparser2) - new_test(test_solparser3) - new_test(test_solparser4) - new_test(test_solparser5) - new_test(test_solparser6) - new_test(test_solparser7) - new_test(test_solparser8) - new_test(test_solparser_normal_map) - new_test(test_solparser_spectrum) - new_test(test_solparser_mirror) - - rcmake_copy_runtime_libraries(test_solparser) -endif() - diff --git a/cmake/receivers/CMakeLists.txt b/cmake/receivers/CMakeLists.txt @@ -1,73 +0,0 @@ -# Copyright (C) 2018, 2019, 2021 |Meso|Star> (contact@meso-star.com) -# Copyright (C) 2016-2018 CNRS -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. - -cmake_minimum_required(VERSION 3.1) -project(srcvl C) - -set(SRCVL_SOURCE_DIR ${PROJECT_SOURCE_DIR}/../../src/receivers) - -################################################################################ -# Define include directories -################################################################################ -include_directories( - ${LibYAML_INCLUDE_DIR} - ${RSys_INCLUDE_DIR} - ${SRCVL_SOURCE_DIR}/../) - -################################################################################ -# Configure and define targets -################################################################################ -set(SRCVL_FILES_SRC srcvl.c) -set(SRCVL_FILES_INC srcvl.h) - -rcmake_prepend_path(SRCVL_FILES_SRC ${SRCVL_SOURCE_DIR}) -rcmake_prepend_path(SRCVL_FILES_INC ${SRCVL_SOURCE_DIR}) - -if(CMAKE_COMPILER_IS_GNUCC) - set(MATH_LIB m) -endif() - -add_library(srcvl STATIC ${SRCVL_FILES_SRC} ${SRCVL_FILES_INC}) -target_link_libraries(srcvl LibYAML ${MATH_LIB}) - -################################################################################ -# Tests -################################################################################ -if(NOT NO_TEST) - function(build_test _name) - add_executable(${_name} - ${SRCVL_SOURCE_DIR}/${_name}.c - ${SRCVL_SOURCE_DIR}/../test_solstice_utils.h) - target_link_libraries(${_name} LibYAML ${MATH_LIB} RSys srcvl) - endfunction() - - function(new_test _name) - build_test(${_name}) - add_test(${_name} ${_name}) - endfunction() - - build_test(test_srcvl) - add_test(test_srcvl_ok test_srcvl - ${SRCVL_SOURCE_DIR}/yaml/test_ok.yaml) - add_test(test_srvvl_ko test_srcvl -e - ${SRCVL_SOURCE_DIR}/yaml/test_ko.yaml) - - new_test(test_srcvl2) - rcmake_copy_runtime_libraries(test_srcvl) - -endif() - - diff --git a/config.mk b/config.mk @@ -0,0 +1,104 @@ +VERSION_MAJOR = 0 +VERSION_MINOR = 10 +VERSION_PATCH = 0 +VERSION = $(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_PATCH) + +PREFIX = /usr/local +LIBPREFIX = $(PREFIX)/lib +INCPREFIX = $(PREFIX)/include + +#LIB_TYPE = SHARED +LIB_TYPE = STATIC + +BUILD_TYPE = RELEASE +#BUILD_TYPE = DEBUG + +################################################################################ +# Defaults +################################################################################ +SOLSTICE_ARGS_DEFAULT_NREALISATIONS = 10000 +SOLSTICE_ARGS_DEFAULT_CAMERA_POS = 0,0,0 +SOLSTICE_ARGS_DEFAULT_CAMERA_TGT = 0,0,-1 +SOLSTICE_ARGS_DEFAULT_CAMERA_UP = 0,1,0 +SOLSTICE_ARGS_DEFAULT_CAMERA_FOV = 70 +SOLSTICE_ARGS_DEFAULT_IMG_WIDTH = 800 +SOLSTICE_ARGS_DEFAULT_IMG_HEIGHT = 600 +SOLSTICE_ARGS_DEFAULT_IMG_SPP = 1 + +################################################################################ +# Tools +################################################################################ +AR = ar +CC = cc +LD = ld +OBJCOPY = objcopy +PKG_CONFIG = pkg-config +RANLIB = ranlib + +################################################################################ +# Dependencies +################################################################################ +PCFLAGS_SHARED = +PCFLAGS_STATIC = --static +PCFLAGS = $(PCFLAGS_$(LIB_TYPE)) + +RSYS_VERSION = 0.15 +S3DUT_VERSION = 0.4 +SSP_VERSION = 0.15 +SSTL_VERSION = 0.7 +YAML_VERSION = 0.2 +SSOL_VERSION = 0.10 +SANIM_VERSION = 0.3 + +INCS = $$($(PKG_CONFIG) $(PCFLAGS) --cflags rsys s3dut star-sp sstl yaml-0.1 ssol sanim)\ + -fopenmp +LIBS = $$($(PKG_CONFIG) $(PCFLAGS) --libs rsys s3dut star-sp sstl yaml-0.1 ssol sanim)\ + -fopenmp -lm + +################################################################################ +# Compilation options +################################################################################ +WFLAGS =\ + -Wall\ + -Wcast-align\ + -Wconversion\ + -Wextra\ + -Wmissing-declarations\ + -Wmissing-prototypes\ + -Wshadow + +CFLAGS_HARDENED =\ + -D_FORTIFY_SOURCES=2\ + -fcf-protection=full\ + -fstack-clash-protection\ + -fstack-protector-strong + +CFLAGS_COMMON =\ + -std=c89\ + -pedantic\ + -fvisibility=hidden\ + -fstrict-aliasing\ + $(CFLAGS_HARDENED)\ + $(WFLAGS) + +CFLAGS_RELEASE = -O2 -DNDEBUG $(CFLAGS_COMMON) +CFLAGS_DEBUG = -g $(CFLAGS_COMMON) +CFLAGS = $(CFLAGS_$(BUILD_TYPE)) + +CFLAGS_SO = $(CFLAGS) -fPIC +CFLAGS_EXE = $(CFLAGS) -fPIE + +################################################################################ +# Linker options +################################################################################ +LDFLAGS_HARDENED = -Wl,-z,relro,-z,now +LDFLAGS_DEBUG = $(LDFLAGS_HARDENED) +LDFLAGS_RELEASE = -s $(LDFLAGS_HARDENED) +LDFLAGS = $(LDFLAGS_$(BUILD_TYPE)) + +LDFLAGS_SO = $(LDFLAGS) -shared -Wl,--no-undefined +LDFLAGS_EXE = $(LDFLAGS) -pie + +OCPFLAGS_DEBUG = --localize-hidden +OCPFLAGS_RELEASE = --localize-hidden --strip-unneeded +OCPFLAGS = $(OCPFLAGS_$(BUILD_TYPE)) diff --git a/doc/solstice-input.5 b/doc/solstice-input.5 @@ -0,0 +1,1328 @@ +.\" SPDX-License-Identifier: GPL-3.0-or-later +.\" Copyright (C) 2016-2018 CNRS, 2018-2019 |Méso|Star> +.\" +.\" This is free documentation: you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation, either version 3 of the License, or +.\" (at your option) any later version. +.\" +.\" This manual is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program. If not, see <http://www.gnu.org/licenses/>. +.Dd $Mdocdate$ +.Dt SOLSTICE-INPUT 5 +.Os +.Sh NAME +.Nm solstice-input +.Nd solar plant description for solstice +.Sh DESCRIPTION +The +.Nm +format is used by the +.Xr solstice 1 +program to represent a solar plant. +It relies on the YAML 1.1 data serialization standard +.Po +see +.Sx NOTES , +reference 1 +.Pc ; +assuming that the file is compatible with the +.Nm +semantic, a solar plant can be described by using the whole YAML 1.1 +functionalities including compact notation and data tagging. +.Pp +A solar plant is composed of a +.Em sun , +an optional +.Em atmosphere +and a collection of +.Em geometries , +i.e.\& +.Em shapes +with their associated +.Em material . +Beside the raw description of the aforementioned data, the +.Nm +format provides the +.Em entity +item to efficiently structure the geometries in the scene. +An entity is a node in a tree data structure where the position of each +child entity is relative to the position of its parent. +An entity can either encapsulate a +.Em geometry +or a +.Em pivot +that controls the dynamic positioning of its child entities with respect +to the pivot constraints and the sun direction submitted to the +.Xr solstice 1 +program. +.Sh GRAMMAR +.Bd -literal +<solar-plant> ::= - <sun> + - <item> + [ - <item> ... ] + [ - <atmosphere> ] + +<item> ::= <entity> + | <geometry> + | <material> + | <medium> + | <spectrum> + | <template> +.Ed +.Bd -literal +<geometry> ::= geometry: + - <object> + [ - <object> ... ] + +<object> ::= <shape> + <material> + [ <transform> ] + +<x_pivot> ::= x_pivot: + <target> + [ ref_point: <real3> ] # Default is [0,0,0] + +<zx_pivot> ::= zx_pivot: + <target> + [ spacing: REAL ] # in [0, INF). Default 0 + [ ref_point: <real3> ] # Default is [0,0,0] + +<target> ::= target: + anchor: <anchor-identifier> + | direction: <real3> + | position: <real3> + | <sun> +.Ed +.Bd -literal +<shape> ::= <cuboid> + | <cylinder> + | <hemisphere> + | <hyperbol> + | <parabol> + | <parabolic-cylinder> + | <plane> + | <sphere> + | <stl> + +<cuboid> ::= cuboid: + size: <real3> # in ]0, INF]^3 + +<cylinder> ::= cylinder: + height: REAL # in ]0, INF) + radius: REAL # in ]0, INF) + [ slices: INTEGER ] # in [4, 4096]. Default is 16 + [ stacks: INTEGER ] # in [1, 4096]. Default is 1 + +<hemisphere> ::= hemisphere: + radius: REAL # in ]0, INF) + [ clip: <polyclip-list> ] + [ slices: INTEGER ] # in [4, 4096] + +<hyperbol> ::= hyperbol: + focals: <hyperboloid-focals> + clip: <polyclip-list> + [ slices: INTEGER ] # in [4, 4096] + +<parabol> ::= parabol: + focal: REAL # in ]0, INF) + clip: <polyclip-list> + [ slices: INTEGER ] # in [4, 4096] + +<parabolic-cylinder> ::= parabolic-cylinder: + focal: REAL # in ]0, INF) + clip: <polyclip-list> + [ slices: INTEGER ] # in [4, 4096] + +<plane> ::= plane: + clip: <polyclip-list> + [ slices: INTEGER ] # in [1, 4096]. Default is 1 + +<sphere> ::= sphere: + radius: REAL # in ]0, INF) + [ slices: INTEGER ] # in [4, 4096]. Default is 16 + [ stacks: INTEGER ] # in [2, 4096]. Default is slices/2 + +<stl> ::= stl: + path: PATH + +<hyperboloid-focals> ::= real: REAL # in ]0, INF) + image: REAL # in ]0, INF) +.Ed +.Bd -literal +<polyclip-list> ::= - <polyclip> + [ - <polyclip> ... ] + +<polyclip> ::= operation: <AND|SUB> + <contour-descriptor> + +<contour-descriptor> ::= <circle-descriptor> + | <vertices-descriptor> + +<vertices-descriptor> ::= vertices: <vertices-list> + +<circle-descriptor> ::= circle: + radius: REAL # in ]0, INF) + [ center: <real2> ] # Default is 0,0 + [ segments: INTEGER ] # in [3, 4096]. Default is 64 + +<vertices-list> ::= - <real2> + - <real2> + - <real2> + [ - <real2> ... ] +.Ed +.Bd -literal +<material> ::= material: + <material-descriptor> + | <double-sided-mtl> + +<double-sided-mtl> ::= front: <material-descriptor> + back: <material-descriptor> + +<material-descriptor> ::= <dielectric> + | <matte> + | <mirror> + | <thin-dielectric> + | <virtual> + +<dielectric> ::= dielectric: + medium_i: <medium-descriptor> + medium_t: <medium-descriptor> + [ <normal-map> ] + +<matte> ::= matte: + reflectivity: <mtl-data> # in [0, 1] + [ <normal-map> ] + +<mirror> ::= mirror: + reflectivity: <mtl-data> # in [0, 1] + slope_error: <mtl-data> + [ microfacet: <normal-distrib> ] # Default is BECKMANN + [ <normal-map> ] + +<normal-distrib> ::= BECKMANN + | PILLBOX + +<virtual> ::= virtual: EMPTY-STRING + +<thin-dielectric> ::= thin_dielectric: + thickness: REAL # in [0, INF) + medium_i: <medium-descriptor> + medium_t: <medium-descriptor> + [ <normal-map> ] + +<normal-map> ::= normal_map: + path: PATH +.Ed +.Bd -literal +<medium> ::= medium: <medium-descriptor> + +<medium-descriptor> ::= refractive_index: <mtl-data> # in ]0, INF) + extinction: <mtl-data> # in [0, INF) +.Ed +.Bd -literal +<entity> ::= entity: <entity-data> + +<template> ::= template: <entity-data> + +<entity-data> ::= name: STRING + [ <geometry-data> | <x_pivot> | <zx_pivot> ] + [ <anchors> ] + [ <transform> ] + [ <children> ] + +<geometry-data> ::= primary: INTEGER # in [0, 1] + <geometry> + +<children> ::= children: + - <entity-data> + [ - <entity-data> ... ] + +<anchors> ::= anchors: + - <anchor-data> + [ - <anchor-data> ... ] + +<anchor-data> ::= name: STRING + <position-descriptor> + +<position-descriptor> ::= position: <real3> + | hyperboloid_image_focals: <hyperboloid_focals> + +<entity-identifier> ::= <self|STRING>[.STRING ... ] + +<anchor-identifier> ::= <entity-identifier>.STRING +.Ed +.Bd -literal +<sun> ::= sun: + dni: REAL # Direct Normal Irradiance in ]0, INF) + [ <spectrum> ] # Default is the smarts295 spectrum + [ <sun-shape> ] + +<sun-shape> ::= <pillbox> | <gaussian> | <buie> + +<buie> ::= buie: + csr: REAL # in [1e-6, 0.849] + +<pillbox> ::= pillbox: + half_angle: REAL # in ]0, 90] + +<gaussian> ::= gaussian: + std_dev: REAL # in ]0, INF) +.Ed +.Bd -literal +<atmosphere> ::= atmosphere: + extinction: <mtl-data> # in [0, 1] +.Ed +.Bd -literal +<mtl-data> ::= REAL + | <spectrum-data-list> + +<transform> ::= transform: + translation: <real3> + rotation: <real3> + +<real2> ::= - REAL + - REAL + +<real3> ::= - REAL + - REAL + - REAL + +<spectrum> ::= spectrum: <spectrum-data-list> + +<spectrum-data-list> ::= - <spectrum-data> + [ - <spectrum-data> ... ] + +<spectrum-data> ::= wavelength: REAL # in [0, INF) + data: REAL # in [0, INF) +.Ed +.Sh SUN +The +.Em sun +describes the source of the solar plant. +Its direction is not defined in the +.Nm +file but is provided by the +.Xr solstice 1 +command. +This allows the same unmodified +.Nm +file to be used for several simulations with different sun directions. +.Pp +The main +.Em sun +property is its direct normal irradiance, or +.Em dni +in W\(md m\u\s-2\-2\s0\d. +Its value is a scalar defining the direct irradiance received on a plane +perpendicular to the main sun direction. +The optional +.Em spectrum +parameter describes the per-wavelength distribution of the sun +.Em dni . +Note that this distribution is automatically normalized by +.Xr solstice 1 . +If the +.Em spectrum +attribute is not defined, +.Xr solstice 1 +uses a default spectrum computed with the SMARTS software +.Po +see +.Sx NOTES , +reference 2 +.Pc +between 0.28 and 4 micrometres. +The total +.Em dni +(integrated over the spectral range) was set to 1000 W\(md m\u\s-2\-2\s0\d. +The standard Mid-Latitude-Summer atmosphere was used with most gas +concentrations set as default (CO2 concentration assumed 400 ppmv). +.Pp +Even if an atmosphere is provided, the atmospheric effects from the top +of the atmosphere to ground level are not computed using the atmosphere +description. +As a result, the sun description +.Pq Em dni No and optional Em spectrum +is expected to include all atmospheric effects (sun irradiance available +at ground level). +.Pp +The +.Em sun-shape +parameter controls the angular distribution of the sun light intensity +across the sun's disk. +If not defined, the distribution is assumed to be a Dirac distribution +(infinite directional source). +The available sun shapes are: +.Bl -tag -width Ds +.It Em pillbox +The +.Em pillbox +distribution defines a uniform intensity over the sun's disk. +Its single +.Em half_angle +parameter is the sun's disk half-angle in degrees, linked to the +apparent size of the sun. +A typical +.Em half_angle +is 0.2664. +.It Em gaussian +The +.Em gaussian +distribution defines a Gaussian distribution of the solar incoming +direction. +Its single +.Em std_dev +parameter is the standard deviation of the distribution in degrees. +Values around 0.2 are typical. +As the Gaussian distribution is not truncated, the resulting sun vector +can theoretically be oriented away from the sun, especially with a +large, non-typical +.Em std_dev +value. +.It Em buie +The +.Em buie +distribution, as first described in reference 3 +.Pq see Sx NOTES . +Its single +.Em csr +parameter is the ratio between the circumsolar irradiance and the sum +of the circumsolar and sun's disk irradiance. +An analysis of typical +.Em csr +values can be found in reference 4 +.Pq see Sx NOTES . +.El +.Sh ATMOSPHERE +The +.Em atmosphere , +when provided, describes the medium surrounding the solar plant. +Its only parameter is its extinction coefficient in m\u\s-2\-1\s0\d, +which can either be a scalar if the extinction is constant over the +spectrum, or can be spectrally described. +The extinction along light paths is only computed after the first +reflector, as the sun description must include all atmospheric effects +before the first reflector (see +.Sx SUN +for more details). +.Pp +If no atmosphere is provided, atmospheric extinction after the first +reflector is not taken into account. +.Sh MATERIAL +A +.Em material +describes the properties of an interface. +These properties can be the same for both sides of the interface or may +be differentiated with a +.Em double-sided-mtl . +The material behaviour is controlled by a +.Em material-descriptor +that specifies the physical properties of the interface as well as its +optional normal perturbation. +Note that the physical properties can be either scalars or spectral data. +.Ss Material descriptors +The available material descriptors are: +.Bl -tag -width Ds +.It Em dielectric +Interface between two dielectric media. +Its +.Em medium_i +parameter defines the current medium (the medium the ray travels in), +while +.Em medium_t +represents the opposite medium. +Incoming rays are either specularly reflected or refracted according to +a Fresnel term: +.Bd -literal -offset indent +Fr = 1/2 * (Rs^2 + Rp^2) +.Ed +.Pp +with Rs and Rp the reflectance for light polarized with its electric +field perpendicular or parallel to the plane of incidence, respectively: +.Bd -literal -offset indent +Rs = (n1 * |wi.N| - n2 * |wt.N|) / (n1 * |wi.N| + n2 * |wt.N|) +Rp = (n2 * |wi.N| - n1 * |wt.N|) / (n2 * |wi.N| + n1 * |wt.N|) +.Ed +.Pp +with n1 and n2 the indices of refraction of the incident and transmitted +media, and wi and wt the incident and transmitted direction. +.Pp +Be careful to ensure media consistency in the +.Nm +file: a ray travelling in a medium +.Em A +can only encounter a medium interface whose +.Em medium_i +attribute is +.Em A . +Consequently, a +.Em dielectric +material must be defined as a double-sided material whose front and back +interfaces are dielectrics with inverted media: +.Bd -literal -offset indent +material: + front: + dielectric: + medium_i: &vacuum { refractive_index: 1, extinction: 0 } + medium_t: &glass { refractive_index: 1.5, extinction: 20 } + back: + dielectric: + medium_i: *glass + medium_t: *vacuum +.Ed +.Pp +If media consistency is not ensured, +.Xr solstice 1 +will fail to run simulations. +Note that by default, the surrounding medium is assumed to be vacuum, +i.e.\& its refractive index and extinction are scalars with values 1 and +0, respectively. +If an atmosphere is defined, the refractive index of the surrounding +medium is still the scalar 1 but its extinction is that of the +atmosphere. +.It Em matte +Diffuse surface. +Reflects the same intensity in all directions independently of the +incoming direction. +.It Em mirror +Specular or glossy reflection, depending on whether the +.Em slope_error +parameter is 0 or not. +Glossy reflections are controlled by a microfacet BRDF. +The microfacet normals are distributed according to the Beckmann or +Pillbox distribution, as specified by the +.Em normal-distrib +attribute. +.Pp +Let S be the +.Em slope_error +parameter in ]0,\ 1]. +The Beckmann distribution is defined as: +.Bd -literal -offset indent +D(wh) = exp(-tan^2(a) / m^2) / (PI * m^2 * cos^4(a)) +.Ed +.Pp +with a = arccos(wh.N) and m = sqrt(2)*S, while the Pillbox distribution +is defined as: +.Bd -literal -offset indent + | 0; if |wh.N| >= S +D(wh) = | + | 1 / (PI * (1 - cos^2(S))); if |wh.N| < S +.Ed +.It Em thin-dielectric +The interface is assumed to be a thin slab of a dielectric material. +The +.Em medium_i +parameter defines the outside dielectric medium while +.Em medium_t +is the medium of the thin slab. +Incoming rays are either specularly reflected or transmitted (without +deviation) according to a Fresnel term (see +.Em dielectric +above for the formula). +The underlying scattering function correctly handles the multiple +refraction effects within the thin slab. +.Pp +The same media consistency rules as for +.Em dielectric +apply: if not ensured, +.Xr solstice 1 +will fail to run simulations. +By default, the surrounding medium is vacuum (refractive index 1, +extinction 0). +If an atmosphere is defined, the refractive index of the surrounding +medium is still 1, but its extinction is that of the atmosphere. +.It Em virtual +Fully transparent interface. +.El +.Ss Normal map +All material descriptors except +.Em virtual +provide an optional +.Em normal-map +attribute that defines a path to a Portable PixMap image +.Po +see +.Sx NOTES , +reference 5 +.Pc +whose pixels store a normal expressed in the tangent space of the +interface. +By default, the unperturbed tangent space normal is {0,0,1}. +The PPM image can be encoded on 8 or 16 bits per component either in +ASCII or binary. +The parameterization of this 2D image onto the shape surfaces depends +on the type of shape. +For the +.Em hemisphere , hyperbol , parabol , plane +and +.Em parabolic-cylinder +shapes, the image is mapped in the {X,Y} plane. +Other shapes are not parameterized; applying a normal-mapped material to +them leads to undefined behaviour. +.Sh SHAPE +A +.Em shape +describes a geometric model defined in its local coordinate system, +whose origin is proper to the shape. +No spatial transformation can be introduced through the declaration of +a shape: it should be transformed externally through an +.Em object +and/or +.Em entity . +.Pp +Two types of shape are provided: quadric and mesh. +The former is used to declare parametric surfaces; the latter describes +triangulated surfaces. +.Ss Quadric +A quadric shape is defined from a quadric equation and a set of 2D +clipping operations performed in its {X,Y} plane. +By convention, the front side of the quadric surface looks toward the +positive Z axis. +Internally, the clipped quadric surface is discretized into a triangular +mesh according to the quadric's discretization parameters. +This mesh is used by +.Xr solstice 1 +as a proxy to speed up access to the quadric shape; the exact position +and normal are ultimately computed from the quadric equation. +.Pp +The quadric surface is parameterized in the {X,Y} plane: +.Bd -literal -offset indent +u = (x - lowerX) / (upperX - lowerX) +v = (y - lowerY) / (upperY - lowerY) +.Ed +.Pp +with +.Em u +and +.Em v +the mapped 2D coordinates from a 3D position {x,y,z} onto the quadric, +and +.Em lower Ns <X|Y> +and +.Em upper Ns <X|Y> +the lower and upper bounds of the clipped quadric along the X and Y +axes. +The available quadrics are: +.Bl -tag -width Ds +.It Em hemisphere +Hemispheric shape defined along the Z axis whose minimum is at the +origin. +The +.Em slices +parameter controls the number of divisions along the Z axis. +.Bd -literal -offset indent +x^2 + y^2 + (z-radius)^2 = radius^2 +.Ed +.It Em hyperbol +Hyperbolic quadric defined along the Z axis whose minimum is at the +origin. +The +.Em slices +parameter controls the discretization of the hyperbol. +If not defined, it is automatically computed from the hyperbol +curvature. +.Bd -literal -offset indent +(x^2 + y^2) / a^2 - (z + z0 - g/2)^2 / b^2 + 1 = 0 + +a^2 = g^2(f - f^2) +b = g(f - 1/2) +z0 = |b| + g/2 +g = focals.real + focals.image +f = focals.real / g +.Ed +.It Em parabol +Parabolic quadric defined along the Z axis whose minimum is at the +origin. +The +.Em slices +parameter controls the discretization of the parabol. +If not defined, it is automatically computed from the parabol curvature. +.Bd -literal -offset indent +x^2 + y^2 - 4 * focal * z = 0 +.Ed +.It Em parabolic-cylinder +Parabolic cylinder oriented along the Z axis, with its main axis along +the X axis and minimum at the origin. +The +.Em slices +parameter controls the discretization. +If not defined, it is automatically computed from the curvature. +.Bd -literal -offset indent +y^2 - 4 * focal * z = 0 +.Ed +.It Em plane +Plane whose normal points along the positive Z axis. +The +.Em slices +attribute controls the discretization of the clipped plane. +.El +.Ss Clipping +A clipping operation, or +.Em polyclip , +removes parts of the quadric surface. +It is defined by a 2D +.Em contour-descriptor +expressed in the {X,Y} plane and a clipping +.Em operation . +The +.Em AND +operand retains the portion of the quadric that intersects the +contour; the +.Em SUB +operand removes the portion that intersects the contour. +The available contour descriptors are: +.Bl -tag -width Ds +.It Em circle-descriptor +Circular contour whose size is defined by the +.Em radius +parameter. +.Xr solstice 1 +discretizes the circular contour using the +.Em segments +attribute as the number of segments used to approximate the circle. +.It Em vertices-descriptor +Polygonal contour described by a list of 2D vertices. +Polygon edges connect each vertex to its predecessor; an additional +edge automatically closes the polygon between the last and first vertex. +Note that +.Xr solstice 1 +assumes the polygon does not self-intersect. +.El +.Pp +The +.Em clip +parameter of a quadric lists a set of +.Em polyclips +applied successively in declaration order. +For example, the following uses 5 clipping operations on a plane to +build a rectangle with a circular hole at each corner: +.Bd -literal -offset indent +plane: + clip: + - {operation: AND, vertices: [[-4,-2],[-4,2],[4,2],[4,-2]]} + - {operation: SUB, circle: {radius: 0.5, center: [-3,-1]}} + - {operation: SUB, circle: {radius: 0.5, center: [-3, 1]}} + - {operation: SUB, circle: {radius: 0.5, center: [ 3,-1]}} + - {operation: SUB, circle: {radius: 0.5, center: [ 3, 1]}} +.Ed +.Ss Triangular mesh +Triangular meshes are generated by +.Xr solstice 1 +from a shape description or loaded from a CAO file. +Their normals are defined per triangle and are thus discontinuous even +for smooth shapes. +Triangular meshes are not parameterized; applying a normal-mapped +material to them produces undefined behaviour. +The available triangular meshes are: +.Bl -tag -width Ds +.It Em cuboid +Axis-aligned cuboid centered at the origin, whose corner positions and +dimensions along the three axes are defined by the +.Em size +parameter. +The front side of the surface looks outside the cuboid. +.It Em cylinder +Cylinder centered at the origin whose +.Em height +is along the positive Z axis. +Top and bottom are capped. +The +.Em stacks +and +.Em slices +parameters control the number of divisions along and around the Z axis, +respectively. +The front side looks outside the cylinder. +.It Em sphere +Triangulated sphere centered at the origin. +The +.Em stacks +and +.Em slices +parameters control the number of divisions along and around the Z axis, +respectively. +The front side looks outside the sphere. +.It Em stl +Path to an external mesh file in ASCII +.Em ST Ns ereo Ns Em L Ns ithography +(STL) format. +The front side of each triangle is determined by the vertex ordering in +the STL file: a triangle is front-facing when its vertices are +clockwise-ordered. +.El +.Sh ENTITY +An +.Em entity +is used to declare and position shapes in the solar plant. +An entity is the only item that effectively instantiates a +.Em geometry +into the solar plant: a geometry declared but not referenced by an +entity is ignored by +.Xr solstice 1 . +An entity is a hierarchical data structure whose child entities' +transformation is relative to their parent. +If not defined, the +.Em transform +of an entity is the identity (null rotation and translation). +.Pp +Each entity has a +.Em name +which must be unique per hierarchy level. +The name string cannot contain dots, spaces or tabulations. +A child entity is identified in the solar plant by concatenating, with +the +.Sq .\& +character, the names of its ancestors with its own name. +For instance, the identifier of a child entity named +.Em level2 +is +.Em level0.level1.level2 : +.Bd -literal -offset indent +entity: + name: level0 + child: + - name: level1 + child: + - name: level2 +.Ed +.Pp +An entity encapsulates either a +.Em geometry +(a collection of +.Em objects ) +or a +.Em pivot . +Each entity can also have a list of +.Em anchors +defining positions relative to the entity. +.Pp +For a geometric entity, one must specify whether the encapsulated +geometry is a +.Em primary +geometry (i.e.\& directly lit by the sun and used to concentrate solar +flux, such as a primary mirror). +Correctly tagging primary geometries drastically improves the +convergence speed of +.Xr solstice 1 +simulations. +.Ss Template +A +.Em template +is a first-level entity with no existence in the solar plant itself. +It is used to pre-declare an entity hierarchy that can then be +instantiated multiple times by referencing it through common entities +with YAML data tagging: +.Bd -literal -offset indent +- template: &my-template + name: bar + primary: 1 + geometry: ... +- entity: + name: foo0 + transform: {translation: [-10.5, 0, 0]} + children: [*my-template] +- entity: + name: foo1 + transform: {translation: [0, 0, 0]} + children: [*my-template] +- entity: + name: foo2 + transform: {translation: [10.5, 0, 0]} + children: [*my-template] +.Ed +.Ss Pivot +A +.Em pivot +is a special kind of node that automatically orients its child geometry +according to the sun position and pivot parameters. +It is typically (but not mandatorily) the parent of a reflector that, +once pivoted, will redirect sun light toward a +.Em target . +A pivot cannot be the child of another pivot. +.Pp +The +.Em target +parameter is the most important pivot parameter. +Four types of target are available: +.Bl -tag -width Ds +.It Em position +The target is an absolute point in world coordinates. +.It Em anchor +The target is a position relative to an entity (see +.Sx Anchor ) . +.It Em sun +The target is the center of the sun. +.It Em direction +The pivot reflects light in the given direction, specified in world +coordinates. +.El +.Pp +Pivots can also have an optional +.Em ref_point +parameter defining a 3D point in the coordinate system of the pivot's +children that is used by the pointing algorithm. +If not provided, it defaults to the origin. +.Pp +Two flavours of pivot are available: +.Bl -tag -width Ds +.It Em x_pivot +Single-axis pivot rotating around the +X axis in its local coordinate +system. +Its pointing algorithm considers an incoming ray from the center of the +sun and rotates its children so that a specular reflection at +.Em ref_point +using +Z as the local normal hits the target, or produces the specified +direction. +.It Em zx_pivot +Two-axis pivot: first a rotation around the +Z axis in its local +coordinate system, then a rotation around the +X axis in the resulting +coordinate system. +The optional +.Em spacing +parameter defines a translation along the +Y axis applied after the +first rotation (default: 0). +Its pointing algorithm considers an incoming ray from the center of the +sun and rotates its children so that a specular reflection at +.Em ref_point +using +Y as the local normal hits the target, or produces the specified +direction. +.El +.Ss Anchor +An +.Em anchor +defines a relative position in the entity hierarchy. +Anchors are particularly useful for pivots and hyperbolic shapes that +must reference a position relative to an entity whose transformation may +depend on its ancestors. +An anchor's +.Em name +must be unique among all anchors in its entity and cannot contain dots, +spaces or tabulations. +An anchor is identified in the solar plant by concatenating its name to +the +.Em entity-identifier +of the entity in which it is declared, using +.Sq .\& +as separator. +For example, the identifier of an anchor named +.Em anchor0 +declared in +.Em level0.level1 +is +.Em level0.level1.anchor0 . +.Pp +When the root entity name of a template is unknown (because the template +has not yet been instantiated), the +.Em self +reserved keyword can be used to reference the unknown root entity. +For example: +.Bd -literal -offset indent +- template: &my-template + name: level0 + anchor: [{name: anchor0, position: [1, 2, 3]}] + child: + - name: level1 + pivot: + x_pivot: + ref_point: {0, 0, 0} + target: {anchor: self.level0.anchor0} + +- entity: {name: entity0, child: [*my-template]} +- entity: {name: entity1, child: [*my-template]} +.Ed +.Ss Transform +A +.Em transform +moves an +.Em object +or an +.Em entity +in space. +The +.Em rotation +parameter lists 3 angles in degrees defining rotations around the X, Y +and Z axes. +The +.Em translation +attribute describes offsets along the X, Y and Z axes. +Given a local frame +.Em p +of an object, +.Em p +is transformed into +.Em p' +as: +.Bd -literal -offset indent +p' = Rx * Ry * Rz * (T + p) +.Ed +.Pp +with +.Em T +the translation vector and +.Em Rx , Ry , Rz +the rotation matrices around the X, Y and Z axes: +.Bd -literal -offset indent + | 1 0 0 | | cY 0 sY | | cZ -sZ 0 | +Rx = | 0 cX -sX |; Ry = | 0 1 0 |; Rz = | sZ cZ 0 | + | 0 sX cX | |-sY 0 cY | | 0 0 1 | +.Ed +.Pp +where +.Em c Ns <X|Y|Z> +and +.Em s Ns <X|Y|Z> +are the cosine and sine of the rotation angles around the X, Y and Z +axes, respectively. +.Sh EXAMPLES +Declare 2 entities and a point-source sun. +The first entity is a purely specular square of size 10 centered at the +origin. +The second is a purely transparent square used as a receiver; its size +is 1 and its center is at {0,0,2}: +.Bd -literal -offset indent +- sun: {dni: 1000} + +- entity: + name: reflector + primary: 1 + geometry: + - material: + mirror: + reflectivity: 1 + slope_error: 0 + plane: + clip: + - operation: AND + vertices: + - [-5.0,-5.0] + - [-5.0, 5.0] + - [ 5.0, 5.0] + - [ 5.0,-5.0] + +- entity: + name: receiver + primary: 0 + transform: + translation: [0, 0, 2] + geometry: + - material: + virtual: # No attrib + plane: + clip: + - operation: AND + vertices: + - [-0.5,-0.5] + - [-0.5, 0.5] + - [ 0.5, 0.5] + - [ 0.5,-0.5] +.Ed +.Pp +Define a circular diffuse reflector surrounded by a virtual sphere, with +a pillbox-shaped sun of +.Em half_angle +0.1 degree. +Use anchors and YAML tags to reference a pre-declared geometry, and the +YAML compact notation to reduce the number of lines: +.Bd -literal -offset indent +- sun: {dni: 1000, pillbox: {half_angle: 0.1}} + +- geometry: &small-circle + - material: {matte: {reflectivity: 1}} + plane: {clip: [{operation: AND, circle: {radius: 0.5}}]} + +- geometry: &big-sphere + - material: {virtual: ""} + sphere: {radius: 2, slices: 128} + +- entity: {name: reflector, primary: 1, geometry: *small-circle} +- entity: {name: receiver, primary: 0, geometry: *big-sphere} +.Ed +.Pp +Declare 2 parabolic reflectors from a templated parabola whose +orientation is controlled by a +.Em zx_pivot +targeting an anchor defined relative to the receiver: +.Bd -literal -offset indent +- sun: {dni: 1000} + +- entity: # Receiver + name: square_receiver + primary: 0 + transform: { rotation: [0,90,0], translation: [100,0,10] } + anchors: [{name: anchor0, position: [0,0,0]}] + geometry: + - material: {virtual: ""} + plane: + clip: + - operation: AND + vertices: [[-.5,-.5],[-.5,.5],[.5,.5],[.5,-.5]] + +- template: &self_oriented_parabol # Reflector + name: pivot + transform: {translation: [0, 0, 4], rotation: [0, 0, 90]} + zx_pivot: {target: {anchor: square_receiver.anchor0}} + children: + - name: parabol + transform: {rotation: [-90, 0, 0]} + primary: 1 + geometry: + - material: {mirror: {reflectivity: 1, slope_error: 0}} + parabol: + focal: 100 + clip: + - operation: AND + vertices: [[-5,-5],[-5,5],[5,5],[5,-5]] + +# Instantiate the reflector template +- entity: + name: reflector1 + transform: {translation: [0,0,0]} + children: [*self_oriented_parabol] +- entity: + name: reflector2 + transform: {translation: [10,43.6,0]} + children: [*self_oriented_parabol] +.Ed +.Pp +Declare a solar furnace with 9 heliostats instantiated from the same +template. +Their position is controlled by a +.Em zx_pivot +to ensure that incoming sun rays are reflected toward the negative X +axis. +Reflected rays are then concentrated by a parabola toward a purely +absorptive receiver. +The heliostats and the parabola share the same double-sided material: +front faces are purely specular, back faces are diffuse: +.Bd -literal -offset indent +- sun: {dni: 1000} + +- material: &specular + front: {mirror: {reflectivity: 1, slope_error: 0}} + back: {matte: {reflectivity: 1}} + +- template: &H # Template of a heliostat + name: heliostat + transform: {translation: [0,0,5.5]} + zx_pivot: {target: {direction: [-1,0,0]}} + children: + - name: reflector + transform: {rotation: [-90,0,0]} + primary: 1 + geometry: + - material: *specular + plane: + clip: [{operation: AND, vertices: [[-5,-5],[-5,5],[5,5],[5,-5]]}] + +- entity: # Receiver entity + name: receiver + primary: 0 + transform: {translation: [18,0,20], rotation: [0,90,0]} + geometry: + - material: {matte: {reflectivity: 0}} + plane: + clip: + - operation: AND + vertices: [[-.5,-.5],[-.5,.5],[.5,.5],[.5,-.5]] + +- entity: # Great parabola + name: parabola + primary: 0 + transform: {translation: [0,0,20], rotation: [0,90,90]} + geometry: + - material: *specular + parabol: + focal: 18 + clip: [{operation: AND, vertices: [[-30,-20],[-30,20],[30,20],[30,-20]]}] + +# Instantiate the heliostat template +- entity: {name: H1, children: [*H], transform: {translation: [40,-20, 0]}} +- entity: {name: H2, children: [*H], transform: {translation: [40, 0, 0]}} +- entity: {name: H3, children: [*H], transform: {translation: [40, 20, 0]}} +- entity: {name: H4, children: [*H], transform: {translation: [60,-20,10]}} +- entity: {name: H5, children: [*H], transform: {translation: [60, 0,10]}} +- entity: {name: H6, children: [*H], transform: {translation: [60, 20,10]}} +- entity: {name: H7, children: [*H], transform: {translation: [80,-20,20]}} +- entity: {name: H8, children: [*H], transform: {translation: [80, 0, 20]}} +- entity: {name: H9, children: [*H], transform: {translation: [80, 20,20]}} +.Ed +.Pp +Three partial parabols with various focal distances concentrate incoming +radiation at a common focal position. +A hyperbol is located between the parabols and their common focal, which +is also one of the two focals of the hyperbol. +Radiation is redirected to the second focal of the hyperbol where the +square target is located. +A cuboid using a glass material is located between the hyperbol and the +target. +This example also illustrates the use of +.Em spectrum +for refractive index and extinction: +.Bd -literal -offset indent +# Spectra +- spectrum: &solar_spectrum + - {wavelength: 0.3, data: 1.0} + - {wavelength: 0.4, data: 2.0} + - {wavelength: 0.5, data: 0.5} + - {wavelength: 0.6, data: 3.5} + - {wavelength: 0.7, data: 1.5} + - {wavelength: 0.8, data: 0.8} + +- spectrum: &air_kabs + - {wavelength: 0.3, data: 1.0e-4} + - {wavelength: 0.4, data: 1.0e-5} + - {wavelength: 0.5, data: 2.0e-5} + - {wavelength: 0.6, data: 2.0e-4} + - {wavelength: 0.7, data: 3.0e-5} + - {wavelength: 0.8, data: 1.0e-4} + +- spectrum: &glass_kabs + - {wavelength: 0.3, data: 1.0e-2} + - {wavelength: 0.4, data: 1.0e-3} + - {wavelength: 0.5, data: 2.0e-3} + - {wavelength: 0.6, data: 2.0e-2} + - {wavelength: 0.7, data: 3.0e-3} + - {wavelength: 0.8, data: 1.0e-3} + +- spectrum: &glass_ref_index + - {wavelength: 0.30, data: 1.40} + - {wavelength: 0.40, data: 1.39} + - {wavelength: 0.50, data: 1.37} + - {wavelength: 0.60, data: 1.34} + - {wavelength: 0.70, data: 1.30} + - {wavelength: 0.80, data: 1.25} + +# Media +- medium: &air_medium + refractive_index: 1 + extinction: *air_kabs + +- medium: &glass_medium + refractive_index: *glass_ref_index + extinction: *glass_kabs + +# Sun & atmosphere +- sun: {dni: 1, spectrum: *solar_spectrum} +- atmosphere: {extinction: *air_kabs} + +# Materials +- material: &specular {mirror: {reflectivity: 1, slope_error: 0}} +- material: &black {matte: {reflectivity: 0}} +- material: &glass + front: {dielectric: {medium_i: *air_medium, medium_t: *glass_medium}} + back: {dielectric: {medium_i: *glass_medium, medium_t: *air_medium}} + +# Primary reflectors +- entity: + name: "primary_reflector1" + primary: 1 + transform: {translation: [0, 0, -2.0]} + geometry: + - material: *specular + parabol: + focal: 12 + clip: + - {operation: AND, circle: {radius: 10}} + - {operation: SUB, circle: {radius: 5}} + +- entity: + name: "primary_reflector2" + primary: 1 + transform: {translation: [0, 0, -4]} + geometry: + - material: *specular + parabol: + focal: 14 + clip: + - {operation: AND, circle: {radius: 15}} + - {operation: SUB, circle: {radius: 10}} + +- entity: + name: "primary_reflector3" + primary: 1 + transform: {translation: [0, 0, -6]} + geometry: + - material: *specular + parabol: + focal: 16 + clip: + - {operation: AND, circle: {radius: 20}} + - {operation: SUB, circle: {radius: 15}} + +# Secondary reflector +- entity: + name: "secondary_reflector" + primary: 0 + transform: {translation: [0, 0, 6]} + geometry: + - material: *specular + hyperbol: + focals: {real: 16.0, image: 4} + clip: [{operation: AND, circle: {radius: 5}}] + +# Glass box +- entity: + name: "glass_slide" + primary: 0 + geometry: + - material: *glass + cuboid: {size: [10,10,0.5]} + transform: {translation: [0, 0, 0.25]} + +# Receiver +- entity: + name: "square_receiver" + primary: 0 + transform: {translation: [0, 0, -10] } + geometry: + - material: *black + plane: + clip: + - operation: AND + vertices: [[-0.5,-0.5],[-0.5,0.5],[0.5,0.5],[0.5,-0.5]] +.Ed +.Sh NOTES +.Bl -enum +.It +YAML Ain't Markup Language \(em +.Lk http://yaml.org +.It +SMARTS, Simple Model of the Atmospheric Radiative Transfer of Sunshine \(em +.Lk http://www.nrel.gov/rredc/smarts/ +.It +D.\& Buie, A.G.\& Monger, C.J.\& Dey. +.Dq Sunshape distributions for terrestrial solar simulations . +.Em Solar Energy , +2003, 74, pp.\& 113\(en122. +.It +D.\& Buie, C.J.\& Dey, S.\& Bosi. +.Dq The effective size of the solar cone for solar concentrating systems . +.Em Solar Energy , +2003, 74, pp.\& 417\(en427. +.It +Portable PixMap \(em +.Lk http://netpbm.sourceforge.net/doc/ppm.html +.El +.Sh SEE ALSO +.Xr solstice 1 , +.Xr solstice-receiver 5 +.Sh HISTORY +.Nm +was initially developed with funding from the +.Em SOLSTICE LabEx +.Pq Laboratory of Excellence , +in collaboration with the PROMES Laboratory of the +French National Centre for Scientific Research +.Pq CNRS . +Starting in 2026, a new development effort funded by Ademe is ongoing. +.Sh AUTHORS +.Nm +was written and is maintained by +.An |M\['e]so|Star> Aq Mt contact@meso-star.com . diff --git a/doc/solstice-input.5.txt b/doc/solstice-input.5.txt @@ -1,1179 +0,0 @@ -// Copyright (C) 2016-2018 CNRS, 2018-2019 |Meso|Star> -// -// This is free documentation: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This manual is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. -:toc: - -solstice-input(5) -================= - -NAME ----- -solstice-input - solar plant description for solstice(1) - -DESCRIPTION ------------ -The *solstice-input* is the format used by the *solstice*(1) program to -represent a solar plant. It relies on the YAML 1.1 data serialization standard -[1]; assuming that the file is compatible with the *solstice-input* semantic, a -solar plant can be described by using the whole YAML 1.1 functionalities -including compact notation and data tagging. - -A solar plant is composed of a *sun*, an optional *atmosphere* and a collection -of *geometries*, i.e. *shapes* with their associated *material*. Beside the raw -description of the aforementioned data, the *solstice-input* format provides -the *entity* item to efficiently structure the geometries in the scene. An -entity is a node in a tree data structure where the position of each child -entity is relative to the position of its parent. An entity can either -encapsulate a *geometry* or a *pivot* that controls the dynamic positioning of -its child entities with respect to the pivot constraints and the sun direction -submitted to the *solstice*(1) program. - -GRAMMAR -------- - -[verse] -_______ -<solar-plant> ::= - <sun> - - <item> - [ - <item> ... ] - [ - <atmosphere> ] - -<item> ::= <entity> - | <geometry> - | <material> - | <medium> - | <spectrum> - | <template> - -------------------------------------- - -<geometry> ::= geometry: - - <object> - [ - <object> ... ] - -<object> ::= <shape> - <material> - [ <transform> ] - -<x_pivot> ::= x_pivot: - <target> - [ ref_point: <real3> ] # Default is [0,0,0] - -<zx_pivot> ::= zx_pivot: - <target> - [ spacing: REAL ] # in [0, INF). Default 0 - [ ref_point: <real3> ] # Default is [0,0,0] - -<target> ::= target: - anchor: <anchor-identifier> - | direction: <real3> - | position: <real3> - | <sun> - -------------------------------------- - -<shape> ::= <cuboid> - | <cylinder> - | <hemisphere> - | <hyperbol> - | <parabol> - | <parabolic-cylinder> - | <plane> - | <sphere> - | <stl> - -<cuboid> ::= cuboid: - size: <real3> # in ]0, INF]^3 - -<cylinder> ::= cylinder: - height: REAL # in ]0, INF) - radius: REAL # in ]0, INF) - [ slices: INTEGER ] # in [4, 4096]. Default is 16 - [ stacks: INTEGER ] # in [1, 4096]. Default is 1 - -<hemisphere> ::= hemisphere: - radius: REAL # in ]0, INF) - [ clip: <polyclip-list> ] - [ slices: INTEGER ] # in [4, 4096] - -<hyperbol> ::= hyperbol: - focals: <hyperboloid-focals> - clip: <polyclip-list> - [ slices: INTEGER ] # in [4, 4096] - -<parabol> ::= parabol: - focal: REAL # in ]0, INF) - clip: <polyclip-list> - [ slices: INTEGER ] # in [4, 4096] - -<parabolic-cylinder> ::= parabolic-cylinder: - focal: REAL # in ]0, INF) - clip: <polyclip-list> - [ slices: INTEGER ] # in [4, 4096] - -<plane> ::= plane: - clip: <polyclip-list> - [ slices: INTEGER ] # in [1, 4096]. Default is 1 - -<sphere> ::= sphere: - radius: REAL # in ]0, INF) - [ slices: INTEGER ] # in [4, 4096]. Default is 16 - [ stacks: INTEGER ] # in [2, 4096]. Default is slices/2 - -<stl> ::= stl: - path: PATH - -<hyperboloid-focals> ::= real: REAL # in ]0, INF) - image: REAL # in ]0, INF) - ----------------------------------------- - -<polyclip-list> ::= - <polyclip> - [ - <polyclip> ... ] - -<polyclip> ::= operation: <AND|SUB> - <contour-descriptor> - -<contour-descriptor> ::= <circle-descriptor> - | <vertices-descriptor> - -<vertices-descriptor> ::= vertices: <vertices-list> - -<circle-descriptor> ::= circle: - radius: REAL # in ]0, INF) - [ center: <real2> ] # Default is 0,0 - [ segments: INTEGER ] # in [3, 4096]. Default is 64 - -<vertices-list> ::= - <real2> - - <real2> - - <real2> - [ - <real2> ... ] - ----------------------------------------- - -<material> ::= material: - <material-descriptor> - | <double-sided-mtl> - -<double-sided-mtl> ::= front: <material-descriptor> - back: <material-descriptor> - -<material-descriptor> ::= <dielectric> - | <matte> - | <mirror> - | <thin-dielectric> - | <virtual> - -<dielectric> ::= dielectric: - medium_i: <medium-descriptor> - medium_t: <medium-descriptor> - [ <normal-map> ] - -<matte> ::= matte: - reflectivity: <mtl-data> # in [0, 1] - [ <normal-map> ] - -<mirror> ::= mirror: - reflectivity: <mtl-data> # in [0, 1] - slope_error: <mtl-data> - [ microfacet: <normal-distrib> ] # Default is BECKMANN - [ <normal-map> ] - -<normal-distrib> ::= BECKMANN - | PILLBOX - -<virtual> ::= virtual: EMPTY-STRING - -<thin-dielectric> ::= thin_dielectric: - thickness: REAL # in [0, INF) - medium_i: <medium-descriptor> - medium_t: <medium-descriptor> - [ <normal-map> ] - -<normal-map> ::= normal_map: - path: PATH - ----------------------------------------- - -<medium> ::= medium: <medium-descriptor> - -<medium-descriptor> ::= refractive_index: <mtl-data> # in ]0, INF) - extinction: <mtl-data> # in [0, INF) - ----------------------------------------- - -<entity> ::= entity: <entity-data> - -<template> ::= template: <entity-data> - -<entity-data> ::= name: STRING - [ <geometry-data> | <x_pivot> | <zx_pivot> ] - [ <anchors> ] - [ <transform> ] - [ <children> ] - -<geometry-data> ::= primary: INTEGER # in [0, 1] - <geometry> - -<children> ::= children: - - <entity-data> - [ - <entity-data> ... ] - -<anchors> ::= anchors: - - <anchor-data> - [ - <anchor-data> ... ] - -<anchor-data> ::= name: STRING - <position-descriptor> - -<position-descriptor> ::= position: <real3> - | hyperboloid_image_focals: <hyperboloid_focals> - -<entity-identifier> ::= <self|STRING>[.STRING ... ] - -<anchor-identifier> ::= <entity-identifier>.STRING - ----------------------------------------- - -<sun> ::= sun: - dni: REAL # Direct Normal Irradiance in ]0, INF) - [ <spectrum> ] # Default is the smarts295 spectrum - [ <sun-shape> ] - -<sun-shape> ::= <pillbox> | <gaussian> | <buie> - -<buie> ::= buie: - csr: REAL # in [1e-6, 0.849] - -<pillbox> ::= pillbox: - half_angle: REAL # in ]0, 90] - -<gaussian> ::= gaussian: - std_dev: REAL # in ]0, INF) - ----------------------------------------- - -<atmosphere> ::= atmosphere: - extinction: <mtl-data> # in [0, 1] - ----------------------------------------- - -<mtl-data> ::= REAL - | <spectrum-data-list> - -<transform> ::= transform: - translation: <real3> - rotation: <real3> - -<real2> ::= - REAL - - REAL - -<real3> ::= - REAL - - REAL - - REAL - -<spectrum> ::= spectrum: <spectrum-data-list> - -<spectrum-data-list> ::= - <spectrum-data> - [ - <spectrum-data> ... ] - -<spectrum-data> ::= wavelength: REAL # in [0, INF) - data: REAL # in [0, INF) -_______ - -SUN ---- - -The *sun* describes the source of the solar plant. Its direction is not defined -into the *solstice-input*(5) file but is provided by the *solstice*(1) command. -This allows to use the same unmodified *solstice-input*(5) file for several -simulations with different sun directions. - -The main *sun* property is its direct normal irradiance, or *dni* in W.m\^-2. -Its value is a scalar defining the direct irradiance received on a plane -perpendicular to the main sun direction. The optional *spectrum* parameter -describes the per wavelength distribution of the sun *dni*. Note that this -distribution is automatically normalized by *solstice*(1). If the *spectrum* -attribute is not defined, *solstice*(1) uses a default spectrum computed with -the SMARTS software [2] between 0.28 and 4 micro-meters. The total *dni* -(integrated over the spectral range) was set to 1000 W.m^-2. The standard -Mid-Latitude-Summer atmosphere was used with most of gases concentration set -as default (the CO2 concentration was assumed 400ppmv in the atmosphere -column). - -Even if an atmosphere is provided, the atmospheric effects from the top of the -atmosphere to ground level are not computed using the atmosphere description. -As a result, the sun description (*dni* and optional *spectrum*) is expected to -include all the atmospheric effects (sun irradiance available at ground -level). - -The *sun-shape* parameter controls the angular distribution of the sun light -intensity across the sun's disk. If not defined, the distribution is assumed to -be a dirac distribution (infinite directional source). The available sun -shapes are: - -*pillbox*:: - The *pillbox* distribution defines an uniform intensity over the sun's disk. - Its single *half_angle* parameter is the sun's disk half-angle in degrees, that - is linked to the apparent size of the sun. A typical half_angle is 0.2664. - -*gaussian*:: - The *gaussian* distribution defines a gaussian distribution of the solar - incoming direction. Its single *std_dev* parameter is the standard deviation - of the distribution in degrees. Values around 0.2 are typical. - As the gaussian distribution is not truncated, the resulting sun vector can - theoreticaly be oriented towards the sun, especially with a big, non-typical - *std_dev* value. - -*buie*:: - The *buie* distribution, as first discribed in [3]. Its single *csr* - parameter is the ratio between the circumsolar irradiance and the sum of - the circumsolar and sun's disk irradiance. An analysis on typical *csr* - values can be found in [4]. - -ATMOSPHERE ----------- - -The *atmosphere*, when provided, describes the medium surrounding the -solar plant. Its only parameter is its extinction coefficient in m^-1, that -can either be a scalar if the *extinction* is constant over the spectrum, or -can be spectrally described. The extinction along light paths is only computed -after the first reflector, as sun description must include all the atmospheric -effects before the first reflector (see sun description for more details). - -If no atmosphere is provided, atmospheric extinction after the first reflector -is not taken into account. - -MATERIAL --------- - -A *material* describes the properties of an interface. These properties can be -the same for the two sides of the interface or may be differentiated with a -*double-sided-mtl*. The material comportment is controlled by a -*material-descriptor* that specifies the physical properties of the interface -as well as its optional normal perturbation. Note that the physical properties -can be either scalars or spectral data. - -Material descriptors -~~~~~~~~~~~~~~~~~~~~ - -The available material descriptors are: - -*dielectric*:: -Interface between 2 dielectric media. Its *medium_i* parameter defines the -current medium, i.e. the medium the ray travels in, while *medium_t* -represents the opposite medium. Incoming rays are either specularly reflected -or refracted according to a Fresnel term computed with respect to the -refractive indices of the 2 media as: -+ -....... -Fr = 1/2 * (Rs^2 + Rp^2) -....... -+ -with Rs and Rp the reflectance for the light polarized with its electric -field perpendicular or parallel to the plane of incidence, respectively. -+ -....... -Rs = (n1 * |wi.N| - n2 * |wt.N|) / (n1 * |wi.N| + n2 * |wt.N|) -Rp = (n2 * |wi.N| - n1 * |wt.N|) / (n2 * |wi.N| + n1 * |wt.N|) -....... -+ -with n1 and n2 the indices of refraction of the incident and transmitted -media, and wi and wt the incident and transmitted direction. -+ -Be careful to ensure the media consistency in the *solstice-input*(5) file; a -ray travelling in a medium _A_ can only encounter a medium interface whose -*medium_i* attribute is _A_. Consequently, a *dielectric* material must be -defined as a double sided material whose front and back interfaces are -dielectrics with inverted media: -+ -....... -material: - front: - dielectric: - medium_i: &vacuum { refractive_index: 1, extinction: 0 } - medium_t: &glass { refractive_index: 1.5, extinction: 20 } - back: - dielectric: - medium_i: *glass - medium_t: *vacuum -....... -+ -If the media consistency is not ensured, *solstice*(1) will fail to run -simulations. Note that by default, the surrounding medium is assumed to be -the vacuum, i.e. its refractive index and its extinction are scalars whose -values are 1 and 0, respectively. If an atmosphere is defined, the refractive -index of the surrounding medium is still the scalar 1 but its extinction is -the one of the atmosphere. In other words, to reference the surrounding medium -in the *medium_i* or the *medium_t* attribute of a *dielectric* interface, one -has to define a medium whose refractive index is the scalar 1 and extinction -is either 0 or the extinction of the atmosphere if the latter is defined or -not, respectively. - -*matte*:: -Diffuse surface. Reflects the same intensity in all directions independently -of the incoming direction. - -*mirror*:: -Specular or glossy reflection whether the *slope_error* parameter is 0 or not, -respectively. Glossy reflections are controlled by a microfacet BRDF. The -microfacet normals are distributed with respect to the Beckmann or the Pillbox -distribution according to the *normal-distrib* attribute. -+ -Let S the *slope_error* parameter in ]0, 1]. The Beckmann distribution is -defined as: -+ -....... -D(wh) = exp(-tan^2(a) / m^2) / (PI * m^2 * cos^4(a)) -....... -+ -with a = arccos(wh.N), and m = sqrt(2)*S while the pillbox distribution is -defined as: -+ -....... - | 0; if |wh.N| >= S -D(wh) = | - | 1 / (PI * (1 - cos^2(S))); if |wh.N| < S -....... - -*thin-dielectric*:: -The interface is assumed to be a thin slab of a dielectric material. The -*medium_i* parameter defines the outside dielectric medium while *medium_t* -is the medium of the thin slab. Incoming rays are either specularly reflected -or transmitted (without deviation) according to a Fresnel term computed with -respect to the refractive indices of the 2 media as: -+ -....... -Fr = 1/2 * (Rs^2 + Rp^2) -....... -+ -with Rs and Rp the reflectance for the light polarized with its electric -field perpendicular or parallel to the plane of incidence, respectively. -+ -....... -Rs = (n1 * |wi.N| - n2 * |wt.N|) / (n1 * |wi.N| + n2 * |wt.N|) -Rp = (n2 * |wi.N| - n1 * |wt.N|) / (n2 * |wi.N| + n1 * |wt.N|) -....... -+ -with n1 and n2 the indices of refraction of the incident and transmitted -media, and wi and wt the incident and transmitted direction. Note that the -underlying scattering function correctly handles the multiple refraction -effects into the thin slab. -+ -Be careful to ensure the media consistency in the *solstice-input*(5) file; a -ray travelling in a medium _A_ can only encounter a medium interface whose -*medium_i* attribute is _A_. If the media consistency is not ensured, -*solstice*(1) will fail to run simulations. Note that by default, the -surrounding medium is assumed to be the vacuum, i.e. its refractive index and -its extinction are scalars whose values are 1 and 0, respectively. If an -atmosphere is defined, the refractive index of the surrounding medium is still -the scalar 1 but its extinction is the one of the atmosphere. In other words, -to reference the surrounding medium in the *medium_i* attribute of a -*thin-dielectric* interface, one has to define a medium whose refractive -index is the scalar 1 and extinction is either 0 or the extinction of the -atmosphere if the latter is defined. - -*virtual*:: -Fully transparent interface. - -Normal map -~~~~~~~~~~ - -All the material descriptors, excepted the *virtual*, provide an optional -*normal-map* attribute that defines a path toward a Portable PixMap image [5] -whose pixels store a normal expressed in the tangent space of the interface. By -default the unperturbed tangent space normal is {0,0,1}. The PPM image can -be encoded on 8 or 16-bits per component either in ASCII or binary. The -parameterization of this 2D image onto the shape surfaces depends on the type -of the shape. For the *hemisphere*, *hyperbol*, *parabol*, *plane* and -*parabolic-cylinder* shapes, the image is mapped in the {X,Y} plane. The other -shapes are not parameterized and consequently, applying a normal-mapped -material on these shapes leads to undefined behaviors. - -SHAPE ------ - -A *shape* describes a geometric model. It is defined in its local space, i.e. -in a coordinate system whose origin is proper to the shape. No space -transformation can be introduced through the declaration of a shape: it should -be transformed externally through an *object* and/or *entities*. -*solstice-input*(1) provides 2 types of shape: quadric and mesh. The former is -used to declare parametric surfaces, while the latter describes triangulated -surfaces. - -Quadric -~~~~~~~ - -A quadric shape is defined from a quadric equation and a set of 2D clipping -operations performed in their {X,Y} plane. By convention, the front side of the -quadric surface looks toward the positive Z axis. Internally, the clipped -quadric surface is discretized in a triangular mesh with respect to the -discretisation parameters of the quadric. This mesh is used by *solstice*(1) -as a "proxy" to speed up the access toward the quadric shape: the quadric -position and its associated normal are in fine computed from the quadric -equation. - -The quadric surface is parameterized in the {X,Y} plane. Its parameterization -domain is defined from the bounds of its clipped mesh in the {X,Y} plane: - - u = (x - lowerX) / (upperX-lowerX) - v = (y - lowerY) / (upperY-lowerY) - -with *u* and *v* the mapped 2D coordinates from a 3D position {*x*,*y*,*z*} -onto the quadric, and *lower*<**X**|**Y**> and *upper*<**X**|**Y**> the lower -and upper bounds of the clipped quadric along the X and Y axis. The available -quadrics are: - -*hemisphere*:: -Hemispheric shape defined along the Z axis whose minimum is positioned at -the origin. The *slices* parameter controls the number of divisions along -the Z axis. -+ -....... -x^2 + y^2 + (z-radius)^2 = radius^2 -....... - -*hyperbol*:: -Hyperbolic quadric defined along the Z axis whose minimum is positioned at -the origin. The *slices* parameter controls the discretisation of the -hyperbol. If not defined, it is automatically computed with respect to the -hyperbol curvature. -+ -....... -(x^2 + y^2) / a^2 - (z + z0 - g/2)^2 / b^2 + 1 = 0 - -a^2 = g^2(f - f^2) -b = g(f - 1/2) -z0 = |b| + g/2 -g = focals.real + focals.image -f = focals.real / g -....... - -*parabol*:: -Parabolic quadric defined along the Z axis whose minimum is positioned at the -origin. The *slices* parameter controls the discretisation of the parabol. If -not defined, it is automatically computed with respect to the parabol -curvature. -+ -....... -x^2 + y^2 - 4 * focal * z = 0 -....... - -*parabolic-cylinder*:: -Parabolic cylinder oriented along the Z axis whose main axis is along the X -axis and minimum is positioned at the origin. The *slices* parameter -controls the discretisation of the parabolic cylinder. If not defined, it is -automatically computed with respect to the parabolic cylinder curvature. -+ -....... -y^2 - 4 * focal * z = 0 -....... - -*plane*:: -Plane whose normal points along the positive Z axis. The *slices* attribute -controls the discretisation of the clipped plane. - -Clipping -~~~~~~~~ - -A clipping operation, or *polyclip*, is used to remove some parts of the -quadric surface. It is defined by a 2D *contour-descriptor* expressed in the -{X,Y} plane and a clipping *operation*. The *AND* and *SUB* clip operands, -remove the quadric surface that intersects or does not intersect the -*contour-descriptor*, respectively. The available *countour-descriptors* are: - -*circle-descriptor*:: -Circular contour whose size is defined by the *radius* parameter. Actually, -*solstice*(1) discretized the circular contour with respect to the *segments* -attribute that defines the overall number of segments used to approximate the -circle. - -*vertices-descriptor*:: -Polygonal contour described by a list of 2D vertices. The polygon edges are -defined by connecting each vertex to its previous one. To ensure that the -polygon is closed, an additional edge is automatically created between the -first and the last vertex. Note that *solstice*(1) assumes that the defined -polygon does not overlap itself, i.e. their non consecutive edges are not -intersecting. - -The *clip* parameter of the quadrics lists a set of the aforementioned 2D -*polyclips*. Each of these clipping operations is successively applied on the -remaining quadric surface, in the order on which they are declared. For -instance, the following example uses 5 clipping operations on a plane to build -a rectangle with a circular hole at each of its corner. The first *polyclip* -limits the infinite plane to a rectangle centered in 0 whose size in X and Y is -8 and 4, respectively. The 4 subsequent *polyclips* drill the -rectangle near of its corner with circles whose radius is 0.5: - -....... -plane: - clip: - - {operation: AND, vertices: [[-4,-2],[-4,2],[4,2],[4,-2]]} - - {operation: SUB, circle: {radius: 0.5, center: [-3,-1]}} - - {operation: SUB, circle: {radius: 0.5, center: [-3, 1]}} - - {operation: SUB, circle: {radius: 0.5, center: [ 3,-1]}} - - {operation: SUB, circle: {radius: 0.5, center: [ 3, 1]}} -....... - -Triangular mesh -~~~~~~~~~~~~~~~ - -Triangular meshes are generated by *solstice*(1) from a shape description or -loaded from a CAO file. Their normals are defined per triangle and are thus -discontinuous even for smooth shapes as spheres. The triangular meshes are not -parameterized, i.e. they do not provide a mapping from a 3D position onto its -surface to a 2D coordinates. Applying a normal-mapped material to a triangular -mesh will thus produce undefined behaviors. - -The available triangular meshes are: - -*cuboid*:: - Axis aligned cuboid centered in 0 whose corner positions and dimensions along - the 3 axis are defined by the *size* parameter. The front side of the cuboid - surface looks outside the cuboid. - -*cylinder*:: - Cylinder centered in 0 whose *height* is along the positive Z axis. The top - and the bottom of the cylinder is capped. The *stacks* and *slices* - parameters control the discretisation, i.e. the number of divisions, along or - around the Z axis, respectively. The front side of the cylinder surface looks - outside the cylinder. - -*sphere*:: - Triangulated sphere centered in 0. The *stacks* and *slices* parameters - control the discretisation, i.e. the number of divisions, along or around the - Z axis, respectively. The front side of the sphere surface looks outside the - sphere. - -*stl*:: - Path toward an external mesh file defined with respect to the ASCII - **ST**ereo **L**ithography file format. The front side of the loaded - triangles is defined with respect to their vertex ordering into the STL - file: a triangle is front facing when their vertices are clock wise ordered. - -ENTITY ------- - -An *entity* is used to declare and position shapes into the solar plant. -Actually, the entity is the only item that effectively spawns a *geometry* into -the solar plant: if a geometry is declared but not referenced by an entity, it -is ignored by *solstice*(1). An entity is a hierarchical data structure that -can have child entities whose transformation is relative to their parent. If -not defined, the *transform* parameter of an entity is assumed to be the -identity, i.e. its *rotation* and *translation* are nulls. - -Each entity has a *name* which must be unique per hierarchy level: 2 root -entities (i.e. entities without parent) cannot have the same name as well as -the children of a same parent entity. In addition, the name string cannot -contain dots, spaces or tabulations. A child entity is identified into the -solar plant by successively concatenating, with the \'.' character, the name -of its ancestors with its own name. This naming convention is used in the -*solstice-receiver*(5) format to define the entities to track during the -*solstice*(1) computations. For instance, in the following example, the -*entity-identifier* of the child entity named *level2* is -*level0.level1.level2*: -....... -entity: - name: level0 - child: - - name: level1 - child: - - name: level2 -....... - -An entity encapsulates either a *geometry* or a *pivot*. The former is a -collection of *objects*, i.e. *shapes* with their associated *material* and an -optional *transformation*. The latter is used to control the dynamic -positioning of the child entities with respect to some constraints defined by -the pivot type, and the sun directions submitted by *solstice*(1). Each entity -can also have a list of *anchors*. An anchor is used to define a position -relative to the entity into which it is declared. - -For a geometric entity one has to define if the encapsulated geometry is a -*primary* geometry, i.e. a geometry directly lit by the sun and used to -concentrate the solar flux (e.g. a primary mirror). One can define all the -solar plant geometric entities as primaries but a well designed solar plant -with correctly tagged primary geometries will drastically improve the -convergence speed of the *solstice*(1) simulations. - -Template -~~~~~~~~ - -A *template* is a first level entity with no existence into the solar plant. It -is used to pre-declare an entity hierarchy that can then be instantiated -several times in the solar plant by referencing it through common entities with -YAML data tagging. In the following example, the templated entity *my-template* -is instantiated 3 times into the scene: -....... -- template: &my-template - name: bar - primary: 1 - geometry: ... -- entity: - name: foo0 - transform: {translation: [-10.5, 0, 0]} - children: [*my-template] -- entity: - name: foo1 - transform: {translation: [0, 0, 0]} - children: [*my-template] -- entity: - name: foo2 - transform: {translation: [10.5, 0, 0]} - children: [*my-template] -....... - -Pivot -~~~~~ - -A *pivot* is a special kind of node that can be used in the tree data -structure describing an entity to automatically point its child geometry -according to the sun position and to the pivot parameters. It is supposed (but -not mandatory) that the children of a pivot includes a reflector, that, -once pivoted, will reflect the sun light towards a *target*. You should -note that a pivot cannot be the child of another pivot. - -The most noticeable pivot parameter is its *target*. Four different types of -targets are available: - -*position*:: - Define the target as being an absolute point in world coordinates. - -*anchor*:: - Define the target as being a position relative to an entity (see the - *anchor* section). - -*sun*:: - Define the target as being the center of the sun. - -*direction*:: - The pivot reflects light in the given direction, specified in world - coordinates. - -Pivots can also have a *ref_point* optional parameter defining a 3D point in -the coordinate system the pivot children that will be used by the pointing algorithm. -If not provided, it is set to the origin. - -Two different flavours of *pivots* are available: *x_pivot* and *zx_pivot*, -each with its own set of parameters and behaviour. - -*x_pivot*:: - Pivot with a single rotation axis: the +X axis in its local coordinate - system. It has a *target* and can have a *ref_point*. Its pointing algorithm - considers an incoming ray of light from the center of the sun and rotates - its children so that a specular reflection at *ref_point* using +Z as - local normal will hit the target point of the pivot, or will have the - specified direction (depending of the kind of target). - -*zx_pivot*:: - Pivot with two rotation axis: the +Z axis in its local coordinate system, - then the +X axis in the coordinate system resulting of the Z rotation. - It has a *target* and can have a *ref_point* and a *spacing* that defines - the translation along the +Y axis after the first rotation. If not - defined, *spacing* is 0. The *zx_pivot* pointing algorithm considers an - incoming ray of light from the center of the sun and rotates its - children so that a specular reflection at *ref_point* using - +Y as local normal will hit the target point of the pivot, or will have - the specified direction (depending of the kind of target). - -Anchor -~~~~~~ - -An *anchor* defines a relative position into the entity hierarchy. They are -particularly useful for pivots and hyperbolic shapes that may have to -reference a position relative to an entity whose transformations may also -depends of its ancestor. An anchor has a *name* that must be unique for the -whole sets of per entity anchors. In addition, a name cannot contain -dots, spaces or tabulations. An anchor is identified into the solar plant by -concatenating, with the \'.' character, its name to the *entity-identifier* of -the entity into which it is declared. For instance, in the following example, -the *anchor-identifier* of the anchor named *anchor0* is -*level0.level1.anchor0*: -....... -entity: - name: level0 - child: - - name: level1 - anchor: - - {name: anchor0, position: [0, 0, 0]} - - {name: anchor1, position: [1, 2, 3]} -....... - -In some situations, the *anchor-identifier* cannot be fully determined. Let a -templated entity with a descendant referencing an anchor of one of its -ancestors. On its declaration, the template is still not instantiated through a -parent entity and consequently the name of the root entity is unknown. -Moreover, the name of the root entity cannot be fixed since it changes for each -instance of the template. To handle these cases, the *self* reserved keyword -allows to reference the unknown root entity of the currently declared -hierarchy. In the following example, the entities *entity0.level0.level1* and -*entity1.level0.level1* encapsulate a pivot that references the anchor -*anchor0* defined in their respective parent *entity0.level0* and -*entity1.level0*: -....... -- template: &my-template - name: level0 - anchor: [{name: anchor0, position: [1, 2, 3]}] - child: - - name: level1 - pivot: - x_pivot: - ref_point: {0, 0, 0} - target: {anchor: self.level0.anchor0} - -- entity: {name: entity0, child: [*my-template]} -- entity: {name: entity1, child: [*my-template]} -....... - -Transform -~~~~~~~~~ - -A *transform* is used to move an *object* or an *entity* in space. The -*rotation* parameter list 3 angles in degrees defining the rotation to perform -around the X, Y and Z axis. The *translation* attribute describes the offsets -to apply along the X, Y and Z axis. Let the local repair *p* of an object, *p* -is transformed in *p'* with respect to its associated *transform* as follow: - - p' = Rx * Ry * Rz * (T + p) - -with *T* the translation vector and *Rx*, *Ry* and *Rz* the rotation matrices -around the X, Y and Z axis defined as: - - | 1 0 0 | | cY 0 sY | | cZ -sZ 0 | - Rx = | 0 cX -sX |; Ry = | 0 1 0 |; Rz = | sZ cZ 0 | - | 0 sX cX | |-sY 0 cY | | 0 0 1 | - -where *c*<**X**|**Y**|**Z**> and *s*<**X**|**Y**|**Z**> are the cosine and the -sinus, respectively, of the rotation angles around the X, Y and Z axis. - -EXAMPLES --------- - -Declare 2 entities and a point source sun. The first entity is a purely -specular square of size 10, whose center is at the origin. The second entity -is a purely transparent square used as a receiver of the solar flux. Its size -is 1 and its center is positioned at {0,0,2}: -....... -- sun: {dni: 1000} - -- entity: - name: reflector - primary: 1 - geometry: - - material: - mirror: - reflectivity: 1 - slope_error: 0 - plane: - clip: - - operation: AND - vertices: - - [-5.0,-5.0] - - [-5.0, 5.0] - - [ 5.0, 5.0] - - [ 5.0,-5.0] - -- entity: - name: receiver - primary: 0 - transform: - translation: [0, 0, 2] - geometry: - - material: - virtual: # No attrib - plane: - clip: - - operation: AND - vertices: - - [-0.5,-0.5] - - [-0.5, 0.5] - - [ 0.5, 0.5] - - [ 0.5,-0.5] -....... - -Define a circular diffuse reflector surrounded by a virtual sphere and a -pillbox-shaped sun whose *half_angle* is 0.1 degree. Use anchors and tags of the -YAML format to reference into the entities a pre-declared geometry. Rely on -the YAML compact notation to reduce the number of lines required to describe -the scene: -....... -- sun: {dni: 1000, pillbox: {half_angle: 0.1}} - -- geometry: &small-circle - - material: {matte: {reflectivity: 1}} - plane: {clip: [{operation: AND, circle: {radius: 0.5}}]} - -- geometry: &big-sphere - - material: {?virtual} - sphere: {radius: 2, slices: 128} - -- entity: {name: reflector, primary: 1, geometry: *small-circle} -- entity: {name: receiver, primary: 0, geometry: *big-sphere} -....... - -Declare 2 parabolic reflectors from a *templated* parabola whose orientation is -controlled by a *zx_pivot*. This pivot ensures that the reflector points toward -the receiver, independently of its position, by targeting an *anchor* whose -position is defined relatively to the receiver: -....... -- sun: {dni: 1000} - -- entity: # Receiver - name: square_receiver - primary: 0 - transform: { rotation: [0,90,0], translation: [100,0,10] } - anchors: [{name: anchor0, position: [0,0,0]}] - geometry: - - material: {?virtual} - plane: - clip: - - operation: AND - vertices: [[-.5,-.5],[-.5,.5],[.5,.5],[.5,-.5]] - -- template: &self_oriented_parabol # Reflector - name: pivot - transform: {translation: [0, 0, 4], rotation: [0, 0, 90]} - zx_pivot: {target: {anchor: square_receiver.anchor0}} - children: - - name: parabol - transform: {rotation: [-90, 0, 0]} - primary: 1 - geometry: - - material: {mirror: {reflectivity: 1, slope_error: 0}} - parabol: - focal: 100 - clip: - - operation: AND - vertices: [[-5,-5],[-5,5],[5,5],[5,-5]] - -# Instantiate the reflector template -- entity: - name: reflector1 - transform: {translation: [0,0,0]} - children: [*self_oriented_parabol] -- entity: - name: reflector2 - transform: {translation: [10,43.6,0]} - children: [*self_oriented_parabol] -....... - -Declare a solar furnace with 9 heliostats instantiated from the same -*template*. Their position is controlled by a *zx_pivot* to ensure that the -incoming sun rays are reflected toward the negative X axis. Reflected rays are -then concentrated by a parabola toward a purely absorptive receiver. The -heliostats and the parabola share the same material: the front faces are -purely specular while the back faces are diffuse: -....... -- sun: {dni: 1000} - -- material: &specular - front: {mirror: {reflectivity: 1, slope_error: 0}} - back: {matte: {reflectivity: 1}} - -- template: &H # Template of an heliostat - name: heliostat - transform: {translation: [0,0,5.5]} - zx_pivot: {target: {direction: [-1,0,0]}} - children: - - name: reflector - transform: {rotation: [-90,0,0]} - primary: 1 - geometry: - - material: *specular - plane: - clip: [{operation: AND, vertices: [[-5,-5],[-5,5],[5,5],[5,-5]]}] - -- entity: # Receiver entity - name: receiver - primary: 0 - transform: {translation: [18,0,20], rotation: [0,90,0]} - geometry: - - material: {matte: {reflectivity: 0}} - plane: - clip: - - operation: AND - vertices: [[-.5,-.5],[-.5,.5],[.5,.5],[.5,-.5]] - -- entity: # Great parabola - name: parabola - primary: 0 - transform: {translation: [0,0,20], rotation: [0,90,90]} - geometry: - - material: *specular - parabol: - focal: 18 - clip: [{operation: AND, vertices: [[-30,-20],[-30,20],[30,20],[30,-20]]}] - -# Instantiate the heliostat template -- entity: {name: H1, children: [*H], transform: {translation: [40,-20, 0]}} -- entity: {name: H2, children: [*H], transform: {translation: [40, 0, 0]}} -- entity: {name: H3, children: [*H], transform: {translation: [40, 20, 0]}} -- entity: {name: H4, children: [*H], transform: {translation: [60,-20,10]}} -- entity: {name: H5, children: [*H], transform: {translation: [60, 0,10]}} -- entity: {name: H6, children: [*H], transform: {translation: [60, 20,10]}} -- entity: {name: H7, children: [*H], transform: {translation: [80,-20,20]}} -- entity: {name: H8, children: [*H], transform: {translation: [80, 0, 20]}} -- entity: {name: H9, children: [*H], transform: {translation: [80, 20,20]}} -....... - -This example illustrates the use of quadrics and refractive materials: in this -example, three partial *parabols* with various focal distances and positions -concentrate incoming radiation at a common focal position. But a *hyperbol* is -located between the parabols and their common focal position, which is also -one of the two focals of the hyperbol. Radiation is therefore redirected to -the second focal of the hyperbol, where the square target is located. Finally, -a *cuboid* using a glass material is located between the hyperbol and the -target. In this example, a small fraction of incoming power is absorbed by the -target. The rest is either missing the target, absorbed or refracted by the -glass. Furthermore, this example illustrates the use of a *spectrum* for -*refractive index* and *extinction* by various *media* (air and glass). -....... -# Spectra -- spectrum: &solar_spectrum - - {wavelength: 0.3, data: 1.0} - - {wavelength: 0.4, data: 2.0} - - {wavelength: 0.5, data: 0.5} - - {wavelength: 0.6, data: 3.5} - - {wavelength: 0.7, data: 1.5} - - {wavelength: 0.8, data: 0.8} - -- spectrum: &air_kabs - - {wavelength: 0.3, data: 1.0e-4} - - {wavelength: 0.4, data: 1.0e-5} - - {wavelength: 0.5, data: 2.0e-5} - - {wavelength: 0.6, data: 2.0e-4} - - {wavelength: 0.7, data: 3.0e-5} - - {wavelength: 0.8, data: 1.0e-4} - -- spectrum: &glass_kabs - - {wavelength: 0.3, data: 1.0e-2} - - {wavelength: 0.4, data: 1.0e-3} - - {wavelength: 0.5, data: 2.0e-3} - - {wavelength: 0.6, data: 2.0e-2} - - {wavelength: 0.7, data: 3.0e-3} - - {wavelength: 0.8, data: 1.0e-3} - -- spectrum: &glass_ref_index - - {wavelength: 0.30, data: 1.40} - - {wavelength: 0.40, data: 1.39} - - {wavelength: 0.50, data: 1.37} - - {wavelength: 0.60, data: 1.34} - - {wavelength: 0.70, data: 1.30} - - {wavelength: 0.80, data: 1.25} - -# Media -- medium: &air_medium - refractive_index: 1 - extinction: *air_kabs - -- medium: &glass_medium - refractive_index: *glass_ref_index - extinction: *glass_kabs - -# Sun & atmosphere -- sun: {dni: 1, spectrum: *solar_spectrum} -- atmosphere: {extinction: *air_kabs} - -# Materials -- material: &specular {mirror: {reflectivity: 1, slope_error: 0}} -- material: &black {matte: {reflectivity: 0}} -- material: &glass - front: {dielectric: {medium_i: *air_medium, medium_t: *glass_medium}} - back: {dielectric: {medium_i: *glass_medium, medium_t: *air_medium}} - -# Primary reflectors -- entity: - name: "primary_reflector1" - primary: 1 - transform: {translation: [0, 0, -2.0]} - geometry: - - material: *specular - parabol: - focal: 12 - clip: - - {operation: AND, circle: {radius: 10}} - - {operation: SUB, circle: {radius: 5}} - -- entity: - name: "primary_reflector2" - primary: 1 - transform: {translation: [0, 0, -4]} - geometry: - - material: *specular - parabol: - focal: 14 - clip: - - {operation: AND, circle: {radius: 15}} - - {operation: SUB, circle: {radius: 10}} - -- entity: - name: "primary_reflector3" - primary: 1 - transform: {translation: [0, 0, -6]} - geometry: - - material: *specular - parabol: - focal: 16 - clip: - - {operation: AND, circle: {radius: 20}} - - {operation: SUB, circle: {radius: 15}} - -# Secondary reflector -- entity: - name: "secondary_reflector" - primary: 0 - transform: {translation: [0, 0, 6]} - geometry: - - material: *specular - hyperbol: - focals: {real: 16.0, image: 4} - clip: [{operation: AND, circle: {radius: 5}}] - -# Glass box -- entity: - name: "glass_slide" - primary: 0 # The entity is not sampled as a primary reflector - geometry: - - material: *glass - cuboid: {size: [10,10,0.5]} - transform: {translation: [0, 0, 0.25]} - -# Receiver -- entity: - name: "square_receiver" - primary: 0 # The entity is not sampled as a primary reflector - transform: {translation: [0, 0, -10] } - geometry: - - material: *black - plane: - clip: - - operation: AND - vertices: [[-0.5,-0.5],[-0.5,0.5],[0.5,0.5],[0.5,-0.5]] -....... - - -NOTES ------ -1. YAML Ain't Markup Language - <http://yaml.org> -2. SMARTS, Simple Model of the Atmospheric Radiative Transfer of Sunshine - - <http://www.nrel.gov/rredc/smarts/> -3. D. Buie, A.G. Monger, C.J. Dey. "Sunshape distributions for - terrestrial solar simulations". Solar Energy, 2003, 74, pp. 113-122. -4. D. Buie, C.J. Dey, S. Bosi. "The effective size of the solar cone for - solar concentrating systems". Solar Energy, 2003, 74, pp. 417-427. -5. Portable PixMap - <http://netpbm.sourceforge.net/doc/ppm.html> - -SEE ALSO --------- -*solstice*(1), *solstice-receiver*(5) diff --git a/doc/solstice-man.css b/doc/solstice-man.css @@ -1,96 +0,0 @@ -/* Copyright (C) 2016-2018 CNRS - * - * This is free style sheet: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This CSS is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see http://www.gnu.org/licenses/. */ - -body.manpage { - font-family:"Liberation Sans",sans-serif; - font-size:10pt; - text-align: justify; - max-width: 55em; - margin: 1em; - background: #ffffff -} - -body.manpage .monospaced, .literalblock { - margin: 2em; - color: #636261 -} - -body.manpage em { - color: #660000 -} - -body.manpage div.verseblock > pre.content { - font-family: "Liberation Mono",monospace; -} - -body.manpage h1 { - padding-bottom: 0.5em; -} -body.manpage h2 { - border-style: none; -} -body.manpage div.sectionbody { - margin-left: 3em; -} - -body.manpage code { - font-family: "Liberation Mono",monospace; -} - -body.manpage #footer { display: none; } - -body.manpage div#toctitle { display: none; } - -body.manpage div#toc { - display: block; - position:fixed; - top:0; - left:60em; - height:100%; - width: 100%; - padding:3em 0 0 0; - border-left:1px solid #dbdbdb; - background: #eeeeee -} - -body.manpage a { - font-weight: bold; - color: #225588; -} - -body.manpage div#toc a, div#toc a:link, div#toc a:visited { - margin:0; - padding-left: 2em; - color:#999999; - text-decoration:none; - font-weight: normal; -} - -body.manpage div.toclevel1 { - line-height: 1.5em; -} - -body.manpage div.toclevel2 { - margin-left: 2em; -} - -body.manpage div#toc a:hover { - color:#666666; -} - -@media print { - body.manpage div#toc { display: none; } -} - diff --git a/doc/solstice-output.5 b/doc/solstice-output.5 @@ -0,0 +1,666 @@ +.\" SPDX-License-Identifier: GPL-3.0-or-later +.\" Copyright (C) 2016-2018 CNRS, 2018-2019 |Méso|Star> +.\" +.\" This is free documentation: you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation, either version 3 of the License, or +.\" (at your option) any later version. +.\" +.\" This manual is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program. If not, see <http://www.gnu.org/licenses/>. +.Dd $Mdocdate$ +.Dt SOLSTICE-OUTPUT 5 +.Os +.Sh NAME +.Nm solstice-output +.Nd output format of solstice +.Sh DESCRIPTION +The +.Nm +format describes the output produced by the +.Xr solstice 1 +program. +All data generated by a +.Xr solstice 1 +invocation are written to a single file or to standard output, depending +on whether an +.Ar output +file is specified through the +.Fl o +option or not. +Submitting several sun directions to +.Xr solstice 1 +through the +.Fl D +option produces as many outputs as sun directions: invoking +.Xr solstice 1 +with N sun directions is equivalent to calling it N times and +concatenating the associated outputs. +.Pp +The type of data generated depends on the mode in which +.Xr solstice 1 +is invoked. +By default, +.Xr solstice 1 +evaluates the power collected by the submitted solar plant. +When invoked with the +.Fl g +option, it converts the solar plant geometries into a list of CAO files. +The +.Fl p +option tracks the sampled radiative paths, and the +.Fl r +option renders an image of the solar facility. +.Sh GRAMMAR +Output values are mainly ASCII data formatted line by line. +By convention, line data in the following grammar are listed between +quote marks. +The grammar may span multiple lines for formatting purposes, but data +are on a single line until a closing quote mark. +.Bd -literal +<o> ::= <simulation-output> + | <dump-geometry-output> # -g option + | <dump-radiative-paths-output> # -p option + | <rendering-output> # -r option + +<simulation-output> + ::= <sun-direction> + <counts> + <global> + [ <receivers-list> ] + [ <primaries-list> ] + [ <rcvXprims-list> ] + [ <receiver-maps> ] + [ <simulation-output> ... ] + +<dump-geometry-output> + ::= <sun-direction> + <geometry-data> + [ <dump-geometry-output> ... ] + +<dump-radiative-paths-output> + ::= <sun-direction> + VTK-RADIATIVE-PATHS + [ <dump-radiative-paths-output> ... ] + +<rendering-output> + ::= <sun-direction> + PPM-FILE # ASCII PPM with 8-bits per component [1] + [ <rendering-output> ... ] +.Ed +.Bd -literal +<sun-direction> ::= "#--- Sun direction: <alpha> <beta> (<sun-vector>)" + +<counts> ::= "<#globals> <#receivers> <#primaries> + <#samples> <#failed>" + +<#globals> ::= 7 +<#receivers> ::= INTEGER # in [0, INF) +<#primaries> ::= INTEGER # in [0, INF) +<#samples> ::= INTEGER # in [0, INF) +<#failed> ::= INTEGER # in [0, INF) + +<global> ::= <potential-flux> + <absorbed-flux> + <cos-factor> + <shadow-loss> + <missing-loss> + <materials-loss> + <atmospheric-loss> +.Ed +.Bd -literal +<receivers-list> ::= <receiver> + [ <receiver> ... ] + +<receiver> ::= "<receiver-name> <receiver-id> <area> + <front> <back>" + +<receiver-name> ::= <entity-identifier> +<receiver-id> ::= INTEGER + +<front> ::= <side> +<back> ::= <side> + +<side> ::= "<incoming-flux> <in-if-no-mat-loss> + <in-if-no-atm-loss> <in-mat-loss> <in-atm-loss> + <absorbed-flux> <abs-if-no-mat-loss> + <abs-if-no-atm-loss> <abs-mat-loss> <abs-atm-loss> + <efficiency>" +.Ed +.Bd -literal +<primaries-list> ::= <primary> + [ <primary> ... ] + +<primary> ::= "<primary-name> <primary-id> <area> <#samples> + <cos-factor> <shadow-loss>" + +<primary-name> ::= <entity-identifier> +<primary-id> ::= INTEGER +.Ed +.Bd -literal +<rcvXprims-list> ::= <rcvXprim> + [ <rcvXprim> ... ] + +<rcvXprim> ::= "<receiver-id> <primary-id> + <rcvXprim-front> <rcvXprim-back>" + +<rcvXprim-front> ::= <rcvXprim-side> +<rcvXprim-back> ::= <rcvXprim-side> + +<rcvXprim-side> ::= "<incoming-flux> <in-if-no-mat-loss> + <in-if-no-atm-loss> <in-mat-loss> <in-atm-loss> + <absorbed-flux> <abs-if-no-mat-loss> + <abs-if-no-atm-loss> <abs-mat-loss> <abs-atm-loss>" +.Ed +.Bd -literal +<receiver-maps> ::= VTK-RECEIVER-MAP + [ <receiver-maps> ... ] + +<geometry-data> ::= OBJ-FILE + [ --- + <geometry-data> ... ] +.Ed +.Bd -literal +<area> ::= REAL # in ]0, INF) +<real3> ::= REAL REAL REAL + +<alpha> ::= REAL # Degrees in [0, 360[ +<beta> ::= REAL # Degrees in [0, 90] +<sun-vector> ::= <real3> + +<incoming-flux> ::= <estimate> +<in-if-no-mat-loss> ::= <estimate> +<in-if-no-atm-loss> ::= <estimate> +<in-mat-loss> ::= <estimate> +<in-atm-loss> ::= <estimate> +<absorbed-flux> ::= <estimate> +<abs-if-no-mat-loss> ::= <estimate> +<abs-if-no-atm-loss> ::= <estimate> +<abs-mat-loss> ::= <estimate> +<abs-atm-loss> ::= <estimate> +<cos-factor> ::= <estimate> +<missing-loss> ::= <estimate> +<materials-loss> ::= <estimate> +<atmospheric-loss> ::= <estimate> +<shadow-loss> ::= <estimate> +<efficiency> ::= <estimate> + +<estimate> ::= <expected-value> <standard-error> +<expected-value> ::= REAL +<standard-error> ::= REAL # in [0, INF) + +<entity-identifier> # Defined in solstice-input(5) +.Ed +.Sh SIMULATION +A +.Em simulation-output +begins with two header lines. +The first reports the sun direction used in the simulation (two angles +in degrees, plus the corresponding sun vector). +The second lists the numbers of global, per-receiver and per-primary +results, as well as the overall number of Monte-Carlo experiments and +the number of experiments that failed due to unforeseen errors such as +numerical imprecisions. +As soon as the number of failed experiments reaches 1% of the required +number of Monte-Carlo experiments, the code exits with an +.Qq Error in integrating the solar flux +message, and the validity of subsequent results is questionable: +estimates are produced using the number of successful experiments, which +is necessarily smaller than the required number. +.Ss Global results +After the two header lines, the output includes various +.Em global +result lines; the exact number is given in the header (currently 7). +Each global result is a pair of real numbers: the expected value and its +standard error. +The global results are, in order: +.Bl -tag -width Ds +.It Em potential-flux +Maximum flux that all primary geometries could intercept if properly +oriented and flat-shaped. +.It Em absorbed-flux +Absorbed part of the flux reaching any receiver geometry. +At most equal to the potential flux. +.It Em cos-factor +Cosine of the angle between the sun direction and the normal of the +primary surfaces (average over all primary geometries). +.It Em shadow-loss +Potential flux intercepted by another geometry before reaching a primary +geometry. +.It Em missing-loss +Part of the flux that reaches a primary geometry and follows a radiative +path but is not absorbed; this flux may have bounced on geometries, +including receivers, without being absorbed. +.It Em materials-loss +Total flux absorbed by non-receivers along radiative paths; includes +both surface and volume absorption. +.It Em atmospheric-loss +Total flux extinction by the atmosphere along radiative paths. +.El +.Pp +These results can be used to check conservation of energy: +.Em potential-flux No * Em cos-factor +and +.Pq Em absorbed-flux No + Em shadow-loss No + Em missing-loss No + Em materials-loss No + Em atmospheric-loss +should be equal within their respective uncertainty ranges. +.Ss Per receiver results +Following the global results, the output includes one line per receiver, +sorted according to the order of the receivers as defined in the +submitted +.Xr solstice-receiver 5 +file. +Each line contains: +.Bl -tag -width Ds +.It Em receiver-name +Name of the receiver, i.e.\& the +.Em entity-identifier +of the entity in which the receiving geometry is defined (see +.Xr solstice-input 5 ) . +.It Em receiver-id +Unique integer identifying the receiver. +.It Em area +Area of the receiver. +.It Em front +Estimated results for the front side of the receiver. +.It Em back +Estimated results for the back side of the receiver. +.El +.Pp +The estimates for the +.Em front +and +.Em back +sides are as follows (each is a pair: expected value and standard +error): +.Bl -tag -width Ds +.It Em incoming-flux +Flux that reaches the receiver side. +.It Em in-if-no-mat-loss +Incoming flux if absorption on non-receivers is not taken into account. +.It Em in-if-no-atm-loss +Incoming flux if atmospheric extinction is not taken into account. +.It Em in-mat-loss +.Em in-if-no-mat-loss No \- Em incoming-flux . +.It Em in-atm-loss +.Em in-if-no-atm-loss No \- Em incoming-flux . +.It Em absorbed-flux +Flux absorbed by the receiver side. +.It Em abs-if-no-mat-loss +Absorbed flux if absorption by non-receivers is not taken into account. +.It Em abs-if-no-atm-loss +Absorbed flux if atmospheric extinction is not taken into account. +.It Em abs-mat-loss +.Em abs-if-no-mat-loss No \- Em absorbed-flux . +.It Em abs-atm-loss +.Em abs-if-no-atm-loss No \- Em absorbed-flux . +.It Em efficiency +Fraction of the potential flux absorbed by this receiver side. +.El +.Pp +Both +.Em front +and +.Em back +side estimates are always output, even if the receiver has only a single +receiving side. +In that case, the results of the non-receiving side are meaningless +(invalid \-1 value). +.Ss Per primary results +Following the per-receiver results, the output includes one line per +primary geometry. +Each line contains: +.Bl -tag -width Ds +.It Em primary-name +Name of the primary geometry, i.e.\& the +.Em entity-identifier +of the entity in which the primary geometry is defined (see +.Xr solstice-input 5 ) . +.It Em primary-id +Unique integer identifying the primary geometry. +.It Em area +Area of the primary geometry. +.It Em #samples +Number of Monte-Carlo experiments sampled on the primary geometry. +.It Em cos-factor +Cosine of the angle between the sun direction and the normal of the +primary surface (average over the primary geometry). +.It Em shadow-loss +Potential flux intercepted by another geometry before reaching this +primary geometry. +.El +.Ss Per receiver and per primary results +Following the per-primary results, the output includes result lines +describing the contribution of each primary geometry to each receiver. +The total number of such lines is the number of receivers times the +number of primary geometries. +Each line contains: +.Bl -tag -width Ds +.It Em receiver-id +Identifier of the involved receiver. +.It Em primary-id +Identifier of the involved primary geometry. +.It Em rcvXprim-front +Estimated results for the receiver front side. +.It Em rcvXprim-back +Estimated results for the receiver back side. +.El +.Pp +The estimated values of +.Em rcvXprim-front +and +.Em rcvXprim-back +are as follows (each is a pair: expected value and standard error): +.Bl -tag -width Ds +.It Em incoming-flux +Flux that reaches the receiver side. +.It Em in-if-no-mat-loss +Incoming flux if absorption on non-receivers is not taken into account. +.It Em in-if-no-atm-loss +Incoming flux if atmospheric extinction is not taken into account. +.It Em in-mat-loss +.Em in-if-no-mat-loss No \- Em incoming-flux . +.It Em in-atm-loss +.Em in-if-no-atm-loss No \- Em incoming-flux . +.It Em absorbed-flux +Flux absorbed by the receiver side. +.It Em abs-if-no-mat-loss +Absorbed flux if absorption by non-receivers is not taken into account. +.It Em abs-if-no-atm-loss +Absorbed flux if atmospheric extinction is not taken into account. +.It Em abs-mat-loss +.Em abs-if-no-mat-loss No \- Em absorbed-flux . +.It Em abs-atm-loss +.Em abs-if-no-atm-loss No \- Em absorbed-flux . +.El +.Pp +Both front and back side estimates are always output, even if the +receiver has only a single receiving side. +In that case, the results of the non-receiving side are meaningless +(invalid \-1 value). +.Ss Receiver map +A receiver defined in the submitted +.Xr solstice-receiver 5 +file can have a per-primitive estimate of its incoming flux density +and/or absorbed flux density if its +.Em per_primitive +flag is active. +In this case, +.Xr solstice 1 +generates a +.Em receiver-map : +an ASCII VTK file +.Po +see +.Sx NOTES , +reference 2 +.Pc +that stores the triangular mesh of the receiver and, for each triangle, +the estimate of its associated incoming and/or absorbed flux density. +The resolution of the receiver map is thus controlled by the +discretization of the receiver's shape as described in the +.Xr solstice-input 5 +file. +To obtain a good estimate of the per-triangle flux densities, the +number of per-triangle experiments must be sufficient; since only a +small fraction of the overall sampled radiative paths reach a given +triangle, the total number of experiments specified through the +.Fl n +option of +.Xr solstice 1 +should be increased significantly, by 1 or 2 orders of magnitude. +.Pp +The number of written per-triangle flux density estimates depends on +the receiver's parameters: both front and back sides can be active, and +each side can produce an estimate for both incoming and absorbed flux +density. +As a consequence, the output can include up to 4 different estimates, +written in the order: incoming front, absorbed front, incoming back, +absorbed back. +The following grammar describes the formatting of a +.Em VTK-RECEIVER-MAP . +Refer to the VTK format specification +.Po +reference 2 +.Pc +for more information on the VTK file format. +.Bd -literal +VTK-RECEIVER-MAP ::= # vtk DataFile Version 2.0 + <receiver-name> + ASCII + DATASET POLYDATA + POINTS <#vertices> float + <map-vertices> + POLYGONS <#triangles> <#triangles*4> + <map-triangles> + CELL_DATA <#triangles> + <map-triangle-data> + +<map-vertices> ::= <real3> + [ <real3> ... ] # up to <#vertices> + +<map-triangles> ::= 3 <triangle-indices> + [ 3 <triangle-indices> ... ] # up to <#triangles> + +<map-triangle-data> ::= <map-front-data> + | <map-back-data> + | <map-front-data> <map-back-data> + +<map-front-data> ::= <map-side-data> +<map-back-data> ::= <map-side-data> + +<map-side-data> ::= <incoming-flux> + | <absorbed-flux> + | <incoming-flux> <absorbed-flux> + +<incoming-flux> ::= <flux-density-data> +<absorbed-flux> ::= <flux-density-data> + +<flux-density-data> ::= SCALARS <side-and-flux-names> float 2 + LOOKUP_TABLE default + <estimate> + [ <estimate> ... ] + +<side-and-flux-names> ::= Front_faces_Incoming_flux + | Front_faces_Absorbed_flux + | Back_faces_Incoming_flux + | Back_faces_Absorbed_flux + +<#triangles> ::= INTEGER +<#vertices> ::= INTEGER +<triangle-indices> ::= INTEGER INTEGER INTEGER +.Ed +.Sh DUMP GEOMETRY +A +.Em dump-geometry-output +is generated when +.Xr solstice 1 +is invoked with the +.Fl g +option. +For each submitted sun direction, +.Xr solstice 1 +converts the geometry of the submitted +.Xr solstice-input 5 +file into triangular meshes written to the output in the format +specified by the +.Cm format +sub-option of +.Fl g . +The only currently supported format is Alias Wavefront OBJ +.Po +reference 3 +.Pc . +With no further sub-option, a single OBJ file containing the whole mesh +of the solar plant is generated. +The +.Cm split +sub-option of +.Fl g +allows generating several OBJ descriptions, one per +.Cm geometry +or per +.Cm object +as defined in the +.Xr solstice-input 5 +format; each description is then followed by a line containing +.Qq --- +to mark the end of the current OBJ. +.Pp +Regardless of the +.Cm split +strategy, each geometry is an OBJ group whose name is the +.Em entity-identifier +of the entity in which it is encapsulated. +The +.Em usemtl +OBJ directive associates to each mesh the name of its material type. +The following grammar describes the formatting of an +.Em OBJ-FILE . +Refer to the OBJ format specification +.Po +reference 3 +.Pc +for more information. +.Bd -literal +OBJ-FILE ::= g <entity-identifier> + <obj-mesh> + [ <obj-mesh> ... ] + +<obj-mesh> ::= usemtl <material-type> + <obj-vertices> + <obj-faces> + +<obj-vertices> ::= v <real3> + [ v <real3> ... ] + +<obj-indices> ::= f <triangle-indices> + [ f <triangle-indices> ... ] + +<material-type> ::= dielectric + | matte + | mirror + | thin_dielectric + | virtual +.Ed +.Sh DUMP RADIATIVE PATHS +For each sun direction, the +.Em dump-radiative-paths-output +lists the geometric data of the radiative paths sampled during a +simulation. +Each path is coloured according to its type: +.Bl -tag -width Ds +.It Yellow +The first segment (the ray from the sun toward a primary geometry) is +occluded by a non-virtual object. +.It Blue +The path is not occluded and reaches a receiver. +.It Turquoise +The path is not occluded and does not reach a receiver. +.It Red +The path was cancelled due to a topologically incoherent impact (an +impact on a surface not at the boundary of the medium in which the ray +was propagating). +.El +.Pp +The following grammar describes the formatting of a +.Em VTK-RADIATIVE-PATHS +file. +Refer to the VTK format specification +.Po +reference 2 +.Pc +for more information. +.Bd -literal +VTK-RADIATIVE-PATHS ::= # vtk DataFile Version 2.0 + Radiative paths + ASCII + DATASET POLYDATA + POINTS <#vertices> float + <paths-vertices> + LINES <#paths> <#paths+#vertices> + <paths-lists> + CELL_DATA <#paths> + SCALAR Radiative_path_type float 1 + LOOKUP_TABLE path_type + <paths-type> + LOOKUP_TABLE path_type 5 + <color-error> + <color-unused> + <color-success> + <color-missing> + <color-occluded> + +<paths-vertices> ::= <real3> + [ <real3> ... ] # up to <#vertices> + +<paths-lists> ::= <radiative-path> + [ <radiative-path> ... ] # up to <#paths> + +<radiative-path> ::= <#path-segments> <path-vertex-id> ... + +<paths-type> ::= <color-id> + [ <color-id> ... ] # up to <#paths> + +<color-id> ::= 0.0 # Red: for error paths + | 0.25 # Green: unused + | 0.5 # Blue: for success paths + | 0.75 # Turquoise: for missing paths + | 1.0 # Yellow: for occluded paths + +<color-error> ::= 1.0 0.0 0.0 1.0 +<color-unused> ::= 0.0 1.0 0.0 1.0 +<color-success> ::= 0.0 0.0 1.0 1.0 +<color-missing> ::= 0.0 1.0 1.0 1.0 +<color-occluded> ::= 1.0 1.0 0.0 1.0 + +<#paths> ::= INTEGER +<#path-segments> ::= INTEGER +<path-vertex-id> ::= INTEGER +.Ed +.Sh RENDERING +When invoked with the +.Fl r +option, +.Xr solstice 1 +generates one image of the solar facility per submitted sun direction. +Each image is preceded by its associated sun direction and saved in the +ASCII PPM file format +.Po +reference 1 +.Pc . +The output images are greyscale images whose pixels store the average +normalized radiance that reaches them. +.Sh NOTES +.Bl -enum +.It +Portable PixMap \(em +.Lk http://netpbm.sourceforge.net/doc/ppm.html +.It +VTK file format \(em +.Lk http://www.vtk.org/wp-content/uploads/2015/04/file-formats.pdf +.It +OBJ file format \(em +.Lk http://www.martinreddy.net/gfx/3d/OBJ.spec +.El +.Sh SEE ALSO +.Xr solstice 1 , +.Xr solstice-input 5 , +.Xr solstice-receiver 5 +.Sh HISTORY +.Nm +was initially developed with funding from the +.Em SOLSTICE LabEx +.Pq Laboratory of Excellence , +in collaboration with the PROMES Laboratory of the +French National Centre for Scientific Research +.Pq CNRS . +Starting in 2026, a new development effort funded by Ademe is ongoing. +.Sh AUTHORS +.Nm +was written and is maintained by +.An |M\['e]so|Star> Aq Mt contact@meso-star.com . diff --git a/doc/solstice-output.5.txt b/doc/solstice-output.5.txt @@ -1,541 +0,0 @@ -// Copyright (C) 2016-2018 CNRS, 2018-2019 |Meso|Star> -// -// This is free documentation: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This manual is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. -:toc: - -solstice-output(5) -================== - -NAME ----- -solstice-output - output format of solstice(1) results - -DESCRIPTION ------------ -The *solstice-output* describes the output format of the *solstice*(1) program. -All the data generated by a *solstice*(1) invocation are written in a single -file or on the standard output whether an _output_ file is defined through the -*-o* option or not, respectively. Note that submitting several sun directions -to *solstice*(1), through the *-D* option, will produce as many outputs as sun -directions. In other words, invoking *solstice*(1) with _N_ sun directions -looks like calling *solstice*(1) _N_ times and concatenating their associated -output. - -The type of the data that are generated depends on the mode in which -*solstice*(1) is invoked. By default, *solstice*(1) evaluates the power -collected by the submitted solar plant. When invoked with the *-g* option, -*solstice*(1) converts the solar plant geometries in a list of CAO files. The -*-p* option is used to track the sampled radiative paths while, finally, the -*-r* option allows to render an image of the solar facility. - -GRAMMAR -------- -The output values are mainly ASCII data formatted line by line. By convention, -in the following grammar the line data are listed between quote marks. The -grammar may use new lines for formatting constraints, but data are actually on -the same line while a closed quote mark is not defined. - -[verse] -_______ -<output> ::= <simulation-output> - | <dump-geometry-output> # -g option - | <dump-radiative-paths-output> # -p option - | <rendering-output> # -r option - -<simulation-output> ::= <sun-direction> - <counts> - <global> - [ <receivers-list> ] - [ <primaries-list> ] - [ <rcvXprims-list> ] - [ <receiver-maps> ] - [ <simulation-output> ... ] - -<dump-geometry-output> - ::= <sun-direction> - <geometry-data> - [ <dump-geometry-output> ... ] - -<dump-radiative-paths-output> - ::= <sun-direction> - VTK-RADIATIVE-PATHS - [ <dump-radiative-paths-output> ... ] - -<rendering-output> ::= <sun-direction> - PPM-FILE # ASCII PPM with 8-bits per component [1] - [ <rendering-output> ... ] - -------------------------------------- - -<sun-direction> ::= "#--- Sun direction: <alpha> <beta> (<sun-vector>)" - -<counts> ::= "<#globals> <#receivers> <#primaries> - <#samples> <#failed>" - -<#globals> ::= 7 -<#receivers> ::= INTEGER # in [0, INF) -<#primaries> ::= INTEGER # in [0, INF) -<#samples> ::= INTEGER # in [0, INF) -<#failed> ::= INTEGER # in [0, INF) - -<global> ::= <potential-flux> - <absorbed-flux> - <cos-factor> - <shadow-loss> - <missing-loss> - <materials-loss> - <atmospheric-loss> - -------------------------------------- - -<receivers-list> ::= <receiver> - [ <receiver> ... ] - -<receiver> ::= "<receiver-name> <receiver-id> <area> - <front> <back>" - -<receiver-name> ::= <entity-identifier> - -<receiver-id> ::= INTEGER - -<front> ::= <side> -<back> ::= <side> - -<side> ::= "<incoming-flux> <in-if-no-mat-loss> - <in-if-no-atm-loss> <in-mat-loss> <in-atm-loss> - <absorbed-flux> <abs-if-no-mat-loss> - <abs-if-no-atm-loss> <abs-mat-loss> <abs-atm-loss> - <efficiency>" - -------------------------------------- - -<primaries-list> ::= <primary> - [ <primary> ... ] - -<primary> ::= "<primary-name> <primary-id> <area> <#samples> - <cos-factor> <shadow-loss>" - -<primary-name> ::= <entity-identifier> - -<primary-id> ::= INTEGER - -------------------------------------- - -<rcvXprims-list> ::= <rcvXprim> - [ <rcvXprim> ... ] - -<rcvXprim> ::= "<receiver-id> <primary-id> - <rcvXprim-front> <rcvXprim-back>" - -<rcvXprim-front> ::= <rcvXprim-side> -<rcvXprim-back> ::= <rcvXprim-side> - -<rcvXprim-side> ::= "<incoming-flux> <in-if-no-mat-loss> - <in-if-no-atm-loss> <in-mat-loss> <in-atm-loss> - <absorbed-flux> <abs-if-no-mat-loss> - <abs-if-no-atm-loss> <abs-mat-loss> <abs-atm-loss>" - -------------------------------------- - -<receiver-maps> ::= VTK-RECEIVER-MAP - [ <receiver-maps> ... ] - -<geometry-data> ::= OBJ-FILE - [ --- - <geometry-data> ... ] - -------------------------------------- - -<area> ::= REAL # in ]0, INF) - -<real3> ::= REAL REAL REAL - -<alpha> ::= REAL # Degrees in [0, 360[ -<beta> ::= REAL # Degrees in [0, 90] -<sun-vector> ::= <real3> - -<incoming-flux> ::= <estimate> -<in-if-no-mat-loss> ::= <estimate> -<in-if-no-atm-loss> ::= <estimate> -<in-mat-loss> ::= <estimate> -<in-atm-loss> ::= <estimate> -<absorbed-flux> ::= <estimate> -<abs-if-no-mat-loss> ::= <estimate> -<abs-if-no-atm-loss> ::= <estimate> -<abs-mat-loss> ::= <estimate> -<abs-atm-loss> ::= <estimate> -<cos-factor> ::= <estimate> -<missing-loss> ::= <estimate> -<materials-loss> ::= <estimate> -<atmospheric-loss> ::= <estimate> -<shadow-loss> ::= <estimate> -<efficiency> ::= <estimate> - -<estimate> ::= <expected-value> <standard-error> -<expected-value> ::= REAL -<standard-error> ::= REAL # in [0, INF) - -<entity-identifier> # Defined in *solstice-input*(5) -_______ - -SIMULATION ----------- - -A *simulation-output* begins with two header lines. The first one reports the -sun direction used in the simulation (two angles in degrees, plus the -corresponding sun vector), -and the second one lists the numbers of global, per receiver and per -primary results as well as the overall number of Monte-Carlo experiments used -by the simulation and the number of experiments that failed due to unforeseen -errors as numerical imprecisions. As soon as the number of failed experiments -reaches 1% of the required number of Monte-Carlo experiments, the code exits -with a "Error in integrating the solar flux" message, and the validity of -subsequent results is questionable: estimates are produced using the number of -Monte-Carlo experiments that have been successful, which is necessarily smaller -than the required number of experiments. - -Global results -~~~~~~~~~~~~~~ - -After the 2 header lines, the output includes various *global* result lines, -the exact number of lines being part of the headers. Currently this number is -7. Each global result is a pair of real numbers: the expected value and its -standard error. The global results are, in this order: - -- *potential-flux*: maximum flux that all the primary geometries could - intercept if properly oriented and flat-shaped; -- *absorbed-flux*: absorbed part of the flux reaching any receiver geometry. - At most equal to the potential flux; -- *cos-factor*: cos of the angle between the sun direction and the normal of - the primary surfaces (average cos over all primary geometries); -- *shadow-loss*: potential flux intercepted by another geometry before - reaching a primary geometry; -- *missing-loss*: part of the flux that reaches a primary geometry, follows a - radiative path, but is not absorbed; this flux could have bounced on - geometries, including receivers, but without being absorbed; -- *materials-loss*: total flux absorbed by non-receivers along radiative - paths; includes both surface and volume absorption; -- *atmospheric-loss*: total flux extinction by the atmosphere along radiative - paths. - -This results can be used to check conservation of energy: - -potential-flux * cos-factor and (absorbed-flux + shadow-loss + -missing-loss + materials-loss + atmospheric-loss) -should be equal within their respective uncertainty ranges. - -Per receiver results -~~~~~~~~~~~~~~~~~~~~ - -Following global results, the output includes various per-receiver lines, one -line per receiver, the exact number of lines being part of the headers. The -per-receiver results are sorted according to the order of the receivers as -defined in the submitted *solstice-receiver*(5) file. Each line contains the -following data: - -- *receiver-name*: name of the receiver, i.e. *entity-identifier* of the - entity in which the receiving geometry is defined (see the - *solstice-input*(5) format); -- *receiver-id*: unique integer identifying the receiver; -- *area*: area of the receiver; -- *front*: estimated results for the front side of the receiver; -- *back*: estimated results for the back side of the receiver. - -The estimates of the *front* and *back* sides are listed bellow. Note that -each of the following estimates is actually a pair of real numbers: the -expected value and its standard error. - -- *incoming-flux*: flux that reaches the receiver side; -- *in-if-no-mat-loss*: incoming-flux if absorption on non-receivers is not - taken into account; -- *in-if-no-atm-loss*: incoming-flux if atmospheric extinction is not taken - into account; -- *in-mat-loss*: in-if-no-mat-loss - incoming-flux; -- *in-atm-loss*: in-if-no-atm-loss - incoming-flux; -- *absorbed-flux*: flux absorbed by the receiver side; -- *abs-if-no-mat-loss*: absorbed-flux if absorption by non-receivers is not - taken into account; -- *abs-if-no-atm-loss*: absorbed-flux if atmospheric extinction is not taken - into account; -- *abs-mat-loss*: abs-if-no-mat-loss - absorbed-flux; -- *abs-atm-loss*: abs-if-no-atm-loss - absorbed-flux; -- *efficiency*: fraction of the potential flux absorbed by this receiver side. - -Both *front* and *back* side estimates are output, even if the receiver has -only a single receiving side. In this case, the results of the non-receiving -side are meaningless (invalid -1 value). - -Per primary results -~~~~~~~~~~~~~~~~~~~ - -Following the per-receiver results, the output includes various per-primary -result lines, one line per primary geometry, the exact number of lines being -part of the headers. Each line contains: - -- *primary-name*: name of the primary geometry, i.e. *entity-identifier* of - the entity in in which the primary geometry is defined (see the - *solstice-input*(5) format); -- *primary-id*: unique integer identifying the primary geometry; -- *area*: area of the primary geometry; -- *#sample*: number of Monte-Carlo experiments sampled on the primary - geometry; -- *cos-factor*: cos of the angle between the sun direction and the normal of - the primary surface (average cos on the primary geometry); -- *shadow-loss*: potential flux intercepted by another geometry before reaching - the primary geometry of interest. - -Per receiver and per primary results -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Following the per-primary results, the output includes various result lines, -each describing the contribution of a primary geometry to a given receiver. -The total number of such lines is the number of receivers times the number of -primary geometries. Each line contains: - -- *receiver-id*: identifier of the involved receiver; -- *primary-id*: identifier of the involved primary geometry; -- *rcvXprim-front*: estimated results for the receiver front side; -- *rcvXprim-back*: estimated results for the receiver back side; - -The estimated values of *rcvXprim-front* and *rcvXprim-back* are listed -bellow. Each of these estimates is actually a pair of real numbers: the -expected value and its standard error. - -- *incoming-flux*: flux that reaches the receiver side; -- *in-if-no-mat-loss*: incoming-flux if absorption on non-receivers is not - taken into account; -- *in-if-no-atm-loss*: incoming-flux if atmospheric extinction is not taken - into account; -- *in-mat-loss*: in-if-no-mat-loss - incoming-flux; -- *in-atm-loss*: in-if-no-atm-loss - incoming-flux; -- *absorbed-flux*: flux absorbed by the receiver side; -- *abs-if-no-mat-loss*: absorbed-flux if absorption by non-receivers is not - taken into account; -- *abs-if-no-atm-loss*: absorbed-flux if atmospheric extinction is not taken - into account; -- *abs-mat-loss*: abs-if-no-mat-loss - absorbed-flux; -- *abs-atm-loss*: abs-if-no-atm-loss - absorbed-flux; - -Both front and back side estimates are output, even if the receiver has only a -single receiving side. In this case, the results of the non-receiving side are -meaningless (invalid -1 value). - -Receiver map -~~~~~~~~~~~~ - -A receiver defined in the submitted *solstice-receiver*(5) file, can have a -per-primitive estimate of its incoming flux density and/or absorbed flux -density if its *per_primitive* flag is active. In this case, *solstice*(1) -generates a *receiver-map* that is actually an ASCII VTK file [2] that stores -the triangular mesh of the receiver and, for each triangle, the estimate of -its associated incoming flux density and/or absorbed flux density. The -"definition" of the receiver map is thus controlled by the discretisation of -the receiver's shape, as described in the *solstice-input*(5) file. Note that -to obtain a good estimate of the per-triangle flux densities, one have to -ensure that the number of per-triangle experiments is sufficient regarding the -targeted accuracy. Since only a small fraction of the overall sampled -radiative paths reach a given triangle, the total number of experiments -required through the *-n* option of *solstice*(1) should be increased -significantly, as 1 or 2 order of magnitude. - -The number of written per-triangle flux density estimates depends on the -receiver's parameters: both front and back sides of the receiver can be active -and each side can produce an estimate both for the incoming flux density and -for the absorbed flux density. As a consequence, the output can include up to -4 different estimates that are written in the order: incoming front, absorbed -front, incoming back, absorbed back. The following grammar gives a brief -description of the formatting of a *VTK-RECEIVER-MAP*. Please refer to the VTK -format specification [2] for more informations on the VTK file format. - -[verse] -_______ -VTK-RECEIVER-MAP ::= # vtk DataFile Version 2.0 - <receiver-name> - ASCII - DATASET POLYDATA - POINTS <#vertices> float - <map-vertices> - POLYGONS <#triangles> <#triangles*4> - <map-triangles> - CELL_DATA <#triangles> - <map-triangle-data> - -<map-vertices> ::= <real3> - [ <real3> ... ] # up to <#vertices> - -<map-triangles> ::= 3 <triangle-indices> - [ 3 <triangle-indices> ... ] # up to <#triangles> - -<map-triangle-data> ::= <map-front-data> - | <map-back-data> - | <map-front-data> <map-back-data> - -<map-front-data> ::= <map-side-data> -<map-back-data> ::= <map-side-data> - -<map-side-data> ::= <incoming-flux> - | <absorbed-flux> - | <incoming-flux> <absorbed-flux> - -<incoming-flux> ::= <flux-density-data> -<absorbed-flux> ::= <flux-density-data> - -<flux-density-data> ::= SCALARS <side-and-flux-names> float 2 - LOOKUP_TABLE default - <estimate> - [ <estimate> ... ] - -<side-and-flux-names> ::= Front_faces_Incoming_flux - | Front_faces_Absorbed_flux - | Back_faces_Incoming_flux - | Back_faces_Absorbed_flux - -<#triangles> ::= INTEGER -<#vertices> ::= INTEGER -<triangle-indices> ::= INTEGER INTEGER INTEGER -_______ - -DUMP GEOMETRY -------------- - -A *dump-geometry-output* is generated when *solstice*(1) is invoked with the -*-g* option. In this mode, for each submitted sun direction, *solstice*(1) -converts the geometry of the submitted *solstice-input*(5) file in triangular -meshes that are then written to the output with respect to the format provided -by the *format* parameter of the *-g* option. The only format currently -supported by *solstice*(1) is the Alias Wavefront OBJ [3] format. With no more -sub-option, *solstice*(1) will thus generate one OBJ file containing the whole -mesh of the solar plant. However, the *split* parameter of the *-g* option -allows to generate several OBJ files: one description is generated per -*geometry* or per *object*, as defined in the *solstice-input*(5) format, -whether the *split* sub-option is set to *geometry* or *object*. In this -situation, each OBJ description is followed by a line with 3 minus characters -in order to identify the end of the current OBJ. - -Independently of the *split* strategy, each *solstice-input*(1) geometry is an -OBJ group whose name is the *entity-identifier* of the entity in which it is -encapsulated. Finally, the *dump-geometry-output* uses the *usemtl* directive -of the OBJ format to associate to a mesh the name of its material type. The -following grammar succinctly describes the formatting of an *OBJ-FILE*. Please -refer to the OBJ format specification [3] for more informations on the OBJ file -format. - -[verse] -_______ -OBJ-FILE ::= g <entity-identifier> - <obj-mesh> - [ <obj-mesh> ... ] - -<obj-mesh> ::= usemtl <material-type> - <obj-vertices> - <obj-faces> - -<obj-vertices> ::= v <real3> - [ v <real3> ... ] - -<obj-indices> ::= f <triangle-indices> - [ f <triangle-indices> ... ] - -<material-type> ::= dielectric - | matte - | mirror - | thin_dielectric - | virtual -_______ - -DUMP RADIATIVE PATHS --------------------- - -For each sun direction, the *dump-radiative-paths-output* lists the geometric -data of the radiative paths sampled during a simulation. Each path is colored -with respect to its type: the path is yellow if its first segment, i.e. -the ray starting from the sun towards a primary geometry, is occluded by a non -virtual object. If not occluded, the path can be blue or turquoise whether it -reaches a receiver or not, respectively. Finally, the path can also be red if -it was canceled due to a topologically incoherent impact (i.e. an impact on a -surface not at the boundary of the medium in which the rays was propagating). -The following grammar describes the formatting of a *VTK-RADIATIVE-PATHS* -file. Refer to the VTK format specification [2] for more informations on the -VTK file format. - -[verse] -_______ -VTK-RADIATIVE-PATHS ::= # vtk DataFile Version 2.0 - Radiative paths - ASCII - DATASET POLYDATA - POINTS <#vertices> float - <paths-vertices> - LINES <#paths> <#paths+#vertices> - <paths-lists> - CELL_DATA <#paths> - SCALAR Radiative_path_type float 1 - LOOKUP_TABLE path_type - <paths-type> - LOOKUP_TABLE path_type 5 - <color-error> - <color-unused> - <color-success> - <color-missing> - <color-occluded> - -<paths-vertices> ::= <real3> - [ <real3> ... ] # up to <#vertices> - -<paths-lists> ::= <radiative-path> - [ <radiative-path> ... ] # up to <#path> - -<radiative-path> ::= <#path-segments> <path-vertex-id> ... - -<paths-type> ::= <color-id> - [ <color-id> ... ] # up to <#paths> - -<color-id> ::= 0.0 # Red: for error paths - | 0.25 # Green: unused - | 0.5 # Blue: for success paths - | 0.75 # Turquoise: for missing paths - | 1.0 # Yellow: for occluded paths - -<color-error> ::= 1.0 0.0 0.0 1.0 -<color-unused> ::= 0.0 1.0 0.0 1.0 -<color-success> ::= 0.0 0.0 1.0 1.0 -<color-missing> ::= 0.0 1.0 1.0 1.0 -<color-occluded> ::= 1.0 1.0 0.0 1.0 - -<#paths> ::= INTEGER -<#path-segments> ::= INTEGER -<path-vertex-id> ::= INTEGER -_______ - -RENDERING ---------- -When invoked with the *-r* option, *solstice*(1) generates an image of the -solar facility for each submitted sun direction. Each image is preceded by its -associated sun direction and is saved with respect to the ASCII PPM file -format [1]. The output images are actually greyscale images whose pixels store -the average normalized radiance that reaches them. - -NOTES ------ -1. Portable PixMap - <http://netpbm.sourceforge.net/doc/ppm.html> -2. VTK file format - - <http://www.vtk.org/wp-content/uploads/2015/04/file-formats.pdf> -3. OBJ file format - - <http://www.martinreddy.net/gfx/3d/OBJ.spec> - -SEE ALSO --------- -*solstice*(1), -*solstice-input*(5), -*solstice-receiver*(5) diff --git a/doc/solstice-receiver.5 b/doc/solstice-receiver.5 @@ -0,0 +1,165 @@ +.\" Copyright (C) 2016-2018 CNRS, 2018-2019 |Meso|Star> +.\" +.\" This is free documentation: you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation, either version 3 of the License, or +.\" (at your option) any later version. +.\" +.\" This manual is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program. If not, see <http://www.gnu.org/licenses/>. +.\" +.Dd $Mdocdate$ +.Dt SOLSTICE-RECEIVER 5 +.Os +.Sh NAME +.Nm solstice-receiver +.Nd declare solar-plant receivers for solstice +.Sh DESCRIPTION +The +.Nm +format is used by +.Xr solstice 1 +to declare which geometric entities defined in a +.Xr solstice-input 5 +file act as receivers. +For each receiver, +.Xr solstice 1 +computes its total intercepted power, associated losses, and efficiency. +Refer to +.Xr solstice-output 5 +for details on the per-receiver data produced by +.Xr solstice 1 . +Defining receivers separately from the solar plant allows the same +.Xr solstice-input 5 +file to be reused across multiple simulations with different receiver +configurations. +For example, you can create a dedicated +.Nm +file that designates certain primary reflectors as receivers to investigate +unexpected behaviour observed in a prior simulation. +.Pp +The +.Nm +format follows the YAML 1.1 data serialization standard +.Po +see +.Sx NOTES , +reference 1 +.Pc . +Provided the file conforms to the +.Nm +semantic, receivers can be described by using the whole YAML 1.1 +functionalities including compact notation and data tagging. +.Pp +A receiver is identified by its +.Em name , +which must be a valid +.Em entity-identifier +as defined in +.Xr solstice-input 5 . +This identifier must refer to a geometric entity, not a pivot or an empty +entity. +The side of the geometry to be tracked is specified by the +.Em side +attribute. +Both the front and back sides of a geometry can be considered by setting +.Em side +to +.Cm FRONT_AND_BACK . +See +.Xr solstice-input 5 +for details on which side of a geometry is considered front-facing or +back-facing. +.Pp +If the optional +.Em per_primitive +flag is enabled, +.Xr solstice 1 +estimates the flux density for each triangle of the receiver and uses this data +to generate a receiver map as described in +.Xr solstice-output 5 . +The +.Em per_primitive +flag accepts the values +.Cm INCOMING , +.Cm ABSORBED , +or +.Cm INCOMING_AND_ABSORBED +to produce the incoming flux density map, the absorbed flux density map, or +both, respectively. +.Sh GRAMMAR +.Bd -literal +<receivers-list> ::= - <receiver> + [ - <receiver> ... ] + +<receiver> ::= name: <entity-identifier> + side: <side-identifier> + [ per_primitive: <per-primitive-mode> ] # Default: NONE + +<side-identifier> ::= FRONT + | BACK + | FRONT_AND_BACK + +<per-primitive-mode> ::= NONE + | INCOMING + | ABSORBED + | INCOMING_AND_ABSORBED + +<entity-identifier> # Defined in solstice-input(5) +.Ed +.Sh EXAMPLES +Designate both the front and back sides of the entity +.Cm small_square +as receivers, and enable per-triangle absorbed flux density computation for each +side: +.Bd -literal +- name: small_square + side: FRONT_AND_BACK + per_primitive: ABSORBED +.Ed +.Pp +Declare the front side of three reflectors as receivers using YAML compact +notation: +.Bd -literal +- {name: H1.heliostat.reflector, side: FRONT} +- {name: H4.heliostat.reflector, side: FRONT} +- {name: H7.heliostat.reflector, side: FRONT} +.Ed +.Pp +Designate the back side of +.Cm receiver +as a receiver with an incoming flux density map, and make the front side of the +reflector named +.Cm LFR0.pivot.reflector +a receiver: +.Bd -literal +- {name: receiver, side: BACK, per_primitive: INCOMING} +- {name: LFR0.pivot.reflector, side: FRONT} +.Ed +.Sh NOTES +.Bl -enum +.It +YAML Ain't Markup Language \(em +.Lk http://yaml.org +.El +.Sh SEE ALSO +.Xr solstice 1 , +.Xr solstice-input 5 , +.Xr solstice-output 5 +.Sh HISTORY +.Nm +was initially developed with funding from the +.Em SOLSTICE LabEx +.Pq Laboratory of Excellence , +in collaboration with the PROMES Laboratory of the +French National Centre for Scientific Research +.Pq CNRS . +.Sh AUTHORS +.Nm +was written and is maintained by +.An |M\['e]so|Star> Aq Mt contact@meso-star.com . diff --git a/doc/solstice-receiver.5.txt b/doc/solstice-receiver.5.txt @@ -1,122 +0,0 @@ -// Copyright (C) 2016-2018 CNRS, 2018-2019 |Meso|Star> -// -// This is free documentation: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This manual is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. -:toc: - -solstice-receiver(5) -==================== - -NAME ----- -solstice-receiver - declare the solar-plant receivers for solstice(1) - - -DESCRIPTION ------------ - -The *solstice-receiver* format is used by *solstice*(1) to declare which -geometric entities defined in a *solstice-input*(5) file are receivers. For -each receiver, *solstice*(1) computes its overall intercepted power, its -associated losses as well as its efficiency. Refer to the *solstice-output*(5) -format for informations on the per receiver data generated by *solstice*(1). -Declaring the receivers separately of the solar plant, allows to use the same -*solstice-input*(5) file for several simulations using different receivers. For -instance, one can define a specific *solstice-receiver* file that declares some -primary reflectors as receivers in order to track an unforeseen comportment -observed during a previous simulation. - -The *solstice-receiver* format uses the YAML 1.1 data serialization standard -[1]; assuming that the file is compatible with the *solstice-receiver* -semantic, the YAML compact notation can thus be used. - -A receiver is identified by its *name* that must be a valid *entity-identifier* -as defined in the *solstice-input*(5) format. This identifier must reference a -geometric entity and not a pivot or an empty entity. The side of the geometry -that is tracked is defined by the *side* attribute of the receiver. Note that -the front and the back side of a geometry can be both considered if the *side* -attribute is set to *FRONT_AND_BACK*. Refer to the *solstice-input*(5) -specification for informations on which side of the geometry is front facing or -back facing. Finally, if the optional *per_primitive* flag is set, -*solstice*(1) will estimate the irradiance for each triangle of the receiver -and use these data to generate a receiver map as described in -*solstice-output*(5). The *per-primitive* flag can be set to *INCOMING*, -*ABSORBED* or *INCOMING_AND_ABSORBED* to produce the incoming flux density -map, the absorbed flux density map, or both. - -GRAMMAR -------- - -[verse] -_______ -<receivers-list> ::= - <receiver> - [ - <receiver> ... ] - -<receiver> ::= name: <entity-identifier> - side: <side-identifier> - [ per_primitive: <per-primitive-mode> ] # Default: NONE - -<side-identifier> ::= FRONT - | BACK - | FRONT_AND_BACK - -<per-primitive-mode> ::= NONE - | INCOMING - | ABSORBED - | INCOMING_AND_ABSORBED - -<entity-identifier> # Defined in *solstice-input*(5) -_______ - -EXAMPLES --------- - -Define that the front and back side of the entity *small_square* are -receivers. For each side, enable the computation of per triangle absorbed -irradiance. - -....... -- name: small_square - side: FRONT_AND_BACK - per_primitive: ABSORBED -....... - -Declare that the front side of 3 reflectors are receivers. Use the YAML -compact notation to reduce the number of lines: - -...... -- {name: H1.heliostat.reflector, side: FRONT} -- {name: H4.heliostat.reflector, side: FRONT} -- {name: H7.heliostat.reflector, side: FRONT} -...... - -Declare that the back side of *receiver* is effectively a receiver and enable -the estimation of its associated incoming irradiance map. Make a receiver from -the front side of the reflector named *LFR0.pivot.reflector*: - -....... -- {name: receiver, side: BACK, per_primitive: INCOMING} -- {name: LFR0.pivot.reflector, side: FRONT} -....... - -NOTES ------ - -1. YAML Ain't Markup Language - <http://yaml.org> - -SEE ALSO --------- -*solstice*(1), -*solstice-input*(5), -*solstice-output*(5) - diff --git a/doc/solstice.1.in b/doc/solstice.1.in @@ -0,0 +1,412 @@ +.\" SPDX-License-Identifier: GPL-3.0-or-later +.\" Copyright (C) 2016-2018 CNRS, 2018-2019 |Méso|Star> +.\" +.\" This is free documentation: you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation, either version 3 of the License, or +.\" (at your option) any later version. +.\" +.\" This manual is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program. If not, see <http://www.gnu.org/licenses/>. +.Dd $Mdocdate$ +.Dt SOLSTICE 1 +.Os +.Sh NAME +.Nm solstice +.Nd compute the power collected by a concentrated solar plant +.Sh SYNOPSIS +.Nm +.Nm +.Op Ar option ... +.Op Ar file +.Nm +.Fl g Ar sub-option Ns Op : Ns Ar ... +.Op Ar option ... +.Op Ar file +.Nm +.Fl p Ar sub-option Ns Op : Ns Ar ... +.Op Ar option ... +.Op Ar file +.Nm +.Fl r Ar sub-option Ns Op : Ns Ar ... +.Op Ar option ... +.Op Ar file +.Sh DESCRIPTION +.Nm +computes the total power collected by a concentrated solar plant, as +described in the +.Xr solstice-input 5 +.Ar file . +If the +.Ar file +argument is not provided, the solar plant is read from standard input. +To evaluate various efficiencies for each primary reflector, it computes +losses due to cosine effect, shadowing and masking, orientation and surface +irregularities, materials properties and atmospheric extinction. +The efficiency for each one of these effects is subsequently computed for +each reflector. +.Pp +The entities on which computations must be performed are listed in the +.Xr solstice-receiver 5 +file submitted through the +.Fl R +option. +The estimated results follow the +.Xr solstice-output 5 +format and are written to the +.Ar output +file or to the standard output whether the +.Fl o Ar output +option is defined or not, respectively. +Note that the +.Nm +algorithm is based on the Monte-Carlo method, which means that every +result is provided with its numerical accuracy. +.Pp +.Nm +is designed to efficiently handle complex solar facilities: several +reflectors can be specified (planes, conics, cylindro-parabolic, etc.\&) +and positioned in 3D space, with a possibility for 1-axis and 2-axis +auto-orientation. +Multiple materials can be used, as long as the relevant physical properties +are provided. +Spectral effects are also taken into account: it is possible to define the +spectral distribution of any physical property, including the input solar +spectrum and the transmissivity of the atmosphere, at any spectral +resolution. +Refer to +.Xr solstice-input 5 +for more information. +.Pp +In addition to the aforementioned computations, +.Nm +provides three other functionalities. +The +.Fl g +option can be used to convert the +.Xr solstice-input 5 +geometries into CAO files. +The +.Fl p +option saves the sampled radiative paths used by the estimates, allowing +to visualise them externally, which may be a great help to identify a +design issue. +Finally, the +.Fl r +option is used to render an image of the submitted solar facility. +Note that these three options are mutually exclusive, and once defined, +they replace the default +.Nm +behaviour. +.Pp +Any coordinate-related question in +.Nm +must be considered with the right-handed convention in mind. +.Sh OPTIONS +.Bl -tag -width Ds +.It Fl D Ar alpha,beta Ns Op : Ns Ar ... +List of sun directions. +A direction is defined by two angles in degrees. +The first one, +.Ar alpha , +is an azimuthal angle in [0,\ 360[ and the second one, +.Ar beta , +is an elevation in [0,\ 90]. +Each provided sun direction triggers a new computation whose results are +concatenated to the +.Ar output +file. +.Pp +Following the right-handed convention, azimuthal rotation is +counter-clockwise, with 0\(de on the X axis. +Elevation starts from 0\(de for directions in the XY plane, up to 90\(de +at zenith. +Thus +.Fl D Ns Ar 0,0 , +.Fl D Ns Ar 90,0 , +.Fl D Ns Ar 180,0 +and +.Fl D Ns Ar 270,0 +produce solar vectors {-1,0,0}, {0,-1,0}, {+1,0,0} and {0,+1,0} +respectively, while +.Fl D Ns Ar alpha , Ns 90 +produces {0,0,-1} regardless of the value of +.Ar alpha . +.It Fl f +Force overwrite of the output files, i.e.\& the +.Ar output +file and the file where the state of the random number generator is saved +(see the +.Fl G +option). +.It Fl G Ar sub-option Ns Op : Ns Ar ... +Save and restore the state of the random number generator. +This option can be used to ensure statistical independence between +successive simulations on the same system. +Available sub-options are: +.Bl -tag -width Ds +.It Cm istate= Ns Ar input_rng_state +Define the file from which the initial state of the random number +generator is read. +If not defined, the random number generator is initialised with its +default seed. +.It Cm ostate= Ns Ar output_rng_state +Define the file where the final state of the random number generator is +written. +If not defined, this state is simply discarded. +.El +.It Fl g Ar sub-option Ns Op : Ns Ar ... +Generate the shape of the geometry defined in the submitted +.Ar file +and store it in +.Ar output . +Available sub-options are: +.Bl -tag -width Ds +.It Cm format=obj +Define the file format in which the meshes are stored. +Currently, only the Alias Wavefront OBJ file format is supported. +.It Cm split= Ns Aq Cm geometry Ns | Ns Cm object Ns | Ns Cm none +Define how the output mesh is split into sub-meshes. +A sub-mesh can be generated for each +.Cm geometry +or for each +.Cm object +as defined in the +.Xr solstice-input 5 +file format. +The +.Cm none +option means that only one mesh is generated for the whole solar +facility. +By default, +.Cm split +is set to +.Cm none . +.El +.It Fl h +List short help and exit. +.It Fl n Ar samples-count +Number of Monte-Carlo samples used to estimate the solar flux. +By default +.Ar samples-count +is set to +.Sy @SOLSTICE_ARGS_DEFAULT_NREALISATIONS@ . +.It Fl o Ar output +Write results to +.Ar output +with respect to the +.Xr solstice-output 5 +format. +If not defined, write results to standard output. +.It Fl p Ar sub-option Ns Op : Ns Ar ... +Register the sampled radiative paths for each sun direction and write +them to +.Ar output . +Available sub-options are: +.Bl -tag -width Ds +.It Cm default +Use default sub-options. +.It Cm irlen= Ns Ar length +Length of the radiative path segments going to infinity. +By default, it is computed relative to the scene size. +.It Cm srlen= Ns Ar length +Length of the radiative path segments coming from the sun. +By default, it is computed relative to the scene size. +.El +.It Fl q +Do not print the helper message when no +.Ar file +is submitted. +.It Fl R Ar receivers +.Xr solstice-receiver 5 +file defining the scene receivers, i.e.\& the solar plant entities for +which +.Nm +computes Monte-Carlo estimates. +.It Fl r Ar sub-option Ns Op : Ns Ar ... +Render an image of the scene through a pinhole camera for each submitted +sun direction. +Write the resulting images to +.Ar output . +Available sub-options are: +.Bl -tag -width Ds +.It Cm fov= Ns Ar angle +Horizontal field of view of the camera in [30,\ 120] degrees. +By default +.Ar angle +is +.Sy @SOLSTICE_ARGS_DEFAULT_CAMERA_FOV@ +degrees. +.It Cm img= Ns Ar width Ns x Ns Ar height +Definition of the rendered image in pixels. +By default the image definition is +.Sy @SOLSTICE_ARGS_DEFAULT_IMG_WIDTH@ Ns x Ns Sy @SOLSTICE_ARGS_DEFAULT_IMG_HEIGHT@ . +.It Cm pos= Ns Ar x , Ns Ar y , Ns Ar z +Position of the camera. +By default it is set to +.Sy { Ns @SOLSTICE_ARGS_DEFAULT_CAMERA_POS@ Ns } +or it is automatically computed to ensure that the whole scene is +visible, whether +.Cm tgt +is set or not, respectively. +.It Cm rmode= Ns Aq Cm draft Ns | Ns Cm pt +Rendering mode. +In +.Cm draft +mode, images are computed by ray-casting; all materials are lambertian, +the sun is ignored and the only light source is positioned at the camera +position. +In +.Cm pt +mode, the scene is rendered with the un-biased path-tracing Monte-Carlo +algorithm; the materials described in the committed +.Ar file +as well as the submitted sun directions are correctly handled and a +uniform skydome is added to simulate the diffuse infinite lighting. +By default +.Cm rmode +is set to +.Cm draft . +.It Cm spp= Ns Ar samples-count +Number of samples per pixel. +If +.Cm rmode +is +.Cm draft , +the sample positions within a pixel are the same for all pixels. +With +.Cm rmode=pt +the pixel samples are generated independently for each pixel. +By default, @SOLSTICE_ARGS_DEFAULT_IMG_SPP@ sample per pixel is used. +.It Cm tgt= Ns Ar x , Ns Ar y , Ns Ar z +Position targeted by the camera. +By default it is set to +.Sy { Ns @SOLSTICE_ARGS_DEFAULT_CAMERA_TGT@ Ns } +or it is automatically computed to ensure that the whole scene is +visible, whether +.Cm pos +is set or not, respectively. +.It Cm up= Ns Ar x , Ns Ar y , Ns Ar z +Up vector of the camera. +If +.Cm rmode +is +.Cm pt , +this vector also defines the direction toward the top of the skydome. +By default, +.Cm up +is set to +.Sy { Ns @SOLSTICE_ARGS_DEFAULT_CAMERA_UP@ Ns } . +.El +.It Fl t Ar threads-count +Hint on the number of threads to use. +By default, as many threads as CPU cores are used. +.It Fl v +Make +.Nm +more verbose. +.It Fl -version +Output version information and exit. +.El +.Sh EXAMPLES +Launch two simulations for sun directions whose azimuthal and elevation +angles are {45,70} and {50,75}. +The solar facility is described in +.Pa input.yaml +and the receivers on which the integrations must be performed are declared +in +.Pa rcvs.yaml . +10000 samples are used by the Monte-Carlo estimates and the results +are written to +.Pa output +even though this file already exists: +.Bd -literal -offset indent +solstice -D45,70:50,75 -R rcvs.yaml -n 10000 -f -o output input.yaml +.Ed +.Pp +Generate a mesh for each geometry described in +.Pa input.yaml +and save them in +.Pa output +with respect to the Alias Wavefront OBJ format. +The meshes are positioned according to their orientation constraints, +with respect to the sun direction whose azimuthal and elevation angles +are {30,60}. +Use +.Xr csplit 1 +to generate one Alias Wavefront OBJ file per geometry stored in +.Pa output . +The generated files are named +.Pa geom Ns Ar NUM Ns .obj +with +.Ar NUM +in [0,\ N-1] where N is the number of geometries described in +.Pa input.yaml . +Refer to +.Xr solstice-output 5 +for information on the regular expression +.Qq ^---$ +used to split the output file: +.Bd -literal -offset indent +solstice -D30,60 -g format=obj:split=geometry -f -o output input.yaml +csplit -f geom -b %02d.obj -z --suppress-matched output /^---$/ {*} +.Ed +.Pp +Trace 100 radiative paths into the solar plant described in +.Pa input.yaml , +with respect to the sun direction whose azimuthal and elevation angles +are 0 and 90 degrees, respectively. +Write the +.Xr solstice-output 5 +result to standard output and postprocess it with +.Xr sed 1 +to remove the first line that stores the sun direction. +The remaining data listing the radiative path geometry are redirected +into +.Pa paths.vtk : +.Bd -literal -offset indent +solstice -n 100 -D0,90 -R rcvs.yaml -p default input.yaml | sed '1d' > paths.vtk +.Ed +.Pp +Use the path-tracing rendering algorithm to draw the solar plant +.Pa solplant.yaml +with respect to the sun direction whose azimuthal and elevation angles +are 180 and 45 degrees, respectively. +Use 64 samples per pixel to estimate the per-pixel radiance and fix the +camera up vector to {0,0,1}. +Write the +.Xr solstice-output 5 +result to standard output, use +.Xr sed 1 +to remove the first line which stores the sun direction, and visualise +the rendered picture by redirecting the remaining data to the +.Xr feh 1 +image viewer: +.Bd -literal -offset indent +solstice -D180,45 -r up=0,0,1:rmode=pt:spp=64 solplant.yaml | sed '1d' | feh - +.Ed +.Sh SEE ALSO +.Xr csplit 1 , +.Xr feh 1 , +.Xr sed 1 , +.Xr solstice-input 5 , +.Xr solstice-output 5 , +.Xr solstice-receiver 5 +.Sh HISTORY +.Nm +was initially developed with funding from the +.Em SOLSTICE LabEx +.Pq Laboratory of Excellence , +in collaboration with the PROMES Laboratory of the +French National Centre for Scientific Research +.Pq CNRS . +Starting in 2026, a new development effort funded by Ademe is ongoing. +.Sh AUTHORS +.Nm +was written and is maintained by +.An |M\['e]so|Star> Aq Mt contact@meso-star.com . diff --git a/doc/solstice.1.txt.in b/doc/solstice.1.txt.in @@ -1,272 +0,0 @@ -// Copyright (C) 2016-2018 CNRS, 2018-2019 |Meso|Star> -// -// This is free documentation: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This manual is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. -:toc: - -solstice(1) -=========== - -NAME ----- -solstice - compute the power collected by a concentrated solar plant - -SYNOPSIS --------- -[verse] -*solstice* -*solstice* [_option_]... [_file_] -*solstice* *-g* <__sub-option__[:...]> [_option_]... [_file_] -*solstice* *-p* <__sub-option__[:...]> [_option_]... [_file_] -*solstice* *-r* <__sub-option__[:...]> [_option_]... [_file_] - -DESCRIPTION ------------ -*solstice* computes the total power collected by a concentrated solar plant, as -described in the *solstice-input*(5) _file_. If the _file_ argument is not -provided, the solar plant is read from standard input. To evaluate various -efficiencies for each primary reflector, it computes losses due to cosine -effect, shadowing and masking, orientation and surface irregularities, -materials properties and atmospheric extinction. The efficiency for each -one of these effects is subsequently computed for each reflector. - -The entities on which computations must be performed are listed in the -*solstice-receiver*(5) file submitted through the *-R* option. The estimated -results follow the *solstice-output*(5) format and are written to the _output_ -file or to the standard output whether the *-o* _output_ option is defined or -not, respectively. Note that the *solstice* algorithm is based on the -Monte-Carlo method, which means that every result is provided with its -numerical accuracy. - -*solstice* is designed to efficiently handle complex solar facilities: several -reflectors can be specified (planes, conics, cylindro-parabolic, etc.) and -positioned in 3D space, with a possibility for 1-axis and 2-axis -auto-orientation. Multiple materials can be used, as long as the relevant -physical properties are provided. Spectral effects are also taken into account: -it is possible to define the spectral distribution of any physical property, -including the input solar spectrum and the transmissivity of the atmosphere, at -any spectral resolution. Refer to *solstice-input*(5) for more informations. - -In addition of the aforementioned computations, *solstice* provides three -other functionalities. The *-g* option can be used to convert the -*solstice-input*(5) geometries in CAO files. The *-p* option saves the sampled -radiative paths used by the estimates, allowing to visualise them externally -which may be a great help to identify a design issue. Finally, the *-r* option -is used to render an image of the submitted solar facility. Note that these -three options are mutually exclusives, and once defined, they replace the -default *solstice* behaviour. - -Please note that any coordinate-related question in Solstice must be -considered with the right-handed convention in mind. - -OPTIONS -------- -*-D* <__alpha__,__beta__[:...]>:: - List of sun directions. A direction is defined by two angles in degrees. The - first one, here refered to as _alpha_, is an azimuthal angle in [0, 360[ and - the second one, here refered to as _beta_, is an elevation in [0, 90]. - Each provided sun direction triggers a new computation whose results are - concatenated to the _output_ file. -+ -Following the right-handed convention, Solstice azimuthal rotation is -counter-clockwise, with 0° on the X axis. Solstice elevation starts from 0° for -directions in the XY plane, up to 90° at zenith. Thus -D0,0 -D90,0 -D180,0 and --D270,0 will produce solar vectors {-1,0,0} {0,-1,0} {+1,0,0} and {0,+1,0} -respectively, while -D__alpha__,90 will produce {0,0,-1} regardless of _alpha_ -value. - -*-f*:: - Force overwrite of the output files, i.e. the _output_ file and the file - where the state of the random number generator is saved (see the *-G* - option). - -*-G* <__sub-option__:...>:: - Save and restore the state of the random number generator. This option can be - used to ensure the statistical independence between successive simulations - on the same system. For instance, one can run a new simulation and - initialising its random number generator with the final state of the - generator as defined by the previous run. Available sub options are: - - **istate=**_input_rng_state_;; - Define the file from which the initial state of the random number generator - is read. If not defined, the random number generator is initialised with - its default seed. - - **ostate=**_output_rng_state_;; - Define the file where the final state of the random number generator is - written. If not defined, this state is simply discarded. - -*-g* <__sub-option__:...>:: - Generate the shape of the geometry defined in the submitted _file_ and store - it in _output_. Available sub-options are: - - *format=obj*;; - Define the file format in which the meshes are stored. Currently, only the - Alias Wavefront OBJ file format is supported. - - *split=*<**geometry**|*object*|*none*>;; - Define how the output mesh is split in sub meshes. A sub mesh can be - generated for each *geometry* or for each *object* as defined in the - *solstice-input*(5) file format. The *none* option means that only one - mesh is generated for the whole solar facility. By default, the *split* - option is set to *none*. - -*-h*:: - List short help and exit. - -*-n* _experiments-count_:: - Number of Monte-Carlo experiments used to estimate the solar flux. By - default _experiments-count_ is set to @SOLSTICE_ARGS_DEFAULT_NREALISATIONS@. - -*-o* _output_:: - Write results to _output_ with respect to the *solstice-output*(5) format. If - not defined, write results to standard output. - -*-p* <__sub-option__:...>:: - Register the sampled radiative paths for each sun direction and write them to - _output_. Available sub-options are: - - *default*;; - Use default sub-options. - - **irlen=**_length_;; - Length of the radiative path segments going to the infinity. By default, it - is computed relatively to the scene size. - - **srlen=**_length_;; - Length of the radiative path segments coming from the sun. By default, it - is computed relatively to the scene size. - -*-q*:: - Do not print the helper message when no _file_ is submitted. - -*-R* _receivers_:: - *solstice-receiver*(5) file defining the scene receivers, i.e. the solar - plant entities for which *solstice* computes Monte-Carlo estimates. - -*-r* <__sub-option__:...>:: - Render an image of the scene through a pinhole camera, for each submitted - sun direction. Write the resulting images to _output_. Available sub-options - are: - - **fov=**_angle_;; - Horizontal field of view of the camera in [30, 120] degrees. By default - _angle_ is @SOLSTICE_ARGS_DEFAULT_CAMERA_FOV@ degrees. - - **img=**_width_**x**_height_;; - Definition of the rendered image in pixels. By default the image definition - is @SOLSTICE_ARGS_DEFAULT_IMG_WIDTH@x@SOLSTICE_ARGS_DEFAULT_IMG_HEIGHT@. - - **pos=**_x_**,**_y_**,**_z_;; - Position of the camera. By default it is set to - {@SOLSTICE_ARGS_DEFAULT_CAMERA_POS@} or it is automatically computed to - ensure that the whole scene is visible, whether *tgt* is set or not, - respectively. - - **rmode=**<**draft**|**pt**>;; - Rendering mode. In *draft* mode, images are computed by ray-casting; all - materials are lambertian, the sun is ignored and the only light source is - positioned at the camera position. In *pt* mode, the scene is rendered with - the un-biased path-tracing Monte-Carlo algorithm; the materials described - in the committed _file_ as well as the submitted sun directions are - correctly handled and an uniform skydome is added to simulate the diffuse - infinite lighting. By default *rmode* is set to *draft*. - - **spp=**_samples-count_;; - Number of samples per pixel. If *rmode* is *draft*, the samples position - into a pixel are the same for all pixels. With *rmode=pt* the pixel - samples are generated independently for each pixel. By default, use 1 - sample per pixel. - - **tgt=**_x_**,**_y_**,**_z_;; - Position targeted by the camera. By default, it is set to - {@SOLSTICE_ARGS_DEFAULT_CAMERA_TGT@} or it is automatically computed to - ensure that the whole scene is visible, whether *pos* is set or not, - respectively. - - **up=**_x_**,**_y_**,**_z_;; - Up vector of the camera. If *rmode* is *pt*, this vector also defines the - direction toward the top of the skydome. By default, *up* is set to - {@SOLSTICE_ARGS_DEFAULT_CAMERA_UP@}. - -*-t* _threads-count_:: - Hint on the number of threads to use. By default use as many threads as CPU - cores. - -*-v*:: - Make solstice more verbose. - -*--version*:: - Output version information and exit. - -EXAMPLES --------- - -Launch two simulations for sun directions whose azimuthal and elevation angles -are {*45*,*70*} and {*50*,*75*}. The solar facility is described in -*input.yaml* and the receivers on which the integrations must be performed are -declared in the *rcvs.yaml* file. *10000* experiments are used by the -Monte-Carlo estimates and the results are written to *output* even though this -file already exists: - - $ solstice -D45,70:50,75 -R rcvs.yaml -n 10000 -f -o output input.yaml - -Generate a mesh for each geometry described in *input.yaml*, and save them in -the *output* file with respect to the Alias Wavefront OBJ format. The meshes -are positioned according to their orientation constraints, with respect to the -sun direction whose azimuthal and elevation angles are {*30*,*60*}. Use the -*csplit*(1) Unix command to generate an Alias Wavefront OBJ file per geometry -stored in *output*. The name of the generated Alias Wavefront OBJ files are -*geom*<__NUM__>**.obj** with __NUM__ in [0, N-1] where N is the number of -geometries described in *input.yaml*. Refer to *solstice-output*(5) for -informations on the regular expression *^---$* used to split the output file: - - $ solstice -D30,60 -g format=obj:split=geometry -f -o output input.yaml - $ csplit -f geom -b %02d.obj -z --suppress-matched output /^---$/ {*} - -Trace 100 radiative paths into the solar plant described in *input.yaml*, with -respect to the sun direction whose azimuthal and elevations angles are *0* and -*90* degrees, respectively. Write the *solstice-output*(5) result to the -standard output and postprocess it with the *sed*(1) Unix command to remove the -first line that stores the sun direction from which the radiative paths come -from. The remaining data that list the radiative paths geometry are redirected -into the *paths.vtk* file: - - $ solstice -n 100 -D0,90 -R rcvs.yaml -p default input.yaml | sed '1d'>paths.vtk - -Use the path-tracing rendering algorithm to draw the solar plant -*solplant.yaml* with respect to the sun direction whose azimuthal and elevation -angles are *180* and *45* degrees, respectively. Use *64* samples per pixel to -estimate the per-pixel radiance and fix the up camera vector to {*0*,*0*,*1*}. -Write the *solstice-output*(5) result to standard output and use the *sed*(1) -Unix command to remove the first line which stores the sun direction used to -draw the image. Finally, visualise the rendered picture by redirecting the -remaining data to the *feh*(1) image viewer. - - $ solstice -D180,45 -r up=0,0,1:rmode=pt:spp=64 solplant.yaml | sed '1d' | feh - - -COPYRIGHT ---------- -Copyright &copy; 2016-2018 CNRS, 2018-2019 |Meso|Star>. License GPLv3+: GNU GPL -version 3 or later <http://gnu.org/licenses/gpl.html>. This is free software. -You are free to change and redistribute it. There is NO WARRANTY, to the extent -permitted by law. - -SEE ALSO --------- -*csplit*(1), -*feh*(1), -*sed*(1), -*solstice-input*(5), -*solstice-output*(5), -*solstice-receiver*(5) diff --git a/score.pc.in b/score.pc.in @@ -0,0 +1,19 @@ +prefix=@PREFIX@ +includedir=${prefix}/include +libdir=${prefix}/lib + +Requires: \ + rsys >= @RSYS_VERSION@ +Requires.private:\ + s3dut >= @S3DUT_VERSION@,\ + star-sp >= @SSP_VERSION@,\ + sstl >= @SSTL_VERSION@,\ + yaml-0.1 >= @YAML_VERSION@,\ + ssol >= @SSOL_VERSION@,\ + sanim >= @SANIM_VERSION@ +Name: score +Description: Solstice Core +Version: @VERSION@ +Libs: -L${libdir} -lscore +Libs.private: -fopenmp -lm +CFlags: -I${includedir} -fopenmp diff --git a/sprs.pc.in b/sprs.pc.in @@ -0,0 +1,14 @@ +prefix=@PREFIX@ +includedir=${prefix}/include +libdir=${prefix}/lib + +Requires: \ + rsys >= @RSYS_VERSION@ +Requires.private:\ + yaml-0.1 >= @YAML_VERSION@ +Name: sprs +Description: Solstice Parser +Version: @VERSION@ +Libs: -L${libdir} -lsprs +Libs.private: -lm +CFlags: -I${includedir} diff --git a/src/parser/solparser.h b/src/parser/solparser.h @@ -22,6 +22,15 @@ #include <rsys/rsys.h> #include <stddef.h> +/* Library symbol management */ +#if defined(SPRSR_SHARED_BUILD) /* Build shared library */ + #define SPRSR_API extern EXPORT_SYM +#elif defined(SPRSR_STATIC) /* Use/build static library */ + #define SPRSR_API extern LOCAL_SYM +#else /* Use shared library */ + #define SPRSR_API extern IMPORT_SYM +#endif + struct mem_allocator; struct solparser; @@ -46,193 +55,193 @@ struct solparser_geometry_iterator { /******************************************************************************* * Solstice parser API. ******************************************************************************/ -extern LOCAL_SYM res_T +SPRSR_API res_T solparser_create (struct mem_allocator* allocator, /* May be NULL <=> use default allocator */ struct solparser** parser); -extern LOCAL_SYM void +SPRSR_API void solparser_ref_get (struct solparser* parser); -extern LOCAL_SYM void +SPRSR_API void solparser_ref_put (struct solparser* parser); -extern LOCAL_SYM res_T +SPRSR_API res_T solparser_setup (struct solparser* parser, const char* stream_name, /* May be NULL */ FILE* stream); /* Return RES_BAD_OP if there is no more YAML document to parse */ -extern LOCAL_SYM res_T +SPRSR_API res_T solparser_load (struct solparser* parser); /* Return NULL if no entity is found */ -extern LOCAL_SYM const struct solparser_anchor* +SPRSR_API const struct solparser_anchor* solparser_find_anchor (struct solparser* parser, const char* anchor_name); /* Return NULL if no entity is found */ -extern LOCAL_SYM const struct solparser_entity* +SPRSR_API const struct solparser_entity* solparser_find_entity (struct solparser* parser, const char* entity_name); -extern LOCAL_SYM const struct solparser_anchor* +SPRSR_API const struct solparser_anchor* solparser_get_anchor (const struct solparser* parser, const struct solparser_anchor_id anchor); -extern LOCAL_SYM const struct solparser_entity* +SPRSR_API const struct solparser_entity* solparser_get_entity (const struct solparser* parser, const struct solparser_entity_id entity); -extern LOCAL_SYM const struct solparser_image* +SPRSR_API const struct solparser_image* solparser_get_image (const struct solparser* parser, const struct solparser_image_id image); -extern LOCAL_SYM const struct solparser_geometry* +SPRSR_API const struct solparser_geometry* solparser_get_geometry (const struct solparser* parser, const struct solparser_geometry_id geom); -extern LOCAL_SYM const struct solparser_material* +SPRSR_API const struct solparser_material* solparser_get_material (const struct solparser* parser, const struct solparser_material_id mtl); -extern LOCAL_SYM const struct solparser_material_double_sided* +SPRSR_API const struct solparser_material_double_sided* solparser_get_material_double_sided (const struct solparser* parser, const struct solparser_material_double_sided_id mtl2); -extern LOCAL_SYM const struct solparser_material_dielectric* +SPRSR_API const struct solparser_material_dielectric* solparser_get_material_dielectric (const struct solparser* parser, const struct solparser_material_dielectric_id dielectric); -extern LOCAL_SYM const struct solparser_material_matte* +SPRSR_API const struct solparser_material_matte* solparser_get_material_matte (const struct solparser* parser, const struct solparser_material_matte_id matte); -extern LOCAL_SYM const struct solparser_material_mirror* +SPRSR_API const struct solparser_material_mirror* solparser_get_material_mirror (const struct solparser* parser, const struct solparser_material_mirror_id mirror); -extern LOCAL_SYM const struct solparser_material_thin_dielectric* +SPRSR_API const struct solparser_material_thin_dielectric* solparser_get_material_thin_dielectric (const struct solparser* parser, const struct solparser_material_thin_dielectric_id thin_dielectric); -extern LOCAL_SYM const struct solparser_medium* +SPRSR_API const struct solparser_medium* solparser_get_medium (const struct solparser* parser, const struct solparser_medium_id medium); -extern LOCAL_SYM const struct solparser_object* +SPRSR_API const struct solparser_object* solparser_get_object (const struct solparser* parser, const struct solparser_object_id obj); -extern LOCAL_SYM const struct solparser_shape* +SPRSR_API const struct solparser_shape* solparser_get_shape (const struct solparser* parser, const struct solparser_shape_id shape); -extern LOCAL_SYM const struct solparser_shape_cuboid* +SPRSR_API const struct solparser_shape_cuboid* solparser_get_shape_cuboid (const struct solparser* parser, const struct solparser_shape_cuboid_id cuboid); -extern LOCAL_SYM const struct solparser_shape_cylinder* +SPRSR_API const struct solparser_shape_cylinder* solparser_get_shape_cylinder (const struct solparser* parser, const struct solparser_shape_cylinder_id cylinder); -extern LOCAL_SYM const struct solparser_shape_imported_geometry* +SPRSR_API const struct solparser_shape_imported_geometry* solparser_get_shape_obj (const struct solparser* parser, const struct solparser_shape_imported_geometry_id impgeom); -extern LOCAL_SYM const struct solparser_shape_paraboloid* +SPRSR_API const struct solparser_shape_paraboloid* solparser_get_shape_parabol (const struct solparser* parser, const struct solparser_shape_paraboloid_id paraboloid); -extern LOCAL_SYM const struct solparser_shape_paraboloid* +SPRSR_API const struct solparser_shape_paraboloid* solparser_get_shape_parabolic_cylinder (const struct solparser* parser, const struct solparser_shape_paraboloid_id paraboloid); -extern LOCAL_SYM const struct solparser_shape_hyperboloid* +SPRSR_API const struct solparser_shape_hyperboloid* solparser_get_shape_hyperbol (const struct solparser* parser, const struct solparser_shape_hyperboloid_id hyperboloid); -extern LOCAL_SYM const struct solparser_shape_hemisphere* +SPRSR_API const struct solparser_shape_hemisphere* solparser_get_shape_hemisphere (const struct solparser* parser, const struct solparser_shape_hemisphere_id hemisphere); -extern LOCAL_SYM const struct solparser_shape_plane* +SPRSR_API const struct solparser_shape_plane* solparser_get_shape_plane (const struct solparser* parser, const struct solparser_shape_plane_id plane); -extern LOCAL_SYM const struct solparser_shape_sphere* +SPRSR_API const struct solparser_shape_sphere* solparser_get_shape_sphere (const struct solparser* parser, const struct solparser_shape_sphere_id sphere); -extern LOCAL_SYM const struct solparser_shape_imported_geometry* +SPRSR_API const struct solparser_shape_imported_geometry* solparser_get_shape_stl (const struct solparser* parser, const struct solparser_shape_imported_geometry_id impgeom); -extern LOCAL_SYM const struct solparser_sun* +SPRSR_API const struct solparser_sun* solparser_get_sun (const struct solparser* parser); -extern LOCAL_SYM const struct solparser_atmosphere* +SPRSR_API const struct solparser_atmosphere* solparser_get_atmosphere (const struct solparser* parser); -extern LOCAL_SYM const struct solparser_x_pivot* +SPRSR_API const struct solparser_x_pivot* solparser_get_x_pivot (const struct solparser* parser, const struct solparser_pivot_id x_pivot); -extern LOCAL_SYM const struct solparser_zx_pivot* +SPRSR_API const struct solparser_zx_pivot* solparser_get_zx_pivot (const struct solparser* parser, const struct solparser_pivot_id zx_pivot); -extern LOCAL_SYM const struct solparser_spectrum* +SPRSR_API const struct solparser_spectrum* solparser_get_spectrum (const struct solparser* parser, const struct solparser_spectrum_id spectrum); -extern LOCAL_SYM int +SPRSR_API int solparser_has_spectrum (const struct solparser* parser); /******************************************************************************* * Entity interator ******************************************************************************/ -extern LOCAL_SYM void +SPRSR_API void solparser_entity_iterator_begin (struct solparser* parser, struct solparser_entity_iterator* it); -extern LOCAL_SYM void +SPRSR_API void solparser_entity_iterator_end (struct solparser* parser, struct solparser_entity_iterator* it); @@ -265,12 +274,12 @@ solparser_entity_iterator_get(struct solparser_entity_iterator* it) /******************************************************************************* * Material iterator ******************************************************************************/ -extern LOCAL_SYM void +SPRSR_API void solparser_material_iterator_begin (struct solparser* parser, struct solparser_material_iterator* it); -extern LOCAL_SYM void +SPRSR_API void solparser_material_iterator_end (struct solparser* parser, struct solparser_material_iterator* it); @@ -303,11 +312,11 @@ solparser_material_iterator_get(struct solparser_material_iterator* it) /******************************************************************************* * Geometry iterator ******************************************************************************/ -extern LOCAL_SYM void +SPRSR_API void solparser_geometry_iterator_begin (struct solparser* parser, struct solparser_geometry_iterator* it); -extern LOCAL_SYM void +SPRSR_API void solparser_geometry_iterator_end (struct solparser* parser, struct solparser_geometry_iterator* it); diff --git a/src/receivers/srcvl.h b/src/receivers/srcvl.h @@ -19,6 +19,15 @@ #include <rsys/rsys.h> +/* Library symbol management */ +#if defined(SRCVL_SHARED_BUILD) /* Build shared library */ + #define SRCVL_API extern EXPORT_SYM +#elif defined(SRCVL_STATIC) /* Use/build static library */ + #define SRCVL_API extern LOCAL_SYM +#else /* Use shared library */ + #define SRCVL_API extern IMPORT_SYM +#endif + enum srcvl_side { SRCVL_FRONT = BIT(0), SRCVL_BACK = BIT(1), @@ -44,35 +53,35 @@ struct srcvl; /******************************************************************************* * Solstice Receiver API ******************************************************************************/ -extern LOCAL_SYM res_T +SRCVL_API res_T srcvl_create (struct mem_allocator* allocator, /* May be NULL <=> use default allocator */ struct srcvl** rcvl); -extern LOCAL_SYM void +SRCVL_API void srcvl_ref_get (struct srcvl* rcvl); -extern LOCAL_SYM void +SRCVL_API void srcvl_ref_put (struct srcvl* rcvl); -extern LOCAL_SYM res_T +SRCVL_API res_T srcvl_setup_stream (struct srcvl* rcvl, const char* stream_name, /* May be NULL */ FILE* stream); /* Return RES_BAD_OP if there is no more YAML document to parse */ -extern LOCAL_SYM res_T +SRCVL_API res_T srcvl_load (struct srcvl* rcvl); -extern LOCAL_SYM size_t +SRCVL_API size_t srcvl_count (const struct srcvl* rcvl); -extern LOCAL_SYM void +SRCVL_API void srcvl_get (const struct srcvl* rcvl, const size_t i, diff --git a/src/score.h b/src/score.h @@ -0,0 +1,60 @@ +/* Copyright (C) 2018-2026 |Meso|Star> (contact@meso-star.com) + * Copyright (C) 2016-2018 CNRS + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef SCORE_H +#define SCORE_H + +#include <rsys/rsys.h> + +struct mem_allocator; +struct solstice; +struct solstice_args; + +/* Library symbol management */ +#if defined(SCORE_SHARED_BUILD) /* Build shared library */ + #define SCORE_API extern EXPORT_SYM +#elif defined(SCORE_STATIC) /* Use/build static library */ + #define SCORE_API extern LOCAL_SYM +#else /* Use shared library */ + #define SCORE_API extern IMPORT_SYM +#endif + +SCORE_API res_T +solstice_init + (struct mem_allocator* allocator, /* May be NULL <=> use default allocator */ + const struct solstice_args* args, + struct solstice* solstice); + +SCORE_API void +solstice_release + (struct solstice* solstice); + +SCORE_API res_T +solstice_run + (struct solstice* solstice); + +SCORE_API res_T +solstice_args_init + (struct solstice_args* args, + const int argc, + char** argv); + +SCORE_API void +solstice_args_release + (struct solstice_args* args); + +#endif /* SCORE_H */ + diff --git a/src/solstice.h b/src/solstice.h @@ -27,6 +27,14 @@ #include <rsys/mem_allocator.h> #include <rsys/str.h> +/* Library symbol management */ +#if defined(SCORE_SHARED_BUILD) /* Build shared library */ + #define SCORE_API extern EXPORT_SYM +#elif defined(SCORE_STATIC) /* Use/build static library */ + #define SCORE_API extern LOCAL_SYM +#else /* Use shared library */ + #define SCORE_API extern IMPORT_SYM +#endif struct solparser; struct solstice_node; struct ssol_device; @@ -202,17 +210,17 @@ struct solstice { struct mem_allocator* allocator; }; -extern LOCAL_SYM res_T +SCORE_API res_T solstice_init (struct mem_allocator* allocator, /* May be NULL <=> use default allocator */ const struct solstice_args* args, struct solstice* solstice); -extern LOCAL_SYM void +SCORE_API void solstice_release (struct solstice* solstice); -extern LOCAL_SYM res_T +SCORE_API res_T solstice_run (struct solstice* solstice); diff --git a/src/solstice_args.c b/src/solstice_args.c @@ -56,7 +56,7 @@ print_help(const char* program) printf( " -h display this help and exit.\n"); printf( -" -n EXPERIMENTS number of Monte Carlo experiments. Default is %lu.\n", +" -n SAMPLES number of Monte Carlo samples. Default is %lu.\n", SOLSTICE_ARGS_DEFAULT.nexperiments); printf( " -o OUTPUT write results to OUTPUT. If not defined, write results to\n" diff --git a/src/solstice_args.h.in b/src/solstice_args.h.in @@ -16,8 +16,10 @@ #ifndef SOLSTICE_ARGS_H #define SOLSTICE_ARGS_H -#include <rsys/math.h> +#include "score.h" + #include <solstice/ssol.h> +#include <rsys/math.h> struct solstice_args_spherical { double azimuth; /* In radians */ @@ -135,15 +137,5 @@ static const struct solstice_args SOLSTICE_ARGS_NULL = SOLSTICE_ARGS_NULL__; static const struct solstice_args SOLSTICE_ARGS_DEFAULT = SOLSTICE_ARGS_DEFAULT__; -extern LOCAL_SYM res_T -solstice_args_init - (struct solstice_args* args, - const int argc, - char** argv); - -extern LOCAL_SYM void -solstice_args_release - (struct solstice_args* args); - #endif /* SOLSTICE_ARGS_H */ diff --git a/srcv.pc.in b/srcv.pc.in @@ -0,0 +1,14 @@ +prefix=@PREFIX@ +includedir=${prefix}/include +libdir=${prefix}/lib + +Requires: \ + rsys >= @RSYS_VERSION@ +Requires.private:\ + yaml-0.1 >= @YAML_VERSION@ +Name: srcv +Description: Solstice Receiver +Version: @VERSION@ +Libs: -L${libdir} -lsrcv +Libs.private: -lm +CFlags: -I${includedir}